Hook 系统允许用户在 Claude Code 的关键生命周期节点注入 shell 命令,实现自动化拦截和扩展。

Hook 事件类型

事件触发时机
PreToolUsetool 执行前
PostToolUsetool 执行后
SessionStart会话启动时
Stop会话结束时

Hook 配置格式(settings.json)

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash*",
        "hooks": [
          { "type": "command", "command": "my-pre-hook.sh", "timeout": 30 }
        ]
      }
    ]
  }
}

matcher 支持:

  • 空字符串:匹配所有 tool
  • 精确匹配:Bash
  • 通配符后缀:Bash*(匹配以 Bash 开头的所有 tool)

Hook 输入

Hook 通过 stdin 接收 JSON payload(HookInput):

{
  "session_id": "...",
  "transcript_path": ".claude/transcript.json",
  "cwd": "/path/to/project",
  "permission_mode": "default",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_use_id": "...",
  "tool_input": { "command": "ls -la" }
}

PostToolUse 额外包含 tool_response 字段。

Hook 输出控制

Hook 可以通过 stdout 输出 JSON 来控制行为(HookJSONOutput):

字段说明
continue: false阻止后续操作(附 stopReason)
suppressOutput: true抑制输出显示
decision: "approve"批准 tool 使用(PreToolUse)
decision: "block"拒绝 tool 使用,并返回 reason
permissionDecision"allow" / "deny" / "ask"
systemMessage注入 system message
updatedInput修改 tool 输入(PreToolUse)
initialUserMessage注入初始用户消息(SessionStart)

退出码约定

退出码含义
0成功(解析 JSON 输出)
2阻塞性错误(stderr/stdout 作为错误消息)
其他非零非阻塞错误(记录但继续)

聚合逻辑

多个 hook 的结果通过 AggregateResults() 合并,规则:

  • 任意一个 blocking → 聚合结果为 blocking
  • systemMessage、permissionBehavior、updatedInput 最后一个值获胜
  • additionalContext 换行拼接
  • retry 任一为 true → 整体 retry

执行环境

Hook 命令以 sh -c(Unix)执行,工作目录为项目根目录,环境变量中额外注入 CLAUDE_PROJECT_DIR。

相关页面