Hooks 完整参考
Hooks 让你在 Claude Code 的关键事件节点插入自定义逻辑,实现工作流自动化。
Hook 事件完整列表
| 事件 | 触发时机 | 能否拦截 | 典型用途 |
|---|---|---|---|
SessionStart | 会话开始,Claude 首次响应前 | 否 | 同步知识库、初始化环境 |
PreToolUse | Claude 调用任何工具之前 | 是 | 安全检查、审计日志 |
PostToolUse | Claude 调用工具完成之后 | 否 | 自动 lint、运行测试 |
Notification | Claude 生成通知消息时 | 否 | 转发到 Slack/钉钉 |
Stop | Claude 任务完成或会话即将结束 | 否 | 提示经验回写 |
配置结构
基础配置
{
"hooks": {
"SessionStart": [
{
"type": "command",
"command": "你的命令"
}
]
}
}
PreToolUse(有 matcher 的特殊结构)
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "安全检查命令"
}
]
}
]
}
}
各事件详解
SessionStart
触发时机:Claude 会话开始,显示第一条响应之前。
用途:
- 同步团队知识库(
git pull) - 打印当前 git 分支和项目名
- 检查依赖是否更新
示例:
"SessionStart": [
{
"type": "command",
"command": "cd ~/Documents/git/team-knowledge && git pull --quiet 2>&1 | tail -1"
}
]
多命令写法(放到脚本中):
"SessionStart": [
{
"type": "command",
"command": "bash ~/scripts/session-start.sh"
}
]
# ~/scripts/session-start.sh
#!/bin/bash
set -e
# 同步知识库
cd ~/Documents/git/team-knowledge && git pull --quiet
echo "✓ 团队知识库已同步"
# 打印项目信息
if [ -f "package.json" ]; then
PROJECT=$(node -e "console.log(require('./package.json').name)" 2>/dev/null)
echo "📦 项目: $PROJECT"
fi
BRANCH=$(git branch --show-current 2>/dev/null)
[ -n "$BRANCH" ] && echo "🌿 分支: $BRANCH"
PreToolUse
触发时机:在 Claude 执行任何工具调用之前。
特点:可以通过非 0 退出码阻止工具执行。这是最强大的安全控制机制。
matcher 匹配规则:
"PreToolUse": [
{
"matcher": "Bash", // 精确匹配工具名
"hooks": [...]
},
{
"matcher": "Write|Edit", // OR 匹配
"hooks": [...]
},
{
"matcher": "*", // 匹配所有工具
"hooks": [...]
}
]
安全检查示例:
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/scripts/safety-check.sh"
}
]
}
]
# ~/scripts/safety-check.sh
#!/bin/bash
# 读取即将执行的命令(由 Claude Code 通过环境变量或 stdin 传入)
# 注意:具体的传入方式取决于 Claude Code 版本
CMD="${CLAUDE_TOOL_INPUT:-$(cat -)}"
# 危险命令模式检查
DANGEROUS_PATTERNS=(
"rm -rf /"
"rm -rf \*"
"dd if=/dev/zero"
":(){ :|:& };:"
"chmod -R 777 /"
"> /dev/sda"
)
for pattern in "${DANGEROUS_PATTERNS[@]}"; do
if echo "$CMD" | grep -qF "$pattern"; then
echo "🚫 危险命令已拦截: $pattern" >&2
exit 1 # 非 0 退出码 = 阻止工具执行
fi
done
exit 0 # 0 退出码 = 允许执行
PostToolUse
触发时机:工具执行完成后。
用途:
- 文件修改后自动运行 lint
- 文件修改后自动运行测试
- 记录审计日志
示例:
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/scripts/auto-format.sh"
}
]
}
]
# ~/scripts/auto-format.sh
#!/bin/bash
# 文件修改后自动运行格式化(如果在前端项目中)
if [ -f "package.json" ]; then
pnpm lint --fix --silent 2>/dev/null || true
echo "✓ 代码已自动格式化"
fi
Notification
触发时机:Claude 生成需要通知用户的消息时(如等待许久的任务完成)。
用途:发送通知到 Slack、钉钉、macOS 通知中心等。
示例(macOS 通知):
"Notification": [
{
"type": "command",
"command": "osascript -e 'display notification \"Claude Code 任务完成\" with title \"Claude Code\"'"
}
]
Stop
触发时机:Claude 认为当前任务已完成,会话即将结束时。
用途:
- 提示执行
/team-learn - 保存会话摘要
- 发送任务完成通知
示例:
"Stop": [
{
"type": "command",
"command": "echo '[EVOLUTION_CHECK] 会话结束,如有新知识建议执行 /team-learn'"
}
]
多个 Hook 的执行顺序
同一事件可以配置多个 Hook,按数组顺序依次执行:
"SessionStart": [
{ "type": "command", "command": "命令1" }, // 先执行
{ "type": "command", "command": "命令2" }, // 后执行
{ "type": "command", "command": "命令3" } // 最后执行
]
PreToolUse 的特殊规则:任意一个 Hook 返回非 0,整个工具调用被阻止。
Hook 调试技巧
技巧 1:最小化测试
先用简单命令验证 Hook 框架是否工作:
"SessionStart": [
{
"type": "command",
"command": "echo 'Hook 测试成功' > /tmp/claude-hook-test.txt"
}
]
启动 Claude 后检查:
cat /tmp/claude-hook-test.txt
# 应该输出:Hook 测试成功
技巧 2:日志记录
# 在 Hook 脚本中记录日志
echo "$(date): SessionStart Hook 执行" >> /tmp/claude-hooks.log
技巧 3:错误处理
#!/bin/bash
set -e # 遇到错误立即退出(适合 PreToolUse)
# 或者允许错误继续(适合非关键的 PostToolUse)
some-command || echo "命令失败,但不阻塞"
完整 Hooks 配置示例
{
"hooks": {
"SessionStart": [
{
"type": "command",
"command": "bash ~/scripts/session-init.sh"
}
],
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"command": "bash ~/scripts/safety-check.sh"
}
]
}
],
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "bash ~/scripts/post-edit.sh"
}
]
}
],
"Stop": [
{
"type": "command",
"command": "echo '[EVOLUTION_CHECK] 任务完成 - 有新知识请执行 /team-learn'"
}
]
}
}