Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions docs/desktop-gap-checklist.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# JuCode Desktop 差距清单(Gap Checklist)

> 基准:`main@6f83aa4`。配套阅读:`docs/workbench-plan.md`。
> 已勾选([x])= 方向已确认、直接排期实施;未勾选([ ])= 存在分歧或多方案,需要 owner 拍板后才能动工。

## 已确认(直接实施)

| 状态 | 事项 | 说明 | 相关代码 |
| --- | --- | --- | --- |
| [x] | 马赛克平铺树 + 多面板同时可见 | 手写二叉 TileTree,叶子为标签栈;替代"右 Dock 单激活面板"模型 | `src/lib/RightDock.svelte`、新 `src/lib/workbench/tiles.ts` |
| [x] | 双击最大化/还原 | 树外记 `maximizedLeafId`,不改布局树 | 新 `src/lib/workbench/` |
| [x] | 拖拽分屏落点预览 | 叶子边缘 1/4 命中区 + 半透明预览层 | 新 `src/lib/workbench/` |
| [x] | Workspace 实体 + 从 Project 迁移 | Workspace ⊃ Project;首启把现有 `SavedProject[]` 包进默认工作区,序列化加 `version` | `src/lib/session.svelte.ts`(`SavedProject`、`serialize/restore`) |
| [x] | 原生 TUI 标签 | `pty_open` 增加 cmd/args,直接跑 jucode/codex/claude 交互式 CLI;v1 为独立会话 | `src-tauri/src/lib.rs`(`pty_open`)、`src/lib/TerminalPanel.svelte` |
| [x] | ACP 作为新增后端(先上 feature flag) | 新 `BackendId` 类别;保留 jucode/codex/claude 原生 adapter(hunks/resume/set_model 不回退) | `src/lib/backends/index.ts`、新 `backends/acp.ts` |
| [x] | 模型选择器四分组 | Codex 官方 / Claude 官方 / JuCode 内置 / 自定义(BYOK),标注官方 vs 内置 | `src/lib/Composer.svelte`、`src/lib/settings/CustomProviderForm.svelte` |
| [x] | serve/CLI 功能对齐残留 | 补齐 `/pin`、`command_list` 等 CLI 已有而桌面缺失/不完整的命令 | `src/lib/backends/{jucode,codex,claude}.ts` |
| [x] | CodeMirror 仅作 AUDIT/diff 审阅面 | 不扩展为编辑器、不加 LSP;默认隐藏,只能由用户交互打开 | `src/lib/editor/EditorPane.svelte` 等 |
| [x] | 内嵌浏览器保留元素拾取器 | 浏览器仅用于预览与用户主动 pick;不做 agent 浏览器自动化,不把 picker 定义为 browser-use | `src-tauri/src/browser.rs`、`src-tauri/src/browser_init.js`、`src/lib/BrowserPanel.svelte`、`src/lib/browser.svelte.ts` |
| [x] | GitHub PR 作为插件 | 保留 PR 交付能力,但从 core 边界移到插件,不作为桌面核心功能 | `src/lib/gitops.ts`、`src/lib/GitPanel.svelte` |
| [x] | 扩展 ASR 接入 | 保留 MiMo ASR,并扩展到更多 ASR 协议/provider;不将 ASR 归类为 LLM provider | `src/lib/audio.ts`、`src/lib/protocol.ts` |
| [x] | IM 独立 agent | OpenClaw 网关优先;默认 confirm-before-assign;v1 随桌面生命周期运行,不做 always-on daemon,后续有需要再评估 | 见 `docs/im-bridge.md` |
| [x] | 技能来源 | 同时支持官方 JuCode 技能与 [anthropics/skills](https://github.com/anthropics/skills),并展示许可与后端兼容性 | `src/lib/Marketplace.svelte`、`src/lib/protocol.ts` |
| [x] | Provider 目录 | 内置 models.dev 快照 + 复用现有 BYOK 通道 + OpenRouter featured;不内嵌 LiteLLM | `src/lib/settings/`、`src/lib/pricing.ts` |
| [x] | 密钥存储 | 密钥继续存 JSON,以简单加密保护;不接 OS keychain | `src/lib/protocol.ts`(`writeConfig`) |
| [x] | Workspace 持久化 | 迁移到 app-data 文件并带版本;不使用 `localStorage` 作为 Workspace/布局持久层 | `src/lib/RightDock.svelte`、`src/lib/session.svelte.ts` |
| [x] | 产品能力边界 | 不做 memory、computer-use、内置 browser-use;元素拾取器仅是用户控制的 preview + pick | `src/lib/BrowserPanel.svelte`、`src-tauri/src/browser_init.js` |

## 后续项(不影响已锁定方向)

| 状态 | 事项 | 规划 | 相关代码 |
| --- | --- | --- | --- |
| [ ] | GUI/TUI 同会话交接(handoff) | v1 不做;v2 可做"显式关一侧、resume 另一侧"(codex `thread/resume`、claude 会话文件)。永不双活 | `src/lib/backends/{codex,claude}.ts` |
58 changes: 58 additions & 0 deletions docs/im-bridge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# IM 桥设计(IM Bridge)

> 配套阅读:`docs/workbench-plan.md` §3.7。定位:IM 是 JuCode Desktop 唯一的第三方集成方向。
>
> **Owner 决策(2026-08-28,已锁定)**:IM 使用独立 agent;v1 优先接 OpenClaw 网关并默认 confirm-before-assign;不做 always-on daemon,后续有明确需要再评估。

## 1. 形态:独立 IM agent

IM 桥是一个 **独立 agent**,不是聊天会话里的一个功能:

- 它不复用 `src/lib/session.svelte.ts` 里的任何会话;它通过桌面端暴露的 MCP server 与工作台交互。
- 职责只有三类:**查询**(workspace / 项目 / 标签页 / 会话的结构化状态)、**通知**(会话进度与完成事件推送到 IM 渠道)、**指派**(把 IM 侧收到的 prompt 提交给指定会话,经确认队列)。
- 它不直接持有任何引擎 adapter,也不读写用户文件系统。

```
IM 渠道 ── OpenClaw 网关 ── IM agent ── MCP(localhost+token) ── JuCode Desktop
(微信/TG/Discord/飞书) (workspace/会话)
```

## 2. 桌面端 MCP 工具清单

桌面端内置一个仅监听 `127.0.0.1` 的 MCP server(streamable HTTP),供 IM agent 调用:

| 工具 | 类型 | 说明 |
| --- | --- | --- |
| `list_workspaces` | 查询 | 返回 workspace → project → 标签页树(id、名称、路径、后端、布局摘要) |
| `get_session_status` | 查询 | 指定会话的状态:引擎、模型、运行/空闲/等待批准、当前 plan 步骤、最近一条消息摘要 |
| `get_session_transcript_tail` | 查询 | 会话最近 N 条消息的脱敏文本(不含文件内容附件) |
| `list_pending_approvals` | 查询 | 各会话待批准的工具调用摘要 |
| `assign_prompt` | 指派 | 向指定会话提交 prompt;**默认进入确认队列**,返回 queue id |
| `get_assignment_status` | 查询 | 查询指派的状态(排队 / 已放行 / 已拒绝 / 已完成) |
| `subscribe_events` | 通知 | 订阅进度事件流:turn 开始/结束、plan 更新、会话完成、错误、待批准出现 |

**刻意不提供**:文件读写、shell 执行、批准/拒绝工具调用、修改配置——IM 侧永远拿不到直接改动本机的能力。

## 3. 安全模型

1. **仅 localhost**:MCP server 绑定 `127.0.0.1`,不监听外网;与外部渠道的连接由 IM agent 经 OpenClaw 网关向外发起(出站连接),桌面端不开公网入站端口。
2. **Token 鉴权**:桌面端启动时生成随机 token,IM agent 必须携带;token 不落 IM 渠道,只存在于本机配置。
3. **确认队列(confirm-before-assign,默认开启)**:`assign_prompt` 不直接注入会话,而是进入桌面 UI 的确认队列,用户看到"来自 <渠道>/<发送者> 的 prompt → 目标会话"后手动放行。可按渠道+会话粒度选择"信任后自动放行",默认不信任。
4. **无文件系统工具**:见上表;即使 IM agent 被劫持,攻击面也止于"读会话摘要 + 排队一条待确认的 prompt"。
5. **发送者白名单**:渠道侧只响应绑定过的账号/群。

## 4. 渠道接入

v1 统一经 **OpenClaw / Cloudbot 网关** 接入,不在应用内手写 5 套渠道 SDK:

| 渠道 | 接入方式 | 说明 |
| --- | --- | --- |
| Telegram | 官方 Bot API | 经 OpenClaw 渠道插件 |
| Discord | 官方 Bot API(Gateway) | 经 OpenClaw 渠道插件 |
| 飞书 | 官方开放平台机器人 API | 经 OpenClaw 渠道插件 |
| 微信 | **腾讯 openclaw-weixin / iLink 插件** | 走腾讯提供的插件通道,而非第三方协议 hook / 逆向方案。注意:不要将其宣传为"合法官方机器人 API"之类的合规背书;本文档不做任何法律层面的声明,接入前请自行确认适用条款 |

## 5. 边界与后续

- **应用退出后 IM 离线**:v1 的 MCP server 与 IM agent 均随桌面应用生命周期运行,不安装 always-on daemon 或系统服务。仅在后续出现明确需求并重新决策后,才评估独立 daemon。
- v1 通知走轮询/事件订阅二选一实现即可,不引入消息队列等重依赖(遵循 AGENTS.md 轻量原则)。
Loading
Loading