Commit Graph

196 Commits

Author SHA1 Message Date
kurihada 527692ec03 refactor(storage): 采用 OpenCode 风格三层存储结构
重构消息存储系统,从"每条消息一个文件"改为分层存储:
- Session → Message → Parts 三层结构
- 12 种 Part 类型(TextPart, ToolPart, ReasoningPart 等)
- ToolPart 状态机(pending → running → completed/error)
- 通用 Storage API(read/write/list/remove)

新增文件:
- parts.ts: Part 类型定义(Zod schema)
- message.ts: MessageInfo 类型定义
- id.ts: ID 生成器
- storage/: 分层存储实现

删除旧文件:
- storage.ts, types.ts, migration.ts

存储路径:
~/.local/share/ai-assist/
├── session/{projectId}/{sessionId}.json
├── message/{sessionId}/{messageId}.json
├── part/{messageId}/{partId}.json
└── todo/{sessionId}.json
2025-12-15 11:16:10 +08:00
kurihada b8fcb65f73 fix(server): 修复消息持久化问题
- 在 adapter.ts 中为 Agent 绑定 Core SessionManager
- 添加 getOrCreateSessionManager 函数创建和恢复会话
- 修改 getOrCreateAgent 为异步函数
- 在 sessions.ts 中转换 AI SDK 消息格式为字符串
2025-12-15 10:45:58 +08:00
kurihada bbce1de60c fix(ui): 优化 WebSocket 连接和 PWA meta 标签
- WebSocket onopen 检查 isClosingRef,组件卸载后自动关闭连接
- 更新 PWA meta 标签为 mobile-web-app-capable
2025-12-15 10:29:49 +08:00
kurihada 9e55237dae fix(ui): 修复 React key 警告和 forwardRef 问题
- ChatMessage/SessionItem 使用 forwardRef 支持 AnimatePresence
- useChat 为 message_received/done 事件生成唯一消息 ID
- sessions API 为历史消息添加 ID 字段
- cli 添加 @types/inquirer 依赖
2025-12-15 10:24:45 +08:00
kurihada 842cf1a3e8 fix(ui): 优化会话初始化逻辑
- 首次启动时自动创建会话
- 用户删除所有会话后不再自动创建,显示空状态
- 使用 localStorage 记录是否曾有会话
2025-12-15 10:05:17 +08:00
kurihada 6342a46e59 refactor(storage): 统一消息存储到 Core 层
问题:Server 端只存储最终文本响应,工具调用的中间消息丢失。

解决方案:
- Agent.chat() 返回 ChatResult,包含完整消息链
- Server SessionManager 简化为只管理会话元数据
- 消息 API 改为从 Core Storage 读取
- 移除 Server 端的消息存储和 addMessage 方法

影响范围:
- core: Agent.chat() 返回类型变更
- server: SessionManager 接口变更,移除消息存储
- server: GET /sessions/:id/messages 从 Core 读取
- server: 移除 POST /sessions/:id/messages 端点
2025-12-15 10:04:22 +08:00
kurihada a657af9bb7 test(server): 修复 SessionManager 测试的 session 清理问题
- 添加 afterEach 钩子清理测试中创建的 session
- 引入 createTrackedSession 辅助函数追踪需要清理的 session
- 防止测试产生的 session 持久化到磁盘影响用户数据
2025-12-15 00:55:02 +08:00
kurihada 5b20420ccd test(server): 增强 auth/ws/sse 测试覆盖率
- auth/token.ts: 50% → 100%
  - 新增 authMiddleware 中间件完整测试
  - 覆盖本地 IP 检测、远程认证、跳过路径等场景
  - 新增 getAuthContext 测试

- ws.ts: 90% → 98%
  - 新增 Blob/非标准数据类型处理测试
  - 新增 addMessage 返回 null 场景测试
  - 新增 tool_response 和 permission_response 边界测试

- sse.ts: 新增事件格式化和统计测试

