多窗口架构
wescode 的 Window-Process-Cell 三位一体架构。
核心模型
- 1 workspace = 1 Go 进程 = 1 Cell(
ws-{hash}) - N 窗口 = M Go 进程(M ≤ N,相同工作区的窗口共享进程)
- 1 Electron 主进程 = 1 WescodeBackendMainService
CellID 派生
Cell ID 由 workspace 路径确定性派生:
sha256(canonicalize(root))[:4] → "ws-a1b2c3d4"
- Multi-root workspace:所有文件夹属于同一 Cell,ID = hash(primary folder)
- 无工作区 = Config Mode(无 Cell,无 Go 进程)
不变量
INV-WS-05:Cell 不可变
Go 进程内 Cell 不可变。切换由 TypeScript 层路由到不同进程。
INV-WS-06:事件路由
Go 后端通知绝不跨窗口/跨工作区广播:
chat/stream按 JSON-RPC 请求 id 路由到发起窗口- 其他通知只扇出到绑定该后端的窗口
INV-WS-07:方法名映射
Renderer 方法名(camelCase)与 Go RPC 名通过 METHOD_MAP 解耦。
INV-WS-08:生命周期回收
窗口关闭后,若 workspace 无任何窗口引用则 shutdown 该进程。
INV-WS-11:对话权随 done 归还
chatInFlight 锁的生命周期 = 用户可见生成轮次:
- 流终端事件(done/error/interrupted)到达即释放
- RPC 返回后的收尾(Settlement、CKG 写库)是后台整理
Config Mode
无工作区时进入 Config Mode:
- 不创建任何 Cell
- 只支持
configModeAllowed白名单 RPC(auth/provider/settings) - 前端 GateGuard 引导打开文件夹
并发控制
同一时刻最多一个 Chat Run(chatInFlight per workspace key):
- 第二个窗口的 Chat 被拒绝:"该工作区已有生成任务进行中"
- Cancel 仅作用于发起窗口的 Run
相关文档
- 工作区即 Cell →
workspace-cell.md - Go→TS 通知契约 →
notification-contract.md - Device Agent →
device-agent.md