合并远程主分支客户端收口
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
| 提交绑定 | 云端成功上传响应 | Main → submission binding v2 | 只持久化成功的 app/version/review/hash;落盘失败返回固定告警但不反转提交 |
|
||||
| 运营发布 | Works Square 审核与交付 | 公共 `play_url` | 客户端只消费服务端发布结果;真实合同校验 → OSS/CDN 生产链仍待整链验收 |
|
||||
| 可信发布门禁 | source+built+artifact contract | 服务端逐字节重算/合同校验 → 不可变 Release 固化 → 人工审核 | 服务端不运行项目 Vite;仍是不可绕过权威,未来 runtime 强门禁需可信 verifier |
|
||||
| 真机预览 | 项目空间 | Main → Owner preview / `play_url` | 核对 app、version、release 和同源 HTTPS;`runtime_url` 仅一版本兼容回退 |
|
||||
| AI 编程首次发送 | ChatPanel 当前 Agent | Renderer Store → Host API → Main → OpenCode session / prompt | 新建 session 已知为空时直接提交 prompt,不在关键路径等待空历史;历史未知或普通历史会话仍按默认路径加载消息 |
|
||||
| AI 编程模型代理错误 | OpenCode provider 请求 | Main Host AI proxy → Works 模型上游 | 配额耗尽保持独立终止态;只有明确的分组上游饱和才投影为 OpenCode 终止状态,通用限速仍保留 `429` |
|
||||
| 客户端更新检查 | 设置页 | Renderer update store → IPC → Main AppUpdater → 目标 feed | Main 记录并重抛原始错误;Renderer 只显示去重、脱敏的单条提示,稳定源缺包不伪装为最新版 |
|
||||
@@ -24,7 +23,7 @@
|
||||
|
||||
- Main 持有刷新凭据、发布 Token、固定 npm runtime、源码/构建归档、临时目录、幂等键和 submission binding v2;Renderer 不持有归档路径、构建 origin 或自动部署状态。
|
||||
- 项目内 `.niancode/project.json` 保存 `ProjectType`;Main 在配置写入和目录复用时保持其不可变,并在打包时重新读取校验。
|
||||
- Renderer 仅持有短效公开会话状态、提交展示状态和安全投影后的公共播放/短时预览 URL。
|
||||
- Renderer 仅持有短效公开会话状态和提交展示状态。
|
||||
- 本地构建临时目录、HTTP origin 和预检 WebContents/partition 只属于一次调用;预检读取与 `built_archive` 相同的内存字节,但结果不写为可信上传 receipt,也不覆盖生产 opaque-origin。
|
||||
- 旧 schema v1 `submitted` 记录迁移并保留;旧 `armed`、`waiting_for_package`、`waiting_for_login`、`uploading`、`failed` 归一为 `legacy_retired`,不再启动 watcher 或上传任务。
|
||||
- AI 绘画 Conversation 持有消息、Brief、Quote、`turnRevision` 和服务端 Session 绑定;Workspace 持有 Conversation 列表、生成任务和资产。
|
||||
@@ -37,8 +36,8 @@
|
||||
|
||||
## External Interfaces
|
||||
|
||||
- Works Square 项目创建、版本上传、构建状态、Owner 状态与 Release preview API。
|
||||
- 本机 Host API 的发布与真机预览路由;发布路由要求 Renderer capability。
|
||||
- Works Square 项目创建、版本上传、构建状态与 Release 状态 API。
|
||||
- 本机 Host API 的发布路由;发布路由要求 Renderer capability。
|
||||
- 本机 Host API 的 OpenCode session、history 与 prompt 路由,以及 Main-owned AI 模型代理。
|
||||
- Main-owned electron-updater IPC 与 Works Square 平台/架构稳定 feed;正式安装产物发布不由 Renderer 控制。
|
||||
- 服务端安全投影后的公共 `play_url`;只接受同源 HTTPS、精确 App 路径和可信版本状态。
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
| `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` | 公共播放与 Owner preview URL 的共享安全校验 | 公共 `play_url` 必须同源 HTTPS 且精确匹配 App 路径 |
|
||||
| `electron/api/routes/device-preview.ts` | 精确提交版本的待审/已发布真机预览解析 | 待审使用短时 Release preview,已发布优先 `play_url` |
|
||||
| `electron/api/works-play-url.ts` | 公共播放 URL 的共享安全校验 | 公共 `play_url` 必须同源 HTTPS 且精确匹配 App 路径 |
|
||||
| `src/pages/Chat/OpencodeChatPanel.tsx` | AI 编程 Agent 选择、首次 session 创建与 prompt 提交流程 | 新 session 仅在消息缓存 own-key 已知时使用不读取历史的快速选择 |
|
||||
| `src/stores/opencode.ts` | OpenCode runtime、session、消息缓存与提交状态 | `sessionMessagesBySessionId` 键缺失表示未知,存在空数组表示已知为空;普通选择默认刷新历史 |
|
||||
| `electron/api/routes/ai-proxy.ts` | Main-owned 模型代理、凭据边界与上游响应投影 | 仅对明确上游分组饱和做终止态兼容投影,通用限速保持 `429` |
|
||||
|
||||
@@ -2,20 +2,19 @@
|
||||
|
||||
## Current Architecture
|
||||
|
||||
Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展示;Electron Main 持有认证、文件系统、安全打包、Works Square 网络访问和预览 URL 校验。
|
||||
Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展示;Electron Main 持有认证、文件系统、安全打包、Works Square 网络访问和发布安全校验。
|
||||
|
||||
## Main Components
|
||||
|
||||
| Component | Responsibility | Notes |
|
||||
|---|---|---|
|
||||
| Renderer | 项目配置、一键提交状态、真机二维码 | 不接触账号 Token、ZIP、幂等键或本地绝对路径 |
|
||||
| Renderer | 项目配置、一键提交状态 | 不接触账号 Token、ZIP、幂等键或本地绝对路径 |
|
||||
| Host API | 校验本地项目请求并投影安全响应 | 发布 mutation 还必须通过 Renderer capability;Host token/base 不能单独触发发布 |
|
||||
| Project Configuration & Template | 保存不可变 `ProjectType`,原子生成新项目骨架 | 小游戏/小程序生成受控 Vite 模板;自定义保持最小项目空间 |
|
||||
| Project Release Builder | Main-owned 安全快照、本地 npm/Vite 构建、双归档与 artifact contract | 固定 npm 11.6.2;Vite 由项目 lockfile 锁定;产物与预检使用同一内存字节 |
|
||||
| Works Session | 七天真实活动滑动续期 | 刷新凭据由 Main 安全持有 |
|
||||
| Submission Binding | 保存云端已接受的精确 app/version/review/hash 绑定 | schema v2 只记录成功提交;旧中间态迁移为 `legacy_retired`,不恢复后台任务 |
|
||||
| Play URL Projection | 校验服务端公共播放地址 | 只接受同源 HTTPS 和精确 `/apps/{app_id}/`;优先 `play_url`,`runtime_url` 仅一版本回退 |
|
||||
| Device Preview | 核对本地绑定、远端版本和 Release | 待审使用短时 Owner preview;已发布使用安全投影后的 `play_url` |
|
||||
| Built Artifact Preflight | 在上传前对最终 built snapshot 做桌面/移动 UX fail-fast | Main 使用临时 loopback origin 与 Electron WebContents/CDP;不使用 Playwright、不生成可信证明 |
|
||||
| App Updater | Main 选择平台/架构 feed、驱动 electron-updater 并记录原始诊断 | Renderer 只接收状态和脱敏后的单条用户提示;稳定源缺包保持错误 |
|
||||
| AI Design Workspace | 保存项目身份、Conversation 列表、生成任务和资产 | 任务和资产在切换 Conversation 后继续可见 |
|
||||
@@ -34,7 +33,7 @@ Makelore 是 Electron 桌面客户端。Renderer 负责项目操作与状态展
|
||||
- 本地 `projectType` 只选择产品路径和内部构建 preset,不是可信授权声明;Main 仍需安全打包,服务端仍需独立校验清单和包体。
|
||||
- 云端确认上传成功后,本机 submission binding 失败只能产生固定、无路径的 `binding_warning`,不能把请求改判为失败;Renderer 仍继续轮询服务端校验与 Release 固化状态。
|
||||
- 公共播放投影只有在上游 `playable === true`、版本名非空且 URL 通过同源 HTTPS、无 userinfo/loopback、长度、精确路径和无 query/fragment 校验时才可播放;不可信数据 fail closed。
|
||||
- Renderer 只能获得安全状态字段和可展示的播放/短时预览 URL,不得持有发布凭据、归档路径或自动部署状态。
|
||||
- Renderer 只能获得安全状态字段和安全投影的公共播放 URL,不得持有发布凭据、归档路径或自动部署状态。
|
||||
- 落盘文件名 `works-cloud-deploy.json` 仅为已安装客户端的数据兼容;领域模型和代码接口是 submission binding,不表示仍存在 cloud deployment coordinator。
|
||||
- AI 绘画中,一个 Workspace 可包含多条 Conversation;消息、Brief、Quote 和 `turnRevision` 属于 Conversation,生成任务和资产属于 Workspace。新建 Conversation 不得隐式创建新 Workspace。
|
||||
- 每条 Conversation 复用服务端持久 Agent Gateway Session。客户端不得在注销或退出时 DELETE 该 Session;只关闭本地事件流并清除本机 Session-id 缓存,重新访问时从 Conversation API 刷新。
|
||||
|
||||
@@ -6,7 +6,6 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
|
||||
|
||||
- `86ece3a` / `4dde8f3`:客户端登录七天滑动续期及集成提交。
|
||||
- `724290e` / `dcc92fc`:Main-owned 一键打包提交审核及集成提交。
|
||||
- `1a19ad9` / `f02e99e`:项目真机预览、待审 Release Owner preview 及集成提交。
|
||||
- `493b31c`:客户端三类 `ProjectType`、小游戏/小程序受控发布模板与自定义项目发布隔离。
|
||||
- `4df0477` / `8dd99c1`:客户端静态发布唯一链路、旧 Compose 协调链退役及安全边界补强。
|
||||
- `4980894` / `03dae62`:AI 绘画 Enter 发送及同一 Workspace 下的多 Conversation 客户端模型。
|
||||
@@ -15,6 +14,7 @@ This file is the integrated default-branch snapshot. Feature tasks record progre
|
||||
- `08da976` / `0ee5254`:AI 编程首次发送已知空 session 快速路径与明确上游饱和终止态投影。
|
||||
- `809364e` / `88281b8` / `7a807a2`:AI 绘画单参考图图生图选择/上传交互、最新客户端主线集成及旧版 Brief medium 缺失兼容。
|
||||
- `f05b9d4` / `e221374`:Updater 稳定源缺包诊断与用户错误脱敏修复,以及当前 `main` 上的图生图最终合并提交。
|
||||
- `f4113a8`:远程主线客户端收口,包含启动预热、课程 Skill、项目 Agent 模型配置、浅色界面整合,并移除独立真机预览与内置 Superpowers。
|
||||
|
||||
## Current Focus
|
||||
|
||||
@@ -28,7 +28,7 @@ Updater 仍由 Electron Main 选择目标 feed、记录原始诊断并保持失
|
||||
|
||||
## Recently Completed
|
||||
|
||||
- 2026-08-08:合并登录续期、一键发布和真机预览;发布成功后保存精确 app/version/review 映射,Renderer 不接触 Token、ZIP 或本地路径。
|
||||
- 2026-08-08:合并登录续期和一键发布;发布成功后保存精确 app/version/review 映射,Renderer 不接触 Token、ZIP 或本地路径。
|
||||
- 2026-08-08:补齐跨平台 Electron E2E fixture、Windows ZIP 预检和异常成功响应安全投影。
|
||||
- 2026-08-09:新建项目支持小游戏、小程序和自定义三类不可变产品类型;前两类生成固定 Vite 发布模板,自定义及缺少类型字段的旧项目不显示一键提交入口。
|
||||
- 2026-08-10:删除客户端旧 Compose deploy-check、watcher/arm/upload 协调和手工 ZIP 路由;submission binding v2 保留旧 `submitted` 绑定并把旧中间态归一为 `legacy_retired`,同时补齐 Renderer capability、`play_url` 安全投影和本机绑定失败告警。
|
||||
@@ -47,8 +47,7 @@ Updater 仍由 Electron Main 选择目标 feed、记录原始诊断并保持失
|
||||
|
||||
1. 成组核对客户端 source+built+contract 上传 → 服务端逐字节校验 → OSS immutable Release → CDN/Edge 的发布契约与客户端 `play_url` 消费契约。
|
||||
2. 配置真实生产环境,分别执行“小游戏/小程序创建 → 客户端本地构建与同字节预检 → 提交 → 服务端合同/摘要校验与不可变 Release 固化 → 运营批准 → App 播放”。
|
||||
3. 核对待审 Owner preview 到期刷新、CDN 发布/撤回、生产监控和告警证据。
|
||||
4. 在一个客户端兼容版本且服务端与存量数据稳定提供 `play_url` 后,删除 `runtime_url` 回退。
|
||||
3. 核对生产环境的提交状态、构建结果和告警证据。
|
||||
|
||||
## Open Questions / Blockers
|
||||
|
||||
@@ -57,7 +56,7 @@ Updater 仍由 Electron Main 选择目标 feed、记录原始诊断并保持失
|
||||
## Risky Areas
|
||||
|
||||
- 一键提交已成功但本机 submission binding 落盘失败时必须保持提交成功、显示固定 `binding_warning` 并继续轮询,避免用户误判上传失败。
|
||||
- 公共 `play_url` 必须满足 Works Square 同源 HTTPS、无 userinfo/loopback、精确 `/apps/{app_id}/` 路径、无 query/fragment、版本非空且上游标记可播放;待审预览仍需绑定当前项目、精确版本和 Release。
|
||||
- 公共 `play_url` 必须满足 Works Square 同源 HTTPS、无 userinfo/loopback、精确 `/apps/{app_id}/` 路径、无 query/fragment、版本非空且上游标记可播放。
|
||||
- `/api/works/projects/publish-source` 必须在读取凭据和项目文件前校验 Renderer capability;Host token/base 不能替代该 UI 边界。
|
||||
- `works-cloud-deploy.json` 仅是已安装数据的兼容文件名,不代表客户端仍拥有自动部署协调器;旧中间态不得恢复为后台任务。
|
||||
- 刷新凭据、发布 Token、ZIP、幂等键和重试只能由 Electron Main 持有。
|
||||
|
||||
@@ -94,15 +94,64 @@ Gate result:
|
||||
|
||||
## Outcome
|
||||
|
||||
- Not completed.
|
||||
- `git fetch origin main --prune` resolved the authoritative remote tip to
|
||||
`f4113a872f7cd6aee6829c9597c882846bc4085b`. The histories had diverged at
|
||||
`253bad8b40c8cd20a25362006f5d80a4e5c4cd4a`: local `main` contained 18
|
||||
integration/preparation commits not on the remote, while the remote contained
|
||||
one consolidation commit not on local `main`.
|
||||
- Merged `origin/main` with `--no-ff --no-commit`, keeping local `main` as the
|
||||
first parent. The only textual conflicts were `README.md` and
|
||||
`.project-docs/20-architecture/data-flow.md`; both were reconciled
|
||||
semantically instead of choosing either side wholesale.
|
||||
- Accepted the remote product consolidation that removes the independent Device
|
||||
Preview capability and the bundled Superpowers distribution, while retaining
|
||||
the reviewed local Updater, image-to-image, first-chat, AI-proxy, publishing,
|
||||
and `/deliverables` behavior. Canonical architecture/current-state documents
|
||||
were updated to remove stale live Device Preview claims and record remote tip
|
||||
`f4113a8` under `Integrated Through`.
|
||||
- Preserved the remote startup warmup, curated course skills, per-Agent model
|
||||
ownership, recursive Skill details, OpenCode path resolution, authentication
|
||||
hardening, light visual consolidation, fonts, and window material changes.
|
||||
- Corrected an upstream course-skill manifest mismatch by retiring the absent
|
||||
`deploy-publish-check` skill instead of advertising it as bundled, with a
|
||||
regression assertion in the manager suite.
|
||||
- Corrected merge-exposed test defects without weakening production behavior:
|
||||
project-config request mocking now receives `RequestInit`; the Windows runtime
|
||||
queue test injects a deterministic port-owner lookup; the legacy agent-folder
|
||||
test accepts the intentionally absent directory; and an unused test binding
|
||||
was removed.
|
||||
- Rebased the Electron E2E contract on the consolidated UI: Code/Canvas enter
|
||||
through the module chooser, hidden module actions are expanded before use,
|
||||
Models is reached through the account/settings flow, Provider seeding uses the
|
||||
Main-owned Host API, and project-backed chat mocks return valid initialized
|
||||
configuration. Two Channels specs were removed because the remote product
|
||||
consolidation removed their UI, route, and Host API rather than relocating
|
||||
them. Stable test IDs were restored to the retained proxy settings controls.
|
||||
- The merge is fully verified and ready for an independent final review and
|
||||
normal push. The final merge commit and remote equality are recorded after
|
||||
those operations complete.
|
||||
|
||||
## Verification
|
||||
|
||||
- Not run.
|
||||
- `pnpm install --frozen-lockfile` — passed.
|
||||
- High-risk focused Vitest selection — 19 files, 494/494 passed.
|
||||
- `pnpm test` — 146 files, 1574/1574 passed.
|
||||
- `pnpm run typecheck` — passed.
|
||||
- `pnpm run lint:check` — passed with 0 errors and 6 existing warnings.
|
||||
- `pnpm run build:vite` — passed.
|
||||
- `pnpm run test:electron:windows` — 3/3 passed.
|
||||
- `pnpm run test:e2e` — rebuilt Renderer/Main/Preload and passed 24/24.
|
||||
- `git diff --check` and `git diff --cached --check` — passed.
|
||||
|
||||
## Follow-ups
|
||||
|
||||
- None recorded.
|
||||
- Signed packaged updater smoke and live Works Square/Bailian image-to-image
|
||||
smoke remain external release gates; this Git synchronization does not claim
|
||||
that either production environment has been exercised.
|
||||
- A cancelled-before-spawn OpenCode restart can still spend roughly one second
|
||||
probing a Windows port owner. The queue regression is now deterministic; a
|
||||
future performance change should distinguish an attached runtime before
|
||||
skipping that lookup so attached-runtime restart behavior remains intact.
|
||||
|
||||
## Promotion Candidates
|
||||
|
||||
|
||||
@@ -11,8 +11,7 @@
|
||||
- 项目 Vite config/plugins 以桌面用户权限执行,因此发布链只适用于用户信任的本地项目;它不是 sandbox。安装依赖需要网络,运行时闭包缺失或版本不符必须 fail closed。
|
||||
- 提交前预检必须由 Main 以一次性 loopback origin 提供最终上传 `built_archive` 的同一内存文件快照,以 fresh 非持久 Electron WebContents/CDP 检查桌面/移动视口、运行错误、白屏与外域访问;不得调用 Playwright 或污染用户浏览器状态。
|
||||
- 客户端预检是可绕过的 UX fail-fast,不上传可信 receipt,也不声称具备生产 opaque-origin parity。服务端把源码、构建归档和 contract 当作不可信字节,独立重算、校验并固化不可变 Release;人工审核仍是不可绕过发布门禁。未来若要求 runtime 强门禁,必须由可信 verifier 绑定精确构建产物。
|
||||
- 待审版本只能通过绑定精确 Release 的短时 Owner preview 验收;旧版本、构建中或失败状态不能生成可扫码假象。
|
||||
- 发布和预览安全边界由 Electron Main 持有,Renderer 不接触账号 Token、ZIP、幂等键和本地绝对路径。
|
||||
- 发布安全边界由 Electron Main 持有,Renderer 不接触账号 Token、ZIP、幂等键和本地绝对路径。
|
||||
- 发布 Host API 必须在读取凭据、查询项目和打包前校验 Renderer capability;仅持有 Host token/base 的非 UI 调用方不得发起发布。
|
||||
- 客户端只持久化服务端已接受的 submission binding v2。旧 `submitted` 绑定必须保留;旧 `armed`、`waiting_for_package`、`waiting_for_login`、`uploading`、`failed` 必须迁移为可理解的 `legacy_retired`,不得恢复后台任务。
|
||||
- 云端上传成功但本机 submission binding 保存失败时,提交仍视为成功;客户端显示固定、无本地路径的告警并继续轮询服务端校验与 Release 固化状态,避免诱导重复提交。
|
||||
|
||||
Reference in New Issue
Block a user