<!-- title: Claude Code Hooks全链路开发实战 -->

## 概述

本教程面向已有Claude Code基础使用经验的开发者，系统讲解Hooks机制——从理解事件模型、配置schema，到编写生产级钩子脚本、调试排错、团队共享。学完后你将具备用Hooks构建确定性工作流的能力，让Claude Code在每次工具调用、文件编辑、会话启停时自动执行你定义的逻辑，彻底告别重复提醒AI的窘境。

**适用人群**：已安装Claude Code并完成至少一个项目的开发者，熟悉JSON配置和基础Shell脚本。

---

## 前置条件

| 项目 | 要求 |
|------|------|
| Claude Code | v1.0.20+（Hooks在早期版本中引入，建议最新版） |
| Shell环境 | Bash/Zsh，支持标准输入输出 |
| 编辑器 | 任意（VS Code推荐） |
| 基础知识 | JSON配置、Shell脚本、正则表达式 |

验证Claude Code版本：
```bash
claude --version
```

---

## 第一章：Hooks机制全景理解

### 1.1 什么是Hooks

Hooks是用户定义的Shell命令、LLM提示或子Agent，在Claude Code生命周期的特定节点**自动执行**。它们提供**确定性控制**——不依赖AI"记住"规则，而是通过系统级机制强制执行。

核心价值：
- **自动格式化**：每次文件编辑后自动运行Prettier/ESLint
- **安全防护**：拦截危险命令（`rm -rf`、修改`.env`）
- **上下文注入**：会话启动或压缩后自动注入项目规范
- **工作流自动化**：编辑后自动运行测试、Git操作
- **通知集成**：任务完成后发送Slack/邮件通知

### 1.2 Hooks事件模型

Claude Code定义了多种Hook事件类型，每种在不同的生命周期节点触发：

```
┌─────────────────────────────────────────────────────────────┐
│                    Claude Code 生命周期                       │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  会话开始 ──→ [SessionStart] ──→ 对话循环 ──→ 会话结束     │
│                ↑                              ↓             │
│          注入上下文/规范              [Stop] 通知用户        │
│                                                             │
│  ┌──────────── 对话循环内部 ────────────┐                   │
│  │                                      │                   │
│  │  AI生成工具调用                       │                   │
│  │       ↓                              │                   │
│  │  [PreToolUse] ──→ 执行工具 ──→ [PostToolUse]            │
│  │   拦截/验证         ↓          格式化/通知               │
│  │                (Write/Edit/Bash/...)                    │
│  │                                      │                   │
│  │  上下文压缩                           │                   │
│  │       ↓                              │                   │
│  │  [Compaction] ──→ 注入关键上下文      │                   │
│  └──────────────────────────────────────┘                   │
└─────────────────────────────────────────────────────────────┘
```

| 事件 | 触发时机 | 典型用途 |
|------|----------|----------|
| `PreToolUse` | 工具调用**之前** | 拦截危险操作、验证输入 |
| `PostToolUse` | 工具调用**之后** | 自动格式化、运行测试 |
| `Notification` | Claude停止生成时 | 发送通知、触发后续流程 |
| `Stop` | 会话结束 | 清理临时文件、汇总报告 |
| `SubagentStop` | 子Agent完成时 | 聚合子任务结果 |

### 1.3 配置层级

Hooks可在三个层级配置，优先级从高到低：

1. **项目级**（`.claude/settings.json`）—— 团队共享，进入版本控制
2. **用户级**（`~/.claude/settings.json`）—— 个人偏好
3. **企业级**（管理员配置）—— 全组织强制策略

---

## 第二章：配置Schema详解

### 2.1 基本结构

