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

140 lines
7.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 修复功能扩展到自定义规则与 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'|'custom'|'ai'``recordFixes` 加 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`
```typescript
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`
```typescript
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 命令协议
- `fixIssue` payload.source`'linter'|'custom'|'ai'`webview 已传),命令分流。
- `fixAll` payload`{ 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/Japrompt 中 `"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.ts` 4 用例:收敛、匹配失败、重检后重试收敛、最大轮次失败。
- 现有 106 用例回归通过(共 110 passing)。
## 10. 验证顺序
`lint → compile → test``npm run lint` / `npm run compile` / `npm test`)。