diff --git a/desktop/README.md b/desktop/README.md new file mode 100644 index 00000000..eeb617ba --- /dev/null +++ b/desktop/README.md @@ -0,0 +1,30 @@ +# Claude Code Haha Desktop + +基于 Tauri 2 + React 的桌面客户端。 + +## 开发 + +```bash +bun install +bun run tauri dev +``` + +## 构建 + +```bash +# macOS (Apple Silicon) +./scripts/build-macos-arm64.sh + +# Windows (x64) +.\scripts\build-windows-x64.ps1 +``` + +构建产物位于 `build-artifacts/` 目录。 + +## 常见问题 + +### macOS 提示"已损坏,无法打开" + +```bash +xattr -cr /Applications/Claude\ Code\ Haha.app +``` diff --git a/desktop/scripts/build-macos-arm64.sh b/desktop/scripts/build-macos-arm64.sh index ee211a25..b4773dfb 100755 --- a/desktop/scripts/build-macos-arm64.sh +++ b/desktop/scripts/build-macos-arm64.sh @@ -137,19 +137,59 @@ build_canonical_dmg() { local app_bundle="$1" local dmg_output="$2" local staging_dir + local rw_dmg staging_dir="$(mktemp -d "${TMPDIR:-/tmp}/cc-haha-dmg.XXXXXX")" + rw_dmg="$(mktemp "${TMPDIR:-/tmp}/cc-haha-rw.XXXXXX").dmg" + cp -R "${app_bundle}" "${staging_dir}/" ln -s /Applications "${staging_dir}/Applications" + # Create a read-write DMG first so we can customize the Finder layout hdiutil create \ -volname "Claude Code Haha" \ -srcfolder "${staging_dir}" \ -ov \ - -format UDZO \ - "${dmg_output}" >/dev/null + -format UDRW \ + "${rw_dmg}" >/dev/null rm -rf "${staging_dir}" + + # Mount the read-write DMG and apply Finder layout via AppleScript + local dev_name mount_dir + dev_name=$(hdiutil attach -readwrite -noverify -noautoopen -nobrowse "${rw_dmg}" \ + | grep -E '^/dev/' | head -1 | awk '{print $1}') + mount_dir=$(hdiutil info | grep -E "${dev_name}" | tail -1 | awk '{$1=$2=""; print}' | xargs) + + # Use AppleScript to set icon positions and window size + osascript </dev/null + rm -f "${rw_dmg}" } if [[ -n "${LATEST_DMG}" ]]; then diff --git a/docs/desktop/01-quick-start.md b/docs/desktop/01-quick-start.md index 597c472a..4e46bd94 100644 --- a/docs/desktop/01-quick-start.md +++ b/docs/desktop/01-quick-start.md @@ -6,12 +6,12 @@ 界面布局 · 对话操作 · 多标签系统 · 权限控制 · 项目管理 · 模型与提供商 · IM 适配器 · 定时任务

-![桌面端界面总览](./images/01-desktop-overview.png) - --- ## 一、界面布局 +![桌面端界面总览](../images/desktop_ui/01_full_ui.png) + 桌面端采用**三栏 + 标签页**的经典 IDE 布局,从左到右分为: | 区域 | 位置 | 功能 | @@ -72,6 +72,8 @@ ### 斜杠命令 +![斜杠命令菜单](../images/desktop_ui/09_slash_command.png) + 输入 `/` 触发命令自动补全菜单: ``` @@ -89,6 +91,8 @@ ### @ 文件引用 +![文件搜索菜单](../images/desktop_ui/09_file_search.png) + 输入 `@` 触发文件搜索菜单,快速将文件引入对话上下文: - 支持路径和文件名自动补全 @@ -168,6 +172,8 @@ AI 回复时实时流式展示,支持: ## 四、权限控制 +![权限请求与 AI 提问](../images/desktop_ui/03_ask_question_and_permission.png) + Claude Code 在执行文件修改、Shell 命令等操作前,会请求你的权限。 ### 权限请求对话框 diff --git a/docs/desktop/02-architecture.md b/docs/desktop/02-architecture.md index 7cbdd096..7e318966 100644 --- a/docs/desktop/02-architecture.md +++ b/docs/desktop/02-architecture.md @@ -1,834 +1,379 @@ -# Claude Code 桌面端 — 架构设计 +# 架构设计 -> 从 Tauri 窗口到 CLI 子进程,深入理解桌面端的三层通信架构。 - -

-技术栈 · 三层架构 · WebSocket 协议 · HTTP API · 状态管理 · 会话生命周期 · 协议转换 · 适配器架构 -

