packages/desktop 是 ZCode 的主形态(desktop-first)。src/ 分五段:main/、host/、preload/、renderer/、scheduler/,另有 shared/。

五段进程模型

Electron Main ──utilityProcess.fork()──> Window Host(唯一 PID / 窗口)
   │  postMessage / MessagePort            ├─ LocalSource → workspaceKey → zcode-cli (stdio)
   │                                        ├─ RemoteConnectionRegistry (SSH/WSL/Docker/Server)
   │                                        ├─ WindowHostControllerProjection(内存,可重建)
   │                                        └─ AttachmentRegistry(desktop-continuous / web-remote-replayable)
Renderer ──MessagePort(@zcode/rpc)──> Host

权威定义在 desktop/src/host/index.ts 头部注释:「每个窗口对应一个独立的 host process」。

  • Main 只做平台调度/窗口/原生能力/attachment 薄转发,不持有 task/session/stream/queue 业务状态。详见 architecture。
  • Host 由 createLocalServices({ parentPort }) 初始化,进程内维护远端连接注册表、Controller 投影、附件注册表。

Main ↔ Host 通信(非 stdio)

desktop/src/main/desktopHostProcess.ts(912 行)是唯一收口:

  • spawnHostProcess()(:157)用 electronUtilityProcess.fork(hostModulePath) 起 Host。
  • 用结构化 {type, ...} postMessage 传控制消息(HostMessageTypes / HostResponseTypes)。
  • 用 MessageChannelMain 建 service port(port1 给 renderer/host,port2 给 Host,:755-767)。
  • Host 上报:数据库启动状态、结构化日志、网络遥测、资源采样、Agent 进程 spawned/ready/exited/error、Cron/OffPeak 结果、BrowserExecute、插件沙箱登记、CUA 状态。
  • disposeHostProcessAndWait()(:857)等待 Host 退出且强杀延迟下限 3.5s,避免编排器子进程成孤儿。

Desktop ↔ Agent stdio 协议

Host 侧 services/src/zcode-agent/zcodeAgentProcessManager.ts 用 spawn() 拉起 zcode-cli(或 remote runtime):

  • 按 workspaceKey 维护单例 client(startingByWorkspaceKey)。
  • 透 ZCodeStdioTransport(NDJSON,一行一消息)+ ZCodeProtocolClient。
  • Host↔CLI 是 ZCode Protocol JSON over stdio NDJSON,method 如 v4/command;CLI 是 conversation 的唯一权威事实源。详见 zcode-protocol。
  • 带完整进程树终止(processTreeTerminator)与 stderr 收集。

窗口级 Local Host 与远端连接注册表

windowRemoteConnectionRegistry

desktop/src/host/windowRemoteConnectionRegistry.ts 是窗口内唯一 owner,管理 ConnectionEntry(key / 脱敏 target / state / abort / session 集 / workspaceKeys / runningTaskCount):

  • 状态机 connecting → online → closing/absent(含 failed/disconnected)
  • remoteSessionId → workspaceKey scoped service 路由
  • SSH pooled / WSL TTL / Docker·Server dedicated 生命周期
  • generation 防旧异步覆盖新连接

windowHostControllerService

desktop/src/host/windowHostControllerService.ts(801 行):WindowHostControllerRuntime 是”Local Host 内聚合权威,不持久化,每次在线查询从 tasks-index 重建投影,断连只冻结最后成功内存快照”。

  • sourceKey = kind\0remoteSessionId/local\0(workspaceIdentity||workspacePath)
  • 远端 source offline 时禁止写操作、禁止回落本地;重连走 replaceDisconnectedSource 原子替换。

windowHostAttachmentRegistry

attachmentId → tracked attachment,每个 attachment 带可信 clientMode、scope、generation、port;detachStaleRemoteSessionAttachments 防旧 generation 残留。详见 zcode-protocol。

插件沙箱(plugin-sandbox)

跨四层实现:main/pluginSandbox/、host/pluginSandbox/、preload/pluginSandbox/、renderer/src/plugin-sandbox/。契约见 main/pluginSandbox/CONTRACT.md:

  • Main 拥有沙箱内容/guest/端口/浏览器分区。
  • guest 固定 contextIsolation/sandbox/webSecurity,禁 Node / webviewTag / plugins / popups。
  • scheme zcode-sandbox://shell-<id>/;partition persist:plugin-sandbox-v2-<hash(appIdentity)>(稳定 origin,跨进程恢复 localStorage/IndexedDB)。
  • CSP default-src none,frame-ancestors 仅该 shell;最多 64 实例。
  • 受信 relay shell 只转发原始 JSON-RPC(一条 MessageChannel),shell 不解析协议。
  • Gen UI 复用同一机具但用内存分区 gen-ui-<appIdentity>,contentKind:"gen-ui" 独立凭证。

Host 侧 host/pluginSandbox/index.ts 仅 createPluginSandboxRegistrationBridge(只拥有 pending 传输,不存沙箱/会话事实)。详见 plugin-system。

其它

  • main/index.ts(~108KB)集中主进程编排(窗口/菜单/自动更新/webRemoteControlManager/浏览器视图/流程编排)。
  • scheduler/ 是独立调度进程(cron / off-peak / automation)。
  • 打包配置:electron-builder.config.js、scripts/、tsup.config.ts、vite.config.ts;E2E 用 WDIO(wdio.conf.ts)。详见 distribution、engineering。

相关页面