首页
/ ECC 的 typescript-reviewer:在 Kiro 中构建类型安全、异步正确性与 Node/Web 安全三位一体的 TypeScript 审查代理

ECC 的 typescript-reviewer:在 Kiro 中构建类型安全、异步正确性与 Node/Web 安全三位一体的 TypeScript 审查代理

2026-09-06 15:55:55作者:明树来

ECC(Everything Claude Code)为 Kiro 提供了一套可直接安装的 AI 代理组件,其中 typescript-reviewer 是专门负责 TypeScript/JavaScript 代码审查的专用代理:它以“只报告、不改写”为铁律,先确定可靠的审查范围与合并就绪状态,再按 CRITICAL/HIGH/MEDIUM 三级优先级清单逐项检查类型安全、异步正确性、错误处理、Node.js 特性与 React/Next.js 模式,最后输出可操作的审查结论。读完本文,你将完整掌握该代理的调用前流程(scope 确定、CI 就绪检查、typecheck/lint 前置)、全部审查优先级清单的判据与整改方向、配套诊断命令的使用方式,以及它在 ECC 的 Kiro 组件体系(hooks、steering、skills、quality-gate 脚本)中如何与其他组件协同工作。

代理定位与配置文件结构

typescript-reviewerKiro 集成目录 中被定义为 33 个内置代理之一,定位为“TypeScript/JavaScript code reviewer. Type safety, async correctness, Node/web security, and idiomatic patterns”。ECC 为每个代理同时提供两种格式:

两者的 frontmatter / 元数据对比如下:

字段 MD 格式 JSON 格式 说明
name typescript-reviewer typescript-reviewer 代理标识,两格式一致
description 专家级 TS/JS 审查者,覆盖类型安全、异步正确性、Node/Web 安全与惯用模式 同左 描述中明确要求“MUST BE USED for TypeScript/JavaScript projects”
allowedTools readshell fs_readshell 只读文件 + 可执行 shell 诊断命令;工具名因平台而异
tools @builtin JSON 格式显式声明使用内置工具集
mcpServers / hooks 均为空 不依赖 MCP 服务器,不内嵌 CLI hooks

值得注意的是,MD 格式的 allowedTools 只有 readshell——没有写入类工具。这与代理正文中“You DO NOT refactor or rewrite code — you report findings only(你不重构或改写代码,只报告发现)”的自我约束在配置层面完全对齐:代理在权限上就无法修改代码,只能运行诊断命令并输出报告。

同一代理在仓库根目录的 agents/typescript-reviewer.md(面向 Claude Code 等其他 harness)中还额外携带了 model: sonnet 声明、tools: Read, Grep, Glob, Bash 工具集以及一段“Prompt Defense Baseline”提示注入防护基线;而 Kiro 版本的模型由用户在 Kiro 中的当前模型选择决定,而非代理配置本身(.kiro/README.md 明确说明:“Agent models are determined by your current model selection in Kiro, not by the agent configuration”)。从源码结构看,两个文件共享同一份核心提示词(审查流程、优先级清单、诊断命令、批准标准逐条一致),差异仅在于 harness 前缀元数据与注入防护基线,这体现了 ECC “一次编写、多 harness 适配”的分发策略。

调用前流程:先定范围,再谈审查

该代理最突出的工程价值在于它把“审查开始前必须完成的准备工作”写成了一条编号明确的流水线(见 typescript-reviewer.md 第 11–24 行)。以下是完整流程与每步的停止条件:

第 1 步:确定审查范围(Establish the review scope)

  • PR 审查:优先使用 PR 的真实 base 分支——可通过 gh pr view --json baseRefName 获取,或回退到当前分支的 upstream / merge-base。不要硬编码 main(许多团队的集成分支不是 main)。
  • 本地审查:优先执行 git diff --stagedgit diff
  • 浅历史兜底:如果历史很浅或只有一个 commit,回退到 git show --patch HEAD -- '*.ts' '*.tsx' '*.js' '*.jsx',仍可通过文件级通配符检查代码层变更。

第 2 步:检查合并就绪状态(merge readiness)

在 PR 审查前,若元数据可用(例如通过 gh pr view --json mergeStateStatus,statusCheckRollup),必须检查:

  • 必需检查(required checks)失败或还在 pending → 停止审查,报告应等待 CI 变绿;
  • PR 存在合并冲突或处于不可合并(non-mergeable)状态 → 停止审查,报告必须先解决冲突;
  • 若当前上下文无法验证合并就绪状态 → 在继续前明确说明这一点,而不是默认就绪。