Hooks配置在`settings.json`的`hooks`字段中：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "your-script.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write $CLAUDE_FILE_PATH"
          }
        ]
      }
    ]
  }
}
```

### 2.2 字段详解

**顶层分组**（Hook Group）：
```json
{
  "matcher": "工具名匹配模式",   // 正则表达式，匹配工具名
  "hooks": [                     // 该匹配下要执行的钩子列表
    { "type": "command", "command": "..." },
    { "type": "prompt", "prompt": "..." }
  ]
}
```

**Matcher字段**：
- 精确匹配：`"Bash"` —— 只匹配Bash工具
- 正则匹配：`"Write|Edit"` —— 匹配Write或Edit
- 通配所有：`".*"` 或省略matcher —— 匹配所有工具

**Hook类型**：
- `"command"` —— 执行Shell命令
- `"prompt"` —— 向AI注入提示文本（不执行Shell）
- `"subagent"` —— 启动子Agent执行任务

### 2.3 环境变量

Hooks执行时可访问关键环境变量：

| 变量 | 含义 | 示例 |
|------|------|------|
| `$CLAUDE_TOOL_NAME` | 当前工具名 | `Bash`, `Write`, `Edit` |
| `$CLAUDE_TOOL_INPUT` | 工具输入（JSON字符串） | `{"command":"ls"}` |
| `$CLAUDE_FILE_PATH` | 涉及的文件路径 | `/src/app.ts` |

对于`PostToolUse`，还可以通过stdin获取工具输出结果。

### 2.4 退出码语义

| 退出码 | 含义 | 对Claude的影响 |
|--------|------|----------------|
| `0` | 成功 | 正常继续 |
| `2` | 阻止+反馈 | 阻止工具执行，将stdout作为反馈返回Claude |
| 其他非零 | 错误 | 记录错误但继续执行（取决于配置） |

退出码`2`是实现安全防护的核心——它**阻止**操作并给Claude一个理由。

---

## 第三章：第一个Hook——5分钟实战

### 3.1 目标：自动格式化

最经典的Hook用例：每次Claude编辑文件后自动运行Prettier。

**步骤1**：在项目根目录创建`.claude/settings.json`：

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
```

**步骤2**：验证配置生效：

```bash
# 启动Claude Code，让AI编辑任意文件
claude
# > 请帮我修改 src/app.ts，把标题改成 "Hello Hooks"
```

**预期结果**：Claude编辑文件后，你会看到Prettier自动运行，文件被格式化。Claude的输出中会显示Hook执行信息。

### 3.2 常见问题

| 问题 | 原因 | 解决方案 |
|------|------|----------|
| Hook未触发 | matcher写错 | 检查工具名大小写（`Write`不是`write`） |
| 命令报错 | 文件路径含空格 | 用双引号包裹`$CLAUDE_FILE_PATH` |
| 格式化卡住 | Prettier缺少配置 | 确保项目有`.prettierrc` |
| 所有文件都格式化 | 缺少忽略规则 | 添加`.prettierignore` |

---

## 第四章：安全防护——拦截危险操作

### 4.1 阻止rm -rf

这是PreToolUse最强大的能力——**在执行前拦截**。

创建脚本`.claude/hooks/block-dangerous.sh`：

```bash
#!/bin/bash
# 从stdin读取工具输入JSON
INPUT=$(cat)

# 检查是否包含危险命令模式
COMMAND=$(echo "$INPUT" | jq -r '.command // empty')

DANGEROUS_PATTERNS=(
  "rm -rf /"
  "rm -rf ~"
  "DROP TABLE"
  "DROP DATABASE"
  "git push --force"
  "git reset --hard"
  "dd if="
  ":(){:|:&};:"
  "chmod -R 777 /"
  "mkfs"
)

for pattern in "${DANGEROUS_PATTERNS[@]}"; do
  if echo "$COMMAND" | grep -qi "$pattern"; then
    echo "⛔ 安全防护：检测到危险命令模式 '$pattern'。此操作已被阻止。如果确需执行，请手动在终端操作。"
    exit 2
  fi
done

exit 0
```

在`settings.json`中配置：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          }
        ]
      }
    ]
  }
}
```

赋予执行权限：
```bash
chmod +x .claude/hooks/block-dangerous.sh
```

### 4.2 保护敏感文件

阻止Claude修改关键配置文件：

```bash
#!/bin/bash
# .claude/hooks/protect-files.sh
INPUT=$(cat)

