跳转至

Hooks

重要性:⭐⭐⭐⭐ 目标读者:Claude Code 高级用户 / 团队管理员 关联topics/deep-dive-main.mdtutorials/build-hook.md


1. Hook 概述

Hook = Claude Code 生命周期事件的自动响应 - 用户级 / 项目级 / Plugin - 9 种事件 - 3 种类型(command / prompt / agent)


2. 9 种 Hook 事件

事件 触发时机 可用
PreToolUse 工具调用前 matcher
PostToolUse 工具调用后 matcher
SessionStart 会话开始 matcher
SessionEnd 会话结束 matcher
Notification 通知触发 -
Stop Claude 停止生成 -
SubagentStop sub-agent 停止 -
UserPromptSubmit 用户提交 -
PreCompact 压缩前 -

9 种


3. 3 种 Hook 类型

3.1 command

{
  "type": "command",
  "command": "/path/to/script.sh",
  "timeout": 30
}

执行 shell 脚本

3.2 prompt

{
  "type": "prompt",
  "prompt": "Decide if this is safe"
}

LLM 评估

3.3 agent

{
  "type": "agent",
  "agent": "reviewer",
  "prompt": "Review this code"
}

Agent 循环


4. Hook 配置位置

4.1 用户级

~/.claude/settings.json

个人

4.2 项目级

.claude/settings.json

项目

4.3 Plugin 内

<plugin>/hooks/hooks.json

Plugin


5. Hook 完整配置

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash|Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "~/.claude/hooks/validate.sh",
            "timeout": 10
          },
          {
            "type": "prompt",
            "prompt": "Is this change safe? Respond approve/block."
          }
        ]
      }
    ]
  }
}

4 层结构:hooks.[].matcher + hooks[]。

5.1 matcher

"matcher": "Bash"              // 单个
"matcher": "Bash|Edit|Write"   // 多个
"matcher": "*"                  // 所有
"matcher": "mcp__github__*"    // MCP 工具

4 种

5.2 timeout

"timeout": 30  // 秒

默认 60s(推测)。

5.3 多个 hook

{
  "matcher": "Bash",
  "hooks": [
    { "type": "command", "command": "hook1.sh" },
    { "type": "command", "command": "hook2.sh" }
  ]
}

多个 hook 顺序执行。


6. Command Hook I/O

6.1 stdin (input)

{
  "session_id": "...",
  "transcript_path": "...",
  "cwd": "...",
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "ls" }
}

8 字段

6.2 stdout / exit code

exit 含义
0 允许
2 阻止 + stderr → user
其他 错误,不阻止

3 种

6.3 输出捕获

# stdout 包含 JSON 时(如 hookSpecificOutput)
# Claude Code 会解析

stdout 解析


7. Prompt Hook I/O

7.1 stdin

{
  "hook_event_name": "PreToolUse",
  "tool_name": "Bash",
  "tool_input": { "command": "ls" }
}

类似

7.2 stdout

{
  "decision": "approve" | "block",
  "reason": "..."
}

2 字段


8. Agent Hook I/O

8.1 stdin

同 prompt。

8.2 stdout

{
  "decision": "approve" | "block",
  "reason": "..."
}

同 prompt


9. 5 个实战 Hook

9.1 Bash 危险命令拦截

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [{
          "type": "command",
          "command": "~/.claude/hooks/block-dangerous.sh",
          "timeout": 5
        }]
      }
    ]
  }
}

block

9.2 Edit 后自动 format

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [{
          "type": "command",
          "command": "~/.claude/hooks/format.sh"
        }]
      }
    ]
  }
}

auto-format

9.3 每次 user prompt 通知

{
  "hooks": {
    "UserPromptSubmit": [{
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/log-prompt.sh"
      }]
    }]
  }
}

logging

9.4 Session start 注入 context

{
  "hooks": {
    "SessionStart": [{
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/load-context.sh"
      }]
    }]
  }
}

load

9.5 PreCompact 备份

{
  "hooks": {
    "PreCompact": [{
      "hooks": [{
        "type": "command",
        "command": "~/.claude/hooks/backup.sh"
      }]
    }]
  }
}

backup


10. 6 个最佳实践

  1. 可幂等 —— 重跑结果一致
  2. 快速失败 —— 5-30s timeout
  3. 明确退出码 —— 0 / 2 / 其他
  4. 不阻塞主流程 —— async 友好
  5. 路径校验 —— 防止 ../ 跳出
  6. 不存敏感 —— stderr 别打 password

6 条


11. 安全考虑

11.1 不 sudo

# ❌ sudo hook
"command": "sudo ~/.claude/hooks/foo.sh"

不要 sudo

11.2 路径白名单

# ✅ 只在 ~/.claude/ 操作
case "$FILE" in
  ~/.claude/*) ;;
  *) exit 1 ;;
esac

白名单

11.3 输入校验

echo "$INPUT" | jq . > /dev/null || exit 1

JSON 校验

11.4 不泄露

# ❌ 打印整个 input
echo "$INPUT"

# ✅ 过滤
echo "$INPUT" | jq 'del(.tool_input.password)'

过滤


12. 调试

12.1 直接测

echo '{"hook_event_name":"PreToolUse","tool_name":"Bash","tool_input":{"command":"ls"}}' | \
  ~/.claude/hooks/my-hook.sh
echo $?

直接

12.2 debug mode

claude --debug hooks

debug

12.3 看 log

tail ~/.claude/logs/<date>.jsonl | grep hook

log


13. 完整示例

// .claude/settings.json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/block-danger.sh", "timeout": 5 }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/format.sh" }
        ]
      }
    ],
    "UserPromptSubmit": [
      {
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/log.sh" }
        ]
      }
    ],
    "SessionStart": [
      {
        "hooks": [
          { "type": "command", "command": "~/.claude/hooks/welcome.sh" }
        ]
      }
    ]
  }
}

完整


14. 写第一个 hook

tutorials/build-hook.md 教程。


15. 总结

Hook = 生命周期事件自动响应

核心: - 9 种事件 - 3 种类型 - 3 种退出码 - 6 个最佳实践 - 4 个安全考虑

下一步:写一个 hook → 测试 → 部署。