这一步把“CI 红灯时不要浪费人工/代理审查精力”的纪律固化进了代理行为,避免对将被 CI 打回的代码做无谓评论。

第 3 步:运行项目的“规范”类型检查命令

规则细节(第 20 行):

  1. 若项目定义了规范检查脚本(例如 npm/pnpm/yarn/bun run typecheck),优先使用它
  2. 若无该脚本,选择覆盖被改代码的那个 tsconfig,而不是默认落到仓库根目录的 tsconfig.json
  3. 在项目引用(project references)结构中,优先使用仓库提供的“不产物的 solution 级检查命令”,而不是盲目调用 build mode(tsc -b);
  4. 以上都不满足时,使用 tsc --noEmit -p <relevant-config>
  5. 纯 JavaScript 项目直接跳过此步,而不是把 typecheck 失败当作审查失败。

第 4 步:运行 ESLint

执行 eslint . --ext .ts,.tsx,.js,.jsx(如可用)。如果 lint 或 TypeScript 检查失败,立即停止并报告——即代理不会在类型/静态检查已经红灯的情况下继续给代码写“风格评论”。

第 5–7 步:无变更保护、读上下文、开始审查

  • 若所有 diff 命令都拿不到相关的 TS/JS 变更 → 停止并报告“审查范围无法可靠确定”(防止代理对着整个代码库漫无目的地评论);
  • 聚焦被修改的文件,先读周边上下文再评论;
  • 满足以上条件后才正式进入审查。

这套流程的本质是:把人类资深审查者的“先跑测试和类型检查、再确认 CI 状态、最后才读 diff”的肌肉记忆,显式编码成代理的行为契约,并用“停止条件(stop-and-report)”防止它在信息不足时产生低质量输出。

审查优先级清单(Review Priorities)

提示词把审查维度组织为 4 个 HIGH 级以上 + 3 个 MEDIUM 级清单。以下逐项继承原文档内容,并补充判据解读。

CRITICAL — 安全(Security)

检查项 判据与整改方向
eval / new Function 注入 用户可控输入进入动态执行——绝不执行不可信字符串
XSS 未净化的用户输入被赋给 innerHTMLdangerouslySetInnerHTMLdocument.write
SQL/NoSQL 注入 查询中做字符串拼接——应使用参数化查询或 ORM
路径穿越 用户可控输入进入 fs.readFilepath.join 且缺少 path.resolve + 前缀校验
硬编码密钥 源码中出现 API key、token、密码——应改用环境变量
原型污染 合并不可信对象时未使用 Object.create(null) 或 schema 校验
child_process 带用户输入 传入 exec/spawn 前必须校验并做白名单(allowlist)

HIGH — 类型安全(Type Safety)

  • 无据使用 anyany 直接关闭类型检查——应使用 unknown 再收窄,或给出精确类型;
  • 非空断言滥用:没有前置守卫的 value!——应加运行时检查;
  • 绕过检查的 as 断言:为压掉报错把值断言成不相关类型——应修正类型本身;
  • 放宽编译器配置:若 tsconfig.json 被本次改动触碰且削弱了 strictness,必须显式点出。

HIGH — 异步正确性(Async Correctness)

  • 未处理的 promise 拒绝async 函数被调用但没有 await.catch()
  • 对独立工作做顺序 await:循环内 await 相互独立的操作——可安全并行的应考虑 Promise.all
  • 浮动 promise(floating promises):事件处理器或构造函数中 fire-and-forget 且无错误处理;
  • async + forEacharray.forEach(async fn) 根本不会等待回调——应改用 for...ofPromise.all

HIGH — 错误处理(Error Handling)

  • 吞掉错误:空 catch 块或 catch (e) {} 无任何动作;
  • 未包 try/catch 的 JSON.parse:非法输入即抛异常——必须包裹;
  • 抛非 Error 对象throw "message"——应始终 throw new Error("message")
  • 缺少错误边界:React 树中异步/数据获取子树外围没有 <ErrorBoundary>