# 提取文件路径
FILE_PATH=$(echo "$INPUT" | jq -r '.file_path // .filePath // empty')

PROTECTED_FILES=(
  ".env"
  ".env.production"
  "credentials.json"
  "service-account-key.json"
  "deploy-keys.pem"
)

PROTECTED_PATTERNS=(
  "\.env$"
  "\.env\."
  "secret"
  "credential"
  "private.?key"
)

for protected in "${PROTECTED_FILES[@]}"; do
  if [[ "$FILE_PATH" == *"$protected"* ]]; then
    echo "🔒 文件保护：'$FILE_PATH' 是受保护文件，禁止修改。如需编辑，请手动操作。"
    exit 2
  fi
done

for pattern in "${PROTECTED_PATTERNS[@]}"; do
  if echo "$FILE_PATH" | grep -qiE "$pattern"; then
    echo "🔒 文件保护：'$FILE_PATH' 匹配敏感文件模式，禁止修改。"
    exit 2
  fi
done

exit 0
```

配置：
```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/protect-files.sh"
          }
        ]
      }
    ]
  }
}
```

### 4.3 合并安全防护配置

将所有安全规则整合为一个完整的settings.json：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          }
        ]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/protect-files.sh"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          }
        ]
      }
    ]
  }
}
```

---

## 第五章：上下文注入——让AI始终了解项目

### 5.1 SessionStart注入

会话启动时自动注入项目规范，无需写入CLAUDE.md：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          }
        ]
      }
    ]
  }
}
```

SessionStart的prompt类型Hook：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "项目使用 React 18 + TypeScript + Vite。路由使用 react-router v6。状态管理用 Zustand。CSS 使用 Tailwind。测试框架 Vitest + Testing Library。所有组件使用函数式组件和 Hooks。"
          }
        ]
      }
    ]
  }
}
```

> **注意**：SessionStart作为特殊事件，推荐使用prompt类型注入上下文。实际配置中，prompt类型hooks直接向Claude的上下文窗口追加文本，不执行Shell命令。

### 5.2 Compaction后注入

当对话上下文被压缩（compaction）时，关键信息可能丢失。通过Compaction Hook重新注入：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "[上下文恢复] 当前项目架构：前端 React 18 + Vite，后端 Node.js + Express，数据库 PostgreSQL。API遵循RESTful规范，使用JWT认证。请继续保持这一技术栈的编码风格。"
          }
        ]
      }
    ]
  }
}
```

### 5.3 动态上下文——基于Git分支注入

更高级的用法：根据当前Git分支动态注入不同规范：

```bash
#!/bin/bash
# .claude/hooks/dynamic-context.sh

BRANCH=$(git branch --show-current 2>/dev/null || echo "unknown")

case "$BRANCH" in
  "main"|"master")
    echo "⚠️ 当前在主分支。所有修改必须：1) 先创建feature分支 2) 通过PR合并 3) 通过CI检查。禁止直接push到main。"
    ;;
  "develop"*)
    echo "📌 当前在开发分支。请确保：1) 编写单元测试 2) 遵循Conventional Commits规范 3) 代码覆盖率不低于80%。"
    ;;
  "feature/"*)
    echo "🔧 功能开发中。完成后请：1) 运行完整测试套件 2) 更新相关文档 3) 创建PR到develop分支。"
    ;;
  "hotfix/"*)
    echo "🚨 紧急修复！请：1) 最小化改动范围 2) 添加回归测试 3) 同时修复main和develop。"
    ;;
esac
```

---

## 第六章：通知与工作流集成

### 6.1 任务完成通知

Claude完成任务后自动发送通知（通过Notification事件）：

```bash
#!/bin/bash
# .claude/hooks/notify.sh

# 获取通知内容
MESSAGE=$(cat)

