新增本地项目素材重命名命令(Rust 侧)
- 新增 Tauri 命令 rename_local_project_asset(输入 projectPath / assetId / newFileName),并在 main.rs 的 generate_handler! 中注册 - 新增 project/asset_rename.rs:重命名语义为“磁盘文件改名 + manifest localPath 更新”,资产 id / kind / mediaType / source / category / tags 全部不变,imageSequenceFrames 里指向该文件的本地帧一并对齐 - 校验判据:新名非空、不含路径分隔符(同时保证不跨目录)、不含 ..、通过可移植路径组件校验、扩展名与原文件一致、同目录不得已存在同名文件、assetId 与磁盘文件必须存在 - 事务与回滚:持既有项目写锁,manifest 写入走既有 write_manifest 边界(版本数组校验 + 安装后回读一致性);写失败把文件改回原名,回滚也失败时两个错误都报出并标记 reconciliation-required;同名重命名按空操作处理 - 新增 tests/asset_rename.rs 9 条用例:成功改名与身份不变、同名空操作、空名 / 分隔符 / .. / 跨目录 / 扩展名不一致 / 目标同名冲突 / 资产与文件缺失拒绝、manifest 写失败回滚、同目录帧对齐 - decision-log 记录素材重命名语义、命令边界,以及“前端调用方落地前 ai-game-creator-shell:typecheck 必然失败”的已知中间状态
This commit is contained in:
@@ -8224,3 +8224,13 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
|
||||
- 边界:`agent-runner.lock` / `agent-runner.gui-owner.lock` 是 OS 独占句柄锁,进程退出即释放,残留文件不阻塞下次启动;不要把它们当成项目写锁的同类残留处理。
|
||||
- 边界:锁文件里的 PID 若超出平台进程号空间(Unix `pid_t` 是有符号 32 位、Windows 是 32 位,均恒大于 0),它不可能属于任何活进程,按“持有者不存在”直接回收,不再落回 600 秒保守分支。
|
||||
- 验证:`project_lock_recovery` 11 条与 `diagnostic_log` 7 条定向测试通过,真实二进制双实例复现“第二个实例写 `startup.runner.owner-lock.failed` 并弹出可见提示”。
|
||||
|
||||
## 2026-09-10 AGC 素材重命名命令(文件改名 + localPath 更新,id 不变)
|
||||
|
||||
- 语义:manifest 资产条目没有 `name` 字段,资源显示名来自 `fileName(localPath)`(`view/project-development/resourceProjectionModel.ts` 的 `label`),所以“重命名”只能是**磁盘文件改名 + manifest `localPath` 更新**,资产 `id` 不变;不新增 manifest / 契约字段。
|
||||
- 命令与实现:Tauri 命令 `rename_local_project_asset`(`commands.rs` 包装层只做 `asset.register` 权限校验),实现落在 `project/asset_rename.rs::rename_local_project_asset_at`;入参 `projectPath` / `assetId` / `newFileName`(只收新文件名,目录由 manifest 现有 `localPath` 决定,调用方无法指定目标目录)。
|
||||
- 校验判据:新名非空;不含 `/` 与 `\`(同时保证不跨目录);不含 `..`;通过 `validate_portable_project_path_component`(控制字符、Windows 保留字符、结尾点或空格、保留设备名);扩展名与原文件一致(大小写不敏感比较,无扩展名必须仍无扩展名);同目录不得已存在同名文件(先检查再 `rename`,不覆盖既有文件,只差大小写的改名按同名冲突拒绝);assetId 必须存在且登记的文件必须是磁盘上的真实普通文件。
|
||||
- 事务与回滚:持既有项目写锁(`asset.register`)后按“读 manifest → 磁盘改名 → 更新 `localPath` → 写 manifest → 推进项目 revision”顺序执行,manifest 写入仍走既有 `write_manifest` 边界(版本数组不可变校验 + 安装后回读一致性校验);写失败把文件改回原名,磁盘 / manifest / revision 三处都不留半成品,回滚也失败时两个错误都报出并标记 `reconciliation-required`。同名重命名是空操作(不动磁盘、不动 manifest、不推进 revision)。
|
||||
- 帧对齐:`imageSequenceFrames` 里**真正指向被改名文件**的本地帧对齐到新路径;判据是 `imageSrc` 为本地相对路径(非绝对路径、非带 scheme 的地址、非反斜杠路径),目录与旧文件目录一致且文件名与旧名一致(大小写不敏感)。同目录但指向别的文件的帧保持原样,避免改名连带改坏其它引用;`kind` / `mediaType` / `source` / `category` / `tags` 全部不变。
|
||||
- 已知中间状态:本切片只落 Rust 侧,前端调用方与 UI 在其他工作包;在 UI 落地前 `npm run ai-game-creator-shell:typecheck` 会因 `check-config.mjs` 要求“每个 Tauri 命令都有 App invoke 调用方”而失败,这是刻意保留的中间状态,**不要**把该命令加进 native-only 白名单来换绿。
|
||||
- 验证:`cargo test --bin genarrative-ai-game-creator-shell asset_rename` 9/9 通过(成功改名与 id 不变、同名空操作、空名 / 分隔符 / `..` 拒绝、跨目录拒绝、扩展名不一致拒绝、目标同名冲突拒绝、assetId 与文件缺失拒绝、manifest 写失败回滚、同目录帧对齐);`cargo check --all-targets` 通过;AGC 前端 69 个测试文件 / 1049 用例全绿。
|
||||
|
||||
Reference in New Issue
Block a user