前言¶
在 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