# macOS通知
if [[ "$OSTYPE" == "darwin"* ]]; then
  osascript -e "display notification \"Claude Code任务完成\" with title \"Claude Code\" sound name \"Glass\""
fi

# Linux通知
if command -v notify-send &>/dev/null; then
  notify-send "Claude Code" "任务完成" --icon=utilities-terminal
fi

# 可选：发送到Slack
# curl -X POST -H 'Content-type: application/json' \
#   --data "{\"text\":\"✅ Claude Code任务完成: $(date)\"}" \
#   "$SLACK_WEBHOOK_URL"
```

### 6.2 自动Git工作流

编辑后自动暂存和提交：

```bash
#!/bin/bash
# .claude/hooks/auto-git.sh
# PostToolUse - 在文件编辑后自动git add

FILE_PATH="$CLAUDE_FILE_PATH"

if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
  exit 0
fi

# 排除不需要自动暂存的文件
IGNORE_PATTERNS=("*.lock" "*.log" ".env*" "dist/" "node_modules/")

for pattern in "${IGNORE_PATTERNS[@]}"; do
  if [[ "$FILE_PATH" == $pattern ]]; then
    exit 0
  fi
done

git add "$FILE_PATH" 2>/dev/null
exit 0
```

### 6.3 编辑后自动运行测试

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "FILE=\"$CLAUDE_FILE_PATH\"; if [[ \"$FILE\" == *.test.* ]] || [[ \"$FILE\" == *.spec.* ]]; then npx vitest run \"$FILE\" 2>&1 | tail -5; elif [[ \"$FILE\" == src/**/*.ts ]] && [[ \"$FILE\" != *.d.ts ]]; then CORRESPONDING_TEST=\"${FILE%.ts}.test.ts\"; if [[ -f \"$CORRESPONDING_TEST\" ]]; then npx vitest run \"$CORRESPONDING_TEST\" 2>&1 | tail -5; fi; fi"
          }
        ]
      }
    ]
  }
}
```

---

## 第七章：高级模式——Prompt Hook与子Agent

### 7.1 Prompt类型Hook

Prompt类型Hook不执行Shell命令，而是直接向Claude注入文本指令。适合注入编码规范、项目上下文：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "编码规范检查提醒：请确保新代码遵循以下规则——1) 使用const而非let，除非需要重新赋值 2) 优先使用可选链(?.)和空值合并(??) 3) 函数不超过30行 4) 组件文件不超过200行。"
          }
        ]
      },
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "prompt",
            "prompt": "执行Shell命令前请注意：本项目使用pnpm作为包管理器，不要使用npm或yarn。Docker命令需要加--user参数。"
          }
        ]
      }
    ]
  }
}
```

### 7.2 多Hook链式执行

同一个matcher下可配置多个hooks，它们按顺序执行：

```json
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "npx prettier --write \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          },
          {
            "type": "command",
            "command": "npx eslint --fix \"$CLAUDE_FILE_PATH\" 2>/dev/null || true"
          },
          {
            "type": "command",
            "command": "echo \"[$(date)] Formatted: $CLAUDE_FILE_PATH\" >> .claude/format-log.txt"
          }
        ]
      }
    ]
  }
}
```

**执行顺序**：Prettier格式化 → ESLint修复 → 记录日志。如果其中任何一个返回退出码2，后续hooks不再执行。

### 7.3 条件式Hook——基于文件类型

```bash
#!/bin/bash
# .claude/hooks/smart-format.sh
# 根据文件扩展名选择格式化工具

FILE_PATH="$CLAUDE_FILE_PATH"

if [[ -z "$FILE_PATH" ]] || [[ ! -f "$FILE_PATH" ]]; then
  exit 0
fi

EXT="${FILE_PATH##*.}"

