# dsh-kit [English](README.md) | 中文 八个 [DeepSeek Harness](https://github.com/deepseek-ai/deepseek-harness) 插件,针对的是"没人盯着时 agent 悄悄搞砸的那些事"。 **其中四个补的是我确实没找到有人做的空白,另外四个有更好的现成替代品,下面点名列出。** DSH 插件生态非常大(`dsh-plugin` topic 下 13,000+ 仓库,[插件雷达](https://github.com/AdamPlatin123/dsh-plugin-radar)编目 8,100 个),装作不知道只会浪费你时间。 这里每个功能都是挂在文档化扩展点上的插件行,没有一处改动 harness 本身。 --- ## 安装 ```sh dsh plugin --profile web add github:FoyonaCZY/dsh-kit dsh --profile web ``` **不需要构建**——纯 ESM JavaScript,从 git 装不需要 `prepare` 脚本,也不用在 profile 的 `pnpm-workspace.yaml` 里加 `allowBuilds`(那玩意儿本质上是"允许这个包在你机器上装的时候执行代码")。运行时只依赖 `@deepseek-ai/schemastery`,harness 本身就在用它做插件配置。 想要常规的供应链保障就固定 commit: ```sh dsh plugin --profile web add github:FoyonaCZY/dsh-kit# ``` --- ## 包含什么 | 插件 | 做什么 | 扩展点 | 生态情况 | |---|---|---|---| | [`autoformat`](#autoformat) | 用项目自己的格式化工具处理 agent 写的文件 | `tools/post-execute` | **没找到替代** | | [`artifact-guard`](#artifact-guard) | 拦住手改 lockfile、构建产物、生成代码 | `tools/pre-execute` | **没找到替代** | | [`env-drift`](#env-drift) | 报告 agent 新增却没记进模板的环境变量 | `tools/post-execute` | **没找到替代** | | [`verify`](#verify) | 项目检查没过就不让这一轮结束 | `agent/turn-stopping` | **没找到替代** | | [`checkpoint`](#checkpoint) | `/rewind` 把工作区退回任一次改文件之前 | `tools/pre-execute` + `ctx.commands` | [有替代 ↓](#existing-alternatives) | | [`secret-guard`](#secret-guard) | 工具输出脱敏 + 凭据文件闸门 | `tools/pre-execute`、`tools/post-execute` | [有替代 ↓](#existing-alternatives) | | [`git-context`](#git-context) | 分支、工作区、最近提交进提示词 | `systemPrompt.context()` | [有替代 ↓](#existing-alternatives) | | [`notify`](#notify) | 跑完 / 要审批时桌面提醒 | `agent/status`、`tools/pre-execute` | [有替代 ↓](#existing-alternatives) | 每个都是独立的行,在 profile 的 `cordis.patch.yml` 里单独关掉: ```yaml - id: dsh-kit-notify disabled: true ``` --- ## 真正补空白的四个 ### autoformat **agent 写过的每个文件,都过一遍项目自己的格式化工具。** 不然你要 review 的 diff 一半是真改动,一半是空白字符。 让它不烦人的关键规则:**项目本来就有这个工具,才会跑。** 每条规则都带 `detect` 路径,一个既没有 Prettier 配置也没装 Prettier 的仓库不会跑 Prettier——不会有意外重排版,不会有 `npx` 去联网下载,对没打算用的项目完全零开销。Prettier、gofmt、rustfmt、ruff、black 开箱即用。 格式化工具**拒绝**这个文件时,那通常是"agent 刚写出语法错误"最快的信号,输出会附到工具结果上。 ```yaml - id: dsh-kit-autoformat config: formatters: - extensions: ['.ts', '.tsx'] command: npx --no-install prettier --write {file} detect: ['.prettierrc', 'node_modules/.bin/prettier'] - extensions: ['.sql'] command: sqlfluff fix --force {file} detect: [] # detect 为空 = 总是运行 timeoutMs: 15000 ``` ### artifact-guard **拦住 agent 手改机器生成的文件。** agent 没有可靠办法区分源文件和派生文件。于是它改 `pnpm-lock.yaml` 来"加依赖"、去补 `dist/` 里的东西、改生成的 protobuf 绑定——这些改动要么被下一次 install / codegen 悄悄冲掉,要么直接搞坏产物,然后在离改动很远的地方把构建搞挂。 两个信号,缺一不可: 1. **路径规则**覆盖惯例产物——14 种 lockfile、构建输出、vendor 目录、生成绑定。 2. **内容标记**覆盖剩下的。`@generated`、`DO NOT EDIT`、Go 的 `Code generated by … DO NOT EDIT.` 几乎是通用约定,所以项目**自己的**生成文件会自报家门,不需要谁去登记。只看前 20 行,所以正文里聊到代码生成的源文件不受影响。 拒绝时会说清楚该干什么——`"改 manifest 让包管理器重新生成"`——因为光说"不许改"只会让 agent 再试一次。 ```yaml - id: dsh-kit-artifact-guard config: onArtifact: ask # ask | deny | allow detectMarkers: true allowPaths: [] # 逃生口:确实手工维护的 dist/ 文件 ``` ### env-drift **抓出 agent 新增却没记进文档的环境变量。** agent 写下 `process.env.STRIPE_SECRET_KEY`,在已经 export 了这个变量的机器上跑得好好的,`.env.example` 却一无所知。下一个 clone 仓库的人在运行时炸掉,而错误信息完全没提"模板里少了一项"。 写入成功后把文件读回来,抽出其中的环境变量访问,把模板里没有的交给 agent 当上下文——趁它还记得这个变量是干嘛的。 覆盖 JS/TS(含 `import.meta.env`)、Python、Go、Rust、Java/Kotlin、Ruby、PHP、C#。shell 裸 `$FOO` 故意不认:它和普通局部变量没法区分。运行时自带的变量(`NODE_ENV`、`CI`、`PATH` …)会过滤,每个变量每会话只报一次,**没有模板的项目什么都不报**——它没采用这个约定,替它发明一个太自作主张。 ```yaml - id: dsh-kit-env-drift config: templates: ['.env.example', '.env.sample', '.env.template'] ignore: ['NODE_ENV', 'CI', 'PATH'] ``` ### verify **让"做完了"等于"还能编译"。** agent 代价最高的失败不是改错,而是改错了还报告说做完了——因为代价落在那个读完总结并且相信了它的人身上。 `agent/turn-stopping` 在轮次边界提交前被 await,提出异议的监听器可以再 steer 一步。所以一轮里动过文件、正要结束时,项目自己的检查就会跑。失败就把输出交回去继续干,通过就照常结束。 > 生态里有个 `dsh-test-runner`,但那是**给模型调用的 tool**,这个是**自动闸门**。区别恰恰在模型不去调那个 tool 的时候才体现——而那正是要解决的失败模式。 默认自动探测**类型检查**命令:`package.json` 里的 `typecheck`/`type-check`/`tsc` 脚本(包管理器从 lockfile 推断),否则用本地 `tsc --noEmit`。测试套件永远不自动探测——在每个轮次边界跑太慢。`maxRounds` 兜底,超出后即使还在失败也会结束,最后一条消息让 agent 如实汇报而不是声称成功。 检查命令指向的可执行文件不在 `PATH` 上时,记日志跳过而不是当失败报给 agent——判断方式是直接遍历 `PATH`,因为 shell 报"找不到命令"**用的是机器自己的语言**(开发时就被这个坑了:中文 locale 的 `cmd.exe` 输出 GBK 编码,任何英文模式都匹配不上)。 ```yaml - id: dsh-kit-verify config: checks: - name: typecheck command: pnpm typecheck - name: unit tests command: pnpm test -- --run autoDetect: true # `checks` 非空时忽略 maxRounds: 2 ``` --- ## 有现成替代的四个 想一次装齐就留着;想要各领域最好的版本就去装替代品。 | 我的 | 建议改用 | 原因 | |---|---|---| | `checkpoint` | **[dsh-checkpoint-rewind](https://github.com/PerryLink/dsh-checkpoint-rewind)** | 客观上更好:用 git `stash create`/`commit-tree` 做快照而不是我那套 blob 目录,覆盖 `bash`/`pwsh`/`terminal_send`(我的做不到),还有 `preview`/`diff` 子命令和会话+配置状态。 | | `secret-guard` | [JohnXu22786/secret-guard](https://github.com/JohnXu22786/secret-guard)、[hol-guard](https://github.com/hashgraph-online/hol-guard) | 同样两个扩展点,规则更多,还有 HMAC 指纹检查工具。我唯一的边际优势:`redactValue`,PTC 部署下 `run_code` 程序能直接读 canonical value,只脱敏 content 挡不住。 | | `git-context` | [qtjg/dsh-plugin-git-context](https://github.com/qtjg/dsh-plugin-git-context)、[dsh-gitflow](https://github.com/search?q=dsh-gitflow) | 覆盖得薄但确实有。我的优势是注册在每个 agent 自己的 `agent.ctx` 上,多工作区部署里每个 agent 拿到自己仓库的状态。 | | `notify` | [dsh-notification](https://github.com/search?q=dsh-notification)、[dsh-notification-center](https://github.com/search?q=dsh-notification-center) | 重度饱和(150+ 个插件涉及通知)。人家和 Web UI 设置页集成;我的是原生系统通知无 UI,另外会响终端提示音,SSH 上也能听见。 | `/rewind` 和用量统计类是这个生态最拥挤的角落。只想要真正缺的东西,就把那四行关掉,留前四个。 --- ## 设计取舍 **不绑 harness 内部实现。** 运行时唯一来自 DSH 生态的 import 是 `@deepseek-ai/schemastery`。用户消息按文档化的普通对象(`id`、`role`、`content`、`source`)构造,没走 `@deepseek-ai/dsh-llm`,这样快速迭代的预览期里核心包升版不会把这套插件带崩。 **故障就地兜住。** 检查点写不进去、通知程序不存在、格式化工具没装、在非仓库目录调 git——每一种都降级成一行日志,没有任何一个会让你损失真正想执行的那次工具调用。 **所有外部调用都有边界。** 一个子进程封装统一管超时、输出上限和取消,并且在 Windows 上杀整棵进程树——否则杀掉 shell 只会让子进程变孤儿,"超时"根本没停下任何东西。 ## 测试 ```sh npm install && npm test ``` 180 个测试,不联网,不需要 harness。纯逻辑(脱敏规则、glob 匹配、git porcelain 解析、恢复计划、环境变量抽取、产物分类)直接测;每个插件再用假 context 加真实临时文件系统端到端跑——检查点真的恢复了文件,失败的检查真的 steer 了轮次,格式化工具真的改写了刚写入的内容,guard 真的从磁盘读了生成文件的头部。 ## 兼容性 基于 2026 年 9 月 `main` 分支的 DeepSeek Harness 开发。DSH 处于开发者预览期,官方文档提示会有破坏兼容的改动,建议固定 commit。用到的每个扩展点都记录在 [`extension-cookbook.md`](https://github.com/deepseek-ai/deepseek-harness/blob/main/docs/cookbook/extension-cookbook.md)。 ## 许可 MIT