feat: 初始化 AI Code Diff Preview 插件项目

- 核心架构搭建:四层架构设计(触发层、隔离层、Diff引擎、UI层)
- 快照管理器:管理 Base/Suggest 双版本,隔离 AI 生成代码
- Diff 引擎:基于 Myers 算法计算差异,生成变更块
- 内联装饰器:红绿高亮显示删除/新增行
- CodeLens 提供器:提供 Accept/Reject 按钮
- 事务处理:Accept/Reject 原子化操作
- Claude Hooks 集成:支持 after_code_edit/after_write_file 事件
- 状态栏显示:实时显示变更状态
- 基础测试用例:7 个测试全部通过

技术栈:TypeScript + VSCode Extension API + diff 库 + esbuild
This commit is contained in:
2026-06-17 21:11:33 +08:00
commit 3168e81aa6
21 changed files with 6912 additions and 0 deletions
+70
View File
@@ -0,0 +1,70 @@
/**
* 状态栏管理器 - 显示 Diff 状态信息
*/
import * as vscode from 'vscode';
import { Snapshot } from '../models/types';
import { STATUS_BAR_PRIORITY } from '../models/constants';
export class StatusBarManager {
private statusBarItem: vscode.StatusBarItem;
private chunkCountItem: vscode.StatusBarItem;
constructor() {
this.statusBarItem = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
STATUS_BAR_PRIORITY.DIFF_STATUS
);
this.chunkCountItem = vscode.window.createStatusBarItem(
vscode.StatusBarAlignment.Left,
STATUS_BAR_PRIORITY.CHUNK_COUNT
);
}
/**
* 更新状态栏
*/
update(snapshot: Snapshot): void {
const pendingChunks = snapshot.chunks.filter(c => c.status === 'pending');
const conflictChunks = snapshot.chunks.filter(c => c.status === 'conflict');
// 更新主状态
this.statusBarItem.text = '$(diff) AI Diff';
this.statusBarItem.tooltip = 'AI Diff Preview 活跃';
this.statusBarItem.show();
// 更新变更块数量
if (pendingChunks.length > 0 || conflictChunks.length > 0) {
this.chunkCountItem.text = `$(edit) ${pendingChunks.length} 个变更`;
if (conflictChunks.length > 0) {
this.chunkCountItem.text += ` (${conflictChunks.length} 个冲突)`;
this.chunkCountItem.backgroundColor = new vscode.ThemeColor(
'statusBarItem.warningBackground'
);
} else {
this.chunkCountItem.backgroundColor = undefined;
}
this.chunkCountItem.tooltip = '点击查看变更详情';
this.chunkCountItem.show();
} else {
this.chunkCountItem.hide();
}
}
/**
* 清除状态栏
*/
clear(): void {
this.statusBarItem.hide();
this.chunkCountItem.hide();
}
/**
* 释放资源
*/
dispose(): void {
this.statusBarItem.dispose();
this.chunkCountItem.dispose();
}
}