研发协作
当需要按 Git ref/focus 审查 diff 并用…
当你想用 diffity agent CLI 对指定 ref 或工作树 diff 做结构化审查并逐条留评论时。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
当需要按 Git ref/focus 审特定
解决思路
- 如果提供 `ref` 参数(如 `main..feature`、`HEAD~3`),审查该 Git ref;否则默认审查工作树变更。
- 如果提供 `focus` 参数(`security`、`performance`、`naming`、`errors`、`types`、`logic` 之一),将审查聚焦该区域;如果省略,审查所有区域。
- 当同时提供 `ref` 和 `focus` 时,两者都用(如 `/diffity-review main..feature security`)。
- 使用 CLI 命令参考:`{{binary}} agent diff`;`{{binary}} agent list [--status open|resolved|dismissed] [--json]`;`{{binary}} agent comment --file <path> --line <n> [--end-line <n>] [--side new|old] --body "<text>"`;`{{binary}} agent general-comment --body "<text>"`;`{{binary}} agent resolve <id> [--summary "<text>"]`;`{{binary}} agent dismiss <id> [--reason "<text>"]`;`{{binary}} agent reply <id> --body "<text>"`。
- 注意 `comment` 需要 `--file`、`--line`、`--body`;`--end-line` 默认 `--line`(单行评论);`--side` 默认 `new`;`general-comment` 创建 diff 级评论,不绑定文件或行;`<id>` 接受完整 UUID 或 8 字符前缀。
- 检查 `{{binary}}` 是否可用:运行 `which {{binary}}`;如果未找到,执行 `{{install_hint}}`。
- 确保 diffity 为正确 ref 运行,且不要打开浏览器。
- 审查需要运行中的会话,其 ref 匹配请求的 ref;ref 不匹配会导致添加评论时 `file not in current diff` 错误。
- 运行 `{{binary}} list --json` 获取所有运行实例。
- 解析 JSON 输出,找到 `repoRoot` 与当前仓库匹配的条目。
- 如果存在匹配条目,将其 `ref` 字段与请求的 ref 比较;registry 对工作树会话存 `"work"`,对命名 ref 存用户提供的 ref 字符串(如 `"main"`、`"HEAD~3"`)。
- 如果 ref 匹配,则复用该会话,记下端口,继续 Step 2。
- 如果 ref 不匹配,则重启:运行 `{{binary}} <ref> --no-open --new`(如果没有 ref 则 `{{binary}} --no-open --new`);`--new` 会杀死旧会话并启动新会话;使用 Bash 工具设置 `run_in_background: true`;等待 2 秒;然后用 `{{binary}} list --json` 验证并记下端口。
- 如果未请求 ref,且运行中会话的 ref 不是 `"work"`,则重启:运行 `{{binary}} --no-open --new`(运行中会话是命名 ref,但需要工作树)。
- 如果该仓库没有会话运行,在后台启动一个:运行 `{{binary}} <ref> --no-open`(如果没有 ref 则 `{{binary}} --no-open`);使用 Bash 工具设置 `run_in_background: true`;等待 2 秒;然后用 `{{binary}} list --json` 验证并记下端口。
- 运行 `{{binary}} agent diff` 直接获取 unified diff;这处理 merge-base 解析、未跟踪文件和所有 ref 类型;输出当前会话的完整 unified diff,行号在 `@@` hunk headers 中。
- 找到并阅读所有相关 `CLAUDE.md` 文件:根 `CLAUDE.md` 以及包含修改文件的目录中的任何 `CLAUDE.md`;这些定义 diff 必须遵守的项目特定规则。
- 评估 diff 大小并调整策略:小(约 100 行以下变更,1-3 个文件)直接按顺序审查每个文件。
- 中(100-500 行变更,3-10 个文件)按区域分组文件(如后端、前端、测试、配置);先审查核心逻辑文件,以便在审查涟漪效应前理解意图。
- 大(500+ 行变更或 10+ 个文件)按区域分组文件;从核心逻辑开始,然后审查每个剩余文件;对于机械重复变更(如相同重命名应用到 20 个文件),在前几个实例上验证模式正确,然后检查每个剩余实例是否有偏离模式;不要跳过任何,但一旦模式建立可以更快检查。
- 无论大小,阅读并审查每个变更文件;不要跳过或抽查文件。
- 先总结变更:在找问题前建立对 diff 的心智模型;问这个变更试图完成什么(新功能、bug 修复、重构、配置变更);哪些文件是结构性变更 vs. 核心逻辑变更;作者意图是什么;阅读 commit messages(`git log --oneline <args>`)以及任何链接的 issue 或 PR 描述获取上下文;作者做出的关键决策是什么,他们在什么约束下工作;理解意图有助于区分有意行为与真实 bug。
- 对每个变更文件(根据规模策略调整),阅读整个文件(不只是 diff hunks)以理解完整上下文。
- 交叉引用调用方和依赖方:对于任何变更的函数签名、重命名导出、修改的返回类型或改变的行为,在整个代码库中 grep 用法;检查谁调用这个函数以及他们能否处理新的返回值/错误/null 情况;谁导入这个模块以及改变的导出名能否解析;这个类型变化是否正确传播到消费者。
- 使用分析技术分析代码变更;如果提供了 focus 参数,集中在该区域;否则应用所有分析 pass 和信号阈值。
- 数据流分析:追踪值通过变更代码;检查变更代码假设非 null 的地方值可能为 null/undefined 吗;变更代码处理了上游条件的所有分支吗;如果函数返回类型变了,所有调用方处理新形状吗;是否有收窄检查(如 `if (x)`)被 diff 意外移出。
- 状态和生命周期分析:对于有状态代码(React state、数据库事务、流、事件监听器),检查变更是否创建了无法到达或无法退出的状态;资源(监听器、订阅、文件句柄)是否仍在所有路径上清理;并发访问会破坏共享状态吗;操作顺序是否仍满足不变量(如先初始化后使用)。
- 契约分析:根据变更代码必须满足的契约检查;函数是否仍满足调用方期望(阅读调用方,不要猜);如果实现接口或覆盖基类方法,是否仍符合;前置条件和后置条件是否保留;对于 API 端点,响应形状是否匹配客户端发送/期望。
- 边界分析:对于系统边界代码(用户输入、网络、文件 I/O、IPC),检查用户控制输入在使用前是否验证;畸形外部数据能崩溃进程或破坏状态吗;有注入向量吗(SQL、shell、XSS、path traversal)。
- 边缘情况分析:仅针对实践中会发生的情况,不是理论情况;检查空数组/字符串、零、负数;循环、切片或索引算术中的 off-by-one;整数溢出、除零,其中除数来自输入。
- 完整性检查:分析代码正确性后,检查变更是否完整——不仅正确,而且完成。
- 测试覆盖:如果 diff 添加新行为(新函数、端点、UI 流程、分支),有测试覆盖吗?如果没有,标记为 `[suggestion]`。
- 如果 diff 修复 bug,有测试能捕获该 bug 吗?回归测试防止重新引入。
- 如果 diff 修改现有行为,现有测试更新以匹配吗?仍通过但过时的测试比没有测试更糟——它们给出虚假信心。
- 如果 diff 包含测试,审查其质量:它们测试正确的东西吗(行为,不是实现细节);它们覆盖代码处理的边缘情况吗(空输入、错误路径、边界值);它们隔离吗(没有对测试顺序或全局状态的隐藏依赖);即使代码坏了它们也能通过吗(同义反复断言、mock 掉的逻辑)。
- 缺失部分:检查 Schema 变更没有 migration;新环境变量没有文档或默认值;新依赖没有 lockfile 更新;改变的 API 响应没有客户端更新;新错误类型没有调用点处理;移除功能没有清理相关代码(死导入、未使用配置、孤儿测试);只标记此变更正确工作明显需要的缺失部分,不要标记理想化改进。
- 要标记什么:标记会影响正确性、安全性或可靠性的真实问题——无法编译、解析或运行的代码(语法错误、类型错误、缺少导入、未解析引用);会产生错误结果的逻辑错误(清晰 bug、off-by-one、坏条件);变更代码中的安全漏洞(注入、XSS、认证绕过、数据暴露);竞态条件或数据丢失风险,你能用具体场景演示;CLAUDE.md 违规,你能引用被破坏的确切规则;破坏的契约——变更函数不再满足调用方期望;新或改变行为缺少测试(作为 `[suggestion]`,不是 `[must-fix]`,除非项目 CLAUDE.md 要求测试);不完整变更——migration、配置、客户端更新,明显需要此变更才能工作。
- 跳过风格问题、linter 可捕获问题和未变更代码中的既有问题;关注 diff,不是整个文件。
- 评论前验证:对每个发现,发布前验证它是真实的——重读周围代码(许多表面 bug 在完整上下文中消失);对于 "missing import" 或 "undefined variable" 声明,grep 确认;对于破坏的调用方,阅读实际调用点;对于 CLAUDE.md 违规,确认规则范围限于此文件;对于缺少测试,检查是否已有不同文件中的测试覆盖此路径。
- 如果重复模式跨文件出现,在第一次出现处评论,并在 general summary 中提及模式,而不是重复评论。
- 按严重性排序评论:先发布所有 `[must-fix]` 评论,然后 `[suggestion]`,然后 `[question]`;在每个严重性内,按文件顺序;这确保作者略读时先看到最重要问题。
- 用严重性前缀分类每个发现:`[must-fix]` 用于 Bug、安全问题、数据丢失风险,会破坏或产生错误结果的代码;`[suggestion]` 用于有明确原因的具体改进,不是风格偏好,包括缺少测试、不完整变更和更好方法;`[question]` 用于需要作者澄清的不清楚之处。
- 对每个发现,使用 `{{binary}} agent comment --file <path> --line <n> [--end-line <n>] [--side new] --body "<comment>"` 留下内联评论;对新增/修改代码使用 `--side new`(默认);对移除代码使用 `--side old`;当问题跨多行时使用 `--end-line`;以问题开头,不是背景;具体且可操作;对于小、自包含修复,包含展示修复的代码建议;对于较大修复(结构性变更、多位置),描述问题和建议方法,不包含完整代码块;如果标记 CLAUDE.md 违规,引用被破坏的确切规则。
- 留下所有内联评论后,决定是否需要 general comment:无发现 → 留下 general comment:"No issues found. Checked for bugs and CLAUDE.md compliance.";1-2 个发现 → 跳过 general comment,除非有内联评论未覆盖的跨切面关注;3+ 个发现 → 留下 general comment 总结主题;大 diff → 总是留下 general comment,注明审查范围并按区域分组发现;不要在 general comment 中使用严重性前缀——前缀仅用于内联发现;以结论开头,直接简洁——无赞美、无填充、不叙述代码做什么。
- 使用 `{{binary}} agent general-comment --body "<overall review summary>"` 留下 general comment。
- 评论准备好后打开浏览器:运行 `{{binary}} open <ref>`;如果提供了 ref 参数则传递(如 `{{binary}} open HEAD~3`);省略则打开默认视图。
- 告诉用户审查已准备好,可以检查浏览器;示例:"Review complete — check your browser. Found: 2 must-fix, 1 suggestion. When you're ready, run **{{slash}}resolve** to fix them."
适用边界 · 注意事项
- 环境中没有 `{{binary}}`(diffity)且无法按 `{{install_hint}}` 安装时。
- 不需要在 diff 上留下内联评论,或只想做口头/非 diffity 工作流审查时。
- 无法在后台启动进程或无法打开浏览器时。