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
@@ -0,0 +1,89 @@
/**
* 创建检查点工具
*/
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getCheckpointManager } from '../../checkpoint/index.js';
export const checkpointCreateTool: ToolWithMetadata = {
name: 'checkpoint_create',
description: loadDescription('checkpoint_create'),
metadata: {
name: 'checkpoint_create',
category: 'core',
description: '创建一个新的工作区检查点快照',
keywords: [
'checkpoint',
'create',
'snapshot',
'save',
'检查点',
'快照',
'保存',
],
deferLoading: true,
},
parameters: {
name: {
type: 'string',
description: '检查点名称 (可选)',
required: false,
},
description: {
type: 'string',
description: '检查点描述 (可选)',
required: false,
},
},
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
const name = params.name as string | undefined;
const description = params.description as string | undefined;
try {
const manager = getCheckpointManager();
if (!manager.isEnabled()) {
return {
success: false,
output: '',
error: '检查点系统已禁用',
};
}
await manager.initialize();
const checkpoint = await manager.createCheckpoint({
name,
description,
trigger: 'manual',
});
const lines = [
`✓ 检查点已创建`,
` ID: ${checkpoint.id}`,
` Commit: ${checkpoint.commitHash.slice(0, 8)}`,
];
if (checkpoint.name) {
lines.push(` 名称: ${checkpoint.name}`);
}
if (checkpoint.filesChanged > 0) {
lines.push(` 文件变更: ${checkpoint.filesChanged}`);
}
lines.push(` 时间: ${new Date(checkpoint.timestamp).toLocaleString()}`);
return {
success: true,
output: lines.join('\n'),
};
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
},
};
@@ -0,0 +1,158 @@
/**
* 检查点差异工具
*/
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getCheckpointManager } from '../../checkpoint/index.js';
export const checkpointDiffTool: ToolWithMetadata = {
name: 'checkpoint_diff',
description: loadDescription('checkpoint_diff'),
metadata: {
name: 'checkpoint_diff',
category: 'core',
description: '显示检查点与当前工作区的差异',
keywords: [
'checkpoint',
'diff',
'compare',
'changes',
'检查点',
'差异',
'比较',
'变更',
],
deferLoading: true,
},
parameters: {
checkpoint_id: {
type: 'string',
description: '检查点 ID 或 commit hash (默认为最近的检查点)',
required: false,
},
file: {
type: 'string',
description: '指定文件路径查看详细差异 (可选)',
required: false,
},
},
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
const checkpointId = params.checkpoint_id as string | undefined;
const file = params.file as string | undefined;
try {
const manager = getCheckpointManager();
if (!manager.isEnabled()) {
return {
success: false,
output: '',
error: '检查点系统已禁用',
};
}
await manager.initialize();
// 获取目标检查点
let targetCheckpoint;
if (checkpointId) {
targetCheckpoint = await manager.getCheckpoint(checkpointId);
if (!targetCheckpoint) {
return {
success: false,
output: '',
error: `找不到检查点: ${checkpointId}`,
};
}
} else {
targetCheckpoint = await manager.getLatestCheckpoint();
if (!targetCheckpoint) {
return {
success: true,
output: '暂无检查点',
};
}
}
// 显示文件详细差异
if (file) {
const fileDiff = await manager.getFileDiff(targetCheckpoint.id, file);
const lines = [
`文件差异: ${file}`,
`检查点: ${targetCheckpoint.commitHash.slice(0, 8)}`,
`变更类型: ${fileDiff.type}`,
'',
];
if (fileDiff.patch) {
lines.push('```diff');
lines.push(fileDiff.patch);
lines.push('```');
} else if (fileDiff.type === 'added') {
lines.push('(新文件)');
} else if (fileDiff.type === 'deleted') {
lines.push('(已删除)');
}
return {
success: true,
output: lines.join('\n'),
};
}
// 显示概要差异
const diff = await manager.getDiff(targetCheckpoint.id);
if (diff.files.length === 0) {
return {
success: true,
output: `检查点 ${targetCheckpoint.commitHash.slice(0, 8)} 与当前工作区相同`,
};
}
const lines = [
`检查点 ${targetCheckpoint.commitHash.slice(0, 8)} 与当前工作区的差异:`,
'',
` +${diff.totalInsertions} 行添加 -${diff.totalDeletions} 行删除`,
'',
'变更的文件:',
];
for (const fileChange of diff.files) {
const symbol =
fileChange.type === 'added'
? '+'
: fileChange.type === 'deleted'
? '-'
: fileChange.type === 'renamed'
? 'R'
: 'M';
let line = ` ${symbol} ${fileChange.path}`;
if (fileChange.oldPath) {
line = ` ${symbol} ${fileChange.oldPath} -> ${fileChange.path}`;
}
if (fileChange.insertions || fileChange.deletions) {
line += ` (+${fileChange.insertions || 0} -${fileChange.deletions || 0})`;
}
lines.push(line);
}
return {
success: true,
output: lines.join('\n'),
};
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
},
};
@@ -0,0 +1,91 @@
/**
* 列出检查点工具
*/
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getCheckpointManager } from '../../checkpoint/index.js';
export const checkpointListTool: ToolWithMetadata = {
name: 'checkpoint_list',
description: loadDescription('checkpoint_list'),
metadata: {
name: 'checkpoint_list',
category: 'core',
description: '列出所有可用的检查点',
keywords: [
'checkpoint',
'list',
'show',
'history',
'检查点',
'列表',
'历史',
],
deferLoading: true,
},
parameters: {
limit: {
type: 'number',
description: '最多显示的检查点数量 (默认 10)',
required: false,
},
},
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
const limit = (params.limit as number) || 10;
try {
const manager = getCheckpointManager();
if (!manager.isEnabled()) {
return {
success: false,
output: '',
error: '检查点系统已禁用',
};
}
await manager.initialize();
const checkpoints = await manager.listCheckpoints();
if (checkpoints.length === 0) {
return {
success: true,
output: '暂无检查点',
};
}
const displayCheckpoints = checkpoints.slice(0, limit);
const lines = [`${checkpoints.length} 个检查点:\n`];
for (const cp of displayCheckpoints) {
const date = new Date(cp.timestamp).toLocaleString();
const hash = cp.commitHash.slice(0, 8);
const name = cp.name ? ` "${cp.name}"` : '';
const files = cp.filesChanged > 0 ? ` (${cp.filesChanged} files)` : '';
lines.push(` ${hash}${name}${files}`);
lines.push(` ${cp.description || cp.trigger}`);
lines.push(` ${date}`);
lines.push('');
}
if (checkpoints.length > limit) {
lines.push(` ... 还有 ${checkpoints.length - limit} 个检查点`);
}
return {
success: true,
output: lines.join('\n'),
};
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
},
};
@@ -0,0 +1,157 @@
/**
* 恢复检查点工具
*/
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getCheckpointManager } from '../../checkpoint/index.js';
export const checkpointRestoreTool: ToolWithMetadata = {
name: 'checkpoint_restore',
description: loadDescription('checkpoint_restore'),
metadata: {
name: 'checkpoint_restore',
category: 'core',
description: '恢复到指定的检查点',
keywords: [
'checkpoint',
'restore',
'rollback',
'undo',
'检查点',
'恢复',
'回滚',
'撤销',
],
deferLoading: true,
},
parameters: {
checkpoint_id: {
type: 'string',
description: '要恢复的检查点 ID 或 commit hash',
required: true,
},
files: {
type: 'string',
description: '只恢复指定文件,多个文件用逗号分隔 (可选)',
required: false,
},
dry_run: {
type: 'boolean',
description: '预览模式,不实际执行恢复',
required: false,
},
},
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
const checkpointId = params.checkpoint_id as string;
const filesStr = params.files as string | undefined;
const dryRun = params.dry_run as boolean | undefined;
if (!checkpointId) {
return {
success: false,
output: '',
error: '请指定要恢复的检查点 ID',
};
}
try {
const manager = getCheckpointManager();
if (!manager.isEnabled()) {
return {
success: false,
output: '',
error: '检查点系统已禁用',
};
}
await manager.initialize();
// 验证检查点存在
const checkpoint = await manager.getCheckpoint(checkpointId);
if (!checkpoint) {
return {
success: false,
output: '',
error: `找不到检查点: ${checkpointId}`,
};
}
// 解析文件列表
const files = filesStr
? filesStr.split(',').map((f) => f.trim()).filter(Boolean)
: undefined;
// 执行恢复
const result = await manager.rollback({
target: checkpointId,
files,
dryRun,
});
if (dryRun) {
const lines = [
`预览: 恢复到检查点 ${checkpoint.commitHash.slice(0, 8)}`,
'',
'将恢复以下文件:',
];
for (const file of result.restoredFiles) {
lines.push(` - ${file}`);
}
lines.push('');
lines.push('(使用 dry_run=false 执行实际恢复)');
return {
success: true,
output: lines.join('\n'),
};
}
if (!result.success) {
const errorLines = ['恢复失败:'];
for (const err of result.errors) {
errorLines.push(` ${err.file}: ${err.error}`);
}
return {
success: false,
output: '',
error: errorLines.join('\n'),
};
}
const lines = [
`✓ 已恢复到检查点 ${checkpoint.commitHash.slice(0, 8)}`,
'',
`恢复了 ${result.restoredFiles.length} 个文件:`,
];
for (const file of result.restoredFiles.slice(0, 10)) {
lines.push(` - ${file}`);
}
if (result.restoredFiles.length > 10) {
lines.push(` ... 还有 ${result.restoredFiles.length - 10} 个文件`);
}
if (result.previousCommit) {
lines.push('');
lines.push(`提示: 可以使用 checkpoint_restore 恢复到 ${result.previousCommit.slice(0, 8)} 来撤销此操作`);
}
return {
success: true,
output: lines.join('\n'),
};
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
},
};
@@ -0,0 +1,9 @@
/**
* 检查点工具模块
*/
export { checkpointCreateTool } from './checkpoint_create.js';
export { checkpointListTool } from './checkpoint_list.js';
export { checkpointDiffTool } from './checkpoint_diff.js';
export { checkpointRestoreTool } from './checkpoint_restore.js';
export { undoTool } from './undo.js';
+143
View File
@@ -0,0 +1,143 @@
/**
* 撤销操作工具 (快捷回滚)
*/
import type { ToolResult } from '../../types/index.js';
import type { ToolWithMetadata } from '../types.js';
import { loadDescription } from '../load_description.js';
import { getCheckpointManager } from '../../checkpoint/index.js';
export const undoTool: ToolWithMetadata = {
name: 'undo',
description: loadDescription('undo'),
metadata: {
name: 'undo',
category: 'core',
description: '撤销上一次文件操作,回滚到最近的检查点',
keywords: ['undo', 'rollback', 'revert', '撤销', '回滚', '恢复'],
deferLoading: false, // 常用命令,始终加载
},
parameters: {
confirm: {
type: 'boolean',
description: '确认执行撤销操作 (默认 true)',
required: false,
},
},
execute: async (params: Record<string, unknown>): Promise<ToolResult> => {
const confirm = params.confirm !== false;
try {
const manager = getCheckpointManager();
if (!manager.isEnabled()) {
return {
success: false,
output: '',
error: '检查点系统已禁用,无法执行撤销操作',
};
}
await manager.initialize();
// 获取最近两个检查点
const checkpoints = await manager.listCheckpoints();
if (checkpoints.length === 0) {
return {
success: false,
output: '',
error: '没有可用的检查点,无法执行撤销操作',
};
}
// 预览模式
if (!confirm) {
const targetCheckpoint =
checkpoints.length > 1 ? checkpoints[1] : checkpoints[0];
const diff = await manager.getDiff(targetCheckpoint.id);
const lines = [
'预览: 撤销将恢复以下文件变更:',
'',
`目标检查点: ${targetCheckpoint.commitHash.slice(0, 8)}`,
` ${targetCheckpoint.description || targetCheckpoint.trigger}`,
` ${new Date(targetCheckpoint.timestamp).toLocaleString()}`,
'',
];
if (diff.files.length > 0) {
lines.push('将恢复的文件:');
for (const file of diff.files.slice(0, 10)) {
const symbol =
file.type === 'added'
? '+'
: file.type === 'deleted'
? '-'
: 'M';
lines.push(` ${symbol} ${file.path}`);
}
if (diff.files.length > 10) {
lines.push(` ... 还有 ${diff.files.length - 10} 个文件`);
}
} else {
lines.push('(无文件变更)');
}
lines.push('');
lines.push('使用 confirm=true 执行撤销');
return {
success: true,
output: lines.join('\n'),
};
}
// 执行撤销
const result = await manager.undo();
if (!result.success) {
const errorLines = ['撤销失败:'];
for (const err of result.errors) {
errorLines.push(` ${err.file}: ${err.error}`);
}
return {
success: false,
output: '',
error: errorLines.join('\n'),
};
}
const lines = [
'✓ 撤销成功',
'',
`恢复了 ${result.restoredFiles.length} 个文件`,
];
if (result.restoredFiles.length > 0 && result.restoredFiles.length <= 5) {
for (const file of result.restoredFiles) {
lines.push(` - ${file}`);
}
}
if (result.previousCommit) {
lines.push('');
lines.push(
`提示: 使用 checkpoint_restore --checkpoint_id ${result.previousCommit.slice(0, 8)} 可以撤销此操作`
);
}
return {
success: true,
output: lines.join('\n'),
};
} catch (error) {
return {
success: false,
output: '',
error: error instanceof Error ? error.message : String(error),
};
}
},
};