IPC 通信机制
OpenCowork 主进程与渲染进程之间的 IPC 组织方式。
IPC 通信机制 / IPC Communication
OpenCowork 使用 Electron IPC 把渲染进程和主进程连接起来。渲染进程发起请求,主进程执行系统能力,结果再回流到 UI。
通道组织 / Channel organization
IPC 按领域分组,避免字符串散落在业务代码里:
| 领域 | 典型通道 |
|---|---|
| 文件系统 | fs:*, ssh:fs:* |
| 数据库 | db:* |
| 设置与配置 | settings:*, config:* |
| Agent / 运行时 | agent:*, sidecar:*, team:*, team-worker:* |
| 消息平台 | plugin:* |
| MCP | mcp:* |
| Cron | cron:* |
| SSH / Terminal | ssh:*, terminal:* |
| 搜索 / Web / Browser | web-search:*, browser:* |
| 通知 / 截图 / 输入 | notify:*, screenshot:*, input:* |
| 图像 | image:*, clipboard:* |
| 资源目录 | skills:*, agents:*, commands:*, prompts:* |
| 迁移 / 其他 | migration:*, wiki:*, git:*, process:*, oauth:* |
调用模式 / Invocation patterns
1) Request / response
大多数读写操作都通过 invoke 完成:
const servers = await window.electron.ipc.invoke('mcp:list')主进程侧通常对应:
ipcMain.handle('mcp:list', () => readServers())2) 事件推送
当主进程需要主动通知 UI 时,会使用 send 或安全封装:
plugin:incoming-messagecron:firedteam:*goal:*chat:*
3) Fire-and-forget
某些状态同步不需要等待返回值,例如写消息、更新任务、保存设置。前端会调用 invoke,但不强依赖返回结果。
重要通道示例 / Important channels
| 通道 | 用途 |
|---|---|
settings:get / settings:set | 设置读取与保存 |
config:get / config:set | 安全配置读写 |
db:* | SQLite 业务数据 CRUD |
cron:* | Cron 任务和运行日志 |
mcp:* | MCP server 管理和能力发现 |
plugin:* | 消息平台插件实例、消息路由和自动回复 |
ssh:* | SSH 连接、远程文件、远程终端 |
team-runtime:* | Team Runtime 持久化和快照 |
team-worker:* | 隔离 worker 启停 |
web-search:* | 搜索与抓取 |
browser:* | 内置浏览器控制 |
notify:* | 桌面通知 |
设计原则 / Design principles
- 主进程是唯一的系统能力入口
- 通道名要能表达业务域
- UI 只持有最小必要信息
- 复杂对象优先用 DTO / shared types 表达
- 事件推送只负责通知,状态详情由存储或查询接口提供
一个实用判断 / Practical rule
如果某个能力会碰到文件、数据库、SSH、窗口、通知、系统代理、更新、外部消息平台或后台任务,它就应该放在 Main,并通过 IPC 暴露;不要直接在 renderer 里硬做。