Files
2026Technology-Competition/docs/superpowers/specs/implementation-steps/15-phase5.1-commands-extension.md
T
范智鹏 a734cdf009 refactor: 品牌重命名 + maxTokens 支持 + 设置面板简化
- CodeGuard → Code Purifier / 净码特工(displayName、命令、配置标题)
- 新增 ai.maxTokens 配置项,所有 Provider 及 fixer 传入 maxTokens
- AI 引擎增强:repairJsonEscapes + JSON 解析 fallback + 详细错误信息
- 设置面板规则管理改为文件级(list/delete .yaml),addRule 改为 AI 从 Markdown 生成 YAML
- yaml-parser 简化:移除 config.yaml 的 enable/disable 过滤逻辑
- 审查报告面板:errorBanner 优先显示具体错误、lint 诊断显示 suggestion、移除 translatedDiagnostics 独立渲染
- merger 中 translatedDiagnostics 覆盖原始 lint 诊断 message/suggestion
- HTML linter 配置项、测试用例重写、typescript-eslint 移入 dependencies
2026-07-20 20:24:40 +08:00

253 lines
8.2 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.
# Step 15 — Phase 5.1: 命令注册 + extension.ts 更新
**依赖**: Step 08, 14Orchestrator + 报告导出),Step 13Fixer 可选)
**参考设计**: §6
## 目标
注册 8 个命令,更新 `package.json` 贡献点,更新 `extension.ts` 入口串联所有模块。
## 文件变更
| # | 文件 | 操作 | 说明 |
|---|------|------|------|
| 1 | `src/activation/commands.ts` | 新建 | 所有命令处理函数注册 |
| 2 | `src/extension.ts` | 修改 | 替换 helloWorld 为正式入口 |
| 3 | `package.json` | 修改 | 添加 commands、viewsContainers、views、menus、configuration |
---
## 1. `src/activation/commands.ts`
```typescript
import * as vscode from 'vscode';
import { Orchestrator } from '../orchestrator/orchestrator';
import { runAIReview } from '../ai/engine';
import { loadActiveRules } from '../rules/yaml-parser';
import { mergeResults } from '../merger/merger';
import { reportToMarkdown } from '../utils/report';
import { getApiKey } from '../config';
export function registerCommands(context: vscode.ExtensionContext, orchestrator: Orchestrator): void {
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.review', async () => {
const editor = vscode.window.activeTextEditor;
if (!editor) {
vscode.window.showWarningMessage('请先打开一个文件');
return;
}
const document = editor.document;
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '';
const workingDir = workspaceRoot || vscode.Uri.joinPath(document.uri, '..').fsPath;
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: '正在审查...',
cancellable: false,
}, async (progress) => {
progress.report({ message: '运行静态分析...' });
const startTime = Date.now();
const staticResult = await orchestrator.runStaticAnalysis(document, workingDir);
progress.report({ message: '运行 AI 审查...' });
const customRules = loadActiveRules(workspaceRoot);
const code = document.getText();
const aiResult = await runAIReview(context, code, staticResult.diagnostics, customRules);
const report = mergeResults({
staticDiagnostics: staticResult.diagnostics,
customRuleResults: aiResult.customRuleResults,
translatedDiagnostics: aiResult.translatedDiagnostics,
aiFindings: aiResult.findings,
errors: [...staticResult.errors, ...(aiResult.error ? [aiResult.error] : [])],
degraded: aiResult.degraded,
startTime,
filePath: document.uri.fsPath,
language: document.languageId,
adapterIds: staticResult.adapterIds,
});
// TODO: Phase 5.3 — 推送报告到审查面板
vscode.window.showInformationMessage(
`审查完成: ${report.linterCount + report.customRuleCount + report.aiCount} 个问题`
);
});
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.reviewSelection', async () => {
const editor = vscode.window.activeTextEditor;
if (!editor) { return; }
const selection = editor.selection;
if (selection.isEmpty) {
vscode.window.showWarningMessage('请先选中要审查的代码');
return;
}
const code = editor.document.getText(selection);
const apiKey = await getApiKey(context);
if (!apiKey) {
vscode.window.showWarningMessage('请先在设置面板中配置 API Key');
return;
}
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '';
const customRules = loadActiveRules(workspaceRoot);
await vscode.window.withProgress({
location: vscode.ProgressLocation.Notification,
title: '审查选中代码...',
cancellable: false,
}, async () => {
const aiResult = await runAIReview(context, code, [], customRules);
vscode.window.showInformationMessage(
`选中代码审查完成: ${aiResult.customRuleResults.length + aiResult.findings.length} 个问题`
);
});
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.openPanel', () => {
// TODO: Phase 5.3 — 打开审查面板
vscode.window.showInformationMessage('审查面板功能开发中');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.exportReport', async () => {
// TODO: 与审查面板集成后获取最新 report
vscode.window.showInformationMessage('请先运行完整审查生成报告');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.addCustomRule', () => {
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
if (!workspaceRoot) {
vscode.window.showWarningMessage('请先打开工作区');
return;
}
// TODO: 打开规则向导,保存到 .code-review/rules/
vscode.window.showInformationMessage('添加自定义规则功能开发中');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.fixIssue', () => {
// TODO: Phase 4.5 — 单条修复(与审查面板交互)
vscode.window.showInformationMessage('单条修复功能开发中');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.fixAll', () => {
// TODO: Phase 4.5 — 批量修复
vscode.window.showInformationMessage('批量修复功能开发中');
})
);
context.subscriptions.push(
vscode.commands.registerCommand('codeReviewer.openSetup', () => {
vscode.commands.executeCommand('workbench.view.extension.code-reviewer');
})
);
}
```
---
## 2. `src/extension.ts` 修改
```typescript
import * as vscode from 'vscode';
import { Orchestrator } from './orchestrator/orchestrator';
import { registerCommands } from './activation/commands';
let orchestrator: Orchestrator;
export function activate(context: vscode.ExtensionContext) {
console.log('净码特工 · Code Purifier 已激活');
orchestrator = new Orchestrator();
registerCommands(context, orchestrator);
const debounceTimers = new Map<string, NodeJS.Timeout>();
context.subscriptions.push(
vscode.workspace.onDidSaveTextDocument((document) => {
const key = document.uri.toString();
const existing = debounceTimers.get(key);
if (existing) { clearTimeout(existing); }
const timer = setTimeout(() => {
debounceTimers.delete(key);
const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath ?? '';
const workingDir = workspaceRoot || vscode.Uri.joinPath(document.uri, '..').fsPath;
orchestrator.runStaticAnalysis(document, workingDir);
}, 500);
debounceTimers.set(key, timer);
})
);
}
export function deactivate() {
orchestrator = undefined!;
}
```
---
## 3. `package.json` 修改
`configuration` 部分替换为完整的命令、视图容器、菜单和配置项。
**commands**:
```json
{
"commands": [
{ "command": "codeReviewer.review", "title": "净码特工: 运行代码审查" },
{ "command": "codeReviewer.reviewSelection", "title": "净码特工: 审查选中代码" },
{ "command": "codeReviewer.openPanel", "title": "净码特工: 打开审查面板" },
{ "command": "codeReviewer.exportReport", "title": "净码特工: 导出报告" },
{ "command": "codeReviewer.addCustomRule", "title": "净码特工: 添加自定义规则" },
{ "command": "codeReviewer.fixIssue", "title": "净码特工: 修复此问题" },
{ "command": "codeReviewer.fixAll", "title": "净码特工: 批量修复" },
{ "command": "codeReviewer.openSetup", "title": "净码特工: 打开设置面板" }
]
}
```
**keybindings**:
```json
{
"keybindings": [
{
"command": "codeReviewer.review",
"key": "ctrl+shift+r",
"when": "editorTextFocus"
}
]
}
```
**viewsContainers** + **views** + **menus** + **configuration**: 见设计 §6.2-6.4
---
## 验收
- [ ] 3 个文件变更完成
- [ ] `Ctrl+Shift+R` 可触发审查
- [ ] 保存文件后 500ms 自动运行静态分析
- [ ] 命令面板显示 8 个命令
- [ ] `npm run compile` 通过
- [ ] `npm run lint` 通过