86 lines
11 KiB
Markdown
86 lines
11 KiB
Markdown
# Task: 客户端静态发布链路唯一化
|
||
|
||
## Identity
|
||
|
||
- Task ID: 20260810-static-release-only-a91c
|
||
- Mode: Feature
|
||
- Branch: codex/20260810-static-release-only-a91c-static-release-only
|
||
- Worktree: D:\Datas\OthersProjects\makelore-static-release-only-a91c
|
||
- Base commit: 2e737dee316058bbc3bb8a98ae8f50223871bd7d
|
||
- Owner: codex
|
||
- Status: Ready for Integration
|
||
|
||
## Scope
|
||
|
||
- 将客户端发布入口收敛为唯一静态链路:项目配置一键提交,由 Main 安全打包并上传服务端 Builder。
|
||
- 为作品广场与真机预览接入 `play_url`,同时保留一个客户端版本的 `runtime_url` 兼容回退。
|
||
- 删除 Compose deploy-check skill、提示词、辅助文件、直传 ZIP 路由以及自动 watcher/arm/upload 协调链。
|
||
- 将旧 `works-cloud-deployment` 收敛为最小提交版本绑定存储,并迁移已经落盘的旧状态。
|
||
- 更新聚焦测试、README 与任务记录;不修改一般 OpenCode、AI 设计、编辑器 Dockerfile 语法能力或服务端实现。
|
||
|
||
## Intent And Constraints
|
||
|
||
- `ProjectPublishAction -> publishWorksProjectSource -> createStaticProjectPackage -> 服务端上传` 是唯一用户发布路径,不允许重新引入手工 ZIP、Docker、Compose 或服务器登录步骤。
|
||
- Renderer 不持有发布 Token、归档路径或自动部署状态;版本绑定只在 Main 成功收到上传结果后落盘。
|
||
- 已发布作品与设备预览优先使用服务端 `play_url`;`runtime_url` 只做一个客户端版本的兼容回退,且继续执行同源 HTTPS 和版本一致性检查。
|
||
- 已经 `submitted` 的旧绑定必须保留;旧 `armed`、`waiting_for_package`、`waiting_for_login`、`uploading`、`failed` 不再恢复后台任务,而是确定性迁移为可理解、可重试的终止状态。
|
||
- 为兼容已安装客户端,落盘文件名暂时保留 `works-cloud-deploy.json`,但内容升级为 schema v2,代码接口和领域名统一为 submission binding。
|
||
- `project-packager` 继续排除历史 Docker/Compose/发布协调文件,避免把遗留控制文件上传到静态 Release;这不是重新支持 Compose。
|
||
- 只在独立 feature worktree 修改任务拥有的文件,不覆盖主工作区或其他任务 WIP;本任务不直接合并 `main`。
|
||
|
||
## Plan
|
||
|
||
1. 固定静态发布单入口和最小版本绑定契约,设计旧状态迁移结果。
|
||
2. 接入 `play_url` 安全投影、广场卡片和真机预览优先级,保留 `runtime_url` 兼容回退。
|
||
3. 删除旧 skill、提示词、helper、协调器、路由和对应测试,保留静态打包上传路径。
|
||
4. 补充绑定迁移、路由、预览与一键提交回归,运行 typecheck、lint、构建和 Electron E2E 收集。
|
||
5. 更新 README、任务记录和文档门禁,提交独立 feature commit,等待集成任务合入。
|
||
|
||
## Outcome
|
||
|
||
- 新增 `WorksSubmissionBindingRecord` schema v2 和 Main-owned 最小存储,只提供 `recordSubmitted`、`get`、启动迁移,不再监听构建产物、等待登录或代替用户上传。
|
||
- 为兼容现有安装数据继续读取 `works-cloud-deploy.json`:旧 `submitted` 记录保留 app/version/review/hash 绑定并升级;五类旧中间/失败状态统一写回 `legacy_retired`、`LEGACY_AUTO_DEPLOY_RETIRED` 和“在项目配置中点击提交审核重新提交”的下一步。
|
||
- 保留并验证 `ProjectPublishAction -> createStaticProjectPackage -> /api/projects/{app}/versions/upload` 一键静态路径;上传成功后仅记录精确提交版本,记录失败不反向伪造上传失败。
|
||
- `ProjectPublic` 和 Host 安全投影新增 `play_url`。广场卡片与真机预览优先使用 `play_url`,只有字段缺失时才读取 `runtime_url`;预览仍限制 Works Square 同源 HTTPS、精确版本和短时 owner preview。
|
||
- 删除旧 Compose deploy-check 内置 skill、机器检查器、`works-publish`/deploy-check helper、自动部署协调器、Renderer arm/fetch API、手工 ZIP 上传 Host 路由,以及 `/works-publish`、`/works-deploy-check`、`/works-cloud-deploy` OpenCode 路由。
|
||
- 内置 skill 清单把 `deploy-publish-check` 标记为 retired,客户端启动时会清理已安装副本;课程、开发和营销提示统一改为“用户一键提交、平台安全打包与云端验收”,不再要求 Dockerfile、Compose、ZIP 或服务器信息。
|
||
- 项目进度同步改用已提交版本绑定识别服务端项目,不再依赖 AI 生成的 `works-publish.json`。README 已同步静态 Release、`play_url` 和兼容边界。
|
||
- 保留一般 OpenCode/Monaco 的 Dockerfile 语法支持、AI 设计能力、会话运行时清理和打包器对历史控制文件的安全排除;这些能力不属于旧 Compose 发布协调链。
|
||
- 补强 Main 边界:`/api/works/projects/publish-source` 必须携带 Renderer capability,缺失或错误时在读取发布凭据、查询项目和打包前直接返回 403,OpenCode 子进程不能只凭 Host token/base 绕过 UI 发起发布。
|
||
- 抽取共享播放 URL 校验器供 ProjectPublic 投影和设备预览复用:只接受与 Works Square base 同源的 HTTPS、禁止 userinfo/loopback、限制长度,公共作品必须精确落在 `/apps/{encodeURIComponent(app_id)}/` 且无 query/fragment;只有 `playable === true`、版本名非空且首选 `play_url`(字段缺失时才兼容 `runtime_url`)可信时才对 Renderer 标记可播放。
|
||
- 上传云端成功但本机版本绑定落盘失败时,Main 返回固定、无磁盘路径的结构化 `binding_warning`;Renderer 显示“已提交云端,但本机预览绑定保存失败;可重新打开项目/重新提交”,同时继续轮询云构建,避免把本地辅助状态失败误报为上传失败。
|
||
- schema v2 读取改为逐字段验证,约束 submitted/legacy_retired 的状态专属字段,并在按项目读取时校验绑定内 `project_id` 与当前项目一致,拒绝复制或串项目的绑定文件。
|
||
- Electron E2E 增加用户可见入口断言:新建小游戏后只展示一个“一键提交审核”按钮,旧“自动部署/部署发布检查”入口不可见。
|
||
|
||
## Verification
|
||
|
||
- `pnpm run typecheck`:通过。
|
||
- `pnpm exec vitest run tests/unit/works-submission-binding.test.ts tests/unit/device-preview-routes.test.ts tests/unit/project-progress-sync.test.ts tests/unit/works-routes.test.ts tests/unit/works-square.test.ts tests/unit/opencode-routes.test.ts tests/unit/project-packager.test.ts`:7 files / 185 tests passed;覆盖五类旧状态归一、旧 submitted 保留、`play_url` 优先与 `runtime_url` 回退、旧路由下线和静态上传版本绑定。
|
||
- `pnpm exec vitest run tests/unit/project-publish-action.test.tsx tests/unit/works-project-publish.test.ts tests/unit/device-preview-page.test.tsx`:3 files / 31 tests passed;覆盖客户端一键提交动作、静态提交视图与真机预览 UI。
|
||
- `pnpm exec vitest run tests/unit/opencode-manager.test.ts -t "removes retired bundled skills"`:1 passed;确认已安装的旧 deploy-check skill 会被清理。
|
||
- 对本任务全部变更 TS/TSX 文件执行 scoped ESLint:0 errors;仅 `src/pages/Makelore/index.tsx` 有 4 条仓库既有 Fast Refresh warning。
|
||
- `pnpm run lint:check`:仓库级尝试未通过;错误位于本任务未修改的 `src/components/layout/MainLayout.tsx`(effect 内同步 setState)和 `tests/unit/chat-command-dialogs.test.tsx`(未使用 `rerender`),另有 6 条既有 warning。本任务变更文件无 lint error。
|
||
- `pnpm run build:vite`:Renderer、Electron Main、Preload 均构建成功;仅有仓库既有 dynamic-import/chunk-size 提示。
|
||
- `pnpm exec playwright test --list --reporter=line`:成功收集 13 个 Electron E2E 文件、21 条用例,当前仓库不存在“缺少 Electron E2E fixture”问题。
|
||
- `git diff --check`:通过;仅有 Git 的 LF/CRLF 工作区提示。
|
||
- 安全补强聚焦回归:`pnpm exec vitest run tests/unit/works-play-url.test.ts tests/unit/works-submission-binding.test.ts tests/unit/device-preview-routes.test.ts tests/unit/project-progress-sync.test.ts tests/unit/works-routes.test.ts tests/unit/works-square.test.ts tests/unit/project-publish-action.test.tsx tests/unit/works-project-publish.test.ts tests/unit/project-packager.test.ts tests/unit/opencode-routes.test.ts`:10 files / 227 tests passed;覆盖 capability 先行拒绝、公共 URL fail-closed 投影、绑定告警继续轮询、schema v2 状态字段与 project_id 一致性。
|
||
- 对本次补强涉及的全部 TS/TSX 文件执行 scoped ESLint:0 errors / 0 warnings。
|
||
- 安全补强后再次执行 `pnpm run typecheck` 与 `pnpm run build:vite`:均通过;构建仅有既有 dynamic-import/chunk-size 提示。
|
||
- `pnpm exec playwright test tests/e2e/project-superpowers-toggle.spec.ts --reporter=line`:1 passed;实际 Electron 启动、创建小游戏、一键提交入口和旧自动部署入口消失均通过。
|
||
- 安全补强后再次执行 `pnpm exec playwright test --list --reporter=line`:成功收集 13 个 Electron E2E 文件、21 条用例。
|
||
|
||
## Follow-ups
|
||
|
||
- 客户端与服务端 OSS immutable Release / CDN 变更需要成组集成后,使用真实账号执行“创建小游戏/小程序 -> 一键提交 -> Builder -> 自动浏览器验收 -> 运营审核发布 -> App `play_url` 播放”的生产整链验收。
|
||
- 下一个客户端兼容版本确认服务端和存量数据均稳定提供 `play_url` 后,删除 `runtime_url` 类型字段、读取回退和对应测试。
|
||
- 仓库级 lint 的两个既有 error 应由独立维护任务处理,避免在发布链路任务中混入无关 UI/测试清理。
|
||
|
||
## Promotion Candidates
|
||
|
||
- Target: `.project-docs/20-architecture/system-overview.md`、`.project-docs/40-domain/business-rules.md` 与 README 当前产品状态。
|
||
- Proposal: 客户端发布唯一链路是 Main 安全生成静态包并提交服务端 Builder;客户端只持久化成功提交的精确版本绑定,不再拥有 Compose runner、自动 watcher/arm/upload 或手工 ZIP 入口。
|
||
- Evidence: 本任务删除 3,000 余行旧协调代码与测试,新增 schema v2 迁移、安全播放 URL 投影和 Renderer capability 门禁;补强后的 227 项聚焦回归、typecheck、Vite 构建、实际 Electron E2E 与 E2E 收集均通过。
|
||
- Future impact: 后续发布功能必须建立在 immutable static Release、`play_url` 和服务端审核发布状态之上;不得重新要求非专业用户准备 Docker/Compose/ZIP/服务器凭证。
|
||
- Semantic conflicts: 落盘文件名 `works-cloud-deploy.json` 仅为已安装数据兼容,不代表仍存在 cloud deployment coordinator;`runtime_url` 仅为一个客户端版本的临时兼容字段。
|
||
- Human confirmation required: 是;用户已明确要求一步到位移除旧 runtime-cleaner/runner 方向并统一到 Builder -> OSS -> CDN -> App,canonical promotion 仍由 Integration Gate 执行。
|