[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-81425":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":9,"language":10,"languages":9,"totalLinesOfCode":9,"stars":11,"forks":12,"watchers":13,"openIssues":13,"contributorsCount":14,"subscribersCount":14,"size":14,"stars1d":15,"stars7d":16,"stars30d":16,"stars90d":14,"forks30d":14,"starsTrendScore":17,"compositeScore":18,"rankGlobal":9,"rankLanguage":9,"license":9,"archived":19,"fork":19,"defaultBranch":20,"hasWiki":21,"hasPages":19,"topics":22,"createdAt":9,"pushedAt":9,"updatedAt":23,"readmeContent":24,"aiSummary":25,"trendingCount":14,"starSnapshotCount":14,"syncStatus":26,"lastSyncTime":27,"discoverSource":28},81425,"Galcode_island","sjyinzju\u002FGalcode_island","sjyinzju","一个面向本地代码项目的桌面 Agent 工作台，把 Claude Code、OpenCode 和 Codex 放进同一套桌宠式界面里。",null,"TypeScript",40,7,1,0,3,6,9,49.31,false,"main",true,[],"2026-06-12 04:01:33","# Galcode Island\n\n> 一个面向本地代码项目的桌面 Agent 工作台，把 Claude Code、OpenCode 和 Codex 放进同一套桌宠式界面里。\n\n[![Tauri 2](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTauri-2-24C8DB?logo=tauri&logoColor=white)](https:\u002F\u002Ftauri.app)\n[![React 19](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FReact-19-149ECA?logo=react&logoColor=white)](https:\u002F\u002Freact.dev)\n[![TypeScript](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FTypeScript-6-3178C6?logo=typescript&logoColor=white)](https:\u002F\u002Fwww.typescriptlang.org)\n[![Rust](https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FRust-stable-DEA584?logo=rust&logoColor=white)](https:\u002F\u002Fwww.rust-lang.org)\n\nGalcode Island 是一个 Tauri 桌面应用，用来在本地项目中运行多个编码 Agent CLI。它不重新实现 Agent 能力，而是直连各 CLI 的原生协议，再补上一层项目化桌面体验：多 tab、会话持久化、结构化流式输出、全局搜索、结果总结、后续追问，以及会随任务状态变化的桌宠反馈。\n\n这份 README 按当前代码重新分析后撰写，避免继续沿用旧文档里已经过时的功能描述。涉及实现细节时，以 `src\u002F` 和 `src-tauri\u002Fsrc\u002F` 下的源码为准。\n\n## 功能概览\n\n- 统一接入 Claude Code、OpenCode、Codex 三个本地 Agent backend。\n- 每个项目会话独立成 tab，拥有自己的工作目录、backend、流式记录、结果卡片和原生会话续接 ID。\n- 将 Agent 过程归一成结构化 block：用户输入、正文、思考、命令、命令输出、todo、文件、diff、工具调用、状态、stderr 和错误。\n- 中栏紧凑展示长命令输出、stderr 和 diff，点击后在右栏查看完整详情。\n- 通过 Zustand localStorage 持久化 tab、近期 block、结果摘要、历史记录、设置和个人档案。\n- 关闭 tab 时归档为历史会话，可从历史面板恢复项目路径、backend、上次结果和可用的 native session\u002Fthread id。\n- 支持两种搜索：左栏跨项目\u002F历史\u002F输出搜索，以及当前 tab 内的 `Cmd\u002FCtrl+F` 页内查找。\n- 可选接入 OpenAI 兼容 LLM，用于中文总结、凉宫春日风格反馈、下一步建议，以及可选的中英输入翻译。\n- 打包时可尝试内置 CLI runtime，失败或跳过时回退到用户系统 `PATH` 上的 CLI。\n- 局域网移动端访问：在「设置 → 局域网移动端访问」里设置密码并启动内置 HTTP 服务，手机 \u002F 平板浏览器打开桌面端给出的 URL 即可使用。**移动端跑的是同一份 React 前端**（包含桌宠 Live2D \u002F 立绘 \u002F 凉宫春日总结 \u002F 结果卡片），通过桥接层把 `invoke`\u002F`listen` 翻译成 HTTP 请求 + 长轮询事件流；窄屏自动切换为顶栏 + 抽屉式侧栏 + 紧凑桌宠的布局。token 缓存在设备本地 30 天免重输；改密或撤销会让所有移动端重新登录。\n- 跨设备状态同步：所有 zustand persist store（tabs \u002F settings \u002F profile）通过 `createSharedStorage` 写入 Rust 端的镜像 + 同步落盘到 `lan-storage.json`，**桌面端是唯一权威数据源**。任一端的修改都会广播 `storage:\u002F\u002Fchanged` 事件触发其它端 rehydrate；用客户端 ID 防回环。移动端启动时直接从镜像 hydrate，能立刻看到桌面端的项目列表 \u002F 历史会话 \u002F LLM 配置等。\n\n## 当前支持的 Backend\n\n| Backend | 接入方式 | 会话模型 | 说明 |\n| --- | --- | --- | --- |\n| Claude Code | 长驻 `claude -p` 进程，使用 `stream-json` stdin\u002Fstdout | 每个 tab 一个 stream client，用 Claude session id 续接 | 启动参数包含 `--permission-mode acceptEdits`；可配置 model、effort、proxy、binary。 |\n| Codex | 共享 `codex app-server`，通过 JSON-RPC 通信 | 全局单 app-server 进程，每个 tab 一个 `thread_id` | 使用 `thread\u002Fstart`、`thread\u002Fresume` 和 `turn\u002Fstart`；避免多个 Codex 进程抢 `~\u002F.codex\u002Fauth.json`。 |\n| OpenCode | 每个 tab 启动一个 `opencode serve`，监听 `127.0.0.1`，端口从 `4096` 起分配 | 每个 tab 一个 OpenCode server 进程和 session id | 使用 HTTP 与 SSE；可配置 provider、model、auth mode、proxy、binary。 |\n\n目前 `start_agent` 只实现了这三个 backend。TypeScript 类型里保留了未来 backend 名称，但 Gemini 和 Cursor 还没有真正接入。\n\n## 架构\n\n```text\nReact \u002F Vite 前端\n  - tabs、sidebars、search、stream blocks、result card、pet character\n  - Zustand stores，持久化到 localStorage\n        |\n        | Tauri invoke\u002Flisten\n        v\nRust 后端\n  - ipc::commands \u002F ipc::events\n  - agent::manager 负责 lifecycle、routing、stop、finalize\n  - llm::* 负责可选的 OpenAI 兼容翻译与总结\n        |\n        +-- Claude Code stream-json process\n        +-- Codex shared app-server JSON-RPC process\n        +-- OpenCode per-tab HTTP\u002FSSE serve process\n```\n\n运行时以 `run_id` 做路由，`run_id` 与前端 tab id 对齐。同一个 tab 开始新 turn 时，会先停止该 tab 尚未完成的旧 turn；其他 tab 不受影响。\n\n## 安装\n\n### 前置要求\n\n- Node.js 20 或更新版本\n- Rust stable toolchain，并包含 `rustfmt`、`clippy`\n- Tauri 2 对应平台依赖\n- 至少安装并登录一个受支持的 Agent CLI\n\n按需安装 backend CLI：\n\n```bash\nnpm install -g @anthropic-ai\u002Fclaude-code\nnpm install -g @openai\u002Fcodex\nnpm install -g opencode-ai\n```\n\n然后完成对应登录：\n\n```bash\nclaude auth login\ncodex login\nopencode auth login\n```\n\n应用内的设置面板也能打开 Claude Code、Codex、OpenCode 的登录终端，并在登录后刷新状态或验证连接。\n\n### 本地运行\n\n```bash\ngit clone https:\u002F\u002Fgithub.com\u002Fsjyinzju\u002FGalcode_island.git\ncd Galcode_island\nnpm install\nnpm run dev\n```\n\n首次进入时选择项目目录和默认 backend，然后在输入气泡中发起任务。`Enter` 发送，`Shift+Enter` 换行。\n\n## LLM 总结与翻译\n\n不配置 LLM API Key 也可以使用应用。此时底层 Agent 的输出会原样展示，结果卡片只提供基础提示。\n\n配置 LLM 后，后端会调用 OpenAI 兼容的 `\u002Fchat\u002Fcompletions` 接口，用于：\n\n- 生成凉宫春日风格的完成反馈\n- 生成客观的中文结果摘要\n- 生成下一步建议按钮\n- 在开启“转换为英文输入”后，将中文 prompt 翻成英文再交给 Agent\n- 在翻译模式开启且输出不是中文时，将 Agent 输出翻回中文\n\n推荐在应用设置中配置。也可以在启动进程前提供环境变量：\n\n```bash\nexport LLM_API_KEY=\"...\"\nexport LLM_BASE_URL=\"https:\u002F\u002Fapi.openai.com\u002Fv1\"\nexport LLM_MODEL=\"gpt-4o-mini\"\nnpm run dev\n```\n\n当前预设服务商包括 DeepSeek、OpenAI、Moonshot、通义千问、智谱 GLM、OpenRouter 和自定义 OpenAI 兼容端点。`转换为英文输入` 默认关闭。\n\n## 基本工作流\n\n1. 选择项目目录与 backend。\n2. 在主输入气泡中提交任务。\n3. 在中栏查看 Agent 的 block 流，包括消息、命令、todo、文件操作、diff 和错误。\n4. 点击 command、diff、stderr block，在右栏查看完整内容。\n5. 任务完成后，从结果卡片点击建议，或直接输入追问继续同一 tab 的会话。\n6. 使用左栏管理活动项目、历史会话和跨项目搜索。\n\ntab 是主要工作单元。每个 tab 都有自己的 backend、项目路径、prompt 历史、native session id、stream blocks 和结果状态。关闭 tab 会写入历史列表，而不是直接丢弃全部上下文。\n\n## 持久化与续接语义\n\nGalcode Island 会持久化 UI 状态，但不会在 Tauri 应用退出后继续保活 CLI 子进程。重启后：\n\n- 已有 tab 会从 localStorage 恢复\n- 上次结果和近期 stream blocks 会重新显示\n- Claude session id、Codex thread id、OpenCode session id 会作为下一轮 turn 的 resume hint\n- 如果上一轮 Agent 已经产出 raw result，但 LLM finalize 阶段被退出打断，应用会尝试重新 finalize\n\n如果应用真正退出时 Agent turn 仍在运行，该 turn 不会从中途继续执行。重新打开后需要发起追问或重试任务。\n\n## 常用脚本\n\n```bash\nnpm run dev              # 启动 Tauri 桌面开发应用\nnpm run dev:web          # 仅启动 Vite 前端\nnpm run typecheck        # TypeScript 类型检查\nnpm run check:rust       # 在 src-tauri 中执行 cargo check\nnpm run fmt:rust         # 在 src-tauri 中执行 cargo fmt\nnpm run lint:rust        # cargo clippy --all-targets -D warnings\nnpm run prepare:runtime  # 为当前平台暂存 CLI runtime\nnpm run build            # prepare runtime + build web + tauri build\nnpm run clean            # 清理 dist、src-tauri\u002Ftarget 和暂存 runtime\n```\n\n`npm run dev` 会通过 Tauri 启动 Vite，端口固定为 `1420`。\n\n## 打包\n\n```bash\nnpm run build\n```\n\nTauri build 前会执行 `scripts\u002Fprepare-runtime.mjs`。脚本会把 CLI npm 包安装到临时目录，再尝试把当前平台的二进制复制到：\n\n```text\nsrc-tauri\u002Fresources\u002Fruntime\u002F\u003Cplatform>-\u003Carch>\u002F\u003Ckind>\u002F\u003Cbinary>\n```\n\n这个步骤是 best effort。某个 backend runtime 如果被跳过或暂存失败，打包产物会回退到用户系统 `PATH` 上查找 `claude`、`codex` 或 `opencode`。\n\n可以按需跳过某个 runtime：\n\n```bash\nnode scripts\u002Fprepare-runtime.mjs --skip-claude\nnode scripts\u002Fprepare-runtime.mjs --skip-codex\nnode scripts\u002Fprepare-runtime.mjs --skip-opencode\n```\n\n发布二进制前，请确认被打包 CLI 的再分发许可。\n\n## 安全模型\n\nGalcode Island 当前定位是本地可信开发工具，权限策略偏自动化：\n\n- Claude Code 使用 `--permission-mode acceptEdits` 启动。\n- Codex 对命令、权限和文件改动审批做自动放行；文件改动路径会按当前实现做工作目录范围判断。\n- OpenCode 会启动 permission auto-approve poller。\n- 底层 Agent backend 可能读取、修改、创建文件，也可能执行命令，具体行为取决于对应 CLI。\n\n建议只在可信仓库中使用。开始任务前保持代码已提交，任务后认真审查 diff，不要随意把包含敏感资料或无关个人文件的目录作为项目目录。\n\n设置不是安全密钥库。全局 LLM API Key 会持久化在前端 localStorage 中；OpenCode API Key 会写入 OpenCode 本地 `auth.json`，同时也会保留在设置表单状态里。\n\n## 仓库结构\n\n```text\nsrc\u002F\n  App.tsx                      # React 顶层应用、IPC hooks、主布局\n  components\u002F                  # UI：侧栏、流式 block、设置、桌宠、气泡\n  hooks\u002F                       # Tauri IPC、stream listener、搜索和主题快捷键\n  stores\u002F                      # Zustand app\u002Ftab\u002Fsettings\u002Fprofile\u002Fui stores\n  types\u002F                       # 前端 IPC、backend、agent、stream block 类型\n\nsrc-tauri\u002F\n  src\u002Fagent\u002F                   # Claude、Codex、OpenCode 接入与运行时状态\n  src\u002Fipc\u002F                     # Tauri commands、events、tray\n  src\u002Fllm\u002F                     # OpenAI 兼容 LLM client 与 prompts\n  src\u002Fsession\u002F                 # session snapshot、状态、清理\n  tauri.conf.json              # 窗口、构建、bundle resources 配置\n\nscripts\u002F\n  run-tauri.mjs                # 跨平台 Tauri 启动器\n  run-cargo.mjs                # 跨平台 cargo wrapper\n  prepare-runtime.mjs          # 打包前暂存 CLI runtime\n\ndocs\u002F\n  architecture.md\n  ipc-protocol.md\n  character-and-prompts.md\n```\n\n`docs\u002F` 下有一些实现说明，但部分内容可能落后于快速迭代的源码。需要精确判断时，以代码为准。\n\n## 常见问题\n\n### 检测不到 backend\n\n先确认 CLI 已安装并登录，然后在设置面板刷新状态。如果 binary 不在 `PATH` 上，可以在 backend preferences 中填写显式路径。\n\n### OpenCode 服务商列表为空\n\n先在设置里启动 OpenCode 服务，再刷新 provider 列表。服务商和模型目录来自运行中的 `opencode serve` API。\n\n### LLM 总结失败\n\n检查 Base URL、API Key 和模型 ID。后端期望服务商兼容 `POST \u002Fchat\u002Fcompletions`，模型列表拉取则使用 `GET \u002Fmodels`。\n\n### 打包产物找不到 CLI\n\n运行 `npm run prepare:runtime` 并检查 `src-tauri\u002Fresources\u002Fruntime`。如果某个 runtime 没有暂存成功，需要让用户全局安装对应 CLI，或在设置里指定 binary 路径。\n\n### Vite 端口被占用\n\n开发模式使用固定端口 `1420` 且启用 strict port。关闭占用该端口的进程后再运行 `npm run dev`。\n\n## 项目状态\n\n当前版本：`0.1.0`。\n\n核心桌面工作流已经实现，包括多 tab 路由、结构化流式输出、会话持久化、backend 设置、历史会话、搜索和打包支持。公开发布前仍建议继续补强交互式权限审批、密钥存储、自动化 UI 测试、素材授权检查，以及 `docs\u002F` 与代码的一致性。\n\n## License\n\nMIT","Galcode Island 是一个面向本地代码项目的桌面 Agent 工作台，将 Claude Code、OpenCode 和 Codex 集成到同一套桌宠式界面中。其核心功能包括多 tab 项目会话管理、结构化流式输出、全局搜索及结果总结等，支持通过 Tauri 框架构建的跨平台桌面应用，并利用 React 和 TypeScript 实现前端交互。该工具特别适用于需要在同一环境中同时使用多个编码助手进行开发或调试的场景，提供了一种高效且直观的方式与不同后端服务交互，同时保持了良好的用户体验和数据持久性。此外，它还具备局域网内移动端访问的能力，进一步增强了使用的灵活性。",2,"2026-06-11 04:05:01","CREATED_QUERY"]