1 概述

Claude Code 提供了几个在工作流程不同时间点运行的 hook 事件:

  • PreToolUse:在工具调用之前运行(可以阻止它们)
  • PostToolUse:在工具调用完成后运行
  • UserPromptSubmit:当用户提交提示时运行,在 Claude 处理之前
  • Notification:当 Claude Code 发送通知时运行
  • Stop:当 Claude Code 完成响应时运行
  • Subagent Stop:当子代理任务完成时运行
  • PreCompact:在 Claude Code 即将运行压缩操作之前运行
  • SessionStart:当 Claude Code 启动新会话或恢复现有会话时运行

每个事件接收不同的数据,并可以以不同的方式控制 Claude 的行为。

2 一些常用hooks

使用以下hooks的环境要求

  • Claude Code已安装
  • jq命令必须可用(jq.exe路径加入到环境变量) (brew install jq / apt install jq / choco install jq / winget install jq)
  • git命令必须可用(git.exe路径加入到环境变量)

如果你使用windows,务必查看 5 配置ClaudeCode可用的Git Bash环境,在添加hooks到你的ClaudeCode之后你必须使用git bash启动ClaudeCode

以下所有hook脚本都存放在 %USERPROFILE%/.claude/hooks文件夹中,没有请自行创建

以下所有hook配置都追加在 %USERPROFILE%/.claude/setting.json文件的hooks属性中

2.1 自动提交git的hook

bash%USERPROFILE%/.claude/hooks/auto-commit.sh
#!/bin/bash
# Stop hook: 任务完成后自动检测未提交变更并触发 commit skill
 
INPUT=$(cat)
STOP_HOOK_ACTIVE=$(echo "$INPUT" | jq -r '.stop_hook_active // false')
 
# 防止无限循环:commit 后再次触发时直接放行
if [ "$STOP_HOOK_ACTIVE" = "true" ]; then
  exit 0
fi
 
# 检查是否有未提交的变更
cd "$CLAUDE_PROJECT_DIR" 2>/dev/null || exit 0
 
# 检查工作区是否有变更(已修改、新文件等)
if git diff --quiet 2>/dev/null && git diff --cached --quiet 2>/dev/null && [ -z "$(git ls-files --others --exclude-standard 2>/dev/null)" ]; then
  # 没有变更,正常结束
  exit 0
fi
 
# 有未提交变更,阻止 Claude 停止,让它继续执行 commit
cat <<'EOF'
{"decision": "block", "reason": "检测到未提交的变更,请调用 /commit-commands:commit 技能提交更新。"}
EOF
json
{
  "hooks": {
    "Stop": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash ~/.claude/hooks/auto-commit.sh"
          }
        ]
      }
    ]
  }
}

2.1.1 完成通知

json
"hooks": {
	"Stop": [
		{
		  "id": "notifications-desktop-task-complete",
		  "name": "Desktop Notification on Task Complete",
		  "event": "Stop",
		  "matcher": "Bash",
		  "command": "bash -c 'MSG=\"Claude Code task complete at $(date +%H:%M)\"; if command -v notify-send &>/dev/null; then notify-send \"Claude Code\" \"$MSG\"; elif command -v osascript &>/dev/null; then osascript -e \"display notification \\\"$MSG\\\" with title \\\"Claude Code\\\"\"; fi'"
		}
	]
}

2.1.2 密钥扫描拦截hook

json
{
  "hooks": {
    "PreToolUse": [
      {
        "id": "security-scan-env-secrets",
        "name": "Scan for Hardcoded Passwords",
        "description": "Checks Write/Edit targets for patterns like password=, secret=, token= with literal values",
        "category": "security",
        "event": "PreToolUse",
        "matcher": "Write",
        "command": "bash -c 'CONTENT=$(echo \"$CLAUDE_TOOL_INPUT\" | jq -r \".content // empty\"); if echo \"$CONTENT\" | grep -qiE \"(password|passwd|secret|token|api_key)\\s*=\\s*[\\x27\\\"][^\\x27\\\"]{6,}\"; then echo \"[SECURITY] Possible hardcoded secret in file write. Review before proceeding.\"; fi'",
        "enabled": true
      }
    ]
  }
}