测试数量: 344 → 369 (+25)
总体覆盖率: 80.82% → 82.98%
2025-12-15 00:36:43 +08:00
kurihada 7bc4f006a0 test(server): 补充 checkpoints/mcp/sse/adapter 测试
- 新增 checkpoints.test.ts: 29 个测试覆盖 Checkpoint 管理 API
- 新增 mcp.test.ts: 15 个测试覆盖 MCP 服务器管理 API
- 扩展 sse.test.ts: 添加 handleSSE 路由测试
- 扩展 adapter.test.ts: 添加 cancelProcessing, getContextUsage,
  compressContext, processMessage 测试

覆盖率提升: 60% -> 80.82%
测试数量: 288 -> 344
2025-12-15 00:32:04 +08:00
kurihada 67e129fce2 fix(commands): 修复路由顺序导致 /content 端点被遮蔽的问题
- 将 /:name{.+}/execute 和 /:name{.+}/content 路由移到 /:name{.+} 之前
- Hono 的 {.+} 模式会贪婪匹配,导致 /test/content 被解析为 name='test/content'
- 更新测试用例以正确测试 /content 端点功能
2025-12-15 00:17:22 +08:00
kurihada c44527a890 test(server): 添加 routes 模块单元测试
- agents.test.ts: Agent presets CRUD API (18 tests)
- tools.test.ts: Tool registration & execution (10 tests)
- files.test.ts: File browser API with path security (24 tests)
- commands.test.ts: Slash commands CRUD & execution (20 tests)
- hooks.test.ts: Hooks configuration management (20 tests)

覆盖率从 29.59% 提升到 60.35%,共 287 个测试
2025-12-15 00:14:27 +08:00
kurihada 5835799b69 test(server): 添加 server 模块单元测试
- 新增 vitest 配置和测试基础设施
- 添加 adapter.test.ts: 测试 Core 模块初始化和 Agent 管理 (18 tests)
- 添加 token.test.ts: 测试 Token 生成、验证和中间件 (25 tests)
- 添加 handler.test.ts: 测试权限处理器 (18 tests)
- 添加 ws.test.ts: 测试 WebSocket 连接和消息处理 (19 tests)
- 添加 sse.test.ts: 测试 SSE 事件发送 (14 tests)
- 添加 sessions.test.ts: 测试会话路由 (16 tests)
- 添加 config.test.ts: 测试配置路由 (10 tests)
- 添加 context.test.ts: 测试上下文压缩路由 (9 tests)
- 添加 providers.test.ts: 测试 Provider 管理路由 (18 tests)
- 添加 manager.test.ts: 测试 SessionManager (48 tests)

总计 195 个测试,覆盖率从 0% 提升至 29.59%
2025-12-15 00:07:32 +08:00
kurihada 503e4c4ccd fix(init): 确保 Registry 在服务启动时正确初始化
- AgentRegistry: 在构造函数中同步初始化预设 Agent
- AgentRegistry: 添加 isInitialized() 方法
- initCore(): 添加 ProviderRegistry.init() 调用
- initCore(): 添加 AgentRegistry.init() 调用

修复用户配置(Provider、Agent)重启后丢失的问题
2025-12-14 23:40:33 +08:00
kurihada aefea715b1 feat(context): 根据模型动态设置 contextLimit
- AgentConfig 添加 contextWindow 字段
- ProviderRegistry 添加 getModelInfo() 方法查询模型信息
- loadConfig() 从 ProviderRegistry 获取模型的 contextWindow
- Agent 构造函数使用 contextWindow 初始化压缩管理器

