# Step 01 — Phase 1: 基础层 **依赖**: 无 **参考设计**: §3.2, §6.4, §13.2 ## 目标 建立公共类型定义和配置管理,为所有上层模块提供基础能力。 ## 新建文件 | # | 文件 | 说明 | |---|------|------| | 1 | `src/types.ts` | 公共类型定义 | | 2 | `src/config/ai.ts` | AI 配置 getter | | 3 | `src/config/linter.ts` | Linter 配置 getter | | 4 | `src/config/fixer.ts` | 修复器配置 getter | | 5 | `src/config/secret.ts` | API Key SecretStorage | | 6 | `src/config/index.ts` | 统一导出 | --- ## 1. `src/types.ts` ```typescript import * as vscode from 'vscode'; export type Severity = 'error' | 'warning' | 'info'; export type AdapterStatus = 'ok' | 'tool-unavailable' | 'execution-failed'; export interface LinterDiagnostic { severity: Severity; ruleId: string; message: string; range: vscode.Range; suggestion?: string; } export interface AdapterResult { diagnostics: LinterDiagnostic[]; status: AdapterStatus; errorMessage?: string; } export interface LinterAdapter { id: string; supportedLanguages: string[]; check(document: vscode.TextDocument, workingDir: string): Promise; isAvailable(): boolean; } ``` --- ## 2. `src/config/ai.ts` ```typescript import * as vscode from 'vscode'; export interface AIConfig { provider: string; model: string; baseUrl: string; temperature: number; timeout: number; outputLanguage: string; } export function getAIConfig(): AIConfig { const config = vscode.workspace.getConfiguration('vscode-code-reviewer'); return { provider: config.get('ai.provider', 'deepseek'), model: config.get('ai.model', 'deepseek-chat'), baseUrl: config.get('ai.baseUrl', 'https://api.deepseek.com/v1'), temperature: config.get('ai.temperature', 0.2), timeout: config.get('ai.timeout', 300), outputLanguage: config.get('ai.outputLanguage', 'zh-CN'), }; } ``` **配置 Key**(前缀 `vscode-code-reviewer.`): | Key | 类型 | 默认值 | |-----|------|--------| | `ai.provider` | enum | `deepseek` | | `ai.model` | string | `deepseek-chat` | | `ai.baseUrl` | string | `https://api.deepseek.com/v1` | | `ai.temperature` | number | 0.2 | | `ai.timeout` | number | 300 | | `ai.outputLanguage` | string | `zh-CN` | --- ## 3. `src/config/linter.ts` ```typescript import * as vscode from 'vscode'; export interface LinterConfig { languageMap: Record; pmdJarPath: string; pmdRulesetPath: string; pmdJspRulesetPath: string; sqlLintConfigFile: string; } export function getLinterConfig(): LinterConfig { const config = vscode.workspace.getConfiguration('vscode-code-reviewer'); return { languageMap: { javascript: config.get('linters.javascript', 'eslint'), typescript: config.get('linters.typescript', 'eslint'), java: config.get('linters.java', 'pmd'), jsp: config.get('linters.jsp', 'jsp'), css: config.get('linters.css', 'stylelint'), sql: config.get('linters.sql', 'sql-lint'), plsql: config.get('linters.plsql', 'sql-lint'), }, pmdJarPath: config.get('pmd.jarPath', ''), pmdRulesetPath: config.get('pmd.rulesetPath', ''), pmdJspRulesetPath: config.get('pmd.jspRulesetPath', ''), sqlLintConfigFile: config.get('sql-lint.configFile', ''), }; } ``` | Key | 类型 | 默认值 | enum | |-----|------|--------|------| | `linters.javascript` | enum | `eslint` | `""` / `eslint` | | `linters.typescript` | enum | `eslint` | `""` / `eslint` | | `linters.java` | enum | `pmd` | `""` / `pmd` | | `linters.jsp` | enum | `jsp` | `""` / `jsp` | | `linters.css` | enum | `stylelint` | `""` / `stylelint` | | `linters.sql` | enum | `sql-lint` | `""` / `sql-lint` | | `linters.plsql` | enum | `sql-lint` | `""` / `sql-lint` | | `pmd.jarPath` | string | `""` | — | | `pmd.rulesetPath` | string | `""` | — | | `pmd.jspRulesetPath` | string | `""` | — | | `sql-lint.configFile` | string | `""` | — | --- ## 4. `src/config/fixer.ts` ```typescript import * as vscode from 'vscode'; export interface FixerConfig { contextLines: number; } export function getFixerConfig(): FixerConfig { const config = vscode.workspace.getConfiguration('vscode-code-reviewer'); return { contextLines: config.get('fixer.contextLines', 5), }; } ``` --- ## 5. `src/config/secret.ts` ```typescript import * as vscode from 'vscode'; const SECRET_KEY = 'vscode-code-reviewer.apiKey'; export async function getApiKey(context: vscode.ExtensionContext): Promise { return context.secrets.get(SECRET_KEY); } export async function setApiKey(context: vscode.ExtensionContext, key: string): Promise { await context.secrets.store(SECRET_KEY, key); } export async function deleteApiKey(context: vscode.ExtensionContext): Promise { await context.secrets.delete(SECRET_KEY); } export async function isApiKeyConfigured(context: vscode.ExtensionContext): Promise { const key = await getApiKey(context); return !!key; } ``` --- ## 6. `src/config/index.ts` ```typescript export { getAIConfig, AIConfig } from './ai'; export { getLinterConfig, LinterConfig } from './linter'; export { getFixerConfig, FixerConfig } from './fixer'; export { getApiKey, setApiKey, deleteApiKey, isApiKeyConfigured } from './secret'; ``` --- ## 验收 - [ ] 6 个文件创建完成 - [ ] `npm run compile` 通过 - [ ] `npm run lint` 通过