- -![技术栈全景](./images/02-tech-stack.png) +> 从 Tauri 窗口到 CLI 子进程,桌面端的三层通信架构。 --- -## 一、技术栈全景 +## 技术栈 -Claude Code 桌面端的技术选型强调**轻量、高性能、跨平台**: - -### 前端层 +### 前端 | 技术 | 版本 | 职责 | |------|------|------| -| **React** | 18.3.1 | UI 框架,函数式组件 + Hooks | -| **Zustand** | 5.0.3 | 轻量级状态管理,零样板代码 | -| **Vite** | 6.0.7 | 构建工具,HMR 热更新 | -| **Tailwind CSS** | 4.0 | 原子化样式框架 | -| **Shiki** | 4.0.2 | VS Code 级别代码语法高亮 | -| **react-diff-viewer** | 4.2.0 | Diff 变更展示 | -| **marked** | 15.0.7 | Markdown 解析渲染 | +| React | 18 | UI 框架 | +| Zustand | 5 | 状态管理 | +| Vite | 6 | 构建工具 | +| Tailwind CSS | 4 | 样式 | +| Shiki | 4 | 代码高亮 | +| Mermaid | 11 | 图表渲染 | +| marked + DOMPurify | - | Markdown 渲染 | +| react-diff-viewer | 4 | Diff 展示 | +| Lucide React | - | 图标 | ### 桌面层 | 技术 | 版本 | 职责 | |------|------|------| -| **Tauri** | 2.x | 跨平台桌面框架(Rust) | -| **tauri-plugin-shell** | 2.x | Sidecar 进程管理 | -| **tauri-plugin-dialog** | 2.x | 原生文件选择对话框 | -| **tauri-plugin-process** | 2.x | 进程生命周期管理 | +| Tauri | 2 | 跨平台桌面框架 (Rust) | +| tauri-plugin-shell | 2 | Sidecar 进程管理 | +| tauri-plugin-dialog | 2 | 原生对话框 | +| tauri-plugin-process | 2 | 进程生命周期 | +| tauri-plugin-updater | 2 | 自动更新 | -### 服务端层 +### 服务端 | 技术 | 职责 | |------|------| -| **Bun** | JavaScript/TypeScript 运行时 + 构建工具 | -| **Bun.serve** | HTTP/WebSocket 服务器 | -| **Zod** | 请求参数校验 | +| Bun | 运行时 + 构建工具 | +| Bun.serve | HTTP/WebSocket 服务器 | -### 字体系统 +### 字体 -桌面端自托管所有字体,无需 CDN 依赖: - -- **Inter** (400-600) — 正文 -- **Manrope** (400-800) — 标题 +- **Inter** — 正文 +- **Manrope** — 标题 - **JetBrains Mono** — 代码 - **Material Symbols Outlined** — 图标 --- -## 二、三层架构 - -![三层架构图](./images/03-three-layer-arch.png) - -桌面端采用**三层架构**设计,各层职责明确: +## 三层架构 ``` -┌─────────────────────────────────┐ -│ Tauri 主进程 (Rust) │ -│ ┌───────────────────────────┐ │ -│ │ WebView (React App) │ │ ← 用户看到的界面 -│ │ Port 1420 (开发) / 内置 │ │ -│ └───────────┬───────────────┘ │ -│ │ HTTP + WebSocket │ -│ ┌───────────▼───────────────┐ │ -│ │ Sidecar: claude-server │ │ ← Bun 编译的服务端二进制 -│ │ Port: 动态分配 │ │ -│ └───────────┬───────────────┘ │ -│ │ 子进程 spawn │ -│ ┌───────────▼───────────────┐ │ -│ │ CLI 子进程 (claude-cli) │ │ ← 实际执行 AI 对话和工具调用 -│ │ stdin/stdout 通信 │ │ -│ └───────────────────────────┘ │ -└─────────────────────────────────┘ +┌─────────────────────────────────────┐ +│ Tauri 主进程 (Rust) │ +│ ┌─────────────────────────────┐ │ +│ │ WebView (React App) │ │ ← 用户界面 +│ └───────────┬─────────────────┘ │ +│ │ HTTP + WebSocket │ +│ ┌───────────▼─────────────────┐ │ +│ │ Server Sidecar (Bun) │ │ ← API 服务 + 会话管理 +│ │ Port: 动态分配 │ │ +│ └───────────┬─────────────────┘ │ +│ │ 子进程 spawn │ +│ ┌───────────▼─────────────────┐ │ +│ │ CLI 子进程 │ │ ← AI 对话 + 工具执行 +│ └─────────────────────────────┘ │ +│ │ +│ ┌─────────────────────────────┐ │ +│ │ Adapter Sidecar (可选) │ │ ← Telegram/飞书接入 +│ └─────────────────────────────┘ │ +└─────────────────────────────────────┘ ``` ### 第一层:Tauri 主进程 -**职责**:窗口管理、进程编排、原生 API 桥接 +**职责**:窗口管理、Sidecar 进程编排、原生 API 桥接 -关键文件:`desktop/src-tauri/src/lib.rs` +核心文件 `desktop/src-tauri/src/lib.rs`,暴露两个 Tauri Command: -```rust -// 核心功能 -fn reserve_local_port() -> u16 // 获取空闲端口 -fn wait_for_server(port) -> bool // 等待服务就绪(超时 10 秒) -fn start_server_sidecar(port) // 启动 Server 后台进程 -fn stop_server_sidecar() // 停止 Server 后台进程 +| Command | 说明 | +|---------|------| +| `get_server_url` | 前端获取 Server Sidecar 的 HTTP 地址 | +| `restart_adapters_sidecar` | 热重启 Adapter Sidecar(修改配置后生效) | -// Tauri 命令(暴露给前端调用) -#[tauri::command] -fn get_server_url() -> String // 返回 http://127.0.0.1:{port} -``` +**状态管理**: -启动流程: -1. Tauri 主进程启动 -2. 调用 `reserve_local_port()` 获取空闲端口 -3. 启动 `claude-server` sidecar 进程,传入端口号 -4. 调用 `wait_for_server()` 轮询等待服务就绪 -5. WebView 加载 React 应用 -6. 前端调用 `get_server_url` 获取服务地址 +| Struct | 说明 | +|--------|------| +| `ServerState` | `Mutex` — 含 server URL 和 Child 进程 handle | +| `AdapterState` | `Mutex>` — adapter 子进程 handle | + +**启动流程**: + +1. `reserve_local_port()` — 绑定 `127.0.0.1:0` 获取 OS 随机端口,再释放 +2. `start_server_sidecar(port)` — 启动 `claude-sidecar server --host 127.0.0.1 --port {port}` +3. `wait_for_server()` — TCP 探活轮询,150ms 间隔,10s 超时 +4. WebView 加载 React 应用 +5. `start_adapters_sidecar()` — 启动 `claude-sidecar adapters --feishu --telegram`,注入 `ADAPTER_SERVER_URL` 环境变量 + +**退出处理**:`RunEvent::Exit` / `ExitRequested` 时自动 kill 两个 sidecar。 + +**平台差异**: +- **macOS**:overlay titlebar + 自定义菜单(关于、设置 Cmd+,、编辑、窗口) +- **Windows**:`set_decorations(false)` 隐藏原生标题栏,前端自定义渲染 `TitleBar` + `WindowControls` ### 第二层:Server Sidecar -**职责**:HTTP API + WebSocket 网关 + 会话管理 + 代理转换 +**职责**:HTTP REST API + WebSocket 网关 + 会话管理 + 协议代理 -关键文件:`src/server/index.ts` +核心文件 `src/server/`(项目根目录),分层结构: -```typescript -// 服务器启动 -Bun.serve({ - port: config.port, - fetch(req, server) { - // HTTP 路由 + WebSocket 升级 - if (url.pathname.startsWith('/ws/')) { - server.upgrade(req, { data: { sessionId } }) - return - } - return router.handle(req) - }, - websocket: { - open(ws) { /* 连接建立 */ }, - message(ws, msg) { /* 消息处理 */ }, - close(ws) { /* 连接关闭 */ } - } -}) ``` - -Server 提供两类服务: -- **HTTP REST API** — 会话管理、配置读写、模型操作 -- **WebSocket** — 实时消息通道(对话流、权限请求、状态推送) +src/server/ +├── index.ts # 入口 +├── server.ts # HTTP 服务器 +├── router.ts # 路由注册 +├── sessionManager.ts # 会话管理器 +├── api/ # REST 路由层 (14 个模块) +├── services/ # 业务服务层 (14 个模块) +├── ws/ # WebSocket 处理 +├── proxy/ # API 代理(Anthropic/OpenAI 协议转换) +├── middleware/ # auth、cors、errorHandler +└── config/ # Provider 预设 +``` ### 第三层:CLI 子进程 -**职责**:AI 对话核心逻辑、工具执行、Agent 编排 +**职责**:AI 对话核心、工具执行、Agent 编排 -Server 为每个 Session 创建一个 CLI 子进程: - -```typescript -// 创建 CLI 子进程 -const child = spawn('claude-cli', ['--session', sessionId], { - cwd: workDir, - env: { ...process.env, ANTHROPIC_AUTH_TOKEN: token } -}) - -// 通过 stdin/stdout 通信 -child.stdin.write(JSON.stringify({ type: 'user_message', content })) -child.stdout.on('data', (chunk) => { - // 解析 stream_event,转发给 WebSocket 客户端 -}) -``` +Server 为每个 Session spawn 一个 CLI 子进程,通过 stdin/stdout JSON 通信。 ### Sidecar 构建 -使用 Bun 将 TypeScript 编译为独立可执行文件: +使用 Bun 编译为独立二进制(`desktop/scripts/build-sidecars.ts`): -```typescript -// desktop/scripts/build-sidecars.ts -// 支持 8 种目标平台: -const targets = [ - 'bun-darwin-arm64', // M1/M2 Mac - 'bun-darwin-x64', // Intel Mac - 'bun-windows-x64', // Windows x64 - 'bun-windows-arm64', // Windows ARM - 'bun-linux-x64', // Linux x64 - 'bun-linux-arm64', // Linux ARM - 'bun-linux-x64-musl', // Alpine Linux - 'bun-linux-arm64-musl', // Alpine ARM -] -``` +三种模式共用一个入口 `desktop/sidecars/claude-sidecar.ts`: +- `server` — 启动 HTTP/WS 服务 +- `cli` — 启动 CLI 子进程 +- `adapters` — 启动 IM 适配器(解析 `--feishu`/`--telegram` 参数,检查凭据后按需加载) 编译产物放置在 `desktop/src-tauri/binaries/`,Tauri 打包时自动包含。 --- -## 三、WebSocket 通信协议 +## WebSocket 通信协议 -![WebSocket 通信协议](./images/04-websocket-protocol.png) - -WebSocket 是桌面端与服务端实时通信的核心通道。 - -### 连接建立 +### 连接地址 ``` ws://127.0.0.1:{port}/ws/{sessionId} ``` -前端通过 `wsManager`(单例)管理所有 WebSocket 连接: +前端通过 `WebSocketManager`(per-session 连接)管理,支持自动重连、消息队列缓冲、ping 心跳保活。 -```typescript -// desktop/src/api/websocket.ts -class WebSocketManager { - private connections = new Map() - - connect(sessionId: string): void { - const ws = new WebSocket(`${baseUrl}/ws/${sessionId}`) - // 自动重连(指数退避) - // 消息队列(连接未就绪时缓冲) - // 心跳 ping(30 秒间隔) - } -} -``` +### 客户端 → 服务端 -### 客户端 → 服务端消息 +| type | 说明 | +|------|------| +| `user_message` | 用户消息(含 content, attachments) | +| `permission_response` | 权限审批(requestId, allowed, rule) | +| `set_permission_mode` | 切换权限模式 | +| `stop_generation` | 停止生成 | +| `ping` | 心跳 | -| type | 字段 | 说明 | -|------|------|------| -| `user_message` | `content`, `attachments?` | 用户发送消息 | -| `permission_response` | `requestId`, `allowed`, `rule?` | 权限审批响应 | -| `set_permission_mode` | `mode` | 切换权限模式 | -| `stop_generation` | — | 停止当前生成 | -| `ping` | — | 心跳保活 | +### 服务端 → 客户端 -### 服务端 → 客户端消息 - -| type | 关键字段 | 说明 | -|------|----------|------| -| `connected` | `sessionId` | 连接成功确认 | -| `status` | `state`, `verb?`, `elapsed?` | 状态变更(thinking/generating) | -| `content_start` | `blockType` | 内容块开始(text/tool_use) | -| `content_delta` | `text?`, `toolInput?` | 增量内容(流式文本) | -| `thinking` | `text` | Extended Thinking 内容 | -| `tool_use_complete` | `toolName`, `input` | 工具调用准备就绪 | -| `tool_result` | `output`, `isError` | 工具执行结果 | -| `permission_request` | `toolName`, `input`, `requestId` | 权限请求 | -| `message_complete` | `usage: TokenUsage` | 消息完成(含 Token 统计) | -| `error` | `message`, `code` | 错误通知 | -| `session_title_updated` | `title` | 会话标题更新 | -| `team_update` | `team` | 团队状态变更 | -| `team_created` / `team_deleted` | `teamName` | 团队创建/删除 | -| `task_update` | `task` | 任务状态变更 | -| `pong` | — | 心跳响应 | - -### 完整消息流示例 - -一条用户消息从发送到收到完整回复的流程: - -``` -用户输入 "写一个排序函数" - ↓ -ChatInput → chatStore.sendMessage() - ↓ -wsManager.send({ type: 'user_message', content: '...' }) - ↓ -Server 收到 → 转发到 CLI 子进程 - ↓ -CLI 开始处理,流式返回事件: - -← { type: 'status', state: 'thinking' } - → UI 显示"思考中..."动画 - -← { type: 'thinking', text: '让我分析...' } - → ThinkingBlock 展示推理过程 - -← { type: 'content_start', blockType: 'text' } - → 准备接收文本内容 - -← { type: 'content_delta', text: 'def sort(' } -← { type: 'content_delta', text: 'arr):\n' } -← { type: 'content_delta', text: ' return sorted(arr)' } - → AssistantMessage 流式渲染,闪烁光标 - -← { type: 'content_start', blockType: 'tool_use' } - → 准备接收工具调用 - -← { type: 'tool_use_complete', toolName: 'Write', input: {...} } - → ToolCallBlock 展示文件写入操作 - -← { type: 'permission_request', toolName: 'Write', requestId: '...' } - → PermissionDialog 弹出,等待用户审批 - -用户点击"允许" - ↓ -→ { type: 'permission_response', requestId: '...', allowed: true } - -← { type: 'tool_result', output: '文件已写入' } - → ToolResultBlock 展示结果 - -← { type: 'message_complete', usage: { input: 1200, output: 350 } } - → 更新 Token 统计,清除流式状态 -``` +| type | 说明 | +|------|------| +| `connected` | 连接成功 | +| `status` | 状态变更(thinking/generating) | +| `content_start` / `content_delta` | 流式文本 | +| `thinking` | Extended Thinking | +| `tool_use_complete` | 工具调用就绪 | +| `tool_result` | 工具执行结果 | +| `permission_request` | 权限请求 | +| `message_complete` | 消息完成(含 Token 统计) | +| `error` | 错误通知 | +| `session_title_updated` | 标题更新 | +| `team_update` / `team_created` / `team_deleted` | 团队事件 | +| `task_update` | 任务变更 | +| `pong` | 心跳响应 | ### 连接管理 -**心跳保活**:每 30 秒发送 `ping`,服务端回复 `pong` - -**自动重连**:指数退避策略 - -``` -重连间隔 = min(1000ms × 2^(attempt-1), 30000ms) -最大重连次数 = 10 -``` - -**消息缓冲**:WebSocket 未就绪时,消息暂存队列,连接恢复后自动发送。 +- **心跳**:30s 间隔 ping/pong +- **重连**:指数退避 `min(1000ms × 2^n, 30000ms)`,最多 10 次 +- **缓冲**:未连接时消息暂存队列,恢复后自动发送 --- -## 四、HTTP API 端点 +## HTTP API -Server 提供完整的 RESTful API,供前端和适配器调用。 - -### 会话管理 +### 会话 | 方法 | 端点 | 说明 | |------|------|------| -| `GET` | `/api/sessions` | 获取会话列表 | -| `POST` | `/api/sessions` | 创建新会话 | -| `GET` | `/api/sessions/:id` | 获取会话详情 | -| `PATCH` | `/api/sessions/:id` | 重命名会话 | -| `DELETE` | `/api/sessions/:id` | 删除会话 | -| `GET` | `/api/sessions/:id/messages` | 获取历史消息 | -| `GET` | `/api/sessions/:id/git-info` | 获取 Git 信息 | -| `GET` | `/api/sessions/:id/slash-commands` | 获取可用斜杠命令 | -| `GET` | `/api/sessions/recent-projects` | 最近项目列表 | +| `GET` | `/api/sessions` | 列表(支持 project/limit/offset 筛选) | +| `POST` | `/api/sessions` | 创建 | +| `GET` | `/api/sessions/:id/messages` | 历史消息 | +| `PATCH` | `/api/sessions/:id` | 重命名 | +| `DELETE` | `/api/sessions/:id` | 删除 | +| `GET` | `/api/sessions/:id/git-info` | Git 信息 | +| `GET` | `/api/sessions/:id/slash-commands` | 可用斜杠命令 | +| `GET` | `/api/sessions/recent-projects` | 最近项目 | ### 模型与提供商 | 方法 | 端点 | 说明 | |------|------|------| +| `GET/PUT` | `/api/models/current` | 当前模型 | | `GET` | `/api/models` | 可用模型列表 | -| `GET` | `/api/models/current` | 当前使用的模型 | -| `POST` | `/api/models/:id/set-current` | 切换模型 | -| `GET/POST` | `/api/models/effort` | 获取/设置 Effort 级别 | -| `GET` | `/api/providers` | 提供商列表 | -| `POST` | `/api/providers` | 创建提供商 | -| `PUT` | `/api/providers/:id` | 更新提供商配置 | -| `DELETE` | `/api/providers/:id` | 删除提供商 | -| `POST` | `/api/providers/:id/activate` | 激活提供商 | +| `GET/PUT` | `/api/effort` | Effort 级别 | +| `GET/POST/PUT/DELETE` | `/api/providers` | 提供商 CRUD | +| `POST` | `/api/providers/:id/activate` | 激活 | | `POST` | `/api/providers/:id/test` | 测试连接 | -| `GET` | `/api/providers/presets` | 获取预设列表 | +| `GET` | `/api/providers/presets` | 预设列表 | ### 定时任务 | 方法 | 端点 | 说明 | |------|------|------| -| `GET` | `/api/scheduled-tasks` | 任务列表 | -| `POST` | `/api/scheduled-tasks` | 创建任务 | -| `PUT` | `/api/scheduled-tasks/:id` | 更新任务 | -| `DELETE` | `/api/scheduled-tasks/:id` | 删除任务 | +| `GET/POST/PUT/DELETE` | `/api/scheduled-tasks` | 任务 CRUD | | `POST` | `/api/scheduled-tasks/:id/run` | 手动运行 | -| `GET` | `/api/scheduled-tasks/runs` | 所有运行记录 | -| `GET` | `/api/scheduled-tasks/:id/runs` | 单任务运行记录 | - -### Agent 团队 - -| 方法 | 端点 | 说明 | -|------|------|------| -| `GET` | `/api/teams` | 团队列表 | -| `GET` | `/api/teams/:name` | 团队详情 | -| `GET` | `/api/teams/:name/members/:agentId/transcript` | 成员转录 | -| `DELETE` | `/api/teams/:name` | 删除团队 | +| `GET` | `/api/scheduled-tasks/runs` | 运行记录 | ### 其他 | 方法 | 端点 | 说明 | |------|------|------| -| `GET` | `/health` | 健康检查 | -| `GET/POST` | `/api/settings/permission-mode` | 权限模式 | -| `GET` | `/api/agents` | Agent 定义列表 | +| `GET` | `/api/teams` | Agent 团队 | +| `GET` | `/api/teams/:name/members/:agentId/transcript` | 成员转录 | +| `GET` | `/api/agents` | Agent 定义 | | `GET` | `/api/skills` | 技能列表 | -| `GET` | `/api/skills/detail` | 技能详情 | | `GET/PUT` | `/api/adapters` | 适配器配置 | +| `GET/PUT` | `/api/settings/user` | 用户设置 | +| `GET/PUT` | `/api/permissions/mode` | 权限模式 | +| `GET` | `/api/tasks/lists` | CLI 任务清单 | +| `GET` | `/health` | 健康检查 | --- -## 五、状态管理 +## 状态管理 -![会话生命周期](./images/05-session-lifecycle.png) +使用 Zustand,按领域拆分为 12 个 Store: -桌面端使用 **Zustand** 进行状态管理,按领域拆分为多个独立 Store。 +| Store | 核心状态 | +|-------|----------| +| `chatStore` | per-session 消息、流式状态、权限请求、Token 统计 | +| `sessionStore` | 会话列表、activeSessionId、项目筛选 | +| `tabStore` | 标签页顺序(localStorage 持久化) | +| `settingsStore` | 权限模式、当前模型、effort、语言 | +| `providerStore` | Provider 列表、activeId | +| `uiStore` | 主题、侧边栏、activeView、Toast、设置标签页 | +| `taskStore` | 定时任务、运行记录 | +| `teamStore` | 团队列表、成员转录轮询 | +| `agentStore` | Agent 定义列表 | +| `skillStore` | 技能元数据、详情 | +| `adapterStore` | 适配器配置、配对码 | +| `cliTaskStore` | per-session CLI 任务追踪 | -### Store 架构 +### 数据流 ``` -stores/ -├── chatStore.ts # 聊天状态(消息、流式、权限) 20KB -├── sessionStore.ts # 会话列表、创建、删除 -├── tabStore.ts # 标签页管理、顺序、持久化 5KB -├── settingsStore.ts # 全局设置(模型、权限、语言) -├── providerStore.ts # LLM 提供商配置 -├── uiStore.ts # UI 状态(主题、Toast、模态框) -├── taskStore.ts # 定时任务管理 -├── teamStore.ts # Agent 团队状态 -├── agentStore.ts # Agent 定义管理 -├── skillStore.ts # 技能库 -├── adapterStore.ts # 适配器配置 -└── cliTaskStore.ts # CLI 任务状态 +用户操作 → Component → Store → API/WebSocket → Server → Store → Component 重渲染 ``` -### chatStore 核心设计 +### 持久化 -`chatStore` 是最复杂的 Store,为**每个 Session 维护独立状态**: - -```typescript -type PerSessionState = { - messages: UIMessage[] // 消息列表 - chatState: 'idle' | 'thinking' | ... // 对话状态 - connectionState: ConnectionState // WebSocket 连接状态 - streamingText: string // 流式文本缓冲 - streamingToolInput: string // 工具输入流 - activeToolUseId: string | null // 当前工具调用 ID - activeToolName: string | null // 当前工具名称 - activeThinkingId: string | null // 当前思考块 ID - pendingPermission: PermissionRequest | null // 待决权限 - tokenUsage: TokenUsage // Token 使用统计 - elapsedSeconds: number // 经过时间 - statusVerb: string // 随机状态动词 - slashCommands: SlashCommand[] // 可用命令列表 -} -``` - -关键方法: - -| 方法 | 职责 | +| 数据 | 存储 | |------|------| -| `connectToSession(id)` | 建立 WebSocket 连接 | -| `disconnectSession(id)` | 断开连接 | -| `sendMessage(id, content, attachments)` | 发送用户消息 | -| `respondToPermission(id, requestId, allowed, rule)` | 权限审批 | -| `stopGeneration(id)` | 停止生成 | -| `loadHistory(id)` | 加载历史消息 | -| `handleServerMessage(id, msg)` | 处理服务端消息 | - -### 数据流向 - -``` -用户操作 - ↓ -Component (调用 Store 方法) - ↓ -Store (更新状态 + 调用 API/WebSocket) - ↓ -API 层 (HTTP 请求 / WebSocket 发送) - ↓ -Server 响应 - ↓ -Store (更新状态) - ↓ -Component (自动重渲染) -``` - -### 持久化策略 - -| 数据 | 存储位置 | 说明 | -|------|----------|------| -| 打开的标签页 | `localStorage` | 页面刷新/重启后恢复 | -| 会话数据 | Server JSONL 文件 | `~/.claude/sessions/` | -| 设置 | Server API | 通过 HTTP 读写 | -| 适配器配置 | `~/.claude/adapters.json` | JSON 文件 | -| 会话映射 | `~/.claude/adapter-sessions.json` | 适配器 Chat→Session 映射 | +| 标签页状态 | `localStorage` | +| 语言偏好 | `localStorage` | +| 会话数据 | Server JSONL (`~/.claude/sessions/`) | +| 设置 | Server API | +| 适配器配置 | `~/.claude/adapters.json` | --- -## 六、会话生命周期 +## 协议代理层 -一个会话从创建到恢复的完整流程: +Server 内置代理层(`src/server/proxy/`),统一不同 AI 提供商的 API 格式。 -### 创建 +### 支持格式 -``` -用户点击 + 新建会话 - ↓ -sessionStore.createSession({ workDir }) - ↓ -POST /api/sessions { workDir: '/path/to/project' } - ↓ -Server 创建 Session 记录 → 返回 { sessionId } - ↓ -tabStore.openTab(sessionId) - ↓ -chatStore.connectToSession(sessionId) - ↓ -WebSocket 连接 → 收到 { type: 'connected' } -``` - -### 交互 - -``` -用户发送消息 - ↓ -wsManager.send({ type: 'user_message', content }) - ↓ -Server 转发到 CLI 子进程 - ↓ -CLI 处理 → 流式返回 stream_event - ↓ -Server 转换为 ServerMessage → 推送到 WebSocket - ↓ -chatStore.handleServerMessage() → UI 更新 -``` - -### 断开 - -``` -用户关闭标签页 / 切换到其他标签 - ↓ -chatStore.disconnectSession(sessionId) - ↓ -WebSocket 关闭 - ↓ -CLI 子进程可能继续运行(后台任务) -``` - -### 恢复 - -``` -应用启动 / 切回标签页 - ↓ -tabStore.restoreTabs() // 从 localStorage 读取 - ↓ -验证会话是否仍存在 (GET /api/sessions) - ↓ -chatStore.connectToSession(sessionId) - ↓ -chatStore.loadHistory(sessionId) // GET /api/sessions/:id/messages - ↓ -WebSocket 重连 → 恢复实时通信 -``` - -### 会话持久化 - -Server 使用 **JSONL(JSON Lines)** 格式持久化会话数据: - -``` -~/.claude/sessions/ -├── {sessionId}/ -│ ├── messages.jsonl ← 流式追加,每行一条消息/事件 -│ ├── metadata.json ← 会话元数据(workDir、标题、模型等) -│ └── ... -``` - -JSONL 格式的优势: -- **流式追加**:新消息直接 append,无需重写整个文件 -- **崩溃恢复**:即使中途崩溃,已写入的行不会丢失 -- **大会话支持**:按行读取,无需一次性加载整个 JSON - ---- - -## 七、代理层协议转换 - -Server 内置了多协议代理层(Proxy),让不同 AI 提供商的 API 统一接入。 - -### 支持的 API 格式 - -| 格式 | 说明 | 典型提供商 | -|------|------|-----------| -| `anthropic` | Anthropic Messages API | Anthropic 官方、MiniMax | -| `openai_chat` | OpenAI Chat Completions | OpenAI、DeepSeek | -| `openai_responses` | OpenAI Responses API | OpenAI 新接口 | - -### 协议转换流程 - -``` -前端发送消息 - ↓ -Server 接收 - ↓ -判断当前 Provider 的 API 格式 - ↓ -┌─────────────────────────────────┐ -│ anthropic │ openai_chat/resp │ -│ 直接透传 │ 转换消息格式 │ -│ │ system → 系统消息 │ -│ │ tool_use → 函数调用 │ -│ │ tool_result → 函数结果│ -└──────┬──────┴──────┬────────────┘ - │ │ - ↓ ↓ - Anthropic API OpenAI API - │ │ - ↓ ↓ - 直接返回 反向转换响应格式 - │ │ - └──────┬──────┘ - ↓ - 统一的 ServerMessage 格式 - ↓ - WebSocket 推送给前端 -``` +| 格式 | 典型提供商 | +|------|-----------| +| `anthropic` | Anthropic、OpenRouter、MiniMax | +| `openai_chat` | OpenAI、DeepSeek、Ollama | +| `openai_responses` | OpenAI Responses API | ### 模型映射 -每个 Provider 可配置四个模型槽位: - -| 槽位 | 用途 | -|------|------| -| `main` | 主对话模型 | -| `haiku` | 快速/轻量任务 | -| `sonnet` | 中等复杂度 | -| `opus` | 最高能力 | - -例如 OpenRouter 配置: - -```json -{ - "apiFormat": "anthropic", - "baseUrl": "https://openrouter.ai/api/v1", - "modelMapping": { - "main": "anthropic/claude-sonnet-4-20250514", - "haiku": "anthropic/claude-haiku-4-5-20251001", - "opus": "anthropic/claude-opus-4-20250514" - } -} -``` +每个 Provider 配置 4 个模型槽位:`main`、`haiku`、`sonnet`、`opus`,前端按槽位名调用,代理层自动映射为实际模型名。 --- -## 八、适配器桥接架构 +## 适配器架构 -![适配器桥接架构](./images/07-adapter-bridge.png) - -适配器系统让**任何 IM 平台**都可以接入 Claude Code,无需修改核心代码。 - -### 整体架构 +适配器系统让 Telegram/飞书等 IM 平台接入 Claude Code。 ``` -┌──────────────┐ ┌──────────────┐ -│ Telegram │ │ 飞书 │ ← IM 平台 -│ grammy │ │ Lark SDK │ -└──────┬───────┘ └──────┬───────┘ - │ │ - ▼ ▼ -┌──────────────────────────────────┐ -│ Adapter 进程 │ ← 平台适配层 -│ ┌─────────────────────────────┐ │ -│ │ common/ 共享模块 │ │ -│ │ config │ ws-bridge │ │ -│ │ pairing │ message-buffer │ │ -│ │ dedup │ chat-queue │ │ -│ │ session │ http-client │ │ -│ └─────────────────────────────┘ │ -└──────────────┬───────────────────┘ - │ HTTP + WebSocket - ▼ -┌──────────────────────────────────┐ -│ Desktop Server │ ← 服务端 -│ POST /api/sessions │ -│ WS /ws/{sessionId} │ -└──────────────┬───────────────────┘ - │ - ▼ -┌──────────────────────────────────┐ -│ CLI 子进程 │ ← AI 对话引擎 -└──────────────────────────────────┘ +IM 平台 → Adapter 进程 → HTTP + WebSocket → Server → CLI ``` -### 四层架构 - -| 层级 | 职责 | 关键文件 | -|------|------|----------| -| **配置层** | 桌面端 UI 填写凭证 | `desktop/src/pages/AdapterSettings.tsx` | -| **存储层** | 配置读写和脱敏 | `src/server/services/adapterService.ts` | -| **适配层** | IM SDK 对接、消息路由 | `adapters/telegram/index.ts`, `adapters/feishu/index.ts` | -| **会话层** | WebSocket 桥接到 Server | `adapters/common/ws-bridge.ts` | - -### 共享模块 - -所有适配器共用 `adapters/common/` 模块: +### 共享模块 `adapters/common/` | 模块 | 职责 | |------|------| -| `config.ts` | 配置加载(环境变量 > JSON 文件 > 默认值) | -| `ws-bridge.ts` | WebSocket 连接管理(心跳、重连、消息路由) | +| `config.ts` | 配置加载(env > JSON > 默认值) | +| `ws-bridge.ts` | WebSocket 桥接(心跳、重连、消息路由) | | `pairing.ts` | 用户配对(6 位安全码、速率限制) | -| `session-store.ts` | Chat→Session 映射持久化 | -| `message-buffer.ts` | 流式消息缓冲(500ms/200 字符阈值刷新) | -| `message-dedup.ts` | 消息去重(防重连重复) | +| `session-store.ts` | Chat → Session 映射持久化 | +| `message-buffer.ts` | 流式缓冲(500ms / 200 字符阈值) | +| `message-dedup.ts` | 消息去重 | | `chat-queue.ts` | 同一 Chat 消息串行队列 | -| `http-client.ts` | HTTP 客户端(创建会话、获取项目列表) | +| `http-client.ts` | HTTP 客户端 | -### 接入新 IM 平台 +### 分片限制 -得益于模块化设计,接入新平台只需三步: - -**1. 创建适配器文件** - -```typescript -// adapters/discord/index.ts -import { WsBridge } from '../common/ws-bridge.js' -import { MessageBuffer } from '../common/message-buffer.js' -import { loadConfig } from '../common/config.js' -import { isPaired, tryPair } from '../common/pairing.js' -``` - -**2. 实现消息接收** - -```typescript -bot.on('message', async (msg) => { - // 去重 → 授权检查 → 会话管理 → WebSocket 桥接 - if (!dedup.tryRecord(msg.id)) return - if (!isPaired('discord', msg.author.id, config)) { - tryPair(msg.content, { userId: msg.author.id, ... }, 'discord') - return - } - bridge.sendUserMessage(chatId, msg.content) -}) -``` - -**3. 处理服务端事件** - -```typescript -bridge.onServerMessage(chatId, async (msg) => { - switch (msg.type) { - case 'content_delta': /* 流式文本 */ break - case 'permission_request': /* 权限按钮 */ break - case 'message_complete': /* 完成 */ break - } -}) -``` - -### 消息缓冲机制 - -为防止 IM 平台的消息频率限制,适配器使用 `MessageBuffer` 批量刷新: - -``` -content_delta: "def " ─┐ -content_delta: "sort(" │→ 缓冲累积 -content_delta: "arr):" │ - ↓ 500ms 或 200 字符 - IM 平台: "def sort(arr): ▍" (编辑消息) - -content_delta: "\n ..." ─┐ -content_delta: "return" │→ 继续缓冲 - ↓ - IM 平台: "def sort(arr):\n return ▍" - -message_complete ↓ - IM 平台: 最终完整文本(分片发送) -``` - -分片限制: - Telegram: 4000 字符/消息 - 飞书: 30000 字符/消息 --- -## 九、项目目录结构 +## 项目目录结构 ``` desktop/ -├── src/ # React 前端 -│ ├── App.tsx # 根组件 -│ ├── main.tsx # 入口 +├── src/ # React 前端 +│ ├── api/ # API 客户端 (15 个模块) │ ├── components/ -│ │ ├── layout/ # 布局:AppShell, Sidebar, TabBar -│ │ ├── chat/ # 聊天:MessageList, ChatInput, ToolCallBlock -│ │ ├── shared/ # 通用:Button, Modal, Toast, Spinner -│ │ ├── controls/ # 控件:ModelSelector, PermissionModeSelector -│ │ ├── markdown/ # MarkdownRenderer -│ │ ├── skills/ # 技能浏览 -│ │ ├── tasks/ # 任务管理 -│ │ └── teams/ # 团队视图 -│ ├── pages/ # 页面:ActiveSession, Settings, ScheduledTasks -│ ├── stores/ # Zustand 状态 -│ ├── api/ # HTTP + WebSocket 客户端 -│ ├── types/ # TypeScript 类型定义 -│ ├── hooks/ # 自定义 Hooks -│ ├── i18n/ # 国际化 -│ ├── theme/ # 全局样式 -│ ├── config/ # 提供商预设 -│ └── lib/ # 工具库 -├── src-tauri/ # Tauri Rust 后端 -│ ├── src/lib.rs # 核心:端口管理、Sidecar 启动 -│ ├── Cargo.toml # Rust 依赖 -│ └── tauri.conf.json # Tauri 配置 -├── sidecars/ # Sidecar 启动器 -│ └── claude-sidecar.ts # server/cli/adapters 三种模式 -├── scripts/ -│ └── build-sidecars.ts # 跨平台编译脚本 -├── vite.config.ts # Vite 构建配置 -├── package.json # 依赖和脚本 -└── tsconfig.json # TypeScript 配置 +│ │ ├── layout/ # AppShell, Sidebar, TabBar, TitleBar, +│ │ │ # WindowControls, StatusBar, ContentRouter, +│ │ │ # ProjectFilter +│ │ ├── chat/ # ChatInput, MessageList, AssistantMessage, +│ │ │ # ToolCallBlock, ToolCallGroup, ThinkingBlock, +│ │ │ # PermissionDialog, CodeViewer, DiffViewer, +│ │ │ # ImageGalleryModal, StreamingIndicator ... +│ │ ├── shared/ # Button, Modal, Toast, Spinner, +│ │ │ # UpdateChecker, DirectoryPicker ... +│ │ ├── controls/ # ModelSelector, PermissionModeSelector +│ │ ├── markdown/ # MarkdownRenderer, MermaidRenderer +│ │ ├── skills/ # SkillList, SkillDetail +│ │ ├── tasks/ # TaskList, TaskRow, NewTaskModal, +│ │ │ # DayOfWeekPicker, PromptEditor ... +│ │ └── teams/ # TeamStatusBar +│ ├── pages/ # ActiveSession, EmptySession, Settings, +│ │ # AdapterSettings, AgentTeams, ScheduledTasks, +│ │ # ComputerUseSettings, ToolInspection ... +│ ├── stores/ # 12 个 Zustand store +│ ├── types/ # TypeScript 类型 (9 个模块) +│ ├── hooks/ # useKeyboardShortcuts +│ ├── i18n/ # 中/英 国际化 +│ ├── config/ # providerPresets, spinnerVerbs +│ └── lib/ # desktopRuntime, cronDescribe, parseRunOutput +├── src-tauri/ +│ ├── src/main.rs # 入口 +│ ├── src/lib.rs # 核心(~415 行) +│ ├── Cargo.toml +│ └── tauri.conf.json +├── sidecars/ +│ └── claude-sidecar.ts # 统一入口 (server/cli/adapters) +└── scripts/ + ├── build-sidecars.ts + ├── build-macos-arm64.sh + └── build-windows-x64.ps1 -src/server/ # 服务端(独立于 desktop/) -├── index.ts # 入口:Bun.serve -├── router.ts # HTTP 路由 -├── ws/ # WebSocket 处理 -├── api/ # REST API 路由 -├── services/ # 业务服务 -├── proxy/ # 代理层(协议转换) -├── middleware/ # 中间件 -├── config/ # 服务端配置 -└── types/ # 类型定义 +src/server/ # 服务端(项目根目录) +├── api/ # REST 路由 (14 个模块) +├── services/ # 业务服务 (14 个模块) +├── ws/ # WebSocket 处理 +├── proxy/ # 协议代理转换 +├── middleware/ # auth, cors, errorHandler +└── config/ # Provider 预设 -adapters/ # 外部 IM 适配器 -├── common/ # 共享模块(9 个文件) -├── telegram/index.ts # Telegram Bot -├── feishu/index.ts # 飞书 Bot -└── package.json # 独立依赖 -``` - ---- - -## 十、快速参考 - -### 关键端口 - -| 端口 | 用途 | -|------|------| -| 1420 | Vite 开发服务器 | -| 动态分配 | Server Sidecar(`reserve_local_port`) | - -### 关键文件路径 - -| 文件 | 说明 | -|------|------| -| `~/.claude/adapters.json` | 适配器配置 | -| `~/.claude/adapter-sessions.json` | 适配器会话映射 | -| `~/.claude/sessions/` | 会话持久化数据 | - -### 开发命令 - -```bash -# 前端开发 -cd desktop && bun run dev - -# 编译 Sidecar -cd desktop && bun run build:sidecars - -# Tauri 开发模式(前端 + 桌面框架) -cd desktop && bunx tauri dev - -# 构建发布包 -cd desktop && bunx tauri build - -# 运行测试 -cd desktop && bun run test +adapters/ # IM 适配器 +├── common/ # 共享模块 (8 个) +├── telegram/ # Telegram Bot +└── feishu/ # 飞书 Bot ``` diff --git a/docs/desktop/03-features.md b/docs/desktop/03-features.md index 4e333119..d9c518be 100644 --- a/docs/desktop/03-features.md +++ b/docs/desktop/03-features.md @@ -1,763 +1,276 @@ -# Claude Code 桌面端 — 功能详解 +# 功能详解 -> 深入每一个功能模块,从聊天引擎到定时任务,全面解析桌面端的能力矩阵。 - -