HIGH — 惯用模式(Idiomatic Patterns)

  • 可变共享状态:模块级可变变量——应倾向不可变数据与纯函数;
  • var 的使用:默认 const,需要重新赋值时用 let
  • 缺失返回类型导致隐式 any:公共函数应显式声明返回类型;
  • 回调式异步:回调与 async/await 混用——统一为 promise;
  • == 而非 ===:全量使用严格相等。

HIGH — Node.js 专项(Node.js Specifics)

  • 请求处理器中使用同步 fsfs.readFileSync 阻塞事件循环——应使用异步变体;
  • 边界处缺少输入校验:外部数据没有 schema 校验(zod、joi、yup);
  • 未校验的 process.env 访问:无 fallback 也无启动期校验;
  • ESM 上下文中的 require():无明确意图地混用模块体系。

MEDIUM — React / Next.js(如适用)

  • 依赖数组缺失useEffect/useCallback/useMemo 依赖不全——启用 exhaustive-deps lint 规则;
  • 状态变异:直接 mutate state 而不是返回新对象;
  • 用索引做 key:动态列表中 key={index}——应使用稳定唯一 ID;
  • useEffect 计算派生状态:派生值应在渲染期间计算,而不是放 effect 里;
  • 服务端/客户端边界泄漏:Next.js 中把 server-only 模块导入客户端组件。

MEDIUM — 性能(Performance)

  • 渲染中创建对象/数组:内联对象作为 props 引发不必要的重渲染——应提升(hoist)或记忆化;
  • N+1 查询:循环内做数据库或 API 调用——批处理或使用 Promise.all
  • 缺失 React.memo / useMemo:昂贵计算或组件每次渲染都重跑;
  • 大包整体导入:如 import _ from 'lodash'——应使用命名导入或可 tree-shake 的替代。

MEDIUM — 最佳实践(Best Practices)

  • 生产代码残留 console.log:应使用结构化日志器;
  • 魔法数字/字符串:应使用命名常量或枚举;
  • 深层可选链无兜底a?.b?.c?.d 没有默认值——应加 ?? fallback
  • 命名不一致:变量/函数用 camelCase,类型/类/组件用 PascalCase。

这套清单与 ECC 的配套技能文档形成了“检查项 ↔ 模式库”的对应关系:coding-standards 技能 给出了命名(如 marketSearchQuery 优于 q、动词-名词函数名)、不可变性等通用标准的 PASS/FAIL 对照示例;frontend-patterns 技能 则给出组件组合、复合组件等 React 参考实现;后端代码则应参照 backend-patterns 技能(.kiro/skills/backend-patterns/)。这正是提示词末尾 Reference 一节“use coding-standards plus frontend-patterns or backend-patterns based on the code being reviewed”的落点。

诊断命令与批准标准

Diagnostic Commands

提示词随附的完整诊断命令表(第 89–99 行):

npm run typecheck --if-present       # Canonical TypeScript check when the project defines one
tsc --noEmit -p <relevant-config>    # Fallback type check for the tsconfig that owns the changed files
eslint . --ext .ts,.tsx,.js,.jsx     # Linting
prettier --check .                  # Format check
npm audit                           # Dependency vulnerabilities
vitest run                          # Tests (Vitest)
jest --ci                           # Tests (Jest)

这些命令与 ECC 的 Kiro 质量门脚本 quality-gate.sh 相互呼应。该脚本(由手动触发的 quality-gate hook 调用)先通过 lock 文件探测包管理器(pnpm-lock.yaml → pnpm,yarn.lock → yarn,bun.lockb/bun.lock → bun,package-lock.json → npm),然后依次执行四个检查:

  1. Buildpackage.json 存在 build 脚本时运行 $PM run build,否则跳过;
  2. Type check:存在 tsconfig.json 且安装了 npx 时运行 npx tsc --noEmit(与代理的 fallback 命令一致),否则探测 Python(pyright/mypy)配置,再无则跳过;
  3. Lint:按 biome.json.eslintrc*/eslint.config.*ruff + pyproject.tomlgolangci-lint + go.mod 的优先级探测 lint 器;
  4. Teststest 脚本 → pytest → go test ./... 逐级兜底。

