Hooks 系統
使用現行 nested hooks schema,自動化並執行 Claude Code 生命週期規則。
你將學到什麼
Hooks 會在 Claude Code 生命週期的明確時間點執行 deterministic automation。它們可以稽核活動、加入 context、格式化檔案,或在行動發生前阻擋它。
現行 settings schema 是 nested 結構:
hooks
└── event name
└── matcher group
└── hooks
└── handler
不要再使用舊的 flat event-to-command 格式。
設定 Hook
依所需 scope,把 hooks 放在 user、project 或 local settings。以下 project hook 會在 Bash 指令執行前檢查它:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/check-command.sh",
"timeout": 30
}
]
}
]
}
}
外層 key 選擇 event;matcher group 過濾該 event;內層 hooks array 放置一個或多個 handlers。目前 handler types 包含 command、http、mcp_tool、prompt,以及仍屬實驗功能的 agent hooks。
使用 /hooks 檢查實際生效的設定與來源。選單是唯讀的;要改變行為,請編輯對應 settings file。
主要生命週期事件
Hooks 不只四種事件。應選擇決策仍來得及發揮作用的準確時間點。
| 階段 | 主要事件 | 常見用途 |
|---|---|---|
| Session | SessionStart, SessionEnd | 載入 context、初始化或封存 |
| User turn | UserPromptSubmit, Stop, StopFailure | 驗證輸入、強制完成條件、記錄失敗 |
| Tool call | PreToolUse, PermissionRequest, PostToolUse, PostToolUseFailure | 阻擋、核准、稽核或回應 tools |
| Workers 與 teams | SubagentStart, SubagentStop, TeammateIdle, TaskCreated, TaskCompleted | 觀察 workers 並執行 quality gates |
| Context 與設定 | PreCompact, PostCompact, ConfigChange, InstructionsLoaded | 保護 context 轉換與設定變更 |
| Worktrees | WorktreeCreate, WorktreeRemove | 自訂隔離環境的建立與清理 |
Reference 還包含其他 events 與精確 matchers。請把該清單視為會隨版本更新的文件,不要永久複製成自己的 enum。
Command Hook 輸入
Command hooks 從 stdin 接收 JSON。共同 fields 包含 session_id、cwd、hook_event_name,每種 event 再加入自己的 fields。例如 PreToolUse 會提供 tool_name、tool_input、tool_use_id。
#!/usr/bin/env bash
set -euo pipefail
payload=$(< /dev/stdin)
command=$(jq -r '.tool_input.command // ""' <<< "$payload")
if [[ "$command" == rm\ * ]]; then
echo "Blocked by project policy" >&2
exit 2
fi
exit 0
Hook scripts 應短小、deterministic 且快速。不同 events 的 payload 不同,因此必須處理缺少 fields 的情況。
輸出與阻擋規則
對 command hooks 而言:
- exit
0:成功;Claude Code 可解析 stdout 的 JSON; - exit
2:對仍可阻擋的 events 表示 blocking error,feedback 來自 stderr; - 其他 non-zero code:對大多數 events 是 non-blocking error;
WorktreeCreate是重要例外:任何 non-zero exit 都會中止建立。
Event 決定「阻擋」的實際意義。PreToolUse 可以在 tool 執行前停止它;PostToolUse 無法復原已執行的 tool。Stop 可以要求 agent 繼續工作,但 SessionEnd 無法阻止已在結束的 session。
若要對 PreToolUse 做 structured control,請在 exit 0 時回傳 JSON:
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "Database writes are not allowed"
}
}
Decision fields 依 event 而異。應從該 event 的官方 reference 複製,不要把某個 event 的 schema 套用到所有 hooks。
安全規則
- 為 variables 加上適當 quoting,並使用真正的 JSON parser。
- Project scripts 使用 absolute paths 或
${CLAUDE_PROJECT_DIR}。 - 不要把 secrets 或完整 environment 印到 hook output。
- 預防行為優先使用
PreToolUse;post events 用於觀察與後續處理。 - 所有符合條件的 hooks 可能平行執行;不要讓多個 hooks 競爭改寫同一份 input。
- 以代表性的 stdin JSON 測試 scripts,再用
/hooks驗證已註冊。
Hooks 即使在寬鬆模式也能收緊政策,但 allow response 不能蓋過更強的 deny rule。請把 hooks 設計成 enforcement layer,而不是 permissions bypass。
官方來源
下一課
下一課將透過受支援的 commands 與 IDs 管理 session 連續性,而不是解析 private transcript structures。