case "$EXT" in
  ts|tsx|js|jsx|json|css|md)
    npx prettier --write "$FILE_PATH" 2>/dev/null
    ;;
  py)
    python -m black "$FILE_PATH" 2>/dev/null
    python -m isort "$FILE_PATH" 2>/dev/null
    ;;
  go)
    gofmt -w "$FILE_PATH" 2>/dev/null
    ;;
  rs)
    rustfmt "$FILE_PATH" 2>/dev/null
    ;;
  java)
    google-java-format -i "$FILE_PATH" 2>/dev/null
    ;;
  *)
    # 未知文件类型，不做格式化
    ;;
esac

exit 0
```

---

## 第八章：调试与排错

### 8.1 调试模式

启用Hooks调试日志：

```bash
# 在Shell中设置环境变量
export CLAUDE_HOOK_DEBUG=1

# 或在.claude/settings.json中
{
  "env": {
    "CLAUDE_HOOK_DEBUG": "1"
  }
}
```

### 8.2 常见错误排查

**问题1：Hook未触发**

```bash
# 检查配置文件是否正确
cat .claude/settings.json | jq '.hooks'

# 验证JSON格式
jq . .claude/settings.json
```

检查清单：
- [ ] 文件路径正确（`.claude/settings.json`）
- [ ] JSON格式有效
- [ ] matcher拼写正确（区分大小写）
- [ ] hooks数组格式正确
- [ ] Shell脚本有执行权限

**问题2：Hook执行报错**

```bash
# 手动测试Hook脚本
echo '{"command":"ls -la"}' | bash .claude/hooks/block-dangerous.sh
echo $?
# 应输出 0 或 2

# 检查脚本的Shell兼容性
shellcheck .claude/hooks/block-dangerous.sh
```

**问题3：格式化循环**

如果Prettier或ESLint的修改触发了新的Write/Edit事件，可能导致循环。解决方案：

```bash
#!/bin/bash
# .claude/hooks/safe-format.sh
FILE="$CLAUDE_FILE_PATH"

# 防重复标记
MARKER=".claude/.formatting-$(echo "$FILE" | md5sum | cut -d' ' -f1)"

if [[ -f "$MARKER" ]]; then
  rm "$MARKER"
  exit 0
fi

touch "$MARKER"
npx prettier --write "$FILE" 2>/dev/null || true
```

### 8.3 日志系统

为所有Hooks建立统一日志：

```bash
#!/bin/bash
# .claude/hooks/logger.sh —— 在每个Hook脚本中source此文件

LOG_FILE=".claude/hooks.log"
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')

log_hook() {
  local level="$1"
  local message="$2"
  echo "[$TIMESTAMP] [$level] $message" >> "$LOG_FILE"
}

log_hook "INFO" "Hook executed: $0, Tool: $CLAUDE_TOOL_NAME, File: $CLAUDE_FILE_PATH"
```

在各个Hook脚本中使用：

```bash
#!/bin/bash
source .claude/hooks/logger.sh
log_hook "INFO" "Starting format check for $CLAUDE_FILE_PATH"
# ... 实际逻辑 ...
log_hook "INFO" "Format check completed"
```

---

## 第九章：团队协作——Hooks工程化

### 9.1 项目Hooks目录结构

```
project-root/
├── .claude/
│   ├── settings.json          # Hooks配置入口
│   ├── hooks/
│   │   ├── README.md          # Hooks说明文档
│   │   ├── block-dangerous.sh
│   │   ├── protect-files.sh
│   │   ├── smart-format.sh
│   │   ├── auto-test.sh
│   │   ├── notify.sh
│   │   └── logger.sh          # 共享日志模块
│   └── hooks.log              # 运行日志（gitignore）
├── .gitignore
└── ...
```

`.gitignore`中添加：
```
.claude/hooks.log
.claude/.formatting-*
```

### 9.2 团队共享配置

将项目Hooks纳入版本控制，确保团队一致性：

```bash
# 初始化
git add .claude/settings.json .claude/hooks/
git commit -m "feat: add Claude Code hooks for project safety and automation"
```

团队成员拉取后自动生效，无需额外配置。

### 9.3 Hooks测试框架

为Hooks编写测试，确保可靠性：

```bash
#!/bin/bash
# .claude/hooks/test-hooks.sh

