| Files | Last commit | Last update |
|---|---|---|
| 1 month ago | ||
| 1 month ago | ||
| 7 months ago | ||
| 7 months ago | ||
| 7 months ago |
Git Graph Demo MiniApp / Git Graph 示例 MiniApp
English
This demo showcases BitFun MiniApp's full-stack collaboration capability — specifically, using a third-party npm package (simple-git) inside a Node.js/Bun Worker to read a local Git repository and render an interactive commit graph.
Features
- Pick a repository — opens a native directory picker via
app.dialog.open({ directory: true }) - Commit graph — Worker fetches
git.graphData(log + refs + stashes + uncommitted in one call); UI renders commit nodes and branch lines as SVG - Branches & status — shows current branch, full branch list, and workspace status (modified / staged / untracked)
- Commit detail — click any commit to view author, timestamp, diff stat, and per-file diff
- Branch management — create, delete, rename, checkout local/remote branches
- Merge / Rebase — merge a branch into HEAD, rebase HEAD onto a branch
- Cherry-pick / Revert / Reset — cherry-pick a commit, revert with a new commit, or hard/mixed/soft reset
- Push / Fetch — push to remote, fetch with prune, fetch a remote branch into a local branch
- Remote management — add, remove, update remote URLs via the Remotes panel
- Stash — push, apply, pop, drop, and branch-from-stash operations
- Search commits — filter commit list by message, hash, or author
- Tag management — add lightweight or annotated tags, delete tags, push tags
Data Flow
- UI → Bridge:
app.call('git.log', { cwd, maxCount })etc. viawindow.app(JSON-RPC) - Bridge → Tauri: postMessage intercepted by the host
useMiniAppBridge, which callsminiapp_worker_call - Tauri → Worker: Rust writes the request to Worker stdin (JSON-RPC)
- Worker:
worker_host.jsloadssource/worker.js; exported handlers are invoked — primarilygit.graphData(returns commits + refs + stashes + uncommitted in one response), plusgit.show,git.checkout,git.merge,git.push,git.stashPush, and 20+ other methods — all backed by thesimple-gitnpm package - Worker → Tauri → Bridge → UI: response travels back via stderr → Rust → postMessage to iframe → UI refreshes graph and detail panel
Directory Structure
miniapps/git-graph/
├── README.md # this file
├── meta.json # metadata & permissions (fs/shell/node)
├── package.json # npm deps (simple-git) + build script
├── storage.json # app KV (e.g. last opened repo path)
└── source/
├── index.html # UI skeleton
├── build.js # build script: concat ui/*.js → ui.js, styles/*.css → style.css
├── ui.js # frontend entry (generated by build, do not edit directly)
├── style.css # style entry (generated by build, do not edit directly)
├── ui/ # frontend modules (run `npm run build` after editing)
│ ├── state.js, theme.js, main.js, bootstrap.js
│ ├── graph/layout.js, graph/renderRowSvg.js
│ ├── components/contextMenu.js, modal.js, findWidget.js
│ ├── panels/detailPanel.js, remotePanel.js
│ └── services/gitClient.js
├── styles/ # style modules (run `npm run build` after editing)
│ ├── tokens.css, layout.css, graph.css
│ ├── detail-panel.css, overlay.css
│ └── (merge order defined in build.js)
├── worker.js # backend CJS (simple-git wrapper)
└── esm_dependencies.json # ESM deps (empty for this demo)
During development: after editing source/ui/*.js or source/styles/*.css, run npm run build inside the miniapps/git-graph directory to regenerate source/ui.js and source/style.css. BitFun will pick up the latest build on next load.
Running in BitFun
-
Install to user data directory: copy this folder into BitFun's MiniApp data directory under an
app_idsubdirectory, e.g.:- The data directory is typically
{user_data}/miniapps/ - Create a subdirectory like
git-graph-sampleand place all files from this folder inside it (i.e.meta.json,package.json,source/etc. at the root of that subdirectory)
- The data directory is typically
-
Or import via API: if BitFun supports path-based import, use
create_miniappor equivalent, pointing to this directory as the source; make sure theidinmeta.jsonmatches the directory name. -
Install dependencies: inside the MiniApp's app directory, run:
bun installornpm install(matching the runtime BitFun detected)- Or use the "Install Dependencies" action in the Mini Apps gallery (calls
miniapp_install_deps)
-
Compile: to regenerate
compiled.html, callminiapp_recompileor let BitFun compile automatically when the MiniApp is opened. -
Open the MiniApp in the Mini Apps gallery, pick a repository, and the Git Graph will appear.
Permissions
| Permission | Value | Purpose |
|---|---|---|
fs.read |
{appdata}, {workspace}, {user-selected} |
Read app data, workspace, and user-selected repo |
fs.write |
{appdata} |
Write app-own data only (e.g. storage) |
shell.allow |
["git"] |
simple-git needs to invoke the system git binary |
node.enabled |
true |
Enable JS Worker to execute simple-git logic in worker.js |
Technical Highlights
- Client-side third-party library:
require('simple-git')inworker.jsruns inside a Bun or Node.js Worker process — no need to reimplement Git in Rust - Zero custom dialect: UI is plain concatenated JavaScript (IIFE modules sharing
window.__GG), Worker is standard CJS — no custom framework or transpiler required;window.appis the unified Bridge API - ESM dependencies: this demo uses plain vanilla JS;
esm_dependencies.jsonis empty — add React, D3, etc. there to have them served via Import Map from esm.sh
中文
本示例展示 BitFun MiniApp 的前后端协同能力,尤其是通过 Node.js/Bun 在端侧使用三方 npm 库(simple-git)读取 Git 仓库并渲染交互式提交图谱。
功能
- 选择仓库:通过
app.dialog.open({ directory: true })打开原生目录选择器,选择本地 Git 仓库 - 提交图谱:Worker 端通过
git.graphData(一次调用返回提交列表 + refs + stash + 未提交变更),UI 端用 SVG 绘制提交节点与分支线 - 分支与状态:展示当前分支、所有分支列表及工作区状态(modified/staged/untracked)
- 提交详情:点击某个 commit 可查看作者、时间、diff stat 及逐文件 diff
- 分支管理:创建、删除、重命名、checkout 本地/远程分支
- Merge / Rebase:将分支合并到 HEAD,或将 HEAD rebase 到目标分支
- Cherry-pick / Revert / Reset:cherry-pick 指定 commit,revert 生成新提交,或 hard/mixed/soft reset
- Push / Fetch:推送到远程,带 prune 的 fetch,将远程分支 fetch 到本地分支
- 远程管理:通过远程面板添加、删除、修改远程 URL
- Stash:push、apply、pop、drop 及从 stash 创建分支
- 搜索提交:按消息、hash 或作者过滤提交列表
- Tag 管理:添加轻量/注解 tag,删除 tag,推送 tag
前后端协同流程
- UI → Bridge:
app.call('git.log', { cwd, maxCount })等通过window.app发起 RPC - Bridge → Tauri:postMessage 被宿主
useMiniAppBridge接收,调用miniapp_worker_call - Tauri → Worker:Rust 将请求写入 Worker 进程 stdin(JSON-RPC)
- Worker:
worker_host.js加载本目录source/worker.js,其导出的处理函数被调用 — 主要是git.graphData(一次返回提交 + refs + stash + 未提交变更),以及git.show、git.checkout、git.merge、git.push、git.stashPush等 20+ 个方法 — 均基于simple-gitnpm 包 - Worker → Tauri → Bridge → UI:响应经 stderr 回传 Rust,再 postMessage 回 iframe,UI 更新图谱与详情
目录结构
miniapps/git-graph/
├── README.md # 本说明
├── meta.json # 元数据与权限(fs/shell/node)
├── package.json # npm 依赖(simple-git)及 build 脚本
├── storage.json # 应用 KV(如最近打开的仓库路径)
└── source/
├── index.html # UI 骨架
├── build.js # 构建脚本:合并 ui/*.js → ui.js,styles/*.css → style.css
├── ui.js # 前端入口(由 build 生成,勿直接编辑)
├── style.css # 样式入口(由 build 生成,勿直接编辑)
├── ui/ # 前端模块(编辑后需运行 npm run build)
│ ├── state.js, theme.js, main.js, bootstrap.js
│ ├── graph/layout.js, graph/renderRowSvg.js
│ ├── components/contextMenu.js, modal.js, findWidget.js
│ ├── panels/detailPanel.js, remotePanel.js
│ └── services/gitClient.js
├── styles/ # 样式模块(编辑后需运行 npm run build)
│ ├── tokens.css, layout.css, graph.css
│ ├── detail-panel.css, overlay.css
│ └── (合并顺序见 build.js)
├── worker.js # 后端 CJS(simple-git 封装)
└── esm_dependencies.json # ESM 依赖(本示例为空)
开发时:修改 source/ui/*.js 或 source/styles/*.css 后,在 miniapps/git-graph 目录执行 npm run build 生成 source/ui.js 与 source/style.css,BitFun 加载时会使用最新构建结果。
在 BitFun 中运行
-
安装到用户数据目录:将本目录复制到 BitFun 的 MiniApp 数据目录下,并赋予一个 app_id 子目录,例如:
- 数据目录一般为
{user_data}/miniapps/ - 新建子目录如
git-graph-sample,将本目录中所有文件按相同结构放入其中(即meta.json、package.json、source/等在该子目录下)
- 数据目录一般为
-
或通过 API 创建:若 BitFun 支持从路径导入,可使用
create_miniapp或等价方式,将本目录作为 source 路径导入,并确保meta.json中的id与目录名一致。 -
安装依赖:在 MiniApp 的 app 目录下执行:
bun install或npm install(与 BitFun 检测到的运行时一致)- 或在 Mini Apps 画廊中对该 MiniApp 执行「安装依赖」操作(调用
miniapp_install_deps)
-
编译:若需重新生成
compiled.html,可调用miniapp_recompile或由 BitFun 在打开该 MiniApp 时自动编译。 -
在 Mini Apps 画廊中打开该 MiniApp,选择仓库后即可查看 Git Graph。
权限说明
| 权限 | 值 | 用途 |
|---|---|---|
fs.read |
{appdata}、{workspace}、{user-selected} |
读取应用数据、工作区及用户选择的仓库目录 |
fs.write |
{appdata} |
仅写入应用自身数据(如 storage) |
shell.allow |
["git"] |
simple-git 需调用系统 git 命令 |
node.enabled |
true |
启用 JS Worker,以便执行 worker.js 中的 simple-git 逻辑 |
技术要点
- 端侧三方库:
worker.js中require('simple-git'),在 Bun 或 Node.js Worker 进程中运行,无需在 Rust 中重新实现 Git 能力 - 无自定义方言:UI 为普通拼接脚本(IIFE 模块通过
window.__GG共享状态),Worker 为标准 CJS,无需自定义框架或转译器;window.app为统一 Bridge API - ESM 依赖:本示例 UI 使用纯 vanilla JS,
esm_dependencies.json为空;若需 React/D3 等,可在其中声明并由 Import Map 从 esm.sh 加载