dsh-parallel-worktree

DSH PLUGIN开发与运行时

仓库 wang-yi-bit64/dsh-parallel-worktree · npm dsh-parallel-worktree

开发与运行时 L5 · 运行验证通过 安全审查:低风险 可信度:金 可安装插件
安装这个插件

为 DeepSeek Harness 补齐多分支并行开发能力:每个任务独立 git worktree,配套注册表、环境引导与同步合并清理闭环。

一句话选型结论

按资料字段整理

dsh-parallel-worktree 是开发与运行时类的 DSH 可安装插件,验证等级 L5 · 运行验证通过,安全审查为低风险,列出 5 项功能,有可直接复制的安装命令。验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么;涉及密钥或系统权限的,建议先在隔离环境试装。

分类开发与运行时 收录类型可安装插件 验证等级L5 · 运行验证通过 安全审查低风险
验证等级 L5 L5 · 运行验证通过
GitHub 星标 1 复刻 0 · 未关闭 issue 0
最近更新 2026-11-04 创建于 2026-11-03
README 41.4 KB 正文体量,越大说明说明书写得越细

安装

可安装插件
在 DSH 里执行,装完用 dsh plugin list 确认已挂上;标了 L4 / L5 的命令已在沙盒里真实跑通
dsh plugin --profile web add github:wang-yi-bit64/dsh-parallel-worktree
  1. 1
    确认版本与运行环境

    兼容的 DSH 版本为 0.2.2-rc.1,Node.js 要求 >=20;版本不匹配时安装会报错。

  2. 2
    执行安装命令

    在 DSH 里执行上面的命令;多包仓库要注意区分具体子包名,别装错包。

  3. 3
    确认已挂载

    用 dsh plugin list 查看列表里是否出现这个插件,出现即挂载成功。

  4. 4
    试跑并检查权限

    加载后跑一个最小用例,确认它能正常工作;同时看它申请了哪些文件、命令或网络权限。

兼容 DSH 版本0.2.2-rc.1版本不匹配时安装会报错
Node.js 要求>=20来自仓库 package.json 的 engines 字段
前置依赖@deepseek-ai/cordis@~4.0.5 || ~4.0.6-alpha.1 || ~4.1.0、@deepseek-ai/dsh-tools@^0.2.1-rc.4 || ^0.2.2-alpha.2需要同时安装的同级依赖
npm 包名dsh-parallel-worktree可用 npm view 查看包信息

能做什么

5 项功能
字段来自项目仓库与公开索引,中文说明由本站标注

dsh-parallel-worktree:为 DeepSeek Harness 提供多分支并行开发的 worktree 管理

  • /worktree 命令管理并行检出
  • worktree_create/list/status 工具
  • composer dock 只读面板
  • 自动复制 .env 与复用 node_modules
  • 同步、合并、清理收尾闭环

适用场景

GitHub 集成文件读写

上游标签

cordisdshdsh-plugingitgit-worktree

验证等级与安全审查

L5 · 运行验证通过
自动化流程结论,不是人工审核
验证等级L5 · 运行验证通过在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来
安全审查低风险静态分析结论,未标注不代表已通过审查
仓库健康度活跃按仓库活跃度与最近更新时间给出
可信度金综合仓库活跃度与验证结果

上面的结论来自上游最近一次自动化验证(2026-11-10): 同一套检查会在插件发新版后重跑,页面显示的是最新一次的逐项结果。

逐项检查结果

L1 · 已找到 ✓ 通过
  • L1.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L2 · 结构化 ✓ 通过
  • L2.0_DEFAULTED_FROM_L3 由 L3 推定 默认通过——L3 安装规范已通过(全库 L3 扫描策略)
L3 · 安装规范 ✓ 通过
  • L3.1_INSTALL_COMMAND_PARSED 安装命令已解析 方式:安装规范解析
  • L3.2_DSH_VERSION_DECLARED DSH 版本已声明 方式:DSH 版本声明
L4 · 安装已测 ✓ 通过
  • L4.1_INSTALL_EXECUTED_CONFINED 受限沙盒内执行安装 方式:沙盒安装执行
  • L4.2_INSTALL_SUCCESS 沙盒安装成功 方式:沙盒安装执行
  • L4.3_ARTIFACT_CONFIRMED 安装产物已确认 方式:沙盒安装执行
L5 · 运行已测 ✓ 通过
  • L5.1_INSTALL_PASSED_SANDBOXED 沙盒安装通过 方式:沙盒安装执行
  • L5.2_WEB_BOOT_READY Web 启动就绪 方式:Web 启动
  • L5.3_HTTP_SERVED HTTP 服务响应 方式:HTTP 请求
  • L5.4_PLUGIN_INVENTORY_ACTIVE 插件清单中已激活 方式:插件清单查询

风险详情

  • 结论说明 静态扫描 低;动态审计无结论(以下以静态为准)→ 总评级 低。
  • 风险计数 严重 0 / 高 0

选择建议

装之前先看这几条
按条目字段给出的判断,不替你决定用不用

值得选的地方

  • 验证等级 L5:安装和运行都在沙盒里跑通过,装完能直接用的概率高。
  • 静态安全审查为低风险,没有发现明显可疑行为。
  • 有可直接复制的安装命令,不用自己翻文档找入口。
  • 标注了兼容的 DSH 版本(0.2.2-rc.1),按版本装不容易报错。
  • 列出了 5 项功能,能直接看出它解决什么问题。

先想清楚的地方

  • 需要同时装好同级依赖,漏装会启动失败。
  • 验证通过不等于安全:插件会读写文件、执行命令或联网,装前先到仓库确认它做了什么。

更适合

  • 需要在开发与运行时场景里给 DSH 补能力的人。
  • 想装完就能用、不想自己排依赖的人。
  • 能接受在本地装依赖、愿意自己确认权限的人。

不太适合

  • 只使用 DSH 官方内置能力、不接受第三方插件的人。

同类对比

6 个同类
同分类里挑最接近的几条,字段以各自详情页为准
插件验证等级安全审查星标兼容版本安装命令
dsh-parallel-worktree当前 L5 · 运行验证通过 低风险 1 0.2.2-rc.1 有
deepseek-harness L3 · 安装规范通过 低风险 24.6 万 未标注 无
rea L4 · 沙盒安装通过 低风险 2.6 万 0.1.1-rc.2 有
dsh-TUI L4 · 沙盒安装通过 中风险 4,292 0.1.7-rc.2 等 5 个 有
mirage L3 · 安装规范通过 低风险 3,681 未标注 无
dashi-taskboard L4 · 沙盒安装通过 低风险 3,311 0.1.1-rc.2 有