效果:
- Anthropic Claude: 168k (200k - 32k 输出预留)
- DeepSeek: 32k (64k - 32k 输出预留)
- 未知模型回退到默认 200k
2025-12-14 23:34:32 +08:00
kurihada cacd9914fd fix(config): 优化配置错误提示信息
- 未选择 provider 时提示"选择并配置模型提供商"
- 已选择 provider 但未配置 API Key 时提示配置该 provider
2025-12-14 22:44:13 +08:00
kurihada 07a039001d feat(ui): 添加配置错误 toast 提示
当 Provider API Key 未配置时,显示 toast 提示并提供
"去配置"按钮,点击可直接打开 Providers 配置面板
2025-12-14 22:35:02 +08:00
kurihada 32064a3531 fix(config): 优雅处理 Provider 未配置错误
- 添加 ConfigurationError 类替代 process.exit(1)
- Server 端捕获配置错误并返回友好消息
- UI 端支持 config_error 类型的 WebSocket 消息
- 服务器不再因配置缺失而崩溃
2025-12-14 22:24:51 +08:00
kurihada c307cd3a7c refactor(agent): 将 Summary Model 改造为内置 Sub Agent
- 扩展 AgentMode 类型添加 'internal' 模式
- 新增 summary agent preset (claude-3-5-haiku)
- AgentRegistry 添加 getInternal/listInternalAgents 方法
- CompressionManager 添加 setSummaryModelFromAgentConfig
- Agent 构造函数改用 Registry 配置初始化 Summary 模型
- 清理旧的 SummaryConfig 配置系统
- UI AgentsPanel 分离显示 System/Preset/Custom agents
- UI AgentEditor 为 internal agent 显示简化编辑界面
2025-12-14 22:12:36 +08:00
kurihada e97daaa0eb refactor(settings): 移除无效的配置项
- 移除 maxTokens/temperature 滑块(后端从不使用)
- 移除 allowedPaths/deniedPaths 显示(权限通过 handler 处理)
- Settings 面板只保留 workdir 和 Summary Model 配置
2025-12-14 21:37:58 +08:00
kurihada 9e011476c8 refactor(config): 移除环境变量依赖,统一使用 Provider 配置系统
- 移除 .env.example 文件
- 简化 resolveApiKey 函数,只从配置文件读取 API Key
- 重构 loadConfig/loadVisionConfig/loadSummaryConfig 使用 ProviderRegistry
- 更新测试以 mock Provider 系统
2025-12-14 21:29:36 +08:00
kurihada c9d0cbce5b fix(session): 修复 getOrCreateProject 死锁问题
读写锁嵌套导致死锁:在持有读锁的情况下尝试获取写锁。
改为先释放读锁再获取写锁,并使用双重检查模式防止竞态条件。
2025-12-14 20:44:55 +08:00
kurihada 70a9a154a4 feat(context): 添加上下文压缩 API 和 UI 组件
Server API:
- 扩展 Agent Adapter 接口添加压缩相关方法
- 新增 context.ts 路由 (GET /sessions/:id/context, POST /sessions/:id/compress)
- 扩展 config.ts 添加摘要模型配置接口 (GET/PUT /config/summary)

UI 组件:
- 新增 ContextUsage 组件显示上下文使用情况
- 扩展 ConfigPanel 添加摘要模型配置区域
- 添加 API 客户端方法和类型定义

Web 集成:
- 在 Chat 页面头部集成 ContextUsage 紧凑模式显示
2025-12-14 20:33:51 +08:00
kurihada f54f24b079 feat(context): 优化对话压缩系统
- 添加独立摘要模型配置支持(SUMMARY_PROVIDER/MODEL/API_KEY/BASE_URL)
- 添加 CompressionStatus 枚举和 DetailedCompressionResult 详细返回类型
- 实现压缩失败检测(空摘要、token膨胀)
- 添加首条 user-assistant 对保护,确保上下文连贯性
- CompressionManager 支持独立摘要模型(优先使用小模型降低成本)
- Agent 自动压缩时显示详细状态信息
- 更新相关测试用例
2025-12-13 11:13:20 +08:00
kurihada 9ff2934089 refactor(session): 升级存储系统架构
- 添加读写锁机制防止并发写入冲突
- 实现数据迁移框架支持版本化升级
- 分层存储结构:项目/会话/消息独立存储
- 使用 Git root commit hash 作为稳定项目 ID
- 增量消息同步避免重复写入
- 每条消息独立文件,按序号命名 (0001.json, 0002.json)
2025-12-13 10:41:36 +08:00
kurihada 26e8646518 feat(ui): 集成 Provider 管理到 web 和 desktop 应用
- 新增 ProviderEditor 组件用于编辑提供商配置
- ProvidersPanel 添加编辑按钮集成 ProviderEditor
- ChatPage 添加 onOpenProviders 工具栏按钮
- web/desktop App.tsx 集成 ProvidersPanel 面板
2025-12-13 02:01:09 +08:00
kurihada 6ec6fe2f9f feat(provider): 添加独立的 Provider 模块管理模型提供商
实现可扩展的 Provider 系统,支持动态注册自定义提供商:

