Files
2026Technology-Competition/docs/superpowers/specs/2026-08-20-custom-ai-fix-design.md
T
范智鹏 d16d680f0f feat: AI 修复链路扩展 + 修复预览两步确认 + 自定义规则/AI 审查条目支持 AI 修复
- 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 展示块
2026-08-20 22:26:30 +08:00

7.1 KiB
Raw Blame History

修复功能扩展到自定义规则与 AI 审查设计书

日期:2026-08-20 状态:已批准(Stage ④ 通过) 流程:① 用户提出 → ② 需求澄清 → ③ 方案设计 → ④ 人类审批

1. 背景与目标

当前自动修复只支持静态分析(linter)条目:fixIssue/fixAllorchestrator.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. 现状关键点(已核实)

  • fixIssuecommands.ts:360)从 orchestrator.getAnalysisResult() 取 linter 诊断,resolveFix 依赖 adapter。
  • custom 诊断在 currentReport.customRuleDiagnosticsLinterDiagnostic[]);ai 诊断在 currentReport.aiFindingsAIFinding[]f.line 已转 0-based)。
  • aiFixEngine.requestFix(依赖 provider/options/diag/context)可复用;其收敛验证 adapter.check 对 custom/ai 不可用。
  • 两步确认基础设施已完备:fixPending.tsopenPreviewDiff/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/buildVerifyUserPromptReviewIssueInput 接口
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/PendingBatchsource 字段
src/activation/commands.ts resolveReviewIssueFix/findCustomIssue/findAIIssuefixIssue 按 source 分流(custom/ai 走 AI 重检);fixAll 分 tab 批量;applyFixPreview/applyAllPreview recordFixes 传 sourcerefreshAfterFix 保留 custom suggestion
src/panel/webview.ts custom/ai 列表启用 AI 修复按钮 + 各自「全部修复」按钮 + 已修复区块(按 source 过滤/徽章);handleMessage.fixAll 传 sourceFixedEntryView 接口
src/ai/schema.ts TranslatedDiagnostic.codeDiffAIFinding.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

流程:每轮 requestFixAI 生成 {originalText,newText})→ indexOf 匹配 → 替换 → verifyFixedAI 重检 {fixed,reason})→ 未消除带 reason 反馈重试。

6.3 命令协议

  • fixIssue payload.source'linter'|'custom'|'ai'webview 已传),命令分流。
  • fixAll payload{ source?: 'linter'|'custom'|'ai' },分 tab 批量。
  • 面板消息 fixAll 透传 sourcesend('fixAll', undefined, undefined, 'custom')

6.4 面板

  • custom/ai 条目:buildIssueItem(..., aiFixable=true) → 显示「🤖 AI 修复」+ 隐藏的应用/取消按钮(复用现有两步确认)。
  • 各 tab 顶部「全部修复」→ send('fixAll', ..., source)
  • 已修复区块:fixedEntriessource 过滤 + buildFixedItem 按 source 渲染徽章;custom/ai 列表用 fixedKeys 过滤已修条目。

7. 删除 codeDiff

  • schema.tsTranslatedDiagnostic.codeDiffAIFinding.codeDiff 移除。
  • engine.ts:完整审查(zh/en/ja)与方法审查(En/Zh/Japrompt 中 "codeDiff" 要求行全部移除。
  • report.tsreportToMarkdown```diff 代码块展示移除。

8. i18n

无需新增 key(复用 fix.aiRunning/fix.aiFailed/fix.noAI/report.fixAll/report.fixAILabel/report.fixedIssues/report.undoFix)。

9. 测试计划

  • 新增 customFixEngine.test.ts 4 用例:收敛、匹配失败、重检后重试收敛、最大轮次失败。
  • 现有 106 用例回归通过(共 110 passing)。

10. 验证顺序

lint → compile → testnpm run lint / npm run compile / npm test)。