仓库档案

开发与运行时
字段来自项目仓库与公开索引,中文说明由本站标注
作者 / 维护方wang-yi-bit64仓库 dsh-parallel-worktree · 默认分支 main
分类开发与运行时dev
收录类型可安装插件声明了 dsh.bundle、可用 dsh plugin add 安装的条目
开发语言JavaScript仓库主语言
许可证MIT商用或二次分发前请确认条款原文
星标 / 复刻 / issue1 / 0 / 0收录时的数值,非实时
创建 / 更新2026-11-03 · 2026-11-04最后推送 2026-11-15
本站收录2026-11-03首次进入本站目录的时间

README 全文

41.4 KB
作者原文,中文版优先;只做安全转义,不改内容

dsh-parallel-worktree

给 DSH 加上「多分支并行开发」能力的插件:为每个任务开一个独立的 git worktree,让多个 Agent / 多个终端在同一仓库上并行干活,互不污染。

它补的是 DSH 内置 create_worktree 之外的一层工程化:内置工具只负责「建一个检出」,这个插件负责注册表、布局约定、环境引导、同步/合并/清理的收尾闭环,以及一条给人类用的 /worktree 命令。

> 本文件是中文主文档。英文版见 README.en.md。


界面与可见性

插件装好并重启 DSH Desktop 后,打开 设置 → 插件,插件列表里会出现本插件的卡片:

  • 标题:中文界面显示「并行 Worktree(多分支并行开发)」,英文界面显示 Parallel Worktrees;
  • 描述:一句话说明能力边界(同样分中英文两份);
  • 图标:随包分发的 icon.svg,原创几何图形(一条基线 + 三个并行检出),用 currentColor 绘制,深色/浅色主题下都清楚。

这三样分别来自包内的 locale/zh.json、locale/en.json 和 icon.svg。DSH 的插件管理器/插件列表无需激活插件就会读取它们,所以即使插件还没启用,也能在列表里认出它是干什么的。任一字段缺失时会回退成 package.json 的 name / description;字段格式错误会在插件详情里显示一条诊断,而不是让整张卡片消失。

客户端半边(同一插件包里的 client 部分)在会话界面提供两块 UI:

  • Dock 徽标:在会话输入框下方的 composer dock 里始终显示。会话落在受管 worktree 内时是「⛛ <名字> <分支>」;不在 worktree 内时是「⛛ 并行 worktree」(仓库里有几个 worktree 就在后面跟一个数字),点开面板仍能看到该仓库的全部 worktree——所以它同时是入口,不是只在特定目录才出现的东西;
  • worktree 面板:点开徽标后向上弹出,列出该仓库全部 worktree,每行是名字 / 分支 / state / 是否脏 / 领先(↑n)/ 落后(↓n) / 是否「当前」/ 完整路径,行内有一个「复制路径」按钮;顶部只有「刷新」与「关闭」。当前目录不是 git 仓库时,面板里显示一行说明而不是空白。

面板只读:数据只走 /worktree status --json(挂载时一次)与 /worktree list --json(点开与刷新时各一次),没有轮询;面板里也没有新建、移除、合并入口——写操作按设计只留在 /worktree 命令与模型工具里(避免在 UI 里误点丢掉未提交改动)。面板、命令与工具读的是同一套管理器与同一份 registry.json,所以展示的永远是一份数据。

为什么需要它

内置 create_worktree 会把检出放进仓库内的 .agents/worktrees/,并且只做创建一步。实际并行开发时你会反复遇到:

  • 检出目录散落在仓库里,git status 被污染,要手工维护 .gitignore;
  • 不知道现在开了哪些分支、各自脏不脏、领先/落后主分支多少;
  • 新建的 worktree 没有 .env,node_modules 要重装;
  • 主分支上还有未提交的改动,新 worktree 拿不到,还得手工 stash/patch;
  • 收尾时要自己 merge、删目录、删分支,顺序错了留下烂摊子。

这个插件把上面这些变成可查询、可重复执行的操作。

功能

  • 创建:worktree_create 工具 + /worktree create 命令,自动 git worktree add、建分支、写注册表。
  • 布局:默认把 worktree 放在仓库外的兄弟目录 .wt/,主仓库永远干净;也可选择 inside(/.worktrees/,自动维护 .gitignore)。
  • 环境引导:可选把主仓库的未提交改动(git diff --binary + apply --3way)和未跟踪文件带进新 worktree;自动复制 .env/.env.local;可 junction/symlink 复用 node_modules(Windows 用 junction,不需要管理员权限)。
  • 可见性:worktree_list 给出一张表——分支、路径、是否还在、是否脏、HEAD、领先/落后基线多少。
  • 同步:/worktree sync 把基线合进来(默认 rebase --autostash,可切 merge),冲突自动 abort 并报 MERGE_CONFLICT。
  • 合并收尾:/worktree merge 在主仓库 merge --no-ff,可选 --remove 删检出、--delete-branch 删分支;主仓库脏或 HEAD 分离会直接拒绝。
  • 清理:/worktree remove(脏目录需 --force)、/worktree prune(清掉目录已消失的注册项)。
  • 并发安全:注册表写入用 tmp + rename 原子替换,跨进程用 registry.lock 文件锁;batch 一次建多个也走同一把锁。

版本与发布状态

两个发布渠道的进度不一样,能装到的版本也不一样:

渠道 最新版本 说明
npm dsh-parallel-worktree 0.2.3(latest,2026-11-15 发布) npm 上依次发布过 0.2.0、0.2.1、0.2.2、0.2.3(0.0.0-stage 是早期占位预发布,latest 不指向它)。0.2.3 修复 DSH 0.2.2-rc.3 上 dock chip 不渲染的崩溃,并让 install.mjs 装完即出现在「设置 → 插件」
GitHub Releases v0.2.3(2026-11-15 发布) 已发布 v0.2.3 Release,条目自带源码 tarball/zip(GitHub 自动生成);此前最新为 v0.2.2

