- AI 修复:无原生 fix 的 linter 条目走 AI 修复(aiFixEngine/fixPrompt,AI 重检收敛),自定义规则与 AI 审查条目新增 AI 修复按钮(customFixEngine),自定义规则条目展开显示 AI 建议(suggestion 字段)
- 修复预览:面板触发修复先用内置 diff 预览,面板内「应用/取消」两步确认后才写入(fixPreview/fixPending,单条与分 tab 批量均支持)
- 修复面板交互:linter/custom/ai 分 tab「全部修复」、已修复+撤销、pending 按钮状态同步
- bug 修复:修复按钮失败后卡 ⏳ 不恢复;custom/ai 修复不稳定(空修复重试、AI 重检收敛判定放宽、降级接受最后一次有效修复)
- 移除 AI codeDiff 展示块
7.1 KiB
7.1 KiB
修复功能扩展到自定义规则与 AI 审查设计书
日期:2026-08-20 状态:已批准(Stage ④ 通过) 流程:① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批
1. 背景与目标
当前自动修复只支持静态分析(linter)条目:fixIssue/fixAll 从 orchestrator.getAnalysisResult() 取 linter 诊断,走 native fix 或 aiFixDiagnostic(依赖 LinterAdapter 重 lint 验证收敛)。
用户要求将修复能力扩展到**自定义规则(custom tab)**与 AI 审查(ai tab) 条目。
2. 需求澄清结论(Stage ② 共识)
| 决策项 | 结论 |
|---|---|
| 修复范围 | 面板 custom + ai 条目标题均支持 AI 修复 |
| 验证方式 | custom/ai 无对应 linter 适配器,无法重 lint 验证 → AI 重检收敛(新文本提交 AI 确认问题消除,未消除带反馈重试 ≤maxIterations) |
| 入口交互 | 面板按钮 + 两步确认(与 linter 一致:打开 diff → 应用/取消) |
| 全部修复 | 分 tab 批量:linter/custom/ai 各自有「全部修复」按钮 |
| 修复引擎 | 新建 customFixEngine.ts,复用 AI 修复 prompt,无 adapter 依赖 |
| 修复后展示 | 各 tab 顶部显示「✅ 已修复 + 撤销」区块 |
| ai codeDiff | 删除该字段(schema/prompt/报告展示全部移除) |
3. 现状关键点(已核实)
fixIssue(commands.ts:360)从orchestrator.getAnalysisResult()取 linter 诊断,resolveFix依赖 adapter。- custom 诊断在
currentReport.customRuleDiagnostics(LinterDiagnostic[]);ai 诊断在currentReport.aiFindings(AIFinding[],f.line已转 0-based)。 aiFixEngine.requestFix(依赖 provider/options/diag/context)可复用;其收敛验证adapter.check对 custom/ai 不可用。- 两步确认基础设施已完备:
fixPending.ts、openPreviewDiff/closePreviewEditor/applyNewText、4 个 preview 命令、reviewPanel.js按钮翻转、pendingStore。 codeDiff字段定义于 schema,唯一用途是 report.ts 导出 Markdown 时展示```diff块,从未用于真实修复。
4. 架构概览
面板 custom/ai 条目标题「🤖 AI 修复」 / 各 tab「全部修复」
│ send('fix', line, ruleId, 'custom'|'ai') / send('fixAll', ..., 'custom'|'ai')
▼
codeReviewer.fixIssue / fixAll (payload.source 分流)
│ source === 'custom'|'ai'
▼
findCustomIssue / findAIIssue 从 currentReport 定位 ReviewIssueInput
│
▼
customFixEngine.aiFixReviewIssue(document, diag, maxIterations, provider, options, dryRun)
每轮:buildFixContext → requestFix(AI 生成 {originalText,newText}) → indexOf 匹配替换
→ verifyFixed(AI 重检 {fixed,reason}) → 未消除带反馈重试 ≤maxIterations
│ dryRun=true 返回 newText(不写盘)
▼
两步确认:openPreviewDiff + pendingStore + postMessage 翻转按钮
▼ 面板「应用」→ applyFixPreview/applyAllPreview → applyNewText + recordFixes(source) + save + refresh
5. 文件变更清单
新建
| 文件 | 职责 |
|---|---|
src/fix/fixPrompt.ts |
共享修复/重检 prompt builder(三语):buildFixSystemPrompt/buildFixUserPrompt/buildFixContext/buildVerifySystemPrompt/buildVerifyUserPrompt,ReviewIssueInput 接口 |
src/fix/customFixEngine.ts |
aiFixReviewIssue:AI 生成修复 + AI 重检收敛,无 adapter 依赖,支持 dryRun |
src/test/customFixEngine.test.ts |
4 用例(收敛/匹配失败/重试收敛/最大轮次失败) |
修改
| 文件 | 变更 |
|---|---|
src/fix/aiFixEngine.ts |
移除内联 prompt builder,改用共享 fixPrompt(行为不变) |
src/fix/fixSession.ts |
`FixedEntry.source: 'linter' |
src/fix/fixPending.ts |
PendingFix/PendingBatch 加 source 字段 |
src/activation/commands.ts |
resolveReviewIssueFix/findCustomIssue/findAIIssue;fixIssue 按 source 分流(custom/ai 走 AI 重检);fixAll 分 tab 批量;applyFixPreview/applyAllPreview recordFixes 传 source;refreshAfterFix 保留 custom suggestion |
src/panel/webview.ts |
custom/ai 列表启用 AI 修复按钮 + 各自「全部修复」按钮 + 已修复区块(按 source 过滤/徽章);handleMessage.fixAll 传 source;FixedEntryView 接口 |
src/ai/schema.ts |
删 TranslatedDiagnostic.codeDiff、AIFinding.codeDiff |
src/ai/engine.ts |
删完整审查 + 方法审查 prompt 中的 codeDiff 要求 |
src/utils/report.ts |
删 Markdown 导出的 ```diff codeDiff 块 |
6. 关键接口
6.1 src/fix/fixPrompt.ts
export interface ReviewIssueInput {
ruleId: string;
line: number; // 0-based
message: string;
suggestion?: string;
}
export function buildFixSystemPrompt(): string;
export function buildFixUserPrompt(diag: ReviewIssueInput, context: string): string;
export function buildFixContext(code: string, line: number): string;
export function buildVerifySystemPrompt(): string;
export function buildVerifyUserPrompt(diag: ReviewIssueInput, code: string): string;
6.2 src/fix/customFixEngine.ts
export async function aiFixReviewIssue(
document: vscode.TextDocument,
diag: ReviewIssueInput,
maxIterations: number,
provider: AIProvider,
options: ChatOptions,
dryRun?: boolean
): Promise<FixResult>; // 复用 FixResult/AppliedFix,无 adapter
流程:每轮 requestFix(AI 生成 {originalText,newText})→ indexOf 匹配 → 替换 → verifyFixed(AI 重检 {fixed,reason})→ 未消除带 reason 反馈重试。
6.3 命令协议
fixIssuepayload.source:'linter'|'custom'|'ai'(webview 已传),命令分流。fixAllpayload:{ source?: 'linter'|'custom'|'ai' },分 tab 批量。- 面板消息
fixAll透传 source:send('fixAll', undefined, undefined, 'custom')。
6.4 面板
- custom/ai 条目:
buildIssueItem(..., aiFixable=true)→ 显示「🤖 AI 修复」+ 隐藏的应用/取消按钮(复用现有两步确认)。 - 各 tab 顶部「全部修复」→
send('fixAll', ..., source)。 - 已修复区块:
fixedEntries按source过滤 +buildFixedItem按 source 渲染徽章;custom/ai 列表用 fixedKeys 过滤已修条目。
7. 删除 codeDiff
- schema.ts:
TranslatedDiagnostic.codeDiff、AIFinding.codeDiff移除。 - engine.ts:完整审查(zh/en/ja)与方法审查(En/Zh/Ja)prompt 中
"codeDiff"要求行全部移除。 - report.ts:
reportToMarkdown中```diff代码块展示移除。
8. i18n
无需新增 key(复用 fix.aiRunning/fix.aiFailed/fix.noAI/report.fixAll/report.fixAILabel/report.fixedIssues/report.undoFix)。
9. 测试计划
- 新增
customFixEngine.test.ts4 用例:收敛、匹配失败、重检后重试收敛、最大轮次失败。 - 现有 106 用例回归通过(共 110 passing)。
10. 验证顺序
lint → compile → test(npm run lint / npm run compile / npm test)。