Hooks 允許在 Qoder CN CLI 的關鍵節點接入 Agent 的主執行流,同時與 CLI 保持解耦。常見用途包括:工具執行前攔截危險操作、任務完成後發送案頭通知、寫檔案後自動跑 lint 等。
Hooks 通過 JSON 設定檔定義,不需要修改代碼,編輯設定檔即可生效。
快速開始
以下樣本示範如何用 Hook 攔截危險命令——當 Agent 嘗試執行 rm -rf 時自動阻止。
第一步:建立指令碼
mkdir -p ~/.qodercn/hooks
cat > ~/.qodercn/hooks/block-rm.sh << 'EOF'
#!/bin/bash
input=$(cat)
command=$(echo "$input" | jq -r '.tool_input.command')
if echo "$command" | grep -q 'rm -rf'; then
echo "危險命令已被阻止: $command" >&2
exit 2
fi
exit 0
EOF
chmod +x ~/.qodercn/hooks/block-rm.sh第二步:編輯設定檔
在 ~/.qodercn/settings.json 中添加:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "~/.qodercn/hooks/block-rm.sh"
}
]
}
]
}
}第三步:驗證效果
啟動 Qoder CN CLI,讓 Agent 執行包含 rm -rf 的命令,Hook 會阻止執行並提示 Agent。
配置
設定檔位置
Hook 配置從以下三個檔案載入,三級配置會被合并執行:
~/.qodercn/settings.json # 使用者級,對所有專案生效
${project}/.qodercn/settings.json # 專案級,對當前專案生效,可提交 git 共用給團隊
${project}/.qodercn/settings.local.json # 專案級(本地),優先順序最高,建議加到 .gitignore配置格式
{
"hooks": {
"事件名": [
{
"matcher": "匹配條件",
"hooks": [
{
"type": "command",
"command": "要執行的命令",
"timeout": 60
}
]
}
]
}
}欄位說明:
欄位 | 必填 | 說明 |
| 是 | 固定為 |
| 是 | 要執行的 shell 命令 |
| 否 | 逾時時間(秒),預設 60 |
| 否 | 匹配條件,不填則匹配所有 |
一個事件下可以配置多個 matcher 分組,每個分組可以包含多個 hook 命令。
matcher 匹配規則
matcher 用於過濾 hook 的觸發範圍,不同事件匹配不同的欄位(見各事件說明)。
寫法 | 含義 | 樣本 |
不填或 | 匹配所有 | 所有工具都觸發 |
精確值 | 精確匹配 |
|
| 匹配多個值 |
|
Regex | 正則匹配 |
|
Hook 指令碼編寫
Hook 指令碼通過 stdin 接收 JSON 輸入,通過 exit code 和 stdout 輸出來控制行為。本節說明所有事件通用的輸入輸出格式,各事件的額外欄位見"支援的事件"。
輸入
Hook 指令碼通過 stdin 接收 JSON 資料。所有事件都包含以下通用欄位:
欄位 | 說明 |
| 當前會話 ID |
| 當前工作目錄 |
| 觸發的事件名稱 |
不同事件會在此基礎上附加額外欄位(見各事件說明)。用 jq 解析輸入:
#!/bin/bash
input=$(cat)
tool_name=$(echo "$input" | jq -r '.tool_name')輸出
Hook 通過 exit code 和 stdout 控制行為。exit code 決定基本行為:0 成功,2 阻塞(stderr 內容注入對話,僅對支援阻塞的事件生效),其他值為非阻塞錯誤。stdout JSON(僅 exit 0 時解析)可為部分事件提供精細控制,具體支援的欄位見各事件說明。exit 非 0 時 stdout 被忽略。
環境變數
Hook 指令碼執行時可以使用以下環境變數:
變數 | 說明 |
| 當前專案的工作目錄 |
支援的事件
Qoder CN CLI 支援以下 Hook 事件,覆蓋會話生命週期的各個階段。
SessionStart
會話開始時觸發。
matcher 匹配: 會話來源
matcher 值 | 觸發情境 |
| 新會話啟動 |
| 恢複已有會話 |
| 上下文壓縮完成後 |
額外輸入欄位:
{
"source": "startup",
"model": "Auto"
}SessionEnd
會話結束時觸發。
matcher 匹配: 結束原因
matcher 值 | 觸發情境 |
| 使用者退出輸入(Ctrl+D 等) |
| 其他原因 |
額外輸入欄位:
{
"reason": "prompt_input_exit"
}UserPromptSubmit
使用者提交 Prompt 後、Agent 處理前觸發。
額外輸入欄位:
{
"prompt": "幫我寫一個排序函數"
}PreToolUse
工具執行前觸發。可以阻止工具執行。
matcher 匹配: 工具名(如 Bash、Write、Edit、Read、Glob、Grep,MCP 工具名如 mcp__server__tool)
額外輸入欄位:
{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf /tmp/build"},
"tool_use_id": "toolu_01ABC123"
}阻止工具執行: exit code 2,stderr 內容作為錯誤返回給 Agent。完整樣本見"快速開始"。
PostToolUse
工具執行成功後觸發。
matcher 匹配: 工具名
額外輸入欄位:
{
"tool_name": "Write",
"tool_input": {"file_path": "/path/to/file.ts", "content": "..."},
"tool_response": "File written successfully",
"tool_use_id": "toolu_01ABC123"
}PostToolUseFailure
工具執行失敗後觸發。
matcher 匹配: 工具名
額外輸入欄位:
{
"tool_name": "Bash",
"tool_input": {"command": "npm test"},
"tool_use_id": "toolu_01ABC123",
"error": "Command exited with non-zero status code 1",
"is_interrupt": false
}Stop
Agent 完成響應後觸發(主 Agent,無待執行的工具調用時)。可以阻止 Agent 停止,讓其繼續工作。
阻止 Agent 停止: exit code 2,stderr 內容作為訊息注入對話,Agent 繼續工作。
SubagentStart / SubagentStop
子 Agent 啟動和完成時觸發。SubagentStop 與 Stop 類似,可以阻止子 Agent 停止。
matcher 匹配: Agent 類型名
額外輸入欄位:
{
"agent_id": "a1b2c3d4",
"agent_type": "task"
}PreCompact
上下文壓縮前觸發。
matcher 匹配: 觸發方式
matcher 值 | 觸發情境 |
| 使用者手動執行 /compact |
| 上下文視窗滿時自動觸發 |
額外輸入欄位:
{
"trigger": "manual",
"custom_instructions": "保留所有工具調用結果"
}Notification
通知事件觸發(許可權請求、任務完成等)。
matcher 匹配: 通知類型
matcher 值 | 觸發情境 |
| 許可權請求通知 |
| Agent 產出結果通知 |
額外輸入欄位:
{
"message": "Agent is requesting permission to run: rm -rf node_modules",
"title": "Permission Required",
"notification_type": "permission"
}PermissionRequest
工具執行需要使用者授權時觸發。
matcher 匹配: 工具名
額外輸入欄位:
{
"tool_name": "Bash",
"tool_input": {"command": "rm -rf node_modules"}
}實用情境
案頭通知提醒
當 Agent 完成任務或需要授權時,彈出案頭通知。指令碼 ~/.qodercn/hooks/notify.sh(macOS):
#!/bin/bash
input=$(cat)
message=$(echo "$input" | jq -r '.message')
if echo "$message" | grep -q "^Agent"; then
osascript -e 'display notification "任務執行完成" with title "Qoder CN CLI"'
else
osascript -e 'display notification "任務需要授權" with title "Qoder CN CLI"'
fi
exit 0配置:
{
"hooks": {
"Notification": [
{
"hooks": [
{
"type": "command",
"command": "~/.qodercn/hooks/notify.sh"
}
]
}
]
}
}寫檔案後自動 Lint
每次 Agent 寫入或編輯檔案後,自動執行 lint 檢查。指令碼 ${project}/.qodercn/hooks/auto-lint.sh:
#!/bin/bash
input=$(cat)
file_path=$(echo "$input" | jq -r '.tool_input.file_path')
# 只檢查 JS/TS 檔案
case "$file_path" in
*.js|*.ts|*.jsx|*.tsx)
npx eslint "$file_path" --fix 2>/dev/null
;;
esac
exit 0配置:事件 PostToolUse,matcher Write|Edit,command .qodercn/hooks/auto-lint.sh。
讓 Agent 繼續工作
在 Agent 停止時檢查是否還有未完成的任務,如果有則注入訊息讓 Agent 繼續。指令碼 ~/.qodercn/hooks/check-continue.sh:
#!/bin/bash
# 檢查是否有未提交的 git 變更
if [ -n "$(git status --porcelain 2>/dev/null)" ]; then
echo "檢測到未提交的變更,請完成 git commit" >&2
exit 2
fi
exit 0配置:事件 Stop,command ~/.qodercn/hooks/check-continue.sh。