脚本对每个检查输出 ✓/✗/○,失败时打印前 20 行输出并在结尾汇总 Results: X passed, Y failed, Z skipped;只要有失败项就以退出码 1 结束并打印 Quality gate: FAILED。这种“探测→跳过→汇总→退出码”的模式,正是 typescript-reviewer 提示词中“if available / skip for JavaScript-only projects instead of failing”等弹性规则在脚本层的等价实现——两者共同保证:在工具缺失的项目里,检查和审查都不会误报失败。

编辑期联动:typecheck-on-edit hook

Kiro 侧还有一条与 TS 审查主题强相关的自动化钩子 typecheck-on-edit.kiro.hook:当 *.ts / *.tsx 文件被保存(fileEdited 触发、匹配 ["*.ts", "*.tsx"])时,以 askAgent 方式提示代理“检查刚保存的 TypeScript 文件中明显的类型错误或类型安全问题并标出”。也就是说,typescript-reviewer 的完整清单用于提交/PR 前的系统性审查,而该 hook 在编辑期提供轻量级实时类型反馈,二者构成“编辑期轻检查 + 审查期重审查”的双层防线。类似地,console-log-check hook 会在保存 .js/.ts/.tsx 时提醒清理 console.log,正好对应优先级清单中 MEDIUM 级的“生产代码残留 console.log”一项。

Approval Criteria

提示词给出了三档明确的批准结论(第 101–105 行):

结论 条件
Approve 无 CRITICAL 或 HIGH 问题
Warning 仅有 MEDIUM 问题(可谨慎合并)
Block 发现任何 CRITICAL 或 HIGH 问题

配合收尾的审查心态设定——“Would this code pass review at a top TypeScript shop or well-maintained open-source project?”——代理的产出是带结论的 findings 报告,而不是修改后的代码。对 harness 使用者而言,这意味着可以把 Block 结论直接映射为 PR 上的 review 驳回,把 Warning 映射为带保留意见的 approve。

安装与调用方式

typescript-reviewer 装入目标 Kiro 项目的方式见 .kiro/install.sh.kiro/README.md 的 Quick Start 一节):

# Go to .kiro folder
cd .kiro

# Install to your project
./install.sh /path/to/your/project

# Or install to the current directory
./install.sh

# Or install globally (applies to all Kiro projects)
./install.sh ~

安装器使用非破坏性复制——不会覆盖已有文件,因此本地对该代理提示词的自定义在重复安装后依然安全。

装入后的调用方式:

  • Kiro IDE:在会话中输入 / 后选择 typescript-reviewer(Kiro 的 Spec 会话自带 planner/designer/architect,与本代理不冲突);
  • Kiro CLI/agent swap 列出可用代理并切换,或直接 kiro-cli --agent typescript-reviewer 启动;
  • 推荐工作流.kiro/README.md “Recommended Workflow”):写码后切换到审查代理,涉及敏感数据或认证代码时叠加 security-reviewer,提交前手动触发 quality-gate hook,创建 PR 前运行 verification-loop 技能做全量校验。

小结:一个可复制的“审查代理”设计范式

回到 typescript-reviewer.md 本体,这份不到 120 行的 Markdown 之所以值得细读,是因为它示范了构建语言专用审查代理的完整方法论:

  1. 权限即约束:frontmatter 中只授予 read + shell,从能力层面保证“只报告不改写”;
  2. 前置门禁:范围确定(base 分支/merge-base,不硬编码 main)、CI/冲突就绪检查、typecheck 与 ESLint 先行,任何一环不满足就“停止并报告”,杜绝无证据审查;
  3. 弹性适配:优先项目自有 typecheck 脚本 → 覆盖被改代码的 tsconfig → 非产出 solution 检查 → tsc --noEmit -p,纯 JS 项目直接跳过,与 quality-gate.sh 的探测-跳过策略同构;
  4. 分级清单:CRITICAL 安全 7 项、HIGH 级 5 组、MEDIUM 级 3 组,每项都给出“反模式 → 整改方向”;
  5. 可判定输出:Approve / Warning / Block 三档标准让代理结论可直接对接 PR 流程。

如果你想在自己的 Kiro 项目里复用这套模式,只需将 typescript-reviewer.json 复制为目标项目的 .kiro/agents/ 目录,按团队规范增删 Review Priorities 条目即可——ECC 官方 README 也明确建议“Edit agent prompts in .kiro/agents/*.json to adjust behavior or add project-specific instructions”,且安装器永不覆盖你修改过的文件。

登录后查看全文
热门项目推荐
相关项目推荐