dsh-hooks-lite:用配置声明 DSH 生命周期钩子

前言

在 DeepSeek Harness(DSH)里跑智能体时,常见需求是:工具调用前做拦截、编辑文件后跑 lint、一轮对话结束时发通知。若每次都在插件里写 TypeScript 并打包客户端,成本偏高。Claude Code、Codex 等环境已把「配置驱动生命周期钩子」做成熟悉模式;DSH 侧已有 tools/pre-execute、tools/post-execute、session/event 等接缝,但缺少一个体量小、贴近宿主配置方式的钩子插件。下面介绍社区插件 dsh-hooks-lite(维护者 xuedipiaofei,分类:工作流),它用 YAML/JSON 声明 event → shell command,不写插件业务代码、不打包 Web GUI、无运行时 npm 依赖。

这是什么

dsh-hooks-lite 的定位是:面向 DeepSeek Harness 的轻量、配置驱动生命周期钩子。在 cordis.patch.yml 或 $DSH_HOME/hooks.json 里列出钩子;宿主在对应事件触发时用 Node 子进程执行 run 指定的命令,并向 stdin 写入稳定 JSON 契约,同时注入 DSH_HOOK_* 等环境变量。它不是 .claude/settings.json 的兼容层;需要多 harness 格式时应另选适配器,本插件保持 DSH 原生、可读的配置形态。

核心功能

事件与拦截能力

on 时机 能否阻断
pre-tool 模型工具调用前 可以:非零退出码拒绝本次调用
post-tool 工具调用结束后 否
turn/end 一轮结束 否;可用 when 按 reason 过滤
step/end 一步结束 否
user/message 出现用户角色消息 否
session/title 会话标题变更 否

pre-tool / post-tool 可用 tools 限定工具名;match 用字段路径到正则(如 args.command);turn/end 可用 when: [error, aborted] 等形式过滤。

配置字段要点

  • id:稳定唯一标识(默认 hook-N)。
  • on(别名 event)、run(别名 command):必填。
  • timeoutMs 默认 10000;pre-tool 超时视同阻断。
  • cwd:默认插件进程 cwd;session 表示会话 cwd。
  • stdin 默认 true;block 对 pre-tool 默认 true(非零退出即拒绝)。
  • enabled、env 等见仓库 README 字段表。

内联 config.hooks 与文件 $DSH_HOME/hooks.json 可并用;文件钩子先加载,内联追加。可通过插件行的 configFile 覆盖文件路径(相对路径相对 $DSH_HOME)。

斜杠命令

  • /hooks:查看已配置钩子、配置告警与近期运行。
  • /hooks-reload:重新读取 $DSH_HOME/hooks.json(内联钩子不变)。

运行环境

package.json 声明 DSH 引擎:>=0.2.1-rc.3 <0.3.0。当前 npm 包版本 0.1.0,许可证 MIT。

安装与启用

从 npm 安装到 web profile:

dsh plugin --profile web add dsh-hooks-lite

从 GitHub 安装:

dsh plugin --profile web add github:xuedipiaofei/dsh-hooks-lite

本地开发路径安装示例:

dsh plugin --profile demo add ./dsh-hooks-lite

安装后 bundle 会插入一条 dsh-hooks-lite 插件行;在 profile patch 里补充 config.hooks,或单独维护 $DSH_HOME/hooks.json。

典型用法

在 profile patch 中声明钩子

下面这段来自仓库 README,展示拦截危险 rm -rf、编辑后 lint、回合完成通知三类钩子:

- id: dsh-hooks-lite
  name: dsh-hooks-lite
  config:
    hooks:
      - id: guard-rm
        on: pre-tool
        tools: [bash, pwsh]
        match:
          args.command: 'rm\s+-rf'
        run: node hooks/guard.mjs
      - id: lint-after-edit
        on: post-tool
        tools: [edit, write]
        run: npm run lint -- --quiet
        timeoutMs: 30000
      - id: notify-done
        on: turn/end
        when: completed
        run: node hooks/notify.mjs

pre-tool 拒绝调用

命令从 stdin 读取 JSON;pre-tool 非零退出时,stderr(或 stdout)作为拒绝原因。README 中的 guard 示例逻辑如下:

// hooks/guard.mjs
const payload = JSON.parse(await new Promise((resolve) => {
  let body = ''
  process.stdin.on('data', (chunk) => (body += chunk))
  process.stdin.on('end', () => resolve(body))
}))
if (payload.args.command.includes('rm -rf')) {
  console.error('refusing destructive command')
  process.exit(1)
}

stdin 载荷示例(字段以实际运行为准):

{
  "source": "dsh-hooks-lite",
  "event": "pre-tool",
  "eventName": "PreToolUse",
  "hookId": "guard-rm",
  "sessionId": "session-...",
  "cwd": "/path/to/project",
  "toolName": "bash",
  "args": { "command": "rm -rf build" }
}

环境变量包括:DSH_HOOK_ID、DSH_HOOK_EVENT、DSH_HOOK_CWD、DSH_SESSION_ID、DSH_TOOL_NAME、CLAUDE_PROJECT_DIR。

独立 hooks.json

{
  "hooks": [
    {
      "id": "from-file",
      "on": "post-tool",
      "tools": ["edit"],
      "run": "npm run lint"
    }
  ]
}

默认路径:$DSH_HOME/hooks.json。

适用场景与注意

适合谁:希望在 DSH 里用 shell/Node 脚本做工具前后检查、CI 式 lint、会话事件通知,且不想维护完整插件代码与客户端 bundle 的开发者。

安全与权限:README 明确说明,钩子是受信任的主机配置——命令以 DSH 宿主进程权限运行,不在模型工具沙箱内。只启用自己编写或审阅过的钩子;pre-tool 可阻断工具调用,post/session 钩子为 fire-and-forget,不会改变模型输出。安装前建议阅读源码与 MIT 许可证。

生态说明:DSH 采用「一切皆插件」思路;社区插件目录为独立站点(如 SkillHub 上的条目页),与 DeepSeek / 幻方无官方从属关系,本文不将其描述为官方应用商店。

参考链接

  • 社区目录页:https://www.skillhub.cn/plugins/xuedipiaofei/dsh-hooks-lite
  • 源码与文档:https://github.com/xuedipiaofei/dsh-hooks-lite

经过上面的步骤,你可以在 profile 或 $DSH_HOME/hooks.json 里用声明式配置把 DSH 已有生命周期接缝接到日常 shell 工作流上,并保持零运行时依赖与可热重载的文件配置。

羽毛球分组比赛记分
小程序二维码

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

小夜