toMedia
Claude Code CLI

Hooks 系统

Claude Code 的钩子系统 — 在工具调用前后自动执行自定义命令

概述

Hooks 允许你在 Claude Code 执行工具的前后自动运行 shell 命令。通过 Hooks,你可以:

  • 工具调用前进行验证或注入上下文
  • 工具调用后运行 linter、测试或自动修复
  • 会话启动时加载项目配置
  • 自动化重复性检查

Hook 事件类型

事件触发时机
PreToolUse工具执行之前
PostToolUse工具执行之后
SessionStart会话启动、恢复、清除时
UserPromptSubmit用户发送消息后
StopClaude 完成回复时

配置方式

settings.json 中配置 hooks:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "echo '即将修改文件: $TOOL_INPUT'"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx eslint --fix $FILE_PATH 2>/dev/null || true"
          }
        ]
      }
    ],
    "SessionStart": [
      {
        "matcher": "startup|resume|clear|compact",
        "hooks": [
          {
            "type": "command",
            "command": "cat .claude/project-context.md"
          }
        ]
      }
    ]
  }
}

matcher 规则

matcher 使用正则表达式匹配:

{
  "matcher": "Write|Edit",
  "hooks": [...]
}
  • "Write|Edit" — 匹配 Write 或 Edit 工具
  • "Bash" — 匹配 Bash 工具
  • ".*" — 匹配所有工具
  • "startup|resume" — 仅在启动或恢复时(SessionStart)

Hook 输入与输出

输入(环境变量)

Hook 命令可以访问以下环境变量:

变量说明
$TOOL_NAME工具名称(如 Write
$TOOL_INPUT工具输入(JSON 字符串)
$FILE_PATH文件路径(文件工具)
$SESSION_ID当前会话 ID

输出格式

Hook 通过 stdout 返回结果,输出 JSON:

{
  "decision": "allow",
  "reason": "检查通过"
}

decision 可选值:

  • "allow" — 允许工具执行
  • "block" — 阻止工具执行
  • "modify" — 修改工具输入

还可以返回 additionalContext 注入额外上下文:

{
  "decision": "allow",
  "additionalContext": "注意:这个文件有特殊的编码要求"
}

实用示例

自动格式化

每次写入或编辑文件后自动运行格式化:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}

阻止危险操作

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "node -e \"const input = JSON.parse(process.env.TOOL_INPUT || '{}'); if (input.command && input.command.includes('rm -rf')) { console.log(JSON.stringify({decision:'block',reason:'禁止执行 rm -rf'})); } else { console.log(JSON.stringify({decision:'allow'})); }\""
          }
        ]
      }
    ]
  }
}

会话启动时注入上下文

{
  "hooks": {
    "SessionStart": [
      {
        "matcher": "startup",
        "hooks": [
          {
            "type": "command",
            "command": "echo '当前分支:' && git branch --show-current && echo '未提交更改:' && git status --short"
          }
        ]
      }
    ]
  }
}

最佳实践

  1. 错误容忍:Hook 命令添加 || true 避免阻断工作流
  2. 快速执行:Hook 应该快速完成,避免阻塞 Claude 的响应
  3. 日志输出:Hook 的 stderr 输出会显示给用户
  4. 项目级配置:团队共享的 Hook 放在 .claude/settings.json
  5. 本地覆盖:个人 Hook 放在 settings.local.json

On this page