前言¶
在 DSH 的插件化工作方式里,很多自动化需求并不复杂:一轮对话结束后发通知、某个工具被调用时写日志、审批请求出现时弹桌面提示。这些动作通常需要监听事件、解析上下文、再执行命令或通知。dsh-hooks 把这类逻辑放在 profile 配置里声明:在 cordis.patch.yml 中写清楚事件、匹配条件和要执行的 run 或 notify,不需要额外写插件代码。
这是什么¶
dsh-hooks 是一个由 PeterBon 维护、采用 MIT 许可的 DeepSeek Harness 插件。它的定位是 config-driven lifecycle hooks:用配置声明 event -> command/notify 的钩子。
它包含两部分:
- 钩子引擎:根据配置监听 DSH 事件,并执行命令或内置通知。
- Web GUI 设置页:安装后,
dsh web的设置面板会增加Hooks区域,提供历史时间线、手动测试、notify 测试、hook editor 和 Feishu connect。
核心能力¶
下面列出 dsh-hooks 的主要能力:
- 在 profile 的
cordis.patch.yml中声明event -> command或event -> notification钩子。 - 不需要编写插件代码,配置即可触发命令或通知。
- 一个包同时提供钩子引擎和 Web GUI 设置页。
- Web GUI 设置面板增加
Hooks区域,包括 history timeline、manual tester、notify tests、hook editor 和 Feishu connect。 - 内置通知渠道:
-desktop:平台气泡/提示。
-webhook:向 HTTP endpoint 发送 JSON,可配置slack: true生成一行摘要。 - 支持以下事件:
-turn/start
-turn/end
-tree/settled
-step/end
-tool/call
-tool/result
-user/message
-approval/asked
-approval/decided
-session/title
-session/created
-session/disposed
-agent/created
-agent/disposed
-agent/error
-agent/status
-hook/failed - 上下文通过
DSH_HOOK_*环境变量传递;如果配置input: stdin,完整 context JSON 会写入命令 stdin。
安装与启用¶
dsh-hooks 要求 Node.js:
node >=22
安装插件可以从 npm 添加:
dsh plugin --profile web add dsh-hooks
也可以直接从 GitHub 仓库添加:
dsh plugin --profile web add github:PeterBon/dsh-hooks
安装后,需要重启 dsh web。重启完成后,设置面板会增加 Hooks 区域,用于查看和配置钩子。
基本配置¶
配置写在 profile 的 cordis.patch.yml 中。下面是几个典型条目:
- id: dsh-hooks
name: dsh-hooks
config:
hooks:
- on: 'turn/end'
when: 'completed'
run: 'node examples/notify-feishu.mjs'
timeoutMs: 10000
- on: 'approval/asked'
notify:
channel: 'desktop'
- on: 'turn/end'
when: 'completed'
notify:
channel: 'webhook'
url: 'https://hooks.slack.com/services/…'
slack: true
- on: 'tool/call'
match:
tool: '^(rm|git|ssh)'
run: 'node examples/notify-webhook.mjs --slack'
上面的配置做了四件事:
- 当
turn/end以completed结束时,执行node examples/notify-feishu.mjs。 - 当出现
approval/asked时,发送桌面通知。 - 当
turn/end完成时,通过 webhook 发送通知,并使用 Slack 风格的一行摘要。 - 当模型请求匹配
rm、git、ssh的工具调用时,执行 webhook 通知脚本。
配置字段¶
dsh-hooks 的 hook 字段覆盖事件触发、条件过滤、执行方式、通知、重试、并发和防抖。常见字段如下:
on:触发事件名,例如turn/end、tool/call、approval/asked。when:过滤turn/end的结束原因,例如completed。match:对上下文字段做条件过滤,例如按工具名正则匹配。run:要执行的命令。run和notify二选一。notify:内置通知,支持channel: desktop和channel: webhook。input:控制上下文传递方式。使用stdin时,会把完整 context JSON 写入命令 stdin。timeoutMs:单条命令的超时时间,单位是毫秒。retries:对非零退出码的重试次数。retryDelayMs:重试间隔,单位是毫秒。enabled:设为false时,配置保留但不触发。cwd:命令工作目录,可以是session或绝对路径;仅用于run。maxConcurrent:同一 hook 的最大并发进程数。debounceMs:高频事件的防抖窗口,单位是毫秒。
典型用法¶
1. 执行命令¶
当某个事件发生时,执行本地命令:
- on: 'turn/end'
when: 'completed'
run: 'node examples/notify-feishu.mjs'
这条配置在 turn/end 且结束原因为 completed 时,启动 node examples/notify-feishu.mjs。
2. 使用桌面通知¶
当审批请求出现时,直接发送平台气泡/提示:
- on: 'approval/asked'
notify:
channel: 'desktop'
这条配置不需要额外脚本,直接由 dsh-hooks 的内置通知处理。
3. 使用 webhook 通知¶
将事件信息 POST 到 HTTP endpoint:
- on: 'turn/end'
when: 'completed'
notify:
channel: 'webhook'
url: 'https://hooks.slack.com/services/…'
slack: true
如果目标是 Slack,可以配置 slack: true,发送一行摘要。
4. 按工具名过滤¶
只监听匹配特定工具名的 tool/call:
- on: 'tool/call'
match:
tool: '^(rm|git|ssh)'
run: 'node examples/notify-webhook.mjs --slack'
这里的 match.tool 是一个正则表达式,用于过滤模型请求调用的工具名。
5. 通过 stdin 传递完整上下文¶
默认情况下,上下文通过 DSH_HOOK_* 环境变量传递。如果脚本需要完整 JSON,可以使用:
- on: 'turn/end'
input: 'stdin'
run: 'node my-hook.mjs'
配置后,完整 context JSON 会写入 node my-hook.mjs 的 stdin。
6. 控制重试¶
对非零退出码进行有限次后台重试:
- on: 'turn/end'
when: 'completed'
run: 'node examples/notify-feishu.mjs'
retries: 2
retryDelayMs: 1000
这里的重试只针对非零退出码。spawn 失败和超时不会进入重试。
7. 控制并发与防抖¶
对高频事件,可以限制并发并做防抖:
- on: 'step/end'
run: 'node examples/log-step.mjs'
debounceMs: 500
maxConcurrent: 2
debounceMs: 500 会在 500 毫秒窗口内合并高频触发;maxConcurrent: 2 会限制同一 hook 的并发进程数。超出上限的触发会被丢弃,并记录为 skipped。
8. 临时禁用某条 hook¶
不想删除配置时,可以保留声明并关闭它:
- on: 'turn/end'
enabled: false
cwd: 'session'
run: 'node examples/log-turn.mjs'
enabled: false 表示这条 hook 不触发,但配置仍然保留。cwd: session 表示命令在 session 的工作目录中运行。
行为说明¶
dsh-hooks 的执行模型偏向“触发外部动作,但不阻塞主流程”:
- 命令执行是 fire-and-forget。
- 命令失败只会
console.warn,默认不会阻塞 DSH 的 agent loop。 run和notify必须二选一。retries只用于非零退出码的后台重试;spawn 失败和超时不重试。maxConcurrent限制同一 hook 的并发进程数;超出上限的触发会被丢弃并记录为 skipped。cwd仅用于run,可以设为session或绝对路径。
依赖与许可证¶
dsh-hooks 的 package 信息中包含以下 peer dependencies:
@deepseek-ai/cordis
@deepseek-ai/dsh-session
@deepseek-ai/schemastery
react
运行时要求:
node >=22
许可证为 MIT。
适用场景¶
dsh-hooks 适合这些场景:
- 希望把 DSH 生命周期事件接到本地脚本或通知系统。
- 需要在
turn/end、tool/call、approval/asked等事件发生时执行轻量自动化。 - 希望发送桌面通知、Slack 风格 webhook 通知,或调用自研脚本。
- 不想为一次事件监听额外维护插件代码,希望直接在 profile 配置里管理。
需要注意:插件中的 run 命令会以当前 DSH 进程拥有的权限执行。安装前建议检查源码、示例脚本和许可证,并确认要执行的命令不会执行危险操作。
结尾¶
dsh-hooks 的价值在于把 DSH 生命周期事件转成低代码的自动化入口:配置 cordis.patch.yml 后,就能在 turn、step、tool、approval、session、agent 等事件上执行命令或发送通知,同时通过 dsh web 的 Hooks 设置页进行管理和测试。
相关链接:
- GitHub 仓库:
https://github.com/PeterBon/dsh-hooks - 插件目录页:当前资料未提供独立 URL;安装后可在
dsh web的设置面板中查看Hooks区域,或在当前 DSH 插件目录入口中检索dsh-hooks。