Does this repo contain opencode desktop code?
This post might have stale content, as HEAD is 65 commits ahead.
这个仓库中有 opencode desktop 的代码吗,如果有,详细解释它的架构
现在我有了充分的信息。让我为用户提供一个详细的架构解析。
##是的,这个仓库中包含 OpenCode Desktop 的代码 ✅
OpenCode Desktop 就在 packages/desktop 目录中。这是一个用 Electron 构建的桌面应用。我来详细解释它的架构:
##🏗️ OpenCode Desktop 架构详解
###1. 整体架构设计
OpenCode Desktop 采用 多进程架构,遵循 Electron 的标准设计模式:
┌─────────────────────────────────────────────────────┐
│ Main Process (Node.js) │
│ ┌─────────────────────────────────────────────┐ │
│ │ - Electron 应用生命周期管理 │ │
│ │ - 窗口管理 (BrowserWindow) │ │
│ │ - IPC 通信处理 │ │
│ │ - 本地服务器启动 (Sidecar) │ │
│ │ - 系统集成 (菜单、通知、更新等) │ │
│ └─────────────────────────────────────────────┘ │
│ ↑↓ IPC │
│ ┌─────────────────────────────────────────────┐ │
│ │ Preload Script │ │
│ │ - 安全隔离 API 暴露到渲染进程 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
↕ IPC
┌─────────────────────────────────────────────────────┐
│ Renderer Process (Web View) │
│ ┌─────────────────────────────────────────────┐ │
│ │ @opencode-ai/app (SolidJS UI) │ │
│ │ - 用户界面 │ │
│ │ - 应用逻辑 │ │
│ │ - 通过 window.api 调用主进程函数 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ Utility Process (Sidecar) - OpenCode 服务器 │
│ ┌─────────────────────────────────────────────┐ │
│ │ - HTTP 服务器 │ │
│ │ - SQLite 数据库 │ │
│ │ - 业务逻辑 │ │
│ │ - 文件监控 │ │
│ └─────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────┘
###2. 关键组件详解
####A. Main Process (src/main/index.ts)
主进程负责:
- 应用初始化:设置应用名称、App ID、用户数据路径
- Sidecar 管理:启动和管理本地 OpenCode 服务器
- 窗口管理:创建和维护主窗口
- IPC 通信:注册所有 IPC 处理器
- 系统集成:
- 菜单和快捷键
- 深层链接(Deep Links)处理
- 应用更新
- 崩溃报告
- 通知
// 关键流程
1. 设置代理和证书
2. 启动 Sidecar 进程(OpenCode 服务器)
3. 创建加载窗口
4. 等待服务器就绪
5. 创建主窗口并加载渲染器
####B. Preload Script (src/preload/index.ts)
在主进程和渲染进程之间提供受控的 API 接口:
// 暴露给渲染进程的 API 对象 (window.api)
export type ElectronAPI = {
// 服务器管理
killSidecar: () => Promise<void>
awaitInitialization: (onStep: (step: InitStep) => void) => Promise<ServerReadyData>
// 文件选择
openDirectoryPicker: (opts?) => Promise<string | string[] | null>
openFilePicker: (opts?) => Promise<string | string[] | null>
saveFilePicker: (opts?) => Promise<string | null>
// 窗口管理
getZoomFactor: () => Promise<number>
setZoomFactor: (factor: number) => Promise<void>
showWindow: () => Promise<void>
// 存储
storeGet: (name: string, key: string) => Promise<string | null>
storeSet: (name: string, key: string, value: string) => Promise<void>
// 其他
parseMarkdownCommand: (markdown: string) => Promise<string>
checkAppExists: (appName: string) => Promise<boolean>
wslPath: (path: string, mode: "windows" | "linux" | null) => Promise<string>
// ... 还有很多其他方法
}
####C. IPC 处理 (src/main/ipc.ts)
通过 ipcMain 注册所有处理器,处理渲染进程的请求:
export function registerIpcHandlers(deps: Deps) {
ipcMain.handle("kill-sidecar", () => deps.killSidecar())
ipcMain.handle("get-window-config", () => deps.getWindowConfig())
ipcMain.handle("open-directory-picker", (...) => { /* 文件选择对话框 */ })
ipcMain.handle("store-get", (...) => { /* 获取本地存储值 */ })
// ... 等等
}
####D. Sidecar Process (src/main/sidecar.ts)
在单独的 Utility 进程中运行 OpenCode 服务器:
// Sidecar 初始化步骤:
1. 接收来自主进程的启动命令
2. 准备环境变量和证书
3. 如果需要,运行 SQLite 数据库迁移(有进度回调)
4. 启动 HTTP 服务器(监听 localhost:port)
5. 发送"ready"消息给主进程
6. 监听"stop"命令以优雅关闭
为什么使用 Sidecar?
- 不阻塞主进程和渲染进程
- 提供隔离的环境
- 可以独立监控和管理
####E. 窗口管理 (src/main/windows.ts)
// 关键功能:
- createMainWindow():创建主应用窗口
- createLoadingWindow():创建加载窗口
- registerRendererProtocol():注册 "oc://" 协议用于加载资源
- 缩放管理(pinch zoom)
- 标题栏主题(Windows)
- 窗口状态持久化
####F. 渲染进程 (src/renderer/index.tsx)
- 使用 SolidJS 框架构建 UI
- 导入
@opencode-ai/app包(共享的 UI 应用代码) - 设置深层链接监听
- 配置 Sentry 错误跟踪
- 提供平台检测(macOS/Windows/Linux)
###3. 通信流程
####初始化流程
用户启动应用
↓
Main Process 启动
↓
Sidecar Process 启动 OpenCode 服务器
↓
数据库迁移(如需要)→ 进度回调给渲染进程
↓
服务器就绪,发送 ServerReadyData
↓
渲染进程接收 URL、用户名、密码
↓
连接到本地 OpenCode 服务器
####用户交互流程
渲染进程 UI 事件
↓
调用 window.api.someFunction()
↓
Preload 拦截,通过 IPC 发送到主进程
↓
主进程 IPC 处理器执行
↓
返回结果给渲染进程
↓
UI 更新
###4. 构建和工具链
// electron.vite.config.ts 配置
主进程构建:
- 入口:src/main/index.ts 和 src/main/sidecar.ts
- 外部化依赖:@lydell/node-pty
- 虚拟模块:virtual:opencode-server(导入编译好的服务器)
预加载脚本:
- 入口:src/preload/index.ts
- 输出:CommonJS 格式
渲染进程:
- 使用 electron-vite + Vite + Solid.js
- 两个 HTML 入口:main 和 loading
- 启用 Source Maps 和 Sentry 上传
###5. 跨平台支持
// 平台相关功能:
macOS:
- Dock 图标管理
- 原生菜单
Windows:
- 标题栏覆盖(自定义标题栏)
- Windows Store 集成
- 进程退出代码处理
Linux:
- Wayland/X11 支持选择
- XDG Base Directory 遵循
WSL 支持:
- 路径转换(Windows ↔ Linux)
- WSL 启用/禁用配置
- Terminal 集成
###6. 关键依赖
{
"electron": "41.2.1",
"electron-vite": "^5",
"electron-updater": "^6",
"electron-store": "^10",
"solid-js": "SolidJS 框架",
"@opencode-ai/app": "共享的 UI 代码",
"@lydell/node-pty": "PTY 支持(终端)",
"drizzle-orm": "数据库 ORM",
"marked": "Markdown 处理"
}
###7. 存储机制
- electron-store:持久化本地配置(缩放、WSL 配置、默认服务器 URL 等)
- SQLite:服务器数据库(通过 Sidecar 管理)
- Electron userData:应用数据目录
###8. 安全特性
- ✅ IPC 隔离:渲染进程只能通过预定义的 API 调用主进程
- ✅ Preload 脚本:使用 contextBridge 安全地暴露 API
- ✅ 内容安全策略:自定义协议注册
- ✅ 错误报告:Sentry 集成用于生产环境监控
这个架构设计非常现代化,采用了 Electron 最佳实践,特别是使用 Utility Process 而不是 Worker Process 来运行服务器,这样可以获得更好的性能和可靠性。
END OF POST