跳到主要内容

Hooks 系统完全指南

概述

Hooks 是 Claude Code 的事件驱动自动化机制,允许在特定事件发生时自动执行预定义的操作。通过 Hooks,你可以实现代码格式化、安全检查、通知等自动化流程。

Hooks 工作原理

事件驱动模型

用户操作 → 触发事件 → 执行 Hook → 继续操作
↓ ↓ ↓ ↓
提交提示 → PreToolUse → 格式化代码 → 执行工具

Hook 执行流程

  1. 事件触发:特定操作发生
  2. Hook 匹配:查找匹配的 Hook
  3. 条件判断:检查是否满足执行条件
  4. 执行动作:运行 Hook 定义的操作
  5. 结果处理:根据结果决定后续行为

支持的 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

故障排除

常见问题

  1. Hook 不执行

    • 检查语法错误
    • 验证文件权限
    • 确认路径正确
  2. 性能问题

    • 优化 Hook 逻辑
    • 减少不必要的操作
    • 使用异步执行
  3. 循环调用

    • 避免在 Hook 中触发相同的工具
    • 使用条件判断防止重复

相关资源