仓库里 package.json 的 version 就是 0.2.3,与 npm、GitHub 两侧的 0.2.3 对应;publish.yml 由 v* tag 触发发 npm,GitHub Release 由单独的 gh release create 创建。

所以:两个渠道都能拿到 0.2.3——按下面的 A 从 npm 装,或从 GitHub Release v0.2.3 下载源码包后走 B 的 install.mjs。想直接跟仓库 main 上的未发布提交,用 git 地址安装(同样要确认 dsh.profile.bundles 里有这个包名):

dsh plugin --profile desktop add github:wang-yi-bit64/dsh-parallel-worktree

安装

DSH 插件激活看同一个包的三件事:包声明了 dsh.bundle(本包自带 cordis.patch.yml)、包名出现在 profile 的 dsh.profile.bundles 里、包文件能被 DSH 从 node_modules 解析到。按「包文件交给谁管」分两条路线,选一条装。

A. 从 npm 安装(推荐;npm 上的最新版就是 0.2.3)

在 DSH 里:设置 → 插件 → 添加插件(箭头菜单里还有「安装第三方插件」,可填包名、Git 仓库或本地目录),输入包名 dsh-parallel-worktree 确认即可。插件管理器会在 profile 目录里跑 pnpm add,把包写进 /package.json 的 dependencies(精确版本,当前 0.2.3),并自动登记到 dsh.profile.bundles;装完显示 pnpm 实际装的版本号。

命令行等价操作是两步——dsh plugin 只是把参数转发给 profile 目录里的 pnpm,它不改 bundles:

dsh plugin --profile desktop add dsh-parallel-worktree    # 在 profile 里 pnpm add

然后把包名加进 /package.json 的 dsh.profile.bundles:

{ &quot;dsh&quot;: { &quot;profile&quot;: { &quot;bundles&quot;: [&quot;...&quot;, &quot;dsh-parallel-worktree&quot;] } } }

这条路线里包文件在 /node_modules/dsh-parallel-worktree,由 pnpm 管:它是写进 dependencies 的真依赖,插件管理器再跑多少次 pnpm install 都不会把它当多余目录删掉。

B. 从源码目录安装(install.mjs,不走 pnpm)

离线、没有 npm 网络,或不想让 profile 的 pnpm 工程管这个包时,用包里自带的安装脚本:

# 在插件目录(仓库根)执行
node install.mjs                    # 装进 %USERPROFILE%\.dsh\profiles\desktop
node install.mjs --dry-run          # 只看计划,不写文件
node install.mjs --profile desktop  # 指定其它 profile(名字或目录都行)
node install.mjs --no-deps          # 旧行为:不进插件管理器列表,只有 DSH_HOME 副本

脚本做三件事:

  1. 预检插件自身能否被当作 bundle 加载(dsh.bundle.patch 指向的 cordis.patch.yml 必须存在且在插件目录内);
  2. 把插件文件复制到 /node_modules/dsh-parallel-worktree(主副本),并把 dsh-parallel-worktree 写进 profile package.json 的 dependencies(精确版本)+ 追加进 dsh.profile.bundles——这三样正是「设置 → 插件」卡片列表的读取契约,装完卡片就会出现;
  3. 往 /node_modules/dsh-parallel-worktree 再放一份兜底副本。

为什么要两份? 主副本让插件管理器能列出、能启停(readProfilePlugins 从 dependencies + /node_modules 读);兜底副本防的是 pnpm 重算:万一插件管理器跑了 pnpm install 把 profile 里的目录当多余文件清掉(手工写 dependencies 而不跑 pnpm 时,lockfile 与目录对不上就会发生),bundle 解析仍能从 ~\.dsh\node_modules 这个上级目录命中——插件退化为「不在列表但照常工作」,而不是启动就报:

dsh: cannot resolve profile bundle &quot;dsh-parallel-worktree&quot; from the dsh installation or ; run &#x27;dsh plugin --profile  install&#x27; if its dependency is not installed

~\.dsh\node_modules 是 Node 解析 node_modules 时的上级目录,DSH 的 app-boot 用 require.resolve.paths() 从上往下找,放这里一样能被找到,而 pnpm 从不管理它——应用内更新插件、跑多少次 pnpm install 都不会删。(路线 A 恰好相反:只有一份,必须写进 dependencies 才留得住。)

改 package.json 前会备份成 package.json.bak-&lt;时间戳&gt;,写入失败自动回滚。--no-bundles 只复制文件不改 bundles,--force 跳过同版本提示,--no-deps 回退旧行为(不出现在插件管理器列表)。复制时会带上 locale/、icon.svg 与全部运行期文件——插件列表里的标题、描述、图标依赖它们,缺一个卡片就会退化成包名。

手工往 dependencies 加这个包时版本号必须与 npm view dsh-parallel-worktree version 一致(pnpm 重算时按 registry 的同名包对账);用脚本装则不用管这条,版本号取自本地 package.json。

装完必须完全退出并重启 DSH Desktop(关窗口不算),profile 在启动时 compose;profile 目录在桌面运行期带写锁,安装脚本应在桌面退出后执行。

验证:在任意 git 仓库的会话里执行 /worktree help,能看到子命令列表即注册成功(/worktree help 不依赖任何 git 状态,/worktree list 才需要仓库)。若命令没出现,看 /.plugin-manager/logs 里最近的日志——常见失败是 ERR_MODULE_NOT_FOUND ... imported from /(包文件没装到位)和 declares no dsh.bundle(dsh.bundle.patch 缺失)。

一分钟上手

两条路,任选一条。

A. 直接用斜杠命令

在仓库(主工作区,或已存在的某个 worktree)里,任意会话输入:

/worktree create feature/login
/worktree list
/worktree path feature/login

create 的典型输出:

✓ 已创建 worktree feature/login
分支   wt/feature/login
路径   D:\code\portal.wt\feature\login
起点   main @ 4f3c9a1b
注册表 D:\code\portal.wt\registry.json

在终端 cd 到上面的路径,或在新会话里把它设为工作目录;该目录的改动与主工作区隔离。

拿到路径后:cd 过去开终端,或在 DSH 里新建会话并把工作目录设为它。list 给出总表,path 只打印路径(方便复制)。

B. 让 AI 来做

同一件事用对话表达(可以直接粘贴):

帮我为「登录页改版」开一个独立的 worktree:从 main 拉,名字用 feature/login,
并把主工作区当前未提交的改动一起带过去。之后所有改动都只在这个目录里做。

