Diagnose and fix
一组可独立装载的 Agent / Claude Code Skills:编码行为准则、横切规范、多仓脚手架与多 agent 代码审计
npx -y skills add 0xkangl/skills --skill diagnose-and-fixAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
"诊断优先"的问题修复 skill。Use when 用户报告一个根因不明、需先定位再动手的问题(疑难 bug、隐蔽的行为异常、性能/并发问题、架构或安全隐患),而非一眼可改的简单修复时。简单机械的改动或已有明确方案的修复不必走本 skill。 接收一个问题(自由文本、issue 编号,或问题列表文件 + 编号),先侦察项目、追踪相关代码、验证问题是否真实存在,产出结构化【诊断报告】(代码分析、根本原因、影响范围、修复方案);用户选定方案后再执行修复 → 测试 → 修复后验证 → 提交。 若输入是问题列表,修复后只在文件内标记 resolved、不提交该变更;要批量循环处理整个问题列表请用 diagnose-and-fix-batch skill。
SKILL.md
15.9 KB, as published. Nobody here has run it
Diagnose and Fix Skill
可由 agent 按场景自动触发,也可手动调用:
@diagnose-and-fix "<问题描述>"
@diagnose-and-fix <问题列表文件> <编号>
@diagnose-and-fix # 进入交互模式,引导用户描述问题
设计理念
本 skill 强制执行"理解优先于修改"原则:
- Phase 1 — 诊断:系统性探索项目,验证问题,产出诊断报告
- Phase 2 — 确认:用户审阅报告,选择修复方案
- Phase 3 — 修复:按确认方案执行修改、测试、验证、提交
诊断不充分时,Phase 2 会阻断流程,避免基于错误假设盲目修改。
Phase 1 — 系统性诊断
Step 1.1 — 问题接收与澄清
解析调用参数,提取问题描述。若信息不足,向用户询问以下几项(知道的填,不确定的跳过):问题现象、预期行为、复现步骤、错误信息原文、已知相关文件/函数。
Step 1.2 — 项目结构侦察
在读任何具体文件前,先建立项目全貌——用你的文件检索工具(Glob/Grep/Read,别逐个裸 cat),快速摸清三件事:
- 语言与框架:看依赖清单(
go.mod/package.json/Cargo.toml/pubspec.yaml/pom.xml/requirements.txt等) - 架构与核心目录:入口在哪、代码主干如何组织
- 测试框架:有没有、是什么
目的是为后续定位画一张地图,不是把整棵目录树读进上下文。仓库较大时可派 Explore subagent 并行侦察、只取结论。
用一两句话汇报侦察结果:语言/框架、架构模式、核心目录、测试框架(未检测到就注明)。
Step 1.3 — 问题定位与代码追踪
围绕问题描述检索并阅读相关代码。目标是找到根因,而不是停在第一个看起来可疑的地方——所以下面几个角度都要覆盖到,但顺序按实际线索走,不必教条:
- 关键词检索:用错误信息、函数名、变量名定位入口(用 Grep 工具按文件类型过滤,别用裸
grep) - 调用链:从入口向下追到问题点,记录每一跳的文件:行号
- 数据流:追踪数据从输入到输出的转换路径,标出可疑的转换点
- 边界与异常路径:空值、错误传播、并发、资源释放、状态一致性——bug 常藏在这里
把所有发现记下来,为 Step 1.4 验证和 Step 1.5 报告提供原始素材。
Step 1.4 — 问题验证
验证问题是否真实存在,避免基于错误假设修复:
| 验证项 | 结论 |
|---|---|
| 代码中是否存在描述的行为? | ✅ 确认 / ❌ 不存在 / ⚠️ 部分存在 |
| 问题是否可被当前代码路径触发? | ✅ 可触发 / ❌ 条件不满足 / ⚠️ 概率性 |
| 问题描述是否与代码实际行为一致? | ✅ 一致 / ❌ 描述有误 / ⚠️ 需更多信息 |
两种提前收束(均不修改代码,对应末尾「终态」):
- 问题不存在 / 描述与代码对不上:告知用户实际观察到的行为,询问重新描述还是跳过。用户确认跳过 → 终态
skipped_inconsistent。 - 问题已被缓解 / 无需修复:说明现状,确认后——若输入为问题列表则按 Step 3.6 标记(
fix_solution: no-op: <原因>、commit: none)——终态skipped_noop。
否则继续 Step 1.5。
Step 1.5 — 诊断报告生成
修复方案:生成与推荐规则
报告里的每个方案都是可执行的推荐,不是草图——给出具体改法、落点文件/函数。生成与推荐时守住下面这条线:
- 推荐标准:选「最标准、最佳实践、且匹配本项目规模」的方案,不是最复杂的。忽略实现工时,只权衡正确性与运维契合度;推荐方案要对得上【根本原因】分类,治根因而非补症状。
- 右尺寸:不引入超出问题所需的抽象、可配置性、分层;也不用「就地打补丁」掩盖根因。能 50 行解决就别写 200 行。
- 遵循项目约定:若仓库有
conventions/或既成模式,优先选贴合它们的方案;若启用了code-conventionsskill,加载它作为规范来源。 - 方案数量按需:
- 根因清晰、最佳解唯一 → 只给一个推荐方案,附一句「为何不考虑其它思路」。
- 存在 2–3 个各有取舍、且代码本身无法裁决的合理方案 → 才并列,每个配一句 trade-off,并对推荐项标
[推荐],在【方案比较】里说明核心取舍。
- quick-fix 直通:当修复无歧义、纯机械、无需任何设计讨论(如错误日志级别、缺失 nil/error 检查、硬编码值提取为配置、配置键拼写、死导入)→ 在方案名后标
[quick-fix],可省去多方案对比,直接进确认。任何需要设计取舍的改动都不是 quick-fix。
输出完整的结构化诊断报告:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📋 诊断报告
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
【问题摘要】
描述:<一句话概括问题>
严重性:P0 崩溃/数据损坏 | P1 功能失效 | P2 行为异常 | P3 体验问题
验证状态:✅ 已确认 | ⚠️ 部分确认 | ❌ 未确认
【代码分析】
问题位置:
- <文件路径>(第N行,FunctionName)
- <文件路径>(第N行,FunctionName) ← 若涉及多处
调用链:
<入口> → <中间层> → <问题点>
相关代码片段:
```<语言>
// <文件>:<行号>
<关键代码,精简,仅展示问题相关部分>
```
【根本原因】
<清晰、具体的一到三段描述>
原因分类:逻辑错误 | 竞态条件 | 资源泄漏 | 配置错误 | 接口契约违反 | 缺失校验 | 其他
【影响范围】
直接影响:<受影响的功能/模块>
潜在影响:<可能的连带问题>
数据风险:<是否有数据一致性风险>
【修复建议】 (方案数量按上方规则;机械修复在名称后标 [quick-fix])
方案 A — <名称> [推荐]
做法:<具体改法,含落点文件/函数>
优点:<为什么好(对得上根本原因)>
缺点/风险:<需要注意>
改动范围:<预计修改哪些文件>
改动量:小(<20行)| 中(20-100行)| 大(>100行)
方案 B — <名称> ← 仅多方案时
做法:<具体改法>
优点:<为什么好>
缺点/风险:<需要注意>
改动范围:<预计修改哪些文件>
改动量:小 | 中 | 大
【方案比较】
单方案:一句话说明为何不考虑其它思路。
多方案:说明为什么推荐 A 而非 B,核心取舍是什么。
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
请选择:
A) 采用方案 A 进行修复
B) 采用方案 B 进行修复 ← 仅多方案时列出
C) 我有其他想法:___
D) 报告有误,我想补充信息
E) 仅需报告,暂不修复
Phase 2 — 用户确认
等待用户回复,按选择处理:
- A / B:进入 Phase 3,执行对应方案
- C(自定义):用户说明想法后,评估可行性,给出简短分析,再次确认后进入 Phase 3
- D(补充信息):接收补充,回到 Step 1.3 重新分析,更新报告后再次等待确认
- E(仅报告):输出
📄 诊断完成,未执行修复后结束(终态user_declined)。不写问题列表(如需手动改状态,见末尾「终态」说明)
Phase 3 — 修复执行
Step 3.1 — 修改代码
按确认方案最小范围修改,保持原代码风格。追踪所有改动文件和行号。
改完后简述:每个文件改了什么、总增删行数。
Step 3.2 — 测试
复用 Step 1.2 侦察到的测试框架,不从零重新探测。命令优先级:项目自定义入口(Makefile test 目标 / package.json scripts.test)→ 该语言的约定测试命令 → 均无则询问用户。
优先只跑覆盖本次改动的测试(按包/目录/文件缩小范围)以快速反馈;通过后再视耗时跑一次相关全量,确认无回归。
测试失败时:展示错误摘要,说明准备如何调整,询问确认后回到 Step 3.1 重试,最多 3 次。超限则告知用户,停止流程,不提交,不标记(终态 skipped_test_failed)。
输出:🧪 测试通过(N 用例) 或 ❌ 测试失败:<摘要>
Step 3.3 — 格式化
沿用 Step 1.2 的语言/工具链判定,只对本次修改的文件执行。优先用项目自带的格式化入口(Makefile fmt/lint 目标、package.json scripts.format/scripts.lint、仓库内 formatter 配置如 .prettierrc/rustfmt.toml/.golangci.yml),无则回退该语言的默认格式化工具。
未找到工具时跳过并提示,不阻塞流程。
输出:🎨 格式化完成 或 ⚠️ 未找到格式化工具,已跳过
Step 3.4 — 修复验证与代码 review
两道独立把关,都通过才进提交。
(1) 修复验证 — 独立 subagent
与 Step 1.4「验证问题存在」对称:修复后必须独立确认「问题已消除」,而不是默认改完就好。派一个验证 subagent(Explore 或 general-purpose),只喂:原问题描述、Step 1.4 的三项结论、本次改动文件:行号。让它不预设修复成功,对照 Step 1.4 逐条复核,重点落在根因/复现路径:
| 验证项 | 修复前(Step 1.4) | 期望修复后 |
|---|---|---|
| 描述的行为是否仍存在? | ✅ 确认 | ❌ 已消除 |
| 问题路径是否仍可触发? | ✅ 可触发 | ❌ 不可触发 |
| 根因是否已被消除? | — | ✅ 已消除 / ⚠️ 部分 / ❌ 未消除 |
subagent 只回结论、不改代码。判定「未消除 / 部分消除」即视为修复未达标 → 回 Step 3.1 重改(与 Step 3.2 测试共享同一 3 次重试上限,超限则停止、不提交、不标记,终态 skipped_test_failed)。
(2) 代码 review — 引用现有 skill
若启用了 code-review 或 requesting-code-review skill,调用它审查本次 diff,重点:是否真正治根因(对得上诊断报告)、有无引入回归、是否符合选定方案与项目约定。未启用则跳过并提示。
- review 报出的 P0/P1 先处理(回 Step 3.1,计入同一重试预算)再继续;
- P2/P3 记入完成摘要,交用户决定是否本次一并处理。
输出:🔍 修复验证:问题已消除 + 🧐 review:N 项(P0:x P1:x P2:x P3:x) 或对应失败/跳过摘要。
Step 3.5 — 提交
修复方案已在 Phase 2 确认,此处直接提交,无需再次询问。
提交前先看 git log 近若干条提交,沿用项目既有的 commit 风格(type 集合、scope 命名、语言);项目无明显约定时按下方缺省规范。
再执行 git diff --name-only HEAD 核查改动文件:仅当混入与本次修复无关的改动时才停下告知用户由其决定;否则只 add 本次修改的文件后直接提交:
git add <仅本次修改的文件>
git commit -m "<subject>" -m "<body>" -m "<footer>"
Commit 消息规范(缺省):
<type>(<scope>): <subject> ← 动词原形开头,≤72字符,不加句号
[body] ← 解释"为什么",引用诊断报告根本原因,可选
Fixes: <问题描述一句话>
- type:
fix(bug)/refactor(重构)/perf(性能)/security(安全)/feat;项目另有惯用 type 则从其惯例。 - scope:取自本次改动所在的模块/包/目录,与项目既有 scope 命名保持一致。
输出:🎉 <hash7> — <subject>
Step 3.6 — 标记问题列表(仅当输入为问题列表文件时)
若本次输入是问题列表文件 + 编号,修复完成后把对应条目标记为已修复——但不提交这次变更。这是有意为之:本 skill 聚焦单个问题的诊断与修复,问题列表的提交时机交给你统一掌控(要批量循环处理整个问题列表,用 diagnose-and-fix-batch skill)。
按原文件格式写入:
| 字段 | 值 |
|---|---|
| status | resolved |
| resolved_at | YYYY-MM-DD |
| fix_solution | 已选方案名 + 一句描述 |
| commit | 代码提交的 <hash7>,未提交则填 uncommitted |
写入格式:
- Markdown → 追加
### ✅ 修复记录小节 - JSON → 合并字段到对应对象
- YAML → 追加字段到对应条目
- 纯文本 → 追加
[resolved DATE | 方案 | commit: HASH]
文件只读时,输出待写内容供你手动应用。完成后提示:📝 已标记 #<编号> resolved(未提交,提交时机由你决定)
完成摘要
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
🏁 诊断与修复完成
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
问题:<一句话>
严重性:P<N>
根本原因:<一句话>
采用方案:<方案名>
改动文件:<N> 个
测试:通过(N 用例)
修复验证:问题已消除
代码 review:N 项(P0:x P1:x P2:x P3:x) 或 未启用
提交:<hash7> 或 未提交
问题列表:已标记 resolved(未提交) 或 不适用
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
终态
本 skill 处理单个问题的最终结果,归为下列其一。被 diagnose-and-fix-batch 编排时,subagent 据此映射上报;独立使用时仅作为收束说明。只有 completed 与 skipped_noop 会写问题列表(若输入为问题列表),其余跳过态不动列表,并提示用户可手动把状态设为 skipped。
| 终态 | 触发点 | 含义 |
|---|---|---|
completed | Step 3.5/3.6 | 修复完成;代码已提交(git 未初始化等情况则未提交),问题列表已标记 resolved |
skipped_inconsistent | Step 1.4 | 问题不存在 / 描述与代码对不上,用户确认跳过 |
skipped_noop | Step 1.4 | 问题已缓解 / 无需修复,用户确认(列表标记 no-op) |
user_declined | Phase 2-E | 用户选「仅报告,暂不修复」 |
skipped_test_failed | Step 3.2/3.4 | 测试或修复后验证重试超 3 次,停止、不提交、不标记 |
错误处理
各 Step 内已说明的失败处理(验证不存在、测试/验证超限、review 分级)不再重复,此处只列横切与环境类异常:
| 情况 | 处理 |
|---|---|
| 问题描述过于模糊 | 进入交互模式,引导用户补充 |
| 涉及多个独立问题 | 拆分为子问题,分别给出修复建议,询问优先修复哪个 |
| git 未初始化 | 跳过提交,仍完成修改、测试、验证 |
| 工作区有无关改动 | 提交前告知用户,由其决定是否 stash |
| 代码 / 问题列表文件只读 | 输出待写内容供手动应用,不直接写入 |