🎁 福利专区全网大模型免费应用 + 新用户福利 + 注册活动入口,低成本玩转 AI

任务工作区管理 JohnXu22786/worktree-mgr

DeepSeek Harness
JohnXu2278610 天前有提交已提供中文文档扫描:含敏感能力

DSH 插件:为任务自动创建隔离的 git 工作区,管理创建/同步/收尾全生命周期 task-isolated git…

38.1/100
综合分
2
GitHub 星标
—
npm 周下载
—/5
用户评分

数据截至 2026/10/25 · 周下载取自 npm 全网(含 CI / 镜像),非本站安装数;综合分由星标、活跃度与兼容性检查合成。

自动兼容检查有告警:未发布到 npm registry,仅可从源码安装。
安装命令 · 需先装 dsh CLI 引擎
dsh plugin --profile web add JohnXu22786/worktree-mgr
该包不可直接 npm 安装,改从 GitHub 源安装(明细见下方安装检查)

状态速览

判定依据:实装验证 · 静态安装检查 · 自动扫描 · 仓库维护状态
信任档位:已验证
是什么
dsh 原生插件 · dev
装得上吗
本站已在 dsh 0.2.1-rc.2 下真实安装成功
非静态推断
L4 · 真实安装等级说明 →
安全吗
本站尚未对该插件做风险分级
暂未覆盖,不等同于无风险
还在维护吗
活跃:最近一次提交在 10 天前
档位由哪些信号合成

本站实装验证(真实安装 L4 覆盖全站;L5 为运行时冒烟或实机截图,覆盖范围小于 L4) · 验证所用 dsh 版本 · 静态安装检查 · 风险分级 · 仓库维护状态。 下方各区块是它的证据明细。

验证判据与等级说明 →
社区实装还没有人打卡 · 装过的第一个就是你
安装兼容性检查⚠ 装前注意

未发布到 npm registry,仅可从源码安装

展开查看检查明细 ↓

以下结论由程序自动检查 npm 包、engines 声明与入口文件得出,未做人工实机验证——能装不等于用着没问题。

✗npm 包worktree-mgr(未发布到 npm,仅可源码安装)
✓Node 引擎要求 >=21 · 基线 Node 22.19 满足
✓dsh CLI 依赖未声明 dsh 版本约束
✓入口文件main/exports/bin 已声明

验证方式:npm registry 存在性 + package.json 静态校验 · 最后检查 2026/10/31 07:31:15

安全扫描自动 · 静态分析源码
v2.7.0
🔵 扫描:含敏感能力尚无人工评估
展开查看扫描说明与证据 ↓

静态扫描发现插件具备触达本地系统的能力:执行外部命令、读写/删除本地文件、读取剪贴板或密钥类环境变量(至少其一)。这是能力清单,不是危险判定——具体能力项与证据见下方,安装前请自行判断是否需要。