Agent 会调用 worktree_create:

{ &quot;name&quot;: &quot;feature/login&quot;, &quot;base&quot;: &quot;main&quot;, &quot;carryUncommitted&quot;: true }

返回结果(节选,实际是 JSON 文本):

{
&quot;name&quot;: &quot;feature/login&quot;,
&quot;branch&quot;: &quot;wt/feature/login&quot;,
&quot;path&quot;: &quot;D:\\code\\portal.wt\\feature\\login&quot;,
&quot;repoRoot&quot;: &quot;D:\\code\\portal&quot;,
&quot;baseCommit&quot;: &quot;4f3c9a1b...&quot;,
&quot;createdAt&quot;: &quot;2026-11-03T06:12:40.000Z&quot;,
&quot;manifestPath&quot;: &quot;D:\\code\\portal.wt\\registry.json&quot;,
&quot;warnings&quot;: []
}

Agent 拿到 path 后会把工作目录切到该目录再改文件(切换动作由会话自己完成,插件不改会话工作目录)。

用法示例:五个场景

每个例子都是「你对 Agent 说什么 → Agent 调什么 → 结果长什么样」。合并、删除这类收尾动作没有模型工具,需要你自己敲命令。

1. 开一个新任务

你:开个 worktree 做支付重试,名字 feature/pay-retry,基线用 release/1.8,
依赖直接复用主仓库的 node_modules,别重新装。
Agent:worktree_create({ name: &quot;feature/pay-retry&quot;, base: &quot;release/1.8&quot;, linkNodeModules: true })

结果:新检出 .wt/feature/pay-retry,分支 wt/feature/pay-retry,起点是 release/1.8 的提交;node_modules 以 junction 链到主仓库,秒级可用。

2. 查看全部 worktree

你:这个仓库现在开了哪些 worktree?谁有未提交改动、谁落后 main?
Agent:worktree_list({})

返回里 worktrees 是数组,每项含 name / branch / path / state / exists / dirty / head / ahead / behind;ahead 是相对基线的领先提交数,behind 是落后数。state 为 active(正常)/ merged(已合并)/ missing(目录已丢失,可 /worktree prune)。

3. 切到某个 worktree 里干活

你:我要改 feature/login 那个检出,帮我把会话工作目录切过去。
Agent:worktree_status({ name: &quot;feature/login&quot; })  → 拿到 path
Agent:(切换会话工作目录后)现在在这个目录里,状态:干净、领先 2 / 落后 0。

不值当开新会话时,也可以 /worktree path feature/login 拿到路径自己 cd。

4. 同步基线

你:feature/login 落后 main 了,把最新 main 同步进去;有冲突就停下告诉我。
(人类命令,Agent 不能代执行)
/worktree sync feature/login --base main

输出:✓ 已把 main 同步进 worktree feature/login(rebase),附 BASE 4f3c9a1b / HEAD 9a12e77c;同步前有未提交改动时会多一行 注意:同步前存在未提交改动(rebase 已自动 autostash)。真冲突会自动 abort 并报 MERGE_CONFLICT,worktree 停在同步前的状态。

5. 合并收尾并清理

你:feature/login 测完了,合进 main,然后把检出和分支都删掉。
/worktree merge feature/login --base main --remove --delete-branch

输出:✓ 已把 wt/feature/login 合并进 main + 合并提交 SHA + checkout 已移除 + 分支 已删除;如果当时主工作区不在 main 上,还会多一行 主工作区已从 &lt;旧分支&gt; 切换到 main。删完后 /worktree list 里就没有它了。

命令参考

/worktree 子命令

子命令 别名 参数 作用 输出要点
create new [--base ] [--carry] [--link] [--no-env] 新建隔离检出 + 分支 + 注册表 ✓ 已创建 worktree、分支、路径、起点 @、注册表路径;有警告时列在 警告: 下
batch — ... [--base ] 依次创建,逐项收集失败 批量创建:成功 N,失败 M;每行 ✓ 名字 → 分支 路径 或 ✗ 名字 [CODE] 消息;有失败时整条按 error 返回
list ls — 表格列出全部 worktree 表头 # 名字 分支 状态 脏 HEAD 领先/落后 路径;首次使用会提示「还没有注册任何 worktree」
status st [name] 查看指定项,或当前会话所在项 worktree + 分支/路径/状态/脏/HEAD/相对主干 领先 X / 落后 Y/创建于;不在受管理目录时给出仓库与根目录
path — `` 只打印检出目录,便于复制 / cd 一行绝对路径
sync — [--base ] [--merge\|--rebase] 把基线同步进 worktree ✓ 已把 同步进 worktree () + BASE/HEAD;冲突自动 abort
merge — [--base ] [--message ] [--remove] [--delete-branch] 在主工作区 merge --no-ff 合并提交 SHA + 是否切换主工作区 + 检出/分支的去留;默认两者都保留
remove rm [--force\|-f] [--delete-branch] 移除检出(可选删分支) 路径 + 分支去留;脏目录不加 --force 会拒绝
prune — — 清理「目录已消失」的注册项 ✓ 没有需要清理的注册项(保留 N 个),或逐条列出被清理项
help — —(空输入、-h、--help 同) 帮助 子命令速查

参数三种写法都认:--base main、--base=main、短选项 -f。参数按空格切分,含空格的值用引号包起来(--message &quot;fix: login redirect&quot;)。

merge 默认保留检出和分支(先确认再删更安全);要一步收尾就显式加 --remove --delete-branch。

--json:结构化输出

任意子命令都可加 --json(简写 -j),把结果作为一行 JSON 文本返回,供客户端面板与脚本解析;它只改变输出格式,不改变任何行为或权限。

成功统一是 { &quot;ok&quot;: true, &quot;action&quot;: &quot;&lt;子命令&gt;&quot;, ... },各 action 的字段:

action 字段
create name、branch、path、baseRef、baseCommit、repoRoot、wtRoot、manifestPath、warnings[]
batch created[](name / branch / path)、failed[](name / code / message)
list repoRoot、wtRoot、layout、baseBranch(探测不到为 null)、registry、worktrees[](字段与 worktree_list 工具一致)
status repoRoot、wtRoot、layout、baseBranch(探测不到为 null)、inWorktree、worktree(不在受管理目录时为 null)
path name、path
sync name、branch、path、base、baseCommit、head、mode、dirtyBefore
merge name、branch、base、mergeCommit、switchedFrom、removed、branchDeleted、note
remove name、path、branch、deletedBranch、dirty
prune pruned[](name / path)、kept

