dsh-hooks-plugin:爲 DeepSeek Harness 提供 Claude Code 風格 hooks

前言

在 DeepSeek Harness(DSH)裏,很多流程需要掛在具體事件上:工具調用前攔截、工具調用後記錄、用戶提交時補檢查、會話開始或結束時寫狀態。若這些邏輯散落在各個腳本里,後續排查和遷移都會比較麻煩。

dsh-hooks-plugin 提供 Claude Code 風格的 hooks:在智能體 / 工具生命週期事件上運行 shell 命令,配置來自 .dsh/hooks.json。

這是什麼

dsh-hooks-plugin 由 KYinCode 維護,採用 MIT 許可證。它爲 DSH 增加一個 hooks 入口,讓開發者在項目、預設或全局層面配置事件響應命令。

核心定位如下:

在 DSH 的 agent / tool 生命週期事件上運行 shell 命令;
配置使用 .dsh/hooks.json;
JSON 結構延續 Claude Code hooks 形狀。

核心功能

四層配置

hooks 配置按目錄生命週期管理,支持四層來源:

全局:~/.dsh/hooks.json
預設:<preset-dir>/hooks.json
項目:<項目根>/.dsh/hooks.json
項目本地:.dsh/hooks.local.json

項目配置改動後會自動重新加載,不需要重啓。

v1 接線事件

v1 實際接線以下事件:

PreToolUse
PostToolUse
PostToolUseFailure
UserPromptSubmit
SessionStart
SessionEnd
Stop
SubagentEnd

其中 PreToolUse 支持通過 stdout 輸出 deny 決策。deny 時會出現官方工具失敗卡片,模型會看到類似這樣的內容:

Error: <reason>

hook 類型與字段

v1 實現 command 與 http 型 hook;prompt / agent 型 hook v1 不做。

hook 公共字段包括:

if
timeout
statusMessage
once

command 型可配置:

command
shell
async
asyncRewake

http 型可配置:

url
headers
allowedEnvVars

配置結構使用 matcher[] + hooks[]:

{
  "<Event>": [
    {
      "matcher": "<模式>",
      "hooks": []
    }
  ]
}

子代理觸發

子代理默認會觸發 hooks,輸入載荷會攜帶:

agent_id
agent_type
delegation_depth

如果需要關閉子代理觸發,可以配置:

{
  "subagents": false
}

熱重載與熱升級

項目配置改動會自動重新加載,無需重啓。

如果安裝了 dsh-hot-installer,升級插件後可以免重啓當場生效:

dsh plugin --profile web add dsh-hooks-plugin@<新版本>

最近記錄與日誌

每條 hook 記錄會寫入最近記錄文件:

recent.jsonl

默認限 200 條,可用環境變量調整:

DSH_HOOKS_RECENT_MAX

文件日誌位於:

~/.dsh/logs/dsh-hooks/dsh-hooks.log

默認超過 1 MiB 自動滾動,可用環境變量調整:

DSH_HOOKS_MAX_LOG_BYTES

最近記錄接口:

GET /dsh-hooks/recent

安裝與啓用

npm 安裝:

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

若使用本地 tarball,可先打包,再把生成的 tarball 交給 dsh 安裝:

npm pack
dsh plugin --profile web add ./<npm pack 生成的 dsh-hooks-plugin tarball>

安裝後新會話自動生效;已有存活會話也會生效。進程重啓後繼續舊會話,會隨 agent 重建自動重新接線。

插件對運行環境有 peerDependencies 要求:

{
  "peerDependencies": {
    "@deepseek-ai/cordis": "^4.0.1",
    "@deepseek-ai/dsh-shell": "^0.1.0-rc.6",
    "@deepseek-ai/dsh-subprocess": "^0.1.0-rc.6",
    "react": "^18.2.0"
  }
}

典型用法

在工具調用前觸發命令

在項目根創建:

<項目根>/.dsh/hooks.json

示例配置如下:

{
  "PreToolUse": [
    {
      "matcher": "Read|Write|Edit",
      "hooks": [
        {
          "type": "command",
          "command": "echo hook triggered",
          "timeout": 5
        }
      ]
    }
  ]
}

這條配置會在 Read、Write、Edit 工具調用前運行:

echo hook triggered

用 PreToolUse 對私有路徑 deny

示例中對 Read 事件配置條件過濾:

{
  "PreToolUse": [
    {
      "matcher": "Read",
      "hooks": [
        {
          "type": "command",
          "command": "node -e \"process.stdout.write(JSON.stringify({hookSpecificOutput:{hookEventName:'PreToolUse',permissionDecision:'deny',permissionDecisionReason:'blocked'}}))\"",
          "if": "Read(*private*)",
          "timeout": 5
        }
      ]
    }
  ]
}

當 Read 命中 *private* 條件時,hook 通過 stdout 輸出 deny 決策。PreToolUse 決策 deny 時,會出現官方工具失敗卡片,模型會看到 Error: <reason>。

命令 hook 的 stdin / stdout

命令 hook 從 stdin 讀取單行 JSON 輸入。常見字段包括:

{
  "session_id": "...",
  "cwd": "...",
  "hook_event_name": "PreToolUse",
  "tool_name": "read",
  "tool_input": {
    "path": "..."
  },
  "tool_use_id": "..."
}

如果是子代理觸發,還會包含:

{
  "agent_id": "...",
  "agent_type": "...",
  "delegation_depth": 0
}

命令 hook 通過 stdout 輸出 JSON 決策。hookSpecificOutput 可包含:

{
  "hookSpecificOutput": {
    "hookEventName": "PreToolUse",
    "permissionDecision": "deny",
    "permissionDecisionReason": "blocked",
    "additionalContext": "..."
  }
}

開發驗證與查看

運行測試:

node --test test/

查看文件日誌:

~/.dsh/logs/dsh-hooks/dsh-hooks.log

查看最近記錄:

GET /dsh-hooks/recent

安裝後可以先加載自動註冊技能:

skill dsh-hooks-authoring

深度配置查看安裝包內文檔:

docs/CONFIGURATION.md

適用場景與注意

適合以下場景:

在工具調用前做攔截或檢查;
在工具調用後做審計、記錄或後續動作;
在會話開始、結束、用戶提交等事件上運行固定流程;
爲項目、預設或全局配置不同層級的 hooks;
在 DSH 中保持 Claude Code hooks 風格的 JSON 配置體驗。

需要注意:

hooks 會執行 shell 命令,會以當前 dsh 進程權限運行;
安裝前應檢查源碼與 MIT 許可證;
配置的生命週期等於它所在目錄的生命週期;
若某預設報 Cannot find package,通常需手動移除對應行或刪除預設目錄;
v1 不做 prompt / agent 型 hook;
parseHookConfig 會拒絕未知類型;
不做卸載生命週期、懸空行提醒、會話級配置檔、PreCompact / PostCompact、設置頁;
不注入 CLAUDE_PROJECT_DIR、CLAUDE_PLUGIN_ROOT 等 CC 專屬環境變量;
不做 ${CLAUDE_PLUGIN_ROOT}、CLAUDE_PLUGIN_OPTION_*、CLAUDE_ENV_FILE 等機制。

DSH 內部決策直接消費 waterfall 返回值。stdout JSON 是命令 hook 表達決策的協議手段,不是按 Claude Code 輸出解析。

鏈接

社區目錄頁(獨立站點,不等同於 DeepSeek 或幻方的官方應用商店):

https://www.skillhub.cn/plugins/KYinCode/dsh-hooks-plugin

GitHub:

https://github.com/KYinCode/dsh-hooks-plugin
羽毛球分组比赛记分
小程序二维码

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

小夜