教程概述
Hooks 是 Everything Claude Code 的自动化核心,让你能够在特定事件发生时自动执行操作,无需手动干预。
你将学到
- ✅ 6 种 Hook 类型及其用途
- ✅ Hook 配置语法(matcher + hooks)
- ✅ 5+ 个实战配置案例
- ✅ hookify 插件使用
- ✅ 常见问题排查
什么是 Hooks?
Hooks 是基于事件的自动化系统,在 Claude Code 的生命周期中的特定时刻触发:
flowchart TD
subgraph 用户操作
A[用户发送消息] --> B[UserPromptSubmit]
end
subgraph 工具执行
C[准备执行工具] --> D[PreToolUse]
D --> E[工具执行]
E --> F[PostToolUse]
end
subgraph 会话管理
G[Claude 停止响应] --> H[Stop]
I[上下文压缩前] --> J[PreCompact]
K[需要权限] --> L[Notification]
end
B --> C
F --> G
6 种 Hook 类型详解
类型概览
| Hook 类型 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse |
工具执行前 | 验证、提醒、拦截 |
PostToolUse |
工具执行后 | 格式化、反馈、记录 |
UserPromptSubmit |
用户发送消息时 | 预处理、上下文注入 |
Stop |
Claude 停止响应时 | 清理、持久化、总结 |
PreCompact |
上下文压缩前 | 保存状态、提取关键信息 |
Notification |
需要权限时 | 自定义通知、日志 |
1. PreToolUse
在工具执行前触发,可用于验证、提醒或拦截操作。
sequenceDiagram
participant C as Claude
participant H as PreToolUse Hook
participant T as Tool
C->>H: 准备执行 Bash
H->>H: 检查命令
alt 命令需要 tmux
H->>C: 提醒使用 tmux
end
C->>T: 执行命令
配置示例:tmux 提醒
{
"PreToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"(npm|pnpm|yarn|cargo|pytest)\"",
"hooks": [
{
"type": "command",
"command": "if [ -z \"$TMUX\" ]; then echo '[Hook] 考虑使用 tmux 以保持会话持久' >&2; fi"
}
]
}
]
}
配置示例:阻止写入非 README 的 Markdown 文件
{
"PreToolUse": [
{
"matcher": "tool == \"Write\" && tool_input.file_path matches \".*\\.md$\" && !tool_input.file_path matches \"(README|CLAUDE)\"",
"hooks": [
{
"type": "command",
"command": "echo '[Hook] 阻止创建非 README 的 .md 文件。如需创建,请显式确认。' >&2; exit 1"
}
]
}
]
}
2. PostToolUse
在工具执行后触发,可用于格式化、反馈循环或记录。
sequenceDiagram
participant T as Tool
participant H as PostToolUse Hook
participant F as 文件系统
T->>H: Edit 完成
H->>F: 运行 prettier
H->>F: 运行 tsc --noEmit
H->>H: 检查 console.log
H->>T: 返回结果
配置示例:自动格式化
{
"PostToolUse": [
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx|js|jsx)$\"",
"hooks": [
{
"type": "command",
"command": "prettier --write \"$TOOL_INPUT_FILE_PATH\""
}
]
}
]
}
配置示例:TypeScript 类型检查
{
"PostToolUse": [
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx)$\"",
"hooks": [
{
"type": "command",
"command": "tsc --noEmit 2>&1 | head -20"
}
]
}
]
}
配置示例:console.log 检查
{
"PostToolUse": [
{
"matcher": "tool == \"Edit\"",
"hooks": [
{
"type": "command",
"command": "grep -n 'console\\.log' \"$TOOL_INPUT_FILE_PATH\" && echo '[Hook] 发现 console.log,请确认是否需要移除' >&2 || true"
}
]
}
]
}
3. UserPromptSubmit
在用户发送消息时触发,可用于预处理或上下文注入。
配置示例:自动加载项目上下文
{
"UserPromptSubmit": [
{
"matcher": "true",
"hooks": [
{
"type": "command",
"command": "cat ~/.claude/context/project-context.md 2>/dev/null || true"
}
]
}
]
}
4. Stop
在 Claude 停止响应时触发,非常适合清理工作或持久化学习。
sequenceDiagram
participant C as Claude
participant H as Stop Hook
participant S as 存储
C->>H: 会话结束
H->>S: 保存会话摘要
H->>S: 检查未提交更改
H->>H: 检查 console.log
配置示例:会话摘要保存
{
"Stop": [
{
"matcher": "true",
"hooks": [
{
"type": "command",
"command": "echo '## 会话摘要 ($DATE)' >> ~/.claude/sessions/log.md && echo '- 完成的任务: ...' >> ~/.claude/sessions/log.md"
}
]
}
]
}
配置示例:console.log 最终检查
{
"Stop": [
{
"matcher": "true",
"hooks": [
{
"type": "command",
"command": "git diff --name-only | xargs grep -l 'console\\.log' 2>/dev/null && echo '[Hook] 以下文件包含 console.log,请检查' >&2 || true"
}
]
}
]
}
5. PreCompact
在上下文压缩前触发,用于保存重要状态。
配置示例:保存关键上下文
{
"PreCompact": [
{
"matcher": "true",
"hooks": [
{
"type": "command",
"command": "cat > ~/.claude/.tmp/pre-compact-state.md << 'EOF'\n# 压缩前状态\n- 当前任务: $CURRENT_TASK\n- 关键决策: ...\n- 待办事项: ...\nEOF"
}
]
}
]
}
6. Notification
在需要权限时触发,用于自定义通知。
配置示例:发送桌面通知
{
"Notification": [
{
"matcher": "true",
"hooks": [
{
"type": "command",
"command": "notify-send 'Claude Code' '需要您的确认'"
}
]
}
]
}
完整 Hooks 配置示例
以下是一个综合的 hooks.json 配置:
{
"PreToolUse": [
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"(npm|pnpm|yarn|cargo|pytest)\"",
"hooks": [
{
"type": "command",
"command": "if [ -z \"$TMUX\" ]; then echo '[Hook] 考虑使用 tmux' >&2; fi"
}
]
},
{
"matcher": "tool == \"Write\" && tool_input.file_path matches \".*\\.md$\" && !tool_input.file_path matches \"(README|CLAUDE)\"",
"hooks": [
{
"type": "command",
"command": "echo '[Hook] 阻止创建 .md 文件' >&2; exit 1"
}
]
},
{
"matcher": "tool == \"Bash\" && tool_input.command matches \"git push\"",
"hooks": [
{
"type": "command",
"command": "git diff --stat origin/$(git branch --show-current) && echo '[Hook] 请审查以上更改后再推送'"
}
]
}
],
"PostToolUse": [
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx|js|jsx)$\"",
"hooks": [
{
"type": "command",
"command": "prettier --write \"$TOOL_INPUT_FILE_PATH\" 2>/dev/null || true"
}
]
},
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"\\.(ts|tsx)$\"",
"hooks": [
{
"type": "command",
"command": "tsc --noEmit 2>&1 | head -10 || true"
}
]
},
{
"matcher": "tool == \"Edit\"",
"hooks": [
{
"type": "command",
"command": "grep -n 'console\\.log' \"$TOOL_INPUT_FILE_PATH\" && echo '[Hook] 发现 console.log' >&2 || true"
}
]
}
],
"Stop": [
{
"matcher": "true",
"hooks": [
{
"type": "command",
"command": "git diff --name-only | xargs grep -l 'console\\.log' 2>/dev/null && echo '[Hook] 检查 console.log' >&2 || true"
}
]
}
]
}
hookify 插件
不想手写 JSON?使用 hookify 插件通过自然语言创建 Hooks。
安装
# 通过插件市场安装
claude plugin marketplace add claude-plugins-official
claude plugin install hookify@claude-plugins-official
使用方法
/hookify
我想创建一个 Hook:
- 当 Claude 执行长时间运行的命令时提醒我使用 tmux
- 当编辑 TypeScript 文件后自动运行 prettier
hookify 会自动生成正确的 JSON 配置。
Matcher 语法
可用变量
| 变量 | 说明 | 示例 |
|---|---|---|
tool |
工具名称 | Bash, Edit, Write, Read |
tool_input |
工具输入 | tool_input.command, tool_input.file_path |
tool_result |
工具结果 | tool_result.exit_code |
匹配操作
== 精确匹配
!= 不等于
matches 正则匹配
contains 包含
&& 与
|| 或
示例
// 匹配所有 Bash 命令
"tool == \"Bash\""
// 匹配包含 npm 的命令
"tool == \"Bash\" && tool_input.command matches \"npm\""
// 匹配 TypeScript 文件
"tool == \"Edit\" && tool_input.file_path matches \"\\.tsx?$\""
// 匹配失败的操作
"tool_result.exit_code != 0"
常见问题排查
Q1:Hook 没有触发
排查步骤:
-
检查 hooks.json 语法:
cat ~/.claude/hooks/hooks.json | python -m json.tool -
检查 matcher 是否正确:
// 确保使用正确的转义 "tool_input.file_path matches \"\\.ts$\"" // ✅ "tool_input.file_path matches \".ts$\"" // ❌ 未转义 -
检查 hook 文件位置:
ls ~/.claude/hooks/ # 应该看到 hooks.json
Q2:Hook 执行失败
排查步骤:
-
手动测试命令:
# 复制 hook 中的命令,手动执行 prettier --write "src/index.ts" -
检查环境变量:
echo $TOOL_INPUT_FILE_PATH -
查看错误输出:
- Hook 的 stderr 输出会显示在 Claude Code 中
Q3:Hook 影响性能
解决方案:
// 限制 hook 执行时间
{
"timeout": 5000 // 5 秒超时
}
// 只在特定目录触发
{
"matcher": "tool == \"Edit\" && tool_input.file_path matches \"^src/\""
}
Q4:多个 Hook 执行顺序
Hook 按数组顺序执行:
{
"PostToolUse": [
{ "matcher": "...", "hooks": [...] }, // 第一个执行
{ "matcher": "...", "hooks": [...] } // 第二个执行
]
}
Q5:如何调试 Hook?
添加调试输出:
{
"hooks": [
{
"type": "command",
"command": "echo '[Debug] Hook triggered: '$TOOL_INPUT_FILE_PATH' >&2"
}
]
}
小结
关键要点
- ✅ 6 种 Hook 类型覆盖 Claude Code 完整生命周期
- ✅ Matcher 语法灵活匹配各种条件
- ✅ PostToolUse 最常用(格式化、检查)
- ✅ Stop Hook 适合清理和持久化
- ✅ hookify 插件让配置更简单
系列导航: