# Module Map ## Source Layout | Path | Responsibility | Owner Notes | |---|---|---| | `src/components/works/ProjectPublishAction.tsx` | 可发布项目的一键提交、云构建轮询与用户可理解状态 | 只通过 Renderer API 提交非敏感元数据;绑定告警不终止轮询 | | `src/lib/works-square.ts` | Renderer 侧 Works Square Host API 契约与安全错误映射 | 不接触 Token、ZIP、本地绝对路径或自动部署状态 | | `electron/api/routes/works.ts` | Works Host API、Renderer capability 门禁、上游安全投影 | 发布凭据、打包、上传与本地绑定均在 Main 内完成 | | `electron/services/project-release-builder.ts` | Main-owned 安全快照、本地 npm/Vite 构建、source+built 双归档与 v1 contract | 固定 npm 11.6.2;项目 Vite 由 lockfile 决定;Vite config/plugins 以桌面用户权限执行 | | `electron/services/publish-runtime.ts` | 安装包内 npm 闭包定位与 Electron Node 执行 | 不回退全局 npm/PATH;缺失或版本不符 fail closed | | `electron/services/static-release-server.ts` | 用内存 built snapshot 建立一次性 loopback origin | 预检和最终上传归档必须来自相同文件字节;总是清理临时服务 | | `electron/agent-browser/module.ts` | built artifact 的桌面/移动临时 WebContents/CDP 预检 | UX fail-fast;不生成可信 receipt、不得升级为平台证明 | | `electron/agent-browser/electron-adapter.ts` | Electron WebContents/CDP 设备指标、事件与临时 partition 适配 | probe 不挂载 UI,并在结束后销毁视图、清理隔离存储 | | `electron/services/project-packager.ts` | 受控项目扫描、静态 ZIP 生成和敏感/历史控制文件排除 | 只允许可发布 `ProjectType`,不提供 Compose 或手工 ZIP 路径 | | `electron/services/works-submission-binding.ts` | submission binding v2 持久化与旧 schema 迁移 | 旧中间态终止为 `legacy_retired`;文件名暂作安装兼容 | | `electron/api/works-play-url.ts` | 公共播放 URL 的共享安全校验 | 公共 `play_url` 必须同源 HTTPS 且精确匹配 App 路径 | | `src/pages/Chat/OpencodeChatPanel.tsx` | AI 编程 Agent 选择、首次 session 创建、per-Session prompt 提交与消息/压缩混合时间线 | 新 session 仅在消息缓存 own-key 已知时使用不读取历史的快速选择;选中 Session 只投影自己的 run error,top-level error 仅用于真实全局错误 | | `src/lib/opencode-session-state.ts` | OpenCode 会话消息与上下文压缩时间线的规范化、hydration 和事件归并 | 压缩 UI identity 不变;native Part/event identity 用于回放去重,completed 状态不可降级 | | `src/stores/opencode.ts` | OpenCode runtime、session、消息缓存、per-Session 提交/启动确认与压缩生命周期 | 每个 Session 独立持有 run/error/queue;10 秒 run-token watchdog 不把 Host 接受或 user transcript 当 ACK,超时只终止对应 Session 且不自动重放;`session.compacted` 只完成压缩项,真实 idle 才释放 run 队列 | | `electron/api/routes/opencode.ts` | Main-owned OpenCode execution acceptance、provider/runtime freshness 与项目 Agent 门禁 | message/command/summarize 共用 bounded manager FIFO;Agent-scoped execution 再进入 per-project FIFO,typed pending 必须发生在 runtime 调用前,普通执行路径不自动 restart/reload/dispose | | `electron/opencode/project-agent-runtime.ts` | 项目 Agent desired/applied fingerprint、runtime generation provenance、live registry acceptance 与配置 mutation 串行化 | live `/agent` 只证明 id;只有 owned fresh generation 可应用内容 fingerprint,attached/unknown fail closed,用户修改的 retired Agent 文件不得被删除 | | `electron/opencode/runtime-config-readiness.ts` | manager + generation scoped provider/runtime stale latch | timeout/partial persistence 保持 sticky uncertain 状态;只有成功显式 apply 后的合格 fresh generation 可解除,迟到 lease 不能改写 readiness | | `electron/api/routes/ai-proxy.ts` | Main-owned 模型代理、凭据边界与上游响应投影 | 仅对明确上游分组饱和做终止态兼容投影,通用限速保持 `429` | | `shared/opencode-error-details.ts` | OpenCode 上游饱和错误的窄化共享分类 | 不以通用 `rate_limit_exceeded` 单独判定饱和 | | `electron/main/updater.ts` | 目标 feed 解析、electron-updater 生命周期与原始诊断 | 缺少稳定 manifest 保持错误;事件/Promise 重复失败按检查实例去重 | | `src/components/settings/UpdateSettings.tsx` | 更新状态、重试与用户可读错误展示 | 只显示一条简洁中文提示;技术诊断统一回退到本地化通用文案 | | `shared/image-workspace.ts` | AI 绘画 Workspace、Conversation、Task、Asset 与事件共享契约 | Conversation 状态与 Workspace 任务归属必须分离 | | `electron/api/routes/image-workspace.ts` | AI 绘画 Host API 与本地事件流投影 | Renderer 只通过该路由访问 Main-owned workspace adapter | | `electron/image-workspace/works-square-workspace.ts` | Works Square 多 Conversation 云端适配器与双向 Gateway 命令/事件映射 | 使用服务端持久 Session;WebSocket 传输故障才以同一幂等 ID 回退 REST;未知 Gateway 错误文本不得穿透安全投影;本地清理不 DELETE 远端 Session | | `electron/image-workspace/local-workspace.ts` | 未打包开发模式的本地 Workspace 适配器和 v2→v3 迁移 | 仅开发使用,不得成为打包回退 | | `src/stores/image-workspace.ts` | 当前 Workspace/Conversation、项目任务及流式更新状态 | Quote/task 按 Workspace 无 UI 错误副作用地对账;Conversation 写入按 Workspace-load + Conversation-selection generation/revision 防护 | | `src/pages/ImageCanvas/index.tsx` | Conversation 对话、Quote 确认、统一任务列表、新会话入口与单图来源选择器 | 图片 Brief 选择/上传图生图参考图;视频 Brief 绑定首帧;均提交一个 Workspace Asset ID | | `src/components/layout/ImageWorkspaceSidebar.tsx` | Workspace 与近期 Conversation 切换/创建 | 切换会话不清空项目级任务 | | `shared/image-prompt-museum.ts` | Prompt Museum 列表、分类、详情、署名与分页共享 DTO | 客户端不包含内容数据集,只定义服务端字段契约 | | `electron/api/routes/image-prompt-museum.ts` | Main-owned Museum 列表/详情代理与 Works 登录态 | 仅 GET 固定路径和白名单查询;Renderer 不获得 Bearer Token | | `src/pages/ImagePromptMuseum/index.tsx` / `src/lib/image-prompt-museum.ts` / `src/stores/image-prompt-museum.ts` | Museum 搜索/筛选/详情与一次性 Prompt 回填 | 原 Prompt 只带回 Canvas 输入框,不自动发送;页面不接受投稿或互动 | | `shared/learning.ts` / `src/lib/learning.ts` | Learning 项目列表、详情、媒体和下载结果的共享 DTO/Renderer facade | 所有访问走固定 Host API;Renderer 不持有 Token、任意上游 URL、归档或本地路径 | | `electron/api/routes/learning.ts` / `electron/services/learning-project-download.ts` | Main-owned Learning 项目代理、受控媒体读取和原生 ZIP 保存 | 固定 Works 路径、严格 DTO/MIME/大小边界、最多五跳同源重定向、SHA-256/ZIP 签名校验和原子重命名 | | `src/pages/Learning/` / `src/components/layout/LearningSidebar.tsx` | 分页项目卡片、README 详情和下载入口 | 保留登录与 `module_access.learning`;README 禁用原始 HTML,图片使用受控媒体路径,旧生成/播放器入口不存在 | | `src/pages/AiHardware/index.tsx` | Robot 管理、现有六位 Binding,以及已实现的 default-on 引导式热点配网状态机 | 只编排非敏感步骤;不接收 Wi-Fi 密码,不把 `bound` 展示为在线证明 | | `src/lib/ai-hardware.ts` | Renderer 侧 Robot Host API 类型、安全错误映射和稳定 Binding/hotspot facade | 读取 Main-owned capability,调用固定 portal-open,并只传递短效 hotspot candidate ID;不添加任意 URL、SSID 或 Renderer IPC | | `electron/api/routes/ai-hardware.ts` | Main-owned Robot 云端代理,以及本地 capability/portal/hotspot actions | 默认开启、精确环境值 `0` 回滚;所有本地操作必须在 Works token/上游访问前返回,且只投影稳定安全错误 | | `electron/robot-hotspot/index.ts` | Robot hotspot 深模块:候选过滤/去重/TTL、操作互斥、超时和精确 SSID 核验 | 只接受 Adapter 输出与不透明 candidate ID;Renderer 不能选择任意 SSID | | `electron/robot-hotspot/windows.ts` | Windows 原生 WLAN 扫描、临时开放网络连接和当前 SSID 查询 | 懒加载 `wlanapi.dll`;不使用 `netsh`、不保存 profile、不主动断开 | | `electron/robot-hotspot/macos.ts` | macOS CoreLocation 授权与 worker-owned CoreWLAN 扫描/关联/核验 | Objective-C 对象不跨线程;取消/超时终止 worker,旧终止屏障阻止迟到权限/native continuation | | `electron/robot-hotspot/adapter.ts` | 平台 Adapter 的最小内部契约与稳定错误分类 | 平台细节不进入 Host/Renderer 公共 DTO | ## Dependency Direction - Renderer UI → Renderer API contract → Main Host routes → Main services → Works Square;Renderer 不反向读取 Main 凭据、文件系统或归档。 - AI 编程 Renderer per-Session run state → Host API → Main manager-scoped acceptance → per-project Agent acceptance → OpenCode runtime;OpenCode provider 请求再经 Main AI proxy 访问模型上游。Renderer 不直接持有上游凭据或本地 runtime URL,Main 临界区只覆盖配置/请求 acceptance,不覆盖模型回复时长。 - Project configuration 决定产品分流;Main release builder 生成 source/built/contract,服务端独立重算和校验决定发布安全,本地 `ProjectType` 不是授权结论。 - Built artifact preflight 检查最终上传的同字节快照,但客户端可被绕过且不产生可信 receipt;服务端仍是合同、摘要和不可变 Release 安全权威。 - Robot Renderer → typed AI hardware API → Main Host route → Robot Hotspot Module → Windows/macOS Adapter。云端 Binding 仍由 Main 代理;热点选择/连接移入页面,但家庭 Wi-Fi 凭据输入仍只留在固件 Portal,系统 Wi-Fi 保留为兜底。 - Prompt Museum Renderer → typed Host API facade → Main fixed list/detail route → Works Square。Museum 只把用户明确选择的 Prompt 原文暂存到进程内 Store 并导航回当前 Canvas;不会直接触发 Agent 命令或生成任务。 - Learning Renderer → typed Host API → Main fixed project routes → Works Square list/detail/media/archive。Main 代理受控图片并持有原生保存与归档校验;Renderer 只获得安全 DTO、图片数据和保存结果。 ## Risky Or Sensitive Areas - `electron/api/routes/works.ts` 同时承担发布 capability、上游安全投影和错误脱敏,变更时必须验证未在拒绝前读取凭据或项目文件。 - `project-release-builder.ts` 执行受信本地项目的 Vite config/plugins,拥有桌面用户权限;必须保持路径、环境、时间、输出、进程树和临时目录限制,不得包装为 sandbox。 - `electron/agent-browser/module.ts` 的预检必须继续拒绝外域访问、隔离临时 partition 并清理所有 view/listener;不能因本地通过而跳过服务端逐字节校验。生产 opaque-origin 行为不由该 loopback 检查覆盖。 - `works-cloud-deploy.json` 是兼容文件名;不得因名称重新引入自动部署协调语义。 - `runtime_url` 是一个客户端版本的迁移回退;删除前必须确认服务端和存量数据稳定提供 `play_url`。 - `ai-proxy.ts` 的上游饱和状态投影依赖当前固定 OpenCode 的重试语义和窄化错误文案;升级 runtime 或调整上游错误格式时必须复核,不能把所有 `429` 统一终止。 - OpenCode 压缩时间线依赖 native compaction Part、Session run token 与 runtime generation 的关联;hydration 必须保持 completed 单调,不能用 `session.compacted` 提前结束 run 或释放 queued prompt。 - OpenCode execution acceptance 同时涉及 provider persistence、runtime lifecycle、Agent config mutation 和 runtime HTTP。锁顺序必须保持 manager → project,所有等待与 HTTP 都使用同一 hard deadline/AbortSignal;timeout 后 lease 必须撤销,queued cancellation 不能让后续 mutation 绕过前驱。 - OpenCode Agent hot reload 没有 authoritative whole-instance quiescence oracle。不得从 `/session/status` 推断 dispose/reload 安全,也不得以 live 同 id 代替内容 fingerprint;若需要即时热更新,必须先获得 upstream directory-scoped invalidation 或权威 quiescence seam。 - `electron/main/updater.ts` 的稳定源错误归一化必须保持窄化:只识别 Works Square 对应 manifest 的 404,不得吞掉其他 feed/网络/签名错误;Renderer 的脱敏边界不能取代 Main 原始日志。 - 多 Conversation 事件处理必须区分对话快照与 Workspace 任务更新;不得用任务时间戳推进 Conversation 流水位,也不得让旧会话的迟到流覆盖当前会话。 - Quote 编辑、重报价、确认和项目删除都跨 Renderer/Main/Works Square。异步结果必须核对当前 Workspace + Conversation;删除当前项目时必须先使旧选择和事件流失效,再加载剩余 Workspace。 - Prompt Museum 图片和来源 URL 来自服务端数据。服务端必须完成内容授权/署名审核;若未来需要凭据化素材,应新增 Main-owned 媒体代理,不能把对象存储凭据放进 Renderer URL。 - Learning 的远端 JSON、Markdown、媒体、错误和 ZIP 下载跨信任边界;必须保持严格 DTO、固定项目/媒体路径、可信 raster MIME、媒体/README/归档大小、同源重定向、声明字节数、SHA-256、ZIP 签名、一次 401 refresh 和固定安全错误,不能把 Renderer 或 README 变成任意 Works/网络/文件系统代理。 - Gateway 命令的 REST fallback 只处理 WebSocket 发送、断连和 ACK 超时,必须复用 `client_command_id`;业务错误回退会造成重复提交。Quote 任务恢复只更新 Workspace 所有的任务,不能覆盖当前 Conversation。 - `closeEventSessions` 只负责本地流和缓存生命周期;远端 Conversation Session 是服务端持久资源。 - 单图来源选择器当前仍由精确中文 quick reply 触发,并以 Brief medium 判断图生图或视频首帧用途;扩展更多输入用途前应先把消息协议升级为结构化 action/purpose,避免展示文案与行为继续耦合。 - Guided Hotspot Binding 已由产品决策默认开启,并通过 native dependency 执行未经认证的热点扫描/连接。未完成指定固件镜像核对、六位码发行契约、签名 macOS x64/arm64 worker/ASAR/Koffi 验证、Windows 真机和完整 Electron/Robot smoke 前不得宣称完整兼容;现场异常使用精确环境值 `0` 回滚。 ## Last Updated 2026-08-20