Skip to content

Everything Claude Code 的 Hooks 体系为 AI 编程助手提供了强大的事件驱动自动化能力,覆盖 PreToolUse、PostToolUse、Stop 等 17 个关键节点,支持代码质量把关、安全防护和自定义自动化。本文将详解 Hook 的执行时序、完整配置表、环境变量动态控制、Node.js 脚本开发模式,并通过四个典型实战配方,帮助开发者高效落地生产级 AI 编程自动化。

Everything Claude Code Hooks 实战:PreToolUse / PostToolUse / Stop 事件驱动自动化完全配置

AI 编程助手正逐步成为开发主力,但如何让 Claude Code、Codex、Cursor 等 Agent 真正“懂规则、守底线、自动纠错”,核心在于事件驱动的 Hooks 自动化体系。Everything Claude Code(ECC)在 10 个月的生产实践中,打造了覆盖 17 个关键节点的 Hook 机制,实现了代码质量、流程安全、团队规范的自动化守护。

本文将系统讲解 ECC Hooks 的执行流程、内置表格、动态配置、Node.js 脚本开发模式,以及 4 个实战 Hook 配方,助你从入门到深度定制全面掌控 AI 编程自动化。

一、Hook 执行时序与核心事件

ECC 的 Hook 体系围绕“工具调用生命周期”设计,核心流程如下:

用户请求 → Claude 选择工具 → PreToolUse Hook 运行 → 工具实际执行 → PostToolUse Hook 运行 → Claude 输出响应 → Stop/Session Hooks

关键事件说明:

  • PreToolUse:工具执行前触发。可阻断(exit code 2)或仅警告(stderr)。
  • PostToolUse:工具执行后触发。可分析输出,但不可阻断。
  • Stop:每次 Claude 响应后触发。适合批量检查、状态持久化。
  • SessionStart/SessionEnd:会话生命周期边界事件,适合初始化和清理。
  • PreCompact:上下文压缩前触发,适合保存状态或持久化。

这种分层事件设计,使得每一步都能插入自动化校验、分析和安全措施。例如,PreToolUse 可阻止危险命令,PostToolUse 可自动格式化代码,Stop 可批量审计所有变更。

二、Everything Claude Code 内置 Hook 完整表(17 个核心 Hook)

ECC 默认配置了 17 个高价值 Hook,覆盖 Bash、Edit、Write、MultiEdit 等常用工具,兼顾安全、质量、可维护性。下表为核心 Hook 一览:

Hook ID事件匹配器主要功能描述是否可阻断
pre:bash:block-no-verifyPreToolUseBash阻止 git --no-verify 跳过 commit/push hook
pre:bash:auto-tmux-devPreToolUseBash自动在 tmux 下启动 dev server,避免日志丢失
pre:bash:tmux-reminderPreToolUseBash长时间命令提醒使用 tmux
pre:bash:git-push-reminderPreToolUseBashgit push 前提醒变更审查
pre:bash:commit-qualityPreToolUseBashcommit 前质量检查,检测 console.log、secrets、commit 格式
pre:write:doc-file-warningPreToolUseWrite非标准文档文件警告
pre:edit-write:suggest-compactPreToolUseEdit/Write建议手动 compact,防止上下文膨胀
pre:insaits:securityPreToolUseBash/Write...可选 AI 安全扫描(需配置环境变量)
pre:governance-capturePreToolUseBash/Write...治理事件捕获(如 secrets、策略违规)
pre:config-protectionPreToolUseWrite/Edit...阻止弱化 linter/formatter 配置
pre:mcp-health-checkPreToolUse*MCP 服务器健康检查
post:bash:pr-createdPostToolUseBashPR 创建后记录 URL 并提示 review 命令
post:quality-gatePostToolUseEdit/Write...文件编辑后质量门控(异步)
post:edit:design-quality-checkPostToolUseEdit/Write...前端编辑后检测“模板化”风险
post:edit:console-warnPostToolUseEdit编辑后 console.log 警告
stop:format-typecheckStop*批量格式化+类型检查(一次性处理所有编辑文件)
stop:check-console-logStop*检查所有变更文件中的 console.log
...(略,详见 hooks.json)

完整配置和更多细节可参考 Everything Claude Code 完全指南

三、Hook 配置与环境变量动态控制

ECC 支持多种方式灵活配置和控制 Hook 行为:

1. 禁用/重载某个 Hook

  • 直接在 hooks.json 注释或移除对应条目
  • 或在 ~/.claude/settings.json 覆盖,例如允许所有 .md 文件创建:
json
{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Write",
        "hooks": [],
        "description": "Override: allow all .md file creation"
      }
    ]
  }
}

2. 运行时环境变量控制(推荐)

无需改配置文件,直接用环境变量动态切换 Hook 组合:

bash
# 选择 Hook 配置强度:minimal | standard | strict(默认 standard)
export ECC_HOOK_PROFILE=standard

# 禁用指定 Hook(用逗号分隔多个 ID)
export ECC_DISABLED_HOOKS="pre:bash:tmux-reminder,post:edit:typecheck"
  • minimal:仅保留核心安全与生命周期 Hook
  • standard:默认,兼顾质量与安全
  • strict:增加更多提醒与防护

3. Hook 事件与匹配器说明

  • matcher 字段精确控制 Hook 作用对象(如 Bash、Edit、Write、MultiEdit、*)
  • 支持正则或多类型匹配,便于精细化自动化

四、Hook 脚本编写模式(Node.js stdin/stdout JSON schema)

