dsh-scratch-vault:DeepSeek Harness 工作流脚本隔离与归档插件

前言

Long-running agent tasks accumulate intermediate files. The files themselves cost nothing on disk; the cost is that every later glob, grep and directory listing has to wade through them, which pushes irrelevant content into context and makes the agent re-derive what it already did.

DSH already has most of the machinery to prevent this. Its workspace-write sandbox grants writes under the workspace root or a platform temporary root (writableRoots returns the workspace root, /tmp and os.tmpdir()), and the workspace change summary already excludes temporary roots (isTemporaryPath — “scratch paths that never enter the change summary”). What is missing is the part that routes scratch work there, and the part that remembers it.

这个插件就是这两部分:路由 scratch 工作到临时根目录,并记住这些文件。

插件定位

dsh-scratch-vault 是一个 DeepSeek Harness 工作流插件,由 TINGOD2006 维护。它的核心价值是让 agent 工作区只保留真实交付物,临时脚本、一次性诊断、转换脚本等执行完后归档到插件管理的 vault 中,不污染仓库。

解决的问题

  1. 工作区污染:agent 写入的临时文件(_probe_models.py、tmp_convert.mjs、apply-paths.ps1 等)会混入仓库,让后续的文件遍历、上下文注入效率下降
  2. 重复推导:agent 需要重新推导已经做过的操作,因为临时文件干扰了上下文
  3. 历史遗留:插件启用前已经存在的临时文件没有地方管理

核心功能

插件在 DSH 中提供了 L2(纪律、环境、内联执行)和 L3(拦截)能力,以及一个 L4 归档 vault。

L2 — discipline, environment, inline execution

  • 系统提示词:在系统提示词中明确告诉模型,操作脚本应运行在 scratch root,而不是工作区
  • 环境变量:每个 shell 调用注入 $DSH_SCRATCH 和 $DSH_VAULT,命名空间按会话重建,始终指向当前会话目录
  • run_script({ language, code, description }) 工具:在 scratch root 写一个文件并执行,通过 ctx.shell 运行,受会话沙箱策略约束。这是”我只想运行一段代码”的正确答案

L3 — interception(拦截)

tools/execute 是唯一能绕过分发、修改 tool body 接收内容的水利枢纽。当 write 或 edit 目标是工作区内的 scratch 脚本时,其 file_path 被重写为会话 scratch root,工具结果返回真实绝对路径 + vault entry id。引用该脚本 shell 命令也会被重写。

安全保证:

  • 映射是纯函数:scratchPathFor 是纯函数,DSH 并行分发 tool 调用,避免竞态条件
  • 仅在文件不存在时重写:遗留文件仍在磁盘上,保持原有行为

Shell 重写是保守的:遇到 glob 元字符、扩展名(x.py.bak)、shell 变量引用($env:X\a.py、$DSH_SCRATCH/a.py、%TEMP%\a.py),或相对路径且无法确定工作目录(cd $env:WORK、cd %WORK%、bare cd、cd ~/proj)时,不重写。

重写仅发生在程序位置:解释器或运行器的参数槽(python、node、pwsh、bash、ruby、lua 等)或命令字本身(.\_probe.ps1)。注释中的脚本名、commit message、grep 模式、单引号 shell payload 是数据,不重写。

L4 — the vault

每个拦截的脚本在 vault 目录下归档,附带 JSONL ledger,以及 scratch_list、scratch_show、scratch_promote(复制回工作区作为真实交付物)和 scratch_purge。

scratch_import retrofits 启用插件前已存在于工作区的 residue:收集指定路径,逐字节验证 vault 副本,再删除原文件。两道防护:仅收集 UTF-8 round trip 存活的字节;不删除被 classifier 保护或位于 src/、node_modules/ 或 excludeGlobs allowlist 中的文件。

vault 写入在插件自身进程内完成,<vaultDir> 位于 DSH_HOME 下,在会话工作区和沙箱可写根之外。agent 通过 shell 运行的程序无法写入 vault,沙箱化工具也无法写入。收集仅在工作区边界的主机侧完成,这正是这些工具运行的位置。

ledger 是追加式,maxVaultEntries trim 等必须重写 ledger 的操作写入临时文件再重命名,中断不会截断历史。读取从以 ledger stat 为键的内存缓存提供,其他写入者(包括共享 vault 的另一个 DSH 窗口)改变签名后下次读取会重新加载。

安装与启用

从官方仓库安装:

dsh plugin --profile desktop add github:TINGOD2006/dsh-scratch-vault

安装后重启 DSH。

从本地 checkout 安装:

dsh plugin --profile desktop add link:C:/path/to/dsh-scratch-vault

Windows 上使用正斜杠,否则 pnpm 会把盘符拼入 profile 目录导致插件安装但不激活。

要求:Node ≥ 22,以及一个挂载 tools 服务的 DSH 构建。插件声明无任何依赖——甚至没有 @deepseek-ai/dsh-tools。链接插件的裸 specifiers 解析到其真实路径,不会触及 profile 的 node_modules,所以一次 host import 足够触发加载失败。工具定义在 lib/tools.js 中手工组装,与 defineTool 的形状完全一致。

编辑 lib/ 下的任何文件需要完整重启 DSH。加载器在启动时构建模块图,按解析 URL 缓存每个模块;禁用/启用 bundle 不会重新导入文件。

典型用法

启用插件后,agent 写入的临时脚本会自动归档到 vault。

before                                    after
repo/                                     repo/
├── src/                                  ├── src/
├── _probe_models.py        ← noise       ├── package.json
├── _recon_api.py           ← noise       └── (deliverables only)
├── tmp_convert.mjs         ← noise
├── apply-paths.ps1         ← noise       vault/
└── package.json                          └── entries/20261012…-a1b2c3/script

通过 $DSH_SCRATCH 和 $DSH_VAULT 环境变量,模型知道在 scratch root 中操作。run_script 工具可直接运行代码而不污染工作区。

通过 scratch_promote,可以将任意归档脚本复制回工作区作为真实交付物。

通过 scratch_import,可以批量迁移启用插件前已存在的临时文件到 vault,并验证字节一致性。

适用场景与注意

适合:

  • 长时间运行的 agent 任务,需要大量中间文件
  • 需要保持工作区整洁,只提交真实交付物
  • 需要归档和追溯临时脚本

注意:

  • 插件以当前 dsh 进程权限运行,安装前应检查源码与许可证(MIT)
  • 需要 Node ≥ 22,以及支持挂载 tools 服务的 DSH 构建
  • 编辑 lib/ 下文件需要完整重启 DSH
  • vault 位于 DSH_HOME,在沙箱边界之外,agent 无法直接修改

总结

dsh-scratch-vault 通过 L2/L3/L4 的分层设计,将临时脚本从工作区隔离到 scratch root,再归档到插件拥有的 vault,让工作区只保留真实交付物。它补全了 DSH 原有的 sandbox 和 change summary 机制,解决了长任务中的文件污染和重复推导问题。安装简单,无依赖,适合需要保持工作区洁净的 agent 工作流场景。

  • 插件目录:https://www.skillhub.cn/plugins/TINGOD2006/dsh-scratch-vault
  • GitHub:https://github.com/TINGOD2006/dsh-scratch-vault
羽毛球分组比赛记分
小程序二维码

欢迎使用《羽毛球分组比赛记分》微信小程序

小夜