DeepSeek Harness 插件

BOWLUNA/dsh-zcode-rewind

Star 数 ★ 0 分类 会话与消息 收录于 2026-09-22

逐工具调用的工作区检查点:记录工作区内每一次文件改动(默认排除 .git 与 node_modules),包括由 shell 命令而非 write/edit 造成的改动,并把每个被改路径的旧内容存进工作区之外的内容寻址库。恢复有两种模式——撤销单条记录,或回到某个时间点——带行级 diff 预览、默认 dry run,且每次恢复前都先写保护快照,所以恢复本身也能被撤销。

安装

# GitHub 源码(首次需按提示配置 allowBuilds 构建授权后重试)

dsh plugin --profile web add github:BOWLUNA/dsh-zcode-rewind

装任何插件都等于在你的机器上跑第三方代码,权限和你本人一样大——能读你的文件、用你的凭据、访问网络,工具审批管不到它。GitHub 来源的插件还会在安装时执行构建脚本——pnpm 默认拦截,所以安装可能停在 ERR_PNPM_GIT_DEP_PREPARE_NOT_ALLOWEDERR_PNPM_IGNORED_BUILDS;dsh 会打印出需要添加的确切键名,把它加进该 profile 的 pnpm-workspace.yamlallowBuilds 下,重跑一次即可装上。放行构建本身就是一次信任判断:请只安装可信来源,并尽量锁定 commit(github:owner/repo#sha)。

README

English | 简体中文

面向 DeepSeek Harness 的逐工具调用工作区检查点——连 shell 副作用一起捕获。

为什么做这个

我们能找到的检查点实现,都只追踪「文件编辑工具」造成的改动。Claude Code 官方文档把话说得很直: 「检查点不追踪被 Bash 命令修改的文件」——rm file.txtmv old.txt new.txtcp source.txt dest.txt 都无法通过 rewind 撤销。Cline 确实能捕获命令副作用,代价是每次工具调用后 把整个仓库提交进一个 shadow git,而它自己的文档提醒:大仓库会明显吃存储、明显变慢。

DSH 自己的市场也一样:我们读过的四个回滚插件(dsh-rewind-plugin@anionex/dsh-turn-rewinddsh-undo-savepointdsh-recall-plugin)要么只解析 write/editfile_path 参数, 要么只在 turn 边界打快照——所以一个 turn 中途的 sed -i,它们全都看不见。

它捕获什么

  • 每一次会改动文件的工具调用:bashpwshwriteedit、MCP 工具、子代理工具。
  • 删除、新建、修改——每个路径都带一个可还原的改动前内容哈希
  • 内容寻址的文件内容,跨会话、跨工作区去重。
  • 一份持久账本:谁在什么顺序上改了什么,重启后仍在。

工作原理

tools/execute (before) ──> 登记 pending;首次捕获写一份全量基线
        │  (工具执行: bash rm/mv/sed、write、edit、MCP …)
tools/post-execute ─────> 指纹差分 → 读变化文件 →
                          内容寻址 blob 库(sha-256,去重)→
                          追加式账本记录

指纹是整棵工作区的 路径 → 大小 + mtime。每次捕获的成本是一次 O(文件数) 的 stat 遍历, 加上只对真正变化的文件读内容——3000 个文件实测 88 ms;首次全量基线 2936 ms, 而零变更捕获只要 86 ms。

安装

dsh plugin --profile web add dsh-zcode-rewind

重启 DSH——bundle 插件在启动装配期生效。用 dsh --profile web --dump-config | grep workspace-rewind 验证合成树。快照库在工作区之外, 位于 $DSH_HOME/workspace-rewind/,绝不碰你的 git 仓库。

工具

工具 作用
rewind_now 立即手动建检查点,比如危险操作之前
rewind_list 最近记录(新→旧):id、时间、工具、+新增 ~修改 -删除、示例路径
rewind_diff 恢复计划 + 行级 unified diff,不改动任何文件
rewind_restore mode=revert 撤销单条记录;mode=asof 回到某个时间点
rewind_undo 撤销最近一次恢复——反复执行即 undo/redo 来回切
rewind_status 快照库状态:记录数、blob、占用、配额、当前配置

配置

- insert:
    - id: workspace-rewind
      name: 'dsh-zcode-rewind'
      config:
        capture: all            # all | fileTools | off
        maxFileBytes: 8388608   # 超过此大小的文件只记事件
        maxFiles: 20000         # 单次遍历文件数上限
        maxTotalBytes: 536870912  # 快照库配额;超限淘汰最旧未引用 blob
        keepRecords: 500        # 账本裁剪阈值
        excludes: ['.git', 'node_modules', 'dist']
        secretNames: ['.env', '*.pem', '*.key']

恢复语义

模式 含义
revert 只抵消某一条记录的增量——「撤销刚才搞坏的东西」用这个
asof 把工作区回到某条检查点记录的状态:折叠账本,并正确处理 target 之后新建的文件

安全

  • 恢复默认 dry-run;必须显式 apply=true 才会动文件系统。
  • 每次恢复前先写一条 rescue 保护记录,所以 rewind_undo 能撤销它——而且可以反复撤销。
  • restore / rescue 记录豁免配额淘汰:撤销链永远不会被清掉。
  • 密钥样式的文件与超限文件只记事件,恢复计划保持它们原样,而不是去猜它们的历史。

兼容性

在 DSH 0.1.5-rc.2(桌面版 harness)与 0.1.6-alpha.2(WSL)上开发并验证。声明的区间是:

>=0.1.5-alpha.1 || >=0.1.6-alpha.1

用到的宿主 API:ctx.tools.registerdefineToolctx.inject(['fs'], …) 及其 tools/execute / tools/post-execute / tools/result 事件、ctx.systemPrompt.sectionctx.logger,以及 @deepseek-ai/dsh-home-pathsresolveDshHome()。peer 走多锚点 createRequire 解析,所以用 link: 装的副本不需要本地 node_modules

测试与守卫

node test/run.mjs                                    # 2 个套件,73 项检查——不需要 DSH
node tools/verify-translation-pairing.mjs --write     # 双语配对哈希
node tools/verify-doc-numbers.mjs                     # 文档数字 vs 真实运行
node tools/verify-version-consistency.mjs --dsh 0.1.6-alpha.2
node tools/verify-boot.mjs --port 31860               # 需要 pnpm 与一份 harness 安装

最后一道守卫是唯一把插件装进一次性 DSH_HOME 再启动的。它存在的原因是:1.0.0 装得上、 73 项单测全过、--dump-config 干净——然后启动时把整个 profile 打下来,起因是 cordis.patch.yml 里有一个词还写着改名前的旧包名。

已知限制

  • 工具调用之间的外部改动会被归到下一次捕获——与整树 shadow commit 同一类限制。
  • 内容从未入库的文件(密钥名、超限、首次捕获前就消失)无法按内容还原;计划会保持它们原样并说明。
  • 巨型 monorepo 需要更大的 excludes 列表,或改用 capture: fileTools

许可证

MIT

内容来自项目 README(GitHub)↗

链接

同类插件

查看整个分类 →

社区评论

评论公开保存在 GitHub Discussions。加载评论会连接 GitHub 和 Giscus;发表内容需要 GitHub 账号。