status 的 inWorktree=true 表示当前会话的工作目录落在某个受管 worktree 内(客户端 Dock 徽标就是靠它判断的);此时 worktree 是那一项的详情,在主工作区或未注册目录里则为 null。

失败时结果按 error 返回,文本是 {&quot;ok&quot;:false,&quot;code&quot;:&quot;...&quot;,&quot;message&quot;:&quot;...&quot;,&quot;hint&quot;:&quot;...&quot; 或 null}:code 与错误码表一致(如 NOT_GIT_REPO、WORKTREE_NOT_FOUND、NAME_REQUIRED),未知子命令是 UNKNOWN_SUBCOMMAND。batch 部分失败也仍返回 ok: true,失败项在 failed[] 里。

两个注意点:/worktree 是人类命令面,模型拿不到它——--json 只是输出格式,不会把命令能力开放给模型;JSON 仍走普通文本通道(kind 保持 success / error),所以旧宿主与既有解析逻辑都兼容。

三个模型工具

工具 参数 说明
worktree_create name(必填)、base、carryUncommitted、linkNodeModules、copyEnv 新建 worktree,返回新检出信息与警告
worktree_list 无 列出当前仓库全部 worktree 与状态
worktree_status name(可选) 查当前会话所在或指定 worktree;不在任何受管理 worktree 时 inWorktree 为 false

参数细节:

参数 类型 默认 含义
name string,必填 — worktree 名,同时决定路径与分支名(默认分支 wt/)。可含 / 分层,如 feature/login;每段由字母/数字/. _ - 组成,首字符为字母或数字;禁止 ..、反斜杠、空格以及 ~ ^ : ? * [ ] @ { };总长 ≤100
base string 主仓库当前分支(配置了 baseBranch 则用配置) 起点 ref:分支、提交或 tag
carryUncommitted boolean false 把主工作区未提交改动(git diff --binary 走 apply --3way)和未跟踪文件带进新检出;跳过 node_modules/ 与 .git/
linkNodeModules boolean 插件配置(默认 false) 把主仓库 node_modules 以链接挂进新检出(Windows 用 junction,无需管理员权限)
copyEnv boolean true 复制插件配置的环境文件(默认 .env、.env.local)

worktree_create 返回字段:

字段 含义
name / branch / path worktree 名 / 新建分支(wt/)/ 检出目录绝对路径
repoRoot 主仓库根目录
baseCommit 起点提交 SHA(完整)
createdAt 创建时间(ISO 8601)
manifestPath 注册表 registry.json 路径
warnings 警告数组(如 --link 建立链接失败会降级成警告,不阻塞创建)

worktree_list 返回 repoRoot、wtRoot(worktree 根目录)、layout(sibling/inside)、baseBranch(探测到的基线,可能缺失)、registry(注册表路径),以及 worktrees[],每项:

字段 含义
name / branch / path 名字 / 分支 / 检出目录
state active | merged | missing
exists 目录当前是否存在
dirty 是否有未提交改动
head 当前 HEAD 短 SHA(可能缺失)
ahead / behind 相对基线领先 / 落后提交数
baseCommit / createdAt / lastSyncAt 创建时的基线提交、创建时间、最近同步时间(可能缺失)

worktree_status 返回 repoRoot、layout、inWorktree(布尔),以及可选的 worktree:name / branch / path / state / exists / dirty / head / ahead / behind / baseCommit。worktree 缺失即表示当前在主工作区或未注册目录。

三个工具的渲染都是原始 JSON(单行文本块),没有额外美化——字段名本身是稳定契约。

典型并行节奏

/worktree create feature/auth
/worktree create feature/pay
/worktree list                     # 看谁脏、谁落后
/worktree sync feature/auth --base main
/worktree merge feature/auth --remove --delete-branch

配合 Agent Teams:每个 teammate 用 /worktree create 拿到自己的目录,在各自 worktree 里改文件,最后由你按顺序 merge;目录互不相交,不会出现共享工作区互相踩写的问题。

配置

配置来自 cordis.patch.yml 里插件行的 config(或在 profile patch 里按 id 覆盖):

- id: parallel-worktree
name: dsh-parallel-worktree
config:
layout: sibling          # sibling(仓库外 .wt/)| inside(/.worktrees/)
dirName: .worktrees      # layout=inside 时的目录名
siblingSuffix: .wt       # layout=sibling 时兄弟目录后缀
branchPrefix: &quot;wt/&quot;      # 新建分支前缀
baseBranch: main         # 未显式 --base 时的基线;不写则探测主仓库当前分支
syncMode: rebase         # rebase | merge
copyEnv: [&quot;.env&quot;, &quot;.env.local&quot;]
linkNodeModules: false
enabled: true

插件行本身长这样(cordis.patch.yml):

- insert:
- id: parallel-worktree
name: dsh-parallel-worktree

enabled: false 时插件整体跳过:不注册工具、不注册命令;插件列表里的卡片仍在(元数据是静态读的)。

目录与注册表

三种落点

检出放在哪儿由配置决定,共三条约定:

布局 触发条件 检出根目录 .gitignore
兄弟目录(默认) layout: sibling(默认) 与仓库同级的 .wt\,例如 D:\code\portal → D:\code\portal.wt\ 不用,它在仓库外
仓库内 layout: inside \.worktrees\(dirName 可改) 插件首次创建时把 # dsh-parallel-worktree 与 /.worktrees/ 追加进仓库根 .gitignore
自定义后缀 / 目录名 改 siblingSuffix 或 dirName 按上面两条规则推导 同对应行

要换落点:改配置里的 layout(或 siblingSuffix / dirName),然后删掉旧注册表再重建。注册表里记了创建时的 layout,配置与它不一致会报 LAYOUT_MISMATCH,提示里直接给出注册表路径和两种解法(改回旧 layout,或删注册表重来)。一个仓库只有一份注册表,所以一个仓库只能选一种布局。

D:\code\portal               # 主仓库
D:\code\portal.wt\            # 默认 wtRoot(仓库外,不进 git)
registry.json               # 注册表 v1:名字/分支/路径/基线/时间戳
registry.lock               # 跨进程写锁(短期存在)
feature\login\              # worktree 检出
fix\header\

