Merge branch 'feat/agc-v3-c7-version-switch' into feat/agc-canvas-resource-workbench-v3

This commit is contained in:
2026-09-10 17:40:46 +08:00
@@ -1310,3 +1310,14 @@ DirectProject 使用 `approvalPolicy=never`,避免每次原生调用再经过
- **素材重命名**:新增 `rename_local_project_asset``project/asset_rename.rs`)。语义是**磁盘文件改名 + manifest `localPath` 更新、资产 `id` 不变**manifest 没有 `name` 字段,显示名来自 `fileName(localPath)`)。校验覆盖新名非空、不含路径分隔符与 `..`、不跨目录、扩展名必须一致、目标不得已存在、原文件必须是真实普通文件;持项目写锁按“读 manifest → 磁盘改名 → 更新 `localPath` → 写 manifest → 推进 revision”执行,**写失败把文件改回原名**,回滚也失败时两个错误都报出并标记 `reconciliation-required`;同名重命名是空操作。已知边界:**不改游戏源码里对旧 `assets/<name>` 的引用**,不做引用扫描与自动替换。
- **聊天引用与润色**`ResourceReferenceInput` 新增 `activeVersionId?: string | null``versions?: GameIterationVersion[]` 两个可选 prop`@` 面板两个页签(当前版本素材 / 全部画布素材)各自持有独立 `{query, filter, selectedResourceIds}`。版本解析口径 `resolveActiveIterationVersion` / `currentIterationVersionAssets`:传 `null` 回退 manifest 最新的版本,悬空绑定自然丢弃,空版本或空绑定显示空态而不报错。新增 `polish_local_project_prompt(prompt, context)`(提示词 `src-tauri/prompts/local-project-prompt-polish.md`),复用与 `suggest_automatic_project_name` 同一条短文本通道:`codex_app_server` 模式走 home direct codex,其余走 `LlmClient` 单轮请求;入参有界(4 000 / 1 000 字符)、输出 2 048 token 有界、空回复一律判失败以保留原文。**计费不自建**:泥点扣费仍在 `server-rs``/api/llm/chat/completions``/api/llm/responses` 路由(`prepare_llm_router_billing` / `settle_llm_router_usage`),本次 server-rs 零改动。发送前提醒是 portal 独立弹窗,判据为“提醒未关闭 + 本轮未确认 + 纯文本 trim 后 ≥ 40 字符 + 不以 `/` 开头”,“不再提醒”偏好存本机 `localStorage`,不进 manifest 与后端。
- **验证**AGC 前端全量 1075 passed / 4 skipped / 0 failed;共享美术画布组件 1372 passed`cargo check --all-targets` 通过;定向 Rust 用例 `asset_delete` 7、`manifest::` 30、`assets::tests` 22、`asset_rename` 9、`local_project_prompt_polish` 4、`bridge_registered_resource` / `bridge_art_resource` 3 全绿;`npm run check:encoding``git diff --check` 干净。
## 2026-09-11 AGC 资源工作台 V3:版本切换、参考图弹窗、标签库与素材重命名 UI
- **标签库是派生数据**:新增 `packages/shared/src/contracts/gameCreationAppAssetTagLibrary.ts`,从 manifest `assets[].tags` 派生去重、含使用计数的标签库,排序口径为「使用次数降序 → 标签 `zh-CN` 升序」,素材 id 也按升序落库,保证任意 manifest 写入顺序下结果可复现;标签归一化沿用写入路径的 `normalizeGameCreationAppAssetTags`。**不新增任何持久化字段**。标签筛选判据 `assetTagsMatchSelection` 为 AND 语义、空选择不过滤,与 `category` 筛选由调用方叠加。
- **筛选组件抽到共享层**:新增 `packages/shared/src/components/PlatformResourceFilterBar.tsx`,把资源画布的分类筛选搬成受控组件(分类选项泛型化,搜索行与标签行可选)。筛选条件与筛后结果一律由宿主持有,因此资源画布、`@` 面板、参考图弹窗各自持有互不影响的筛选状态。画布侧的标签筛选是画布级收窄条件,不按「按依赖 / 按类型」再分一份。
- **运行模块版本切换(C7**:版本状态只有一份,放在 `WorkspaceLauncherShell`,透传给 `ProjectDevelopmentView`(资源卡「当前使用」高亮)与 supervisor(`@` 面板「当前版本素材」)。运行模块右上角新增 `GameRunVersionPicker`:数据只来自 manifest `versions[]`,**没有版本时不渲染入口**,不伪造版本;展示口径为「中文创建原因 · 创建时间」(`initial` 初始版本 / `resource-replacement` 资源替换 / `agent-revision` 智能体修订)。`currentVersionResourceBindingIds` 增加 `activeVersionId` 参数并复用 `resolveActiveIterationVersion`,不复制第二套版本解析口径。换项目、或选中的版本已不在 manifest 时把选择清回「最新版本」。
- **版本切换不引入运行时资源重映射**:素材不可变(编辑产出新素材而不是改文件),版本之间没变的资源本就是同一份文件,因此切换只做「记录层 + UI 层」并复用既有 `onPlay` 预览入口重载画面;**不做代码注入、不做 Phaser wrapper、不改资源文件、不创建新版本**。
- **参考图弹窗(C9**:新增 `src/components/image-editor/ImageCanvasProjectAssetPickerDialog.tsx`,网格卡片 + 多选 + 筛选/搜索 + 清空/确认/取消,筛选状态由弹窗自持;生成 composer 的参考图来源菜单新增「从项目素材中选择」(不传回调则不出现,原「从画布中选择」「上传图片」两条路径不变)。确认时 `replaceProjectAssetPickerReferences` **整组替换**素材库来源的参考图(引用 id 前缀 `project-asset-`),画布点选与上传来的参考图保持不动。素材 id 经 `sourceAssetId` 走既有 `createGenerationInputReference` 落进 `generationInputs.references``refType: 'asset'`),即本次任务的参考图 ID 快照,源素材后续变化不影响已提交任务;**不新增后端表 / 接口,不改 `/api/external/v1`,不改 SpacetimeDB schema**
- **素材重命名 UI**:新增 `ResourceRenameDialog`,入口在资源卡选中工具条的 `extraActions`(与「分类与标签」并列),只输入新文件名。前端严格按 `deny_unknown_fields` 只传 `{ projectPath, assetId, newFileName }`;成功后复用 `reloadManifestAfterAssetCommand` 这条既有 manifest 重载路径刷新资源卡与 `@` 面板显示名。资料性边界沿用 Rust 侧口径:不改游戏源码里对旧 `assets/<name>` 的引用。
- **过渡 allowlist 收敛**`check-config.mjs``allowedUncalledTauriCommands` 删除 `normalize_local_project_raster_resource`——该命令在 C3 之后的选中工具条里已有真实前端调用方,不再是「无人调用」的过渡项。
- **验证**AGC 前端全量 1080 passed / 4 skipped / 5 failed5 条失败全部是 C3 交互改造后仍待更新的既有用例,与本包改动无关:`renders immutable manifest versions…``keeps the resource toolbar and canvas interactive…``loads registered documents, art media, video, and audio…``moves historical resource positions…`,以及 `projectResourceLiveIntegration` 的一条选中按钮选择器);本包新增的 25 条测试(标签库 5、筛选条 3、参考图弹窗 6、参考图模型 7、重命名 2、版本判定 5、版本切换 3,其中 5 条落在共享契约与共享组件目录)全部通过;共享美术画布组件 1385 passed`cargo check --all-targets` 通过;`asset_rename` 9 passed`npm run check:encoding``git diff --check` 干净。