可执行外部命令读写/删除本地文件
查看扫描证据(共 61 处,展示前 39 条)
  • 执行外部命令固定命令
    src/git.js:92
    return spawnSync('git', ['--version'], { stdio: 'ignore' }).status === 0
  • 读取本地文件
    src/tools.js:41
    text = readFileSync(join(root, '.wtm.json'), 'utf8')
  • 读取本地文件
    src/ops.js:218
    return { exists: true, isDirectory: statSync(path).isDirectory() }
  • 读取本地文件
    src/ops.js:316
    if (existsSync(wtPath)) {
  • 读取本地文件
    src/ops.js:378
    if (!existsSync(src)) {
  • 写入本地文件
    src/ops.js:383
    mkdirSync(dirname(dst), { recursive: true })
  • 写入本地文件
    src/ops.js:384
    copyFileSync(src, dst)
  • 删除本地文件
    src/ops.js:725
    rmSync(headLock.path, { force: true })
  • 删除本地文件递归
    src/ops.js:807
    if (snapshotGuard) rmSync(snapshotGuard.hooksPath, { recursive: true, force: true })
  • 删除本地文件递归
    src/ops.js:948
    rmSync(guard.hooksPath, { recursive: true, force: true })
  • 删除本地文件递归
    src/ops.js:984
    rmSync(guard.hooksPath, { recursive: true, force: true })
  • 删除本地文件
    src/ops.js:1163
    if (created) rmSync(path, { force: true })
  • 删除本地文件
    src/ops.js:1270
    rmSync(abandonHeadLockPath, { force: true })
  • 读取本地文件
    src/vault.js:169
    if (!statSync(existing).isDirectory()) {
  • 读取本地文件
    src/vault.js:181
    const stat = lstatSync(candidate)
  • 读取本地文件
    src/vault.js:250
    if (!existsSync(indexPath)) return structuredClone(EMPTY_LEDGER)
  • 读取本地文件
    src/vault.js:253
    text = readFileSync(indexPath, 'utf8')
  • 写入本地文件
    src/vault.js:284
    mkdirSync(vaultDir, { recursive: true })
  • 写入本地文件
    src/vault.js:287
    writeFileSync(tmpPath, JSON.stringify(ledger, null, 2), 'utf8')
  • 写入本地文件
    src/vault.js:288
    renameSync(tmpPath, indexPath)
  • 读取本地文件
    src/vault.js:384
    st = lstatSync(path)
  • 删除本地文件
    src/vault.js:390
    unlinkSync(path)
  • 删除本地文件
    src/vault.js:394
    try { unlinkSync(join(path, child)) } catch (err) {
  • 删除本地文件
    src/vault.js:398
    rmdirSync(path)
  • 读取本地文件
    src/vault.js:411
    tombstoneStat = lstatSync(tombstonePath)
  • 写入本地文件
    src/vault.js:419
    mkdirSync(path, { mode: tombstoneStat.mode })
  • 写入本地文件
    src/vault.js:431
    renameSync(join(tombstonePath, child), join(path, child))
  • 删除本地文件
    src/vault.js:433
    rmdirSync(tombstonePath)
  • 删除本地文件
    src/vault.js:449
    unlinkSync(tombstonePath)
  • 写入本地文件
    src/vault.js:477
    renameSync(path, tombstonePath)
  • 删除本地文件
    src/vault.js:548
    try { unlinkSync(tombstonePath) } catch (err) {
  • 写入本地文件
    src/merge-guard.js:178
    writeFileSync(hookPath, body, 'utf8')
  • 写入本地文件
    src/merge-guard.js:179
    chmodSync(hookPath, 0o755)
  • 删除本地文件递归
    src/merge-guard.js:234
    rmSync(hooksPath, { recursive: true, force: true })
  • 写入本地文件
    src/merge-guard.js:274
    writeFileSync(hookPath, body, 'utf8')
  • 写入本地文件
    src/merge-guard.js:275
    chmodSync(hookPath, 0o755)
  • 删除本地文件递归
    src/merge-guard.js:443
    rmSync(hooksPath, { recursive: true, force: true })
  • 读取本地文件
    src/triggers.js:19
    accessSync(join(dir, 'setsid'), constants.X_OK)
  • 读取本地文件
    src/triggers.js:288
    const stat = readFileSync(`/proc/${pid}/stat`, 'utf8')
扫描于 2026/11/3(0 天前) · 范围 入口闭包 + 发布文件清单 · 来源 GitHub 仓库

静态扫描只反映源码中出现的调用,不构成安全背书;人工评估与自动扫描相互独立、互不覆盖。

给这个插件打分还没有人投票↓
用户评分
还没有人投票,来当第一个

功能亮点

  • 自动创建隔离工作区
  • 管理创建同步收尾
  • 任务级git工作区
展开完整介绍(92 字)↓

DSH 插件:为任务自动创建隔离的 git 工作区,管理创建/同步/收尾全生命周期 (task-isolated git worktrees for DeepSeek Harness)

README

由 DeepSeek 最新模型翻译生成
worktree-mgr 为 dsh(DeepSeek Harness,运行在 Cordis 插件框架之上的插件化 harness)提供「任务隔离工作区」能力的插件。 模型并行处理多个任务时,每个任务都在独立的 git 工作区(git worktree)与独立分支中完成,互不污染主工作区;任务结束自动提交、合并、清理。整个生命周期——创建 / 同步 / 总览 / 收尾 / 批量清理——由 5 个工具 + 1 个 CLI 覆盖,全程零手工 git 操作。 核心概念 | 概念 | 说明 | | 任务(task) | 一项独立工作,如 add-search-box。工具以任务名为入口 | | 分支 | 由任务名自动派生:<prefix>/<任务slug>,默认 wtm/add-search-box,也可显式指定 | | 工作区 | 位于 vault 目录下(默认平台数据目录 wtm/vaults/<仓库slug>/),与主仓库隔离 | | 账本 | vault 下的 index.json,持久化「任务 ↔ 分支 ↔ 路径」映射(JSON 格式,原子写入 + 互斥锁) | | 基分支 | 任务合并的目标分支,默认主工作区当前分支 | 特性 - 任务驱动:给模型一个任务名,分支名、路径、账本记录全部自动生成,无需指定分支
展开完整文档(README 剩余 1 节)
worktree-mgr

为 dsh(DeepSeek Harness,运行在 Cordis 插件框架之上的插件化 harness)提供「任务隔离工作区」能力的插件。

模型并行处理多个任务时,每个任务都在独立的 git 工作区(git worktree)与独立分支中完成,互不污染主工作区;任务结束自动提交、合并、清理。整个生命周期——创建 / 同步 / 总览 / 收尾 / 批量清理——由 5 个工具 + 1 个 CLI 覆盖,全程零手工 git 操作。

核心概念

| 概念 | 说明 |
| 任务(task) | 一项独立工作,如 add-search-box。工具以任务名为入口 |
| 分支 | 由任务名自动派生:<prefix>/<任务slug>,默认 wtm/add-search-box,也可显式指定 |
| 工作区 | 位于 vault 目录下(默认平台数据目录 wtm/vaults/<仓库slug>/),与主仓库隔离 |
| 账本 | vault 下的 index.json,持久化「任务 ↔ 分支 ↔ 路径」映射(JSON 格式,原子写入 + 互斥锁) |
| 基分支 | 任务合并的目标分支,默认主工作区当前分支 |

特性

- 任务驱动:给模型一个任务名,分支名、路径、账本记录全部自动生成,无需指定分支
- 分支名安全:任务名 → slug 规范化(段内 ..、.lock 结尾、段首点等非法形态在源头修正),ref 合法性双重校验;不同任务派生同一 slug 时拒绝创建
- 未提交改动检测:基分支脏时拒绝合并(防止混入未完成工作);任务工作区脏时默认自动快照提交
- 合并目标一致性:合并前校验「主工作区当前分支 == 账本基分支」「工作区当前分支 == 账本任务分支」,不一致一律拒绝——杜绝改动被提交到错误分支却报告成功的静默错误
- 同步与收尾分离:wtm_merge 只合并不清理,wtm_finish 提交→合并→删工作区→删分支→清记录;重试场景自动跳过已完成的合并(不产生重复空 merge 提交)
- 批量清理:wtm_purge 一次收尾多个任务,单任务失败不中断其余,任一失败即非零退出码
- 仓库级配置:<仓库根>/.wtm.json 支持分支前缀、消息模板、种子文件(带路径越界防护)、生命周期触发器(固定工作目录)
- 并发安全:账本写操作带互斥锁——锁内含唯一 token 与心跳刷新,陈旧锁仅在进程崩溃后回收,释放时绝不误删后继持有者的锁
- 失败恢复:创建中途失败自动回滚已创建的 worktree 与分支;合并冲突给出 git merge --abort 恢复指引
- 跨平台:Windows(cmd)与 POSIX(sh)触发器执行;路径比较大小写/分隔符归一化
- 零依赖、免构建:纯 Node ESM,node >= 21 即可,安装即用

安装

在 DSH 中安装(从 GitHub)

从 GitHub 安装最新版本到 profile:

dsh plugin --profile demo add github:JohnXu22786/worktree-mgr

移除:

dsh plugin --profile demo remove worktree-mgr

方式一:作为 dsh bundle 安装(推荐)

在包含本目录的路径下:

dsh plugin --profile demo add ./worktree-mgr

- package.json 声明了 dsh.bundle.patch → cordis.patch.yml,dsh 会自动把插件行插入 profile 的配置层;
- 该层默认 root: !!js process.cwd()(以 dsh 启动目录为主仓库),可按需覆盖;
- 本包为纯 JavaScript,无构建步骤,从 git 安装也不会缺产物。

方式二:overlay 加载(不装进 profile)

dsh --profile demo --patch ./examples/overlay.yml

overlay.yml 与插件行配置结构一致,适合临时挂载或改配置。

方式三:独立 CLI

npm link # 或 node bin/wtm.js ...
wtm begin "Add Search Box"

快速开始

1. 为任务创建隔离工作区(自动派生分支 wtm/add-search-box) wtm begin "Add Search Box"

2. 在 <vault>/add-search-box 中自由修改代码(或让模型在任务工作区目录中工作)

3. 查看所有任务的状态(脏/领先/落后) wtm status

4. 只同步不回填清理:把任务改动合并回基分支,工作区保留 wtm merge "Add Search Box"

5. 收尾:快照提交 → 合并 → 移除工作区 → 删除分支 → 清账本 wtm finish "Add Search Box"

6. 批量收尾 wtm purge "Task A" "Task B" # 指定任务 wtm purge --all # 全部任务

所有命令支持 --json 输出结构化结果,便于脚本与 harness 消费。

CLI 参考

bin/wtm.js 可独立使用(npm link 后为 wtm,或 node bin/wtm.js);每个子命令都支持 --json,结构化结果输出到 stdout。

| 命令 | 说明 | 退出码 |
| wtm begin <task> | 创建隔离工作区(--base、--branch、--note、--root) | 0 成功 / 1 失败 |
| wtm merge <task> | 任务分支合并回基分支,工作区保留(--mode、--message) | 0 / 1 |
| wtm finish <task> | 收尾并清理(--mode、--message) | 0 / 1 |
| wtm status | 全部任务总览 | 0 / 1 |
| wtm purge [task...] | 批量收尾;--all 表示全部 | 0,任一任务失败为 1 |
| wtm help | 打印用法 | 0(裸 wtm 为 2) |

退出码语义:0 成功;1 操作失败(--json 模式下失败信息在 JSON 载荷中,且 purge 任一子任务失败同样为 1);2 用法错误(未知或缺失命令)。WTM_ 环境变量对 CLI 同样生效。

工具接口(模型可见)

| 工具 | 作用 | 关键参数 |
| wtm_begin | 为任务创建隔离工作区 | task(必填), base, branch, note, root |
| wtm_merge | 同步:任务分支合并回基分支(工作区保留) | task(必填), mode(commit/refuse), message, root |
| wtm_finish | 收尾:提交→合并→清理工作区与分支 | task(必填), mode(commit/abandon/keep), message, root |
| wtm_status | 任务总览(存在性/脏状态/领先落后) | root |
| wtm_purge | 批量收尾 | tasks, all, mode, message, root |

mode 语义

- commit(默认):先自动快照提交任务工作区的未提交改动,再合并回基分支,最后清理
- refuse:任务工作区有未提交改动时直接拒绝(仅 wtm_merge)
- abandon:丢弃任务全部改动,强制清理工作区并删除分支(不可恢复,谨慎使用)
- keep:仅解除管理,工作区与分支原样保留(仅 wtm_finish)

安全边界(工具与 CLI 一致):

- 基分支工作区存在未提交改动 → 拒绝合并(wtm_merge / wtm_finish 的 commit 模式)
- 主工作区当前分支与账本基分支不一致、任务工作区当前分支与账本记录不一致 → 拒绝操作(防止改动落错分支)
- 任务分支已存在、任务已登记、工作区目录已存在、不同任务派生同一工作区路径 → 拒绝创建
- 任务名或分支名非法(git ref 规则)→ 在任何 git 操作之前拒绝
- 种子文件路径越界(../x 等逃逸仓库/工作区)→ 拦截并告警
- 调用被取消(exec.signal abort)→ 干净返回;创建中途失败自动回滚已创建的 worktree 与分支

插件接入说明(harness 如何加载它)

本插件遵循 dsh 的标准插件协议,共三块拼图:

worktree-mgr/
├── package.json # ① dsh.bundle manifest:声明本包是一个配置层 ├── cordis.patch.yml # ② 配置层内容:向 profile 插入插件行 ├── index.js # ③ 入口模块:导出 name / inject / apply └── src/ # 实现:naming/config/vault/git/triggers/ops/tools

① bundle manifest(package.json):

{
"name": "worktree-mgr",
"type": "module",
"main": "index.js",
"dsh": { "bundle": { "patch": "./cordis.patch.yml" } }
}

② 配置层(cordis.patch.yml):

- insert:
- id: worktree-mgr
name: worktree-mgr # 按包名解析,Node 模块解析找到 index.js config: root: !!js process.cwd()

③ 入口模块(index.js)导出:

export const name = 'worktree-mgr'
export const inject = ['tools'] // 声明依赖 tools 注册表
export function apply(ctx, config = {}) {
ctx.tools.register(...) // 注册 5 个工具
}

加载顺序:profile 组装 → 本 bundle 的 patch 层插入插件行 → 加载器等待 tools 服务就绪 → 调用 apply(ctx, config) → 工具 schema 自动汇入系统提示词,模型即可调用。

工具定义形态(与 dsh 工具约定一致):

{
name: 'wtm_status',
description: '...', // 模型可见描述
parameters: { // JSON Schema 对象
type: 'object',
properties: {
root: { type: 'string', description: '仓库路径' }
}
},
output: {
schema: { type: 'object', properties: { ok: { type: 'boolean' }, ... }, required: ['ok'] },
render: (args, value) => [{ type: 'text', text: '...' }] // 模型可见内容
},
async execute(args, exec) { ... } // 返回规范 JSON;exec.signal 支持取消 }

事件/钩子接口:插件本身不订阅 harness 事件;生命周期扩展通过仓库级配置的 触发器(triggers)实现——在 on_begin / on_merge / on_finish 三个节点执行仓库配置的 shell 命令,注入 WTM_TASK / WTM_BRANCH / WTM_BASE / WTM_PATH / WTM_ROOT 环境变量。触发器有固定工作目录:on_begin 在新工作区内执行,on_merge / on_finish 在主仓库根目录执行。触发器失败只记警告,不中断主流程。

配置

优先级(低 → 高):内置默认 < 插件行 config < 仓库 .wtm.json < 环境变量 WTM_

| 键 | 默认 | 说明 |
| root | process.cwd() | 主仓库路径(仅插件行/工具参数) |
| vault | 平台数据目录 wtm/vaults/<仓库slug>/ | 任务工作区与账本存放目录;相对路径按仓库路径解析 |
| prefix | wtm | 分支前缀,派生分支为 <prefix>/<slug> |
| commitMessage | chore(wtm): snapshot {task} | 快照提交模板,占位符 {task} {branch} {base} |
| mergeMessage | merge(wtm): fold {task} into {base} | 合并提交模板 |

环境变量:WTM_ROOT(工具与 CLI 均生效)、WTM_VAULT、WTM_PREFIX、WTM_COMMIT_MESSAGE、WTM_MERGE_MESSAGE(WTM_ROOT 优先级低于工具参数与插件配置)。

仓库级配置 <仓库根>/.wtm.json

{
"prefix": "wtm",
"vault": "D:/wtm-vaults",
"commitMessage": "chore(wtm): snapshot {task}",
"mergeMessage": "merge(wtm): fold {task} into {base}",
"seed": { "files": ["docs/AGENTS.md"] },
"triggers": {
"on_begin": ["pnpm install"],
"on_merge": ["pnpm lint"],
"on_finish": []
}
}

- vault 必须位于仓库工作树之外(否则主工作区会被 vault 目录持续弄脏,插件会直接拒绝);
- seed.files:创建任务工作区时从主仓库复制到工作区的文件(如团队约定文档);路径必须位于仓库/工作区内,越界条目会被拦截并告警;
- triggers.:生命周期钩子命令数组,见上文「事件/钩子接口」。

未知键会产生警告并被忽略;损坏的 .wtm.json 不阻塞操作,仅告警。

安全说明(重要)

- 仓库配置即代码:.wtm.json 的 seed.files 会把仓库内的文件复制进工作区,triggers. 会以当前用户权限执行任意 shell 命令。只应在可信仓库中启用本插件——克隆并操作不可信仓库时,仓库自带的 .wtm.json 等同于自动获得你的执行权限。无需此能力时留空 seed/triggers 即可。
- 快照提交包含未跟踪文件:任务工作区脏时,默认快照会 git add -A 提交全部改动(含未跟踪文件,如构建产物)。不想把大目录纳入历史,请先在任务工作区维护 .gitignore,或使用 refuse 模式手动处理。
- abandon 不可恢复:wtm_finish --mode abandon 与批量 wtm_purge 会强制删除工作区并删除任务分支(-D),其中的改动无法恢复,仅应在确认丢弃时使用。

账本与并发

- 账本:<vault>/index.json,{version: 1, records: [{task, branch, base, path, createdAt, updatedAt, note?}]}
- 写入原子(临时文件 + rename),且全程持有 .lock 互斥锁;
- 锁内含持有者唯一 token 与 30s 心跳刷新:进程崩溃后锁超过 5 分钟判定陈旧并回收;释放时校验 token,绝不误删后继持有者的锁;等待超时默认 5 秒。

开发与测试

npm test # node --test,零第三方依赖
npm run typecheck # 可选:需 dev 安装 typescript + @types/node

测试覆盖:命名规则、配置合并、账本(原子写/锁/陈旧回收/损坏恢复)、git 输出解析、触发器、生命周期编排(fake git 注入)、工具 schema、以及调用真实 git 的集成测试(begin → 改文件 → status → finish 全链路)。

目录结构

worktree-mgr/
├── package.json # bundle manifest + 元数据 ├── cordis.patch.yml # 插件配置层 ├── index.js # dsh 插件入口(name/inject/apply) ├── bin/wtm.js # 独立 CLI ├── README.md # 文档(EN) ├── README.zh.md # 文档(ZH) ├── LICENSE # MIT 许可 ├── src/ │ ├── naming.js # 任务名→分支映射与 ref 校验 │ ├── config.js # 配置合并与模板渲染 │ ├── vault.js # 账本持久化(原子写/锁) │ ├── git.js # git 执行层与输出解析 │ ├── triggers.js # 生命周期触发器 │ ├── ops.js # 生命周期编排(begin/merge/finish/status/purge) │ └── tools.js # dsh 工具定义 ├── examples/ │ ├── .wtm.json.example # 仓库配置示例 │ └── overlay.yml # dsh overlay 示例 └── tests/ # node:test 单元 + 集成测试

许可

MIT — 见 LICENSE。
预览分享卡片长什么样 ↓JohnXu22786/worktree-mgr
分享 · DeepSeek Harness Hub
JohnXu22786/worktree-mgr

DSH 插件:为任务自动创建隔离的 git 工作区,管理创建/同步/收尾全生命周期 task-isolated git…

这是你的仓库?认领条目

回到顶部