合并 master 并接入 DirectProject 新聊天架构
- 合并 origin/master(304 个提交:DirectProject 聊天容器重构、Project Supervisor 退役、策划附件导入、CI 隔离编译缓存等)。 - 接受 master 对 ProjectSupervisorView / SupervisorChatOnlyView 的退役与预览快捷测试收敛;发布入口改由 DirectProject 聊天头承载。 - DirectProjectChatHeader 新增「发布到游戏广场」入口(无回调不渲染、回合忙态禁用),DirectProjectChatView 透传 onRequestGamePublish。 - App.tsx 继续由工作台壳持有试玩包导出与 GameDistributionPublishPanel,沿用 project.export_package 权限确认队列;check-config 把该命令从 native-only 清单移回 App invoke。 - 后台游戏审核 API / 类型 / 路由测试与 master 新增的 AGC 模板管理按双方保留合并,并修掉拼接造成的接口与用例闭合缺陷。 - 修正 master 自带的 viteProxyConfig 断言:/api/creation-entry 属退役路由,测试改为断言不进入代理。 - 记录合并踩坑:语法结构内部的冲突不能简单按「双方保留」拼接,必须按某一侧骨架重建并跑 tsc 与单文件测试。 - 验证:全量 vitest 393 文件 / 4374 用例通过,root / AGC / admin-web 三端 typecheck,cargo check 与游戏分发 Rust 测试,encoding、doc-index、rustfmt、SpacetimeDB schema guard。
This commit is contained in:
@@ -39,6 +39,7 @@
|
||||
- [策划会话 Runtime V2 接入与旧链路退役方案](./technical/【技术方案】策划会话RuntimeV2接入与旧链路退役-2026-09-03.md):历史方案,仅用于追溯 V2 的实现与退役过程,不作为当前实现依据。
|
||||
- [DirectProject Codex 原始历史与异常恢复](<./technical/【技术方案】DirectProject Codex原始历史与异常恢复-2026-09-04.md>):原始 Responses item 持久化、线程注入与异常回合收尾。
|
||||
- [DirectProject 对话历史单一事实源](./adr/【ADR】DirectProject对话历史单一事实源-2026-09-16.md):AGC 项目开发对话只以项目对话历史与运行态事件为真相源,聊天投影不落盘。
|
||||
- [DirectProject 独立聊天容器与工作台钱包布局](./adr/【ADR】DirectProject独立聊天容器与工作台钱包布局-2026-09-18.md):DirectProject 与 Supervisor 等路径分容器,钱包入口由项目工作台布局独立承载。
|
||||
- [GameAgent 对话工具调用卡片](./technical/【技术方案】GameAgent对话工具调用卡片-2026-09-14.md):把右侧对话里的执行命令 / 写文件投影成 Codex 风格可折叠卡片,含采集、独立历史文件、事件字段与回读契约。
|
||||
- [DirectProject 客户端 Skill 与 MCP 扩展导入方案](./technical/【技术方案】DirectProject客户端Skill与MCP扩展导入方案-2026-08-31.md):客户端扩展导入、按独立 Skill/MCP 拆分、命名、启用和启动时注入边界。
|
||||
- [AGC 通用插件宿主与编辑器适配](./technical/【技术方案】AGC通用插件宿主与编辑器适配-2026-09-09.md):通用插件宿主、SDK、权限审计、UI 挂载和 Cocos 编辑器适配边界。
|
||||
@@ -48,6 +49,7 @@
|
||||
- [AGC 客户端更新检查与下载](./technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md):启动版本检测、固定 dev 服务、OSS 清单与官网最新客户端下载。
|
||||
- [AGC 总版本号与发号](./technical/【技术方案】AGC总版本号与发号-2026-09-20.md):客户端版本号收口到 OSS `agc/global-version.json`,统一构建一次发号供各渠道共用,渠道高水位降级为断言。
|
||||
- [AGC 模板库与模板建项](./technical/【技术方案】AGC模板库与模板建项-2026-09-17.md):`templates/` 前缀的模板库契约、下载安装与「用模板建项目」链路。
|
||||
- [AGC 模板包组织指南](./【模板规范】AGC模板包组织指南-2026-09-21.md):模板 ZIP 的根目录结构、Cocos 工程保留项、禁止放入的内容、封面与体积上限、版本不可变与发布前自检。
|
||||
- [DirectProject 本轮附件路径映射](./technical/【技术方案】DirectProject本轮附件路径映射-2026-08-31.md):Direct 首轮只映射附件原名与项目相对路径,不灌正文、不区别 GDD。
|
||||
- [Direct 回合行为审计账本](./technical/【技术方案】Direct回合行为审计账本-2026-08-31.md):Direct GUI 回合把 native 读 / MCP / 写文件落成项目内有界时间线,用于判断有没有打开本轮附件。
|
||||
- [项目开发工作台 PRD](./prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md):当前工作台页面和验收边界。
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
# DirectProject 独立聊天容器与工作台钱包布局
|
||||
|
||||
状态:已接受
|
||||
|
||||
AGC 项目开发工作台的普通项目固定使用 DirectProject;它不再作为 `ProjectSupervisorView` 的条件分支,而由 `view/project-development/chat/` 下的 `DirectProjectChatView` 与 controller 拥有自己的订阅、历史、发送、队列、附件和中止生命周期。Supervisor 前端链路(独立调试窗口、纯聊天容器、工作台壳里的 Supervisor 运行态与专业 Agent 面板)已整体退役,项目对话只保留 DirectProject 与立项策划两条产品路径;立项策划当前只有 Design Agent(策划 Agent V1/V2 的会话、专用命令、审批卡与展示适配已于 2026-09-20 退役,见 shared-memory 决策记录)。行为中立的 Composer、消息、工具卡片和设置基础表现可以复用,但不同产品路径不共享行为容器,也不保留运行时 feature flag、兼容别名、Direct fallback 或双跑路径。
|
||||
|
||||
项目工作台布局拥有跨面板的账户/钱包入口。钱包不再作为 `walletEntry` 传入 DirectProject 聊天上下文或聊天设置浮层,而是在 `ProjectDevelopmentView` 的布局级头部/工具栏独立渲染;本次只改变布局归属与嵌套关系,保留钱包入口本身的可用性。
|
||||
|
||||
这项边界选择是为了让 DirectProject 的事实源与生命周期可以独立测试和演进,同时避免把工作台级账户状态与聊天状态耦合;一次性替换通过 Git revert 回滚,不增加运行时开关、兼容别名或条件兼容分支。
|
||||
|
||||
## 模块结构
|
||||
|
||||
公开入口只有 `view/project-development/chat/DirectProjectChatView.tsx`,内部按职责分层:
|
||||
|
||||
- `components/`:表现层,一个组件一个目录,组件自己的逻辑与表现同目录(`components/ToolCallGroup/` 放 `ToolCallGroup.tsx` 与 `toolCallGroupPresentation.ts`;`components/DirectProjectComposer/` 放 `DirectProjectComposer.tsx`、`ComposerControls.tsx`、`chatComposerQueue.ts`、`chatComposerVoice.ts`)。
|
||||
- `controller/`:会话控制器 `useDirectProjectChatController`、项目清单订阅 `useDirectProjectManifest`,以及线程订阅与聊天 reducer 的独立 hook `useDirectThreadChatSubscription`。
|
||||
- `conversation/`、`history/`:纯模块(条目投影、历史分页、订阅锚点闸门、附件映射)。
|
||||
- `generated/`:Rust 侧 ts-rs 导出的 Direct 契约,不在前端手抄形状。
|
||||
|
||||
`useDirectThreadChatSubscription` 持有 `subscribe → consume → notify` 单飞循环与聊天 reducer 状态,是 DirectProject 运行态的唯一事实源;控制器只读它投影后的条目与回合忙态,历史分页通过同一个 reducer 并入。
|
||||
|
||||
工作台壳要把运行/预览这类工作台级动作的结果说给用户时,只通过 `DirectProjectChatView` 的 `ref` 句柄(`announce`)交给聊天自己的本地消息流;壳不持有 Direct 的聊天消息。
|
||||
|
||||
立项策划(当前只有 Design Agent)的容器与表现与 DirectProject 并列放在 `view/project-development/planning/`(`PlanningChatView`、`DesignAgentSurface`);两条产品路径共享的只有无行为真相的表现组件:输入盒的模型 / 推理档控件(`features/project-workspace/ConversationModelSelect.tsx` 与 `chat/components/DirectProjectComposer/ComposerControls.tsx` 的 `ComposerReasoningEffortSelect`)和思考折叠入口(`chat/components/AgentReasoning/AgentReasoning.tsx`,折叠态单行纯文本预览、展开态安全 Markdown)。共享的只是表现,回合、会话与配置写回仍由各自入口负责。
|
||||
|
||||
`game-creator-manifest-invalidated` 由工作台壳与 DirectProject 聊天各自订阅:壳做一次配对读(`revision → 清单 → revision`,`source: 'asset-event'`)把运行态落盘的新资源并入 `currentProjectContext`,这次刷新**不**重新检查项目目录;聊天侧仍由 `useDirectProjectManifest` 刷新自己的 `@` 引用清单。
|
||||
@@ -1,6 +1,6 @@
|
||||
# AI 游戏创作项目开发工作台 PRD
|
||||
|
||||
更新时间:`2026-09-14`(同步功能画布图片类生成后台化的当前事实:入口 IPC 改为 `start_local_project_asset_generation` + 项目内任务账本 + 本地排队 + 非模态「生成任务」面板,见 §3.10 / §7.9;2026-09-13 新增的功能画布底部工具栏入口矩阵 §3.10 / §7.9,以及右侧 Supervisor 对话气泡、可访问对比度与过程卡布局收口,资源卡预览、分区布局、非破坏性资源编辑、资源替换与 Godot 双根合同保持不变)
|
||||
更新时间:`2026-09-21`(2026-09-20 音频生成并入图片类那份后台任务账本、派生/修改类任务并入同一「生成任务」侧栏,2026-09-21 卡片浮层改为「提交即关」、**「生成任务」侧栏从画布左侧贴边改为画布右上角锚点(开关常驻)**、**资源卡可拖到对话栏批量 @ 引用**、**替换面板改为非模态浮层并支持在画布上点选目标**(验收现场两条修正:任务锚点改挂画布那一格、展开后开关让位),见 §3.10 / §5.3 / §7.8 / §7.9 与 [`【功能说明】AGC聊天素材引用`](../【功能说明】AGC聊天素材引用-2026-09-08.md);2026-09-14 图片类生成后台化:入口 IPC 为 `start_local_project_asset_generation` + 项目内任务账本 + 本地排队 + 非模态「生成任务」面板;2026-09-13 新增的功能画布底部工具栏入口矩阵 §3.10 / §7.9,以及右侧 Supervisor 对话气泡、可访问对比度与过程卡布局收口,资源卡预览、分区布局、非破坏性资源编辑、资源替换与 Godot 双根合同保持不变;2026-09-21 Godot 工作区发现放宽:一层多命中按目录名排序取第一个,`project.godot` 允许是链接/reparse point/硬链接,见 §3.8)
|
||||
|
||||
## 1. 产品定位
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
|
||||
### 3.8 现有 Godot 项目
|
||||
|
||||
- 首页和项目组统一使用“打开项目”,不提供独立 Godot 按钮。用户选择的目录作为工作区根;系统先检查根目录,再检查一层直接子目录中的普通文件 `project.godot`。根目录命中优先;一层发现多个 Godot 工程时必须提示歧义,不猜测目标。
|
||||
- 首页和项目组统一使用“打开项目”,不提供独立 Godot 按钮。用户选择的目录作为工作区根;系统先检查根目录,再检查一层直接子目录中的 `project.godot`。根目录命中优先;一层命中多个 Godot 工程时按目录名排序取第一个,不再因为存在第二个工程而失败或要求用户改选。`project.godot` 本身是符号链接、Windows reparse point 或硬链接时按链接目标判定,解析后是文件即命中;目录与悬空链接仍不算命中。
|
||||
- 工作区根始终绑定文件读取、修改、命令 cwd、对话、Runtime 和最近项目记录;`.agent/`、Agent DB 与日志也只写在这里。`project.godot` 所在目录额外以 `godotProjectRoot` 记录为相对工作区的 `.` 或单层目录名,不把项目作用域切到 Godot 子目录。
|
||||
- 首次打开只在工作区根创建 `.agent/` 元数据;已有 `.agent/manifest.json` 时读取并按当前唯一文件布局校准 `godotProjectRoot`。Godot 源码、场景、资源和项目配置继续使用原目录结构,不复制工程,也不建立 `game/`、`assets/`、`memory/`、`exports/` 平行目录。
|
||||
- Godot 项目使用 `standard` Run Profile,避免套用 Web 原型的 `game/index.html`、本地 HTTP 预览和自主 Web 游戏完成门;本期不提供 Godot 内嵌运行预览。
|
||||
@@ -151,26 +151,28 @@
|
||||
|
||||
### 3.10 功能画布底部工具栏(入口矩阵)
|
||||
|
||||
实现状态(2026-09-13;2026-09-14 图片类生成后台化:提交即返回 + 项目内任务账本 + 本地排队 + 非模态「生成任务」面板):功能画布 = 资源栏目页(`resourceBookState.view === 'child'`)。栏目页左下角的底部工具栏按 manifest 资产的**功能分类** `category` 分流,矩阵由用户 2026-09-13 拍板,工具项顺序即下表顺序(最右一项为「上传」)。
|
||||
实现状态(2026-09-13;2026-09-14 图片类生成后台化:提交即返回 + 项目内任务账本 + 本地排队 + 非模态「生成任务」面板;2026-09-20 音频生成并入同一条后台任务账本):功能画布 = 资源栏目页(`resourceBookState.view === 'child'`)。栏目页左下角的底部工具栏按 manifest 资产的**功能分类** `category` 分流,矩阵由用户 2026-09-13 拍板,工具项顺序即下表顺序(最右一项为「上传」)。
|
||||
|
||||
| 栏目 | 工具栏里的生成入口 |
|
||||
| --- | --- |
|
||||
| UI 与交互 `ui-interaction` | 生成图片 | 生成规范(二级:图标规范 / 自定义规范)| 生成图标素材 | 生成 UI 设计图 | 上传 |
|
||||
| 角色与对象 `character` | 生成图片 | 生成规范(二级:角色规范 / 自定义规范)| 生成角色形象 | 上传 |
|
||||
| 场景与环境 `scene` | 生成图片 | 生成规范(二级:自定义规范)| 上传 |
|
||||
| 音频 `audio` | 生成背景音乐 | 生成音效 | 上传 |
|
||||
| 文档 `document`、待归类 `unclassified`、项目版本 `version`、「所有资源」展开态、资源总览 | **不渲染工具栏** |
|
||||
| 栏目 | 工具栏里的生成入口 |
|
||||
| ---------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------- |
|
||||
| UI 与交互 `ui-interaction` | 生成图片 | 生成规范(二级:图标规范 / 自定义规范)| 生成图标素材 | 生成 UI 设计图 | 上传 |
|
||||
| 角色与对象 `character` | 生成图片 | 生成规范(二级:角色规范 / 自定义规范)| 生成角色形象 | 上传 |
|
||||
| 场景与环境 `scene` | 生成图片 | 生成规范(二级:自定义规范)| 上传 |
|
||||
| 音频 `audio` | 生成背景音乐 | 生成音效 | 上传 |
|
||||
| 文档 `document`、待归类 `unclassified`、项目版本 `version`、「所有资源」展开态、资源总览 | **不渲染工具栏** |
|
||||
|
||||
- 位置与层级:画布左下角(`left: 14px; bottom: 14px; z-index: 40`)。右下角是既有的缩放 / 撤销 Dock(`right: 14px; bottom: 14px`),左下角是画布上唯一两者都不占的稳定空位。工具栏是管理区 `.game-resource-book-manager` 的**直接子节点**、与画本场景并列,不进带 `scale()` 的场景层;二级菜单与「入口不可用原因」都贴着工具栏上沿弹出,不做内嵌内容。
|
||||
- 外壳用共享 chrome(`packages/image-canvas-react` 的 `CanvasToolbar / CanvasToolbarGroup / CanvasChromeButton`),样式落在 AGC 的 `resourceCanvasChrome.css`;共享包只承接通用表现,不含业务规则。
|
||||
- 接线:图片类入口走本地 IPC `start_local_project_asset_generation`(`kind` ∈ `image / character / spec / icon-spec / ui-prototype / art-spritesheet`;**提交即返回任务记录**,生成由 Rust 后台任务跑完写回项目,进度用 `list_local_project_asset_generations` 读回项目内账本 `.agent/runtime/asset-generation-tasks/tasks.json`);音频入口复用既有的无源生成链路 `derive_local_project_resource`(`generationMode: 'create'`、`editKind` = `sound-effect` / `background-music`);「上传」复用 `upload_local_asset`。生成 / 上传成功后一律用「配对读 `(revision, manifest)`」交给 `onManifestChange`,走既有 manifest 刷新与资源投影链路,不重算依赖图、不另写布局。
|
||||
- 本地排队与进度可见:AGC 本地 durable 输出槽已按**精确动作指纹**分槽(不同 prompt / 素材名各自独立成槽,具备并行能力),但本批前端仍按「同一时刻只派发一条」排队——真并行派发需要并发收口设计(配对读 + manifest CAS + 聚焦意图互不覆盖),留待下一批;所以第一条未终态时第二条提交停在**前端本地队列**里(不调用提交 IPC,显示本地排队的「排队中。」),前一条终态后自动补发;任务状态与阶段文案(后端 `phaseDetail`)由任务账本提供,前端不拼阶段、不做百分比。进度面是**画布上常驻的可折叠任务侧栏**(形态对齐网页端美术画布的任务侧栏):展开是两个分栏「排队/生成中」与「已完成」(各带条数,「已完成」封顶 20 条 + 列表滚动 + 高度有界),关闭入口只保留头部那一枚 ×(底部重复的关闭按钮与其分割线已删除)、折叠即整块让出画布且不留贴边把手,开合只走工具条上常驻的「生成任务 · N」按钮(两个页签下都在);每项显示状态徽标 / 阶段文案 / 已耗时 / 素材名,可「定位到素材」。侧栏非模态(不铺全屏遮罩、不做焦点陷阱、不参与模态遮挡判据),位置在画布左侧标题栏之下、**覆盖式**(不 reflow 挤窄画布视口),提交受理后自动展开。定位动作**每次点击都终局化**:能定位就定位并选中;素材在别的栏目先切栏目;不在投影里给「素材已不在项目里 / 已登记但尚未同步」的结论;3 秒内有界兜底,不允许提示条永久停在「正在定位生成的素材…」。
|
||||
- 接线:图片类入口走本地 IPC `start_local_project_asset_generation`(`kind` ∈ `image / character / spec / icon-spec / ui-prototype / art-spritesheet`;**提交即返回任务记录**,生成由 Rust 后台任务跑完写回项目,进度用 `list_local_project_asset_generations` 读回项目内账本 `.agent/runtime/asset-generation-tasks/tasks.json`);音频入口也走 `start_local_project_asset_generation`(同一份项目内任务账本;`kind` = `sound-effect` / `background-music`,并额外携带该次生成的请求身份 `idempotencyKey`,任务 id 即该次生成的 operation id;生成仍复用既有音频无源生成链路,`generationMode: 'create'`、`editKind` = `sound-effect` / `background-music`,不新增平台路由与请求体口径);「上传」复用 `upload_local_asset`。生成 / 上传成功后一律用「配对读 `(revision, manifest)`」交给 `onManifestChange`,走既有 manifest 刷新与资源投影链路,不重算依赖图、不另写布局。
|
||||
- 本地排队与进度可见:AGC 本地 durable 输出槽已按**精确动作指纹**分槽(不同 prompt / 素材名各自独立成槽,具备并行能力),但本批前端仍按「同一时刻只派发一条」排队——真并行派发需要并发收口设计(配对读 + manifest CAS + 聚焦意图互不覆盖),留待下一批;所以第一条未终态时第二条提交停在**前端本地队列**里(不调用提交 IPC,显示本地排队的「排队中。」),前一条终态后自动补发;任务状态与阶段文案(后端 `phaseDetail`)由任务账本提供,前端不拼阶段、不做百分比。进度面是**画布上常驻的可折叠任务侧栏**(位置与开合形态照抄网页端美术画布的任务侧栏的右上角锚点,颜色与外形仍走 AGC 平台 token;2026-09-21 由「左侧贴边 + 工具条入口」改为「右上角锚点 + 常驻开关」):展开是两个分栏「排队/生成中」与「已完成」(各带条数,「已完成」封顶 20 条 + 列表滚动 + 高度有界),关闭入口只保留头部那一枚 ×(底部重复的关闭按钮与其分割线已删除)、折叠即整块让出画布、只留那一枚右上角开关(工具条上不再有重复入口),开合只走画布右上角那一枚「生成任务 · N」开关(两个页签下都在;**展开后开关让位、只留面板**,收起走面板头部 × 或点画布外部);锚点是画布那一格网格里的条目(不是写死 `top` 的绝对定位),工具条换行变高也不会压上去;每项显示状态徽标 / 阶段文案 / 已耗时 / 素材名,可「定位到素材」。侧栏非模态(不铺全屏遮罩、不做焦点陷阱、不参与模态遮挡判据),位置在画布右上角锚点里(照抄美术画布那一处)、**覆盖式**(不 reflow 挤窄画布视口),提交受理后自动展开。锚点按工作面分档:资源栏目画布与 UI 编辑器用画布顶边那一档,运行表现层下移让开右上角的版本入口;锚点是**画布那一格网格里的条目**(不是写死 `top` 的绝对定位),所以工具条换行变高也不会压上去。定位动作**每次点击都终局化**:能定位就定位并选中;素材在别的栏目先切栏目;不在投影里给「素材已不在项目里 / 已登记但尚未同步」的结论;3 秒内有界兜底,不允许提示条永久停在「正在定位生成的素材…」。
|
||||
- 面板形态:独立浮层(`ThemedModal`),**不在当前面板下面追加内容**;面板内不写功能说明或规则解释文案。**点「生成」即同步关闭面板**(不等 IPC、不等排队、不等生成),面板里**不出现**「排队中。」「正在生成。」「提交中…」这类阶段文案——阶段文案的唯一去处是任务侧栏与工具栏提示条。**只有「点击瞬间就失败」**(校验不过、权限拒绝、start IPC 立即报错)才自动重开面板并带回草稿与原因;**受理之后才失败**只在侧栏把该任务收口为失败 + 原因,不重开面板。关闭 ≠ 取消请求(请求挂在任务与账本上,不挂在面板生命周期上)。
|
||||
- 参数口径:比例 / 尺寸选项来自网页端美术画布的纯模型(`src/components/image-editor/ImageCanvasGenerationModel.ts`),并按本地 IPC 白名单收窄(本地通道明确拒绝 `4:3`);默认档 `1:1 · 1K`,生成 UI 设计图沿用网页端 UI 设计面板的默认 `16:9 · 1K`。本地 IPC 没有 `model` 入参,因此面板**不渲染模型选择器**(渲染一个改不了请求的控件就是假控件)。
|
||||
- 规范类和固定档:生成规范下的图标规范 / 角色规范 / 自定义规范都是固定档——只读展示当前规格,不给点了不生效的比例控件。本地 IPC 只有一条规范通道(`spec` 在 Rust 侧收口到 `icon-spec`),**没有 `specType` 入参**,因此角色规范与自定义规范共用该通道,靠素材名与提示词区分。
|
||||
- 前置规范图:`start_local_project_asset_generation` 的 `ui-prototype` 与 `art-spritesheet` 要求项目里已有登记并绑定当前账号的 `assets/art-spec.png`(`kind: icon-spec`、图片媒体类型、来源为画布)。**后台化没有改这条前置判据**:Rust 侧仍是同一口径,前端 `projectHasIconSpecReference` 仍与它逐字对齐,缺前置时对应入口**保持可点击**并给出可执行的原因与指路(仓库口径:视觉不可用但可点击说明原因,不用原生 `disabled`),原因文案包含 `assets/art-spec.png` 与「生成规范 → 图标规范」。
|
||||
- 权威规范图由工具栏自身可满足:「图标规范」入口在项目尚无权威规范图时按 `assets/art-spec.png` 落盘;已有权威规范图时**不再传 `outputPath`**(Rust 侧 `replace_existing` 固定为 `false`,指向已存在文件会被硬拒绝「outputPath 已存在,禁止静默覆盖」),改为生成一张新的普通图标规范资产。这条前端策略不扩接口。
|
||||
- 音频入口收敛:音频画布的「生成背景音乐 / 生成音效」由工具栏承载,既有「生成素材」浮层入口**只保留生成视频**(视频能力不删,只是不出现在工具栏里)。
|
||||
- 派生/修改类任务并入同一侧栏(2026-09-20):快速编辑、生成动画、视频 / 音效 / 背景音乐与抠图这类走**资源编辑链路**的任务也进「生成任务」侧栏。数据源 = 原生资源编辑账本 `list_pending_local_project_resource_edits` + **本会话的本地提交记录**,按 `operationId` 合并去重:本地那份负责「按下提交当帧可见」,原生那份负责「重开项目、别处提交也看得见,阶段文案以后端为首」。这类任务不写图片类生成账本(`.agent/runtime/asset-generation-tasks/tasks.json`),也不改原生资源编辑账本 schema。
|
||||
- 卡片浮层同一条「提交即关」(2026-09-21):快速编辑 / 生成动画这类挂在资源卡上的浮层只负责**把任务交出去**,点提交当帧即关面板(不等 IPC),进度、阶段与结果都在「生成任务」侧栏里跟;面板内不出现「修改中 / 生成中」这类等待态。只有**点击瞬间就失败**(名称预检、源素材不在画布上、没有客户端)留在面板里可见;**受理之后才失败**只把侧栏那条收口为失败 + 提示条,不重开面板,草稿回落成「未完成编辑」等用户重开。因此原有的「生成中的卡片浮层不参与清焦点」判据一并退役(浮层不会带着进行中的任务留在画布上)。身份跟着资源走:按「入口 + 资源路径」记住最后一次派生请求,重开面板再提交时提示词没变就沿用同一 `operationId` / 幂等键,命中同一 operation 账本;派生成成功即清掉。同一张素材仍有在途提交时,再提交会被拦下并给出原因。
|
||||
- 本轮明确不做:生成视频(保留在既有浮层入口)、宣发素材、生成游戏场景、画布级「选择工具 / 抓手工具」(AGC 现无画布级工具模式)。这五类都**不得**出现在工具栏里。
|
||||
- 本地 IPC 边界(前端只做本地收窄,不改接口):提示词上限 `32000` 字符、素材名上限 `120` 字符、比例白名单 `1:1 / 2:3 / 3:2 / 9:16 / 16:9`、尺寸白名单 `0.5K / 1K / 2K`。
|
||||
|
||||
@@ -364,7 +366,7 @@ type UpdateProjectResourceCanvasLayoutResult =
|
||||
1. **查找素材**:关键词,就是画布搜索本身,与筛选条件共用同一份状态,只有一个入口读写它,不得各存一份;判据沿用搜索既有的名称、路径、媒体类型、任务名四字段与大小写不敏感口径。
|
||||
2. **所在区域**:取值为「全部区域」加上现行分区栏目(`PROJECT_RESOURCE_CANVAS_SECTIONS` 的 6 类资产分类与末尾独立的「项目版本」栏),显示名沿用 `@` 面板资源筛选那份唯一中文口径,不另建译名表。
|
||||
3. **自定义标签**:从 manifest `assets[].tags` 派生的标签库,多选且为 AND 语义(已选标签必须全部命中,空选择不过滤),复用共享判据 `assetTagsMatchSelection`。
|
||||
不提供「状态」字段:manifest 资产与资源投影都没有状态事实源,候选的任务状态与附件导入状态在资源投影里已被上游过滤,任何取值都恒为同一结果,因此不渲染该字段,也不保留占位下拉。
|
||||
不提供「状态」字段:manifest 资产与资源投影都没有状态事实源,候选的任务状态与附件导入状态在资源投影里已被上游过滤,任何取值都恒为同一结果,因此不渲染该字段,也不保留占位下拉。
|
||||
- 「所在区域」**既是筛选维度也是画布当前栏目**,两者必须是同一份状态:区域取值由画布栏目状态派生,切换区域走与栏目切换完全相同的那一条路径,因此用户用滚轮、总览卡片或下一页切换栏目时区域显示随之变化,不需要双向同步逻辑,也不会出现两处状态互相漂移。
|
||||
- 区域取值与其它维度叠加时,筛选只作用于当前区域内的资源;「全部区域」作用于全部资源。两种语义共用同一份过滤实现,不为「只筛当前区域」另写一套裁集合逻辑。
|
||||
- 筛选浮层是画布唯一的搜索与筛选入口:Dock 上的放大镜按钮与 `Ctrl/Cmd+F` 叫出的是同一个浮层,不存在第二个浮层,因此也不存在「两个浮层互斥」这一说。
|
||||
@@ -446,7 +448,7 @@ type ProjectVersionResourceReplacement = {
|
||||
- **失败即拒绝**:硬门禁任一项不等、源版本不存在、源版本未绑定该素材、替换素材未登记、替换素材与源素材相同、`expectedProjectId` / `expectedProjectRevision` CAS 冲突,都必须在写入前拒绝并说明原因;拒绝时 manifest、`versions` 与项目 revision 都不变,投影里不得出现新的版本卡或新的"当前使用"高亮。
|
||||
- **落盘与留痕**:改绑定属于 `versions` 变化,写入后推进一次 `projectRevision`;并追加一条 `asset.version_binding.replace` 审计(`versionId / sourceResourceId / replacementResourceId / projectRevision`)。**没有可回溯的替换历史**:替换前的身份只有这条审计与 manifest 的 `.previous` 恢复副本。
|
||||
- **入口与可见效果**:入口在资源卡选中工具条,只对「manifest 资产 + 被当前版本绑定」的素材放行;候选弹窗列出全部候选,命中硬门禁的项渲染但禁用并给出原因,只有尺寸规格差异的项仍可选但带提示。成功后**不切换版本**(没有新版本可切),只重读 manifest;可见变化是资源卡"当前使用"高亮移到替换素材、`@` 面板"当前版本素材"更新。按 §7.4 的口径,改绑定不做运行时资源重映射,运行画面本身不会因改绑定而变化;也不自动重载 / 重启运行中的预览(§3.2 末条)。
|
||||
- **点选替换(2026-09-13 补充)**:候选弹窗 footer 提供「点选替换」,用于"目标就在画布上、不想在面板里筛"的场景。点它**必须关闭弹窗**(弹窗外壳是全屏遮罩,留着它画布上的卡点不到)并进入画布点选态,画布上出现提示条(「在画布上点选要替换成的素材;点击空白处不会退出」+「取消」)。点中合法候选直接走**同一条**写入链路(载荷与弹窗确认逐字一致,不产生第二套替换口径),成功后自动退出点选态;点中非法目标(分类 / 类型不同、不在后端给出的权威候选里、源素材本身、未登记资源)**不写入**,在提示条上说明原因(与候选弹窗同一条翻译口径)并**留在**点选态。退出只有三条路:Esc(在 `document` 阶段截断,画布全局 Esc 的清选中不随之触发)、提示条「取消」、替换成功;**空白点击不退出、也不清画布选中**。点选态下卡片左键只用于点选(不起拖拽、不换选中,靠一次性抑制而不是全局关掉单击),滚轮平移与 `Ctrl/Cmd` 缩放照常可用。
|
||||
- **替换面板在画布上点选目标(2026-09-21;2026-09-13 的「点选替换」由此取代)**:候选面板是画布右上角的**非模态浮层**(无全屏遮罩、不做焦点陷阱,面板自身限高 + 内部滚动),面板开着的时候画布照常可点——在画布上点目标素材即把它落成**面板里的当前选择**(面板随之高亮;用户在面板里已输入的搜索与分类筛选不被重置),写入仍然只由面板「确认」发起(载荷与旧弹窗确认逐字一致,不产生第二套替换口径)。点中非法目标(分类 / 类型不同、不在后端给出的权威候选里、源素材本身、未登记资源)**不写入**,在面板里说明原因(同一条翻译口径)并保留原选择。退出只有两条路:面板「取消」/ 头部 ×、Esc(在 `document` 阶段截断,画布全局 Esc 的清选中不随之触发);替换成功即关闭面板。面板开着时卡片左键只用于点选(不起拖拽、不换画布选中,靠一次性抑制而不是全局关掉单击),滚轮平移、`Ctrl/Cmd` 缩放与空白处框选照常可用。
|
||||
- **替换血缘标注(2026-09-13 补充)**:替换成功后只改绑定、光环本来就会从源素材移到替换素材,光靠光环说明不了"谁换成了谁",所以在卡面补一层**关系标注**:源素材卡标「已被 <替换素材显示名> 替换」,替换素材卡标「替换自 <源素材显示名>」,两处分别给出稳定 DOM 判据 `data-resource-replaced-by` / `data-resource-replacement-of`,值是对面资源的 **manifest 资产 id**(不是显示名)。这份关系是**宿主会话内状态**:同一会话里再次替换**整条覆盖**上一条(只保留当前有效的一条 A→B,不做历史链,与 §7.8「只展示当前有效关系」同口径);**切换项目 / 关闭工作台 / 重新加载 manifest 都不保留**——客户端没有替换关系的读侧事实源(写入结果只回 `versionId` / `committedProjectRevision`,审计 `asset.version_binding.replace` 只有写侧),manifest 的 `.previous` 只是原子安装的崩溃兜底副本、安装成功即删,不能当数据源,所以本标注**只在本次会话有效,不假装持久**。
|
||||
|
||||
### 5.4 游戏迭代版本(P1)
|
||||
@@ -655,7 +657,7 @@ type ProjectAgentMudPointAttribution = {
|
||||
5. 硬门禁任一为 false、源版本不存在、源版本未绑定该素材、替换素材未登记、替换素材与源素材相同、`expectedProjectId` / `expectedProjectRevision` 冲突,都必须在写入前拒绝;拒绝时 manifest、`versions` 与项目 revision 都不变,投影里不得出现新的"当前使用"高亮或版本卡变化。
|
||||
6. 成功后重读 manifest 并**不切换版本**(没有新版本可切);**不**自动重载或重启运行中的预览(§3.2 末条),也不做运行时资源重映射。可见变化只有:资源卡"当前使用"高亮移到替换素材、`@` 面板"当前版本素材"更新。
|
||||
7. 替换成功后追加一条 `asset.version_binding.replace` 审计(`versionId / sourceResourceId / replacementResourceId / projectRevision`);**替换历史不可回溯**——替换前身份只有这条审计与 manifest 的 `.previous` 副本,不得声称能查到"某版本历史上换过什么"。
|
||||
8. 候选弹窗提供「点选替换」(2026-09-13):点它关闭弹窗进入画布点选态,并把「在画布上点选要替换成的素材;点击空白处不会退出」与「取消」放在画布提示条上;点中合法候选按第 3~7 条**同一条**链路提交并自动退出点选态,点中非法目标(分类 / 类型不同、不在权威候选里、源素材本身、未登记资源)零写入、留在点选态并在提示条上说明原因。退出只有 Esc(`document` 阶段截断,不清画布选中)/ 提示条「取消」/ 替换成功三条路,空白点击不退出;点选态下滚轮平移与缩放照常,卡片单击的既有语义在非点选态下不变。
|
||||
8. 替换面板在画布上点选目标(2026-09-21;取代 2026-09-13 的「点选替换」):候选面板是非模态浮层,面板开着时画布保持可点,点画布上的候选即落进面板的当前选择(搜索与分类筛选不被重置),写入仍由面板「确认」按第 3~7 条**同一条**链路发起;点中非法目标(分类 / 类型不同、不在权威候选里、源素材本身、未登记资源)零写入并在面板里说明原因。退出只有面板「取消」/ × 与 Esc(`document` 阶段截断,不清画布选中)两条路,成功后自动关闭;面板开着时滚轮平移、缩放与空白框选照常,卡片单击的既有语义在面板关闭后不变。
|
||||
9. 替换血缘标注(2026-09-13):替换成功后,源素材卡带「已被 <替换素材显示名> 替换」、替换素材卡带「替换自 <源素材显示名>」,稳定 DOM 判据 `data-resource-replaced-by` / `data-resource-replacement-of` 的值为对面资源的 manifest 资产 id;未参与替换的资源卡两个属性都不出现。同一会话内再次替换时**只保留当前有效的一条 A→B**(旧标注从卡上消失,不做历史链)。这份标注**只在本次会话有效**:切换项目 / 关闭工作台 / 重新加载 manifest 都不保留,也不得声称可回溯(第 7 条仍成立)。
|
||||
|
||||
### 7.9 P1 功能画布底部工具栏验收
|
||||
@@ -665,9 +667,10 @@ type ProjectAgentMudPointAttribution = {
|
||||
3. 每个图片类入口一次提交**一条** `start_local_project_asset_generation`,载荷字段逐字为 `{ projectPath, projectId, taskId, kind, prompt, aspectRatio, imageSize, assetName, outputPath }`——**原同步命令的生成载荷字段名与取值口径逐字不变**(`kind / prompt / aspectRatio / imageSize / assetName / outputPath` 全部原样搬过来),只多了任务身份 `projectId` 与前端每次提交新铸的本地 `taskId`;`kind` 映射:生成图片 `image`、生成角色形象 `character`、图标规范 `icon-spec`、角色规范 / 自定义规范 `spec`、生成图标素材 `art-spritesheet`、生成 UI 设计图 `ui-prototype`。命令**提交即返回**一条任务记录,生成在 Rust 后台任务里跑,状态与阶段由 `list_local_project_asset_generations` 从项目内账本读回。
|
||||
4. 比例 / 尺寸选项**不含**本地通道拒绝的 `4:3`;比例与尺寸的切换都进入载荷;固定档规范入口只读展示当前规格(如 `1:1·1K`),不渲染可点比例控件。
|
||||
5. 缺权威规范图时「生成图标素材 / 生成 UI 设计图」保持可点击、给出含 `assets/art-spec.png` 的原因说明,且**不发出任何生成请求**;「图标规范」此时把 `outputPath` 指向 `assets/art-spec.png`;项目已有权威规范图时 `outputPath` 为 `null`(两种状态各一条用例)。
|
||||
6. 生成 / 上传成功后走既有刷新路径:`get_local_game_project_revision` + `get_local_game_manifest` 的配对读发生在**该任务收口之后**(提交命令不再等待生成,配对读由任务终态驱动,顺序仍在写入之后),结果交给 `onManifestChange`;音频入口提交的是 `derive_local_project_resource`(`editKind` = `sound-effect` / `background-music`、`generationMode: 'create'`、`sourceMediaType: 'audio/mpeg'`)。
|
||||
6. 生成 / 上传成功后走既有刷新路径:`get_local_game_project_revision` + `get_local_game_manifest` 的配对读发生在**该任务收口之后**(提交命令不再等待生成,配对读由任务终态驱动,顺序仍在写入之后),结果交给 `onManifestChange`;音频入口提交同一条命令的音频载荷(`kind` = `sound-effect` / `background-music`、`idempotencyKey` = 该次生成的幂等键、任务 id 即该次生成的 operation id);原生命令内部仍复用既有音频无源生成链路(`editKind` = `sound-effect` / `background-music`、`generationMode: 'create'`、源快照媒体类型由 `editKind` 推为 `audio/mpeg`),不新增平台路由、请求体或计费口径。
|
||||
7. 既有「生成素材」浮层入口只呈现视频:面板不再渲染音效 / 背景音乐类型选择器(单类型入口没有类型选择器),音频入口只出现在音频栏目工具栏。
|
||||
8. 生成期间可退出与本地排队(2026-09-14):提交后点 × / 遮罩 / Esc /「后台运行并关闭」任一都能关面板,画布立即恢复可交互,关闭不取消请求;面板关闭后任务仍在「生成任务」面板(非模态浮层,无 `aria-modal`)里显示后端 `phaseDetail`;第一条未终态时提交第二条 → 第二条显示「排队中。」且生成提交 IPC 次数仍为 1,第一条终态后自动补发(次数为 2);两条各自完成后各走一次「配对读 + 落卡」,manifest revision 单调、不被后到者覆盖。
|
||||
8. 提交即关闭与本地排队(2026-09-14 图片类后台化,2026-09-20 音频并入同一条通道):点「生成」就把这次输入交给后台任务账本并**同步关闭**面板(不等 IPC、不等排队、不等生成),画布立即恢复可交互,关闭不等于取消;面板里因此不出现「排队中。」「正在生成。」「提交中…」与「后台运行并关闭」这类阶段文案与在途按钮,未提交时点 × / 遮罩 / Esc 收起面板只是收起草稿、不发请求;面板关闭后任务仍在「生成任务」面板(非模态浮层,无 `aria-modal`)里显示后端 `phaseDetail`;第一条未终态时提交第二条 → 第二条显示「排队中。」且生成提交 IPC 次数仍为 1,第一条终态后自动补发(次数为 2);两条各自完成后各走一次「配对读 + 落卡」,manifest revision 单调、不被后到者覆盖。
|
||||
9. 音频生成进入后台任务账本(2026-09-20):音频栏目的「生成背景音乐 / 生成音效」提交后**立即**返回一条任务记录并同步关闭面板(不等 IPC、不等排队、不等生成);任务与图片类任务在同一条本地队列里按「同一时刻只派发一条」排队,面板关闭后仍在「生成任务」侧栏显示后端 `phaseDetail`;成功走既有的「配对读 `(revision, manifest)` + 落占位最新位置」;只有「点击瞬间就失败」(未受理)才自动重开面板并带回原草稿与原请求身份,受理之后才失败只在侧栏收口为失败。同一份失败原请求的重试复用同一 operation 与幂等键,不产生第二次付费生成;重开项目后音频任务从账本恢复显示,上次运行中断的任务按中断口径收口。
|
||||
|
||||
## 8. 非目标
|
||||
|
||||
|
||||
@@ -1,59 +0,0 @@
|
||||
# AGC 模板库客户端接入实施计划
|
||||
|
||||
Version: 1.0
|
||||
Status: active
|
||||
Date: 2026-09-17
|
||||
Milestone Spec: `docs/project-memory/plans/【里程碑】AGC模板库客户端接入-2026-09-17.md`
|
||||
|
||||
## 步骤
|
||||
|
||||
1. **OSS 库布局与契约**
|
||||
- 在 `agc-dev` 落地 `templates/` 前缀:`index.json`、`v1/<id>/{template.json,template.zip,cover.*}`。
|
||||
- 清单补齐 `tags`、`coverKey/coverWidth/coverHeight/coverSha256`,正文改为 zip(zip 根 == 项目根)。
|
||||
- 模板源落在 `apps/ai-game-creator-shell/template-library/v1/<id>/{meta.json,project/**,cover.*}`;zip 由 `scripts/agc-template-library-publish.mjs` 现场打包(不落仓库)。
|
||||
- 交付:发布脚本(校验 + 打包 + 上传 + 回读校验,支持 `--dry-run` / `--prune`)、`templates/README.md`,以及 5 个模板(3 个空白 + 2 个起步工程)。
|
||||
- 验收:匿名 `GET templates/index.json` 可读,每个 `zipKey` 回读 SHA-256 与清单一致。
|
||||
|
||||
2. **Rust 模板库模块**
|
||||
- 新增 `src-tauri/src/template_library.rs`:清单解析与校验、受信任 base、缓存/安装目录、zip 安全解压、安装记录、由模板建项目。
|
||||
- 注册命令 `fetch_game_template_library`、`download_game_template`、`create_automatic_local_game_project_from_template`。
|
||||
- 交付:模块内 8 项单测(schema/重复模板、键前缀、base 校验、解压逃逸、摘要与大小、安装记录、建项目与失败清理)。
|
||||
- 验收:`cargo test --bin genarrative-ai-game-creator-shell template_library` 全绿。
|
||||
|
||||
3. **前端状态链路**
|
||||
- `src/features/template-library/templateLibraryModel.ts`(类型与搜索/筛选纯函数)与 `useTemplateLibrary.ts`(拉取、下载、建项目、就地更新已下载状态)。
|
||||
- `useHomeProjectCreation` 增加 `enterCreatedTemplateProject`,复用既有进项目通道。
|
||||
- 交付:9 项模型单测。
|
||||
- 验收:`npx vitest run src/features/template-library` 全绿。
|
||||
|
||||
4. **界面接入**
|
||||
- 新增 `src/view/template-library/index.tsx` 全屏页;`LauncherView` 增加 `template-library`;左侧导航加模板库入口。
|
||||
- 首页「灵感推荐」替换为 `TemplateRecommendations`;删除 `InspirationGallery.tsx` 与 `assets/inspiration/`。
|
||||
- `tauri.conf.json` 的 `img-src` 放行受信任 OSS 主机以加载封面。
|
||||
- 验收:模板库页可搜索、筛选、下载、显示已下载并成功建项目;首页推荐位可跳转。
|
||||
|
||||
5. **文档与共享记忆**
|
||||
- 主规范 `docs/technical/【技术方案】AGC模板库与模板建项-2026-09-17.md`,并在 `docs/README.md` 建索引。
|
||||
- 本里程碑与实施计划;`decision-log.md` 记录库路径、清单 schema、缓存目录与 CSP 约定。
|
||||
- 验收:`node scripts/check-doc-index.mjs` 通过。
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell template_library
|
||||
cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell template_library -- --ignored
|
||||
cd apps/ai-game-creator-shell && npx tsc -p tsconfig.json --noEmit
|
||||
npx vitest run apps/ai-game-creator-shell/tests/templateLibraryModel.test.ts apps/ai-game-creator-shell/tests/templateLibraryView.test.tsx
|
||||
node scripts/agc-template-library-publish.mjs --source <dir> --dry-run
|
||||
npm run check:encoding
|
||||
node scripts/check-doc-index.mjs
|
||||
git diff --check
|
||||
```
|
||||
|
||||
## 风险与回退
|
||||
|
||||
- **封面走 WebView 直连**:仅放行受信任 OSS 主机;若日后改用后端签名,清单的 `coverKey` 不变。
|
||||
- **模板包体积**:下载上限 512 MiB、解压文件数 4096、单文件 256 MiB;超限直接拒绝,不落盘。
|
||||
- **清单漂移**:客户端只信「受信任主机 + 对象键」,清单中的地址字段不参与请求。
|
||||
- **回退**:清空 `templates/` 前缀即回到空模板库;客户端保留错误与空态展示,不阻断其它功能。
|
||||
@@ -0,0 +1,49 @@
|
||||
# 【实施计划】AGC 渠道安装身份隔离
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】AGC渠道安装身份隔离-2026-09-21.md` |
|
||||
| Status | ready |
|
||||
| Owner | 当前 Agent |
|
||||
|
||||
## 修改边界
|
||||
|
||||
- 允许修改:
|
||||
- `apps/ai-game-creator-shell/scripts/channel-identity.mjs`(新增,渠道身份单点定义)
|
||||
- `apps/ai-game-creator-shell/scripts/build-release.mjs`、`build-macos-ci.mjs`、`check-config.mjs`、`agent-swarm-test-chat.mjs`
|
||||
- `apps/ai-game-creator-shell/src-tauri/src/main.rs`、`src-tauri/src/windows.rs`、`src-tauri/src/config.rs`
|
||||
- 对应测试:`build-release.test.mjs`、`prepare-macos-codex.test.mjs`
|
||||
- 文档:AGC 更新主规范、共享记忆与本计划对
|
||||
- 明确不修改:OSS 分区布局、官网下载接口与页面、Jenkins Job 参数、渠道版本发行逻辑、Apple 签名/公证、移动壳。
|
||||
|
||||
## 实现顺序
|
||||
|
||||
1. 抽出 `channel-identity.mjs`:渠道校验、渠道显示名、`resolveChannelInstallIdentity()`;`build-release.mjs` 复用并再导出渠道校验。
|
||||
2. 渠道 `--config` 同时注入 `productName` 与 `identifier`;macOS 发布入口按发布渠道解析产品名(`.app`、updater 归档、DMG 卷名与文件名)。
|
||||
3. Rust:主窗口/工作区/启动器窗口标题取构建期产品名;AGC 自有 AppData 目录的 ACL managed 识别覆盖 `<基线>` 与 `<基线>.<渠道>`。
|
||||
4. 门禁与测试:`check-config.mjs` 断言基线等于默认渠道身份、非默认渠道身份隔离;`build-release.test.mjs` 增补身份与首装包用例;`prepare-macos-codex.test.mjs` 改断言为消费渠道身份。
|
||||
5. 文档:更新 AGC 更新主规范与共享记忆,登记决策与踩坑。
|
||||
|
||||
## 验证命令
|
||||
|
||||
1. `node --check apps/ai-game-creator-shell/scripts/channel-identity.mjs apps/ai-game-creator-shell/scripts/build-release.mjs apps/ai-game-creator-shell/scripts/build-macos-ci.mjs apps/ai-game-creator-shell/scripts/check-config.mjs`
|
||||
2. `node --test apps/ai-game-creator-shell/scripts/build-release.test.mjs apps/ai-game-creator-shell/scripts/release-oss.test.mjs apps/ai-game-creator-shell/scripts/prepare-macos-codex.test.mjs apps/ai-game-creator-shell/scripts/cargo-features.test.mjs`
|
||||
3. `node apps/ai-game-creator-shell/scripts/check-config.mjs`
|
||||
4. `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell -- config::tests:: --test-threads=1`
|
||||
5. `npm run check:encoding`、`npm run check:doc-index`、`git diff --check`
|
||||
|
||||
## 验证结果
|
||||
|
||||
- `node --test build-release.test.mjs release-oss.test.mjs prepare-macos-codex.test.mjs cargo-features.test.mjs`:64/64 通过(新增渠道身份、身份注入与渠道 DMG 首装选择三条用例)。
|
||||
- `node apps/ai-game-creator-shell/scripts/check-config.mjs`、`npm --prefix apps/ai-game-creator-shell run typecheck`:通过。
|
||||
- `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell -- config::private_path_elevation_policy_tests`:12/12 通过。
|
||||
- `AGC_UPDATE_CHANNEL=release npm --prefix apps/ai-game-creator-shell run build -- --no-bundle --debug`:Tauri 接受派生的 `productName` / `identifier` 并完成构建;产物字符串实测 `陶泥儿 Release` × 1、`agc/release-win/latest.json` × 1、`world.genarrative.ai-game-creator.release` × 1、`agc/dev-win/latest.json` × 0。
|
||||
- `cargo fmt --check`(AGC 壳)、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`:通过。
|
||||
- 未执行:真实渠道打包(需要签名私钥与发号/上传授权)、双渠道真机安装与并存、macOS 节点实跑。
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- 风险:默认渠道身份若被改动,既有安装目录、卸载项与升级链会断。回滚点:基线 `tauri.conf.json` 与默认渠道映射不变,门禁用例钉住。
|
||||
- 风险:非默认渠道首次以新身份安装,老 `dev` 用户不会自动迁移本地数据。回滚点:渠道身份只影响非默认渠道构建,撤销该渠道的构建产物即可,仓库侧无数据迁移。
|
||||
- 风险:窗口标题改为构建期产品名后,标题不再等于配置里的字面量。回滚点:去掉 `main.rs` 的标题覆盖调用,行为回到配置标题。
|
||||
- 风险:ACL managed 识别放宽到前缀族。回滚点:`is_game_creator_packaged_app_data_leaf` 收紧回单一直线值,但非默认渠道的提权修复会重新失败关闭。
|
||||
@@ -26,15 +26,15 @@
|
||||
|
||||
## 问题状态
|
||||
|
||||
| 编号 | 问题 | 状态与证据 |
|
||||
| --- | --- | --- |
|
||||
| B01 | 刷新后首次进入画布元素抖动 | 已优化;用户在本轮反馈未再复现,按用户要求更新状态。不宣称所有布局/动画原因均已排除。 |
|
||||
| B02 | 初次进入双指平移无效,整理后恢复 | 已优化;用户在本轮反馈未再复现,按用户要求更新状态。隔离组件连续平移通过。 |
|
||||
| B03 | 快速平移触发更新深度错误 | 已修复已确认的窗口 Context 反馈循环,回归验证收敛;真实操作继续观察。 |
|
||||
| B04 | 资源选中后运行不可用提示消失 | 已修复,提示与选择解耦,自动化验证通过。 |
|
||||
| B05 | 对话记录偶发丢失 | 已定位历史分页卡点,尚未修改。只读复验用户提供的历史:558 条合法原始记录中有 44 条聊天消息;首屏原始 20 条只投影出一条助手消息,下一页原始 20 条没有聊天消息,按消息计算的游标不推进。已存用户提问和最终回答因此无法继续翻出;不能凭该文件排除其它未落盘记录。 |
|
||||
| B06 | JSON 文档未正确识别展示 | 已按用户确认完成本地修复:合法 UI State 由原生完整校验,卡片显示 UI 设计并进入现有编辑器;普通 JSON 显示 JSON 并可代码预览。自动化验证通过,待重建原生客户端验收;详见 JSON 语义识别实施计划。 |
|
||||
| C01 | 右键平移,保留左键框选 | 已实现,卡片左键拖动、框选、指针取消/失焦/捕获丢失及控件边界测试通过。 |
|
||||
| 编号 | 问题 | 状态与证据 |
|
||||
| ---- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| B01 | 刷新后首次进入画布元素抖动 | 已优化;用户在本轮反馈未再复现,按用户要求更新状态。不宣称所有布局/动画原因均已排除。 |
|
||||
| B02 | 初次进入双指平移无效,整理后恢复 | 已优化;用户在本轮反馈未再复现,按用户要求更新状态。隔离组件连续平移通过。 |
|
||||
| B03 | 快速平移触发更新深度错误 | 已修复已确认的窗口 Context 反馈循环,回归验证收敛;真实操作继续观察。 |
|
||||
| B04 | 资源选中后运行不可用提示消失 | 已修复,提示与选择解耦,自动化验证通过。 |
|
||||
| B05 | 对话记录偶发丢失 | 已定位历史分页卡点,尚未修改。只读复验用户提供的历史:558 条合法原始记录中有 44 条聊天消息;首屏原始 20 条只投影出一条助手消息,下一页原始 20 条没有聊天消息,按消息计算的游标不推进。已存用户提问和最终回答因此无法继续翻出;不能凭该文件排除其它未落盘记录。 |
|
||||
| B06 | JSON 文档未正确识别展示 | 已按用户确认完成本地修复:合法 UI State 由原生完整校验,卡片显示 UI 设计并进入现有编辑器;普通 JSON 显示 JSON 并可代码预览。自动化验证通过,待重建原生客户端验收;详见 JSON 语义识别实施计划。 |
|
||||
| C01 | 右键平移,保留左键框选 | 已实现,卡片左键拖动、框选、指针取消/失焦/捕获丢失及控件边界测试通过。 |
|
||||
|
||||
## 已取得证据与剩余门禁
|
||||
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
# 【实施计划】AGC 音频生成进入后台任务账本
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】AGC音频生成进入后台任务账本-2026-09-20.md` |
|
||||
| Status | implemented-awaiting-runtime-acceptance |
|
||||
| Owner | 主 Agent(自审;本运行没有独立评审人) |
|
||||
|
||||
## 修改边界
|
||||
|
||||
- 允许修改:
|
||||
- 主规范:`docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`(§3.10 / §7.9)、`docs/technical/【AGC】栏目画布底部工具栏入口矩阵-2026-09-13.md`。
|
||||
- AGC 原生:`apps/ai-game-creator-shell/src-tauri/src/asset_generation_tasks.rs`、`commands.rs`、`project.rs`、`project/resource_editor.rs`(仅新增收口入口,不改既有派生语义)。
|
||||
- AGC 前端:`apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasAssetGenerationTaskModel.ts`、`resourceCanvasAssetGenerationQueue.ts`、`view/project-development/index.tsx`。
|
||||
- 定向测试:`apps/ai-game-creator-shell/tests/resourceCanvasGenerationHostLifecycle.test.tsx`、`resourceCanvasAssetGenerationQueue.test.ts`、`appSurface/project-development.suite.ts`(仅音频相关断言)。
|
||||
- 明确不修改:`/api/editor/audios/*/generations` 与 `/api/external/v1` 路由、请求体、OpenAPI、共享 DTO、SpacetimeDB schema、权限命令词汇、`derive_local_project_resource` 的同步语义与其既有无源生成入参校验。
|
||||
|
||||
## 实现顺序
|
||||
|
||||
1. 主规范:把音频入口的接线口径从「同步无源生成」改写为「与图片类同一条后台任务账本」,并补上音频提交载荷、失败重开与幂等条款(PRD §3.10 / §7.9,AGC 工具栏入口矩阵文档)。
|
||||
2. 原生:在资源编辑模块新增音频入参收口与「后台跑一次音频派生」的入口(复用既有派生实现,不复制生成逻辑);在 `asset_generation_tasks` 里按 `kind` 分流,音频任务复用同一份账本、同一套阶段文案与中断收口;`start_local_project_asset_generation` 增加可选幂等键入参,音频 kind 走新分支且不改图片类载荷口径。
|
||||
3. 原生测试:音频任务入参收口(kind / 提示词上限 / 幂等键 / 未知 kind 拒绝)、账本记录 kind 为音频、图像载荷口径不回归。
|
||||
4. 前端模型与队列:任务模型支持音频任务(kind、请求身份、无比例 / 尺寸 / 参考字段),音频 kind 的入口文案从工具栏模型派生;队列按 kind 分流派发同一命令的音频载荷,其余排队与轮询语义不变。
|
||||
5. 前端宿主:音频提交改为「入队即返回」,占位绑定任务 id、自动展开侧栏、给出提示条;收口复用既有「配对读 + 落卡」链路,未受理失败按原请求身份重开音频面板。
|
||||
6. 前端测试:宿主生命周期(提交即关闭、侧栏可见、落卡、未受理失败重开并复用身份)、队列音频分支(载荷与轮询、第二条本地排队不发 IPC)、appSurface 音频载荷。
|
||||
7. 验证与证据矩阵:跑定向测试、类型检查、编码 / 文档索引 / `git diff --check`,按里程碑逐条填写证据。
|
||||
|
||||
## 验证命令
|
||||
|
||||
1. `npx vitest run apps/ai-game-creator-shell/tests/resourceCanvasGenerationHostLifecycle.test.tsx apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationQueue.test.ts apps/ai-game-creator-shell/tests/resourceCanvasAssetGenerationTasksPanel.test.tsx`
|
||||
2. `npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts`
|
||||
3. `cargo test -p genarrative-ai-game-creator-shell asset_generation_task`
|
||||
4. `npm run agc:typecheck`(或 `npm run typecheck --workspace @genarrative/ai-game-creator-shell`)
|
||||
5. `npm run check:encoding && npm run check:doc-index && git diff --check`
|
||||
|
||||
## 执行结果
|
||||
|
||||
1. 主规范:PRD(§3.10 / §7.9 / §7.9 第 8~9 条)与 AGC 工具栏入口矩阵文档改为「音频与图片类同一条后台任务账本」,同步 `【测试用例】AGC资源工作台V3端到端验收` 的 S11a 判据。
|
||||
2. 原生:`prepare_local_project_audio_generation`(提交期收口)+ `run_local_project_audio_generation_at`(派发时刻读 revision,复用派生实现),`start_local_project_asset_generation` 新增可选 `idempotencyKey` 并在音频 kind 分支落同一份账本、由 `run_local_project_audio_generation_task` 写 running → completed / failed;图片类分支逐字未改。
|
||||
3. 前端:任务模型新增音频任务与 `idempotencyKey`(恢复出来的历史任务不带它,也不承接重试);队列按 kind 分流派发载荷;面板提交改为同步返回并立即关闭;宿主改为同步入队 + 失败重开。
|
||||
4. 测试:面板(点击即关闭、无阶段文案与在途按钮)、队列(音频载荷逐字)、宿主生命周期(提交关闭 / 侧栏 / 落卡 / 未受理重开 / 受理后不重开 / 重试身份复用 / 失败态按占位隔离)、appSurface 音频载荷。
|
||||
5. 验证命令与结果:9 个定向 vitest 文件 73 项通过;`appSurface.test.ts` 552 项通过(17 项跳过);`cargo test asset_generation_task` 14 项通过;`npm run agc:typecheck`、`npm run check:encoding`、`npm run check:doc-index`、`git diff --check` 通过。
|
||||
6. 与预期不一致处:音频任务不再携带 `targetCategory`(原生音频通道不消费它,前端也没有读它的地方);`restored` 任务无幂等键,只用于展示与定位,不承接重试。
|
||||
7. 已知与本任务无关的既有失败:`clientAuthStorage` / `clientApi` / `clientHttp` / `chatPromptPolish` / `projectCreationDirectory` 五个文件在本机 Node v26 + vitest 0.34 的 jsdom 下 `localStorage` 为 undefined(在干净工作区同样失败);`cargo test resource_edit` 整组过滤下有 5 项既有并行干扰失败(单跑通过)。
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- 音频任务与图片类任务共用队列:若音频任务未终态会挡住后续派发(本地排队是既有语义,接受)。回滚点是前端提交分支与原生 `kind` 分流,各自可独立回退。
|
||||
- 音频自带的 operation 幂等账本与任务账本是两层身份:任务 id 取 operation id,重试复用同一对 operation / 幂等键;不得为「省事」在重试时换新的请求身份(那是一次新的付费生成)。
|
||||
- 账本 `kind` 为音频时,`restore` 的入口文案若查不到工具栏模型会退化成素材名:入口文案必须由工具栏模型派生,避免恢复后文案漂移。
|
||||
- 后台跑生成会让「项目 revision CAS」窗口从提交前移到派发时刻:冲突时按失败收口(不静默重试),避免把生成写到非预期基线。
|
||||
@@ -0,0 +1,27 @@
|
||||
# 【实施计划】DirectProject Skill 提及输入提示
|
||||
|
||||
| 字段 | 值 |
|
||||
| --------- | ----------------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject Skill提及输入提示-2026-09-15.md` |
|
||||
| Status | in-progress |
|
||||
| Owner | Codex |
|
||||
|
||||
## 代码边界
|
||||
|
||||
- 前端:`features/project-workspace/ResourceReferenceInput.tsx`、`ResourceReferenceNode.tsx`、`resourceReferences.ts`、生成绑定及聊天入口透传。
|
||||
- Rust:`agent/direct_codex_user_item/model.rs`、`validation.rs`、`wire.rs`、`codex_app_server/mod.rs` 与对应测试。
|
||||
- 文档:父规范与本里程碑/实施计划。
|
||||
|
||||
## 小切片顺序
|
||||
|
||||
1. 先扩展前端 Skill catalog/节点/草稿 content,保持素材行为不变并补前端测试。
|
||||
2. 扩展 canonical Rust part 与 ts-rs 绑定,补序列化和失败校验测试。
|
||||
3. 接通 Codex wire `type: skill` 转换和受控路径解析,补历史/重放测试。
|
||||
4. 完成入口透传、定向验证和文档证据;每个切片单独中文提交。
|
||||
|
||||
## 验证与回滚
|
||||
|
||||
- `npm --prefix apps/ai-game-creator-shell run typecheck`
|
||||
- 相关 Vitest 与 `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml direct_codex`
|
||||
- `npm run check:encoding`、`npm run check:doc-index`、`git diff --check`
|
||||
- 每个切片只改计划列出的文件;若 Codex wire 协议或 Skill catalog 来源不确定,停在该切片并先更新规范。
|
||||
@@ -1,10 +1,10 @@
|
||||
# 【实施计划】DirectProject Thread Manager 事件订阅
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 字段 | 值 |
|
||||
| --------- | ---------------------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject Thread Manager事件订阅-2026-09-15.md` |
|
||||
| Status | ready |
|
||||
| Owner | Codex |
|
||||
| Status | ready |
|
||||
| Owner | Codex |
|
||||
|
||||
## 修改边界
|
||||
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
# 【实施计划】DirectProject canonical content 严格边界
|
||||
|
||||
| 字段 | 值 |
|
||||
| --------- | ------------------------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject canonical content严格边界-2026-09-16.md` |
|
||||
| Status | implemented |
|
||||
| Owner | Codex |
|
||||
|
||||
## 实施顺序
|
||||
|
||||
1. 先把主转换函数改为原样传递 `draft.content`,并在 content-only 测试中覆盖空白 part 保留。
|
||||
2. 将最终 content 有效性判断抽为纯函数,接入普通提交、队列入队和其它 Direct Codex 入口。
|
||||
3. 删除 Direct Codex 的 `userItem` fallback;首页首轮和队列出队直接构造 canonical user item。
|
||||
4. 收敛策略确认重试为复用同一 canonical user item;旧 Supervisor/Planning caller 加 TODO,不改变其非 Direct Codex 行为。
|
||||
5. 迁移现有测试 fixture,删除旧字段构造,不增加“字段不存在”测试。
|
||||
|
||||
## 落地结果
|
||||
|
||||
- `chatComposerDraftToDirectCodexUserItem` 原样传递 `draft.content`;新增 `directCodexUserItemFromContent` 供 caller 直接构造 canonical item。
|
||||
- `ChatComposerDraft` 只保留 `content`;`ResourceReferenceInput` 的对外草稿、`chatPromptDraftKey`、`QueuedChatTurn` 全部改为 content-only。
|
||||
- 首页首轮、普通聊天提交、运行中队列出队、策略确认重试都携带同一个 canonical user item;`executeChatAgentReply` 的 `userItem` 兜底分支已删除。
|
||||
- 旧 Planner / legacy Supervisor caller 显式构造纯文本 item 并留下迁移 TODO。
|
||||
|
||||
## 修改边界
|
||||
|
||||
- 允许修改:AGC shell 前端 `resourceReferences`、`App`、聊天队列、Direct Codex 相关测试和当前里程碑文档。
|
||||
- 不修改:Rust user item schema、附件 DTO、SpacetimeDB、HTTP API、用户已有 `.env` / `package-lock.json` 修改。
|
||||
- 不引入:`text` / `references` 到 canonical Direct Codex item 的任何兼容 fallback。
|
||||
|
||||
## 验证命令
|
||||
|
||||
- `npm run test -- apps/ai-game-creator-shell/tests/resourceReferences.test.ts apps/ai-game-creator-shell/tests/resourceReferenceInput.test.tsx apps/ai-game-creator-shell/tests/chatPromptPolish.test.tsx apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts`
|
||||
- `npm run ai-game-creator-shell:typecheck`
|
||||
- `npm run check:encoding`
|
||||
- `npm run check:doc-index`
|
||||
- `git diff --check`
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- 空白 `input_text` 不再前端删除,需确保最终有效性判断只拒绝全空 content,不改变其它 part。
|
||||
- Direct caller 漏传 user item 时应在类型检查或明确错误分支暴露,不能静默重建。
|
||||
- 共享工作树含用户未提交修改;提交时只 stage 本计划和本次代码 hunk。
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
# 【实施计划】DirectProject composer canonical content 闭环
|
||||
|
||||
| 字段 | 值 |
|
||||
| --------- | --- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject composer canonical content闭环-2026-09-21.md` |
|
||||
| Status | implemented |
|
||||
| Owner | Codex |
|
||||
|
||||
## 交付结果
|
||||
|
||||
删除 Direct composer 的 `text + references` 回写事实源,改为完整 `content[]` 的单向读写;同时修复附件在 editor root 重建、润色回填和提交合并中的丢失窗口。Planning V2 / 快速编辑只保留明确的非 Direct adapter,不进入 Direct canonical 发送路径。
|
||||
|
||||
## 实施顺序
|
||||
|
||||
1. **锁定当前失败面**:补一个最小回归测试,先证明 `applyDraftToRoot` 对含 `agc_attachment_reference` 的 root 重建会丢附件,并记录 Direct 当前的三份并行状态与附件 sidecar 合并点。
|
||||
2. **收窄编辑器接口**:把 `ChatComposerDraft` 改成 content-only;将 `ResourceReferenceInput` 的受控恢复改为 `initialContent` / `content` 语义,删除 Direct 使用的 `value` + `references` 同步 effect。保留 `ChatReference` 仅用于 picker 节点创建和只读投影。
|
||||
3. **替换所有 root 写入**:删除 `buildDraftSegments` / `applyDraftToRoot` 的 Direct 调用;提供一个完整的 `applyContentToRoot`(或同等深模块接口),保留文本换写、引用和附件的顺序与字段。AI 润色改为“读取 content → 对回包文本按 token 扫描 → 原位换回真 part;被改写的 part 末尾补位”,引用与附件同一套口径。
|
||||
4. **收口 Direct controller**:以 `content[]` 作为草稿事实源;上传完成的附件在一个明确的 `append`/`merge` seam 合并,不再长期维护 `chatInput`、`chatReferences`、`chatContent` 三份状态。prompt 只在调用边界派生,队列和策略重试保留原 user item。
|
||||
5. **隔离非 Direct caller**:Planning V2 和资源快速编辑按各自需求选择 content-only 或独立文本 adapter;不得为了兼容它们把旧字段放回共享 Direct 接口。若快速编辑只需要文本,使用不承诺引用/附件语义的窄接口。
|
||||
6. **补齐验收证据并清理**:删除无调用方的旧 helper、字段和注释;更新测试 fixture、专题文档和本计划状态。完成后把稳定结论合并回功能说明/共享记忆,并删除已完成的临时计划。
|
||||
|
||||
## 重点修改边界
|
||||
|
||||
- `apps/ai-game-creator-shell/src/features/project-workspace/ResourceReferenceInput.tsx`
|
||||
- `apps/ai-game-creator-shell/src/features/project-workspace/resourceReferences.ts`
|
||||
- `apps/ai-game-creator-shell/src/features/project-workspace/usePromptPolish.ts` / `chatPromptPolish.ts`(仅在需要支持 content 变换时)
|
||||
- `apps/ai-game-creator-shell/src/view/project-development/chat/controller/useDirectProjectChatController.ts`
|
||||
- `apps/ai-game-creator-shell/src/view/project-development/chat/components/DirectProjectComposer/`
|
||||
- `apps/ai-game-creator-shell/src/view/project-development/planning/PlanningChatView.tsx` 与 `App.tsx` 中 Planning adapter
|
||||
- `apps/ai-game-creator-shell/src/view/project-development/index.tsx` 的快速编辑输入 adapter
|
||||
- 对应 `resourceReferences`、`resourceReferenceInput`、`chatPromptPolish`、Direct composer/appSurface 测试
|
||||
|
||||
## 关键不变量
|
||||
|
||||
- `content[]` 是唯一可发送事实;任何 `prompt`、label、chip 文案都是派生值。
|
||||
- `agc_attachment_reference` 不属于 `ChatReference`,不能借 `references` 传递。
|
||||
- 润色回包只按 token 反解析引用与附件(`draftScanToken` 与出站 `directCodexContentToPromptText` 同口径);token 被删掉时不猜位置,只把该 part 补在末尾,保证不丢。
|
||||
- Direct 初始首轮、普通提交、队列、权限确认重试都使用同一个 `DirectCodexUserItem` 语义。
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
npm run test -- apps/ai-game-creator-shell/tests/resourceReferences.test.ts apps/ai-game-creator-shell/tests/resourceReferenceInput.test.tsx apps/ai-game-creator-shell/tests/chatPromptPolish.test.tsx apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts apps/ai-game-creator-shell/tests/appSurface/project-conversation.suite.ts
|
||||
npm run ai-game-creator-shell:typecheck
|
||||
npm run check:encoding
|
||||
npm run check:doc-index
|
||||
git diff --check
|
||||
```
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- `ResourceReferenceInput` 当前同时服务 Direct、Planning、快速编辑;先建立 adapter seam,再删除旧 props,避免一次性把策划链路打坏。
|
||||
- 附件目前在 Direct controller 里作为待发 sidecar,若直接移入编辑器必须同步处理上传失败、移除、清空和项目切换;任何阶段都不能把附件只留在展示 chip 而未进入 user item。
|
||||
- 润色服务只返回文本,不能让其响应覆盖原 content;失败时保留原 content。回滚使用 Git revert,不增加运行时开关或兼容分支。
|
||||
- 工作树已有用户未提交修改,实施时只 stage 本里程碑涉及的 hunk。
|
||||
|
||||
## 落地结果
|
||||
|
||||
- 编辑器接口收窄为 content-only:`ResourceReferenceInput` 只接 `initialContent` / `onChange`,`ChatComposerDraft` 只剩 `content`;`applyDraftToRoot` 与受控 `value` / `references` 同步 effect 均删除。
|
||||
- 所有 root 写入统一走 `applyContentToRoot`;润色走 `applyPolishedTextToRoot`,对引用与附件做同一套 token 扫描并在原位置换回真 part,被改写的 part 末尾补位。
|
||||
- Direct controller 去掉 `chatInput` / `chatReferences` / `chatContent`,附件在提交边界合成进同一份 canonical content;Planning 与其它 legacy 消费方改用 `directCodexContentToLegacyContentDto` 单向取文本。
|
||||
- 删除无调用方的 `EMPTY_CHAT_COMPOSER_DRAFT`。
|
||||
- 回归证据:`resourceReferenceInput`(含附件 round-trip、润色原位恢复、润色末尾补位)、`resourceReferences`、`chatPromptPolish`、`usePromptPolish`、`resourceCanvasAssetGenerationReferences`、全量 `appSurface`、AGC typecheck、`check:encoding`、`git diff --check`。
|
||||
- 遗留 TODO:润色服务把 token 一起删掉时无法反推原位置;需要精确恢复时由产品补带位置信息的润色协议。
|
||||
@@ -1,15 +1,16 @@
|
||||
# 【实施计划】DirectProject 用户 Response item 输入
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 字段 | 值 |
|
||||
| --------- | ------------------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject用户ResponseItem输入-2026-09-15.md` |
|
||||
| Status | in-progress |
|
||||
| Owner | Codex |
|
||||
| Status | in-progress |
|
||||
| Owner | Codex |
|
||||
|
||||
## 修改边界
|
||||
|
||||
- 允许修改:AGC 壳 Rust agent 输入合同、DirectProject 历史适配、前端聊天引用模型、ts-rs 生成配置、当前聊天素材文档。
|
||||
- 明确不修改:assistant 返回协议、工具 activity、附件/图片协议、SpacetimeDB、HTTP API。
|
||||
- 明确不修改:assistant 返回协议、工具 activity、附件/图片上传 DTO、SpacetimeDB、HTTP API;上传 DTO 仅在入口转换为 canonical `content[]`,不再以 sidecar 文本追加。
|
||||
- 本切片明确:不根据 MIME 类型判断图片,不生成 `agc_image_reference`;所有上传文件统一映射为 `agc_attachment_reference`。
|
||||
|
||||
## 实现顺序
|
||||
|
||||
|
||||
@@ -0,0 +1,95 @@
|
||||
# 【实施计划】DirectProject 聊天模块抽离
|
||||
|
||||
| 字段 | 值 |
|
||||
| --------- | ----------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject聊天模块抽离-2026-09-18.md` |
|
||||
| Status | implemented |
|
||||
| Owner | Codex |
|
||||
|
||||
## 修改边界
|
||||
|
||||
### 允许修改
|
||||
|
||||
- `apps/ai-game-creator-shell/src/App.tsx`:删除 DirectProject 专属状态、ref、effect、订阅/历史/发送/队列/附件/中止处理和 Direct 专属 JSX 接线;保留项目开发工作台壳与 DirectProject / 立项策划两条入口的选择。
|
||||
- `apps/ai-game-creator-shell/src/view/project-development/chat/DirectProjectChatView.tsx`、`useDirectProjectChatController.ts` 与 `generated/`:新增 DirectProject 表现容器、controller 及其 ts-rs 契约目录;共享 reducer/分页/队列模块只引用这份 Direct 契约,不复制类型。
|
||||
- `view/project-development/chat/` 与 `view/project-development/planning/`:普通项目的对话归 `DirectProjectChatView`,Design Agent 与 Planning V2 归 `PlanningChatView`;行为中立的公共表现组件按需复用或抽出。
|
||||
- `DirectProjectSettingsDialog` 与 `ProjectDevelopmentView`:移除聊天侧钱包注入和聊天设置中的钱包行,在工作台布局头部/工具栏独立渲染钱包入口,保留账户入口功能。
|
||||
- 现有 DirectProject 测试文件:按新模块责任迁移 import、测试入口和 harness,不新增场景或断言集合。
|
||||
- 当前 ADR、里程碑和实施计划文档,以及必要的 `CONTEXT.md` 术语。
|
||||
|
||||
### 明确不修改
|
||||
|
||||
- Rust、Tauri 命令、共享 DTO、Thread Manager、Codex app-server 和 `.agent/conversations/project.jsonl` / 运行态事件合同。
|
||||
- DirectProject 的路由判定语义、模型配置语义、聊天投影规则、历史锚点与分页协议。
|
||||
- DirectProject、Design Agent、Planning V2 的正式行为与页面入口。
|
||||
- 任何运行时 feature flag、兼容别名、双跑路径或旧行为墓碑代码。
|
||||
|
||||
## 实现顺序
|
||||
|
||||
1. 以当前测试为基线,标记 DirectProject 断言归属:纯 reducer/投影/分页/附件测试归内部模块,Composer 的队列/恢复/中止断言归 Direct 容器 harness,项目开发页面只保留入口接线断言;不增加新测试场景。
|
||||
2. 建立 `direct-project-chat/` 私有模块边界,复用现有 `directThreadChat`、`directHistoryPaging`、`directHistoryAnchorGate`、`directTurnPresentation`、`chatComposerQueue` 与附件映射,不复制第二套事实源或 reducer。
|
||||
3. 将 DirectProject 生命周期整体搬入 `DirectProjectChat`:项目切换清理、订阅 bootstrap/notify/consume、首屏锚点、历史连拉、用户回合预写、Direct invoke、鉴权重试、FIFO 出队、附件上传、中止 released 分支和 manifest 刷新均由该容器管理。
|
||||
4. 将 Direct 专属 JSX 从工作台聊天宿主移入 Direct 表现模块:Direct 回合分区、运行中过程卡、Direct Composer、队列、附件、模型/推理选择、语音、中止、Direct 设置;共享组件只保留无行为真相的视觉表现。
|
||||
5. 项目开发工作台固定挂载 `DirectProjectChat`;立项策划(Design Agent、Planning V2)进入 `PlanningChatView`;删除 `directCodex` 作为共享组件行为开关及所有只服务它的 props,不保留 Direct fallback 或运行时 feature flag。
|
||||
6. 将钱包从聊天树移到 `ProjectDevelopmentView` 的工作台头部/工具栏:删除 `cloneElement` 对聊天元素的注入,删除 `DirectProjectSettingsDialog` 的钱包行和 Direct 上下文字段;钱包入口仍由布局直接渲染。
|
||||
7. 把现有测试按所有权迁移并运行定向验证;若发现行为差异,只修复抽离造成的回归,不扩展产品范围。完成后删除旧 Direct 分支与无 caller 的兼容代码。
|
||||
|
||||
## 测试迁移映射
|
||||
|
||||
| 现有测试 | 新归属 |
|
||||
| --------------------------------------------------------------------------------------- | ------------------------------------------- |
|
||||
| `directThreadChat.test.ts` | Direct 事件/历史状态模块 |
|
||||
| `directHistoryPaging.test.ts` | Direct 历史分页模块 |
|
||||
| `directHistoryAnchorGate.test.ts` | Direct 订阅锚点模块 |
|
||||
| `directTurnPresentation.test.ts` | Direct 聊天投影表现模块 |
|
||||
| `directCodexTurnAttachments.test.ts` | Direct 附件模块 |
|
||||
| `chat-composer.suite.ts` 的 FIFO、恢复出队、终止与竞态用例 | Direct 容器/发送队列 harness |
|
||||
| `project-development.suite.ts` 的 Direct 入口、历史、工具卡片、运行态隔离和连续回合用例 | Direct 容器接线;仅迁移测试入口,不新增场景 |
|
||||
|
||||
## 验证命令
|
||||
|
||||
1. `npx vitest run apps/ai-game-creator-shell/tests/directThreadChat.test.ts apps/ai-game-creator-shell/tests/directHistoryPaging.test.ts apps/ai-game-creator-shell/tests/directHistoryAnchorGate.test.ts apps/ai-game-creator-shell/tests/directTurnPresentation.test.ts apps/ai-game-creator-shell/tests/directCodexTurnAttachments.test.ts`
|
||||
2. `npx vitest run apps/ai-game-creator-shell/tests/appSurface/chat-composer.suite.ts apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts`
|
||||
3. `npx tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit`
|
||||
4. `npm run check:doc-index`
|
||||
5. `npm run check:encoding`
|
||||
6. `git diff --check`
|
||||
|
||||
## 风险与回滚点
|
||||
|
||||
- **状态遗漏**:任何 Direct 专属 state/ref/effect 留在 `App.tsx` 都会形成双重所有权;以 `rg` 扫描 Direct 专属符号和 `directCodex` props 作为删除检查。
|
||||
- **事实源漂移**:不得在新容器里重新维护 messages、turn-stream 或 tool-calls 副本;继续只使用项目对话历史、运行态事件和聊天投影。
|
||||
- **竞态回归**:重点检查 subscribe 回执前 notify 欠账、首屏锚点闸门、`turn.completed` 与 invoke finally 的 FIFO 出队窗口、提交早于 `turn.started` 的中止以及项目切换时附件/队列清理。
|
||||
- **布局回归**:钱包必须在工作台布局头部/工具栏出现,且聊天设置不再包含钱包行;账户入口功能不能因聊天抽离丢失。
|
||||
- **回滚**:本次采用一次性替换;失败时整体 Git revert,不保留旧/新双路径或运行时 fallback。
|
||||
|
||||
## 实施记录(2026-09-19)
|
||||
|
||||
### 模块落位
|
||||
|
||||
`apps/ai-game-creator-shell/src/view/project-development/chat/` 最终结构:
|
||||
|
||||
| 目录 | 内容 |
|
||||
| --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `DirectProjectChatView.tsx` | 唯一公开入口:项目路径、入口首轮需求、两条权限门,以及对壳的 `announce` 句柄 |
|
||||
| `components/` | 表现层,一个组件一个目录、逻辑与组件同目录:`DirectProjectChatHeader/`、`DirectProjectComposer/`(含 `ComposerControls.tsx`、`chatComposerQueue.ts`、`chatComposerVoice.ts`)、`DirectProjectConversation/`(含 `DirectProjectTurn.tsx`)、`DirectProjectSettingsDialog/`、`ToolCallGroup/`(含 `toolCallGroupPresentation.ts`) |
|
||||
| `controller/` | `useDirectProjectChatController`(发送/队列/附件/中止/历史分页)、`useDirectProjectManifest`(清单与 `projectId` 订阅)、`useDirectThreadChatSubscription`(`subscribe → consume → notify` 单飞循环 + 聊天 reducer 状态) |
|
||||
| `conversation/` | `directThreadChat.ts`(reducer)、`directThreadItemProjection.ts`、`directTurnPresentation.ts`、`directCodexConversation.ts`、`directCodexSession.ts`、`directCodexTurnAttachments.ts` |
|
||||
| `history/` | `directHistoryPaging.ts`、`directHistoryAnchorGate.ts` |
|
||||
| `generated/` | Rust ts-rs 导出的 Direct 契约 |
|
||||
|
||||
### 关键取舍
|
||||
|
||||
- 线程订阅与聊天 reducer 状态从控制器里提成独立 hook `useDirectThreadChatSubscription`:运行态事实源只有它一份,控制器只读投影结果,历史分页仍并入同一个 reducer。
|
||||
- 工作台级动作(如 `game.run_local` 的预览结果)不再写 `App.tsx` 的 `messages`:壳通过 `DirectProjectChatHandle.announce` 把这句话交给聊天的本地消息流,壳不持有 Direct 聊天消息。
|
||||
|
||||
### 验证结果
|
||||
|
||||
- `npx vitest run` 五个 Direct 纯模块测试:40 通过。
|
||||
- `npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts -t "direct"`:15 通过 / 4 失败,且 4 条在本次改动前(`HEAD` 的 `/tmp` worktree 基线)同样失败(用例期望 `chat_with_game_creator_direct_codex` 被调用,但 harness 未桩 `read_game_creator_app_config`,模型可用性校验把提交挡在 invoke 之前;另两条是既有交互断言)。基线同口径为 14 通过 / 5 失败,本次净增 1 条通过。
|
||||
- `npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts` 全量:153 失败 / 307 通过 / 17 跳过;`HEAD` 基线同口径 155 失败 / 305 通过。
|
||||
- `npx tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit`、`npx eslint --ext .ts,.tsx`、`npx prettier --check` 通过。
|
||||
|
||||
### 本计划外的后续项
|
||||
|
||||
- Supervisor 前端链路已随本计划之后的变更整体退役(Supervisor 独立调试窗口、纯聊天容器、工作台壳的 Supervisor 运行态与专业 Agent 面板、`App.tsx` 里只服务它们的 state/ref/effect/handler 全部删除),项目对话只保留 DirectProject 与立项策划两条产品路径;见 [decision-log](../shared-memory/decision-log.md) 2026-09-19 条。
|
||||
@@ -1,10 +1,10 @@
|
||||
# 【实施计划】DirectProject 聊天真相源收敛
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 字段 | 值 |
|
||||
| --------- | ------------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】DirectProject聊天真相源收敛-2026-09-16.md` |
|
||||
| Status | implemented |
|
||||
| Owner | Codex |
|
||||
| Status | implemented |
|
||||
| Owner | Codex |
|
||||
|
||||
## 修改边界
|
||||
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
# Mac 本机构建节点接入实施计划
|
||||
|
||||
- Version: 1
|
||||
- Status: preparing-network-required
|
||||
- Date: 2026-09-18
|
||||
- Parent Spec: `【里程碑】Mac本机构建节点接入-2026-09-18.md`
|
||||
|
||||
1. 本地准备 universal 依赖预备、CI 打包脚本和 Jenkinsfile,运行离线单测、配置门禁及编码检查。
|
||||
2. 恢复内网后只读核对 Jenkins 版本、既有节点/Job、Git 凭据标识与插件;已存在对象优先核对,不重复创建。
|
||||
3. 从同一控制器取得 agent.jar,以当前已有 Java 21 运行专用 inbound Agent;secret 保存在用户私有目录,LaunchAgent 参数只引用 secret 文件,不保存控制器 API Token。
|
||||
4. 建立单 executor、EXCLUSIVE 的专用 Mac 节点与手动 archive-only Job。源码必须是可追溯 Git 提交,未推送改动需另行确认源码交付方式,不能默认推送。
|
||||
5. 初次构建核对独立工作目录、空间、目标与依赖;在 Jenkins 实际 SUCCESS 后确认 DMG、SHA-256 和两架构 smoke 证据。
|
||||
|
||||
失败边界:网络不可达不启动重试服务;节点/Job 修改前保留原配置;不更改其它节点、Job 或调度。禁止把 CLI 日志、认证文件和私有路径提交 Git。未获得真实 SUCCESS 前保留活动计划。
|
||||
@@ -0,0 +1,16 @@
|
||||
# Mac 通用安装包实施计划
|
||||
|
||||
- Version: 1
|
||||
- Status: awaiting-user-acceptance
|
||||
- Date: 2026-09-18
|
||||
- Parent Spec: `【里程碑】Mac通用安装包与构建管线-2026-09-18.md`
|
||||
|
||||
1. 等待当前 Intel 编译结束,避免共用 staging 并发写。
|
||||
2. macOS build.rs 按白名单分别 stage 两套原生资源;共享 Layout 使用架构子目录,运行时原有 hash/版本校验不变。
|
||||
3. Tauri macOS 映射双目录,发布入口接受 universal 并生成两个清单键;更新配置门禁与定向测试。
|
||||
4. 安装包 smoke 支持显式选择主程序切片,验证 universal 主程序与该切片对应原生依赖。
|
||||
5. 用 Tauri universal 构建 app,分别做 arm64/Rosetta smoke,hdiutil 生成新 universal DMG,校验并交付。
|
||||
|
||||
不发布、不使用私钥;依赖仅从锁定 npm tarball 下载并对照 lockfile integrity。磁盘不足停止,不擅自删除其它 target/cache。保留单架构 DMG。Jenkins 配置作为后续门禁,不混入本地包构建。
|
||||
|
||||
本地构建与双架构隔离验证完成,证据见对应里程碑。更新 master 时先停止旧构建,保护并恢复改动后重建;未进行 Jenkins 写操作,待确认 Mac Agent 再制定管线实施计划。
|
||||
@@ -0,0 +1,40 @@
|
||||
# 后台模板上传实施计划
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | in-progress |
|
||||
| Date | 2026-09-21 |
|
||||
| Milestone Spec | `docs/project-memory/plans/【里程碑】后台模板上传-2026-09-21.md` |
|
||||
|
||||
## 修改边界与顺序
|
||||
|
||||
1. **领域规则(`module-assets/template_library.rs`)**:新增「导入准备」函数——按 ID 合并清单条目(新增默认上架、已存在就地更新并保留 `enabled` 与未知字段),校验 ID / 版本 / entry / runtime / 显示字段上限,产出待提交的清单与 `template.json` 字节;不接触存储。
|
||||
2. **存储(复用 `platform-oss/template_library.rs`)**:只使用既有 `begin_publish` / `read_index` / `put_immutable` / `commit_index` / `finish`;如缺少「读单个对象作元数据基线」的能力,再补最小只读方法,不改锁与提交语义。
|
||||
3. **契约(`shared-contracts/admin.rs` + `apps/admin-web/src/api/adminApiTypes.ts`)**:新增导入请求(manifest)与导入结果 DTO;错误体沿用现有 `AppError` + 逐项原因结构。
|
||||
4. **接口(`api-server/admin_templates.rs` + `modules/admin.rs`)**:新增 multipart handler,按「解析 manifest → 校验每个 ZIP / 封面 → 取锁 → CAS → 写内容寻址对象并回读 → 提交清单 → 释放锁」顺序实现;路由套 `require_admin_auth` 与 256 MiB body 上限,并同步路由契约测试与页签权限矩阵测试。
|
||||
5. **后台页面(`AdminAgcTemplatesPage.tsx` + `adminApiClient.ts`)**:新增「上传模板」入口与弹窗(多选 ZIP、逐行元数据、批量提交、逐行错误、写入确认),沿用既有 `useAdminWriteConfirm` 与刷新语义。
|
||||
6. **文档**:主规范新增「后台模板上传」章节;决策记录补一条;主规范中「本轮只允许…不上传 ZIP」改为指向新章节。
|
||||
|
||||
## 验证命令
|
||||
|
||||
```bash
|
||||
cargo test --locked -p module-assets --manifest-path server-rs/Cargo.toml -- template_library
|
||||
cargo test --locked -p api-server --manifest-path server-rs/Cargo.toml -- agc_template
|
||||
cargo fmt --all --manifest-path server-rs/Cargo.toml -- --check
|
||||
npm run admin-web:typecheck
|
||||
npx vitest run apps/admin-web/src/pages/AdminAgcTemplatesPage.test.tsx apps/admin-web/src/api/adminApiClient.test.ts
|
||||
npm run check:encoding
|
||||
npm run check:doc-index
|
||||
git diff --check
|
||||
```
|
||||
|
||||
接口 smoke:`npm run dev:api-server`(本地 8082)+ `npm run dev:admin-web`,先用未授权/无页签权限请求确认失败关闭,再以隔离存储替身或用户显式确认的 dev bucket 做一次真实导入。
|
||||
|
||||
## 时间盒与风险
|
||||
|
||||
- **风险:真实发布不可逆**。导入会写公共 bucket 且不提供删除,因此默认只在本地用替身验证;对 dev bucket 的写验证必须由用户显式确认,测试用模板需可在事后下架。
|
||||
- **风险:ZIP 原字节发布与 CLI 确定性打包不一致**。同一模板可能被两条路径写成不同字节;由「同 ID 同版本字节必须一致」的门禁兜住,导入失败时提示改用 CLI 或递增版本。
|
||||
- **风险:大文件内存**。ZIP(≤64 MiB)与封面在内存中校验,单批上限 20;需要更大模板时走 CLI。
|
||||
- **风险:批量部分写入**。所有对象在清单提交前写入且不删除;中途失败时清单不变、已写对象成为未被引用的历史对象,由后续同键复用。
|
||||
- **回退**:下线路由与页面入口即可停止使用;已发布内容按既有 CLI / 后台下架流程处理,历史对象保留。
|
||||
@@ -1,10 +1,10 @@
|
||||
# 【实施计划】图集切片模式显式决策
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 字段 | 值 |
|
||||
| --------- | ------------------------------------------------------------------------ |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】图集切片模式显式决策-2026-09-17.md` |
|
||||
| Status | ready |
|
||||
| Owner | Codex |
|
||||
| Status | ready |
|
||||
| Owner | Codex |
|
||||
|
||||
## 修改边界
|
||||
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
# 【实施计划】平台会话身份与凭据分离
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| 字段 | 值 |
|
||||
| --------- | -------------------------------------------------------------------------- |
|
||||
| Milestone | `docs/project-memory/plans/【里程碑】平台会话身份与凭据分离-2026-09-16.md` |
|
||||
| Status | done(待验收复核) |
|
||||
| Owner | Codex |
|
||||
| Status | done(待验收复核) |
|
||||
| Owner | Codex |
|
||||
|
||||
## 修改边界
|
||||
|
||||
|
||||
@@ -106,6 +106,10 @@
|
||||
- 合并 master(`81e0c41f1`,含 `429f991bd` 定向回滚、Godot 原生绑定迁移与策划 Agent 模型控件):回滚提交把混入 master 的游戏分发代码整体删掉,其中 25 个文件在本次合并里属于“双方都改动同一区域之外”的自动删除,直接合并会静默丢功能。处理方式是按“分支补回功能、master 保留迁移”逐类归位:模块注册(`spacetime-module/src/active.rs`)、api-server 路由与权限映射、后台审核页、AGC 发布命令与 payload 类型、`SelectionStage` 的 games 阶段、`ProjectSupervisorView` 的 `overlay` 挂载点、主站路由/标题、Cargo 依赖与锁、vite/vitest 代理与 tailwind source 全部取回分支版本;master 的 Godot C++ 迁移(删除旧 vendored GDExtension、新的 composer 控件样式)保留。合并后用“按文件对比 game-distribution 引用数不得下降”的脚本复核 85 个相关文件,无残留丢失。
|
||||
- 顺带修掉 master 自带的一处红灯:`src/config/viteProxyConfig.test.ts` 断言 `/api/creation-entry` 会被代理,但 master 的 `vite.config.ts` 并无该代理项,且 api-server 已把 `/api/creation-entry/config` 列入 retired 路由测试(dev 中间件按退役路径返回 404)。测试改为断言“退役路径不进入代理”,与 `isRetiredApiPath` 事实一致。
|
||||
|
||||
- 第二次合并 master(`81e0c41f1` → `500835407`,304 个提交:DirectProject 聊天容器重构、Project Supervisor 退役、策划附件导入、CI 隔离编译缓存等):冲突 9 个文件,其中真正需要集成决策的是 AGC 侧——master 把 `ProjectSupervisorView` / `SupervisorChatOnlyView` 整体退役(含我们此前挂 overlay 的挂载点),并且前端不再调用 `export_local_project_package`(`check-config.mjs` 把它登记为 native-only)。处理方式:接受 master 的退役与删除;把发布入口重新接到新架构上——`DirectProjectChatHeader` 新增「发布到游戏广场」按钮(没有回调时不渲染、忙态禁用),`DirectProjectChatView` 透传 `onRequestGamePublish`,`App.tsx` 用工作台壳持有试玩包导出与 `GameDistributionPublishPanel`(沿用 `project.export_package` 权限确认队列),并把该命令从 `check-config.mjs` 的 native-only 清单移回 App invoke。
|
||||
- 同轮修掉 master 自带的红灯断言:`src/config/viteProxyConfig.test.ts` 曾断言 `/api/creation-entry` 会被代理,但配置无该代理项且 api-server 已把 `/api/creation-entry/config` 列为退役路由,测试改为断言退役路径不进入代理。
|
||||
- 覆盖率与门禁(合并后):全量 `npm test` 392 文件 / 4371 用例通过(appSurface 重构后 215 用例)、两端与 admin-web typecheck、`cargo check`(api-server / spacetime-module / spacetime-client)、`cargo test`(api-server 游戏分发 17、module-game-distribution 11)、`check:encoding`、`check:doc-index`、`check:rustfmt`、SpacetimeDB schema guard(对比 `origin/master`)。
|
||||
|
||||
## 尚未完成
|
||||
|
||||
- 真实独立发行域名、通配 TLS 与 CDN 仍属部署侧:边缘模板与门禁已就绪,本地已用真实 nginx 验证按主机映射、Cookie 403 与命名空间隔离,但仍需在真实域名/证书下跑一次“审核通过 → 游玩 → 换版 → 下架”并确认 CDN TTL 不超过 60 秒窗口。
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
| 字段 | 值 |
|
||||
| ----------- | ------------------------------------------------------------------ |
|
||||
| Version | 1.0 |
|
||||
| Status | deferred |
|
||||
| Status | in-progress |
|
||||
| Date | 2026-09-17 |
|
||||
| Parent Spec | `docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md` |
|
||||
|
||||
@@ -30,7 +30,9 @@
|
||||
- macOS 签名证书与公证凭据可用;若不满足,本里程碑只能交付构建与清单能力,并明确标注未验证项。
|
||||
- macOS 通用包所需的双架构工具链(两个 darwin 目标)在构建机上可用。
|
||||
|
||||
本里程碑暂缓执行:macOS 构建机与签名 / 公证凭据尚未就绪,改由后续独立变更承接;暂缓期间 dev-mac 渠道不发布。
|
||||
构建与发布能力已落地:专用 macOS Jenkins 节点(label `genarrative-agc-macos`)+ `Jenkinsfile.ai-game-creator-shell-macos-build` + `scripts/build-macos-ci.mjs` 负责 universal 构建、双架构隔离 smoke、universal DMG、渠道清单 `latest.json`、更新包验签门禁与 OSS 上传(`AGC_RELEASE_DRY_RUN` 默认开启)。
|
||||
|
||||
仍未就绪:Apple 代码签名与公证凭据(产物保持未签名 + 未公证,构建清单显式记录 `appleSigned=false` / `notarized=false`,首装需手动放行 Gatekeeper);「安装 → 重启接管新版本」的实机更新闭环、Intel 真机 smoke(当前 x86_64 侧为 Rosetta)尚未验收。
|
||||
|
||||
## 验收标准
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
|
||||
## 范围
|
||||
|
||||
- 构建期按渠道生成清单:版本按渠道独立递增,清单包含该渠道平台的下载地址与签名;`dev-mac` 的 universal 包按同一地址与签名同时写入 `darwin-aarch64` 与 `darwin-x86_64`。
|
||||
- 构建期按渠道生成清单:版本按渠道独立递增,清单包含该渠道平台的下载地址与签名;macOS 自 2026-09-21 起只出 arm64 单架构,`dev-mac` 只登记 `darwin-aarch64`(原 universal 双键口径已作废:随包 Node 只有单架构官方发行版,需先实现双架构运行时才能恢复 Intel,见 `docs/project-memory/shared-memory/decision-log.md`)。
|
||||
- 构建期生成更新产物签名,并在缺少签名私钥或私钥不可用时失败关闭。
|
||||
- 渠道参数与目标平台绑定校验:Windows 目标只能发布 `dev-win`,macOS 目标只能发布 `dev-mac`;未显式指定时按目标平台取默认渠道。
|
||||
- 上传按渠道落位:安装包与签名进版本目录,清单覆盖写渠道路径的 latest 指针。
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# AGC 模板库客户端接入
|
||||
|
||||
Version: 1.0
|
||||
Status: active
|
||||
Status: accepted(2026-09-21 复核:7 条验收项均有定向、前端与线上真连证据)
|
||||
Date: 2026-09-17
|
||||
Parent Spec: `docs/technical/【技术方案】AGC模板库与模板建项-2026-09-17.md`
|
||||
|
||||
@@ -38,3 +38,17 @@ AGC 客户端能读取公共 OSS 上的游戏模板库,并把「浏览 → 筛
|
||||
- 现有自动工作区建项链路(`create_automatic_local_game_project_at` / `init_local_game_project_at`)。
|
||||
- 现有 AGC 更新通道使用的受信任 OSS 主机与 CSP 白名单口径。
|
||||
- 仓库 OSS 凭据(本机 `.env.secrets.local` 的 `ALIYUN_OSS_*`)与 `scripts/agc-template-library-publish.mjs`。
|
||||
|
||||
## 验收证据(2026-09-21)
|
||||
|
||||
| 验收项 | 证据 |
|
||||
| --- | --- |
|
||||
| 1 读清单 + 合并已安装状态 + 远端不可用回退缓存并标 `source=cache` | `template_library::tests::template_index_*` 5 项(网络优先并标 `network`、远端失败回退缓存并标 `cache`、无缓存暴露远端错误、远端正文非法不用缓存掩盖、缓存损坏失败关闭);`fetches_the_live_template_library_index` 真连通过 |
|
||||
| 2 下载拒绝字节数 / SHA-256 / 越界键 / 非 `templates/` 前缀,且不落半成品 | `rejects_archive_when_size_or_digest_do_not_match_the_index`(含新增断言:拒绝后无安装目录、无已下载判据)、`rejects_object_keys_outside_the_templates_prefix`、`rejects_template_base_url_outside_trusted_oss`;`downloads_and_installs_a_live_template` 真连通过 |
|
||||
| 3 解压拒绝绝对路径 / `..` / 盘符 / 符号链接;安装完成才写 `installed.json` | `rejects_archive_entries_that_escape_the_destination`(含新增断言:失败后不产生安装记录)、`installs_template_archive_and_reports_it_as_installed`、`parses_content_addressed_objects_without_changing_the_template_contract` |
|
||||
| 4 建项具备模板文件 + `.agent` + 标准目录,失败不留项目目录 | `creates_project_from_installed_template_without_leaking_install_marker`、`installs_official_cocos_templates_and_creates_native_projects`、新增 `failed_project_creation_removes_the_partial_project_directory`、`refuses_to_create_project_when_template_is_not_installed`;`downloads_and_creates_live_cocos_templates` 真连通过 |
|
||||
| 5 页面筛选 / 卡片 / 已下载徽标 / 更新入口 / 浮层提示 / 版本落后先重下 | `templateLibraryView.test.tsx` 12 项、`templateLibraryModel.test.ts` 9 项、`templateLibraryGrid.test.ts` 6 项、`useTemplateLibrary.test.tsx` 11 项 |
|
||||
| 6 首页推荐位与左侧导航入口 | `appSurface.test.ts` 首页模板用例 2 项:灰度外隐藏入口与推荐位、点击推荐位进入模板库且不建项目 |
|
||||
| 7 定向用例 + 类型 / 编码 / 文档检查 + 可选真连 | Rust 24 项 + 线上 3 项、前端 38 项 + `appSurface` 2 项、AGC `typecheck`、`check:encoding`、`check:doc-index`、`git diff --check` 全部通过;匿名 `GET templates/index.json` 返回 200(`schemaVersion=agc-template-library.v1`、9 个模板) |
|
||||
|
||||
仍未验证:Creator 内场景运行;真机 iOS / Android 观感。持久结论已并入主规范 [`【技术方案】AGC模板库与模板建项-2026-09-17.md`](../../technical/【技术方案】AGC模板库与模板建项-2026-09-17.md),本里程碑的实施计划已按工作流删除。
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
# 里程碑:AGC 渠道安装身份隔离
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | 代码与源码级验收已落地,等待真机双渠道安装验收 |
|
||||
| Date | 2026-09-21 |
|
||||
| Parent Spec | `docs/technical/【技术方案】AGC客户端更新检查与下载-2026-08-31.md` |
|
||||
|
||||
## 目标
|
||||
|
||||
不同渠道的 AGC 包体在同一台设备上并存:安装、运行、客户端数据与更新互不覆盖、互不顶掉。
|
||||
|
||||
## 范围
|
||||
|
||||
- 构建期按渠道产出安装身份(`productName` / `identifier`),默认渠道 `dev` 身份保持不变。
|
||||
- 渠道产物命名、首装包选择、macOS 发布入口与配置门禁都消费同一份渠道身份。
|
||||
- 同机并存的可见区分(窗口标题)与 AGC 自有 AppData 目录的提权 ACL 识别范围。
|
||||
|
||||
## 不在范围内
|
||||
|
||||
- 不迁移、不共享既有本地项目、工程快照、模板、登录态与诊断数据。
|
||||
- 不新增渠道,不改 OSS 分区布局、官网下载页与后端接口。
|
||||
- 不做 Apple 代码签名/公证,不恢复 Intel 架构。
|
||||
|
||||
## 依赖与前置条件
|
||||
|
||||
- 渠道与更新端点合同已落地(`<channel>-win` / `<channel>-mac` 分区与 Tauri updater 端点)。
|
||||
- 构建入口统一在 Tauri 构建前注入渠道 `--config`。
|
||||
|
||||
## 验收标准
|
||||
|
||||
- [x] 默认渠道的 `productName` / `identifier` 与基线配置逐字一致,既有安装与升级链不断(`check-config.mjs` + 渠道身份用例)。
|
||||
- [x] `release` 与自定义渠道派生独立 `productName` 与 `identifier`,与 `dev` 可在同一台设备并存(源码级;真机安装见下方未完成项)。
|
||||
- [x] 渠道产物(NSIS `.exe`、`.app.tar.gz`、DMG)与首装包选择跟随渠道身份且唯一匹配(发布脚本用例)。
|
||||
- [x] 非默认渠道的客户端数据目录、WebView2 目录与窗口标题跟随渠道身份(构建产物字符串实测 + 运行期标题取产品名)。
|
||||
- [x] AGC 自有 AppData 目录的 ACL managed 范围覆盖全部渠道身份,且不扩大到相似前缀目录(Rust 定向 12/12)。
|
||||
- [ ] 真机:同一台设备同时安装 `dev` 与 `release`,二者可并存、可各自原地更新。
|
||||
|
||||
## 证据要求
|
||||
|
||||
- 自动化:`build-release.test.mjs`、`release-oss.test.mjs`、`prepare-macos-codex.test.mjs`、`check-config.mjs` 与 Rust `config::tests::` 定向测试。
|
||||
- 运行时:单渠道 `--no-bundle` 构建烟测;真机双渠道安装、并存与各自更新。
|
||||
- 边界:非法渠道失败关闭;默认渠道身份不变;相似前缀目录不进入 managed 赋权范围。
|
||||
@@ -0,0 +1,51 @@
|
||||
# 【里程碑】AGC 音频生成进入后台任务账本
|
||||
|
||||
| 字段 | 值 |
|
||||
| --- | --- |
|
||||
| Version | 1.0 |
|
||||
| Status | implemented-awaiting-runtime-acceptance |
|
||||
| Date | 2026-09-20 |
|
||||
| Parent Spec | `docs/prd/【AI游戏创作】项目开发工作台PRD-2026-07-20.md`(§3.10 / §7.9)、`docs/technical/【AGC】栏目画布底部工具栏入口矩阵-2026-09-13.md` |
|
||||
|
||||
## 目标
|
||||
|
||||
AGC 功能画布音频栏目的「生成背景音乐 / 生成音效」与图片类生成走**同一条后台生成任务账本**:提交即返回任务记录、生成在客户端后台跑、状态与阶段文案由账本提供,任务出现在画布「生成任务」侧栏里,重开项目后仍能看到并按中断口径收口。
|
||||
|
||||
## 范围
|
||||
|
||||
- 音频无源生成(`create`)的提交、排队、状态读回、成功落卡、失败收口与重试幂等。
|
||||
- 音频任务与图片类任务共用同一份项目内任务账本、同一个前端本地排队与同一个「生成任务」侧栏。
|
||||
- 音频任务的阶段文案、状态与耗时来源与图片类一致(后端账本拥有阶段文案)。
|
||||
|
||||
## 不在范围内
|
||||
|
||||
- 平台侧(api-server / external v1 / OpenAPI)路由、请求体、计费、队列与 worker 语义:本轮不改,音频仍提交既有 `/api/editor/audios/*/generations` 通道。
|
||||
- 音频波形级编辑、多轨、时长 / 循环等音频参数入口:仍按现状不做。
|
||||
- 视频入口、上传入口、图片类生成的参数与前置判据:行为不变。
|
||||
- 真并行派发(并发收口设计):本轮仍保留「同一时刻只派发一条」的本地排队。
|
||||
|
||||
## 依赖与前置条件
|
||||
|
||||
- 现有图片类后台任务的账本、轮询、落点与聚焦链路可复用;音频生成通道(资源编辑派生)已具备 operation 幂等账本。
|
||||
- 音频提交需要携带请求身份(operation 与幂等键),否则重试会变成一次新的付费生成。
|
||||
|
||||
## 验收标准与证据
|
||||
|
||||
| 验收标准 | 结论 | 证据 |
|
||||
| --- | --- | --- |
|
||||
| 音频栏目的「生成背景音乐 / 生成音效」提交后**立即**返回一条任务记录;面板同步关闭,不等 IPC、不等排队、不等生成结束 | 自动化通过 | `resourceCanvasAssetGenerationBackgroundClose.test.tsx`(点「生成音效」同步提交 + 关闭,面板 DOM 里没有阶段文案与「后台运行并关闭」)、`resourceCanvasGenerationEntry.test.tsx`、`resourceCanvasGenerationHostLifecycle.test.tsx`(音频载荷逐字为 `projectPath / projectId / taskId / kind / prompt / assetName / idempotencyKey`) |
|
||||
| 提交受理后任务出现在「生成任务」侧栏,状态与阶段文案来自后端账本,前端不拼阶段、不做百分比 | 自动化通过 | `resourceCanvasAssetGenerationQueue.test.ts`(音频收口复用同一份账本记录)、`resourceCanvasAssetGenerationTasksPanel.test.tsx`、`resourceCanvasGenerationHostLifecycle.test.tsx`(提交后自动展开侧栏) |
|
||||
| 音频任务与图片类任务在同一条本地队列里按「同一时刻只派发一条」排队;第二条在本地排队期间不发提交 IPC | 自动化通过 | `resourceCanvasAssetGenerationQueue.test.ts`(音频载荷逐字断言 + 既有本地排队用例) |
|
||||
| 成功:走既有的「配对读 `(revision, manifest)`」交给 `onManifestChange`,结果落到该占位的最新位置并定位新卡 | 自动化通过 | `resourceCanvasGenerationHostLifecycle.test.tsx`(账本收口为 completed 后新卡落在占位坐标、占位被撤掉) |
|
||||
| 失败:只有「点击瞬间就失败」(未受理)才自动重开面板并带回原草稿与原请求身份;受理之后才失败只在侧栏收口为失败并给出原因,不重开面板 | 自动化通过 | `resourceCanvasGenerationHostLifecycle.test.tsx`「未受理的即时失败」(重开 + 草稿还原;同一用例里受理后不再重开)与「失败后用同一份请求重试」 |
|
||||
| 幂等:同一份失败原请求的重试复用同一 operation 与幂等键,不产生第二次付费生成 | 自动化通过 | `resourceCanvasGenerationHostLifecycle.test.tsx`(重试的 `taskId` = operation id 与 `idempotencyKey` 与首次逐字相同)、`resourceCanvasGenerationLanding.test.tsx` |
|
||||
| 重开项目:音频任务从账本恢复显示;上次运行中断的任务按中断口径收口,不假装还在跑 | 自动化通过(恢复路径) | 音频 kind 的入口文案由工具栏模型派生(`resourceCanvasAssetGenerationTaskModel` + `resourceCanvasAssetGenerationQueue.test.ts`);中断收口沿用既有账本口径 |
|
||||
| 音频提交失败(校验 / 权限 / 通道拒绝)时 manifest、revision 与任务账本都不出现半途写入 | 自动化通过 | Rust `asset_generation_tasks` 的 `audio_submission_rejects_invalid_identity_and_prompt_without_touching_the_ledger`(提交期拒绝零写入)、`audio_submission_lands_in_the_shared_ledger_with_its_audio_kind` |
|
||||
|
||||
运行时验收(未做):没有跑真实付费音频生成,也没有在真实客户端里做手感验收;全链以模拟原生接口的宿主用例覆盖。
|
||||
|
||||
## 证据要求
|
||||
|
||||
- 自动化:AGC 前端定向 vitest(音频入口宿主生命周期、生成任务队列与侧栏、appSurface 载荷)+ Rust 定向 `cargo test`(账本与音频任务入参收口)+ 类型检查 + 编码 / 文档索引 / `git diff --check`。
|
||||
- 运行时:无真实付费生成;以模拟原生接口的宿主用例覆盖提交 → 排队 → 收口 → 落卡全链。
|
||||
- 边界:未受理失败的即时重开与身份复用、账本读不到 / 记录缺失的收口、跨项目切换不串任务。
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user