名字里的 / 会映射成分层目录,所以 feature/login → feature\login。注册表记录基线提交、创建时间、最近同步/合并信息;prune 只清「目录已不存在」的项,不会动活着的 worktree。

layout: inside 时注册表就在 \.worktrees\registry.json,会随仓库走;代价是它属于仓库工作树的一部分,团队协作时要确认那行 .gitignore 已经提交。

与其它 worktree 能力的共存

DSH 里可能同时出现几类 worktree 能力,层次不同,混装前先看清各自注册了什么:

能力 提供方 对外注册 检出目录 改会话工作目录 注册表
本插件 dsh-parallel-worktree 工具 worktree_create / worktree_list / worktree_status,命令 /worktree 默认仓库外 .wt\,可配 inside 否 registry.json
内置 @deepseek-ai/dsh-experimental-tool-worktree(DSH 自带) 只有工具 create_worktree 仓库内 .agents/worktrees\ 是(建完把会话 cwd 切过去) 无
PR 评审 @deepseek-ai/dsh-experimental-forge-bundle(DSH 自带,即「变更请求与工作树」卡片) 会话侧栏跟踪 GitHub PR:检查状态、评审意见、代码差异、分支更新 不建检出 否 无
任务级 dsh-task-worktree(第三方) 也注册 /worktree(mode-on / mode-off / create / list / status / finish / bring-back / remove / prune) 按它自己的约定 否 每仓库 manifest
视图 @cerbur/clutch-dsh-worktree(第三方) 只加一个 Worktree 视图(按 worktree 给会话分组) 不建目录 否 无

与内置 create_worktree:不冲突,可以同时装。 工具名不同(create_worktree vs worktree_create)。区别在于:内置工具建完把当前会话的工作目录切到新检出(省一步),检出在仓库内、没有注册表;本插件不改会话目录,靠返回的 path 或 /worktree path 自己切,换来注册表、仓库外布局、环境引导与收尾闭环。临时开个洞用内置就够,长期并行任务用本插件;两者混用也没问题。

与官方「变更请求与工作树」(dsh-experimental-forge-bundle,DSH 0.2.2-rc.1 起):不冲突,方向不同,可以同时装。 名字里都有「工作树」,但它走的是 PR 评审视角——在会话侧栏集中跟踪已存在的 GitHub PR(检查状态、评审意见、代码差异、重跑失败检查、请求评审、更新分支),不创建任何检出;本插件走的是 本地编排视角——创建/列出/同步/合并/清理本地 git worktree,不碰 PR。一个管「改动在远端被评审」,一个管「改动在本地并行生长」;混用时你在本插件开的检出里干活,推送后它的卡片接手跟踪 PR。

与 @cerbur/clutch-dsh-worktree:不冲突。 它只做展示层(按 worktree 给会话分组),不创建、不修改 worktree,也没有命令;本插件负责操作层。同时装时,视图里能看到你用本插件建的检出。

与 dsh-task-worktree:会冲突。 它也注册名为 worktree 的斜杠命令,而命令名在 DSH 里全局唯一。两个插件都加载时,后注册的那个抛错并加载失败:

