ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ECC Hooks 系统深度解析:PreToolUse / PostToolUse / Stop 钩子机制、权限安全与自定义实战

ECC Hooks 系统深度解析:PreToolUse / PostToolUse / Stop 钩子机制、权限安全与自定义实战 ECC Hooks 系统深度解析PreToolUse / PostToolUse / Stop 钩子机制、权限安全与自定义实战【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECCHooks 是 ECCEverything Claude Code中基于事件驱动的自动化机制它们挂载在 Agent 每次工具调用的前后与会话生命周期边界上用于强制执行代码质量、提前拦截错误并自动化重复性检查。本文以docs/ja-JP/rules/common/hooks.md的 Hook 架构规范为核心结合仓库中的hooks/hooks.json配置图、hooks/README.md安装指南与scripts/hooks/下的真实实现系统讲解 Hook 类型、自动接受权限的安全边界、TodoWrite 最佳实践以及如何编写可跨平台运行的自定义 Hook。读完本文你将掌握在 Claude Code / Codex / Opencode 等 harness 上部署、调优和扩展 ECC Hook 体系的完整方法。Hooks 系统的工作流程Hooks 是事件驱动的自动化在 Claude Code 工具执行之前或之后触发。ECC 的核心执行链路可以概括为User request → Claude picks a tool → PreToolUse hook runs → Tool executes → PostToolUse hook runsPreToolUsehooks 在工具执行前运行可以阻止exit code 2或警告stderr 不阻止PostToolUsehooks 在工具完成后运行可以分析输出但不能阻止Stophooks 在每次 Claude 响应后运行SessionStart / SessionEndhooks 在会话生命周期边界运行PreCompacthooks 在上下文压缩前运行适合保存状态。Hook 类型详解PreToolUse工具执行前验证、参数修改PreToolUse 是唯一可以真正阻止工具调用的 Hook 类型适合做验证与参数修改。ECC 内置了多个 PreToolUse 钩子例如 pre-bash-dev-server-block.js 会在非 tmux 环境下阻止npm run dev等开发服务器命令退出码 2以保证日志可访问性。从源码可以看到它会展开$(...)命令替换与(...)子 shell 分组递归收集所有命令行分段防止$(npm run dev)这类包装命令绕过检查。ECC 的 PreToolUse 钩子通常经过 run-with-flags.js 这个门控执行器运行——只有当当前 Hook Profile 允许该钩子时才真正执行脚本否则直接透传 stdin 并以退出码 0 结束fail-open不干预工具调用。该执行器还实现了路径穿越防护拒绝指向插件根目录之外的脚本以及大输入截断处理超过 1MB 时抑制透传避免截断的 JSON 被 harness 判定为 hook 失败。PostToolUse工具执行后自动格式化、检查PostToolUse 在工具完成后运行典型用途包括自动格式化、质量门禁、构建分析与 PR 日志。ECC 在hooks/hooks.json中通过post:dispatcher:sync同步与post:dispatcher:async后台异步两个分发器钩子在单进程内批量执行所有 PostToolUse 钩子同时保留每个钩子各自的 profile 门控。Stop会话结束时最终验证Stop 钩子在每次 Agent 响应结束后运行适合做最终验证与状态持久化。典型例子是 check-console-log.js它遍历本次修改过的 JS/TS 文件检查是否残留console.log并给出警告同时遵守always-exit-0约定通过 stderr 输出警告而不阻断流程。源码中通过EXCLUDED_PATTERNS排除了测试文件、配置文件与scripts/目录这些场景中console.log是合理的。ECC 的 Stop 钩子还承担了大量会话管理职责Plan Canvas 待交付反馈投递stop:plan-canvas-pending、批量格式化与类型检查stop:format-typecheck对本次响应编辑过的所有 JS/TS 文件统一执行 Biome/Prettier 与tsc避免每次 Edit 后都跑一遍、会话状态持久化stop:session-end、模式提取stop:evaluate-session支撑持续学习、成本追踪stop:cost-tracker与桌面通知stop:desktop-notify。会话生命周期钩子除三大核心类型外ECC 还实现了完整的生命周期钩子SessionStart加载历史上下文并探测包管理器、恢复 Plan Canvas 浏览器评审、PreCompact上下文压缩前保存状态、SessionEnd生命周期标记与清理日志、PostToolUseFailure跟踪失败的 MCP 工具调用并标记不健康服务器。退出码语义与阻止/警告机制Hook 通过退出码与 stdout/stderr 与 harness 通信退出码含义适用范围0成功继续执行所有 Hook2阻止该工具调用仅 PreToolUse其他非零错误记录日志但不阻止所有 Hook警告warn向 stderr 输出提示信息工具调用照常进行阻止blockPreToolUse 钩子以退出码 2 退出工具调用被拦截透传约定Hook 必须将原始 stdin 原样写回 stdout否则 harness 可能误判为 Hook 失败。一个需要特别注意的细节非阻塞 PreToolUse 钩子的 stderr 只写入调试日志不会进入模型上下文。若要向模型展示用户可见的建议需要像 suggest-compact.js 那样向 stdout 输出结构化 JSON 中的hookSpecificOutput.additionalContext字段。该钩子利用两个信号触发战略压缩建议工具调用计数默认每 50 次提醒一次和会话 transcript 中真实的上下文 token 用量按窗口比例缩放阈值200k 窗口默认 160k 触发、1M 窗口 250k 触发。自动接受权限与安全边界ECC 规则文档对自动接受权限Auto-Accept Permissions给出了明确的红线必须谨慎使用为受信任、定义明确的计划启用——当任务的每一步都是可预期、可审计的时候为探索性工作禁用——当 Agent 的行为边界不清晰、需要逐步确认的时候切勿使用dangerously-skip-permissions标志——这是绕过所有权限确认的核选项会抹掉 Agent 行为的全部审计痕迹改为在~/.claude.json中配置allowedTools——以白名单方式精确放行特定工具而不是一刀切跳过权限。allowedTools的典型配置方式如下{ permissions: { allow: [ Bash(npm run test), Read, Edit ] } }这一安全立场与仓库中的安全指南一致。the-security-guide.md 明确指出如果你无法看到 Agent 读取了什么、调用了哪个工具、尝试访问哪个网络目标就无法对其设防文中直接点名了在--dangerously-skip-permissions下运行多 Agent 循环并直接推送 main 分支的反面案例。ECC 的立场是权限放行应当最小化、可审计、面向受信计划而不是用跳过权限换取便利。TodoWrite 最佳实践TodoWrite 是长任务执行中的进度管理工具。ECC 规则要求使用 TodoWrite 工具来跟踪多步骤任务的进度验证对指令的理解写出计划等于把理解显式化实现实时指导让用户/监督者随时看到 Agent 的当前步骤展示细粒度的实现步骤。更重要的是Todo 列表本身是 Agent 对任务理解的暴露面一份糟糕的 Todo 列表会直接揭示步骤顺序错误——说明对依赖关系理解有偏差缺失的项目——说明遗漏了关键需求额外不必要的项目——说明过度设计或误读了范围粒度错误——过粗则无法跟踪过细则淹没在噪音中被误解的需求——Todo 与指令不一致时应尽早纠正而非埋头执行。实践要点在任务开始前写 Todo随执行进度实时勾选更新在里程碑处对照 Todo 清单做偏差审查。在 ECC 中安装与启用 HooksECC 的 Hook 安装由官方安装器完成仓库内hooks/hooks.json是面向插件/仓库形态的配置图不建议手工将其粘贴到~/.claude/settings.json或直接复制到~/.claude/hooks/hooks.json——因为安装器会把 Hook 命令重写为针对你实际 Claude 根目录的路径。bash ./install.sh --target claude --modules hooks-runtime --enable-hookspwsh -File .\install.ps1 --target claude --modules hooks-runtime --enable-hooks安装后解析好的 Hook 会写入~/.claude/hooks/hooks.json在 Windows 上 Claude 配置根目录为%USERPROFILE%\.claude。内存持久化的生命周期定义位于 hooks/memory-persistence/ 目录它是 SessionStart、PreCompact、观测、活动跟踪与 SessionEnd 行为的稳定契约。运行时控制环境变量与 ProfileECC 推荐用环境变量在运行时控制 Hook 行为而无需编辑 hooks.json# 总开关。显式环境变量值优先于插件偏好设置。 export ECC_HOOKS_ENABLEDtrue # minimal | standard | strict默认standard export ECC_HOOK_PROFILEstandard # 按钩子 ID 禁用指定钩子逗号分隔 export ECC_DISABLED_HOOKSpre:bash:tmux-reminder,post:edit:typecheck # 仅在安装/恢复期间禁用 GateGuard export ECC_GATEGUARDoff # 限制 SessionStart 附加上下文默认 8000 字符 export ECC_SESSION_START_MAX_CHARS4000 # 完全禁用 SessionStart 附加上下文 export ECC_SESSION_START_CONTEXToff # 保留上下文/范围/循环警告但抑制 API 速率成本估算 export ECC_CONTEXT_MONITOR_COST_WARNINGSoffWindows PowerShell 下使用用户级环境变量[Environment]::SetEnvironmentVariable(ECC_CONTEXT_MONITOR_COST_WARNINGS, off, User)三个运行时 Hook Profile 的含义源码见 scripts/lib/hook-flags.js其中VALID_PROFILES只接受minimal | standard | strict三者minimal——只保留必要的生命周期与安全钩子standard——默认值均衡的质量 安全检查strict——启用额外的提醒与更严格的护栏。Claude 插件形态下ecc setup --mode claude-plugin会安装或更新插件并暴露与个人设置hooks_enabled、hook_profile相同的选项。此外ECC_GATEGUARDoff是setup-only值通过ecc setup关闭本地 ECC Hook 工作它不是运行时 Hook Profile。仓库内置钩子清单ECC 在 hooks/hooks.json 中维护了完整的可执行 Hook 图以下按类型汇总PreToolUse HooksHookMatcher行为退出码开发服务器阻止器Bash阻止在 tmux 外运行npm run dev等——确保日志可访问2阻止tmux 提醒Bash对长时运行命令npm test、cargo build、docker建议使用 tmux0警告git push 提醒Bash提醒在git push前审查变更0警告提交前质量检查Bashgit commit前执行质量检查lint 暂存文件、校验-m/--message提交信息格式、检测 console.log/debugger/密钥2阻止严重/ 0警告文档文件警告Write对非标准.md/.txt文件给出警告放行 README、CLAUDE、CONTRIBUTING、CHANGELOG、LICENSE、SKILL、docs/、skills/跨平台路径处理0警告战略压缩建议Edit\|Write在逻辑间隔约每 50 次工具调用建议手动/compact0警告hooks.json中还注册了pre:observe持续学习观测采集异步、pre:governance-capture治理事件捕获密钥/策略违规/审批请求需ECC_GOVERNANCE_CAPTURE1启用、pre:config-protection阻止修改 linter/formatter 配置文件引导 Agent 修代码而非放宽配置、pre:mcp-health-checkMCP 工具执行前健康检查拦截不健康调用与pre:edit-write:gateguard-fact-force事实强制门禁对每个文件的首次 Edit/Write 要求先完成调查再放行。PostToolUse HooksHookMatcher作用PR 日志Bashgh pr create后记录 PR URL 与审查命令构建分析Bash构建命令后的后台分析异步、非阻塞质量门禁Edit\|Write\|MultiEdit编辑后运行快速质量检查设计质量检查Edit\|Write\|MultiEdit前端编辑趋向通用模板 UI 时给出警告Prettier 格式化Edit编辑后自动用 Prettier 格式化 JS/TS 文件TypeScript 检查Edit编辑.ts/.tsx文件后运行tsc --noEmitconsole.log 警告Edit警告已编辑文件中出现的console.logLifecycle HooksHook事件作用会话启动SessionStart加载历史上下文并探测包管理器Plan Canvas 会话SessionStart呈现打开的 Plan Canvas 浏览器评审让新会话恢复循环压缩前保存PreCompact上下文压缩前保存状态console.log 审计Stop每次响应后检查所有修改文件中的console.log会话摘要Stop在可获取 transcript 路径时持久化会话状态模式提取Stop评估会话中可提取的模式持续学习成本追踪Stop输出轻量级运行成本遥测标记桌面通知Stop发送 macOS 桌面通知并附带任务摘要会话结束标记SessionEnd生命周期标记与清理日志编写自定义 HookHooks 本质上是 shell 命令从 stdin 接收工具输入JSON并把结果输出到 stdout。跨平台Windows / macOS / Linux的关键是用 Node.js 实现 Hook 逻辑——ECC 的所有内置 Hook 均为此模式。基本结构// 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] 将展示给 Claude 的警告信息); // 阻止仅 PreToolUse以退出码 2 退出 // process.exit(2); // 始终将原始数据输出到 stdout console.log(data); });Hook 输入 Schemainterface HookInput { tool_name: string; // Bash, Edit, Write, Read 等 tool_input: { command?: string; // Bash正在运行的命令 file_path?: string; // Edit/Write/Read目标文件 old_string?: string; // Edit被替换的文本 new_string?: string; // Edit替换后的文本 content?: string; // Write文件内容 }; tool_output?: { // 仅 PostToolUse output?: string; // 命令/工具输出 }; }异步 Hooks对于不应阻塞主流程的 Hook如后台分析设置async: true并给出超时{ type: command, command: node my-slow-hook.js, async: true, timeout: 30 }异步 Hook 在后台运行无法阻止工具执行。ECC 内置的观测采集、会话持久化、成本追踪与桌面通知均采用异步模式。常见配方警告新增 TODO 注释{ matcher: Edit, hooks: [{ type: command, command: node -e \let d;process.stdin.on(data,cdc);process.stdin.on(end,(){const iJSON.parse(d);const nsi.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 }阻止创建超大文件{ matcher: Write, hooks: [{ type: command, command: node -e \let d;process.stdin.on(data,cdc);process.stdin.on(end,(){const iJSON.parse(d);const ci.tool_input?.content||;const linesc.split(\\n).length;if(lines800){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 }用 ruff 自动格式化 Python 文件{ matcher: Edit, hooks: [{ type: command, command: node -e \let d;process.stdin.on(data,cdc);process.stdin.on(end,(){const iJSON.parse(d);const pi.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 }要求新源码文件附带测试文件{ matcher: Write, hooks: [{ type: command, command: node -e \const fsrequire(fs);let d;process.stdin.on(data,cdc);process.stdin.on(end,(){const iJSON.parse(d);const pi.tool_input?.file_path||;if(/src\\/.*\\.(ts|js)$/.test(p)!/\\.test\\.|\\.spec\\./.test(p)){const testPathp.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 }禁用或覆盖 Hook要禁用某个 Hook在hooks.json中移除或注释对应条目以插件方式安装时可在~/.claude/settings.json中覆盖{ hooks: { PreToolUse: [ { matcher: Write, hooks: [], description: Override: allow all .md file creation } ] } }源码与测试验证Hook 体系的实现集中在 scripts/hooks/ 目录50 余个脚本核心支撑包括run-with-flags.js——profile 门控执行器同时处理截断保护、路径穿越防护与require()直载优化导出了run()的钩子无需再 spawn 子进程可节省约 50–100ms/钩子scripts/lib/hook-flags.js——环境变量解析与 Profile 合法性校验scripts/lib/utils.js——跨平台工具函数Git 修改文件探测、stdin JSON 读取、日志与输出pre-bash-dispatcher.js 与 posttooluse-dispatcher.js——Bash 前置与 PostToolUse 的分发器session-start-bootstrap.js——会话启动引导。测试方面tests/hooks/ 下有覆盖上述机制的完整测试例如hook-flags.test.js环境变量与 Profile 解析、pre-bash-reminders.test.jstmux / push 提醒、posttooluse-dispatcher.test.js分发器行为、doc-file-warning.test.js、mcp-health-check.test.js与continuous-learning-observe-runner.test.js等可作为理解钩子契约与编写新 Hook 的参考范例。小结ECC 的 Hooks 系统将工具调用前验证、工具调用后检查、会话生命周期管理三条自动化主线统一在hooks/hooks.json的 Hook 图之下并借助 profile 门控与运行环境变量实现细粒度启停无需改动配置即可在minimal/standard/strict之间切换。对使用者而言牢记三条核心纪律即可PreToolUse 才能阻止、永远不要使用dangerously-skip-permissions、用 TodoWrite 暴露对任务的理解。在此基础上参考scripts/hooks/下的实现与tests/hooks/下的测试你就能写出安全、跨平台、可复用的自定义 Hook把 ECC 的自动化护栏延伸到自己的工程实践中。【免费下载链接】ECCThe agent harness performance optimization system. Skills, instincts, memory, security, and research-first development for Claude Code, Codex, Opencode, Cursor and beyond.项目地址: https://gitcode.com/GitHub_Trending/ev/ECC创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表