diff --git a/docs/project-memory/plans/【实施计划】AGC资源kindRust枚举与ts-rs绑定-2026-09-15.md b/docs/project-memory/plans/【实施计划】AGC资源kindRust枚举与ts-rs绑定-2026-09-15.md index 36ac9c444..d1ac588d7 100644 --- a/docs/project-memory/plans/【实施计划】AGC资源kindRust枚举与ts-rs绑定-2026-09-15.md +++ b/docs/project-memory/plans/【实施计划】AGC资源kindRust枚举与ts-rs绑定-2026-09-15.md @@ -18,33 +18,39 @@ 本切片已落地: -- `GameCreationAppAssetManifestEntry.kind` 改为 `GameCreationAppAssetKind`;manifest 反序列化未知值收口为 `Unknown`。 +- `GameCreationAppAssetManifestEntry.kind` 由 `String` 收紧为 `GameCreationAppAssetKind`:这是公开 Rust 类型的破坏性变更,按「不写历史兼容代码」直接改类型,不加兼容层、不做数据迁移;manifest 反序列化未知值收口为 `Unknown`。 - 上传内容推断的字体写入 `Font`,未知上传类型写入 `Unknown`;图集切片 manifest 写入 `Icon`。 -- shell TS 资源引用边界开始消费生成绑定,并为未知值保留原始值与上下文日志。 +- shell 内 manifest kind 的写入侧与读取侧统一为正式枚举成员:资源登记、字体导入、direct runtime 产物、平台美术登记与恢复、manifest 必填校验、资源编辑派生、UI 设计桥接与工作流。 +- 资源编辑请求的 `sourceSubtype` 只传正式枚举成员;资源编辑内部源身份拆成「正式 kind / 项目版本 / Agent 回执」三类,项目版本与 Agent 回执不再冒充 manifest kind。 +- ts-rs 绑定改由 `cargo test export_bindings` 生成:枚举自带 `#[ts(export, export_to = …/src/contracts/generated/)]`;退役的 `BindingDTO` / `BindingChange` 不再导出,手写的 `exports_ui_editor_types` 已删除。 +- `src/contracts/generated/` 加入 `.prettierignore` 与 eslint `ignorePatterns`,生成文件保持 ts-rs 原始格式,`cargo test export_bindings` 可幂等复现且不再污染工作树。 +- shell TS 资源引用边界消费生成绑定,资源 kind 集合从生成的 union 穷举派生,并为未知值保留原始值与上下文日志。 明确不修改: -- manifest 结构体的 `kind: String` 字段及所有调用方(留给下一个小提交); - `category`、`mediaType`、`source.kind`、`source.generationKind`; - api-server、SpacetimeDB schema、OpenAPI; -- alias/fallback 删除和 Unknown writer 处理(留给后续切片)。 +- shared-contracts 的 canonical alias 表与读时自愈:本次不新增、不扩展,留给独立词汇收敛切片; +- `packages/shared` 中重复的资源 kind 手写契约与其余前端裸 `string` 字段(后续切片)。 ## 实现顺序 1. 新建独立 kind 模块,定义当前正式成员:17 个现有 canonical kind + `font` + `Unknown`,serde 使用 kebab-case。 2. 为 enum 增加可选 ts-rs derive,默认 shared-contracts 构建不引入 ts-rs。 3. 让 shell 的 shared-contracts 依赖打开绑定 feature,在 shell 专属 contracts/generated 目录生成 TS。 -4. 增加 Rust serde round-trip 与 Unknown 解析/序列化测试;增加 TS 生成文件存在和值集合测试。 - 未知值通过 `parse_with_context` 收口到 `Unknown`,并在启用 shell 的 `kind-observability` feature 时记录原始值与解析上下文。 -5. 运行 shared-contracts 与 shell 定向测试;通过后暂停,等待下一个内部字段收紧切片。 +4. 增加 Rust serde round-trip 与 Unknown 解析/序列化测试;TS 侧不再手写生成值集合,改为从生成 union 穷举派生。 + 未知值通过 `parse_with_context` 收口到 `Unknown`,并在启用 shell 的 `kind-observability` feature 时记录原始值与解析上下文。 +5. 运行 shared-contracts 与 shell 定向测试,并用 `export_bindings` 复现生成文件;通过后暂停,等待下一个内部字段收紧切片。 ## 验证命令 1. `cargo fmt --all -- --check` 2. `cargo test --locked -p shared-contracts game_creation_app --manifest-path server-rs/Cargo.toml` -3. `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml exports_game_creation_app_asset_kind` -4. `npm run check:encoding` -5. `git diff --check` +3. `cargo test --locked -p shared-contracts --features ts-bindings export_bindings --manifest-path server-rs/Cargo.toml`(生成 `apps/ai-game-creator-shell/src/contracts/generated/GameCreationAppAssetKind.ts`) +4. `cargo test --locked --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml export_bindings`(生成 shell 自己的 ts-rs 绑定) +5. `npx vitest run apps/ai-game-creator-shell/tests/assetKind.test.ts apps/ai-game-creator-shell/tests/assetKindCanonicalMapping.test.ts` +6. `npm run check:encoding` +7. `git diff --check` ## 风险与回滚点 diff --git a/docs/project-memory/plans/【里程碑】AGC资源kind枚举化Rust绑定与内部收紧-2026-09-15.md b/docs/project-memory/plans/【里程碑】AGC资源kind枚举化Rust绑定与内部收紧-2026-09-15.md index 27aefd851..96742f4e1 100644 --- a/docs/project-memory/plans/【里程碑】AGC资源kind枚举化Rust绑定与内部收紧-2026-09-15.md +++ b/docs/project-memory/plans/【里程碑】AGC资源kind枚举化Rust绑定与内部收紧-2026-09-15.md @@ -31,8 +31,10 @@ ## 验收标准 -- [ ] Rust enum 与生成的 TS 绑定值逐项一致,JSON 使用 kebab-case;正式资源成员为当前 17 个 canonical kind 加 `font`,另有 `Unknown` 解析成员。 -- [ ] 未知输入得到 `Unknown`,日志包含原始值与调用上下文。 -- [ ] 生产 writer 不再接受裸 `string` 作为 GameCreationApp kind。 -- [ ] `font`、`audio`、`sound-effect`、`background-music` 均有真实生产路径或明确的测试证据。 -- [ ] 旧 alias 不再由共享契约转换为 canonical。 +- [x] Rust enum 与生成的 TS 绑定值逐项一致,JSON 使用 kebab-case;正式资源成员为当前 17 个 canonical kind 加 `font`,另有 `Unknown` 解析成员。TS 侧不再手写值集合,改为对生成 union 做穷举 `Record`。 +- [x] 未知输入得到 `Unknown`,日志包含原始值与调用上下文(`parse_with_context` + `kind-observability`)。 +- [x] 生产 writer 不再接受裸 `string` 作为 GameCreationApp kind(manifest 写入、资源登记、direct runtime、平台美术登记、资源编辑派生均只传枚举成员)。 +- [x] `font`、`audio`、`sound-effect`、`background-music` 均有真实生产路径(字体导入、上传音频推断、资源编辑音频派生)。 +- [x] ts-rs 绑定由 `cargo test export_bindings` 生成,生成目录加入 `.prettierignore` / eslint `ignorePatterns`,可幂等复现且不污染工作树。 +- [x] 退役的 `BindingDTO` / `BindingChange` 不再导出,手写的 `exports_ui_editor_types` 已删除。 +- [ ] 旧 alias 不再由共享契约把非 canonical 输入收口成 canonical(该表属读边界,本次未新增也未扩展,留给独立词汇收敛切片)。 diff --git a/docs/project-memory/todos/【待办】AGC资源kind枚举化扫描清单-2026-09-15.md b/docs/project-memory/todos/【待办】AGC资源kind枚举化扫描清单-2026-09-15.md index e7d293a98..276cd9b3b 100644 --- a/docs/project-memory/todos/【待办】AGC资源kind枚举化扫描清单-2026-09-15.md +++ b/docs/project-memory/todos/【待办】AGC资源kind枚举化扫描清单-2026-09-15.md @@ -78,12 +78,13 @@ ## 当前未决项 -- [ ] 逐处确认 `asset` 是错误 fallback 还是其他领域标识。 -- [ ] 逐处确认 `art-spritesheet` / `art-spritesheet-slice` 是 manifest kind 还是图集 workflow 标识。 -- [ ] 逐处确认 `game-background` / `game-art` / `illustration` / `character-art` 的写入边界。 -- [ ] 逐处确认 `ui` / `ui-prototype` 是否仍有生产 manifest writer。 -- [ ] 确认 `Unknown` 的 tracing 字段和 writer 禁止规则。 -- [ ] 确认 ts-rs 生成文件的实际路径、生成命令和 CI verify 实现。 +- [x] `asset`:确认是上传推断的兜底值,已改为无法判断时写 `Unknown`,不再回落到 `asset`。 +- [x] `art-spritesheet` / `art-spritesheet-slice`:确认是平台请求与图集 workflow 词汇;manifest 写入分别收口为 `IconSpritesheet` / `Icon`,协议标识只留在各自字符串字段。 +- [x] `game-background` / `game-art` / `illustration` / `character-art`:确认只出现在平台请求词汇;写入 manifest 前经显式转换函数收口为 `scene` / `image` / `character`。 +- [x] `ui` / `ui-prototype`:确认 UI 设计桥接与工作流已无生产 manifest writer,只写 `ui-design` / `ui-design-doc`。 +- [x] `Unknown` 的 tracing 字段为 `raw_kind` + `source_context`,由 `kind-observability` feature 控制;生产 writer 只传正式枚举成员。 +- [x] ts-rs 生成路径为 `apps/ai-game-creator-shell/src/contracts/generated/`,命令为 `cargo test -p shared-contracts --features ts-bindings export_bindings`(枚举自带 `export_to`),生成目录已在 `.prettierignore` / eslint `ignorePatterns` 中保持原始格式。 +- [ ] 接入 CI verify(在 CI 中跑一次 `export_bindings` 并断言生成文件无 diff)。 ## 已确认的 manifest kind 入口(M0 审计结果)