set -e

PASS=0
FAIL=0

assert_exit_code() {
  local test_name="$1"
  local expected="$2"
  local actual="$3"
  if [[ "$actual" == "$expected" ]]; then
    echo "✅ PASS: $test_name"
    ((PASS++))
  else
    echo "❌ FAIL: $test_name (expected=$expected, actual=$actual)"
    ((FAIL++))
  fi
}

# 测试1：安全命令应通过
echo '{"command":"ls -la src/"}' | bash .claude/hooks/block-dangerous.sh
assert_exit_code "Safe command passes" "0" "$?"

# 测试2：rm -rf应被阻止
echo '{"command":"rm -rf /"}' | bash .claude/hooks/block-dangerous.sh
assert_exit_code "rm -rf blocked" "2" "$?"

# 测试3：DROP TABLE应被阻止
echo '{"command":"echo \"DROP TABLE users;\""}' | bash .claude/hooks/block-dangerous.sh
assert_exit_code "DROP TABLE blocked" "2" "$?"

# 测试4：保护.env文件
echo '{"file_path":"./.env"}' | bash .claude/hooks/protect-files.sh
assert_exit_code ".env protected" "2" "$?"

# 测试5：普通文件可编辑
echo '{"file_path":"./src/app.ts"}' | bash .claude/hooks/protect-files.sh
assert_exit_code "Normal file allowed" "0" "$?"

echo ""
echo "═══════════════════════════"
echo "  Results: $PASS passed, $FAIL failed"
echo "═══════════════════════════"

[[ $FAIL -eq 0 ]] || exit 1
```

运行测试：
```bash
bash .claude/hooks/test-hooks.sh
```

预期输出：
```
✅ PASS: Safe command passes
✅ PASS: rm -rf blocked
✅ PASS: DROP TABLE blocked
✅ PASS: .env protected
✅ PASS: Normal file allowed

═══════════════════════════
  Results: 5 passed, 0 failed
═══════════════════════════
```

---

## 第十章：完整实战项目——全栈项目Hooks套件

### 10.1 项目场景

一个React + Node.js + PostgreSQL全栈项目，需要：
1. 自动格式化（Prettier + ESLint）
2. 安全防护（阻止危险命令、保护敏感文件）
3. 编辑后自动测试
4. Git分支规范注入
5. 任务完成通知

### 10.2 完整配置

**`.claude/settings.json`**：

```json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/block-dangerous.sh"
          },
          {
            "type": "prompt",
            "prompt": "本项目使用pnpm，不要使用npm或yarn。Docker命令需加--user $(id -u):$(id -g)。"
          }
        ]
      },
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/protect-files.sh"
          },
          {
            "type": "prompt",
            "prompt": "编码规范：TypeScript严格模式，React函数式组件，Zustand状态管理，Tailwind CSS。每个组件不超过200行，函数不超过30行。"
          }
        ]
      }
    ],
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/smart-format.sh"
          },
          {
            "type": "command",
            "command": "bash .claude/hooks/auto-test.sh"
          },
          {
            "type": "command",
            "command": "bash .claude/hooks/auto-git.sh"
          }
        ]
      }
    ],
    "Notification": [
      {
        "matcher": "",
        "hooks": [
          {
            "type": "command",
            "command": "bash .claude/hooks/notify.sh"
          }
        ]
      }
    ]
  }
}
```

### 10.3 工作流全览

```mermaid
flowchart TB
    A[Claude Code 会话启动] --> B{工具调用?}

    B -->|Bash命令| C[PreToolUse: Bash]
    C --> C1[安全检查脚本]
    C --> C2[pnpm规范提示]
    C1 -->|exit 0| D[执行Bash命令]
    C1 -->|exit 2 阻止| E[返回错误给Claude]

    B -->|Write/Edit文件| F[PreToolUse: Write/Edit]
    F --> F1[敏感文件保护检查]
    F --> F2[编码规范注入]
    F1 -->|exit 0| G[执行文件编辑]
    F1 -->|exit 2 阻止| E

    D --> H[PostToolUse]
    G --> H

    H --> H1[智能格式化]
    H1 --> H2[自动运行测试]
    H2 --> H3[自动Git暂存]

    H3 --> I[Claude继续响应]

    I --> J{会话结束?}
    J -->|是| K[Notification Hook]
    K --> K1[发送桌面通知]
    K --> L[会话结束]

    J -->|否| B

    style C1 fill:#ff6b6b,color:#fff
    style F1 fill:#ff6b6b,color:#fff
    style E fill:#ffd93d,color:#333
    style K1 fill:#6bcb77,color:#fff