Core 模块 (packages/core/src/provider/):
- types.ts: Provider 相关类型定义
- builtin/: 内置提供商 (Anthropic, OpenAI, DeepSeek)
- registry.ts: ProviderRegistry 单例类
- config.ts: 配置持久化 (~/.ai-terminal-assistant/providers.json)
- utils.ts: 连接测试等工具函数

Server API (packages/server/src/routes/providers.ts):
- GET/POST/PUT/DELETE /providers 提供商管理
- POST /providers/:id/test 连接测试
- 自定义模型管理接口

Frontend (packages/ui/):
- ProvidersPanel 组件用于管理提供商
- API client 函数和类型定义

主要功能:
- 支持动态注册 OpenAI 兼容服务 (Ollama, vLLM 等)
- 每个提供商独立的 API Key 配置
- 预设模型列表 + 自定义模型输入
- 连接测试验证
2025-12-13 01:50:27 +08:00
kurihada 1d69fd876d feat(permission): 实现 WebSocket 权限确认机制
重构权限系统,将终端 UI 代码从 core 模块移除,实现基于 WebSocket 的权限确认流程:

Core 模块清理:
- 删除 permission/prompt.ts 和 file-prompt.ts(终端交互)
- 删除 diff.ts 中的 chalk 渲染函数
- 删除 config.ts 中的 inquirer 交互
- 移除 chalk 依赖

Server 权限处理:
- 新增 permission/handler.ts,实现 WebSocket 权限请求/响应
- 更新 agent/adapter.ts 设置权限回调
- 更新 ws.ts 处理 permission_response 消息

Web 权限组件:
- 新增 PermissionDialog 组件,显示权限请求详情和 Diff
- 更新 useChat hook 管理权限状态
- 更新 Chat 页面集成权限弹窗
2025-12-13 01:09:35 +08:00
kurihada 5d4afecd48 refactor(core): 移除 UI 交互层,保持 core 为纯能力模块
- 删除 terminal.ts 及其测试(UI 交互应属于 cli 包)
- 清理 index.ts 中的 CLI 入口代码
- 合并 lib.ts 导出到 index.ts
- 移除 commander、inquirer 依赖
- 更新 package.json 导出配置
2025-12-13 00:42:07 +08:00
kurihada 5b7d62e793 chore: 忽略 Astro 自动生成目录 2025-12-12 23:11:21 +08:00
kurihada 87620a1141 feat(website): 添加文档页面布局和根目录快捷脚本
- 新增 DocsSidebar 文档导航侧边栏组件
- 新增 DocsLayout 文档页面布局模板
- 首页导航添加文档入口链接
- 根目录 package.json 添加各包快捷脚本
2025-12-12 23:09:41 +08:00
kurihada 2f9db8d7d8 feat(website): 添加项目官网
使用 Astro 框架构建的静态官网
2025-12-12 22:53:02 +08:00
kurihada cb554c65b4 feat(checkpoint): 添加 Checkpoint 可视化管理功能
Core 层增强:
- 添加 safety.ts: 7点安全检查机制
- 添加 session-tracker.ts: 会话级检查点跟踪
- 添加 lock.ts: 并发控制文件锁
- 添加 lfs.ts: Git LFS 大文件支持
- 添加 path-validator.ts: 路径验证
- 添加 commit-message.ts: 智能提交消息生成
- 增强 manager.ts: 支持三种恢复模式、unrevert 撤销回滚

