ECC TypeScript/JavaScript Hooks 规则:在 Agent 编辑 JS/TS 文件后自动格式化、类型检查与 console.log 审计

发布时间:2026/9/7 18:22:45
ECC TypeScript/JavaScript Hooks 规则:在 Agent 编辑 JS/TS 文件后自动格式化、类型检查与 console.log 审计 ECC TypeScript/JavaScript Hooks 规则在 Agent 编辑 JS/TS 文件后自动格式化、类型检查与 console.log 审计【免费下载链接】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本文以 ECC 仓库中的 .cursor/rules/typescript-hooks.md 规则文件为主体完整解读它为 TypeScript/JavaScript 项目定义的 Hook 策略在每次编辑文件之后PostToolUse执行 Prettier 自动格式化、tsc类型检查与console.log警告在会话结束前Stop对所有修改过的文件做最终的console.log审计。读完本文你将理解这套规则在 ECC 中如何被 .cursor/hooks.json 注册、如何通过 .cursor/hooks/adapter.js 适配到 Claude Code 风格的 hook 协议以及底层 scripts/hooks 目录下各检查脚本的具体实现逻辑与容错设计。一、规则文件定位按 glob 精确生效的 TypeScript 扩展规则.cursor/rules/typescript-hooks.md 是一个 Cursor 规则rules文件其 frontmatter 决定了两件事——在什么文件上生效、是否总是注入--- description: TypeScript hooks extending common rules globs: [**/*.ts, **/*.tsx, **/*.js, **/*.jsx] alwaysApply: false ---globs限定了规则只在 TS/TSX/JS/JSX 文件被操作时加载覆盖典型的前端与 Node.js 项目文件类型alwaysApply: false表示该规则不会常驻上下文只在文件模式命中时按需生效这是一种控制 token 开销的写法。文件开头明确说明其定位是在通用 hooks 规则的基础上扩展 TypeScript/JavaScript 专属内容。与之配合的是通用规则 .cursor/rules/common-hooks.md它定义了 Hook 体系的三个基本类型是本规则文件的父集Hook 类型触发时机典型用途PreToolUse工具执行前参数校验、参数修改、拦截危险操作PostToolUse工具执行后自动格式化、质量检查Stop会话响应结束时最终验证与收尾审计typescript-hooks.md的全部规范内容即围绕 PostToolUse 与 Stop 两类展开这正是它在通用规则之上只补差异的设计意图通用层定义框架语言专属层只声明该语言需要哪些具体检查。二、PostToolUse Hooks编辑文件后的三道即时防线规则文件为 PostToolUse 阶段声明了三项配置文档指出配置入口为~/.claude/settings.jsonPrettier编辑 JS/TS 文件后自动格式化TypeScript check编辑.ts/.tsx文件后运行tsc做类型检查console.log warning对被编辑文件中的console.log发出警告。这三项并非纸面约定在仓库中有完整对应的实现链路。2.1 事件注册afterFileEdit 钩子.cursor/hooks.json 将afterFileEdit事件绑定到.cursor/hooks/after-file-edit.js其描述直接对应规则文件中的三条能力Auto-format, TypeScript check, console.log warning, and frontend design-quality reminder。2.2 适配层Cursor 事件如何落到共享脚本.cursor/hooks/after-file-edit.js 本身是一个极薄的分发器它通过adapter.js读取 stdin 中的 Cursor 事件 JSON转换为 Claude Code 风格的 hook 输入tool_input.file_path等字段然后依次委托给三个共享脚本// 累积被编辑路径供 Stop 时批量 format typecheck runExistingHook(post-edit-accumulator.js, claudeStr); // 对刚编辑的文件做 console.log 即时警告 runExistingHook(post-edit-console-warn.js, claudeStr); // 前端设计质量提醒standard/strict profile 下启用 if (hookEnabled(post:edit:design-quality-check, [standard, strict])) { runExistingHook(design-quality-check.js, claudeStr); }.cursor/hooks/adapter.js 中的transformToClaude负责字段映射path/file/args.filePath归一到tool_input.file_pathrunExistingHook通过execFileSync以 15 秒超时调用scripts/hooks/下的实际脚本并且会在子进程返回退出码 2 时向上传播该码——这是 hook 协议中阻断当前操作的约定。2.3 console.log 即时警告的实现scripts/hooks/post-edit-console-warn.js 是规则中console.log warning的直接实现。它对编辑路径做扩展名过滤\.(ts|tsx|js|jsx)$命中后逐行扫描文件内容输出带行号的警告const matches content .split(\n) .map((line, index) ({ line, index })) .filter(item /console\.log/.test(item.line)) .map(item ${item.index 1}: ${item.line.trim()}); if (matches.length 0) { warnings.push([Hook] WARNING: console.log found in ${filePath}); warnings.push(...matches.slice(0, 5)); // 最多展示前 5 处 warnings.push([Hook] Remove console.log before committing); }值得注意的两个细节警告写入 stderr、原始 stdin JSON 原样回写 stdout保持 hook 链路透传约定且任何输入异常都静默降级为 pass-through——保证检查失败永远不会阻塞编辑操作。2.4 批量延迟策略格式化和 tsc 为何不在每次编辑后跑规则文档写的是编辑后自动 Prettier、编辑 .ts/.tsx 后运行 tsc但实现上采取了延迟批量策略其动机在 scripts/hooks/post-edit-accumulator.js 的头注释中说明得很清楚每次编辑都跑格式化 类型检查会产生可观的延迟因此该脚本只负责把编辑过的 JS/TS 路径按行追加写入一个会话级临时文件$TMPDIR/ecc-edited-sessionId.txt由 Stop 阶段的stop-format-typecheck.js一次性对全部文件执行 format typecheck。从源码结构看这里的工程考量包括使用appendFileSync追加写入使并发 hook 进程互不覆盖会话 ID 取自CLAUDE_SESSION_ID缺失时退化为 cwd 的 SHA1 前 12 位并对 ID 做字符清洗replace(/[^a-zA-Z0-9_-]/g, _)防止路径注入同时处理Edit/Write单个file_path与MultiEditedits数组两种工具输入去重被刻意推迟到 Stop 阶段完成。这也解释了 hooks/hooks.json 中 Claude Code 侧 Stop 事件里stop:format-typecheck条目的描述Batch format (Biome/Prettier) and typecheck (tsc) all JS/TS files edited this response — runs once at Stop instead of after every Edit其超时被放宽到 300 秒因为批量tsc在大型项目中耗时较长。三、Stop Hooks会话结束前的 console.log 全量审计规则文件的第二段要求在会话结束前检查所有被修改文件的console.log。这一能力的注册与实现如下3.1 事件注册与 profile 门控.cursor/hooks.json 将stop事件绑定到 .cursor/hooks/stop.js描述为 Console.log audit on all modified files。stop.js在分发前通过hookEnabled做 profile 门控stop:check-console-log仅在standard/strictprofile 下运行。hookEnabled的判定逻辑见 adapter.js由两个环境变量控制环境变量取值作用ECC_HOOK_PROFILEminimal/standard/strict默认standard非法值回退standard决定哪些 profile 允许该 hook 运行ECC_DISABLED_HOOKS逗号分隔的 hook ID 列表显式禁用指定 hook优先级最高这意味着用户可以按项目阶段整体降档如minimal只保留最核心的会话生命周期钩子或单独关闭某一项检查而无需改动任何 hook 配置文件。3.2 审计脚本只查工作区实际改过的文件scripts/hooks/check-console-log.js 是 Stop 审计的实现其工作方式与编辑后的即时警告形成互补数据来源不是 hook 事件里的单个文件而是getGitModifiedFiles([\\.tsx?$, \\.jsx?$])即通过 git 获取当前工作区所有已修改的 JS/TS 文件——这正对应规则文档中Checkall modified files的语义内置排除规则EXCLUDED_PATTERNS测试文件*.test.*、*.spec.*、__tests__/、__mocks__/、配置文件*.config.*以及scripts/目录下的文件不触发警告因为console.log 在这些地方往往是有意为之命中时输出两条日志WARNING: console.log found in file与收尾提示Remove console.log statements before committing非 git 仓库直接跳过检查。容错设计同样值得一提脚本对 stdin 设置 1MB 上限MAX_STDIN若输入被截断则不回传stdin 数据——注释说明这是为避免半截 JSON 被 harness 判定为 Stop hook 校验失败对应 issue #2090任何异常都走 fail-open最终passThroughAndExit保证 hook 永远不会阻断会话结束。3.3 两级检查的分工综合源码可以看到console.log治理实际上是一个两级漏斗编辑后即时层PostToolUse → post-edit-console-warn.js只看刚编辑的那一个文件输出精确行号最多展示 5 处命中帮助 Agent/开发者在编码当下立即清理会话收尾层Stop → check-console-log.js基于 git 修改清单做全量兜底审计覆盖即时层可能漏掉的文件例如通过 shell 命令修改的文件并以测试/配置目录白名单降低误报。四、与 Claude Code 侧配置的对应关系ECC 的 hook 体系是一套底层脚本、多端注册的结构Cursor 侧通过 .cursor/hooks.json .cursor/hooks 薄适配器注册Claude Code 侧则通过 hooks/hooks.json 直接以matcher匹配工具名注册。以本文主题相关的检查为例Claude 侧的对应条目包括PostToolUse的post:dispatcher:sync/post:dispatcher:async将同步与后台 PostToolUse 检查收敛到 scripts/hooks/posttooluse-dispatcher.js 单进程内分发同步通道 30 秒、异步通道 45 秒超时Stop的stop:check-console-log调用 check-console-log.js、stop:format-typecheck调用 stop-format-typecheck.js300 秒超时、stop:session-end、stop:evaluate-session、stop:cost-tracker等均带minimal,standard,strict或standard,strict的 profile 门控此外 PreToolUse 中还有pre:config-protection等互补机制——阻断 Agent 修改 linter/formatter 配置文件引导 Agent 去修代码而不是削弱配置与本文的自动格式化 hook 构成一攻一防的组合。需要说明的适用前提.cursor/目录下的 hook 依赖 Cursor 的 hooks 能力加载 .cursor/hooks.json而规则文件本身frontmatter 自然语言主要服务于 Cursor 的规则注入场景。~/.claude/settings.json是 Claude Code 的配置入口ECC 仓库提供的 hooks/hooks.json其$schema指向 claude-code-settings即面向该入口的等价实现。两端事件命名不同如afterFileEditvsPostToolUse但委托的底层脚本是同一批行为保持一致。五、要点总结与实践参考从 .cursor/rules/typescript-hooks.md 这一份不到 20 行的规则文件出发结合仓库源码可以提炼出 ECC 处理Agent 写 TS/JS 代码的完整质量闭环阶段能力注册位置底层实现PostToolUse编辑后 console.log 行级警告.cursor/hooks.jsonafterFileEditscripts/hooks/post-edit-console-warn.jsPostToolUse累积编辑路径供批量处理同上scripts/hooks/post-edit-accumulator.jsStop批量 Prettier/Biome 格式化 tsc 类型检查hooks/hooks.jsonstop:format-typecheckscripts/hooks/stop-format-typecheck.jsStop全量修改文件 console.log 审计两端 Stop 事件scripts/hooks/check-console-log.js其设计取舍对搭建自有 Agent hook 体系有直接参考价值高频轻检查正则扫描放在编辑后即时执行并给出行号重检查tsc通过路径累积文件延迟到 Stop 批量执行以消除逐次延迟所有检查脚本统一 1MB stdin 上限、fail-open 容错与原样回传 stdin的链路透传约定检查项通过ECC_HOOK_PROFILE与ECC_DISABLED_HOOKS环境变量实现 profile 降档与按 ID 的精细禁用敏感目录测试、脚本、配置以白名单排除误报。这些机制均可在 scripts/hooks 目录下逐文件查证测试用例位于 tests 与 tests/hooks 对应文件中可作为行为验证的入口。【免费下载链接】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),仅供参考