```

### 10.4 配置验证清单

部署前逐项验证：

```bash
# 1. JSON格式检查
jq . .claude/settings.json && echo "✅ JSON valid"

# 2. 所有脚本可执行
for f in .claude/hooks/*.sh; do
  test -x "$f" && echo "✅ $f" || echo "❌ $f (chmod +x needed)"
done

# 3. 依赖检查
command -v jq >/dev/null && echo "✅ jq" || echo "❌ jq missing"
command -v npx >/dev/null && echo "✅ npx" || echo "❌ npx missing"

# 4. 运行Hooks测试
bash .claude/hooks/test-hooks.sh

# 5. 端到端验证
echo "启动Claude Code并执行以下测试："
echo "  a) 让Claude编辑一个.ts文件 → 应自动格式化"
echo "  b) 让Claude运行'rm -rf /' → 应被阻止"
echo "  c) 让Claude编辑.env → 应被保护"
```

---

## 第十一章：性能优化与最佳实践

### 11.1 性能原则

| 原则 | 说明 |
|------|------|
| **快速执行** | Hook应<500ms完成，避免阻塞Claude |
| **异步非阻塞** | 耗时操作（测试、通知）考虑后台执行 |
| **失败优雅** | 用`\|\| true`确保Hook失败不中断主流程 |
| **条件判断前置** | 先检查文件类型再执行具体操作 |

### 11.2 异步Hook模式

对于耗时操作（运行完整测试套件、发送通知），使用后台执行：

```bash
#!/bin/bash
# .claude/hooks/async-test.sh

FILE="$CLAUDE_FILE_PATH"

# 快速检查是否有对应测试
if [[ "$FILE" != *.ts ]] && [[ "$FILE" != *.tsx ]]; then
  exit 0
fi

TEST_FILE="${FILE%.ts}.test.ts"
[[ ! -f "$TEST_FILE" ]] && TEST_FILE="${FILE%.ts}.spec.ts"
[[ ! -f "$TEST_FILE" ]] && exit 0

# 后台运行测试，结果写入日志
(
  RESULT=$(npx vitest run "$TEST_FILE" 2>&1)
  echo "[$(date)] Test $TEST_FILE: $RESULT" >> .claude/hooks/test-results.log
) &

# 立即返回，不阻塞Claude
exit 0
```

### 11.3 配置分层策略

```
┌──────────────────────────────────────┐
│     企业级（管理员配置）              │  ← 安全策略、合规要求
│     所有项目强制执行                  │
├──────────────────────────────────────┤
│     用户级（~/.claude/settings.json）│  ← 个人偏好（主题、通知）
│     跨项目统一                       │
├──────────────────────────────────────┤
│     项目级（.claude/settings.json）  │  ← 项目特定规则
│     团队共享，进入版本控制            │
└──────────────────────────────────────┘
```

**建议分配**：
- **企业级**：阻止危险命令、保护敏感文件（强制）
- **用户级**：个人通知偏好、个人格式化工具
- **项目级**：项目特定格式化规则、测试策略、编码规范注入

### 11.4 避免的常见陷阱

1. **不要在Hook中执行长时间阻塞命令**——Claude会等待Hook完成才继续
2. **不要在PreToolUse中执行修改操作**——只做检查和阻止
3. **不要在PostToolUse中返回exit 2**——PostToolUse的阻止语义与PreToolUse不同
4. **不要依赖AI行为来触发Hook**——Hook是确定性的，但AI不一定每次都调用相同工具
5. **不要忽略跨平台兼容性**——团队成员可能使用不同操作系统

---

## 第十二章：Hook与CLAUDE.md的协作

Hooks和CLAUDE.md各有分工，理解它们的关系能更好地组织项目规范：

| 维度 | CLAUDE.md | Hooks |
|------|-----------|-------|
| 本质 | AI读取的文本指令 | 系统执行的代码/脚本 |
| 确定性 | AI可能忽略 | 100%执行 |
| 适用场景 | 编码风格、架构决策 | 安全防护、自动化流程 |
| 可维护性 | Markdown，易读 | Shell脚本，需测试 |
| 执行时机 | 会话启动时加载 | 每次工具调用时触发 |

**最佳实践**：
- **CLAUDE.md**：记录"应该做什么"（编码规范、架构说明）
- **Hooks**：执行"必须做什么"（安全检查、自动格式化）
- **两者互补**：CLAUDE.md告诉AI项目背景，Hooks确保AI不犯低级错误

---

## 延伸阅读

- [Claude Code Hooks官方文档](https://code.claude.com/docs/en/hooks) —— 最权威的参考手册，包含完整schema定义
- [Claude Code Hooks实战指南](https://code.claude.com/docs/en/hooks-guide) —— 官方快速上手教程
- [disler/claude-code-hooks-mastery](https://github.com/disler/claude-code-hooks-mastery) —— 社区维护的Hooks示例集合（3.7k stars）

---

## 参考来源

1. [Hooks Reference - Claude Code Docs](https://code.claude.com/docs/en/hooks) — Anthropic官方Hooks参考文档，涵盖schema、事件类型、环境变量、退出码
2. [Automate Actions with Hooks - Claude Code Docs](https://code.claude.com/docs/en/hooks-guide) — 官方Hooks快速上手指南，包含实战示例
3. [Claude Code Hooks: Complete Guide with 20+ Examples](https://aiorg.dev/blog/claude-code-hooks) — 社区综合指南，20+即用配置模板
4. [disler/claude-code-hooks-mastery - GitHub](https://github.com/disler/claude-code-hooks-mastery) — 开源Hooks示例仓库，3.7k stars
5. [Claude Code Hooks: A Practical Guide - DataCamp](https://www.datacamp.com/tutorial/claude-code-hooks) — DataCamp教程，适合系统学习

---

**训练营适用性评估**：

| 训练营类型 | 适用性 | 预计时长 | 说明 |
|------------|--------|----------|------|
| Claude Code初级营 | ⭐⭐ | 2小时 | 建议只讲第1-3章（概念+第一个Hook） |
| Claude Code进阶营 | ⭐⭐⭐⭐⭐ | 4-6小时 | 全部章节，重点第4-7章 |
| 企业AI工程化营 | ⭐⭐⭐⭐⭐ | 6-8小时 | 全部章节+团队协作+CI/CD集成 |
| DevOps自动化营 | ⭐⭐⭐⭐ | 3-4小时 | 重点第6、8、9章 |
| 安全工程营 | ⭐⭐⭐ | 2-3小时 | 重点第4、8章（安全防护+测试框架） |

> [!tip] 51学通信知识星球
> **星主：爱卫生**（微信：gprshome201101）——公众号「51学通信」创办者，19 年通信行业运维与讲师经验，著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书（各大电商平台有售）。
> **星球定位**：深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域，主打运维岗位与信令分析。
> **当前规模**：5200 篇主题 / 990 个回答，198 元/年。
> **加入福利**：加入星球后请加爱卫生微信，拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题，另有群内分享。
> **AI 加持**：51学通信知识星球已作为 skill 接入 WorkBuddy，使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例，做总结、找文档和 PPT 等场景全覆盖。

![51学通信知识星球海报-扫码加入](https://wiki.500nian.com/images/zhixingqiu_qrcode.png)
