feat: 重构为 Monorepo 架构并实现 HTTP Server

架构变更:
- 采用 pnpm workspaces 实现 Monorepo 结构
- 将现有代码迁移到 packages/core
- 新增 packages/server HTTP 服务层

Server 功能:
- REST API: 会话管理、工具管理、配置管理
- WebSocket: 实时双向通信支持
- SSE: 服务端事件推送
- Hono + Bun 作为运行时

API 端点:
- GET/POST /api/sessions - 会话 CRUD
- GET/POST /api/sessions/:id/messages - 消息管理
- GET /api/sessions/:id/events - SSE 事件流
- WS /api/ws/:sessionId - WebSocket 连接
- GET/POST /api/tools - 工具管理
- GET/PUT /api/config - 配置管理
This commit is contained in:
2025-12-12 10:42:20 +08:00
parent 59dbed926e
commit 5e32375f0e
301 changed files with 3281 additions and 43 deletions
+329
View File
@@ -0,0 +1,329 @@
/**
* Git 管理器
*
* 整合 GitRepo、AutoCommitManager、MessageGenerator、UndoManager
* 提供统一的 Git 集成接口
*/
import type {
GitConfig,
GitStatus,
CommitResult,
UndoResult,
UndoEntry,
DiffResult,
CommitInfo,
GitEvent,
GitEventListener,
} from './types.js';
import { DEFAULT_GIT_CONFIG } from './types.js';
import { GitRepo } from './repo.js';
import { AutoCommitManager } from './auto-commit.js';
import { MessageGenerator } from './message-generator.js';
import { UndoManager } from './undo-manager.js';
export class GitManager {
private repo: GitRepo;
private autoCommit: AutoCommitManager;
private messageGenerator: MessageGenerator;
private undoManager: UndoManager;
private config: GitConfig;
private workdir: string;
/** 事件监听器 */
private eventListeners: GitEventListener[] = [];
/** 是否已初始化 */
private initialized: boolean = false;
constructor(workdir: string, config?: Partial<GitConfig>) {
this.workdir = workdir;
this.config = { ...DEFAULT_GIT_CONFIG, ...config };
// 创建组件
this.repo = new GitRepo(workdir, this.config);
this.messageGenerator = new MessageGenerator(this.config.messageFormat);
this.autoCommit = new AutoCommitManager(
this.repo,
this.config.autoCommit,
this.messageGenerator
);
this.undoManager = new UndoManager(this.repo, this.config.undo);
// 设置自动提交回调
this.autoCommit.setOnCommit((result) => {
if (result.success && result.shortHash && result.message) {
// 记录到 undo 历史
const files = this.autoCommit.getPendingFiles();
this.undoManager.recordCommit(
result.hash!,
result.shortHash,
result.message,
files
);
// 发送事件
this.emitEvent('commit', {
hash: result.shortHash,
message: result.message,
auto: true,
});
}
});
}
/**
* 初始化 Git 管理器
*/
async initialize(): Promise<boolean> {
if (!this.config.enabled) {
return false;
}
const isRepo = await this.repo.initialize();
this.initialized = isRepo;
return isRepo;
}
/**
* 检查是否已初始化
*/
isInitialized(): boolean {
return this.initialized;
}
/**
* 获取仓库状态
*/
async getStatus(): Promise<GitStatus> {
return this.repo.getStatus();
}
/**
* 文件变更后调用(由工具执行器调用)
*/
async onFileChanged(
filePath: string,
changeType: 'create' | 'modify' | 'delete'
): Promise<void> {
if (!this.initialized || !this.config.enabled) {
return;
}
await this.autoCommit.onFileChanged(filePath, changeType);
}
/**
* 手动提交
*/
async commit(options: {
message?: string;
files?: string[];
all?: boolean;
} = {}): Promise<CommitResult> {
if (!this.initialized) {
return { success: false, error: 'Git not initialized' };
}
// 如果有待提交的文件,先处理
if (this.autoCommit.hasPendingFiles()) {
await this.autoCommit.flush();
}
// 获取差异用于生成消息
const diff = await this.repo.getDiff({ staged: options.all });
const message = options.message || this.messageGenerator.generate(diff);
const result = await this.repo.commit({
message,
files: options.files,
all: options.all,
aiEdits: true,
});
if (result.success && result.shortHash && result.message) {
// 记录到 undo 历史
const files = options.files || [];
this.undoManager.recordCommit(
result.hash!,
result.shortHash,
result.message,
files
);
// 发送事件
this.emitEvent('commit', {
hash: result.shortHash,
message: result.message,
auto: false,
});
}
return result;
}
/**
* 撤销上一次 AI 提交
*/
async undo(): Promise<UndoResult> {
if (!this.initialized) {
return { success: false, message: 'Git not initialized' };
}
const result = await this.undoManager.undo();
if (result.success) {
this.emitEvent('undo', {
hash: result.commitHash,
files: result.restoredFiles,
});
}
return result;
}
/**
* 获取 undo 预览
*/
getUndoPreview(): UndoEntry | null {
return this.undoManager.getUndoPreview();
}
/**
* 获取 undo 历史
*/
getUndoHistory(): UndoEntry[] {
return this.undoManager.getHistory();
}
/**
* 检查是否可以 undo
*/
async canUndo(): Promise<{ canUndo: boolean; reason?: string }> {
return this.undoManager.canUndo();
}
/**
* 获取差异
*/
async getDiff(options: {
staged?: boolean;
file?: string;
commit?: string;
} = {}): Promise<DiffResult> {
return this.repo.getDiff(options);
}
/**
* 获取最近的提交
*/
async getRecentCommits(count: number = 10): Promise<CommitInfo[]> {
return this.repo.getRecentCommits(count);
}
/**
* 获取当前分支
*/
async getCurrentBranch(): Promise<string> {
return this.repo.getCurrentBranch();
}
/**
* 强制刷新待提交
*/
async flushPendingCommits(): Promise<CommitResult | null> {
return this.autoCommit.flush();
}
/**
* 获取待提交文件
*/
getPendingFiles(): string[] {
return this.autoCommit.getPendingFiles();
}
/**
* 添加事件监听器
*/
addEventListener(listener: GitEventListener): void {
this.eventListeners.push(listener);
}
/**
* 移除事件监听器
*/
removeEventListener(listener: GitEventListener): void {
const index = this.eventListeners.indexOf(listener);
if (index !== -1) {
this.eventListeners.splice(index, 1);
}
}
/**
* 发送事件
*/
private emitEvent(type: GitEvent['type'], data: unknown): void {
const event: GitEvent = {
type,
timestamp: Date.now(),
data,
};
for (const listener of this.eventListeners) {
try {
listener(event);
} catch (error) {
console.error('Git event listener error:', error);
}
}
}
/**
* 获取配置
*/
getConfig(): GitConfig {
return { ...this.config };
}
/**
* 更新配置
*/
updateConfig(config: Partial<GitConfig>): void {
this.config = { ...this.config, ...config };
}
}
// 全局 Git 管理器实例
let gitManager: GitManager | null = null;
/**
* 获取全局 Git 管理器
*/
export function getGitManager(): GitManager | null {
return gitManager;
}
/**
* 初始化全局 Git 管理器
*/
export async function initGitManager(
workdir: string,
config?: Partial<GitConfig>
): Promise<GitManager | null> {
gitManager = new GitManager(workdir, config);
const initialized = await gitManager.initialize();
if (!initialized) {
gitManager = null;
return null;
}
return gitManager;
}
/**
* 重置全局 Git 管理器
*/
export function resetGitManager(): void {
gitManager = null;
}