ECC 的 Hook 推荐用 Node.js 编写,兼容 Windows/macOS/Linux,输入输出均为 JSON,易于集成与调试。

基本结构

javascript
// my-hook.js
let data = '';
process.stdin.on('data', chunk => data += chunk);
process.stdin.on('end', () => {
  const input = JSON.parse(data);

  // 读取工具信息
  const toolName = input.tool_name;        // "Edit", "Bash", "Write" 等
  const toolInput = input.tool_input;      // 工具参数
  const toolOutput = input.tool_output;    // PostToolUse 时可用

  // 警告(不阻断):输出 stderr
  console.error('[Hook] Warning message shown to Claude');

  // 阻断(PreToolUse 专用):exit code 2
  // process.exit(2);

  // 必须原样输出数据到 stdout
  console.log(data);
});

Exit code 语义

  • 0:正常继续
  • 2:阻断本次工具调用(仅 PreToolUse 支持)
  • 其它非零:记录错误但不阻断

Hook 输入 JSON Schema

typescript
interface HookInput {
  tool_name: string;          // "Bash", "Edit", "Write" 等
  tool_input: {
    command?: string;         // Bash 命令
    file_path?: string;       // 文件路径
    old_string?: string;      // Edit 替换前文本
    new_string?: string;      // Edit 替换后文本
    content?: string;         // Write 文件内容
  };
  tool_output?: {             // 仅 PostToolUse
    output?: string;          // 工具输出
  };
}

异步 Hook 支持

对于不应阻塞主流程的 Hook(如异步分析),可配置:

json
{
  "type": "command",
  "command": "node my-slow-hook.js",
  "async": true,
  "timeout": 30
}

五、4 个实战 Hook 配方

结合 ECC 实践,以下 4 个 Hook 配方可直接落地:

1. TODO/FIXME 警告

场景:新增代码含 TODO、FIXME、HACK 时警告,提醒规范管理。

json
{
  "matcher": "Edit",
  "hooks": [{
    "type": "command",
    "command": "node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const ns=i.tool_input?.new_string||'';if(/TODO|FIXME|HACK/.test(ns)){console.error('[Hook] New TODO/FIXME added - consider creating an issue')}console.log(d)})\""
  }],
  "description": "Warn when adding TODO/FIXME comments"
}

2. 大文件创建拦截

场景:阻止一次性生成超大文件,强制拆分模块。

json
{
  "matcher": "Write",
  "hooks": [{
    "type": "command",
    "command": "node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const c=i.tool_input?.content||'';const lines=c.split('\\n').length;if(lines>800){console.error('[Hook] BLOCKED: File exceeds 800 lines ('+lines+' lines)');console.error('[Hook] Split into smaller, focused modules');process.exit(2)}console.log(d)})\""
  }],
  "description": "Block creation of files larger than 800 lines"
}

3. Python ruff 自动格式化

场景:每次 Python 文件编辑后自动调用 ruff 格式化,保障风格统一。

json
{
  "matcher": "Edit",
  "hooks": [{
    "type": "command",
    "command": "node -e \"let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path||'';if(/\\.py$/.test(p)){const{execFileSync}=require('child_process');try{execFileSync('ruff',['format',p],{stdio:'pipe'})}catch(e){}}console.log(d)})\""
  }],
  "description": "Auto-format Python files with ruff after edits"
}

4. 新增源码文件强制检测测试文件

场景:新增 src/ 下的 ts/js 文件时,自动检查是否有对应 test 文件,缺失时提醒先写测试。

json
{
  "matcher": "Write",
  "hooks": [{
    "type": "command",
    "command": "node -e \"const fs=require('fs');let d='';process.stdin.on('data',c=>d+=c);process.stdin.on('end',()=>{const i=JSON.parse(d);const p=i.tool_input?.file_path||'';if(/src\\/.*\\.(ts|js)$/.test(p)&&!/\\.test\\.|\\.spec\\./.test(p)){const testPath=p.replace(/\\.(ts|js)$/,'.test.$1');if(!fs.existsSync(testPath)){console.error('[Hook] No test file found for: '+p);console.error('[Hook] Expected: '+testPath);console.error('[Hook] Consider writing tests first (/tdd)')}}console.log(d)})\""
  }],
  "description": "Remind to create tests when adding new source files"
}

更多自动化与质量提升技巧,推荐阅读 Claude Code 高级技巧:Token 优化、记忆持久化、并行化与验证循环

六、跨平台兼容与最佳实践

  • ECC Hooks 推荐 Node.js 实现,兼容 Windows/macOS/Linux。
  • 部分 observer hook 保留 shell 实现,已做 profile/平台兼容处理。
  • 建议所有自定义 Hook 均输出原始数据到 stdout,避免副作用。

相关主题推荐


FAQ

Q: 如何快速禁用某个默认 Hook?
A: 推荐用 export ECC_DISABLED_HOOKS="hook_id1,hook_id2" 环境变量临时关闭,无需改配置文件,hook_id 可在 hooks.json 查找。

Q: Hook 脚本必须用 Node.js 写吗?
A: 推荐 Node.js 以保证跨平台兼容,也支持 shell 脚本,但需自行保证输入输出为 JSON 格式,且处理好 exit code。

Q: 如何让自定义 Hook 只在特定工具或文件类型下触发?
A: 配置 hooks.json 时用 matcher 字段精准匹配,如 "Edit|Write"、"Bash" 或正则表达式,灵活控制 Hook 作用范围。