command &quot;worktree&quot; is already registered (for a per-agent variant, mount a command-injected plugin under that agent&#x27;s `agent.ctx`)

症状:/worktree 仍然可用,但子命令集与本文档不一致——出现 mode-on、finish、bring-back 之类。排查办法:

  1. 打开 设置 → 插件,看是否有加载失败/诊断提示;
  2. 看 /package.json 的 dsh.profile.bundles 顺序——先出现的先注册;
  3. 只保留一个:从 bundles 里去掉另一个,或直接卸载它,然后重启。

本机当前状态:dsh-task-worktree 装在 dependencies 里但不在 dsh.profile.bundles,所以它没有被加载,/worktree 属于本插件。

常见问题(FAQ)

启动报 cannot resolve profile bundle &quot;dsh-parallel-worktree&quot; 怎么办?

这是「包文件被 pnpm 当成多余目录删掉了」。profile 是 pnpm 工程,插件管理器跑 pnpm install 时,凡是不在 dependencies 里的目录都会被清理;把插件复制进 /node_modules 却没写 dependencies(比如手工拷贝)就会中招。

重跑安装脚本即可(主副本进 /node_modules 并写 dependencies,另在 /node_modules 放兜底副本,pnpm 不会碰那里):

node install.mjs --profile desktop --force

然后完全退出并重启 DSH Desktop。想确认装好了,检查:

Test-Path &quot;$env:USERPROFILE\.dsh\profiles\desktop\node_modules\dsh-parallel-worktree\package.json&quot;   # True 才对(主副本)
Test-Path &quot;$env:USERPROFILE\.dsh\node_modules\dsh-parallel-worktree\package.json&quot;   # True 才对(兜底副本)

也可以干脆改走 npm 路线:用插件面板安装,或 dsh plugin --profile desktop add dsh-parallel-worktree 之后把包名登记进 dsh.profile.bundles。这样包是 profile 的真依赖,pnpm 会把它当自己人,不会再被清掉。

1. 和 DSH 自带的 create_worktree 有什么区别?会不会打架

不打架(工具名不同)。内置工具只建检出、建完把当前会话目录切过去、目录在仓库内 .agents/worktrees/ 且没有注册表;本插件建检出 + 分支 + 注册表,目录默认在仓库外,也不接管会话目录。要「临时开一个洞」用内置够了;要「同时开三四个任务、知道谁脏谁落后、最后合回来」用本插件。

2. 我装了别的 worktree 插件,/worktree 子命令对不上

见上一节:多个插件注册同名 worktree 命令时只有一个生效。先用 /worktree help 反查当前生效的是谁的子命令集,然后只保留一个插件,重启。

3. 仓库不是 git 仓库,或我在子目录里执行

插件靠 git 定位仓库,必须处于某个 git 工作树内。不是仓库会报 NOT_GIT_REPO(提示「请先 git init 或进入已有仓库」)。在仓库的任意子目录执行都可以——它用 git rev-parse --git-common-dir 找主仓库根。在已存在的 worktree 里执行同样有效,注册表始终是主仓库那一份,不会变成「每个 worktree 各一份」。

4. 同一个分支能开两个 worktree 吗

不能,git 本身也不允许同名分支被两个检出同时持有。对应的三个错误码:

  • BRANCH_EXISTS:分支已存在 —— 换名字,或先 git branch -D;
  • PATH_EXISTS:目标目录已存在 —— 换名字,或先手动删目录;
  • NAME_EXISTS:注册表里已有同名项 —— 先 /worktree remove 再建。

5. 路径含空格、中文、在别的盘符,可以吗

可以。所有 git 调用都走 argv 数组(不经 shell 拼接),空格和中文不会丢。含空格的参数值在斜杠命令里用引号包起来即可(--message &quot;fix: login redirect&quot;)。跨盘同样可以建检出;但 node_modules 的链接依赖卷/文件系统能力,非 NTFS 或网络盘上可能失败——失败只记进 warnings,不会阻塞创建。

6. Windows 长路径(>260 字符)报错

git 与 Node 都受 Windows 传统 MAX_PATH 限制,表现为 GIT_FAILED 且底层是「找不到路径/无法创建文件」。两种解法:

  • 把检出根目录放在短路径:默认兄弟目录 .wt 会继承仓库名,仓库本身很深时容易超长;可改 siblingSuffix / dirName,或直接把仓库放浅(如 D:\code\portal);
  • 打开系统长路径支持:组策略 Computer Configuration → Administrative Templates → System → Filesystem → Enable Win32 long paths,或注册表 HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\LongPathsEnabled = 1,并保持 git 较新版本。

7. 用 --link 共用 node_modules 有什么坑

--link 把主仓库的 node_modules 链进新检出(Windows 用 junction,无需管理员权限),秒级可用。三个坑:

  • 共享:在任一侧 npm install / 改版本,另一侧立刻跟着变,容易出现「主工作区能跑、worktree 里跑不了」;
  • 工具兼容:增量构建、文件 watcher、部分 pnpm 配置对 junction 反应慢或报重复模块;
  • 删除顺序:先删掉链接本身再移除检出(cmd /c rmdir &lt;检出&gt;\node_modules 只删链接、不递归内容;不要用会递归的工具直接删),避免删除操作顺着链接走进主仓库。

需要独立依赖时不要 --link,在 worktree 内自己装(可先复制主仓库的 lock 文件)。

8. .gitignore 需要我手工加吗

默认布局(sibling)不用,检出在仓库外。只有 layout: inside 才需要,而插件首次创建时会自动在仓库根 .gitignore 追加:

# dsh-parallel-worktree
/.worktrees/

团队协作时把这行提交上去,否则别人会把检出目录看成一堆未跟踪文件。

9. profile 目录能搬走或改名吗

不能直接搬。DSH 在 profile 的 node_modules 下按包名解析插件,搬走后启动报 ERR_MODULE_NOT_FOUND。卸载后重装即可,worktree 数据不受影响(都在仓库里或仓库外,与 profile 无关)。

10. 卸载会不会删掉我的 worktree

不会。卸载只删包本身(install.mjs 装的两份:主副本 /node_modules/dsh-parallel-worktree 和兜底副本 /node_modules/dsh-parallel-worktree;npm 路线的那份在 /node_modules)与 dependencies、bundles 里的条目。worktree 目录、分支、registry.json 都留着,要清理用 /worktree remove / prune 或手工删。卸载后那些目录仍是正常 git 检出,分支也还在。

11. 为什么 AI 不能合并 / 删除,非要我自己敲命令

设计取舍:merge 改主分支、remove 会丢未提交改动、prune 改注册表——这些不可撤销或影响面大,只放在人类命令面;模型侧只有 create / list / status。这样 Agent 不会「顺手」把主分支或你的分支删掉。需要时可以让它把命令写好,你自己执行。

12. 为什么创建后会话工作目录没变

本插件不改会话工作目录(内置 create_worktree 会改)。拿 worktree_create 返回的 path 自己切,或先 /worktree path 拿到路径再 cd。

13. registry.json 能手工编辑吗

不建议。写入是原子替换 + 文件锁,手工改容易与 git 实际状态不一致(例如目录已删而注册表还在 → state: missing,用 /worktree prune 修)。JSON 损坏会报 MANIFEST_CORRUPT,修法是删掉 registry.json 重建(丢掉历史记录,worktree 目录本身不受影响)。

14. 一个仓库最多开多少 worktree

git 层面几乎没限制,约束在磁盘与依赖:每个检出都是独立文件树,node_modules 不要逐个复制(用 --link,或只在需要时安装)。

错误码

命令与工具失败时都会给出 ✗ &lt;消息&gt;,WorktreeError 还带一行 → 建议。按场景分类:

错误码 含义 典型处理
NO_CWD 拿不到会话工作目录 在某个目录里重开会话
NOT_GIT_REPO 不在 git 工作树内 git init 或进入已有仓库
LAYOUT_MISMATCH 注册表的布局与当前配置不一致 改回旧 layout,或删注册表重建
NO_REGISTRY 该仓库还没有注册表 先 /worktree create
NAME_REQUIRED 缺 name 补上名字
INVALID_NAME 名字不合法(..、空格、反斜杠、过长等) 按规则改名
INVALID_BRANCH 分支名不合法 检查 branchPrefix
NAME_EXISTS 注册表已有同名项 先 remove,或换名
PATH_EXISTS 目标目录已存在 换名或删目录
BRANCH_EXISTS 分支已存在 换名,或 git branch -D
BASE_NOT_RESOLVED 解析不了起点 / 基线 ref 确认 ref 存在,必要时 git fetch
GIT_FAILED git worktree add 失败 看消息里的 stderr(常见是长路径/权限)
WORKTREE_MISSING 注册表有、目录已不在 /worktree prune 清理
WORKTREE_NOT_FOUND 名字没注册 /worktree list 看现有名字
BASE_REQUIRED 同步/合并没给基线 --base 或配置 baseBranch
BASE_NOT_CHECKED_OUT 主仓库切不到目标基线 手动 git switch 后重试
BRANCH_MISSING worktree 的分支已不存在 /worktree prune 清理
DIRTY_MAIN 主工作区有未提交改动 先提交或 stash
DIRTY_WORKTREE worktree 有未提交改动 remove 加 --force(会丢弃改动);merge 同步先提交/stash
DETACHED_MAIN 主仓库 HEAD 分离 先 git switch
MERGE_CONFLICT rebase/merge 冲突,已自动 abort 在目标目录手动 rebase/merge 解冲突
MANIFEST_CORRUPT registry.json 损坏 删掉重建
LOCK_TIMEOUT 另一进程长期持有注册表锁 关闭另一个并发操作后重试

开发与测试

node install.mjs --dry-run      # 预检 + 打印安装计划
node --test test/manager.test.mjs test/schema.test.mjs test/tools.test.mjs test/cwd.test.mjs test/commands-json.test.mjs

当前 29 项测试:27 通过、0 失败、2 跳过(平台/宿主相关用例),耗时约 110 秒。测试不需要 DSH 桌面进程,纯 Node + 本机 git;会建临时仓库并在结束时清理。工具定义在解析不到宿主 @deepseek-ai/dsh-tools 时会降级到 lib/schema.js 的本地等价实现(参数校验规则一致,schema.test.mjs 覆盖)。

改代码后别忘了同步验证 locale 与图标:locale/*.json 必须是合法 JSON 且 meta.title / meta.description 均为非空字符串(空串会被宿主当成格式错误,整张卡片退化成诊断)。

卸载

先看这个包当初是怎么装的,卸载方式与安装路线一一对应。

A. npm / pnpm 装的(插件面板或 dsh plugin add)

dsh plugin --profile desktop remove dsh-parallel-worktree    # 在 profile 里 pnpm remove

这条命令会更新 /package.json 的 dependencies 与 pnpm-lock.yaml,并删掉 /node_modules/dsh-parallel-worktree;再从 dsh.profile.bundles 里删掉 dsh-parallel-worktree。在插件面板里直接卸载会一并处理这两件事。

B. install.mjs 装的

node uninstall.mjs                   # 从默认 profile 卸载
node uninstall.mjs --profile desktop # 指定 profile(名字或目录都行)
node uninstall.mjs --dry-run         # 只看计划

它做三件事:从 dsh.profile.bundles 移除 dsh-parallel-worktree(dependencies 里有也一并移除)、删掉 /node_modules/dsh-parallel-worktree(目标存在时顺带清掉老版本留在 /node_modules 的副本)、改 package.json 前备份成 package.json.bak-&lt;时间戳&gt;。

注意它不跑 pnpm:如果这个包是以 profile 依赖身份装的,脚本只移除清单条目,/node_modules 里的文件要等下一次 pnpm install 才清掉——那种情况用 A。

卸载后要重启 DSH。 卸载不影响任何 worktree 数据:检出目录、分支、registry.json 都留着,它们仍是普通 git 检出;要清理用 /worktree remove / /worktree prune,或手工删。

设计取舍

  • 收尾动作只给人:模型侧只有 create/list/status,merge/remove/prune 留在 /worktree。不可撤销的操作必须有人确认。
  • 检出默认在仓库外:主工作区永远干净,不用维护 .gitignore,git status 不被污染。代价是检出不在仓库目录树里(IDE 需要单独打开)——用 layout: inside 可以换回来。
  • 注册表属于插件,不属于 git:能记基线、创建时间、最近同步时间,能 prune;代价是可能与 git 实际状态短暂不一致,所以 list/status 每次都现场探测 exists / dirty / ahead / behind 来纠偏。
  • 冲突一律自动 abort:命令必须在无人值守下可预测,冲突留给人手动处理。
  • 不接管会话工作目录:插件保持「纯工具」,目录由用户或 Agent 决定。

常见问题

9 问
答案由本站依据条目字段整理,不引用上游原文
dsh-parallel-worktree 怎么安装?

在 DSH 里执行 `dsh plugin --profile web add github:wang-yi-bit64/dsh-parallel-worktree` 即可。对应的 npm 包名是 `dsh-parallel-worktree`。

dsh-parallel-worktree 的验证等级是什么意思?

L5 · 运行验证通过。在 dsh 沙盒中完成安装与运行冒烟——装得上、跑得起来

dsh-parallel-worktree 安全吗?

低风险。静态扫描 低;动态审计无结论(以下以静态为准)→ 总评级 低。

dsh-parallel-worktree 装之前要先确认什么?

先看它会读写哪些文件、执行哪些命令、连接哪些网络地址;验证等级只说明装得上、跑得起来,不等于安全。涉及密钥或系统权限的,建议先在隔离环境试装。

dsh-parallel-worktree 支持哪些 DSH 版本?

上游记录的兼容版本包括 0.2.2-rc.1。

dsh-parallel-worktree 需要什么运行环境?

Node.js >=20;需要同时安装 @deepseek-ai/cordis@~4.0.5 || ~4.0.6-alpha.1 || ~4.1.0、@deepseek-ai/dsh-tools@^0.2.1-rc.4 || ^0.2.2-alpha.2。环境不满足时安装会失败,建议先确认本机版本。

dsh-parallel-worktree 用的是什么许可证?

上游标注为 MIT。商用或二次分发前请到仓库确认许可证原文。

dsh-parallel-worktree 有哪些功能?

/worktree 命令管理并行检出、worktree_create/list/status 工具、composer dock 只读面板、自动复制 .env 与复用 node_modules、同步、合并、清理收尾闭环。

这条记录的数据可靠吗?

本站按仓库名去重后合并整理,字段以作者仓库与 npm 元数据为准;安装命令、仓库地址与 README 保持原文,带 L4 / L5 标记的安装命令已在隔离沙盒里真实跑通。

同名或近似条目

1 条
不同作者的仓库分开列,请确认你要装的是哪一个
开发与运行时
按星标排序,可作替代方案

rea

rea

L4 · 沙盒安装通过 2.6 万 星

dsh-TUI

dsh-TUI

Claude Code 风格全屏终端 UI:像素鲸鱼顶栏、实时工作状态行、思考流式展开。

L4 · 沙盒安装通过 4,292 星

mirage

mirage

把文件系统与 bash 提供者换成 mirage 虚拟工作区:文件工具与 shell 命令作用于挂载的资源(RAM、S3、Redis、Sla

L3 · 安装规范通过 3,681 星

dashi-taskboard

dashi-taskboard

把当前已安装并运行中的 Codex Taskboard 嵌入 DeepSeek Harness 侧边栏,并通过 Launcher 运行时描述

L4 · 沙盒安装通过 3,311 星

插件的元信息来自作者仓库;分类、验证等级与安全结论的中文说明为中文整理,最近核验 2026-11-10。