suzmii
daef9f6cc9
修复素材删除幂等、重命名 CAS 与 manifest 预览缓存一致性
...
修复素材删除幂等、重命名 CAS 与 manifest 预览缓存一致性(PR #316 review)
- assets.rs:2048-2049 [bug · medium] 已被修复:删除登记在「身份 + revision 两项 CAS 都已通过」后遇到素材已不在 manifest 时按 no-op 成功收敛并照常推进 revision,不再报「项目资源不存在」;新增 `asset_delete_retry_converges_when_only_the_revision_advance_failed` 复现「manifest 已提交、revision 未推进」并验证重试收敛(原「不存在的素材必须报错」断言相应改为幂等语义,前端只消费 assetId/committedProjectRevision)。
- assets.rs:2035-2042 [performance · low] 已被修复:引用集合只算一次并用 `HashSet<String>` 做成员判定,`retain` 不再是 O(V²);版本守卫闭包按约定在写入前另行求值、拿不到该可变借用,故两次扫描保留并已在注释里说明。
- commands.rs:1032 [maintainability · medium] 已被修复:`RenameLocalProjectAssetInput` 补 `expectedProjectId` / `expectedProjectRevision`,`rename_local_project_asset_at` 与删除/分类更新同口径做两段身份复核 + revision CAS,失败时磁盘、manifest、revision 全不动;新增 CAS 用例(陈旧 revision / 跨项目身份 / 空身份)。注意:前端 `confirmResourceRename` 必须同时补传这两个字段(TS 侧由前端 owner 落地)。
- asset_rename.rs:84 [bug · low] 已被修复:新增 `asset_frame_directory_matches`,目录段在 Windows/macOS 按大小写不敏感比较(Linux 保持敏感),与文件名比较同口径;新增 `Assets/hero.png` 帧对齐用例。
- asset_rename.rs:249-250 [bug · medium] 已被修复:revision 推进失败改为报 `reconciliation-required: 素材已改名…且 manifest 已落盘,但项目 revision 未能推进`,明确这是「已提交但对账未完成」而非普通失败;同时新增的 CAS 使后续命令必须按新 revision 重试,重试会命中同名 no-op 分支收敛。
- tests/asset_rename.rs:257-263 [maintainability · medium] 已被修复:删除 `RenameLocalProjectAssetFaultStage` 枚举与生产签名上的 `fault` 参数,故障注入改用 `#[cfg(test)]` 的 `.agent/runtime/test-fail-next-asset-rename-manifest-write` 标记文件(与 agent_db 既有约定一致),生产 API 面不再能被推上「只回滚、不写 manifest」的路径。
- manifest.rs:1386 [bug · medium] 已被修复:预览缓存失效点下沉到唯一的装盘公共体 `write_manifest_locked_with_version_guard`(install 成功后立即失效,含安装后回读不一致的失败路径),`mutate_manifest_at_allowing_version_removals` 与绑定改写通道一并覆盖;`write_manifest_with_lock_hook` 里的重复调用已移除。
- manifest.rs:1480-1482 [bug · medium] 已被修复:填充侧改为「先取身份快照 → 读取 → 复核快照一致才入缓存」,不再可能出现「旧内容 + 新文件身份」的缓存条目。
- manifest.rs:1135 [security · low] 已被修复:新增 `normalize_manifest_asset_tags`,在共享归一化之后按数量(16)与单标签长度(32 字符)失败关闭;超长标签不截断,避免与共享标签库静默分叉。
- manifest.rs:1180-1181 [bug · medium] 已被修复:审计改为幂等——前后分类与标签完全相同时不追加记录,重试不会再写出 `previousCategory == category` 的假变更审计(保留「manifest 落盘后、推进 revision 前追加」这一既有位置约定)。
- manifest.rs:1140 [maintainability · low] 已被修复:分类写入的项目写锁标签由 `asset.register` 改为 `asset.classification.update`,争用诊断不再误报成素材登记。
- 测试:新增 preview_cache_tests(命中/TOCTOU 不入缓存/身份漂移丢弃/主写入通道显式失效)、分类重复写入不留假审计、标签上下界拒绝;7 条变异验证全部 CAUGHT。
2026-09-12 20:20:12 +08:00
suzmii
3a9e45c805
修复素材导出缺少敏感文件拒绝与自我覆盖保护
...
修复素材导出缺少敏感文件拒绝与自我覆盖保护(PR #316 review)
- asset_export.rs:27-30 [security · high] 已被修复:`resolve_export_source_file` 现在与通用读取路径同一口径,normalize 后先 `reject_agent_runtime_private_control_path` 再 `reject_sensitive_project_file_read`,`.env` / 本地凭据配置与 `.agent/runtime|checkpoints|workbench` 控制面都不能被复制到项目外。
- asset_export.rs:31-33 [security · medium] 已被修复:源路径改用 `resolve_local_project_path` 逐段复核符号链接与 Windows reparse point,`assets` 本身是链接/junction 时不再把项目外文件当成素材导出。
- asset_export.rs:76-78 [bug · high] 已被修复:新增 `reject_export_destination_matching_source`,在创建写句柄之前按「路径等价(大小写不敏感平台忽略大小写)」+「文件身份(含硬链接,退化身份不参与判定)」拒绝保存目标与源素材同一份文件;否则 `File::create` 先截断源文件、复制读到 0 字节还会报成功。
- asset_export.rs:93-95 [other · low] 已被修复:复制改为同目录临时文件 + `sync_all` + `rename` 原子替换,失败时清理临时文件;不再先截断既有目标、也不再留下半截文件。
- 文档:命令 docstring 不再声称「只导出 manifest 已登记素材」——DirectProject 导入的附件同样要能另存,而它们不是 manifest 资产,所以这里明确写成与通用读取同一套路径门禁。
- 测试:新增 5 条用例覆盖敏感/控制面源拒绝、中间目录符号链接逃逸、目标即源文件、硬链接目标、原子替换不留临时文件;7 条变异验证全部 CAUGHT。
2026-09-12 20:19:57 +08:00
suzmii
1cc258d2a4
合并资源工作台分支:PR review 共享契约与样式批次并入滚轮修复
...
Project CI / Repository checks (pull_request) Successful in 2m38s
Project CI / Frontend tests (pull_request) Successful in 3m12s
Project CI / Backend tests (pull_request) Successful in 5m33s
Project CI / Native shell tests (pull_request) Successful in 16m46s
- 把远端最新 fc6743980(浮层滚轮归属修复)合入本分支(PR #316 review 的 shared/server-rs/CSS/scripts 三笔:9835bbec9、8b8597782、3b385ef57)
- 冲突零:自动合并成功
- 验证:npm run typecheck exit 0;shared 契约/标签/筛选条与 lint-staged 用例全绿
2026-09-12 19:54:16 +08:00
k88936
a19684a5f5
Merge remote-tracking branch 'origin/master' into feat/ui-editor-auto-seperation
Project CI / Repository checks (pull_request) Failing after 1m7s
Project CI / Frontend tests (pull_request) Successful in 3m10s
Project CI / Backend tests (pull_request) Successful in 6m0s
Project CI / Native shell tests (pull_request) Successful in 18m41s
2026-09-12 19:46:41 +08:00
suzmii
3b385ef575
修复 PR316 review:pre-commit Rust 格式检查按暂存文件筛 workspace
...
- scripts/lint-staged-rustfmt.mjs:12 [maintainability medium] 改为读取 lint-staged 追加的暂存 .rs 路径,只对真正命中暂存文件的 workspace 跑 cargo fmt --all -- --check:此前永远全量跑两个 workspace,只暂存 server-rs 干净文件的提交会被别人未暂存的 src-tauri 改动挡下来;没收到暂存列表(手工执行)时回退全量检查并在 stderr 说明,避免假装检查过。
- scripts/lint-staged-rustfmt.mjs:7 [maintainability low] apps/desktop-shell/src-tauri 显式记为「有意排除」而不是静默通过:实测该 workspace 当前整体不过 cargo fmt --check(host_bridge/mod.rs 等),直接纳入会让任何 Rust 提交都失败;命中该前缀的暂存文件会打印跳过提示,纳入步骤写在模块注释里(同时要补 package.json 的 check:rustfmt / format:rust,package.json 不在本批次改动范围)。
- 新增 scripts/lint-staged-rustfmt-workspaces.mjs:把「暂存路径 → 待检查 workspace」的纯映射逻辑独立出来,附 Windows 反斜杠/绝对路径归一化。
- 新增 scripts/lint-staged-rustfmt.test.ts(vitest,随 npm test 运行):覆盖只暂存单侧 workspace 的回归判据、手工执行回退全量、排除项与未登记路径必须被点名、路径归一化,以及与 package.json check:rustfmt 的 workspace 表同集交叉校验。
2026-09-12 19:44:18 +08:00
suzmii
8b85977828
修复 PR316 review:共享分段页签宽度下限作用域、标签契约与资源画布样式
...
- packages/shared/src/components/styles.css:528 [bug medium] min-width: max-content 收窄到新的 .platform-segmented-tabs--scroll 修饰类:grid 分支没有溢出容器、轨道是 minmax(0,1fr),同样的下限只会让内容画到相邻格上;grid 侧靠轨道等分与宿主 truncateLabels 收口,选中 PlatformSegmentedTabs.tsx 的 scroll 分支补修修饰类。
- packages/shared/src/components/PlatformResourceFilterBar.test.tsx 同步改成钉「下限只挂在 --scroll」+「grid 分支不带 --scroll/overflow-x-auto」(声明级断言,jsdom 不计算外部样式表,属弱验证,真机判据见提交说明)。
- packages/shared/src/components/PlatformResourceFilterBar.tsx:24 [maintainability low] Props 改为以 tagItems 为判别项的联合类型:给 tagItems 就必须给 onToggleTag,非法状态编译期不可表达;组件内部再兜 disabled={!onToggleTag} 供给不带类型检查的调用方,并补对应运行时用例。
- packages/shared/src/components/PlatformResourceFilterBar.tsx:107 [style low] 标签行补 scrollbar-hide:它是唯一还画滚动条的横向滚动容器,与 styles.css 里 .scrollbar-hide 的注释口径对齐;补类名与声明级用例。
- packages/shared/src/contracts/gameCreationAppAssetTagLibrary.ts:51 [maintainability low] assetIds 排序改为确定性 code-unit sort(),不再依赖运行环境默认 locale(标签那一层仍显式钉 zh-CN),补跨输入顺序可复现的用例。
- packages/shared/src/contracts/gameCreationAppAssetTagLibrary.ts:68 [bug low] assetTagsMatchSelection 两侧对称归一化:selectedTags 也过 normalizeGameCreationAppAssetTags,' 像素风 ' 这类未归一化的选中项不再静默匹配不上。
- packages/shared/src/contracts/gameCreationApp.test.ts [test low] 新增解析 Rust PROJECT_RESOURCE_CANVAS_SECTIONS 与 TS 常量对齐的交叉校验(仿 assetKindCanonicalMapping.test.ts 解析 Rust 常量先例),钉住两侧分区顺序不漂移。
- packages/shared/src/contracts/gameCreationApp.ts 同步「读显示 / 写回」口径注释:未知 category 已在 Rust 读侧失败关闭,「非法值 → 派生」只剩内存对象语义。
- apps/ai-game-creator-shell/src/styles.css:5790 [bug medium] :has() 悬停高亮分类值换成现行 7 个分区(ui-interaction/character/scene/audio/document/unclassified/version),删掉永不渲染的 code/art 死选择器,补齐缺失栏目的高亮。
- apps/ai-game-creator-shell/src/styles.css:6873 [bug medium] hover/focus-within/is-selected 由只写 border-color 改为完整 border: 1px solid #d57b51(基规则 border: 0 下 border-color 无效果,选中/焦点态此前完全不可见),box-sizing: border-box 下不改卡片尺寸。
- apps/ai-game-creator-shell/src/styles.css:10151 [bug medium] 去掉高优先级 :focus-within 规则里的 box-shadow: none:它盖掉了 --platform-input-focus-ring 焦点光环,direct-codex 输入区此前没有任何可见焦点(无障碍回归),现在光环生效。
- apps/ai-game-creator-shell/src/styles.css:10198 [bug low] 润色状态文字与操作排改为同一行分列(grid-row: 2 + grid-column: 1 / 2),不再整行独占或与按钮重叠,状态出现/消失不改变输入框高度。
- apps/ai-game-creator-shell/src/styles.css:10206 [maintainability low] 删除永不命中的 .resource-reference-input-at direct-codex 规则(showTriggerButton={!directCodex} 不渲染该按钮),保留说明指向真正的 .project-supervisor-reference-trigger。
- 附带 prettier 对 .design-agent-reasoning summary 单行规则的换行归一(该文件本来未过 prettier --check)。
2026-09-12 19:43:58 +08:00
suzmii
9835bbec9f
修复 PR316 review:shared-contracts 资产级失败关闭 + 快速编辑别名白名单
...
- server-rs/crates/shared-contracts/src/game_creation_app.rs:517 [bug high] 资产级 wire 结构补 deny_unknown_fields:与顶层 GameCreationAppManifest 同一取向,避免「读一次 + 任意一次写」静默抹掉未来新增的 assets[i] 字段;新增契约测试 asset_manifest_entry_rejects_unknown_asset_fields(裸条目 + 顶层 manifest 两条读路径都失败关闭,且已知字段照旧往返)。
- server-rs/crates/shared-contracts/src/game_creation_app.rs:536 [bug medium] 未知 category 从「退回 kind 派生值」改为失败关闭:反序列化结果就是落盘原值、要被整结构体写回,静默替换等于无迁移改落盘数据;缺字段仍按 kind 派生,派生只保留在 game_creation_app_asset_effective_category;原用例改名重写为 asset_manifest_entry_keeps_explicit_category_and_rejects_unknown_category。
- server-rs/crates/shared-contracts/src/game_creation_app.rs:780 [test low] 分区顺序跨语言交叉校验:packages/shared 侧新增解析 Rust PROJECT_RESOURCE_CANVAS_SECTIONS 并与 TS 常量对齐的测试(TS 侧补,见后续提交)。
- server-rs/crates/api-server/src/editor_project.rs:4120 [bug medium] 静态图别名白名单补 "asset"(register_local_asset_entry 空 kind 兜底值,canonical 映射到 image),数组长度 17→18,并在用例里补放行/拒绝两条断言。
- server-rs/crates/api-server/src/editor_project.rs:20747 [test low] AGC 快速编辑回归用例不再自洽:agc_payload 真正反序列化成 EditorImageEditRequest 并由请求体自己的 generationInputs.assetKind 驱动判据,另加源码级闸门断言(resolve_editor_image_edit_source / ensure_editor_image_edit_target_matches_source 体内不得再出现 generation_inputs)。
- TS 侧 gameCreationApp 的口径注释同步为「非法值这一支已不可达」(见后续提交)。
2026-09-12 19:43:19 +08:00
suzmii
fc67439802
修复资源画布浮层里的滚轮被画布消费:@ 选择器列表滚动时画布跟着平移 / 缩放
...
Project CI / Repository checks (pull_request) Successful in 2m27s
Project CI / Frontend tests (pull_request) Successful in 3m3s
Project CI / Backend tests (pull_request) Successful in 6m33s
Project CI / Native shell tests (pull_request) Successful in 18m54s
- 共享浮层判据抽出 isEventInsideFloatingOverlay,并新增 isFloatingOverlayWheelEvent:关闭判定与滚轮归属共用同一份口径(DOM 不在边界里的 portal 浮层 + 已登记浮层)
- isEventInsideFloatingMenu 返回值收紧为布尔,避免判据把命中的元素当真值往下传
- 资源画布唯一滚轮入口 handleResourceBookWheel 加统一守卫:浮层里的滚轮一律不消费(不 preventDefault、不动视口),不再逐浮层加 stopPropagation
- resourceCanvasFocusModel 增加 RESOURCE_CANVAS_WHEEL_OVERLAY_SELECTOR 与 isResourceCanvasWheelOverlayTarget,登记留在画布 DOM 里自带滚动区的浮层(快速编辑 / 信息 / 筛选)
- projectResourceLiveIntegration 新增用例:在选择器列表上派发真实 wheel → 浮层自己收到该事件、画布 data-resource-viewport 不变;对照组场景根派发 wheel → 视口照旧变化
- resourceCanvasFloatingDismiss 新增判据单测:portal 浮层 / 共享弹出层 / 已登记浮层三种来源归浮层,边界里的卡片与空白仍归画布,判不出归属不抢
- pitfalls.md 记录「portal 事件沿 React 树冒泡导致画布误吃滚轮」的根因与排查口径
2026-09-12 19:29:20 +08:00
suzmii
e4c2f2466f
合并资源工作台分支:卡片从所属摞浮现与既有三条修复并存
...
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
- 把远端最新 05612c46a(弹窗宿主类样式迁共享表 + 标签统计刷新 + 工具条分隔线去重)合入本分支 b41b26cab(卡片全部从所属摞浮现)
- 冲突零:仅 pitfalls.md 两侧追加记录自动合并,两条都保留
- 验证:npm run typecheck exit 0;resourceBookController / resourceBookLayout / resourceTagStatsRefresh / projectAssetPickerDialogShellStyle / selectedLayerToolbarDividerDedupe 五文件全绿
2026-09-12 18:58:52 +08:00
suzmii
b41b26cab8
修复资源画本进栏目只有少数卡片有位移:没有 First 帧的卡片改从那一摞起飞
...
- apps/ai-game-creator-shell/src/view/project-development/resourceBookController.ts:begin() 顺带按 (栏目, 类型摞列号) 记下同一摞最深那张卡的 First 矩形当"堆锚点",play() 时没有 First 帧的卡片认领它当合成 First(仍是同一套 FLIP,不新增动画系统、不为动画多渲染节点);堆锚点只在本次转场有效(maybeFinish / settle / invalidate 清掉),转场中重基(已在跑动画)不认领锚点,起点仍是"此刻像素"。
- apps/ai-game-creator-shell/src/view/project-development/resourceBookLayout.ts:展开态(allOpen)的卡片补上真实类型摞列号,不再一律 0——否则第 2 摞之后的卡片会全从第 1 摞飞出来。
- apps/ai-game-creator-shell/src/view/project-development/index.tsx:卡片宿主补 data-resource-book-stack-column / data-resource-book-stack-index,把"哪一摞"的摞身份交给转场层。
- apps/ai-game-creator-shell/tests/resourceBookController.test.ts:新增 3 条用例——每一张卡都从自己那一摞位移出来(含第 0/1 摞分别认领各自锚点、总览已渲染的仍用自己 First)、转场中重基从此刻像素而不是被拉回摞上、转场收尾后挂载的卡片不从过期锚点飞出。
- apps/ai-game-creator-shell/tests/resourceBookLayout.test.ts:新增"展开态每张卡带自己那一摞的列号"用例(同栏目两摞 ⇒ [0,0,1])。
- apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts:在既有总览/进栏目用例里钉住宿主上的摞身份属性(总览 3 张 = 下标 0,1,2;进栏目后 5 张 = 下标 0..4、同类型列号 0)。
- docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md:把资源画本转场一节更新为当前状态(堆锚点来源、锚点生命周期、展开态列号)。
- docs/project-memory/shared-memory/pitfalls.md:记录本次排障——现象、已用代码核实的原因(总览每摞只铺 3 张 ⇒ 其余卡片没有节点、没有 First 帧)、"钉住的标题栏移出 world"那笔改动不是原因的证据、处理、变异验证与真机判据。
2026-09-12 18:56:43 +08:00
k88936
46b0871e6d
补充背景节点规则说明
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Backend tests (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 2m48s
Project CI / Native shell tests (pull_request) Successful in 19m57s
2026-09-12 18:56:31 +08:00
suzmii
05612c46ae
合并资源工作台分支:弹窗宿主类样式迁到共享表与既有修复并存
...
Project CI / Repository checks (pull_request) Successful in 2m36s
Project CI / Frontend tests (pull_request) Successful in 3m11s
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
- 把远端最新 b498c2780(标签统计刷新 + 工具条分隔线去重)合入本分支 074924190(弹窗宿主类 platform-modal-shell/overlay/backdrop 迁到共享样式表)
- 冲突零:src/index.css 自动合并(本分支删除三条宿主类规则,远端最新新增分隔线去重规则)
- 验证:npm run typecheck exit 0;projectAssetPickerDialogShellStyle + selectedLayerToolbarDividerDedupe + resourceTagStatsRefresh 三个用例文件全绿
2026-09-12 18:51:33 +08:00
suzmii
0749241908
修复 AGC「选择替换素材」弹窗面板透明:平台弹窗外壳规则移入共享样式表
...
- 根因:弹窗面板用的 `platform-modal-shell`(遮罩 `platform-overlay`)规则原先只写在网页端整站样式表 src/index.css;AGC 只加载 packages/shared/src/components/styles.css 与 theme.css,类名挂上了但一条声明都没命中,面板因此无底色、无边框、无阴影,背后模糊的资源画布直接透出
- 把 platform-modal-shell / platform-modal-backdrop / platform-overlay 三条宿主类规则从 src/index.css 移进 packages/shared/src/components/styles.css:两个宿主都 import 这张表,规则只保留一份,不在 AGC 业务样式里复制平行副本;三处声明逐字照搬,网页端层叠结果不变
- 新增 apps/ai-game-creator-shell/tests/projectAssetPickerDialogShellStyle.test.tsx:从 src/main.tsx 按真实 import 关系解析出「AGC 到底加载了哪些样式表」,断言清单里有这三条规则、背景引用主题 token、light 主题下 --platform-modal-fill 各色停 alpha ≥ 0.9;DOM 契约断言面板挂 platform-modal-shell、遮罩带 platform-overlay 与 platform-theme--light;并断言这三条规则只在共享表里各定义一次(禁止平行拷贝)
- docs/project-memory/shared-memory/pitfalls.md 记录「共享弹窗的宿主类必须落在所有宿主都会加载的样式表里」的排障经验
2026-09-12 18:48:31 +08:00
suzmii
b498c2780e
修复改完素材标签后聊天侧标签统计与候选不刷新
...
Project CI / Repository checks (pull_request) Successful in 2m56s
Project CI / Frontend tests (pull_request) Successful in 3m54s
Project CI / Backend tests (pull_request) Successful in 6m47s
Project CI / Native shell tests (pull_request) Has been cancelled
- App.tsx:新增跟随工作台壳清单快照的 effect(`manifestRef` + 同一 `projectId` 且内容确实变了才 `setManifest`),
让聊天侧 `@` 选择器的标签计数与候选在资源命令写入后跟上画布那份清单
- tests/resourceTagStatsRefresh.test.tsx(新增):真宿主链路用例 —— 资源画布「编辑标签」保存后,
聊天 `@` 选择器出现该标签 chip 与计数、并按它收窄候选;反向用例钉住未标注标签时不渲染标签 chip
- docs/project-memory/shared-memory/decision-log.md:记录标签派生数据的三处来源与各自数据源、
根因(`initialProjectManifest` 只是 `useState` 初值,壳里换清单不会再进来)、修复口径与已知未覆盖项
2026-09-12 18:48:04 +08:00
suzmii
bb91e8909d
修复选中资源工具条出现两条相邻分隔线
...
- 成因:共享工具条在 showQuickEdit 分支于「快速编辑」后输出一条分隔线,同时为 extraActions 自动生成前置分隔线(extraActionDivider);AGC 资源卡是「快速编辑可用 + 中间动作未接通不渲染」的组合,两条因此相邻
- 修法:样式层去重(相邻的两条只显示一条),不改 JSX 结构,对美术画布与资源画布两端都成立,也不会隐藏任何真正起分隔作用的那一条
- 新增契约用例 selectedLayerToolbarDividerDedupe.test.ts 钉住去重规则与它的成因两端
- 验证:该用例 3 passed;变异验证(删掉去重规则)→ 1 failed,还原后 3 passed
2026-09-12 18:23:02 +08:00
k88936
5c40abce47
识别树根节点改为模型根节点
...
识别协议改用 trees[].root 并保留根节点非几何字段
同步根节点解析校验、提示词与 UI 树转换
2026-09-12 18:10:45 +08:00
suzmii
4c180ac29a
合并 fix/agc-manifest-revision-cas:钉住的栏目标题栏移出画布缩放层(解 pitfalls.md 冲突)
...
Project CI / Repository checks (pull_request) Successful in 2m48s
Project CI / Frontend tests (pull_request) Successful in 3m42s
Project CI / Backend tests (pull_request) Successful in 6m30s
Project CI / Native shell tests (pull_request) Successful in 17m5s
- 合并来源:ff0bc5a3e(fix/agc-manifest-revision-cas)。
- 冲突只有 1 个文件 1 处:docs/project-memory/shared-memory/pitfalls.md(两侧都在文件末尾追加了一条 2026-09-12 记录,文本上是同一个插入点)。
- 解冲突(两侧内容逐字都保留,都不改写、不删):
- 保留 HEAD 侧 6618207b5 的「运行模块切换版本报 listeners[eventId].handlerId」一节(pitfalls.md:5397)。
- 追加 ff0bc5a3e 的「资源工作台顶部那一行发虚」一节(pitfalls.md:5407)。
- 同一天的记录之间没有排序语义,取「HEAD 内容不动、新记录追加在末尾」,这样两侧 diff 都是纯插入。
- 另外两处自动合并(git 未报冲突)已逐段语义核对,两侧行为都在:
- apps/ai-game-creator-shell/src/view/project-development/index.tsx:ff0bc5a3e 的 renderTitlebar 结构完整保留(:1187 定义、:1244 总览态在 world 内渲染、:1313-1317 钉住的那一条渲染在 world 之外、作为 world 的兄弟节点);ff0bc5a3e 删掉的 titlebarTransform / safeViewport / safeMainViewport 已无残留;本分支 V3 的行为同时保留(:1234 plan.map 栏目卡、:1250 card.presentation、:1279 isResourceBookAllTarget 预览卡、:1307 worldOverlay、:1318 overlay)。
- apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts:ff0bc5a3e 钉的新不变量(:782-800 钉住标题栏不在 world 内、内联 transform 为空、父节点是场景根)与本分支 V3 既有用例都在。
- resourceBookController.ts 未冲突:nodeWorldTransform(:221)、readWorld 补的 element 输出、nodeWorld 贯穿 cleanRect / FLIP / worldScale(:457、:521)都在。
- 自证:
- 仓库内 git grep '^<<<<<<<|^>>>>>>>' 无命中。
- git diff --name-only 87fbf92c5 <本提交> 恰好 18 个文件 = 6618207b5(10) + ff0bc5a3e(5,与前者共用 pitfalls.md) + 46458a825(2) + DesignWorkspacePanel.tsx(1),没有多余文件。
- git diff ff0bc5a3e <本提交> -- resourceBookController.ts resourceBookController.test.ts 为空(这两个文件 ff0bc5a3e 改过、master 没碰,因此必须逐字一致);与 ff0bc5a3e 的差异只落在双方都改过的 index.tsx / project-development.suite.ts / pitfalls.md 三个文件上。
- 验证(两条修复都并入后统一执行,全绿):npm run typecheck exit 0;npm --prefix apps/ai-game-creator-shell run typecheck exit 0;npx vitest run apps/ai-game-creator-shell/tests → 98 files / 1394 passed | 4 skipped(0 failed);npm run check:encoding → 4489 file(s) passed;git diff --check 干净;npm run check:rustfmt exit 0(这两笔修复都没动 Rust,额外确认一次)。
2026-09-12 18:09:57 +08:00
suzmii
46458a8253
修复运行模块版本菜单「点了选项没反应」:portal 菜单被「点外部」判定吃掉 click
...
与 665982eb9 的 tauri 事件注销竞态是两个独立原因,用户看到的是同一个症状:
① 切换版本时的重载被事件竞态报错打断(665982eb9,已并入 6618207b5);
② 版本菜单在选项收到 click 之前被「点外部」判定收掉,onSelectVersion 永远不被调用(本提交)。
- 现象:在运行模块点版本菜单里的选项没有任何反应(菜单直接消失、当前版本不切换)。
- 原因:菜单用 createPortal 挂到 document.body(运行画面会缩放,挂 body 才不跟着画布跑偏),DOM 上不在触发按钮 rootRef 的子树里;而「点外部关闭」判定只认 rootRef,落在选项上的那一次按下就被当成点外部,菜单在选项收到 click 之前被卸载,选项的 onClick 永远不会触发。
- 改法:删掉自建的 window mousedown 判定,复用共享 hook useImageCanvasFloatingOptionDismiss(AGC 的 view/project-development/index.tsx:1661 已在用同一份口径,不新造第二套判定),并把 portal 菜单登记成第二个边界:GameRunVersionPicker.tsx:35 新增 menuRef、:37-41 传 boundaryRefs: [rootRef, menuRef]、:69 把 menuRef 挂到菜单容器上。菜单的关闭时机随之从 mousedown 变为 click,与画布浮层口径一致。
- 回归用例(apps/ai-game-creator-shell/tests/resourceVersionSwitch.test.tsx,全部走真实指针序列 mousedown → mouseup → click,不再像旧用例那样只派发 click):
- does not dismiss the portal version menu when an option is pressed down:mousedown 后菜单必须还在,随后 mouseup+click 必须调用 onSelectVersion('version-root')。
- selects the version from the run module when the option is clicked after a real press:真实 launcher + 运行模块,走完真实序列后宿主必须收到 onActiveVersionChange('version-root')。
- keeps the portal menu mounted when the click lands on the menu itself:点 portal 菜单自身(非选项区)不算点外部。
- 变异验证(两条,都先红后绿):
- 还原旧实现(window mousedown + 只认 rootRef)→ 3 条新用例全红:2 条 AssertionError: expected null not to be null(菜单被关掉),1 条 expected "spy" to be called with arguments: [ 'version-root' ] / Number of calls: 0(onActiveVersionChange 没被调用,正是用户症状)。
- 只把边界收回 boundaryRefs: [rootRef](仍复用 hook,但不登记 portal 菜单)→ keeps the portal menu mounted when the click lands on the menu itself 变红(expected null not to be null)。注意另两条此时仍绿:共享 hook 的判定在 click 而非 mousedown,所以要复现用户现象必须连旧的 mousedown 判定一起还原,这也是本次把判定整体换成共享 hook 的直接理由。
- 验证:npx vitest run apps/ai-game-creator-shell/tests/resourceVersionSwitch.test.tsx 7 passed(原 4 条 + 新 3 条);npm --prefix apps/ai-game-creator-shell run typecheck exit 0。
2026-09-12 18:02:13 +08:00
suzmii
665982eb99
合并 fix/agc-version-switch-event:切换版本报 listeners[eventId].handlerId 的订阅竞态修复并入资源工作台 V3(解 App.tsx 冲突)
...
- 合并来源:6618207b5(fix/agc-version-switch-event)。冲突只有 1 个文件 1 处:apps/ai-game-creator-shell/src/App.tsx:1889-1940。
- 冲突成因:master 侧(策划 agent 重构)在 planning-session-v2-stream 之后新增了一条 design-agent-update 订阅(App.tsx:1888);6618207b5 则把这处相邻的 manifest-invalidated 守卫 `const listen = window.__TAURI__?.event?.listen; if (!listen)` 换成 `canSubscribeTauriEvents()`,两段文本相邻导致冲突。
- 解冲突(两侧都保留,未删任何一侧):
- 保留 master 新增的 design-agent-update effect 及其全部行为符号:designAgentTurnRef 轮次配对、payload.projectPath 比对、setPlanningV2TransientReply、setPlanningV2Reasoning、applyDesignView(App.tsx:1888-1931);只把它的订阅方式换成 6618207b5 的入口(subscribeTauriEvent<DesignEvent> + canSubscribeTauriEvents 守卫)。
- 采用 6618207b5 对 manifest-invalidated 的写法:canSubscribeTauriEvents() 守卫 + subscribeTauriEvent<GameCreatorManifestInvalidatedEvent>(App.tsx:1933-1940),refreshManifest 行为不变。
- 冲突区外补齐同一件修复:apps/ai-game-creator-shell/src/features/project-workspace/DesignWorkspacePanel.tsx:264-301 是 master 新增、而 6618207b5 基于共同祖先 46788edbb 写作时还没出现(base 里没有这个文件)的一处订阅,事件同为 design-agent-update、写法同为「订阅后立刻注销」,会同样踩 React.StrictMode 的注销竞态,因此一并改走订阅入口;否则「唯一订阅入口」不成立、该竞态在本次要打包的版本里仍然活着。
- docs/project-memory/shared-memory/pitfalls.md 自动合并成功,6618207b5 与 ff0bc5a3e 两条 2026-09-12 记录都在(无手工取舍)。
- 自证:git grep '^<<<<<<<|^>>>>>>>' 无命中;AGC 内除 services/tauriEventSubscription.ts 自身外,已无 __TAURI__?.event?.listen 直连订阅。
- 验证(本提交时点):npm --prefix apps/ai-game-creator-shell run typecheck exit 0;npx vitest run apps/ai-game-creator-shell/tests/resourceVersionSwitch.test.tsx 7 passed。全量验证(两侧 typecheck、AGC 全量用例、encoding、git diff --check)在两条修复都并入后统一执行。
2026-09-12 18:01:38 +08:00
k88936
47d09d51ef
简化并集中化随机 NodeId 生成逻辑
2026-09-12 17:57:48 +08:00
suzmii
87fbf92c58
合并 origin/master 到资源工作台 V3 分支:解 4 处冲突并保留两侧行为
...
Project CI / Repository checks (pull_request) Successful in 3m14s
Project CI / Frontend tests (pull_request) Successful in 3m57s
Project CI / Backend tests (pull_request) Successful in 6m30s
Project CI / Native shell tests (pull_request) Successful in 17m27s
- WorkspaceLauncher.tsx:保留本分支清单快照 CAS 拒收提示(manifestMergeNotice 提示条、data-manifest-merge-* 观察点、recoverRejectedManifestSnapshot「重新读取清单」)与 activeVersionId/onActiveVersionChange 版本口径,并入 master 的策划/游戏运行态切换(onMakeGame + switchToGameRuntime、suppressInitialGameTurn 抑制首轮、supervisor key 带 agentRuntimeMode、onSwitchToGameRuntime),planningStartMode 统一取 master 的派生值(上下文 startMode 为 planning 且未切到 game 运行时)
- ProjectSupervisorView.tsx:props 同时保留本分支 versions/activeVersionId 与 master 的 designView/onDesignApprove/onDesignClarify/onDesignRetry,DesignAgentSurface 审批链路与本分支资源引用输入区并存;directCodex 输入区保留本分支 @ 引用按钮 + 模型选择 + 发送按钮控制条,发送按钮禁用条件并入 master 的 designView 审批待定口径,模型选择沿用 master 的「对话中可切换」口径
- styles.css:本分支追加的资源画布/输入区样式块与 master 追加的 .design-agent-reasoning 样式块都保留,并补上本分支最后一条规则的收尾大括号
- view/project-development/index.tsx:保留本分支的 image-editor 引用(ImageCanvasProjectAssetPickerDialog、ImageCanvasQuickEditPanelView、ImageCanvasSelectedLayerToolbarView、useImageCanvasFloatingOptionDismiss),去掉 master 对已退役 features/asset-canvas 的 import(本分支已由 resource-canvas 取代),保留 master 的 DesignWorkspacePanel 与 planningStartMode 策划工作台分支
- tests/workspaceLauncherManifestMerge.test.tsx:补 master 新引入的 get_design_agent_runtime_mode mock(返回 null,与 master 各套件同口径),拒收提示断言不变
- tests/appSurface/design-agent.suite.ts:审批待定禁用输入的断言改用本分支 Lexical 输入区的禁用口径(容器 data-disabled + editor.setEditable(false)),断言意图不变
- 验证:npm run typecheck 通过;apps/ai-game-creator-shell typecheck 通过;apps/ai-game-creator-shell/tests 96 个测试文件 1380 通过 4 跳过 0 失败;全仓 vitest 297 通过 2 失败(scripts 下两例为 Windows 权限语义导致的既有失败,相关文件与实现均未参与本次合并);npm run check:encoding 与 git diff --check 通过
2026-09-12 17:31:51 +08:00
suzmii
6618207b5b
修复运行模块切换版本报 listeners[eventId].handlerId:事件订阅改为自建登记 + 幂等注销
...
- 新增 apps/ai-game-creator-shell/src/services/tauriEventSubscription.ts:AGC 唯一的事件订阅入口。真实 WebView 内用 plugin:event|listen + transformCallback 自建登记,注销时先 unregisterCallback(handlerId)(callbacks.delete,幂等、缺条目也不抛)再发 plugin:event|unlisten,并对重复注销去重,注销失败只在 console.warn 显式记录;非原生环境沿用注入的 event.listen(两参调用形状不变),未接桥接时返回空操作。tauri 2.11 的注销脚本会先读注册表条目再摘回调,而条目由注册 eval 异步写入,与 IPC 返回无序,这一层自建登记正好绕开该竞态(上游 tauri-apps/tauri#15799 / #15800,2.12 起脚本自带判空,升级后可删掉 internals 分支)。
- App.tsx:5 处事件订阅(game-creator-direct-turn-update / agent-progress / agent-runtime-update / planning-session-v2-stream / manifest-invalidated)与角色 Agent 流式回复监听改用订阅入口,守卫由 window.__TAURI__?.event?.listen 换成 canSubscribeTauriEvents()。
- features/app-shell/useDeveloperAgentPanel.ts:Agent Runtime 与角色 Agent 流式回复两处订阅改用订阅入口。
- services/errorReportingBridge.ts:error-report-updated 订阅改用订阅入口,不再直接依赖库内 listen。
- components/AppUpdateNotice.tsx:更新下载进度订阅改用订阅入口。
- components/WindowChrome.tsx:窗口尺寸监听不再走 nativeWindow.onResized,改为订阅 tauri://resize(限定当前窗口),避开库内注销竞态。
- 新增 tests/tauriEventFake.ts:与 tauri 2.11.3 等价的 Tauri 事件替身(注册表条目由注册 eval 异步写入、库内注销脚本读缺失条目即抛并留痕、全局桥 event.listen 按库内实现返回会读条目的注销函数)。
- 新增 tests/tauriEventSubscription.test.ts(7 例):注册 eval 未落地就注销、重复注销只摘一次、注册落地后能投递且注销后不再投递、真实 WebView 不走库内注销脚本、无 internals 时回落注入桥接、无桥接时空操作。
- 新增 tests/runVersionSwitchEventSubscription.test.tsx(2 例):真实 launcher + 运行模块连续切换两次版本(断言 start_local_game_preview 被调用)、卸载后后端订阅与 JS 回调都不泄漏、切换版本后清单失效事件仍能送达并重读清单。
- docs/project-memory/shared-memory/pitfalls.md:记录该竞态的成因、触发面、处理取舍与变异验证结论。
2026-09-12 17:23:22 +08:00
suzmii
ff0bc5a3e7
资源工作台钉住的标题栏移出画布缩放层:整行文字不再发虚
...
- 钉在视口上的栏目标题栏(栏目名 / 计数徽标 / 资源总览入口)改挂场景根,成为带 scale() 的 .game-resource-book-scene-world 的兄弟节点,不再用 scale(1 / s) 抵消 world;总览态的栏目标题栏仍留在 world 里与缩略卡对齐
- index.tsx 抽出 ResourceBookScene.renderTitlebar(placement.pinned) 一处产出两种宿主,删除只服务抵消变换的 titlebarTransform 与 safeViewport/safeMainViewport 中间量
- resourceBookController 按节点自己的坐标系换算:world 内用 world 缩放,world 外(钉住标题栏)用 1;新增 nodeWorldTransform,readWorld 补 element 输出,nodeWorld 贯穿 cleanRect / FLIP 反向 transform / worldScale
- 更新 resourceBookFlipValues 与 readOrigin 的口径注释:translate 单位是宿主自身坐标系,不再假定所有宿主都在 world 里
- appSurface 用例改钉新不变量:钉住的标题栏内联 transform 必须为空、不在 world 内、父节点为场景根,卡片必须仍在 world 内;并说明标题栏宿主不再跨视图同一节点、转场仍由控制器按 key 记录的 First 屏幕矩形驱动
- resourceBookController 用例新增「屏幕坐标系的宿主不被 world 缩放除」,并保留 world 内卡片仍按缩放除的对照
- 技术方案 2026-09-05 段落同步新结构;pitfalls 增记取证(截图墨色峰值 98.6 vs 同色正文 91.7、点阵周期反推 dpr=1)、本机复现尝试与结论、三处变异验证和真机判据
2026-09-12 17:09:42 +08:00
suzmii
2d40f02286
合并资源工作台分支:素材类型可由用户变更与角标显示资源类型并入
...
Project CI / Repository checks (pull_request) Failing after 14s
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Frontend tests (pull_request) Successful in 3m0s
Project CI / Native shell tests (pull_request) Successful in 17m12s
- 把 v3 顶端 ace31a5f1(快速编辑 @ 引用素材 + @ 面板标签筛选)合入本分支,与本分支 1079f6c91(用户可变更素材类型、角标改显示资源类型)并存
- 冲突零:index.tsx 两侧改动落点不同(快速编辑 promptInputSlot 接线 vs 角标取值点),projectResourceLiveIntegration 与验收文档自动合并
- 验证:npm run typecheck exit 0;resourceClassificationPanel + projectResourceLiveIntegration 共 45 tests 全绿;check:encoding 4409 文件通过;git diff --check 干净
2026-09-12 16:57:28 +08:00
suzmii
1079f6c91b
资源工作台可变更素材类型:面板加类型选择器、卡片角标改显示资源类型
...
- ResourceClassificationPanel.tsx:加素材类型(功能分类)选择器,与标签同一次保存、同一条写入路径;选项 = GAME_CREATION_APP_ASSET_CATEGORIES × resourceReferenceCategoryLabel,不新造第二套中文译名
- ResourceClassificationPanel.tsx:选择器读显示口径(与画布栏目 projectResourceAssetCategory 同源,选中项就是卡片所在栏目);写回分两路——没碰过类型控件回传 gameCreationAppAssetPersistedCategory 的落盘原值,主动选过才写用户选的值(categoryChoice ?? persisted),保证「只改标签」不漂移分类
- index.tsx:资源卡右上角角标由「文件/媒体类型」改为「资源类型」,取 categoryLabels[resource.category](栏目与筛选共用的同一份文案),角标恒等于该卡所在栏目;projectResourceTypeLabel 仍服务资源管理面板小字与总览摞分列,不再用于角标
- tests/resourceClassificationPanel.test.tsx:新增「变更素材类型」6 条用例(选择器 6 项与中文口径、选择器显示显示口径自愈值、主动选值写入载荷、只改标签回传落盘原值对照、显式待归类写入 unclassified、连续两次各带当次选择且不关窗),并按新增控件更新既有按钮序与「分类不再由面板编辑」两条断言
- tests/projectResourceLiveIntegration.test.tsx:新增真宿主跟随链用例(角标显示资源类型并与栏目同名、改类型后卡片进目标栏目且角标跟着变、原栏目不再有它),配套状态化宿主 fixture、分类写入与 get_local_game_manifest 两条命令桩、切栏目与读角标助手
- tests/appSurface/project-development.suite.ts:原 data-resource-type 媒体类型断言改为资源类型(角色与对象 / 待归类 / 音频),并说明卡面正文走媒体分支、角标走资源类型这两个独立轴
- docs:PRD §5.3 由「分类没有用户手动设置入口」改为当前两口径分叉(选择器读显示口径、写回按是否主动选过分流)与「显式待归类被读时自愈覆盖」盲区
- docs:AGC 资源工作台 V3 端到端验收 S5 的「前端交互不能改分类」改写为可改分类,补判据(角标读 .game-resource-card-type-badge)与盲区说明;实施计划写入命令一节的面板名与职责同步为「编辑素材标签(标签 + 素材类型)」
- docs:decision-log 新增条目记录本次决策(Rust 无需改动、画布跟随链无需额外迁移代码、待归类盲区、四条变异验证结果与一条不可构造的变异)
- 说明:Rust、manifest 字段构成与 SpacetimeDB 均不改;写入命令 update_local_project_resource_classification 早已接受任意合法 category
2026-09-12 16:54:24 +08:00
suzmii
ace31a5f19
合并资源工作台分支:快速编辑 @ 引用素材与标签面板不关窗两套行为并存
...
Project CI / Repository checks (pull_request) Failing after 15s
Project CI / Backend tests (pull_request) Failing after 15s
Project CI / Frontend tests (pull_request) Successful in 3m2s
Project CI / Native shell tests (pull_request) Successful in 17m29s
- 把 v3 顶端 46788edbb(「编辑素材标签」保存后不关窗)合入本分支,与 35d3a92af(快速编辑支持 @ 引用素材、@ 面板补标签筛选)并存
- 冲突零:index.tsx 两侧改动落在不同位置(keepClassificationPanelOpen 与 quickEditReferences/promptInputSlot 接线),自动合并
- 验证:npm run typecheck exit 0;resourceClassificationPanel + resourceVersionReplacement + resourceReferenceInput + projectResourceLiveIntegration 共 4 files / 73 tests 全绿
2026-09-12 16:51:56 +08:00
suzmii
35d3a92afd
快速编辑提示词支持 @ 引用素材,@ 面板补标签筛选
...
- 快速编辑面板提示词换成与聊天同一个 `ResourceReferenceInput`,`@` 候选、插入动作与引用模型全部复用聊天那一套
- 共享 composer / 快速编辑面板新增 `promptInputSlot` 注入位,宿主控件替换默认 textarea,不传时 DOM 与行为逐字不变
- `ResourceReferenceInput` 新增 `showPolishAction`:快速编辑的润色仍由 ResourcePromptPolishSlot 承担,面板里不再出现第二个润色入口
- `ResourceReferenceInput` 的多行输入区把 Enter 留给换行,只有单行输入区才用 Enter 提交
- `@` 面板的搜索与筛选改用共享 `PlatformResourceFilterBar`,搜索 + 功能分类 + 标签三者在面板内叠加生效
- 新增 `resourceReferenceMatchesTagSelection` / `resourceReferenceTagLibrary`,标签口径(多标签 AND、计数与排序)落在共享标签库,两个页签各持一份
- 宿主新增 `quickEditReferences` 与 `applyResourceQuickEditDraft`,派生请求的 prompt 就是输入区回填的那份文本(`@显示名`),不引入第二种引用格式
- `useImageCanvasFloatingOptionDismiss` 新增 `isInsideExtraOverlay`:宿主 portal 到 body 的 `@` 选择器与候选菜单不再被判成点外部而收起快速编辑面板
- 资源画布快速编辑提示词输入区补样式(铺满 composer 一整行、高度上限),`@` 面板去掉手写搜索行样式
- 用例:新增标签库口径、标签筛选(多标签叠加 + 关键字 + 功能分类)、两页签独立标签、聊天与快速编辑草稿一致性、快速编辑内 `@` 出选择器且派生 payload 断言;扩展 AGC 资源工作台 V3 端到端验收用例
2026-09-12 16:44:55 +08:00
k88936
f05f6e49ab
复用原始图片编辑 HTTP 客户端
...
Project CI / Repository checks (pull_request) Failing after 12s
Project CI / Backend tests (pull_request) Failing after 13s
Project CI / Frontend tests (pull_request) Successful in 3m12s
Project CI / Native shell tests (pull_request) Failing after 4m20s
让 raw edit 接收 api-server 构造的 VectorEngine reqwest 客户端。
通过 request builder 保留有效请求超时,不修改现有连接池策略。
移除不再使用的客户端构造错误分支并同步技术方案。
2026-09-12 16:33:33 +08:00
k88936
c7fe531b16
恢复预览百分比按钮适配画布
...
将缩放百分比显示改为可点击的适配画布按钮
复用工具栏按钮的鼠标焦点处理并按当前容器重新计算视口
补充预览缩放组件回归测试并同步交互设计文档
2026-09-12 16:31:55 +08:00
k88936
d44c6ab62c
补充背景节点规则示例说明
2026-09-12 16:28:31 +08:00
k88936
6764950aec
限制原始图片上传字节
...
将 image 和 mask multipart 字段改为分块读取并限制单字段大小。
新增图片总字节上限、413 错误和字段/总量边界测试。
同步 Raw GPT Image 2 代理技术方案的资源防护合同。
2026-09-12 16:27:23 +08:00
k88936
0944667c37
限制原始图片解码并发
...
为 raw image PNG 预处理增加 AppState 专用 semaphore。
按请求截止时间限制槽位等待和 blocking 解码等待,并让 permit 持有到任务结束。
2026-09-12 16:22:06 +08:00
k88936
bb2f080d3b
分离产物使用 UUID 文件名
...
切分图片文件名改用 UUID,避免把 NodeId 当作物理路径。
继续通过 cut_paths 写入 BoundNode.cut_image_path,保留逻辑节点 ID 与产物路径的独立性。
2026-09-12 16:18:13 +08:00
lhk229
3f69ce8bb7
Merge pull request '重构策划agent,接入新工作流+harness' ( #322 ) from design_agent_refactor into master
...
Project CI / Repository checks (push) Successful in 2m33s
Project CI / Frontend tests (push) Successful in 3m18s
Project CI / Backend tests (push) Successful in 6m13s
Project CI / Native shell tests (push) Successful in 17m28s
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/322
2026-09-12 16:10:07 +08:00
suzmii
46788edbb8
修复「编辑素材标签」保存后关窗:点「添加」成功后面板保持打开,可连续添加
...
Project CI / Repository checks (pull_request) Successful in 2m44s
Project CI / Frontend tests (pull_request) Successful in 3m37s
Project CI / Backend tests (pull_request) Successful in 7m5s
Project CI / Native shell tests (pull_request) Successful in 17m30s
- 定位关窗来源:面板的 saveResourceClassification 只调 onSaved、从不调 onClose;真正卸载面板的是宿主 index.tsx 的 setResourceClassificationAssetId(null)(在 reloadManifestAfterAssetCommand 里,由 handleResourceClassificationSaved 触发)
- 在宿主层给 reloadManifestAfterAssetCommand 加 keepClassificationPanelOpen 开关:默认仍然收起,删除素材 / 版本替换 / 重命名的既有行为不变,只有标签保存显式传 true
- 标签保存后不再清 resourceClassificationAssetId:面板保持打开,新标签已落成 pill、输入框已清空,用户可以接着加下一个标签
- 关闭面板仍只走头部 ×;标签 pill 内的「删除标签」按钮与删除素材流程都不受影响
- 面板用例:添加后不得调用 onClose、面板仍在、新标签出现在已有标签列表、输入框清空;连续两次「添加」各自写盘且第二次带上累计标签、category 仍原样回传落盘值
- 工台用例(resourceVersionReplacement.test.tsx)补真宿主链路:经工具条「编辑标签」打开面板 → 添加 → 断言写入载荷与面板仍在 → 再添加一次 → 两次写入各自发生且面板依然打开(只测面板组件看不出宿主把面板卸载了)
2026-09-12 15:59:44 +08:00
lhk229
2e87a1403a
自动隔离损坏的策划会话并修复 CI
...
Project CI / Repository checks (pull_request) Successful in 2m40s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 6m3s
Project CI / Native shell tests (pull_request) Successful in 17m48s
会话读取损坏时自动备份并允许项目继续打开
登记会话重置命令并补齐 Native shell 配置检查
2026-09-12 07:48:07 +00:00
k88936
413707da33
提前拒绝高位深 PNG 解码
...
通过 image crate 的 ImageReader decoder 元数据在像素缓冲分配前拒绝 16-bit PNG。
继续使用同一外部 decoder 执行受限像素读取校验,不手写 PNG 解析器。
2026-09-12 15:40:26 +08:00
k88936
6235fa3298
修复分离状态跨平台原子替换
...
使用唯一临时文件并同步写入,避免 checkpoint 临时文件互相覆盖。
Unix 使用 rename,Windows 使用 MoveFileExW 原子覆盖已有 state.json。
拒绝符号链接和非普通文件目标,并增加覆盖已有目标回归测试。
2026-09-12 15:40:12 +08:00
lhk229
f505d2792f
允许损坏策划会话降级打开项目
...
Project CI / Repository checks (pull_request) Successful in 2m34s
Project CI / Frontend tests (pull_request) Successful in 3m12s
Project CI / Native shell tests (pull_request) Failing after 4m5s
Project CI / Backend tests (pull_request) Successful in 5m51s
会话读取失败时保留工作台与产物访问能力
新增策划会话备份重置命令,不删除工作区产物
2026-09-12 07:33:49 +00:00
suzmii
dc243b0d57
资源工作台「替换素材」候选窗接上预览管线,补齐候选排序、禁用态可读性与删除素材入口
...
Project CI / Repository checks (pull_request) Successful in 2m48s
Project CI / Frontend tests (pull_request) Successful in 3m14s
Project CI / Backend tests (pull_request) Successful in 7m49s
Project CI / Native shell tests (pull_request) Successful in 18m27s
- 「替换素材」候选卡缩略图接入资源卡同一条预览管线:新增 ResourcePreviewMedia,复用同一份预览身份、同一条队列与 LRU 缓存,不再只渲染类型占位图标
- 预览 hook 暴露 sweepVisiblePreviews:弹窗内容挂在 portal 下、不在资源画本 observer 的 root 子树内,改为在「弹窗打开」与「候选区滚动」两个几何变化点显式按同一套视口几何判据兜底放行,不新增第二条加载通路
- 候选排序抽出纯函数 sortResourceReplacementCandidates:可替换(无硬门禁失败)的排最前,其余按后端原名次跟随且仍渲染但禁用;判据与弹窗禁用状态同源,不会出现「排最前却点不动」
- 抽出纯函数 projectResourcesByManifestAssetId,让弹窗素材映射与候选缩略图共用同一份资源投影口径
- 共享选择弹窗的禁用态不再整卡压透明度:变灰只压在缩略图与名称上,「分类不同」这类禁用原因保持全对比度可读(网页端美术画布不传禁用原因,视觉逐字不变)
- 资源卡选中工具条末位新增「删除素材」,前置共享工具条同一套分隔线与前面的非破坏性动作隔开,只在 manifestAssetId 存在时才渲染
- 删除流程抽成 useResourceAssetDeleteFlow(读引用信息 → ResourceAssetDeleteDialog 二次确认 → delete_local_project_asset 的 deleteReferencedVersions 三分支),工具条与面板共用同一份实现,没有第二套删除
- 「编辑素材标签」面板底部只留右下角一个「添加」:点它把输入框内容(含未按回车的尾巴)落成 pill 并按现有写入路径保存,分类仍原样回传落盘原值;删除素材/取消/保存标签三个按钮移除,关闭仍走头部 ×
- 标签 pill 内的删除标签按钮保持不变
- 更新与补充用例:候选排序、排序与禁用同源、候选缩略图真链路与滚动兜底放行、工具条删除入口位置与 IPC 载荷、连带删除分支、面板无删除入口与「添加」语义、禁用态可读性类名契约、工具条动作清单
2026-09-12 15:30:38 +08:00
k88936
8a9d37d5ad
移除分离提示词的破坏性清洗
...
保留描述、返工意见和 NodeId 原文,删除重复截断与字符改写。
返工意见仍由 validate_binding_response 统一执行 MAX_REWORK_NOTE_CHARS 校验。
2026-09-12 15:19:24 +08:00
lhk229
74fad546ff
增加 Responses 槽位安全保险丝
...
拒绝超出 4096 的 output_index,避免异常上游输入触发巨额扩容
补充安全边界测试且不限制正常输出内容
2026-09-12 07:17:16 +00:00
lhk229
16a6cdaf79
修复策划审批回调跨项目污染
...
为审批响应增加项目路径与请求身份校验
防止旧项目回调覆盖当前会话并清理新项目状态
2026-09-12 07:11:40 +00:00
k88936
9bbfc56cd7
修正分离期间保存选项的闭包判断
...
由调用方明确传入的 allowDuringSeparation 直接生效,避免依赖点击时捕获的过期状态。
2026-09-12 15:02:56 +08:00
k88936
e9d0180054
集中管理 GPT Image 2 尺寸限制
...
将请求尺寸压缩与原始编辑校验共用同一组像素、边长和对齐常量。
2026-09-12 15:00:55 +08:00
k88936
664bdd6877
避免伪造原始图片供应商请求编号
...
原始图片响应未提供供应商 request id 时不再写入操作名作为关联编号。
2026-09-12 14:58:21 +08:00
k88936
39a64a864a
声明图片平台使用 reqwest 流式特性
...
为 Part::stream 补齐 platform-image 的直接依赖特性,支持独立构建。
2026-09-12 14:56:54 +08:00
k88936
f055961714
修正分离源图 MIME 识别回退
...
缺失或未知 MIME 时强制走 PNG 规范化,避免非 PNG 数据被误标为 image/png。
2026-09-12 14:55:35 +08:00
k88936
3bcabe36fa
清理字体校验中的冗余空值判断
...
按 FontSource 的实际联合类型保留运行时字体资源校验。
2026-09-12 14:54:49 +08:00
k88936
2bfc870854
复用分离流程已选批次节点
...
让批次校验和应用使用同一份已选节点,避免重复选择造成目标漂移。
2026-09-12 14:54:05 +08:00