Server 层:
- 添加 checkpoints.ts: 16个 REST API 端点
  - GET/POST /checkpoints: 列表/创建检查点
  - GET/DELETE /checkpoints/🆔 获取/删除检查点
  - GET /checkpoints/:id/diff: 获取差异
  - POST /checkpoints/:id/restore: 恢复到检查点
  - POST /checkpoints/unrevert: 撤销回滚
  - GET /checkpoints/:id/safety-check: 安全检查

UI 层:
- 添加 CheckpointPanel.tsx: 检查点列表面板
- 添加 CheckpointDiffViewer.tsx: 差异查看器
- 添加 RestoreDialog.tsx: 恢复确认对话框
- 添加 16 个 API 客户端函数
- 添加完整的 TypeScript 类型定义

Web/Desktop 集成:
- 添加 History 按钮到工具栏
- 集成 CheckpointPanel 组件
2025-12-12 22:52:27 +08:00
kurihada a225e66ad7 feat(agents): 添加 Agent 预设管理功能
- 创建 Server Agents API 路由 (CRUD + presets + defaults)
- 添加 UI Agent 类型定义和 API 客户端函数
- 实现 AgentsPanel 组件 (预设/自定义 Agent 列表)
- 实现 AgentEditor 组件 (创建/编辑 Agent)
- 实现 AgentDefaultsEditor 组件 (全局默认配置)
- 集成 AgentsPanel 到 Web 和 Desktop 应用
2025-12-12 21:23:01 +08:00
kurihada 9365e07df1 feat(hooks): 添加 Hooks 配置管理功能
- 新增 Server Hooks API 路由 (CRUD + 测试执行)
- 新增 HooksPanel 组件用于管理所有钩子类型
- 新增 HookEditor 组件用于编辑单个钩子规则
- 支持 file_edited/file_created/file_deleted/session_completed 四种钩子
- 集成到 web 和 desktop 应用
2025-12-12 21:02:06 +08:00
kurihada 622bd869f9 docs: 添加选择性构建规则到 CLAUDE.md 2025-12-12 20:42:11 +08:00
kurihada bad7bfcc36 feat(mcp): 添加 MCP 服务器管理功能
- 新增 Server MCP API 路由 (/api/mcp/*)
  - GET /servers - 获取所有服务器状态
  - POST /servers/:name/connect|disconnect|enable|disable
  - GET /tools - 获取所有 MCP 工具
  - GET /config - 获取 MCP 配置

- 新增 UI MCPPanel 组件
  - 显示服务器列表和状态指示灯
  - 支持连接/断开/启用/禁用操作
  - 展开查看服务器配置和工具列表
  - 响应式设计支持移动端

- 集成到 Web 和 Desktop
  - 添加 Plug 图标按钮到工具栏
  - 点击打开 MCP 管理面板
2025-12-12 20:41:49 +08:00
kurihada 5a482f78ff feat(ui): 集成命令管理面板到 web 和 desktop
- 新增 CommandPanel 组件用于命令列表/搜索/CRUD
- 新增 CommandEditor 组件用于命令编辑/创建
- web/desktop 工具栏添加 Terminal 图标按钮
- 点击按钮打开命令管理面板
2025-12-12 20:15:24 +08:00
kurihada 2973369778 feat(cli): 添加命令 CRUD API 方法 2025-12-12 18:53:25 +08:00
kurihada f0385ef221 feat(commands): 实现命令 CRUD 完整功能
Core:
- 新增 CommandManager 类,支持创建、更新、删除命令
- 验证命令名称防止路径遍历攻击
- 自动生成 Markdown 文件(含 YAML frontmatter)
- 内置命令保护(不可修改/删除)

Server:
- POST /api/commands - 创建命令
- GET /api/commands/:name/content - 获取命令完整内容
- PUT /api/commands/:name - 更新命令
- DELETE /api/commands/:name - 删除命令

UI:
- 新增 createCommand、updateCommand、deleteCommand、getCommandContent 函数
- 新增 CreateCommandInput、UpdateCommandInput、CommandContent 类型
2025-12-12 18:51:38 +08:00
kurihada db711648e0 feat(ui): 添加斜杠命令输入支持
- 新增 useCommands hook 用于加载和搜索命令
- 新增 CommandMenu 组件,支持键盘导航和选择
- ChatInput 支持 / 触发命令菜单
- 导出命令相关 API 和类型
2025-12-12 18:38:43 +08:00
kurihada c25faa13b5 fix(core): 导出命令系统函数供 Server 使用 2025-12-12 18:29:24 +08:00
kurihada 61735317a0 feat(server): 添加统一命令系统 API
- 新增 /api/commands 路由,支持列出、查询、执行和搜索命令
- Server 通过动态导入 Core 的 CommandRegistry 和 CommandExecutor
- CLI、Web、Desktop 客户端均可通过 REST API 访问斜杠命令
- 支持三层命令优先级: project > user > builtin
2025-12-12 18:24:04 +08:00
kurihada ada9f890c6 fix(ui): 修复响应式侧边栏重复渲染问题
移动端抽屉和桌面端侧边栏分别用 md:hidden 和 hidden md:flex 控制显示
2025-12-12 17:59:08 +08:00
kurihada 3ccc47ca5a fix(ui): 修复删除按钮图标不显示问题
移除 motion.button 的 initial opacity 设置,避免覆盖 CSS hover 样式
2025-12-12 17:56:47 +08:00
kurihada 65a23f1e71 feat: 添加会话标题自动生成功能
- 后端:首次 AI 回复后自动从用户消息提取标题
- 后端:通过 WebSocket 推送 session_updated 事件
- 前端:useChat hook 处理标题更新事件
- 前端:Sidebar 组件实时更新会话标题显示
2025-12-12 17:45:17 +08:00
kurihada f561687307 feat(ui): 添加 Markdown 渲染和代码高亮功能
- 新增 CodeBlock 组件,使用 Shiki 语法高亮
- 新增 Markdown 组件,支持 GFM 语法
- AI 消息自动渲染 Markdown,用户消息保持原样
- 代码块支持一键复制和语言标签显示
2025-12-12 17:32:25 +08:00
kurihada cbbe9c7af1 feat(ui): 集成 shadcn/ui 原语、Framer Motion 动画和 Sonner Toast
- 添加 shadcn/ui 风格原语组件 (Button, Input, Dialog, Select, Slider, Switch, Tooltip)
- 集成 Framer Motion 动画库,添加动画预设
- 集成 Sonner Toast 通知系统
- 改造 ChatMessage 添加淡入动画和复制按钮
- 改造 Sidebar 添加动画、空状态引导和骨架屏
- 改造 ConfigPanel 使用新原语组件
- 优化 Chat 页面空状态和连接状态指示器
- 添加 tailwindcss-animate 插件
2025-12-12 17:20:41 +08:00
kurihada 67c6918b28 refactor(ui): 将工具栏按钮移入 Chat Header
- 移除 App.tsx 中 absolute 定位的悬浮按钮
- 将设置和文件浏览器按钮移入 Chat Header
- 通过 props 传递按钮状态和回调函数
- 修复 tsconfig.json 的 include 配置错误
2025-12-12 16:34:06 +08:00
kurihada 68ab6a2016 feat(ui): 创建共享 UI 组件包
将 web 和 desktop 的重复代码抽取到 @ai-assistant/ui 包:

- 添加可配置的 API 客户端 (configureApiClient)
- 迁移共享组件: ChatMessage, ChatInput, Sidebar, FileBrowser, ConfigPanel
- 迁移共享 hook: useChat
- 添加 responsive prop 支持响应式布局
- 更新 web/desktop 依赖并删除重复代码
2025-12-12 15:52:53 +08:00
kurihada 563224fa73 docs: 添加中文文档 2025-12-12 15:31:38 +08:00