0d0bba2ec2
- 资源卡选中工具条放行「替换素材」按钮:判据复用现役的 isResourceUsedByCurrentVersion(manifest 身份 + 被当前版本绑定),未绑定的素材一律不渲染,避免"点了没反应"的假按钮;本仓工具条 opt-in 硬约定要求真链路先通,因此入口放在最后一批提交 - 按钮落在宿主 extraActions,与「UI 编辑器 / 编辑标签 / 重命名」同处,不动 ImageCanvasSelectedLayerToolbarAction 共享 union、不改 resourceCanvasToolbarModel 的 supportedActions - selectActiveVersion 改为 useCallback 固定身份:替换成功后要走同一条记录层版本切换通道,普通函数声明会让 useCallback 依赖数组每次渲染都变(eslint react-hooks/exhaustive-deps 报错);替换相关的处理函数随之挪到它之后声明,依赖数组求值顺序才对 - 新增 tests/resourceVersionReplacement.test.tsx(真链路 4 条):入口只在被当前版本绑定时渲染、候选弹窗禁用不兼容项并显示原因且不合成非候选素材、写入 IPC 载荷逐字精确、成功后切版本但不重载预览(onPlay 不被调用)、后端拒绝时保留弹窗显示原因且不切版本不重读 manifest、候选读取失败时不弹空壳弹窗 - 新增 tests/resourceVersionReplacementModel.test.ts(8 条):禁用原因口径(后端原因优先、按 PRD §5.3 字段顺序派生、兜底不静默放行)、候选→弹窗素材映射(复用资源投影口径、不给 img 喂空 src、缺投影不合成条目)、失败文案逐条映射与未知错误原样透出、两个命令的 IPC 载荷形状 - 用例独立成文件,不往 tests/appSurface/project-development.suite.ts 里插,避免与工具条那条线互相踩 - 变异验证:放宽入口判据为"只要有 manifest 身份"→「不给假按钮」用例转红;失败路径改成静默关弹窗→「保留弹窗显示原因」用例转红;均已还原