-聊天引擎 · 工具调用 · 代码展示 · Agent Teams · 提供商管理 · 技能与 Agent · 定时任务 · IM 适配器 · 设计系统 -

- -![功能全景图](./images/06-features-grid.png) +> 桌面端核心功能模块一览。 --- -## 一、聊天引擎 +## 聊天引擎 -聊天引擎是桌面端的核心,负责消息的发送、接收、渲染和交互。 +![任务列表与工具调用](../images/desktop_ui/04_tasktodo_list.png) -### 消息列表(MessageList) +聊天引擎是桌面端核心,负责消息收发、流式渲染和工具交互。 -**文件位置**:`desktop/src/components/chat/MessageList.tsx` +### 消息类型 -消息列表是对话的主展示区域: +| 类型 | 组件 | 说明 | +|------|------|------| +| 用户消息 | `UserMessage` | 文本 + 附件画廊 | +| 助手消息 | `AssistantMessage` | Markdown 渲染 + 流式光标 `▍` | +| 思考块 | `ThinkingBlock` | Extended Thinking,默认折叠 | +| 工具调用 | `ToolCallBlock` / `ToolCallGroup` | 按工具类型专门展示 | +| 工具结果 | `ToolResultBlock` | 成功/失败状态 + 输出内容 | +| 权限请求 | `PermissionDialog` | 操作预览 + 允许/一直允许/拒绝 | +| AI 提问 | `AskUserQuestion` | AI 向用户提问的专用输入框 | +| 任务摘要 | `InlineTaskSummary` | 后台任务进度内联展示 | -- **自动滚动**:新消息到达时 smooth 滚动到底部 -- **消息分组**:Tool calls 和对应的 results 按组展示 -- **混合渲染**:支持文本、代码、Diff、工具调用等多种内容类型 +### 工具展示 -### 消息类型详解 +不同工具有专门的渲染方式: -#### 用户消息(UserMessage) +- **Bash** — `TerminalChrome` 终端风格,深色背景 + `$` 提示符 +- **Edit / Write** — `DiffViewer` 展示文件变更,词级别高亮 +- **Read** — `CodeViewer` 语法高亮 +- **Glob / Grep** — 搜索模式 + 匹配结果 +- **其他** — JSON 格式展示输入参数 -``` -┌──────────────────────────────┐ -│ 👤 写一个快速排序算法 │ -│ 📎 screenshot.png (附件) │ -│ [复制] │ -└──────────────────────────────┘ -``` +### 输入系统 -- 用户头像 + 消息文本 -- 附件画廊展示(图片缩略图、文件图标) -- 悬浮显示消息操作栏 +`ChatInput` 组合组件: -#### 助手消息(AssistantMessage) +- 自适应高度文本框(最高 200px) +- 附件画廊(粘贴图片 / 拖拽上传 / 文件选择) +- 项目上下文芯片(Git 仓库 + 分支) +- `/` 斜杠命令菜单(服务端动态提供,支持搜索) +- `@` 文件搜索菜单(路径自动补全) +- 图片画廊(`ImageGalleryModal` / `InlineImageGallery`) -``` -┌──────────────────────────────────┐ -│ ┌──────────────────────────────┐ │ -│ │ 好的,我来实现快速排序: │ │ -│ │ │ │ -│ │ ```python │ │ -│ │ def quicksort(arr): │ │ -│ │ if len(arr) <= 1: │ │ -│ │ return arr │ │ -│ │ ``` │ │ -│ │ [复制] ▍ │ │ -│ └──────────────────────────────┘ │ -└──────────────────────────────────┘ -``` +### 流式输出 -- 带边框的气泡容器 -- 完整 Markdown 渲染(标题、列表、表格、引用、链接) -- 代码块使用 Shiki 语法高亮 -- 流式输出时显示闪烁光标 `▍` - -#### 思考块(ThinkingBlock) - -``` -┌──────────────────────────────────┐ -│ 💭 思考过程 [展开 ▼] │ -│ │ -│ ┌──────────────────────────────┐ │ -│ │ 让我分析一下用户的需求... │ │ -│ │ 快速排序的时间复杂度是... │ │ -│ │ 我应该用 Lomuto 分区方案... │ │ -│ └──────────────────────────────┘ │ -└──────────────────────────────────┘ -``` - -- 默认折叠,显示第一行预览 -- 点击展开查看完整推理过程 -- 流式更新时显示动画光标 -- 自动滚动到最新思考内容 - -#### 权限请求(PermissionDialog) - -``` -┌──────────────────────────────────┐ -│ ⚠️ 权限请求 │ -│ │ -│ 工具: Write │ -│ 文件: /src/sort.py │ -│ │ -│ ┌──────────────────────────────┐ │ -│ │ + def quicksort(arr): │ │ -│ │ + if len(arr) <= 1: │ │ -│ │ + return arr │ │ -│ └──────────────────────────────┘ │ -│ │ -│ [允许] [一直允许] [拒绝] │ -└──────────────────────────────────┘ -``` - -- 显示工具类型和操作目标 -- 预览操作内容(Diff、命令等) -- 可展开查看完整输入参数 -- 三个操作按钮:允许 / 一直允许 / 拒绝 - -#### AskUser 提问 - -当 AI 使用 `AskUserQuestion` 工具向你提问时,会显示一个专用输入框,你的回答会直接发送给 AI。 - -#### 内联任务摘要(InlineTaskSummary) - -当 AI 创建后台任务时,对话中会内联显示任务的进度和结果摘要。 - -### 输入系统(ChatInput) - -**文件位置**:`desktop/src/components/chat/ChatInput.tsx` - -输入框是一个功能丰富的组合组件: - -``` -┌──────────────────────────────────┐ -│ 📎 screenshot.png × │ ← 附件画廊 -├──────────────────────────────────┤ -│ 🏷️ myproject (main) │ ← 项目上下文芯片 -├──────────────────────────────────┤ -│ │ -│ 输入消息... │ ← 可扩展文本框 -│ │ -├──────────────┬───────────────────┤ -│ [+] │ [发送] │ ← 工具栏 -└──────────────┴───────────────────┘ -``` - -**核心功能**: - -1. **自适应高度**:文本框随内容自动扩展,最高 200px -2. **附件画廊**:显示待发送的文件/图片 -3. **项目上下文芯片**:展示当前 Git 仓库和分支 -4. **Plus 菜单**:添加文件 / 插入斜杠命令 -5. **斜杠命令菜单**:`/` 触发,支持搜索和键盘导航 -6. **文件搜索菜单**:`@` 触发,路径自动补全 -7. **快捷键**:Enter 发送、Shift+Enter 换行、Esc 关闭菜单 +- Shiki 实时语法高亮 +- 闪烁光标动画 +- `StreamingIndicator` 状态指示 +- 随时可停止(`Cmd/Ctrl + .`) --- -## 二、工具调用系统 - -当 AI 执行工具操作时,桌面端会以结构化的方式展示工具调用和结果。 - -### 工具调用块(ToolCallBlock) - -**文件位置**:`desktop/src/components/chat/ToolCallBlock.tsx` - -每种工具有专门的展示方式: - -#### Bash 工具 - -``` -┌──────────────────────────────────┐ -│ 🖥️ Bash │ -│ │ -│ $ npm install express │ ← 终端风格 -│ │ -│ 说明: Install express package │ -│ [展开] │ -└──────────────────────────────────┘ -``` - -使用 `TerminalChrome` 组件模拟终端界面: -- 深色背景 -- 绿色提示符 `$` -- 显示命令内容和说明 - -#### Edit / Write 工具 - -``` -┌──────────────────────────────────┐ -│ ✏️ Edit src/app.ts │ -│ │ -│ ┌──────────────────────────────┐ │ -│ │ - const port = 3000 │ │ ← Diff 视图 -│ │ + const port = 8080 │ │ -│ └──────────────────────────────┘ │ -│ │ -│ +1 -1 行 │ -└──────────────────────────────────┘ -``` - -- 使用 `DiffViewer` 展示文件变更 -- 显示行数统计(+N / -N) -- 自动识别文件语言 -- 词级别 Diff 高亮 - -#### Read 工具 - -展示被读取的文件内容,使用 `CodeViewer` 语法高亮。 - -#### Glob / Grep 工具 - -展示搜索模式和匹配结果。 - -#### WebSearch / WebFetch 工具 - -展示搜索关键词或目标 URL。 - -#### 其他工具 - -以 JSON 格式展示工具的输入参数,可展开查看详情。 - -### 工具结果块(ToolResultBlock) - -工具执行后的输出展示: - -- **成功** → 绿色状态指示 + 输出内容 -- **错误** → 红色状态指示 + 错误信息 -- 输出以代码块展示,支持语法高亮 -- 超长输出自动截断,显示行数摘要 - ---- - -## 三、代码展示系统 - -桌面端在代码展示方面追求**VS Code 级别的体验**。 +## 代码展示 ### CodeViewer -**文件位置**:`desktop/src/components/chat/CodeViewer.tsx` - -- **引擎**:Shiki(与 VS Code 相同的语法高亮引擎) -- **主题**:自定义温暖色调主题,与应用设计系统匹配 -- **行号**:左侧行号显示 -- **折叠**:超过 20 行时自动折叠,点击展开 -- **复制**:右上角一键复制按钮 +基于 Shiki(VS Code 同款引擎),支持行号、超 20 行自动折叠、一键复制。 ### DiffViewer -**文件位置**:`desktop/src/components/chat/DiffViewer.tsx` - -- **引擎**:react-diff-viewer-continued -- **模式**:单列(split view 更紧凑) -- **高亮**:词级别变更高亮 -- **统计**:顶部显示 +N/-N 行数变化 -- **语言识别**:根据文件扩展名自动识别语言 +基于 react-diff-viewer-continued,单列模式,词级别变更高亮,自动识别文件语言。 ### MarkdownRenderer -**文件位置**:`desktop/src/components/markdown/MarkdownRenderer.tsx` +基于 marked + DOMPurify,代码块自动 Shiki 高亮,支持表格、列表、引用、链接。 -- 基于 `marked` 解析 Markdown -- 代码块自动使用 Shiki 高亮 -- 支持表格、列表、引用、链接 -- 内联代码和粗体/斜体 +### MermaidRenderer -### Mermaid 图表渲染 - -支持 Mermaid 图表实时渲染(`MermaidRenderer` 组件),使用 `securityLevel: 'strict'` 安全模式。支持流程图、时序图、甘特图、类图等所有 Mermaid 图表类型。渲染失败时自动回退显示源代码。 +支持流程图、时序图、甘特图等,`securityLevel: 'strict'`,渲染失败回退显示源码。 --- -## 四、Agent Teams 团队协作 +## 多标签系统 -![聊天消息流](./images/08-chat-message-flow.png) +- `Cmd/Ctrl + N` 新建标签 +- 拖拽排序、右键菜单(关闭当前/其他/左侧/右侧/全部) +- 标签状态:绿色脉冲 = 运行中,红色 = 出错 +- 关闭运行中标签需确认 +- 标签状态 localStorage 持久化,重启恢复 -桌面端可视化展示 Agent Teams 的协作状态。 +--- -### 团队视图(AgentTeams) +## 权限控制 -**文件位置**:`desktop/src/pages/AgentTeams.tsx` +### 四种模式 -当 AI 创建 Agent Team 时,桌面端显示团队管理界面: - -- **团队列表**:所有活跃团队 -- **成员状态**:每个 Agent 的实时状态 - -| 状态 | 指示 | +| 模式 | 说明 | |------|------| -| running | 绿色脉冲动画 | -| idle | 灰色 | -| completed | 完成标记 | -| error | 红色错误标记 | +| 询问权限 (default) | 每个操作需确认 | +| 自动接受 (acceptEdits) | 自动允许编辑 | +| 计划模式 (plan) | 只展示计划不执行 | +| 绕过权限 (bypassPermissions) | 全部自动(需二次确认) | -- **成员标签**:彩色标签显示 Agent 角色和名称 -- **实时更新**:通过 WebSocket 推送 `team_update` 事件 +### 权限请求对话框 -### 转录视图(AgentTranscript) - -点击团队成员可查看该 Agent 的完整对话转录: - -- 与主聊天相同的消息渲染 -- 支持查看工具调用和结果 -- 「返回团队」导航按钮 - -### TeamStatusBar - -**文件位置**:`desktop/src/components/teams/TeamStatusBar.tsx` - -在活跃会话底部展示团队状态条: -- 团队名称 -- 成员数量和状态分布 -- 快速导航到团队视图 +显示工具类型、操作预览(Diff/命令内容)、可展开详情。三个按钮:允许 / 一直允许 / 拒绝。 --- -## 五、提供商管理 +## Agent Teams -桌面端提供了完整的 AI 提供商管理界面。 +当 AI 创建 Agent Team 时,桌面端可视化展示协作状态。 -### 提供商列表 +- **团队视图** (`AgentTeams` 页面) — 团队列表 + 成员状态(running/idle/completed/error) +- **成员转录** — 点击成员查看完整对话记录(1.5s 轮询更新) +- **TeamStatusBar** — 活跃会话底部展示团队名称和成员状态 -**文件位置**:`desktop/src/pages/Settings.tsx`(Providers 标签页) +--- -展示所有已配置的提供商: +## 提供商管理 -``` -┌──────────────────────────────────┐ -│ ✅ Anthropic (Official) [活跃] │ ← 官方提供商 -├──────────────────────────────────┤ -│ 🔵 OpenRouter [编辑]│ ← 自定义提供商 -│ Base: openrouter.ai/api/v1 │ -│ Format: anthropic │ -├──────────────────────────────────┤ -│ ⚪ Ollama (Local) [编辑]│ ← 本地模型 -│ Base: localhost:11434 │ -│ Format: openai_chat │ -├──────────────────────────────────┤ -│ [+ 添加提供商] │ -└──────────────────────────────────┘ -``` +![提供商设置](../images/desktop_ui/05_settings.png) -### 提供商配置 +在设置 → Providers 标签页管理 AI 提供商。 -每个提供商可配置: +### 预设 + +点击「添加提供商」从预设快速创建:Anthropic、OpenAI、OpenRouter、Ollama、Azure OpenAI、Google AI 等。预设自动填充 Base URL 和 API 格式。 + +### 配置项 | 字段 | 说明 | |------|------| -| 名称 | 提供商显示名称 | -| API Key | 密钥(密码输入,自动脱敏) | -| Base URL | API 基础地址 | +| API Key | 密钥(密码输入) | +| Base URL | API 地址 | | API 格式 | `anthropic` / `openai_chat` / `openai_responses` | -| 模型映射 | main / haiku / sonnet / opus 槽位对应的模型名 | - -### 预设系统 - -**文件位置**:`desktop/src/config/providerPresets.ts` - -点击「添加提供商」时,可从预设快速创建: - -- Anthropic -- OpenAI -- OpenRouter -- Ollama -- Azure OpenAI -- Google AI -- 自定义... - -预设自动填充 Base URL 和 API 格式,只需填入 API Key。 +| 模型映射 | main / haiku / sonnet / opus 对应的实际模型名 | ### 连接测试 -配置完成后点击「测试」,系统执行两步验证: - -1. **连接性测试** — 发送简单请求验证网络可达 -2. **模型可用性测试** — 验证配置的模型是否可用 - -结果以 Toast 通知展示(成功 / 失败 + 错误信息)。 +两步验证:连接性 + 模型可用性,结果以 Toast 通知展示。 --- -## 六、技能与 Agent 定义 +## 技能与 Agent -### 技能浏览(SkillList / SkillDetail) +### 技能浏览 -**文件位置**:`desktop/src/components/skills/` +设置 → Skills 标签页: -技能库浏览界面: +- 按来源分类(bundled / user / project / plugin) +- 搜索过滤 +- 详情视图:元数据 + 源代码目录树 + 代码内容 -- **列表视图**:按来源分类(bundled / user / project / plugin) -- **搜索过滤**:按名称和描述搜索 -- **详情视图**: - - 技能元数据(描述、版本、来源) - - 源代码目录树 - - 代码文件内容(带语法高亮) - - Frontmatter 属性展示 +### Agent 定义 -### Agent 定义管理 +设置 → Agents 标签页: -**文件位置**:`desktop/src/pages/Settings.tsx`(Agents 标签页) - -管理 Agent 类型定义: - -| 字段 | 说明 | -|------|------| -| agentType | Agent 类型标识符 | -| description | 描述(何时使用) | -| model | 默认模型(sonnet/haiku/opus) | -| tools | 可用工具列表 | -| systemPrompt | 自定义系统提示词 | -| color | 标识颜色 | - -**来源分类**: - -| 来源 | 说明 | -|------|------| -| built-in | 系统内置(不可修改) | -| plugin | 插件提供 | -| userSettings | 用户级自定义 | -| projectSettings | 项目级自定义 | -| localSettings | 本地自定义 | - -### 关于页面 - -设置页新增「关于」标签页(About),展示应用名称、版本号、GitHub 仓库链接、作者信息及社交链接。macOS 菜单栏的「关于 Claude Code Haha」菜单项会直接导航到此页面,而非弹出系统默认的关于弹窗。 +管理 Agent 类型定义(agentType、description、model、tools、systemPrompt、color),支持 built-in / plugin / userSettings / projectSettings / localSettings 多种来源。 --- -## 七、定时任务系统 +## 定时任务 -### 任务管理页面 +![定时任务](../images/desktop_ui/08_scheduled_task.png) -**文件位置**:`desktop/src/pages/ScheduledTasks.tsx` - -#### 统计卡片 - -页面顶部三个统计卡片: - -``` -┌──────────┐ ┌──────────┐ ┌──────────┐ -│ 总计 5 │ │ 活跃 3 │ │ 禁用 2 │ -└──────────┘ └──────────┘ └──────────┘ -``` - -#### 任务列表 - -每个任务行展示: - -``` -┌──────────────────────────────────────────────┐ -│ 📋 每日代码审查 [启用 ✓] │ -│ 每天 09:00 执行 │ -│ cron: 0 9 * * * │ -│ │ -│ [运行历史 ▼] [手动运行] [删除] │ -│ │ -│ ┌──────────────────────────────────────┐ │ -│ │ 2026-04-10 09:00 ✅ 成功 (12s) │ │ -│ │ 2026-04-09 09:00 ✅ 成功 (8s) │ │ -│ │ 2026-04-08 09:00 ❌ 失败: timeout │ │ -│ └──────────────────────────────────────┘ │ -└──────────────────────────────────────────────┘ -``` +侧边栏时钟图标进入,顶部统计卡片(总计/活跃/禁用)。 ### 创建任务 -**文件位置**:`desktop/src/pages/NewTaskModal.tsx` +| 字段 | 说明 | +|------|------| +| 任务名称 | 描述性名称 | +| 提示词 | `PromptEditor` 多行编辑 | +| Cron 表达式 | 标准语法 + `cronDescribe` 人类可读描述 | +| 星期几 | `DayOfWeekPicker` 可视化多选 | +| 模型 | 选择 AI 模型 | +| 权限模式 | 执行时的权限策略 | -模态框表单: +### 任务管理 -| 字段 | 组件 | 说明 | -|------|------|------| -| 任务名称 | Input | 描述性名称 | -| 提示词 | PromptEditor | 多行文本编辑器 | -| Cron 表达式 | Input + 解释文本 | 支持标准 Cron 语法 | -| 星期几 | DayOfWeekPicker | 可视化多选星期 | -| 模型 | ModelSelector | 使用的 AI 模型 | -| 权限模式 | PermissionModeSelector | 执行时的权限策略 | - -#### DayOfWeekPicker - -``` -┌───┬───┬───┬───┬───┬───┬───┐ -│ 日│ 一│ 二│ 三│ 四│ 五│ 六│ -│ │ ✓ │ ✓ │ ✓ │ ✓ │ ✓ │ │ -└───┴───┴───┴───┴───┴───┴───┘ -``` - -可视化选择任务执行的星期几,自动更新 Cron 表达式。 - -### Cron 表达式 - -使用 `cronDescribe` 工具将 Cron 表达式转换为人类可读描述: - -``` -0 9 * * 1-5 → "周一到周五每天 09:00" -*/30 * * * * → "每 30 分钟" -0 0 1 * * → "每月 1 号 00:00" -``` +启用/禁用开关、运行历史(可展开)、手动运行、删除。 --- -## 八、IM 适配器 +## IM 适配器 -### 适配器设置页面 +![IM 适配器设置](../images/desktop_ui/07_im.png) -**文件位置**:`desktop/src/pages/AdapterSettings.tsx` +设置 → Adapters 标签页,配置 Telegram / 飞书接入。 -#### 配对管理 +### 配置 -``` -┌──────────────────────────────────┐ -│ 🔐 用户配对 │ -│ │ -│ 当前配对码: A3K7NP │ -│ 过期时间: 58 分钟后 │ -│ │ -│ [生成新配对码] │ -│ │ -│ 已配对用户: │ -│ ┌──────────────────────────────┐ │ -│ │ Telegram │ @john 2026-04-01 │ │ -│ │ 飞书 │ 张三 2026-04-05 │ │ -│ └──────────────────────────────┘ │ -└──────────────────────────────────┘ -``` +**Telegram**: Bot Token + 允许的用户 ID -#### Telegram 配置 +**飞书**: App ID + App Secret + 加密密钥 + 验证 Token + 允许的用户 open_id + 流式卡片开关 -| 字段 | 类型 | 说明 | -|------|------|------| -| Bot Token | 密码输入 | Telegram Bot API Token | -| 允许的用户 ID | 逗号分隔 | 静态白名单 | +### 用户配对 -#### 飞书配置 +6 位安全码(排除易混淆字符),60 分钟有效,一次性使用。同一用户 5 分钟内最多失败 5 次。 -| 字段 | 类型 | 说明 | -|------|------|------| -| App ID | 文本 | 飞书应用 ID | -| App Secret | 密码 | 飞书应用密钥 | -| 加密密钥 | 密码 | 事件加密密钥 | -| 验证 Token | 密码 | 事件验证 Token | -| 允许的用户 | 逗号分隔 | open_id 白名单 | -| 流式卡片 | 开关 | 是否启用流式消息卡片 | +### IM 操作 -### 飞书适配器特性 +| 命令 | 效果 | +|------|------| +| 直接发文本 | 与 Claude Code 对话 | +| `/new [项目]` 或 `新会话` | 开始新会话 | +| `/projects` 或 `项目列表` | 查看最近项目 | +| `/stop` 或 `停止` | 停止生成 | -**文件位置**:`adapters/feishu/index.ts` - -- **连接方式**:WebSocket 长连接(无需公网地址) -- **消息格式**:飞书 JSON 富文本 → Markdown 文本 -- **权限审批**:Interactive Card(卡片按钮) -- **消息更新**:Patch API 编辑已发消息(流式效果) -- **分片发送**:超过 30000 字时自动分片 - -### Telegram 适配器特性 - -**文件位置**:`adapters/telegram/index.ts` - -- **连接方式**:Polling 模式(Bot 主动轮询) -- **消息格式**:纯文本 + Markdown -- **权限审批**:Inline Keyboard(内联按钮) -- **消息更新**:`editMessageText` 编辑已发消息 -- **分片发送**:超过 4000 字时自动分片 - -### 权限请求在 IM 中的展示 - -**Telegram**: -``` -⚠️ 权限请求 -工具: Bash -命令: npm install express -说明: Install express package - -[✅ 允许] [❌ 拒绝] ← Inline Keyboard -``` - -**飞书**: -``` -┌──────────────────────────┐ -│ ⚠️ 权限请求 │ -│ │ -│ 工具: Bash │ -│ 命令: npm install express│ -│ │ -│ [✅ 允许] [❌ 拒绝] │ ← Interactive Card -└──────────────────────────┘ -``` +权限请求在 IM 中以按钮形式展示(Telegram Inline Keyboard / 飞书 Interactive Card)。 --- -## 九、设计系统 +## Computer Use -### 颜色体系 +![Computer Use 设置](../images/desktop_ui/06_settings_computer_use.png) -桌面端采用**暖色调**设计语言: +设置 → Computer Use 标签页,查看和配置 Computer Use 功能状态。 -**文件位置**:`desktop/src/theme/globals.css` +`ComputerUseSettings` 页面展示:平台信息、Python 环境、venv 状态、依赖安装情况、权限配置。 -#### 主色 +--- -| 变量 | 色值 | 用途 | -|------|------|------| -| `--color-primary` | #8F482F | 品牌色、CTA 按钮 | -| `--color-primary-container` | #AD5F45 | 品牌色容器 | -| `--color-on-primary` | #FFFFFF | 品牌色上的文字 | +## 工具检查 -#### 表面色 +`ToolInspection` 页面,查看当前会话中可用的工具列表和详情。 -| 变量 | 色值 | 用途 | -|------|------|------| -| `--color-surface` | #FAF9F5 | 主背景(浅米色) | -| `--color-surface-container` | #EFEEEA | 卡片背景 | -| `--color-surface-container-low` | #F4F4F0 | 次级容器 | -| `--color-surface-container-high` | #E9E8E4 | 高层级容器 | +--- -#### 语义色 +## 设计系统 -| 变量 | 色值 | 用途 | -|------|------|------| -| `--color-secondary` | #2D628F | 信息、链接 | -| `--color-tertiary` | #4F6237 | 成功、确认 | -| `--color-error` | #BA1A1A | 错误、警告 | +### 颜色 -#### 文本色 +暖色调设计语言: -| 变量 | 色值 | 用途 | -|------|------|------| -| `--color-on-surface` | #1B1C1A | 主文本 | -| `--color-on-surface-variant` | #54433E | 次级文本 | -| `--color-outline` | #87736D | 边框 | -| `--color-outline-variant` | #DAC1BA | 弱边框 | +- **品牌色**: `#8F482F`(褐红色) +- **浅色背景**: `#FAF9F5`(奶油色) +- **信息色**: `#2D628F` / **成功色**: `#4F6237` / **错误色**: `#BA1A1A` -### 字体系统 +### 主题 -| 字体 | 用途 | 字重 | -|------|------|------| -| **Inter** | 正文 | 400-600 | -| **Manrope** | 标题 | 400-800 | -| **JetBrains Mono** | 代码 | 400 | - -### 图标系统 - -使用 **Material Symbols Outlined** 图标集,自托管字体: - -- 齿轮 → 设置 -- 时钟 → 定时任务 -- + → 新建 -- × → 关闭 -- 文件夹 → 项目 -- 搜索 → 搜索 +浅色/深色切换,设置 → 通用中配置。 ### 动画 -| 名称 | 效果 | 用途 | -|------|------|------| -| `animate-pulse-dot` | 脉冲闪烁 | 运行中会话指示 | -| `animate-shimmer` | 闪烁光标 | 流式输出光标 | -| slide-in / fade-in | 滑入淡入 | Toast 通知 | +| 名称 | 用途 | +|------|------| +| `shimmer` | 流式输出闪烁光标 | +| `pulse-dot` | 运行中会话指示 | +| `spin` | 加载旋转 | +| `progress-fill` | 进度条填充 | -### 通知系统(Toast) +### Toast 通知 -**文件位置**:`desktop/src/components/shared/Toast.tsx` +右下角固定通知,四种类型(success/error/warning/info),自动消失 + 手动关闭。 -右下角固定位置的通知组件: +### 自动更新 -``` - ┌──────────────────────────┐ - │ ✅ 提供商连接测试成功 ×│ - │ 所有模型可用 │ - └──────────────────────────┘ -``` - -四种类型: - -| 类型 | 左边框色 | 场景 | -|------|----------|------| -| success | 绿色 | 操作成功 | -| error | 红色 | 操作失败 | -| warning | 黄色 | 警告提示 | -| info | 蓝色 | 信息通知 | - -- 自动消失(可配置时长) -- 点击 × 手动关闭 -- 从右侧滑入动画 +`UpdateChecker` 组件:启动后检查 GitHub Releases,有新版本时弹出更新提示,支持自动下载安装重启。 --- -## 十、国际化 +## 国际化 -**文件位置**:`desktop/src/i18n/` +支持中文 (`zh`) 和英文 (`en`),设置 → 通用中切换,`localStorage` 持久化。 -### 支持语言 - -- **en** — English -- **zh** — 简体中文 - -### 使用方式 - -```typescript -// 在 React 组件中 -const t = useTranslation() -return - -// 支持参数插值 -t('chat.tokenCount', { count: 1200 }) -``` - -### 翻译 Key 体系 - -| 命名空间 | 示例 | 说明 | -|----------|------|------| -| `common.*` | save, cancel, delete | 通用词汇 | -| `sidebar.*` | newSession, search | 侧边栏 | -| `chat.*` | sendMessage, thinking | 聊天 | -| `settings.*` | providers, permissions | 设置 | -| `status.*` | connected, error | 状态 | -| `titlebar.*` | appName | 标题栏 | - -### 切换语言 - -在设置 → 通用 中切换语言,设置保存到 `localStorage`,即时生效。 +Key 命名空间:`common.*`、`sidebar.*`、`chat.*`、`settings.*`、`status.*`、`titlebar.*` 等。 --- -## 十一、快速参考 +## 键盘快捷键 -### 组件清单 - -| 组件 | 路径 | 职责 | -|------|------|------| -| AppShell | `components/layout/AppShell.tsx` | 应用根容器、初始化 | -| Sidebar | `components/layout/Sidebar.tsx` | 侧边栏导航 | -| TabBar | `components/layout/TabBar.tsx` | 标签页管理 | -| ContentRouter | `components/layout/ContentRouter.tsx` | 页面路由 | -| StatusBar | `components/layout/StatusBar.tsx` | 状态栏 | -| ChatInput | `components/chat/ChatInput.tsx` | 消息输入 | -| MessageList | `components/chat/MessageList.tsx` | 消息列表 | -| ToolCallBlock | `components/chat/ToolCallBlock.tsx` | 工具调用展示 | -| CodeViewer | `components/chat/CodeViewer.tsx` | 代码高亮 | -| DiffViewer | `components/chat/DiffViewer.tsx` | Diff 展示 | -| PermissionDialog | `components/chat/PermissionDialog.tsx` | 权限审批 | -| ModelSelector | `components/controls/ModelSelector.tsx` | 模型选择 | -| Toast | `components/shared/Toast.tsx` | 通知系统 | - -### Store 清单 - -| Store | 路径 | 核心状态 | -|-------|------|----------| -| chatStore | `stores/chatStore.ts` | messages, chatState, streamingText | -| sessionStore | `stores/sessionStore.ts` | sessions, activeSessionId | -| tabStore | `stores/tabStore.ts` | tabs, activeTabId, tabOrder | -| settingsStore | `stores/settingsStore.ts` | model, permissionMode, language | -| providerStore | `stores/providerStore.ts` | providers, activeProvider | -| uiStore | `stores/uiStore.ts` | theme, toasts, modals | -| taskStore | `stores/taskStore.ts` | tasks, runs | -| teamStore | `stores/teamStore.ts` | teams, members | - -### API 客户端清单 - -| 模块 | 路径 | 职责 | -|------|------|------| -| client | `api/client.ts` | HTTP 基础客户端 | -| websocket | `api/websocket.ts` | WebSocket 管理器 | -| sessions | `api/sessions.ts` | 会话 CRUD | -| providers | `api/providers.ts` | 提供商管理 | -| models | `api/models.ts` | 模型操作 | -| tasks | `api/tasks.ts` | 定时任务 | -| teams | `api/teams.ts` | Agent 团队 | -| agents | `api/agents.ts` | Agent 定义 | -| skills | `api/skills.ts` | 技能查询 | -| adapters | `api/adapters.ts` | 适配器配置 | -| search | `api/search.ts` | 搜索 | -| filesystem | `api/filesystem.ts` | 文件系统 | +| 快捷键 | 功能 | +|--------|------| +| `Cmd/Ctrl + N` | 新建会话 | +| `Cmd/Ctrl + K` | 聚焦搜索 | +| `Cmd/Ctrl + .` | 停止生成 | +| `Escape` | 关闭模态框 | +| `Enter` | 发送消息 | +| `Shift + Enter` | 换行 | +| `/` | 斜杠命令 | +| `@` | 文件搜索 | diff --git a/docs/desktop/04-installation.md b/docs/desktop/04-installation.md index f1b66a68..8f13e366 100644 --- a/docs/desktop/04-installation.md +++ b/docs/desktop/04-installation.md @@ -1,349 +1,56 @@ -# Claude Code 桌面端 — 安装与构建指南 +# 安装指南 -> 从下载到运行,覆盖 macOS / Windows / Linux 三大平台。 +## 下载 -

