Hooks 系统完全指南
概述
Hooks 是 Claude Code 的事件驱动自动化机制,允许在特定事件发生时自动执行预定义的操作。通过 Hooks,你可以实现代码格式化、安全检查、通知等自动化流程。
Hooks 工作原理
事件驱动模型
用户操作 → 触发事件 → 执行 Hook → 继续操作
↓ ↓ ↓ ↓
提交提示 → PreToolUse → 格式化代码 → 执行工具
Hook 执行流程
- 事件触发:特定操作发生
- Hook 匹配:查找匹配的 Hook
- 条件判断:检查是否满足执行条件
- 执行动作:运行 Hook 定义的操作
- 结果处理:根据结果决定后续行为
支持的 Hook 类型
1. PreToolUse - 工具执行前
在工具调用之前运行,可以:
- 验证输入参数
- 阻止危险操作
- 记录操作日志
示例:
{
"preToolUse": {
"Bash": "echo '即将执行: {command}' && if [[ '{command}' =~ 'rm -rf' ]]; then read -p '确认删除? (y/N) ' && [[ $REPLY != 'y' ]] && exit 1; fi"
}
}
2. PostToolUse - 工具执行后
在工具执行完成后运行,适合:
- 自动格式化
- 结果验证
- 状态更新
示例:
{
"postToolUse": {
"Edit": "npm run format",
"Write": "git add {filePath}"
}
}
3. UserPromptSubmit - 用户提交提示时
在用户提交提示时运行,可用于:
- 提示词优化
- 上下文增强
- 记录历史
示例:
{
"userPromptSubmit": "echo '$(date): {prompt}' >> ~/.claude/history.log"
}
4. SessionStart - 会话开始时
在新会话或恢复会话时运行:
- 环境设置
- 上下文加载
- 状态初始化
示例:
{
"sessionStart": "echo 'Welcome back! Last session: $(date -r ~/.claude/last_session)'"
}
5. SessionEnd - 会话结束时
在会话结束时运行:
- 清理临时文件
- 保存状态
- 生成报告
示例:
{
"sessionEnd": "echo 'Session ended at $(date)' >> ~/.claude/sessions.log"
}
6. Notification - 发送通知时
当 Claude Code 发送通知时运行:
- 自定义通知格式
- 额外处理逻辑
- 日志记录
示例:
{
"notification": "notify-send 'Claude Code' '{message}'"
}
7. Stop - 响应完成时
当 Claude Code 完成响应时运行:
- 结果后处理
- 自动保存
- 触发后续操作
示例:
{
"stop": "echo 'Response completed' >> ~/.claude/responses.log"
}
配置方法
1. 在 settings.json 中配置
{
"hooks": {
"preToolUse": {
"Bash": "echo 'Executing: {command}'",
"Edit": "cp {filePath} {filePath}.backup"
},
"postToolUse": {
"Write": "npm run lint"
}
}
}
2. 使用 /hooks 命令管理
# 查看所有 Hooks
/hooks
# 添加新 Hook
/hooks add preToolUse.Bash "echo 'Running command'"
# 删除 Hook
/hooks remove postToolUse.Write
# 测试 Hook
/hooks test preToolUse.Bash
3. 项目级配置
在项目根目录创建 .claude/hooks.json:
{
"preToolUse": {
"Edit": "prettier --write {filePath}"
},
"postToolUse": {
"Bash": "npm test"
}
}
实用 Hook 示例
1. 代码格式化自动化
{
"hooks": {
"postToolUse": {
"Edit": "npm run format",
"Write": "npm run format"
}
}
}
2. 安全检查
{
"hooks": {
"preToolUse": {
"Bash": "security_check.sh '{command}'"
}
}
}
security_check.sh 内容:
#!/bin/bash
command="$1"
# 检查危险命令
if [[ $command =~ (rm\ -rf|sudo|chmod\ 777) ]]; then
echo "⚠️ 检测到潜在危险操作:$command"
read -p "确认执行?(y/N) " -n 1 -r
echo
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
exit 1
fi
fi
3. 自动备份
{
"hooks": {
"preToolUse": {
"Edit": "cp {filePath} backups/{filePath}.$(date +%s)",
"Write": "mkdir -p backups && cp {filePath} backups/{filePath}.$(date +%s) 2>/dev/null || true"
}
}
}
4. 测试自动运行
{
"hooks": {
"postToolUse": {
"Edit": "if [[ '{filePath}' =~ test\\.(js|ts|py)$ ]]; then npm test -- {filePath}; fi"
}
}
}
5. 提交自动化
{
"hooks": {
"sessionEnd": "if [[ $(git status --porcelain) ]]; then git add -A && git commit -m 'Auto-commit: $(date)'; fi"
}
}
高级用法
1. 条件执行
使用条件表达式:
{
"hooks": {
"postToolUse": {
"Write": "if [[ '{filePath}' =~ \\.(js|ts)$ ]]; then npm run typecheck {filePath}; fi"
}
}
}
2. 管道操作
多个命令组合:
{
"hooks": {
"postToolUse": {
"Edit": "npm run format && npm run lint && git add {filePath}"
}
}
}
3. 环境变量
使用环境变量:
{
"hooks": {
"sessionStart": "export PROJECT_NAME=$(basename $PWD) && echo 'Starting work on $PROJECT_NAME'"
}
}
4. 函数封装
创建可复用的 Hook 函数:
# ~/.claude/hook_functions.sh
format_and_lint() {
local file="$1"
if [[ "$file" =~ \.(js|ts|tsx)$ ]]; then
npm run format "$file"
npm run lint "$file"
fi
}
run_tests() {
local file="$1"
if [[ "$file" =~ test\. ]]; then
npm test "$file"
fi
}
在 settings.json 中引用:
{
"hooks": {
"postToolUse": {
"Edit": "source ~/.claude/hook_functions.sh && format_and_lint {filePath}"
}
}
}
Hook 参数
可用变量
在 Hook 中可以使用以下变量:
{command}- 执行的命令{filePath}- 文件路径{prompt}- 用户提示{message}- 通知消息{timestamp}- 时间戳{sessionId}- 会话 ID
示例使用
{
"hooks": {
"preToolUse": {
"Bash": "echo '[{timestamp}] 执行命令: {command}' >> ~/.claude/command.log"
},
"postToolUse": {
"Write": "echo '[{timestamp}] 修改文件: {filePath}' >> ~/.claude/files.log"
}
}
}
最佳实践
1. 保持简单
- Hook 应该快速执行
- 避免阻塞主流程
- 处理失败情况
2. 错误处理
# 总是检查命令是否成功
command || echo "Command failed: $?" >&2
# 使用 trap 处理中断
trap 'echo "Interrupted"; exit 1' INT
3. 日志记录
{
"hooks": {
"preToolUse": {
"Bash": "echo \"$(date '+%Y-%m-%d %H:%M:%S') [PRE] {command}\" >> ~/.claude/hooks.log"
},
"postToolUse": {
"Bash": "echo \"$(date '+%Y-%m-%d %H:%M:%S') [POST] {command}\" >> ~/.claude/hooks.log"
}
}
}
4. 性能考虑
- 避免重复操作
- 使用缓存减少开销
- 异步执行耗时操作
常见场景
1. 开发环境
{
"hooks": {
"sessionStart": "npm run dev",
"postToolUse": {
"Edit": "npm run format"
}
}
}
2. 生产环境
{
"hooks": {
"preToolUse": {
"Bash": "if [[ $ENV == 'production' ]]; then echo 'Production mode - extra checks'; fi"
},
"postToolUse": {
"Edit": "if [[ $ENV == 'production' ]]; then npm run build:prod; fi"
}
}
}
3. 团队协作
{
"hooks": {
"postToolUse": {
"Write": "git add {filePath} && git commit -m 'Auto-commit: {filePath}'"
},
"sessionEnd": "git push origin main"
}
}
调试技巧
1. 启用调试模式
claude --debug
2. 查看日志
tail -f ~/.claude/hooks.log
3. 测试 Hook
# 手动触发 Hook
/hooks test postToolUse.Write
# 使用测试命令
echo "test" | npm run format
故障排除
常见问题
-
Hook 不执行
- 检查语法错误
- 验证文件权限
- 确认路径正确
-
性能问题
- 优化 Hook 逻辑
- 减少不必要的操作
- 使用异步执行
-
循环调用
- 避免在 Hook 中触发相同的工具
- 使用条件判断防止重复