本文是 Claude Code Hooks 系统的完整技术参考。Hooks 是用户定义的 Shell 命令、HTTP 端点或 LLM Prompt,在 Claude Code 生命周期的特定节点自动执行。如需快速上手示例,请先阅读Hooks 实战指南。
Hook 生命周期概览
| 事件 | 触发时机 |
|---|---|
SessionStart | 会话开始或恢复时 |
InstructionsLoaded | CLAUDE.md 或 .claude/rules/*.md 加载到上下文时 |
UserPromptSubmit | 用户提交提示词后,Claude 处理前 |
PreToolUse | 工具调用执行前(可阻止) |
PermissionRequest | 权限对话框出现时 |
PostToolUse | 工具调用成功后 |
PostToolUseFailure | 工具调用失败后 |
Notification | Claude Code 发送通知时 |
SubagentStart | Subagent 启动时 |
SubagentStop | Subagent 结束时 |
Stop | Claude 完成响应时 |
TeammateIdle | Agent 团队成员即将进入空闲时 |
TaskCompleted | 任务被标记为完成时 |
ConfigChange | 会话中配置文件变更时 |
WorktreeCreate | Worktree 创建时(替换默认 git 行为) |
WorktreeRemove | Worktree 被删除时 |
PreCompact | 上下文压缩前 |
SessionEnd | 会话结束时 |
配置结构
// settings.json
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": ".claude/hooks/check-cmd.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write $CLAUDE_TOOL_INPUT_PATH",
"background": true
}
]
}
]
}
}Hook 处理器字段
通用字段
| 字段 | 说明 |
|---|---|
type | "command"、"http"、"prompt" 或 "agent" |
background | true = 异步运行,不等待结果(见下文) |
Command Hook 字段
| 字段 | 说明 |
|---|---|
command | 要执行的 Shell 命令字符串 |
timeout | 超时秒数(默认无限制) |
HTTP Hook 字段
| 字段 | 说明 |
|---|---|
url | 目标端点(必须是 allowedHttpHookUrls 中允许的 URL) |
method | HTTP 方法(默认 POST) |
headers | 请求头对象 |
timeout | 超时秒数 |
Prompt 和 Agent Hook 字段
| 字段 | 说明 |
|---|---|
prompt | 传给 LLM 的提示词(prompt 类型) |
agent | Agent 名称(agent 类型) |
model | 使用的模型(默认 Haiku) |
Matcher 模式
Matcher 控制哪些事件触发 Hook:
{ "matcher": "Edit|Write" } // 匹配 Edit 或 Write 工具
{ "matcher": "Bash(git *)" } // 匹配 git 开头的 Bash 命令
{ "matcher": "mcp__github" } // 匹配 github MCP 服务器所有工具
{ "matcher": "mcp__github__create_issue" } // 匹配特定 MCP 工具
{ "matcher": "" } // 匹配所有(等同 *)Hook 输入/输出
输入(stdin / POST body)
Command Hook 通过 stdin 接收 JSON:
{
"hook_event_name": "PreToolUse",
"session_id": "abc123",
"tool_name": "Bash",
"tool_input": { "command": "npm test" }
}退出码含义
| 退出码 | 含义 |
|---|---|
0 | 成功,继续执行 |
2 | 阻止当前工具调用(仅 PreToolUse) |
| 其他非零 | 显示错误但继续 |
每种事件的退出码 2 行为
| 事件 | 退出码 2 效果 |
|---|---|
PreToolUse | 阻止工具调用 |
UserPromptSubmit | 阻止将提示词发给 Claude |
Stop | 阻止 Claude 停止(让 Claude 继续运行) |
TeammateIdle | 阻止成员进入空闲 |
TaskCompleted | 阻止任务标记为完成 |
JSON 输出(结构化决策)
Command Hook 的 stdout 如果是有效 JSON,Claude Code 解析为结构化输出:
// PreToolUse:拒绝工具调用
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "deny",
"permissionDecisionReason": "危险命令已被拦截"
}
}
// PreToolUse:允许并修改输入
{
"hookSpecificOutput": {
"hookEventName": "PreToolUse",
"permissionDecision": "allow",
"updatedInput": { "command": "npm test 2>&1 | grep -E '(FAIL|ERROR)' | head -50" }
}
}
// Stop:要求 Claude 继续
{
"hookSpecificOutput": {
"hookEventName": "Stop",
"decision": "block",
"reason": "请先运行测试套件再停止"
}
}SessionStart:持久化环境变量
SessionStart Hook 可以在 JSON 输出中设置环境变量,这些变量会被注入到该会话的所有后续工具调用中:
{
"hookSpecificOutput": {
"hookEventName": "SessionStart",
"env": {
"PROJECT_ENV": "production",
"DATABASE_URL": "postgresql://..."
}
}
}异步 Hook(background: true)
异步 Hook 不阻塞 Claude Code 执行流程:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/run-tests.sh",
"background": true
}
]
}
]
}
}异步 Hook 行为:
- Hook 在后台启动,Claude Code 立即继续
- 后台进程 stdout/stderr 不进入 Claude 上下文
- 退出码被忽略(不能阻止工具调用)
- 适合:运行测试、发送通知、记录日志
示例:文件变更后在后台运行测试:
#!/bin/bash
# ~/.claude/hooks/run-tests.sh
FILE=$(cat /dev/stdin | jq -r '.tool_input.path // empty')
if [[ "$FILE" == *.ts ]] || [[ "$FILE" == *.js ]]; then
cd "$(git rev-parse --show-toplevel)"
npm test --silent > /tmp/test-results.log 2>&1 || true
echo "Test run complete: $(tail -1 /tmp/test-results.log)" >> /tmp/hook-log.txt
fiPrompt-based Hook
使用 LLM 评估条件,适合需要判断力而非规则的场景:
{
"hooks": {
"Stop": [
{
"hooks": [
{
"type": "prompt",
"prompt": "Review the work done this session. If all tests pass and documentation is updated, allow stop. Otherwise block and explain what's missing.",
"model": "haiku"
}
]
}
]
}
}Prompt Hook 响应 Schema:
{
"decision": "allow", // allow | block
"reason": "可选原因"
}WorktreeCreate Hook(自定义 Worktree 创建)
WorktreeCreate Hook 完全替换 Claude Code 的默认 git worktree 创建行为:
{
"hooks": {
"WorktreeCreate": [
{
"hooks": [
{
"type": "command",
"command": "~/.claude/hooks/create-worktree.sh"
}
]
}
]
}
}Hook 输出(指定 worktree 路径):
{
"hookSpecificOutput": {
"hookEventName": "WorktreeCreate",
"worktreePath": "/path/to/custom/worktree"
}
}调试 Hook
# 启用 Hook 调试日志
export CLAUDE_CODE_HOOK_DEBUG=1
claude
# 查看 Hook 输出
# 检查 /tmp/hook-debug.log(自己在脚本中写)通过 /hooks 菜单查看已配置的 Hook;在设置中临时禁用 Hook 调试问题。
原文:Hooks reference - Claude Code Docs | 来源:Anthropic 官方文档