- 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
253 lines
8.2 KiB
Markdown
253 lines
8.2 KiB
Markdown
# Step 15 — Phase 5.1: 命令注册 + extension.ts 更新
|
||
|
||
**依赖**: Step 08, 14(Orchestrator + 报告导出),Step 13(Fixer 可选)
|
||
**参考设计**: §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` 通过
|