← 返回列表
⚠ 装前注意
一个 DeepSeek Harness 插件,为任务启动窗口添加 git worktree…
基本兼容但装前注意:未发布到 npm registry,仅可从源码安装 · 最近上游提交 2026/9/18 · 已提供中文文档
综合分
29.7
GitHub 分
29.7
用户评分
—
★ Stars
0
周下载量
—
安装插件(需先安装 dsh CLI 引擎:npm install -g @deepseek-ai/dsh)
dsh plugin --profile web add shenkonghui/dsh-worktree-manager未发布到 npm registry,仅可从源码安装,改用 GitHub 源安装
信任档位:已验证本站已于 1 天前真实安装成功
- 是什么
- dsh 原生插件 · market
- 装得上吗
- 本站已真实安装成功(非静态推断)
- 安全吗
- 本站尚未对该插件做风险分级(暂未覆盖,不等同于无风险)
- 还在维护吗
- 活跃:最近一次提交在 7 天前
档位由下列信号合成:本站实装验证(真实安装,当前最高到 L4)· 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。下方各区块是它的证据明细。 验证判据与等级说明 →
🟢实装验证通过· 2026/9/25
由本站实装验证器在真实 dsh 环境安装成功,非静态推断。
数据截至 2026/9/21(元数据每日更新 · 实装验证按队列轮转,单条结论的验证时间见上方)
安装兼容性检查⚠ 装前注意
以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。
✗npm 包dsh-worktree-manager(未发布到 npm,仅可源码安装)
✓Node 引擎未声明 engines.node
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明
未发布到 npm registry,仅可从源码安装
验证方式:npm registry 存在性 + package.json 静态校验 · 最后验证 2026/9/22 00:11:11
依赖的 DSH / Cordis 模块
@deepseek-ai/cordis@deepseek-ai/cordis-plugin-loader@deepseek-ai/dsh-client-ui-workspace用户评分
还没有人投票,来当第一个
订阅周报,不错过优质插件更新
每周一封 · 高评分插件 + 新用户活动
README
由 DeepSeek 最新模型翻译生成dsh-worktree-manager
一个 DeepSeek Harness 插件,为任务启动窗口添加 git worktree 管理功能——列出、创建并选择用于开发的 worktree。
为什么
Git worktree 让你可以将多个工作目录连接到同一个仓库,每个目录位于不同的分支上。当你想要以下操作时,这非常有用:
- 在功能分支上工作,而无需在 main 上暂存更改
- 在一个分支上运行测试,同时在另一个分支上开发
- 在开发时保留一个干净的 main 检出以供参考
dsh 任务启动窗口有一个用于选择工作目录的工作区选择器,但它不了解 git worktree。本插件通过以下方式弥补这一差距:
1. 在工作区选择器区域添加一个“Git Worktree”按钮
2. 扫描所有已注册的 dsh 工作区,并将位于 git 仓库内的工作区按其共享的仓库根目录分组
3. 提供一个下拉菜单,按仓库分组列出 worktree,带有每个仓库的可折叠分区和跨仓库搜索过滤器
4. 允许使用目标仓库选择器创建新的 worktree(新分支)
5. 自动将选中/创建的 worktree 注册为 dsh 工作区并切换到它们
架构
本插件遵循 dsh 双半插件模式:
宿主半部分(src/index.ts)
一个 Cordis 插件,注入 ctx.webServer、ctx.shell 和 ctx.workspaceRegistry。它在 /plugins/dsh-worktree-manager/api/ 下注册 HTTP 路由:
| 方法 | 路径 | 描述 |
|--------|------|-------------|
| GET | /api/list?repoPath= | 列出某个仓库的 git worktree |
| GET | /api/topology | 每个仓库的分支/工作区拓扑(在一次扫描中完成仓库发现 + worktree 列表 + 合并状态) |
| GET | /api/changes?path= | 包含该目录的仓库的工作树更改,递归进入子模块 |
| GET | /api/history?path=&limit= | 包含该目录的 worktree 的提交历史,最新在前 |
| GET | /api/commit?path=&hash=[&sub=] | 一个提交的已更改文件;子模块指针移动会列出其间的子模块提交。使用 sub 时,hash 指的是该子模块内的一个提交 |
| GET | /api/diff?path=&file=[&sub=][&hash=] | 单个文件的统一 diff(工作树与 HEAD 对比,或某个提交) |
| POST | /api/create | 创建一个新的 worktree 并将其注册为工作区 |
| POST | /api/remove | 移除一个 git worktree 并注销其 dsh 工作区 |
| POST | /api/branches | 列出某个仓库中的分支 |
宿主半部分使用 node:child_process 运行 git worktree 命令,并使用 ctx.workspaceRegistry.create() 将 worktree 注册为 dsh 工作区。当 Origin 头与请求的 Host 不匹配时,POST 请求会被拒绝(CSRF 防护);省略 Origin 的非浏览器客户端不受影响。
客户端半部分(src/client/index.ts)
一个在启动时加载的浏览器模块(immediately: true)。它使用 MutationObserver 检测工作区选择器何时出现在 SPA 中,然后注入一个“Git Worktree”按钮。点击该按钮会打开一个下拉菜单,它会:
- 调用 GET /api/topology 以发现已注册的 dsh 工作区中的所有 git 仓库
- 通过 GET /api/list 并发加载每个已发现仓库的 worktree
- 按仓库分组渲染 worktree,每个分组可折叠;包含当前工作区的仓库默认展开
- 提供一个搜索框,可按名称、分支或路径过滤所有仓库中的 worktree
- 提供一行创建区域,包含目标仓库选择器(默认为当前工作区的仓库)和新分支输入框
客户端通过 fetch() 调用自定义 HTTP 路由与宿主通信。
安装
从 git 源直接安装即可——仓库已提交构建产物 lib/,安装过程中不做任何编译,也不需要 allowBuilds 构建授权:
dsh plugin --profile web add github:shenkonghui/dsh-worktree-manager
也可以从本地检出构建后安装,再启动 Web UI:
npm run build
npm install
npx @deepseek-ai/dsh web
harness 会从 dsh manifest 字段发现该插件,并:
- 将宿主部分作为 Cordis 插件加载(注册 HTTP 路由)
- 在启动时注入客户端 bundle(immediately: true)
产物维护
lib/ 已纳入版本控制(.gitignore 不再忽略它),这正是 git 源安装能免构建的原因。代价是:改动 src/ 后必须重新构建并连同 lib/ 一起提交,否则远程仓库会停留在旧产物上。
npm run build # 重建 lib/(host 半 tsc 输出 + client 半 esbuild 打包)
npm run check:lib # 把源码重建到临时目录,与入库产物逐字节比对
npm run check:lib 在产物缺失、多余或内容不同时以非零码退出并列出差异文件,用来在提交前拦住漂移。
自检脚本
两个脚本都读 lib/ 产物,所以要在 npm run build 之后跑:
node scripts/changes-self-check.mjs # 「变更」视图的 git 管线(status/diff-tree/submodule)
node scripts/merge-self-check.mjs # worktree 合并状态判定(分支级快查 + detached HEAD 单点判定)
用法
1. 启动 dsh Web UI
2. 在任务启动窗口中,找到工作区选择器附近的“Worktree”按钮
3. 点击它打开 worktree 下拉菜单——它会扫描所有已注册的工作区,并按仓库对 worktree 分组
4. 选择现有 worktree:展开某个仓库分组,然后点击一个 worktree 切换到它
5. 过滤:在搜索框中输入内容,可按名称、分支或路径匹配所有仓库中的 worktree
6. 创建新 worktree:从选择器中选择目标仓库(默认为当前仓库),输入新分支名称,然后点击“创建”
所选/创建的 worktree 目录会被注册为 dsh 工作区,侧边栏会切换到它。
合并状态配色
分组开启后,侧边栏里每个 worktree 行的分支徽标会体现它是否已经合回主干:
- 基准分支 = 该仓库主工作树当前检出的分支(/api/topology 的 mainBranch)。主工作树自身是基准,不参与判定,保持蓝色。
- 判定方式 = 该 worktree 分支的 tip 是否可从基准到达,即完全合并(git branch --merged );detached HEAD 的 worktree 改用其 HEAD 提交做单点祖先判定(git merge-base --is-ancestor)。合并后又有新提交的算未合并。
- 绿色 = 已合并到基准;蓝色 = 未合并。
- 徽标的 hover 提示会写明 已合并到 / 未合并到 。
- 判不出来时(基准不存在,例如主工作树处于 detached HEAD)不在 /api/topology 的 worktree 行上给 merged 字段:徽标保持蓝色,但提示只显示分支名,不会被误报成「未合并」。
判定在宿主侧完成(/api/topology 的 worktrees[].merged),客户端只负责取色,因此拓扑刷新时状态会一起更新。
API Reference
GET /plugins/dsh-worktree-manager/api/list
Query parameters: repoPath (required)
Returns:
{
"worktrees": [
{
"path": "/repo/main",
"head": "abc123...",
"branch": "main",
"bare": false,
"locked": false,
"prunable": false
}
]
}
GET /plugins/dsh-worktree-manager/api/topology
No parameters. Scans every registered dsh workspace, resolves its git repository root via git rev-parse --git-common-dir (so linked worktrees group under their main worktree), and returns one entry per distinct root — repo discovery, per-repo worktree lists and merge status all in one response.
{
"repos": [
{
"root": "/path/to/repo",
"name": "repo",
"mainBranch": "main",
"worktrees": [
{ "path": "/path/to/repo-worktrees/feature", "branch": "feature", "merged": true, "locked": true }
],
"workspaces": [
{ "id": "ws-uuid", "path": "/path/to/repo", "title": "repo" },
{ "id": "ws-uuid-2", "path": "/path/to/repo-worktrees/feature", "title": "feature" }
]
}
]
}
worktrees lists only linked worktrees (the main worktree is root itself); merged is absent when the host could not decide (e.g. the main worktree is on detached HEAD). locked/prunable are present only when set, for dropdown badges.
GET /plugins/dsh-worktree-manager/api/changes
Query parameters: path (required, any directory inside the repo/worktree)
Returns the working-tree changes of the containing worktree. Submodule pointer rows are excluded from files and reported per submodule instead; each submodule's own working-tree changes are listed file-level.
{
"root": "/path/to/worktree",
"branch": "main",
"files": [{ "code": "??", "path": "new.txt" }],
"submodules": [
{
"path": "sub",
"name": "sub",
"newCommits": true,
"uninitialized": false,
"files": [{ "code": " M", "path": "a.txt" }]
}
]
}
GET /plugins/dsh-worktree-manager/api/history
Query parameters: path (required), limit (optional, 1–200, default 50)
Returns { root, branch?, commits: [{ hash, subject, author, date }] } (date = epoch ms). Empty commits for a repository with no commits yet.
GET /plugins/dsh-worktree-manager/api/commit
Query parameters: path (required), hash (required, commit hash), sub (optional, submodule path relative to the worktree root)
返回一个提交的变更文件。子模块指针行会变成 submodules 条目,列出旧指针和新指针之间的子模块提交(git -C log old..new)。使用 sub 时,hash 改为指代该子模块内的某个提交——处理程序会在子模块内运行 git diff-tree,并只返回该提交的 files(submodules 为空)。
{
"files": [{ "code": "M", "path": "f.txt" }],
"submodules": [{ "path": "sub", "name": "sub", "commits": ["abc1234 sub change"] }]
}
GET /plugins/dsh-worktree-manager/api/diff
查询参数:path(必填)、file(必填,相对于仓库)、sub(可选,文件所在的子模块相对目录)、hash(可选,提交哈希)
返回 { diff }——单个文件的统一差异。带 hash 时,返回该提交对该文件的差异;否则返回工作区与 HEAD 的差异(已暂存 + 未暂存)。未跟踪文件回退为 /dev/null 伪差异。file/sub 必须位于工作区内(绝对路径和 .. 片段会被拒绝)。
POST /plugins/dsh-worktree-manager/api/create
请求体:
{
"repoPath": "/path/to/repo",
"branch": "feature/my-feature",
"newBranch": true,
"targetPath": "/path/to/worktree"
}
返回创建的工作区信息以及 dsh 工作区 ID。
POST /plugins/dsh-worktree-manager/api/remove
请求体:
{
"worktreePath": "/path/to/worktree",
"force": false
}
从其主工作区中删除该工作区,并注销为其注册的 dsh 工作区(如果有)。
POST /plugins/dsh-worktree-manager/api/branches
请求体:
{
"repoPath": "/path/to/repo"
}
返回 { "branches": ["main", "develop", ...], "current": "main" }。
许可证
MIT