-下载 · macOS · Windows · Linux · 源码构建 · 自动更新 · 发布流程 -

+前往 [GitHub Releases](https://github.com/NanmiCoder/cc-haha/releases) 下载对应平台的安装包: ---- +| 平台 | 文件 | +|------|------| +| macOS (Apple Silicon) | `Claude.Code.Haha_x.x.x_aarch64.dmg` | +| macOS (Intel) | `Claude.Code.Haha_x.x.x_x64.dmg` | +| Windows (x64) | `Claude.Code.Haha_x.x.x_x64-setup.exe` | -## 一、下载安装包 +> 不确定 Mac 架构?点击左上角 → 关于本机,芯片为 Apple M 开头选 aarch64,Intel 选 x64。 -前往 [GitHub Releases](https://github.com/NanmiCoder/cc-haha/releases) 页面,根据你的系统下载对应安装包: +## macOS 安装 -| 平台 | 架构 | 文件 | -|------|------|------| -| macOS | Apple Silicon (M1/M2/M3/M4) | `Claude.Code.Haha_x.x.x_aarch64.dmg` | -| macOS | Intel | `Claude.Code.Haha_x.x.x_x64.dmg` | -| Windows | x64 | `Claude.Code.Haha_x.x.x_x64-setup.exe` | -| Linux | x64 | `.deb` 或 `.AppImage` | -| Linux | ARM64 | `.deb` 或 `.AppImage` | - -> **不确定 Mac 的架构?** 点击左上角 → 关于本机 → 查看"芯片"信息。Apple M 开头就选 ARM64,Intel 就选 x64。 - ---- - -## 二、macOS 安装 - -### 正常安装 - -1. 双击下载的 `.dmg` 文件 -2. 将 `Claude Code Haha.app` 拖入 `Applications` 文件夹 -3. 在启动台或 `Applications` 中打开应用 - -### 处理"未签名应用"提示 - -由于应用暂未进行 Apple 公证签名,macOS 会阻止首次运行。有以下几种方式处理: - -#### 方法一:右键打开(最简单) - -1. 在 **Finder** 中找到 `Claude Code Haha.app`(在应用程序文件夹中) -2. **右键点击**(或 Control + 点击)该应用 -3. 选择 **「打开」** -4. 在弹出的对话框中点击 **「打开」** - -> 只需操作一次,后续可正常双击启动。 - -#### 方法二:命令行移除隔离标记(推荐) - -打开终端,执行: +1. 双击 `.dmg` 文件,将应用拖入 `Applications` 文件夹 +2. 首次打开如果提示**"已损坏,无法打开"**,在终端执行: ```bash xattr -cr /Applications/Claude\ Code\ Haha.app ``` -此命令移除 macOS 的 Gatekeeper 隔离属性,之后可正常双击启动。 +> 由于应用暂未进行 Apple 开发者签名,macOS 会阻止首次运行,执行上述命令移除隔离属性后即可正常使用。 -#### 方法三:系统设置中允许 +## Windows 安装 -1. 打开 **系统设置** → **隐私与安全性** -2. 向下滚动,在安全性区域找到关于 Claude Code Haha 被阻止的提示 -3. 点击 **「仍然打开」** -4. 输入密码确认 +1. 双击 `.exe` 安装程序,按向导完成安装 +2. 首次运行如果 SmartScreen 弹出警告,点击 **「更多信息」** → **「仍要运行」** -> macOS Sequoia (15.x) 及以上版本可能需要先尝试打开一次应用,才会在系统设置中出现该选项。 +> 应用暂未进行 Windows 代码签名,仅首次运行需要此操作。 -### macOS 系统要求 +## Web UI 模式 -- macOS 11.0 (Big Sur) 或更高版本 -- Apple Silicon 或 Intel 处理器 - ---- - -## 三、Windows 安装 - -### 正常安装 - -1. 双击下载的 `.exe` 安装程序 -2. 按照 NSIS 安装向导完成安装 -3. 安装完成后从开始菜单或桌面快捷方式启动 - -### 处理 SmartScreen 拦截 - -由于应用暂未进行 Windows 代码签名,首次运行时 SmartScreen 会弹出警告。 - -#### 绕过方式 - -1. 在 SmartScreen 蓝色窗口中点击 **「更多信息」**(More info) -2. 点击 **「仍要运行」**(Run anyway) - -> 只需第一次运行时操作,后续不再提示。 - -#### 如果没有"更多信息"选项 - -部分企业版 Windows 可能隐藏了该选项。可以通过以下方式临时关闭 SmartScreen: - -1. 打开 **Windows 安全中心** → **应用和浏览器控制** -2. 点击 **「基于信誉的保护设置」** -3. 临时关闭 **「检查应用和文件」** -4. 安装并运行应用后,建议重新开启此选项 - -### WebView2 运行时 - -Claude Code Haha 依赖 Microsoft Edge WebView2 运行时。大多数 Windows 10/11 系统已预装。如果提示缺少 WebView2: - -- 从 [Microsoft 官方](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) 下载 Evergreen Bootstrapper 并安装 - -### Windows 系统要求 - -- Windows 10 (1803+) 或 Windows 11 -- x64 处理器 -- WebView2 运行时 - ---- - -## 四、Linux 安装 - -### Debian / Ubuntu(.deb) +如果桌面端安装遇到问题,可以直接通过浏览器使用 Web UI。在项目根目录下分别启动服务端和前端: ```bash -sudo dpkg -i claude-code-haha_x.x.x_amd64.deb -# 如果提示缺少依赖: -sudo apt-get install -f +# 1. 启动服务端(在项目根目录) +SERVER_PORT=3456 bun run src/server/index.ts + +# 2. 启动前端(在 desktop 目录) +cd desktop +bun run dev --host 127.0.0.1 --port 2024 ``` -### AppImage(通用) +启动后浏览器访问 `http://127.0.0.1:2024` 即可。 -```bash -chmod +x Claude.Code.Haha_x.x.x_amd64.AppImage -./Claude.Code.Haha_x.x.x_amd64.AppImage -``` +## 常见问题 -> AppImage 无需安装,赋予执行权限后直接运行。 +**Q: macOS 提示"来自身份不明的开发者"?** -### 系统依赖 +右键点击应用 → 选择「打开」→ 在弹窗中点击「打开」,仅需操作一次。 -Linux 版本需要以下系统库(.deb 安装时会自动处理依赖): +**Q: Windows 提示缺少 WebView2?** -```bash -# Ubuntu / Debian -sudo apt-get install -y \ - libwebkit2gtk-4.1-0 \ - libgtk-3-0 \ - libayatana-appindicator3-1 \ - librsvg2-2 -``` - -### Linux 系统要求 - -- Ubuntu 22.04+ 或同等 glibc 版本的发行版 -- x64 或 ARM64 处理器 -- WebKitGTK 4.1 - ---- - -## 五、从源码构建 - -如果你想自己编译桌面端,或想参与开发: - -### 前置依赖 - -| 工具 | 最低版本 | 安装方式 | -|------|---------|----------| -| **Bun** | 1.0+ | `curl -fsSL https://bun.sh/install \| bash` | -| **Rust** | 1.70+ | `curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh` | -| **Node.js** | 20+ | [nodejs.org](https://nodejs.org/) | - -**Linux 额外依赖:** - -```bash -sudo apt-get install -y \ - libwebkit2gtk-4.1-dev \ - libappindicator3-dev \ - librsvg2-dev \ - patchelf -``` - -### 构建步骤 - -```bash -# 1. 克隆仓库 -git clone https://github.com/NanmiCoder/cc-haha.git -cd cc-haha - -# 2. 安装依赖 -bun install -cd desktop && bun install - -# 3. 开发模式运行 -bun run tauri dev - -# 4. 生产构建(生成安装包) -bun run tauri build -``` - -构建产物位于 `desktop/src-tauri/target/release/bundle/` 目录下。 - -### 跨平台构建 - -Sidecar 构建脚本会自动检测当前平台的 Rust target triple,也可以手动指定: - -```bash -# 为 macOS Intel 构建 sidecar -TAURI_ENV_TARGET_TRIPLE=x86_64-apple-darwin bun run build:sidecars - -# 为 Linux x64 构建 sidecar -TAURI_ENV_TARGET_TRIPLE=x86_64-unknown-linux-gnu bun run build:sidecars -``` - -> 注意:Tauri 应用本身不支持在 macOS 上交叉编译 Linux/Windows 版本。跨平台构建由 CI/CD 流水线在各自平台的构建环境中完成。 - ---- - -## 六、自动更新 - -桌面端内置了自动更新机制(基于 Tauri Updater 插件): - -1. **检查更新** — 应用启动 5 秒后自动检查 GitHub Releases -2. **提示更新** — 如有新版本,右上角弹出更新提示卡片 -3. **下载安装** — 点击「Update now」自动下载并安装 -4. **重启应用** — 安装完成后自动重启 - -> 自动更新需要网络连接到 GitHub。如果你在受限网络环境中,可以手动从 Releases 页面下载。 - ---- - -## 七、发布流程(开发者) - -项目使用 **tag-based release** 工作流,推送版本标签后自动触发跨平台构建。 - -### 发布新版本 - -```bash -# 1. 确保在 main 分支且工作区干净 -git checkout main && git pull - -# 2. 使用 release 脚本更新版本号 -bun run scripts/release.ts patch # 0.1.0 → 0.1.1 -bun run scripts/release.ts minor # 0.1.0 → 0.2.0 -bun run scripts/release.ts major # 0.1.0 → 1.0.0 -bun run scripts/release.ts 2.0.0 # 指定版本号 - -# 3. 预览变更(不会修改任何文件) -bun run scripts/release.ts patch --dry - -# 4. 推送到远程,触发 CI 构建 -git push origin main --tags -``` - -### CI 构建矩阵 - -推送 `v*.*.*` 标签后,GitHub Actions 自动在 5 个平台并行构建: - -| 构建环境 | 目标 | 产物 | -|----------|------|------| -| `macos-latest` | `aarch64-apple-darwin` | `.dmg`, `.app.tar.gz` | -| `macos-latest` | `x86_64-apple-darwin` | `.dmg`, `.app.tar.gz` | -| `ubuntu-22.04` | `x86_64-unknown-linux-gnu` | `.deb`, `.AppImage` | -| `ubuntu-22.04-arm` | `aarch64-unknown-linux-gnu` | `.deb`, `.AppImage` | -| `windows-latest` | `x86_64-pc-windows-msvc` | `.exe`, `.msi` | - -所有产物自动上传到 GitHub Draft Release。检查无误后手动点击发布。 - -### 配置代码签名(可选) - -如需正式签名以消除安全警告,需在 GitHub 仓库 Settings → Secrets 中配置: - -**macOS(需 Apple Developer Program,$99/年):** - -| Secret | 说明 | -|--------|------| -| `APPLE_CERTIFICATE` | Base64 编码的 .p12 证书 | -| `APPLE_CERTIFICATE_PASSWORD` | .p12 导出密码 | -| `APPLE_SIGNING_IDENTITY` | 如 `Developer ID Application: Your Name (TEAMID)` | -| `APPLE_TEAM_ID` | 10 位 Team ID | -| `APPLE_ID` | Apple 账号邮箱 | -| `APPLE_PASSWORD` | App 专用密码(非 Apple ID 密码) | - -**Windows(需 OV 代码签名证书):** - -| Secret | 说明 | -|--------|------| -| `AZURE_CLIENT_ID` | Azure AD 应用客户端 ID | -| `AZURE_TENANT_ID` | Azure AD 租户 ID | -| `AZURE_CLIENT_SECRET` | Azure AD 客户端密钥 | - -**自动更新签名:** - -| Secret | 说明 | -|--------|------| -| `TAURI_SIGNING_PRIVATE_KEY` | Updater 签名私钥 | -| `TAURI_SIGNING_PRIVATE_KEY_PASSWORD` | 私钥密码 | - -生成 Updater 签名密钥: - -```bash -bunx tauri signer generate -w ~/.tauri/claude-code-haha.key -``` - -> 请妥善保管私钥!丢失后已安装用户将无法自动更新。 - ---- - -## 八、常见问题 - -### macOS:"app is damaged and can't be opened" - -执行以下命令后重试: - -```bash -xattr -cr /Applications/Claude\ Code\ Haha.app -``` - -### macOS:"unidentified developer" - -参考上方 [方法一:右键打开](#方法一右键打开最简单) 或 [方法三:系统设置](#方法三系统设置中允许)。 - -### Windows:安装后无法启动 - -确认系统已安装 WebView2 运行时。从 [Microsoft 官方](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) 下载安装。 - -### Linux:AppImage 双击无反应 - -确保已赋予执行权限: - -```bash -chmod +x Claude.Code.Haha_*.AppImage -``` - -### Linux:提示缺少 libwebkit2gtk - -```bash -sudo apt-get install libwebkit2gtk-4.1-0 -``` - -### 构建时 sidecar 编译失败 - -确认 Bun 和 Rust 已正确安装: - -```bash -bun --version # 应 >= 1.0 -rustc --version # 应 >= 1.70 -``` - -### 自动更新不工作 - -- 确认网络可访问 GitHub -- 检查是否配置了 `TAURI_SIGNING_PRIVATE_KEY` -- 查看应用日志中的 updater 错误信息 +从 [Microsoft 官方](https://developer.microsoft.com/en-us/microsoft-edge/webview2/) 下载安装 WebView2 运行时。 diff --git a/docs/desktop/images/01-desktop-overview.png b/docs/desktop/images/01-desktop-overview.png deleted file mode 100644 index f0a93577..00000000 Binary files a/docs/desktop/images/01-desktop-overview.png and /dev/null differ diff --git a/docs/desktop/images/02-tech-stack.png b/docs/desktop/images/02-tech-stack.png deleted file mode 100644 index 41b943da..00000000 Binary files a/docs/desktop/images/02-tech-stack.png and /dev/null differ diff --git a/docs/desktop/images/03-three-layer-arch.png b/docs/desktop/images/03-three-layer-arch.png deleted file mode 100644 index 0ac37d85..00000000 Binary files a/docs/desktop/images/03-three-layer-arch.png and /dev/null differ diff --git a/docs/desktop/images/04-websocket-protocol.png b/docs/desktop/images/04-websocket-protocol.png deleted file mode 100644 index 035c691b..00000000 Binary files a/docs/desktop/images/04-websocket-protocol.png and /dev/null differ diff --git a/docs/desktop/images/05-session-lifecycle.png b/docs/desktop/images/05-session-lifecycle.png deleted file mode 100644 index 4836df3f..00000000 Binary files a/docs/desktop/images/05-session-lifecycle.png and /dev/null differ diff --git a/docs/desktop/images/06-features-grid.png b/docs/desktop/images/06-features-grid.png deleted file mode 100644 index 95b04a38..00000000 Binary files a/docs/desktop/images/06-features-grid.png and /dev/null differ diff --git a/docs/desktop/images/07-adapter-bridge.png b/docs/desktop/images/07-adapter-bridge.png deleted file mode 100644 index b474cf9f..00000000 Binary files a/docs/desktop/images/07-adapter-bridge.png and /dev/null differ diff --git a/docs/desktop/images/08-chat-message-flow.png b/docs/desktop/images/08-chat-message-flow.png deleted file mode 100644 index 4ca10476..00000000 Binary files a/docs/desktop/images/08-chat-message-flow.png and /dev/null differ diff --git a/docs/desktop/index.md b/docs/desktop/index.md index 35d1d33c..41ca79ab 100644 --- a/docs/desktop/index.md +++ b/docs/desktop/index.md @@ -1,90 +1,28 @@ -# Claude Code 桌面端文档 +# 桌面端文档 -> 图形化的 AI Code Editor,支持多会话、多标签、外部 UI 接入的完整桌面体验。 +> 图形化的 AI Code Editor,支持多会话、多标签、IM 接入的完整桌面体验。 + +![桌面端界面](../images/desktop_ui/01_full_ui.png) --- ## 文档目录 -### [01-quick-start.md](./01-quick-start.md) — 快速上手 +### [快速上手](./01-quick-start.md) -面向用户的桌面端使用指南,涵盖: +面向用户的桌面端使用指南:界面布局、对话操作、多标签、权限控制、项目管理、模型配置、IM 适配器、定时任务。 -- **启动与界面**:首次运行、界面布局、主题切换 -- **对话操作**:新建会话、发送消息、附件上传、斜杠命令 -- **多标签系统**:标签切换、拖拽排序、关闭策略 -- **权限控制**:四种权限模式、工具审批流程 -- **项目管理**:工作目录关联、项目筛选、Git 信息展示 -- **模型与提供商**:模型切换、自定义 Provider、连接测试 -- **IM 适配器**:Telegram / 飞书接入、用户配对 -- **定时任务**:Cron 任务创建、运行历史查看 +### [架构设计](./02-architecture.md) -**适合人群**:所有桌面端用户 +面向开发者的技术架构:三层架构(Tauri → Server → CLI)、WebSocket 协议、HTTP API、状态管理、协议代理、适配器桥接、目录结构。 ---- +### [功能详解](./03-features.md) -### [02-architecture.md](./02-architecture.md) — 架构设计 +深入每个功能模块:聊天引擎、代码展示、工具调用、Agent Teams、提供商管理、技能/Agent、定时任务、IM 适配器、设计系统。 -面向开发者的技术架构解析,涵盖: +### [安装指南](./04-installation.md) -- **技术栈总览**:Tauri 2 + React 18 + Zustand + Vite + Tailwind CSS 4 -- **三层架构**:Tauri Shell → Express Server → CLI 子进程 -- **通信协议**:WebSocket 消息格式、HTTP API 端点、流式输出机制 -- **状态管理**:Zustand Store 设计、数据流向、持久化策略 -- **会话生命周期**:创建 → 连接 → 交互 → 断开 → 恢复 -- **代理层**:多协议转换(Anthropic / OpenAI)、Provider 管理 -- **适配器桥接**:外部 IM 平台的 WebSocket 接入架构 - -**适合人群**:贡献者、架构师、想接入自定义 UI 的开发者 - ---- - -### [03-features.md](./03-features.md) — 功能详解 - -深入解析桌面端每个功能模块,涵盖: - -- **聊天引擎**:消息类型、流式渲染、代码高亮、Diff 展示、思考块 -- **工具调用系统**:权限请求卡片、Tool 输入/输出展示、Bash 终端模拟 -- **Agent Teams**:团队视图、成员状态、转录查看 -- **技能与 Agent 定义**:技能浏览、Agent 配置、自定义扩展 -- **定时任务**:Cron 编辑器、Day-of-Week 选择、运行日志 -- **国际化**:中英文切换、翻译 Key 体系 -- **键盘快捷键**:全局快捷键、输入框快捷操作 - -**适合人群**:想充分利用桌面端功能的高级用户和开发者 - ---- - -### [04-installation.md](./04-installation.md) — 安装与构建指南 - -面向所有用户的安装手册,涵盖: - -- **下载安装包**:各平台安装包对应表 -- **macOS 安装**:Gatekeeper 未签名应用处理(右键打开 / xattr / 系统设置) -- **Windows 安装**:SmartScreen 绕过、WebView2 依赖 -- **Linux 安装**:.deb / AppImage 安装、系统依赖 -- **从源码构建**:前置依赖、构建步骤、跨平台编译 -- **自动更新**:内置 Updater 机制说明 -- **发布流程**:tag-based release、CI 构建矩阵、代码签名配置 - -**适合人群**:所有用户(安装部分)、开发者(构建与发布部分) - ---- - -## 配图说明 - -所有配图采用深色背景(#1a1a2e)+ Anthropic 品牌橙铜色(#D97757)风格,与项目文档视觉语言一致。 - -| 图片 | 说明 | 所属文档 | -|------|------|----------| -| `01-desktop-overview.png` | 桌面端界面总览 — 布局与核心区域 | 快速上手 | -| `02-tech-stack.png` | 技术栈全景 — 框架与工具链 | 架构设计 | -| `03-three-layer-arch.png` | 三层架构图 — Tauri / Server / CLI | 架构设计 | -| `04-websocket-protocol.png` | WebSocket 通信协议 — 消息类型与流向 | 架构设计 | -| `05-session-lifecycle.png` | 会话生命周期 — 创建到恢复的完整流程 | 架构设计 | -| `06-features-grid.png` | 功能全景图 — 核心功能模块一览 | 功能详解 | -| `07-adapter-bridge.png` | 适配器桥接 — 外部 IM 平台接入架构 | 功能详解 | -| `08-chat-message-flow.png` | 聊天消息流 — 从输入到渲染的数据流 | 功能详解 | +下载安装、macOS/Windows 常见问题、Web UI 模式。 --- @@ -92,44 +30,30 @@ ### 用户 -1. 阅读 [快速上手](./01-quick-start.md) -2. 了解界面布局和基本操作 -3. 配置 AI 模型提供商 -4. 开始你的第一次对话 +1. 阅读 [安装指南](./04-installation.md) 下载安装 +2. 阅读 [快速上手](./01-quick-start.md) 了解界面和操作 +3. 配置 AI 模型提供商,开始对话 ### 开发者 -1. 阅读 [架构设计](./02-architecture.md) -2. 查看源码位置: - - `desktop/src/` — React 前端代码 +1. 阅读 [架构设计](./02-architecture.md) 理解三层架构 +2. 关键源码位置: + - `desktop/src/` — React 前端 - `desktop/src-tauri/` — Tauri Rust 后端 - - `desktop/sidecars/` — Sidecar 启动器 + - `desktop/sidecars/` — Sidecar 入口 - `src/server/` — Express API 服务端 - - `adapters/` — 外部 IM 适配器 -3. 理解三层架构和 WebSocket 通信协议 + - `adapters/` — IM 适配器 --- -## 核心概念速查 +## 核心概念 | 概念 | 说明 | |------|------| -| **Tauri** | 轻量级跨平台桌面框架,用 Rust 管理窗口和 Sidecar 进程 | -| **Sidecar** | 随 Tauri 主进程启动的后台服务,运行 Express API 服务器 | +| **Tauri** | 跨平台桌面框架,Rust 管理窗口和 Sidecar 进程 | +| **Sidecar** | 随主进程启动的后台服务,运行 API 服务器 | | **Session** | 一次对话会话,绑定工作目录,通过 WebSocket 通信 | -| **Tab** | 标签页,一个 Tab 对应一个 Session 或特殊页面(设置、任务) | -| **Provider** | AI 模型提供商,支持 Anthropic、OpenAI 兼容等多种接口 | -| **Adapter** | 外部 IM 适配器,让 Telegram / 飞书等平台接入 Claude Code | -| **Pairing** | 配对机制,6 位安全码授权外部 IM 用户访问 | -| **Store** | Zustand 状态容器,管理聊天、会话、设置等状态 | -| **Slash Command** | 斜杠命令,`/commit`、`/review-pr` 等快捷操作 | - ---- - -## 相关资源 - -- [Claude Code Haha 主页](/) -- [多 Agent 系统文档](/agent/) -- [记忆系统文档](/memory/) -- [Skills 系统文档](/skills/) -- [GitHub Issues](https://github.com/NanmiCoder/cc-haha/issues) +| **Tab** | 标签页,对应一个 Session 或特殊页面 | +| **Provider** | AI 模型提供商,支持 Anthropic/OpenAI 兼容接口 | +| **Adapter** | IM 适配器,Telegram/飞书接入 Claude Code | +| **Store** | Zustand 状态容器,按领域拆分管理 | diff --git a/docs/images/desktop_ui/01_full_ui.png b/docs/images/desktop_ui/01_full_ui.png new file mode 100644 index 00000000..6083716b Binary files /dev/null and b/docs/images/desktop_ui/01_full_ui.png differ diff --git a/docs/images/desktop_ui/03_ask_question_and_permission.png b/docs/images/desktop_ui/03_ask_question_and_permission.png new file mode 100644 index 00000000..c27b3867 Binary files /dev/null and b/docs/images/desktop_ui/03_ask_question_and_permission.png differ diff --git a/docs/images/desktop_ui/04_tasktodo_list.png b/docs/images/desktop_ui/04_tasktodo_list.png new file mode 100644 index 00000000..b2a55ba3 Binary files /dev/null and b/docs/images/desktop_ui/04_tasktodo_list.png differ diff --git a/docs/images/desktop_ui/05_settings.png b/docs/images/desktop_ui/05_settings.png new file mode 100644 index 00000000..3186b8e7 Binary files /dev/null and b/docs/images/desktop_ui/05_settings.png differ diff --git a/docs/images/desktop_ui/06_settings_computer_use.png b/docs/images/desktop_ui/06_settings_computer_use.png new file mode 100644 index 00000000..7e7aa51a Binary files /dev/null and b/docs/images/desktop_ui/06_settings_computer_use.png differ diff --git a/docs/images/desktop_ui/07_im.png b/docs/images/desktop_ui/07_im.png new file mode 100644 index 00000000..c91bfe9d Binary files /dev/null and b/docs/images/desktop_ui/07_im.png differ diff --git a/docs/images/desktop_ui/08_scheduled_task.png b/docs/images/desktop_ui/08_scheduled_task.png new file mode 100644 index 00000000..c9376f40 Binary files /dev/null and b/docs/images/desktop_ui/08_scheduled_task.png differ diff --git a/docs/images/desktop_ui/09_file_search.png b/docs/images/desktop_ui/09_file_search.png new file mode 100644 index 00000000..c9927b10 Binary files /dev/null and b/docs/images/desktop_ui/09_file_search.png differ diff --git a/docs/images/desktop_ui/09_slash_command.png b/docs/images/desktop_ui/09_slash_command.png new file mode 100644 index 00000000..8cf38246 Binary files /dev/null and b/docs/images/desktop_ui/09_slash_command.png differ