Commit Graph

235 Commits

Author SHA1 Message Date
lhk229 9aa6f5efea 解决platform-llm和策划agent reasoning问题,并修复若干bug (#350)
Project CI / AI game creator shell Rust shard 1/4 (push) Successful in 4m44s
Project CI / AI game creator shell Rust shard 2/4 (push) Successful in 5m9s
Project CI / AI game creator shell Rust shard 3/4 (push) Successful in 4m33s
Project CI / AI game creator shell Rust smoke (push) Successful in 1m50s
Project CI / AI game creator shell Rust shard 4/4 (push) Successful in 3m53s
Project CI / AI game creator shell Rust crates (push) Successful in 2m51s
Project CI / Frontend tests (push) Successful in 4m58s
Project CI / Repository checks (push) Successful in 3m18s
Project CI / Native shell tests (push) Successful in 6m10s
Project CI / Backend tests (push) Successful in 7m7s
Project CI / AI game creator shell web tests (push) Successful in 2m16s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (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 / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Reviewed-on: #350
2026-09-15 00:50:36 +08:00
suzmii d0b15dbc54 AGC 生成任务侧栏:收起也补上退场动画,退场期间内容不跳
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 2m52s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 2m58s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 2m59s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 3m2s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 1m40s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 3m2s
Project CI / Native shell tests (pull_request) Failing after 6m29s
Project CI / Repository checks (pull_request) Failing after 4m3s
Project CI / Backend tests (pull_request) Successful in 9m6s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m13s
Project CI / Frontend tests (pull_request) Has been cancelled
- 进场本来就有动画(`…-enter`),收起却是瞬间卸载,观感上"闪一下没了"。现在收起先播退场再卸载:`open` 变 false 后进入 `leaving`,根节点挂 `is-leaving` 播 `…-leave`(与进场同向反向,160ms,`pointer-events: none`),播完才卸载
- 时长在组件与 CSS 两处各写一次,组件导出 `RESOURCE_CANVAS_ASSET_GENERATION_TASKS_LEAVE_MILLIS` 并由用例钉住两处一致
- 减动效偏好下 CSS 已关掉动画,组件那边同步按 0ms 处理,收起立即卸载,不白等 160ms
- 退场期间沿用收起前那一份列表(`lastRenderedRef`):宿主会在同一帧里收起侧栏并把在途任务收口,直接吃新 props 会让退场动画里的内容跳一下;滚动区的空态分支也改读这份冻结快照,不能读实时 `ordered`(这是本批调试时用假时钟用例抓到的真问题)
- 用例:面板用例新增「收起时先播完收起动画再卸载,动画期间列表内容不跳」;样式用例新增「is-leaving 挂上收起动画、pointer-events: none、减动效同样关掉」;既有生成任务相关性用例改为等退场动画走完再断言(新增 `waitForTasksSidebarLeaveAnimationToFinish`)
- 文档:AGC 入口矩阵与 decision-log 同步退场动画口径

验证:tsc --noEmit 通过;appSurface 全量 441 条通过;侧栏面板 9 条、样式 10 条、开合与入口 3 条通过;变异验证:把早返回改回「立即卸载」与把 CSS 的 `is-leaving` 选择器写错,对应断言分别变红
2026-09-14 23:01:35 +08:00
suzmii 96971403ee AGC 资源画布:定位到素材后把视口居中到该卡
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 2m38s
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (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 / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
- 根因:`handleResourceSelect` 只改选中、不移动画布,而这张画布是 transform 平移的、资源卡不在任何滚动容器里;既有的 `card.scrollIntoView()` 碰不到滚动祖先,卡在视口外时用户看到的就是「定位过去了但依然见不到素材」
- 新增 `centerResourceCanvasOnResource`:读该卡在当前布局位置表里的 x/y 与卡片尺寸,按 `canvasSize / 2 − 卡中心 × scale` 求视口平移量;缩放保持不变(定位不改用户缩放预期,与 `ensureResourceBookContentVisible` 同口径)
- 聚焦链在「选中新资源」那一步之后调用它;`scrollIntoView` 保留(栏目页仍有带滚动条的祖先)
- 用例:新增「centers the canvas viewport on the located asset so it is actually visible」,用渲染进 DOM 的真实画布尺寸断言 `viewportX + 卡中心 × scale = 画布中心`
- 文档:decision-log 补「失去焦点即收起」与「定位必须让素材真的可见」两条决策;AGC 入口矩阵同步自动收起、入口顺序与定位居中口径

验证:tsc --noEmit 通过;appSurface 全量 441 条通过;变异验证:把定位链里的居中调用摘掉,新用例变红(450 vs 400,正好是画布宽 800 的一半与旧视口之差)
2026-09-14 22:36:32 +08:00
suzmii 96ae3db1df AGC 资源工作台三处交互收口:侧栏关闭入口合并、删除折叠把手、播放左对齐
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Failing after 2m14s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Failing after 2m9s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Failing after 2m53s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Failing after 2m46s
Project CI / AI game creator shell Rust smoke (pull_request) Failing after 1m53s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m5s
Project CI / Frontend tests (pull_request) Successful in 4m28s
Project CI / Native shell tests (pull_request) Failing after 4m57s
Project CI / Repository checks (pull_request) Successful in 3m30s
Project CI / Backend tests (pull_request) Successful in 7m19s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m21s
- 「生成任务」侧栏头部右上角由返回箭头(ChevronLeft / aria-label=收起生成任务)改为关闭 X,并与底部那枚重复的 X 统一为同一个 aria-label=关闭生成任务
- 删除「生成任务」侧栏底部 footer(关闭按钮 + border-top 分割线):关闭入口只留头部一枚
- 删除「生成任务」侧栏折叠态的左侧贴边竖排把手(handle 及其标签 / 在途角标 / 进场动画 / 悬停位移):折叠后组件不再渲染任何常驻入口
- 清理上述删除留下的悬空样式:focus-visible 分组选择器、480px 窄屏媒体查询与 prefers-reduced-motion 块里的把手分支
- 工具条「生成任务」入口移出 `mode === 'resources'` 分支:两个页签下都常驻。侧栏本体本来就是无条件渲染的浮层,运行态可见;入口只留资源页签时,切到运行关掉侧栏就再也打不开(此前靠左侧贴边把手兼作运行态入口)
- 工具条把「播放」移到「资源管理 / 运行」右侧并左对齐:新增 .game-workbench-view-tabs 作为左侧控件组,播放按钮由 absolute + left:50% + translateX(-50%) 的居中悬浮改为 static;相应删除 max-width:1000px 里的居中兜底规则
- 播放按钮并进按钮基础外观与 focus-visible 规则列表:新位置不再命中 .game-workbench-tabs / .game-workbench-view-actions 的选择器,漏掉会掉成零圆角、零内边距、无边框、默认字号的裸按钮(颜色规则仍生效,肉眼容易漏)
- 播放按钮保持两个页签下都常驻(回到改动前的可见性):运行视图空态与预览失败态要靠它重跑
- 同步更新断言:侧栏关闭入口唯一且 footer 不存在、折叠态不渲染任何按钮或把手、样式表不残留被删类名、播放按钮声明为左对齐静态定位且仍在基础外观/焦点环规则内
- 生成任务用例补回机器证据:折叠后工具条按钮的 data-resource-generation-task-count 归零、重开后头部「在途生成任务 0」徽标跟上收口结果、运行页签下侧栏仍能重开(先用 aria-selected 钉住真的切了页签);用例夹具新增 runnable 开关把首个原型标成完成
- 同步文档现状:PRD 顶部播放按钮与任务侧栏进度面两条、AGC 栏目画布底部工具栏入口矩阵的侧栏形态、decision-log 的进度面形态决策

验证:tsc -p apps/ai-game-creator-shell/tsconfig.json --noEmit 通过;vitest appSurface 全量 440 条通过、生成任务侧栏 8 条与侧栏样式 9 条通过;check-encoding 通过;prettier --list-different 未新增命中(project-development/index.tsx 属基线既有非格式化文件);变异验证:还原播放按钮基础外观规则、还原折叠把手与 footer、还原折叠态早返回、把「生成任务」入口退回 mode 分支,对应断言均变红
2026-09-14 22:00:06 +08:00
suzmii aeac6c7b74 合并 origin/master(279a5e8e0,#356 UI 编辑器返回后资源画布平移)到验收批次
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 4m55s
Project CI / AI game creator shell Rust smoke (pull_request) Successful in 1m32s
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Successful in 4m43s
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Successful in 4m38s
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Successful in 4m15s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 2m3s
Project CI / Frontend tests (pull_request) Successful in 3m56s
Project CI / Repository checks (pull_request) Successful in 3m28s
Project CI / Native shell tests (pull_request) Successful in 6m19s
Project CI / Backend tests (pull_request) Successful in 7m32s
Project CI / AI game creator shell web tests (pull_request) Successful in 3m0s
- 合并最新 master,使 PR #358 的头包含当前 master 顶端(CI 门禁要求)
- 冲突按「两侧语义都保住」解:
  - docs/project-memory/shared-memory/pitfalls.md:保留我方新增的「严格 IPC 桩缺登记新命令」
    与上游新增的「UI 编辑器返回后资源画布滚轮平移失效」两条,只删除冲突标记行
  - index.tsx / tests/appSurface/harness.ts / project-development.suite.ts:保留本批生成任务与
    资源画布改动,同时并入上游的资源画布平移回归用例与共享 ResizeObserver 桩
- 工作树里另有 5 个版本号改动(package.json / Cargo.toml / Cargo.lock / tauri.conf.json /
  package-lock.json,0.1.29 → 0.1.34)属发布动作,**本次刻意未提交**,原样留在工作树
2026-09-14 20:27:05 +08:00
k88936 174b6dd347 抽取共享 ResizeObserver 测试桩
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Successful in 4m59s
Project CI / AI game creator shell Rust crates (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 / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
让项目开发测试复用统一 observer 安装 helper

保留 observer 创建与断开计数断言
2026-09-14 19:24:23 +08:00
k88936 a8aacb27bd 修正资源画布回归测试 IPC 桩
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (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 / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
使用 manifest projectId 匹配真实布局读取契约

补充初始化布局更新命令回执
2026-09-14 18:53:52 +08:00
suzmii e6d92b2d98 Merge branch 'feat/agc-generation-task-progress' into fix/agc-canvas-acceptance-batch 2026-09-14 18:50:00 +08:00
suzmii ec02c39a5d feat(agc): 「生成任务」改造成常驻画布的可折叠侧栏(分栏 / 计数 / 自动展开 / 折叠不影响任务)
- ResourceCanvasAssetGenerationTasksPanelView 由非模态浮层改造成任务侧栏:展开时是贴边
  `<aside>`(`role="region"`、`aria-label="生成任务"`、不铺遮罩、不做焦点陷阱、不进模态遮挡判据),
  折叠时只留一个可点的贴边把手(`aria-label="展开生成任务"`)并带在途数量角标
- 位置取舍:右侧是「智能创作」对话面板、底部是栏目工具栏、顶部是栏目标题栏,所以挂在**左侧、标题栏
  之下、工具栏之上**(`top-16 / bottom-24 / left-3 / w-[300px]`)且是**覆盖式**而不是把画布挤窄——
  画布视口数学与资源卡排布都不被 reflow 动到,收起即完全让出画布;不再保留原来的浮层形态,没有平行入口
- 两个分栏:「排队/生成中」与「已完成」各带条数,只做客户端分组;「已完成」条数封顶 20 条(超出给出
  还剩多少条的说明),列表自身 `overflow-y-auto`,侧栏高度有界
- 入口按钮常驻可见并显示在途数量(`生成任务 · N`,无在途时仍是「生成任务」,`aria-label="生成任务"` 保留),
  把手上的角标同步;提交受理后侧栏自动展开(对齐网页端排队提交后主动弹任务栏)
- index.tsx:新增在途数量派生;侧栏常驻渲染并受同一个开合开关控制,折叠只影响这个视图,
  任务本身仍活在账本与本地队列里
- 测试:任务侧栏用例改为侧栏形态并补「两个分栏 + 条数」「高度有界 + 列表滚动 + 已完成封顶 20」
  「折叠后把手带上在途计数(0 / 2)」;AppSurface 补「提交后自动展开」「折叠期间任务照常推进、
  在途计数归零、再展开仍能看到结果」
2026-09-14 18:49:22 +08:00
suzmii 14a0286f70 fix(agc): 生成面板点击即关闭、面板内不再出现阶段文案,只有即时失败才把草稿带回来
- ResourceCanvasAssetGenerationPanelView:删掉 `phaseDetail` 通道与整套在途状态(`submitting` /
  禁用输入 / 「后台运行并关闭」),主按钮文案恒为动作名;提交时**同步**调用 onSubmit 并 onClose,
  面板不等 IPC、不等排队、不等生成。新增 `draft` / `error` 两个入参:只有「后端从未受理」的即时
  失败重开时,宿主才把草稿与原因带回来(`role="alert"` 可见、改完即可重试)
- index.tsx:`submitResourceAssetGeneration` 改为同步返回(不再 await 终局),记录本次提交上下文
  (taskId / action / 草稿 / 是否本来就该立刻派发),提交后自动开任务面板并给一次提示条;
  收尾回调里区分两类失败:`record === null` 且本来就该立刻派发 → 重开提交面板并带回草稿;
  受理之后才失败 → 不重开面板,只在任务面板收口为失败 + 提示条
- index.tsx:删掉只为旧「在途阶段文案」服务的 `resourceAssetGenerationPanelTaskIdRef` 与成功后的
  自动收面板逻辑(面板此时已关闭)
- 测试:`resourceCanvasAssetGenerationBackgroundClose.test.tsx` 的图片类用例改写为「点击即关闭 +
  面板 DOM 里从不出现 排队中。/正在生成。/提交中…」+「即时失败重开带回草稿与原因」;音频面板用例不变
- 测试:`resourceCanvasBottomToolbar.test.tsx` 的失败重试用例按新语义改写(点击即关闭、重开时显示原因)
- 测试:AppSurface 新增三条(同步关闭且面板无阶段文案、后端未受理时重开并保留草稿、受理后失败不重开
  只在任务面板收口),并把既有生成任务 e2e 的提交步骤改为「点击即关闭」
- 顺带按仓库规范修正以上文件的 eslint import sort 与 prettier 格式(未触碰无关文件)
2026-09-14 18:35:11 +08:00
k88936 c485ce94a1 修复 UI 编辑器返回后资源画布平移
Project CI / AI game creator shell Rust shard 1/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 2/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 3/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust shard 4/4 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust smoke (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (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 / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
资源管理卸载重挂时重新绑定画布 wheel 监听

补充 UI 编辑器返回后的资源画布平移回归用例

记录资源画布事件监听重挂排障经验
2026-09-14 18:30:33 +08:00
suzmii 2f47540eeb fix(agc): 「定位到素材」每次点击都终局化,不再卡在「正在定位生成的素材…」
- index.tsx 新增 `resourceAssetGenerationFocusRequest` 序号并加进聚焦 effect 的依赖:手动点定位不改画布
  任何状态,原依赖一个都不变 → effect 不重跑、intent 永远没人消费,这正是「点了没反应 + 提示条永久
  停在中转文案」的根因
- index.tsx `focusResourceAssetGenerationTask` 重写:先按当前投影与清单判一次目标——不在投影里就当场给
  结论(素材已不在项目里 / 已登记但尚未同步),不挂 intent 也不留中转提示;在别的栏目先切栏目再定位;
  挂 intent 后推进聚焦请求序号,并起一个 3 秒有界兜底:仍停在中转文案就收口成可执行提示,intent 被判
  invalid 被静默清掉时也给一条「定位请求已失效」的结论,绝不留下悬而未决的状态
- index.tsx 聚焦 effect 的 `focusedCommitIdsRef` 提前返回分支补 `setResourceWorkbenchNotice('')`:
  已聚焦过时把中转提示一并收掉,不再永久留在提示条上(自动落卡那条链同源问题)
- index.tsx `resourceAssetGenerationContextRef` 扩到带 `manifest` / `resources` / `activePageCategory`
  并在每次渲染刷新:定位回调据此取权威目标与栏目,不再依赖可能过期的闭包值
- 新增 4 条 AppSurface 用例(同栏目直点定位并选中卡片、素材在另一个栏目先切栏目再定位、被搜索挡住时给出
  既有「清除搜索并定位」、素材不在项目里时给明确结论且清掉中转提示)
2026-09-14 18:20:50 +08:00
suzmii 7240b3793f Merge branch 'feat/agc-generation-task-progress' into fix/agc-canvas-acceptance-batch 2026-09-14 17:50:40 +08:00
suzmii 4fff733516 fix(agc): 生成任务账本读不到时不再抛未处理拒绝,改为保留本地状态并给出提示
- resourceCanvasAssetGenerationTaskModel.applyLocalProjectAssetGenerationRecords:入参在函数入口归一化,
  非数组(undefined / null / 字符串 / 数字 / 对象)一律按「没有后端记录」处理,数组内的垃圾条目
  (null / 数字 / 缺 taskId)逐条丢弃;类型放宽为 `readonly …[] | null | undefined`
- resourceCanvasAssetGenerationQueue:轮询 `list_local_project_asset_generations` 的 IPC 拒绝与非数组
  返回值都在本地接住,按「本轮读不到」计数;到上限后按「账本不可用」与「账本里没有这条」两种原因分别收口;
  派发循环再补两道兜底(dispatch 意外抛出、宿主 onSettled 抛出),保证 `void (async …)()` 不产生未处理拒绝、
  也不会把任务永远卡在「已派发但未终态」
- index.tsx 恢复任务账本的 effect:IPC 拒绝与返回非数组都落到既有提示条
  「生成任务列表读取失败,暂时无法恢复历史任务」,本地任务列表保持原样不清空
- 测试:模型层补「undefined / 非数组 / 垃圾条目不抛错且列表不变」,驱动器层补
  「轮询返回 undefined」「轮询 IPC reject」两条(收口原因、不产生未处理拒绝、后续排队任务照常补发)
- AppSurface 补两条:账本返回 undefined / 读取被拒绝时视图照常渲染、生成入口还在、提示可见
- AppSurface 既有的「布局读时提示」用例显式登记 `list_local_project_asset_generations` 返回空账本:
  该命令是只读的独立链路,严格桩把它判成 unexpected invoke 会让新提示混进「没有任何提示」的断言
2026-09-14 17:47:03 +08:00
suzmii 6b5f67d207 Merge branch 'feat/agc-generation-task-progress' into fix/agc-canvas-acceptance-batch 2026-09-14 17:31:32 +08:00
suzmii bb7cbae118 feat(agc): 图片类生成后台化,生成面板可随时关闭并新增「生成任务」进度面板
- Rust 新增 asset_generation_tasks.rs:图片类生成拆成「提交即返回任务记录 + 后台 spawn 生成」,
  生成本身仍转调既有 generate_platform_art_asset_with_options_at(不复制生成 / 幂等 / 登记逻辑)
- 任务账本落项目内 .agent/runtime/asset-generation-tasks/tasks.json(复用 agent runtime sidecar 原语),
  阶段文案 phaseDetail 由后端拥有,读取时把上次运行留下的非终态记录收口为「中断失败」,账本上限 50 条
- Rust 新增 IPC start_local_project_asset_generation / list_local_project_asset_generations 并在 main.rs 注册;
  同步命令 generate_local_project_asset 保留不动
- 新增前端纯模型 resourceCanvasAssetGenerationTaskModel.ts:任务状态机、在途判据、账本恢复、耗时文案
- 新增 resourceCanvasAssetGenerationQueue.ts:本地排队驱动器,第二条不发提交 IPC、前一条终态后自动补发,
  状态与阶段一律以后端账本为准,账本查不到该任务时按上限停止等待
- 两块生成浮层在提交期间放开 × / 遮罩 / Esc,次按钮在途时改为「后台运行并关闭」(关闭不等于取消请求),
  图片类面板的在途文案改为渲染后端 phaseDetail
- 新增非模态「生成任务」面板(不铺遮罩 / 不做焦点陷阱 / 不进模态遮挡判据),显示状态、后端阶段、
  已耗时与素材名,已完成条目复用 pendingResourceFocusRef 聚焦链定位素材卡
- index.tsx 宿主接线:任务列表状态与 ref、提交回调不再读面板状态、按项目恢复任务账本、
  工具栏「生成任务」入口按钮与面板渲染点
- check-config.mjs:把已无前端调用方的同步命令 generate_local_project_asset 登记进 native-only 白名单
- 测试:新增「生成面板提交期间可关闭」「本地排队驱动器」「生成任务面板」三组用例;
  appSurface 生成载荷断言改为 start_local_project_asset_generation + list 轮询桩
- 文档:入口矩阵补 §4a 与验证命令、V3 验收 S11a 判据、decision-log 记录本次决策
2026-09-14 17:26:36 +08:00
suzmii 7ce4a3a9c6 把素材类型从「编辑素材标签」面板拆成独立入口
- 新增 ResourceTypePanel(src/view/project-development/ResourceTypePanel.tsx):类型选一项即落盘,category 传用户选中值、tags 逐字回传落盘原值,保存在飞时沿用 closeOnBackdrop/closeOnEscape = !saving
- 新增 resourceAssetDisplayName.ts:两块面板共用同一个素材名副标题口径(localPath basename),不再各写一份
- 新增 resourceTypePanel.css:类型面板的弹窗骨架与信息浮层「分类」行入口样式,按 AGC 内独立文件约定,不动 packages/** 与 styles.css
- ResourceClassificationPanel 删掉类型 chip 与 categoryChoice:保存时恒回传 gameCreationAppAssetPersistedCategory(asset),「只改标签不动分类」由结构保证
- index.tsx 新增 resourceTypeAssetId 与 resourceTypeAsset;工具条在「编辑标签」旁新增「素材类型」按钮(Shapes 图标)
- index.tsx 用合并后的 resourceClassificationOverlayOpen 纳入点外部/Esc 浮层遮挡判据,并同步 useEffect 依赖项
- index.tsx 渲染新面板:保存成功后由宿主收起面板并沿用 manifest 重载路径,让卡片立刻落到新栏目
- 信息浮层「分类」行接出第二入口:按钮渲染在 dd 之外,不污染 dt/dd 字段读取口径;非 manifest 资产不给入口
- resourceCanvasInfoModel 导出 RESOURCE_INFO_CATEGORY_FIELD_LABEL,模型与入口共用同一行标识
- 新增 tests/resourceTypePanel.test.tsx:选中即落盘、tags 逐字回传、没碰过不写盘、显式待归类、失败回退、saving 锁、Esc/遮罩、面板骨架共 11 条
- 迁移「没碰过分类就回传落盘原值」对照用例并保留两条(标签面板侧),chip 用例搬到新面板文件
- 集成用例改走新入口:选中即落盘并自动关窗,另补 Esc/点外部不串台、只改标签后 manifest category 逐字不变两条宿主级用例
- appSurface 工具条清单补上「素材类型」
2026-09-14 17:07:15 +08:00
kdletters 7092689b36 收口 AGC 生命周期超时隔离与建项恢复
Project CI / Repository checks (push) Successful in 3m11s
Project CI / Frontend tests (push) Successful in 4m4s
Project CI / Backend tests (push) Successful in 6m14s
Project CI / Native shell tests (push) Failing after 14m20s
## 变更内容

在 master(0f829cd25)上用故障注入复现出四类"每走一步都会卡住"的生命周期残留,本轮按"超时后真正隔离并核对底层操作"收口,不再新增 operation 字段:

- 本地会话写入队列从"无限等上一次完成"改为带解围期限的闸门(60s)。Rust 侧 install/clear 本来就按 generation 单调拒绝更旧写入,所以渲染层只需保证新 generation 不被卡死的调用永久挡住;
- generation floor 读取不再把一次瞬时失败缓存成永久失败(原先 `??=` 缓存了已 reject 的 promise,导致同一渲染进程内后续登录/退出全部失败);
- 登录 UI 的 45 秒围栏只放弃等待、不放弃结果:本地运行时确实装好会话时界面跟随进入工作区,且迟到结果不会覆盖更新的登录尝试;
- 首页自动建项从 `deadlineMs: null` 改为 10 分钟兜底期限:到点解围并提示(底层创建继续在后台跑,迟到成功照常进项目),失败时保留 `scope.projectPath`、登记最近项目并新增「打开已创建的工作区」入口;底层创建未返回期间只挡"再建一个",不挡打开已有项目;
- 同步 `project.bootstrap` 权限文案断言、生命周期技术方案状态与 shared pitfalls。

## 验证

- `npm --prefix apps/ai-game-creator-shell run typecheck`(含 skill-pack、check-config)
- `vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts`(428/428,含新增 5 个故障注入回归;`project.bootstrap` 文案断言在此前 master 上确定性失败)
- 定向 `clientHttp`、`clientApi`、`clientOperation`、`recentProjectsModel`、`clientRuntimeErrorBoundary`、`sessionPreview`、`start-dev-stack`、`dev-port`、`start-tauri-dev`(全部通过)
- `npm run check:doc-index`、`npm run check:encoding`、`git diff --check`

原生 Runner/IPC 与真实 Provider 下的同一批时序未执行,本轮结论来自 deterministic surface 与 mock 故障注入。

Co-authored-by: DotCraft <273930855+dotcraft-ai@users.noreply.github.com>
2026-09-14 14:49:45 +08:00
kdletters 991b2a1104 修复 AGC 异步操作恢复闭环 (#346)
Project CI / Repository checks (push) Successful in 3m43s
Project CI / Frontend tests (push) Successful in 3m54s
Project CI / Backend tests (push) Successful in 6m16s
Project CI / Native shell tests (push) Successful in 20m0s
## 变更内容

AGC 登录、Runner 会话、最近项目检查和首页自动创建原先各自维护异步状态,响应体卡住、单目录变慢或切页会导致按钮长期 busy、项目列表整体不可用或重复创建项目。本 PR 将这些入口收口到可恢复的生命周期边界:

- 认证响应体读取增加独立超时,refresh singleflight 在失败后释放;
- Runner 会话安装/清除移到 blocking worker,登录/退出增加 45 秒 UI fence;
- 最近项目逐项检查并设置单项目超时,已完成行不受其它慢目录阻塞;
- 首页自动创建锁提升到 WorkspaceLauncher,切页后仍防重并保留状态;
- 新增异步闭环技术方案、body 卡住测试、逐行项目测试和跨页创建测试。

## 验证

- `npm --prefix apps/ai-game-creator-shell run typecheck`
- `npm --prefix apps/ai-game-creator-shell exec -- vitest run tests/clientHttp.test.ts tests/clientApi.test.ts tests/recentProjectsModel.test.ts --reporter=dot`
- `npm --prefix apps/ai-game-creator-shell exec -- vitest run tests/appSurface.test.ts --reporter=dot`
- `cargo check --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml`
- `npm run check:doc-index`
- `npm run check:encoding`
- `git diff --check`

`appSurface.test.ts` 390/390 通过;保留仓库既有 act/jsdom media warning。本 PR 未触发真实 Provider 或发布安装包。

Reviewed-on: #346
Co-authored-by: kdletters <kdletters@qq.com>
Co-committed-by: kdletters <kdletters@qq.com>
2026-09-14 13:19:13 +08:00
lhk229 340d8241a5 优化策划agent (#340)
Project CI / Repository checks (push) Successful in 2m53s
Project CI / Frontend tests (push) Successful in 3m55s
Project CI / Backend tests (push) Successful in 6m50s
Project CI / Native shell tests (push) Successful in 17m42s
Reviewed-on: https://git.genarrative.world/git/GenarrativeAI/Genarrative/pulls/340
Co-authored-by: Linghong <ink29535@proton.me>
Co-committed-by: Linghong <ink29535@proton.me>
2026-09-13 19:32:12 +08:00
suzmii 7ae71441ba 合并 master:接入 AGC 内置插件宿主与 Cocos 编辑器能力(#338)
Project CI / Repository checks (pull_request) Successful in 2m49s
Project CI / Frontend tests (pull_request) Successful in 3m46s
Project CI / Backend tests (pull_request) Successful in 6m42s
Project CI / Native shell tests (pull_request) Successful in 17m35s
合并 origin/master 4a46f89c9 到 chore/agc-acceptance-build(HEAD 55fab1776),本次合并共涉及 117 个文件(113 个自动合并 + 4 个冲突)。

- 自动合并 113 个文件:插件宿主与插件工作区(plugin_host.rs / builtin_plugins.rs / editor_adapter(_s).rs / plugins/agc-cocos-editor / cocos-editor-bridge crate / editor-adapter-api)、构建与打包脚本、locked Cargo.lock 及 master 侧锁与资源链路改动;不逐条列出。
- 冲突 1 apps/ai-game-creator-shell/src/App.tsx:271-278:两侧各自新增一个 import(本分支 ./services/tauriEventSubscription、master ./services/pluginHost),两个 import 都保留,并按 simple-import-sort 口径排在 ./services/platformSession 之后、tauriEventSubscription 之前;四个符号都仍被使用。
- 冲突 2 docs/project-memory/shared-memory/decision-log.md:8338-8469:两侧在同一位置追加记录,逐字保留两侧记录且各自原有顺序不变(先本分支的 2026-09-11 资源卡预览 data URL / loopback HTTP 两条,后 master 的 2026-09-09~2026-09-12 通用插件宿主、Cocos 桥接与内置插件开关条目),不改写、不合并措辞。
- 冲突 3 docs/project-memory/shared-memory/pitfalls.md:79-112:同上,保留本分支的「2026-09-05 资源画本转场与视口分离」与 master 的「2026-09-11 首页自动工作区必须使用 AGC 管理目录」「2026-09-12 Cocos 项目识别不等于编辑器桥就绪」「2026-09-11 Cocos 项目必须走独立导入分支」,内容逐字保留、两侧原顺序不变。
- 冲突 4 apps/ai-game-creator-shell/src-tauri/src/agent/direct_project_history.rs:400-435:判据是「两侧不互斥」,解法为 both(语义超集)。
- 冲突 4 保留本分支的有界退避重试循环(DIRECT_PROJECT_HISTORY_CONTENTION_RETRY_BACKOFF_MS + is_direct_project_history_contention_failure + 测试注入点)与单次尝试函数 append_direct_project_history_item_once(含锁外幂等回扫与锁内状态复核)。
- 冲突 4 保留 master 的有界等待取项目写锁:把该函数内原来的零等待 crate::project::acquire_project_write_lock(root, "conversation.write") 换成 acquire_game_creator_agent_runtime_project_write_lock_with_wait(root, "conversation.write"),并原样保留 master 的注释(agc_write_file 占锁 5.5 秒期间,零等待取锁会让流式历史落盘直接失败)。
- 冲突 4 判断依据:master 只替换了同一处的取锁语义(零等待 → 约 10 秒有界等待,并有 append_waits_for_a_same_process_project_writer 用例锁定),不改变函数签名、调用方与错误类型;HEAD 的重试循环因此仍然可达,与有界等待叠加后语义更强——写文件占锁由有界等待吃掉,等待窗口耗尽后的残余争用再由一次 250ms 短退避重试兜底。未删除任何一侧行为,也未放弃任何一侧语义。
- 冲突 4 位置取舍:有界等待取锁仍放在锁外回扫与序列化之后(本分支结构),保住「幂等回扫与序列化留在锁外、不让他人等整份历史读完」的性能语义;master 的注释与调用参数逐字保留。
- 验证:npm run typecheck、npm --prefix apps/ai-game-creator-shell run typecheck、cargo check --locked --all-targets(exit 0,0 error)、npm run check:rustfmt、npm run check:encoding、git diff --check 全部通过;冲突标记扫描为空。
- 定向 Rust 测试(--test-threads=1):direct_project_history 19 passed / 0 failed(含本分支 contention_failure_is_retried_with_bounded_backoff、contention_failure_beyond_the_backoff_budget_fails_closed、shape_failure_is_not_retried 与 master 的 append_waits_for_a_same_process_project_writer);conversation 36 passed / 0 failed;write_lock 21 passed / 0 failed。两侧用例同时绿,证明有界等待取锁与有界退避重试叠加后语义自洽。
- 未跑全量测试(按仓库约定本地只跑定向,全量交给 CI);本次不 push。
2026-09-13 15:33:48 +08:00
kdletters 4a46f89c9b 接入 AGC 内置插件宿主并补齐 Cocos 编辑器能力 (#338)
Project CI / Repository checks (push) Successful in 2m45s
Project CI / Frontend tests (push) Successful in 3m27s
Project CI / Backend tests (push) Successful in 6m18s
Project CI / Native shell tests (push) Failing after 13m52s
客户端新增随包提供的插件宿主和 Cocos Creator 集成:识别并导入 Cocos 项目,通过内置桥接操作已打开的编辑器,无需安装项目 MCP 扩展。DirectProject 现在公开 36 个独立 cocos_* 工具,保留通用 JavaScript 执行入口。

- 通用插件 SDK、命令/能力/面板注册、编辑器适配器和跨进程内置插件开关。
- Cocos 场景、节点、组件、Prefab、UI、Layout/Widget、资源、保存、撤销、日志与预览调试;目录和实现由 JS/native 共用。
- 编辑事务回读、失败回滚、后续手动修改保护及不确定结果禁止重放;预览截图通过 MCP image 返回。
- DirectProject 跳过无关专业 Agent 历史,将项目打开和历史读取中的同步 I/O 移出窗口线程,消除 Cocos 执行与项目文件锁的错误耦合。

验证:
- 合并 master 后:类型/配置检查、编码检查、Rust 格式检查和提交钩子通过。
- 合并 master 后:Cocos 项目打开、插件面板和开发启动定向测试 10 通过、2 跳过;DirectProject MCP 测试 17 通过、1 项真实 Creator opt-in 忽略;插件宿主测试 9/9。
- 插件行为测试 17/17;native 测试 20/20,4 项 opt-in 测试默认忽略。
- 真实 Creator 3.8.8 的 36/36 操作 smoke,以及客户端 MCP tools/list、tools/call、UI/撤销和预览截图,在功能实现阶段已验证通过;本次 master 合并后未重复真实 GUI smoke。

验证边界:发行安装包和远端 CI 尚未验收。

Reviewed-on: #338
Co-authored-by: kdletters <kdletters@qq.com>
Co-committed-by: kdletters <kdletters@qq.com>
2026-09-13 14:48:55 +08:00
suzmii 55fab1776a AGC 画布验收问题修复与栏目画布底部工具栏
Project CI / Repository checks (pull_request) Successful in 2m55s
Project CI / Frontend tests (pull_request) Successful in 3m59s
Project CI / Backend tests (pull_request) Successful in 6m50s
Project CI / Native shell tests (pull_request) Failing after 14m3s
- 合并资源画布命名筛选与条件筛选为单一筛选浮层,Dock 只留放大镜入口
- 修复「编辑素材标签」面板标签多时不可见且不可滚:加高度上界与标签区独立滚动
- 替换素材新增点选替换模式,并在资源卡标注会话内替换血缘
- 新增栏目画布底部工具栏,按功能画布分流图片类生成、音频生成与上传入口
- 新增 Tauri IPC generate_local_project_asset,收口图片类无源生成的 kind 与提示词目录
- 同步 PRD、AGC 验收用例、决策日志、踩坑记录与待解决事项文档
2026-09-13 14:07:03 +08:00
suzmii d04fe83f10 修复 PR #316 review(前端 TS/TSX):@ 引用与提示词润色主链路
- App.tsx:`conversation.write` 策略确认后的重跑改为整体复用首轮入参(`directCodexPolicyRetryInput`),不再手写字段,修掉漏传 `references` 导致 @ 引用被静默丢弃的缺陷
- resourceReferences.ts:运行画面引用的判别指纹补上 `resourceIds`(排序集合口径)/`versionId`/`elementRole`/`width`/`height`,避免不同选点撞 key 被 `dedupeChatReferences` 去重丢掉
- ResourceReferenceInput.tsx:程序化重建编辑器内容改为把 chip 内联嵌在文本里的同名 token 位置(不再另起一段堆在末尾),并把 `lastEmittedDraftRef` 记为「编辑器实际读回来的草稿」而不是 props,消除每轮多一段 `@显示名` 的渲染循环
- ResourceReferenceInput.tsx:候选浮层(候选菜单 / 素材选择器)打开时 Enter 不再提交表单,把按键让给 `LexicalTypeaheadMenuPlugin`
- ResourceReferenceInput.tsx:`assets` / `currentVersionAssetReferences` 的 memo 依赖改用内容签名;预览请求在换素材 / 卸载时主动作废上一个 scope;空态文案的嵌套三元抽成 `pickerEmptyMessage`
- usePromptPolish.ts:`polish()` 补 `catch`,注入式 `requestPolish` 拒绝时给出可见失败提示而不是未处理拒绝;`reset()` 递增请求代次作废在飞请求
- ChatPromptPolishReminder.tsx:章节级 Esc 分支补 `busy` 判据,与关闭按钮 / 遮罩同一口径(在飞不许关面板)
- LocalGamePreviewFrame.tsx:资源 id 改用专用净化(允许 `:` 与可打印非 ASCII),修掉 `local-asset:<id>`、`persisted-角色草图.png` 被整条过滤导致引用丢素材关联
- sessionPreview.ts:`get_local_game_preview_status` 读失败不再当作「确认没有在跑」去发停止命令,避免停掉真在跑的活体预览
- useHomeProjectCreation.ts:进项目流程加代次令牌,慢请求后到不再覆盖新项目
- WorkspaceLauncher.tsx:拒收恢复的阶段回写按 `projectId`/`heldRevision`/`snapshotRevision` 关联,不再把恢复结果盖到后续新拒收的提示上
- 用例:`directCodexPolicyRetryInput` 透传、引用指纹区分度、重建不循环、浮层打开时 Enter 不提交、润色拒绝 / reset 作废、预览读失败不停预览
2026-09-12 20:48:13 +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
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 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 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 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 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
lhk229 832f1e8b59 修复策划项目重开运行态恢复
Project CI / Repository checks (pull_request) Successful in 2m17s
Project CI / Frontend tests (pull_request) Successful in 3m8s
Project CI / Backend tests (pull_request) Successful in 7m46s
Project CI / Native shell tests (pull_request) Successful in 19m52s
持久化策划项目 design 运行模式并在重开时恢复 design/game 工作台。

补充旧策划会话兼容判断、前端夹具和恢复回归测试。
2026-09-12 06:41:49 +00:00
suzmii 349c9d80ce 修复「所有资源」页面缩放读取错误视口
展开态缩放、滚轮、平移和卡片拖动改读 all 专用内存视口 ref

避免复用普通栏目页视口导致按钮按下后倍率被旧状态覆盖

补充所有资源连续缩放 appSurface 回归断言,并同步更新项目决策与踩坑记录
2026-09-12 12:25:27 +08:00
suzmii 3f7e41e466 「所有资源」展开态改回平铺画布:不再为每个栏目渲染标题栏
Project CI / Repository checks (pull_request) Successful in 2m50s
Project CI / Frontend tests (pull_request) Successful in 3m19s
Project CI / Backend tests (pull_request) Successful in 7m23s
Project CI / Native shell tests (pull_request) Successful in 19m4s
展开态真实栏目不再渲染栏目标题栏,整个场景只留 all 那一条钉在视口上、带「资源总览」收起入口的标题栏

原因是分带只为有可见资源的栏目生成,空栏目拿不到标题栏矩形后全部回落到世界原点叠成一摞(空项目必现,现场是 7 条)

ResourceBookSceneCategoryPlan 新增 titlebar 字段,渲染层按它决定是否产出标题栏节点

分带去掉标题栏横带的高度预留与矩形换算,删除 RESOURCE_BOOK_ALL_BAND_TITLE_HEIGHT 与 resourceBookAllTitlebarRects

拖动写回口径不变(resourceBookAllBandLocalPoint 一行未改),零 CSS 变更

resourceBookLayout.test 与 appSurface 两条「所有资源」用例加反向守卫;变异验证改回旧行为时两条同时红(got 7)

decision-log 与 pitfalls 记这次倒因为「缺一路坐标输入时不要静默回落到原点」
2026-09-12 09:38:03 +08:00
suzmii f11942f357 展开态补回空态提示:复用栏目页同一个 .game-resource-page-empty 与文案,不新增样式
Project CI / Repository checks (pull_request) Failing after 1m18s
Project CI / Frontend tests (pull_request) Successful in 3m29s
Project CI / Backend tests (pull_request) Successful in 6m42s
Project CI / Native shell tests (pull_request) Successful in 17m44s
- index.tsx:展开态在"可见资源为 0"时渲染 <p class="game-resource-page-empty">没有匹配资源</p>,与栏目页那一条同一条判据口径与同一句文案
- 它挂在既有的画布浮层 host 下(该 host 自身不定位),因此按画本场景根居中,观感与栏目页一致,不需要任何新 CSS
- 测试:空项目的「所有资源」用例补三条断言——进入展开态后标题栏是 .is-active[data-resource-book-category="all"]、卡片宿主数为 0、空态文案是「没有匹配资源」(把"复用既有空态、不新增样式"变成可执行判据)
2026-09-11 23:55:36 +08:00
suzmii 9788248d9b 「所有资源」页改走画本场景:与栏目页同一套卡片宿主与几何,并可拖动
- 新增 resourceBookShowsAllCategories:把"子画布里的 all"这一态判定收在 resourceBookModel 一处
- resourceBookCategoryCardPresentation:展开态下真实栏目返回 child(卡片仍由各栏目组承载,每张资源只有一个宿主)、all 自己返回 null(只出标题栏与全量计数)
- 新增纯函数 buildResourceBookAllLayout:按栏目顺序纵向排"分带",用各栏目可见资源的 extent 定带宽高;卡片世界坐标 = 栏目内局部坐标 + 带原点
- 新增 resourceBookAllTitlebarRects:分带 → 栏目标题栏矩形,让展开态复用总览态"按矩形钉标题栏"的同一条渲染路径(ResourceBookScene 不需要知道"展开态"这个概念)
- 新增 resourceBookAllBandLocalPoint:展开态世界坐标 → 栏目内局部坐标,这是落盘前唯一的换算(减带原点)
- buildResourceBookScenePlan:展开态下 all 只出标题栏(钉在视口 + 全量计数),真实栏目按带偏移铺满 child 卡;真实栏目这一支仍按 presentation === child 取卡,"能出卡的判定"只有一处
- buildResourceBookScenePlan:返回总览的淡出改为按"刚离开的那段子画布"判定(exitingCategory 传 all 时覆盖所有栏目),并用带偏移位置淡出,否则返回动画会跳位置
- buildResourceBookScenePlan:「所有资源」组不再接 child / exiting 卡,避免同一张卡在两组里各挂一份(DOM 查询与 FLIP 键撞车)
- index.tsx:删掉独立网格页组件、其 host 块与 resourceBookAllResourcesSections memo,展开态整体交给画本场景
- index.tsx:新增内存态 resourceBookAllViewport(不落盘、不进按真实栏目键的 resourceCanvasViewports),滚轮 / 缩放 / 适应 / 平移 / 框选都作用到它
- index.tsx:分带几何按"项目 + 排序 + 可见资源集"冻结(签名 + ref 短路;签名不含 state.token——返回总览时 token 也会变,含它会在淡出期间重算),拖动不重算带高,避免"拖上面一带让后面所有带整体位移"
- index.tsx:拖动放开——展开态下每张卡都能拖,section 取 resource.category(栏目页仍只拖当前分页栏目)
- index.tsx:提交前用 resourceBookAllBandLocalPoint 把世界坐标减回带原点,写回的仍是同一 mode 同一 sidecar 的同一 section(.agent/workbench/resource-layouts/{dependency,type}.json),没有第二份空间,不改契约与 schema
- index.tsx:renderResourceBookCard 去掉 options.draggable:展开态已可拖,这个"只读"开关没有调用方了
- 测试:resourceBookModel.test 钉住展开态 presentation 与"栏目页仍是原判据";resourceBookLayout.test 退役旧分组函数用例,新增分带几何 / 标题栏矩形 / 减带原点换算 / 展开态计划(含"每张资源只有一个宿主"与按带位置淡出)断言
- 测试:appSurface 两处「所有资源」判据从旧网格宿主改为画本场景(.game-resource-book-scene-card[data-resource-book-category] 与 .is-active[data-resource-book-category="all"]),并断言旧网格容器 / 宿主一个都不再存在
2026-09-11 23:33:08 +08:00
suzmii 28781a420c 补资源总览网格的声明级断言:钉住 width:100% 与 max-width 并存,防止退回单列
- 新增用例「keeps the resource overview grid off fit-content so its columns stay responsive」:断言 .game-resource-book-main-grid 同时声明 width: 100% / max-width: 1120px / margin: 0 auto / repeat(auto-fit …),并同款断言 .game-resource-book-main-heading 的 width: 100%
- 取声明体前先剥掉 CSS 注释:本次修复的注释里就写着 width: 100% 等字样,不剥掉会让断言匹配到注释而假绿(删掉真正的声明也照样通过)
- 注释里写明这条断言**验不到布局**:AGC 的 vitest 没开 css: true、styles.css 不会被加载、jsdom 也没有布局引擎,gridTemplateColumns 的解析结果与缩略卡列数只能在真机量;真机判据(3 个非 0 轨道 / grid 宽 432→1120 / 8 张缩略卡 top 只有 3 个取值,且需在总览态取样)写在用例注释里
- 变异验证:临时删掉 .game-resource-book-main-grid 的 width: 100% → 用例变红且失败信息打印的是真实声明体(证明注释剥离生效);还原后 styles.css 逐字节哈希与已提交版本一致,复跑绿灯
- 门禁:npm run typecheck exit 0;npm run check:encoding exit 0(4399 files);npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts 本用例 1 passed
2026-09-11 22:50:01 +08:00
suzmii b12b0998d0 分类改动不再丢弃已落盘的画布坐标:分区不一致时归并到资源当前分类并保留 x / y
- 原缺陷(3082c3e85 的连带副作用):`kind:"UI"` 的资产投影分类由「待归类」修到「UI 交互」后,它们落盘的坐标 section 仍是现行栏目值 `unclassified`,于是 resolveResourceCanvasSection 走「现行栏目值 != 资源当前分类 ⇒ null」直接判丢弃,8 条用户手摆的坐标没能跟过来、被自动排布重算。
- resourceCanvasSectionMapping.ts:现行栏目值改为返回**资源当前分类**("这张卡属于哪一栏"的唯一真源本来就是 resource.category,协调时也按它分组),与旧栏目归并支路同一条语义 —— 只改写 section,x / y / manuallyPlaced 原样保留。判据:坐标是栏目内局部坐标(reconcileResourceCanvasLayout 先按 section 分组再算栏目带原点),所以换栏目保留 x / y 得到的正是"这张卡在新栏目里的同一个槽位";而"丢弃 + 自动重排"会连 manuallyPlaced 一起抹掉,是用户可见的损失。
- 判断与理由:**保坐标重写 section 可行**。同一函数对更难的旧栏目 case(旧 `art` 可能归并到 4 个不同栏目)已经在做同样的事,对 `unclassified → ui-interaction` 反而更窄;拒绝它是自相矛盾。
- 丢弃口径收窄:resolveResourceCanvasSection 只在**确实无从归并**时返回 null —— 无法识别的分区值,以及旧栏目归并目标集合不含资源当前分类(如旧 `code` 遇到已归为 `document` 的资源)。useProjectResourceCanvasLayout.ts 的 droppedSectionMismatch 文档与读盘统计注释按此更新(用户可见文案未变,它对新口径仍然成立)。
- 断言:resourceCanvasSectionMapping.test.ts 把原「沿用既有行为丢弃该坐标」用例改写为守新契约(归并 + changed=true),并新增 x / y / manuallyPlaced 逐项不变用例;resourceCanvasLayoutModel.test.ts 原「drops a persisted position…」改写为「rewrites … keeping the coordinates」;useProjectResourceCanvasLayout.test.ts 的读盘统计由 normalized 1 / droppedSectionMismatch 1 改为 normalized 2 / droppedSectionMismatch 0,并新增"归并必须连坐标一起保住"的断言,另补一条用例钉住 droppedSectionMismatch 只剩"无从归并"两类来源;appSurface/project-development.suite.ts 的提示文案与 data-* 计数同步,并新增写盘坐标断言。
- 变异验证(提交前已跑):把 resolveResourceCanvasSection 还原成 `section === resourceCategory ? section : null` → 6 条用例变红(映射 2 条、布局模型 1 条、读盘统计 2 条、appSurface 1 条),还原后复跑 83 passed + appSurface 该条 passed。
- 门禁:resourceCanvasSectionMapping 9 passed、resourceCanvasLayoutModel 47 passed、useProjectResourceCanvasLayout 27 passed。
2026-09-11 21:48:43 +08:00
suzmii 4175d82fa1 工具条「引用」不再渲染成「@ @引用」:@ 只留图标,文案去掉重复的 @
- index.tsx 选中工具条的引用按钮:title 由「@引用」改为「引用」,可见文案 <span>@引用</span> 改为 <span>引用</span>。图标 AtSign 本身就是 `@`,文案再写一次就渲染成「@ @引用」。
- label={`引用资源 ${selectedResource.label}`} 保持不变:无障碍名仍要能读出「引用资源 <素材名>」,本次只去掉可见文案与 title 里的 `@`。
- 断言(appSurface/project-development.suite.ts):静态形状用例改判 title="引用" / <span>引用</span>,并新增 not.toContain('@引用') 反向守卫;键盘通路用例改判 title === '引用'、可见标签 .genarrative-image-canvas__chrome-button-label 文本为「引用」,并新增 aria-label === '引用资源 hero.png',钉住无障碍名没有被一起去掉。
- 变异验证(提交前已跑):把 index.tsx 的 title 与可见文案一起改回「@引用」→ appSurface 两条用例变红(资源卡的 @ 引用入口只留在选中工具条里 / 工具条里的「引用」用键盘也能插进聊天输入框),还原后复跑 412 passed。
- 门禁:`npx vitest run apps/ai-game-creator-shell/tests/appSurface.test.ts` 412 passed(改动前后同一时刻对照,均为 412 passed)。
2026-09-11 21:25:14 +08:00
suzmii e15456ea14 读时丢弃的坐标不再静默:提示条带条数并在 DOM 上分开三类计数
- readReport 增加 droppedMissingResource(资源已不在 manifest)/ droppedSectionMismatch(分区与资源分类不匹配)/ dropped(两者之和),判据仍是 normalizeResourceCanvasPosition,未改 resourceCanvasLayoutModel 的丢弃语义。

- 文案补上跳过条数与两类原因:归并与丢弃同时发生时用「另有 N 条坐标无法对齐已跳过(…)」;只有丢弃时用「打开项目时有 N 条坐标无法对齐已跳过(…)」。

- 提示条暴露 data-resource-canvas-layout-normalized / -dropped / -dropped-missing-resource / -dropped-section-mismatch,供排障直接读 DOM;完全没丢时四个值都是 0。

- 读盘触发条件放宽为「有归并或有丢弃」,避免只有丢弃时什么都不提示。

- 断言:读盘统计用例覆盖三种情况分离;文案用例覆盖四形态(含真机 112 / 66 / 16 口径);appSurface 用例断言四个 data-* 与完整文案。

- 变异验证:把 dropped 计数改成恒 0 → 统计用例、读盘报告用例、提示条用例三处变红;去掉 data-resource-canvas-layout-dropped → 提示条用例变红。
2026-09-11 19:18:12 +08:00
suzmii 18361f8585 读时归并不再静默:打开项目归并旧分区坐标后给一次性提示
- useProjectResourceCanvasLayout 新增读盘只读统计 inspectProjectResourceCanvasLayoutRead 与文案 describeProjectResourceCanvasLayoutRead。

- 读盘判定 changed 时写入 readReport(项目作用域身份 + 排序模式 + 旧分区归并条数),判据复用 normalizeResourceCanvasPosition,只统计、不改写回与丢弃语义。

- index.tsx 在既有 game-resource-book-notices 提示层内渲染一次性提示条,复用 .game-resource-live-notice 样式与「知道了」关闭按钮;每个项目只提示一次,切换项目清空。

- 断言:useProjectResourceCanvasLayout.test.ts 覆盖归并时 readReport 与文案、无需归并且不写盘、只补新资源落位的写回不报读时统计;appSurface/project-development.suite.ts 覆盖提示条出现(data-resource-canvas-layout-normalized、可关闭)与无需归并时不出现。

- 变异验证:去掉 setReadReport → 上述读盘统计与提示条用例变红。
2026-09-11 19:14:44 +08:00
lhk229 d6a72c895c 修复策划项目命名相关 CI 检查
Project CI / Repository checks (pull_request) Successful in 2m47s
Project CI / Frontend tests (pull_request) Successful in 3m25s
Project CI / Backend tests (pull_request) Successful in 6m55s
Project CI / Native shell tests (pull_request) Successful in 20m14s
同步首页项目创建测试中的 planning 参数断言
格式化项目 Rust 测试文件以通过 rustfmt
2026-09-11 09:11:27 +00:00
suzmii e088ede217 让「当前使用」的资源卡真的发光,并修掉版本高亮的两处既有缺陷
- .game-resource-card.is-current-version 的外向扩散层从 0 0 0 2px /14%(那是描边)改成 0 0 0 3px /32% + 0 0 20px /34% 的真发光,边框口径仍是 1px
- 新增 game-resource-card-current-version-breathe 关键帧与 ::after 光环(只呼吸 opacity,照本页 .ui-editor-status-attention 的既有写法):声明档位 38%,呼吸区间 0.58 ↔ 1,视觉上约 22% ↔ 38%
- prefers-reduced-motion 下关掉动画但保留可见档位(opacity 0.75),收敛动画不收敛可见性
- 缺陷①:.game-resource-card.is-relation-version-binding 原本只写 border-color,而卡片本体 border: 0,规则从未生效(「点击版本卡后高亮绑定资源」这条 PRD 语义一直看不见);改为真实的 1px 边框 + ring,并把该规则移到 .is-current-version 之前,让常驻光环在两者同时命中时仍然赢
- 缺陷②:当前版本规则与 hover/focus/selected 同权重且在后,导致当前版本卡几乎看不出被选中;新增 .is-current-version.is-selected / :hover / :focus-within / .is-dragging 变体,显式提权到 (0,3,0) 并带上选中态自己那层阴影
- 测试:新增 resourceCardCurrentVersionStyle.test.ts(外向扩散层档位、呼吸实现方式与关键帧区间、选中态变体权重更高、reduced-motion 下仍可见、版本聚焦规则不再是死规则)
- 测试:resourceVersionSwitch 补 data-used-by-current-version 的 DOM 断言(命中为 "true"、未命中不含该属性、切版本后跟着换手)
- 测试夹具修正:project-development.suite 的版本夹具把 slotId 从 'player' 改成恒等映射 'asset:asset-player'('historical' → 'asset:asset-removed'),否则「当前版本」判定永远不命中、照它写断言必成假守卫;并补一条自证断言钉住它真的命中
2026-09-11 16:42:58 +08:00
suzmii 082d8d62de 把运行页签的资源信息搬到画布选中工具条,两处共用一份只读字段
- 新增「信息」动作:排在「@引用」之后、「编辑标签」之前,点开非模态信息浮层,再点一次即收起(aria-pressed 反映开合)
- 新增只读字段组件 ResourceInfoFieldsView(ResourceInfoPanelView.tsx),运行页签的「信息展示」与画布浮层共用,字段清单只在 resolveResourceInfoFieldRows 单点定义
- 字段口径:名称 / 路径 / 类型 + 只读分类与标签(分类取画布栏目口径,标签为空时给「暂无标签」),刻意不含来源任务、资产 ID 等 manifest 内部标识
- 浮层 chrome 与快速编辑浮层同族(同一锚点、同档圆角与阴影),样式落在 resourceCanvasChrome.css;关闭入口三处:动作按钮、面板关闭按钮、画布浮层统一的 Esc / 点边界外
- 关闭判据收口:resolveResourceCanvasQuickEditDismissOpen 更名为 resolveResourceCanvasFloatingPanelDismissOpen、参数改为 isFloatingPanelOpen,宿主把「快速编辑开」与「信息开」合成一个布尔
- .game-resource-info-panel 补进 RESOURCE_CANVAS_INTERACTION_SELECTOR,否则点在只读字段值上会被判成点画布空白而清掉选中
- 换选 / 清空选中 / 切项目时信息浮层自动收起:在选中派生处按 selectedResourceId 收口,不在每个重置点各补一行
- 测试:新增 resourceCanvasInfoModel 三条与「信息面板在画布浮层与运行页签里渲染同一份只读字段」(工具条顺序、开合、关闭按钮只收面板、点画布以外收起、Esc 连工具条一起收、运行页签字段逐行相同);resourceCanvasFloatingDismiss 的判据用例与交互选择器夹具改为浮层通用口径
- resourceCanvasChrome.css 的字段排版收在浮层选择器下,不跨上下文改运行页签的字号与列宽
- decision-log 新增一条:记录这次对 Issue #309 C3「取消资源详情面板」的有意局部回退(只回退「看信息」,不恢复可编辑详情面板与全屏编辑路由),并登记需要同步的 C3 引用位置
2026-09-11 16:42:40 +08:00
suzmii d80011656b 把资源卡的 @ 引用入口挪进选中资源工具条
- 删除资源卡右上角的 @ 引用圆钮,连同它的 44×44 热区伪元素与全部样式一起退役
- 选中资源的画布工具条新增「@引用」动作,排在「UI 编辑器」之后,出站负载与来源逐字未变(source: 'resource-card')
- 测试:原「卡片圆钮视觉尺寸」用例改写为「入口只留在工具条里」的源级 + 样式级断言,并补反向断言卡片组件内不再出现插入调用
- 测试:新增键盘通路用例,聚焦后回车必须真正派发 agc-resource-reference-insert,且两条通路负载逐字相同、每次激活只派发一次
- harness 注释同步:资源卡本体只剩「选中资源」与媒体播放钮
2026-09-11 16:28:48 +08:00
suzmii 81482b4587 同步「编辑标签」入口文案的既有断言
- tests/appSurface/project-development.suite.ts:跟随 6bdc8bbd9 把资源卡工具条入口由
  「分类与标签」改为「编辑标签」,同步音频资源工具条那条既有断言(否则 HEAD 的树是红的)
- 同一处注释同步说明:该面板只编辑 manifest `assets[].tags`,分类不再有手动入口
2026-09-11 15:41:17 +08:00
suzmii ea9668e4a9 资源总览「所有资源」卡补上资源预览
- 现象与归因:「所有资源」卡的预览区一直是空的,原因是我在 1cc9a2381 里加的闸 `!isResourceBookAllTarget(category)`(当时为避开"同一张资源卡挂两份")让它一张卡片计划都不生成;预览卡从来只由画本场景注入,占位摞本身不含卡片
- 改为真正生成卡片计划:喂进去的仍是全量投影(与标题栏计数徽标同一份口径),但当成一摞交给栏目卡同一个选取函数 `selectResourceBookOverviewCards`——没有视图中心时按投影顺序取前 `RESOURCE_BOOK_OVERVIEW_STACK_LIMIT`(=3) 张,与栏目卡每摞上限同口径;不分类型列,避免 66 项一口气铺出十几列
- 预览用同一个 `renderCard` 与同一套 `resourceBookOverviewCardLayout` 几何渲染,唯一差别是宿主类名换成 `.game-resource-book-preview-card`:转场层按 `.game-resource-book-scene-card` 收集 FLIP 节点并以 `card:${resourceId}` 为键,同一张卡两个宿主会让两条记录互相顶掉,因此预览宿主不进收集范围(`resourceBookController` 一行未改)
- 预览宿主带 `aria-hidden` + `pointer-events: none`:无障碍树与 `getByRole` 里每张资源卡仍然只有栏目卡那一份,不会重复命中;点预览区仍走进「所有资源」页,栏目卡预览卡仍可选中
- 转场淡出集合(`resourceBookPlanKeysRef` 那段)跳过「所有资源」组,避免预览节点被当成"离开视图的卡片"按子画布坐标重新贴到画布别处
- `ResourceBookThumbnail`:该卡正文的占位摞从最多 3 摞改为对齐真实摞数的 1 摞,卡片高度回到与栏目卡同一条口径
- `styles.css`:把 `.game-resource-book-preview-card` 并进 `.game-resource-book-scene-card` 的两条既有规则(宿主几何、主态卡片圆角/阴影)与 `prefers-reduced-motion`;没有新写一套预览样式
- 断言(`project-development.suite.ts`):预览卡的 `data-resource-card-id` 序列恰等于全量投影前 3 个、条数 == `min(3, 计数徽标)`、预览里是完整卡片(视觉体 + 选中按钮)、宿主在 `aria-hidden` 子树里、宿主几何规则与栏目卡共用同一条
- 断言(新增用例):空项目下沿用既有空态「暂无资源」、预览节点 0 个、计数 `0 项`、入口行仍在,卡片不破版
- 单测(`resourceBookLayout.test.ts`):把已被新行为取代的旧断言(`all` 组不出卡片、全计划无重复卡片键)删掉,换成新合同(预览 = 全量投影前 3 张、只铺一列、各栏目摞不变),并补空投影 → 0 张
- 变异验证(两条都跑过并已还原):① 喂进去的资源改回空数组 → `AssertionError: expected +0 to be 4`;② 恢复旧闸(计数仍正确、预览为 0)→ `AssertionError: expected [] to deeply equal [ Array(3) ]`
2026-09-11 15:37:17 +08:00
suzmii 39a96aa418 模型下拉菜单高度有界:健壮性补强,条目多时不再盖住消息
Project CI / Repository checks (pull_request) Successful in 2m36s
Project CI / Frontend tests (pull_request) Successful in 3m20s
Project CI / Backend tests (pull_request) Successful in 6m29s
Project CI / Native shell tests (pull_request) Successful in 18m34s
- 性质说明:本条是**健壮性补强**,不是用户本轮报的那几条之一;由上一提交(锚点修复)排查时顺手发现的未修观察收尾。
- styles.css:`.conversation-model-menu` 补 `max-height: min(240px, 40vh)` + `overflow: auto` + `overscroll-behavior: contain`。菜单此前没有高度上限,模型条目很多时会长到 composer 顶边以上、盖住消息;240px 与视口 40vh 取小者,矮窗 / 窄屏(移动端优先)更稳。`overscroll-behavior: contain` 与既有 `.resource-reference-menu` 同一口径,菜单内滚动不传染给背后的消息列表。不新增视觉:border / radius / padding 与 token 全部沿用原值。
- 语义零改动:锚点与流式归属不变(`position: absolute; right: 0; bottom: calc(100% + 8px)` 未动),打开 / 选择 / 刷新模型列表的交互不变。
- project-development.suite.ts:新增声明级守卫「bounds the model dropdown height so a long catalog cannot cover the composer」——菜单规则必须同时声明 `max-height: min(240px, 40vh)`、`overflow: auto`、`overscroll-behavior: contain`,并仍是 `position: absolute`(高度有界不改锚点)。
- 变异验证(已实测):把 `max-height` 摘掉 → 用例红灯(expected '…' to match /max-height:\s*min\(\s*240px\s*,\s*40vh\s*\)/u)。
- 门禁:typecheck exit 0;AGC 子集 1206 passed / 4 skipped / 0 failed(基线 1205 + 本次新增 1 条);src/components/image-editor 1385 passed;check:encoding 4379 文件通过;`git diff --check` 全量与本次两个文件范围均 exit 0。
2026-09-11 14:59:42 +08:00
suzmii ff287c19fc 模型下拉弹层改回以触发钮为锚点,输入区高度变化不再牵动它
- styles.css:direct-codex 控制排里的 .conversation-model-select 由 position: static !important 改为 position: relative !important(只改这一个词,另补一段注释说明它同时是弹层锚点)。这颗容器是 .conversation-model-menu(position: absolute; right: 0; bottom: calc(100% + 8px))与模型提示([role='alert'] / [role='status'],position: absolute; bottom: 36px)的包含块;写成 static 时包含块回落到最近的有定位祖先——也就是 position: absolute 的 composer 盒子,菜单于是出现在整个 composer 上方、与触发钮之间隔着整个输入区,输入区一变高(多行、引用 chip、AI 润色)菜单与提示跟着往上飘:这就是"编辑框把元素挤开"的形态。
- styles.css:right/bottom: auto、flex: 0 1 auto、min-width: 0、max-width: 180px 全部保持原样——relative 不会把模型选择钮移出控制排,也不改它被压缩换行的行为;交互语义零改动(打开/选择/刷新模型、发送、@ 引用、快速模式全在原位)。
- project-development.suite.ts:新增一条声明级守卫。① 弹层不参与父容器流式布局(菜单与模型提示都是 absolute,菜单 bottom: calc(100% + …)、right: 0);② 锚点必须是有定位的容器(relative 且不是 static),同时仍在原位(right/bottom auto、flex 0 1 auto、min-width 0);③ 输入区高度变化不得推动同排操作元素(composer 是底边锚定的两行网格:position: absolute + bottom: 12px + grid-template-rows: auto auto;控制排是单行 flex 且不换行,@ 与发送钮 flex: 0 0 30px 不可压缩,窄屏下被压缩的是可收缩的模型选择钮)。
- conversationModelSelect.test.tsx:新增一条 DOM 守卫——菜单必须是 .conversation-model-select 的直接子节点,且不得成为控制排容器 .project-supervisor-composer-controls-right 的流式子节点。
- 变异验证(均已实测红灯):① 锚点改回 static → "expected … to match /position:\s*relative\s*!important/";② 菜单改成 position: static(弹层回流式)→ "expected … to match /position:\s*absolute/";③ 把菜单渲染挪出触发钮容器(变成同排容器的流式子节点)→ DOM 守卫 "expected null not to be null"。
- 门禁:typecheck exit 0;AGC 子集 1205 passed / 4 skipped / 0 failed(基线 1203 + 本次新增 2 条);src/components/image-editor 1385 passed;check:encoding 4379 文件通过;本次三个文件单独 `git diff --check` exit 0(全量 `git diff --check` 目前报的是另一位 Agent 在途修改的 packages/shared/src/components/styles.css:1281 EOF 空行,与本次无关)。
2026-09-11 14:53:11 +08:00
lhk229 123c699db9 修复策划澄清卡自由文本回答
Project CI / Repository checks (pull_request) Successful in 5m25s
Project CI / Frontend tests (pull_request) Successful in 6m36s
Project CI / Backend tests (pull_request) Successful in 29m4s
Project CI / Native shell tests (pull_request) Successful in 33m51s
将自由文本与选项回答分开提交

补充澄清卡回归测试和迁移方案说明
2026-09-11 06:44:47 +00:00
suzmii 9c4778c881 把资源卡右下角的 @ 引用按钮做小:视觉缩到 0.8×,热区保持 44×44
Project CI / Repository checks (pull_request) Successful in 3m31s
Project CI / Frontend tests (pull_request) Successful in 4m24s
Project CI / Backend tests (pull_request) Successful in 6m51s
Project CI / Native shell tests (pull_request) Successful in 18m37s
- styles.css:`.game-resource-card-reference` 视觉尺寸 30×30 → 24×24(0.8×),新加 `.game-resource-card-reference svg` 把内部 `AtSign` 图标同步从 16px 收到 13px,圆角/描边/底色/阴影 token 全部沿用原值。
- styles.css:`bottom` 由 9px 调到 14px,与右侧 34px 播放钮圆心对齐(9 + 34 / 2 = 14 + 24 / 2),避免缩小后两颗圆钮错位。
- styles.css:新增 `.game-resource-card-reference::before` 伪元素撑出 44×44 热区(本仓 window chrome / 素材选择列表同口径的最小可点尺寸),只扩命中范围、不参与布局也不改变绘制;整体向左让 4px,让热区右边缘与播放钮的盒子恰好相邻,不覆盖它。
- 语义未动:仍是「插入素材引用」入口,className、`aria-label={\`引用资源 ${resource.label}\`}`、key 与 `dispatchResourceReferenceInsert` 调用一行未改,本次只改 CSS 声明。
- 测试:新增 CSS 声明级用例,断言按钮与图标确实变小(24 < 30、13 < 16)、热区不小于 44×44、热区右边缘不越过播放钮盒子,并顺带钉住 `index.tsx` 里 @ 入口的 className / aria-label / 插入动作仍在。
- 变异验证:把按钮改回 30px、热区改回 24px、图标改回 16px → 用例红灯;只把热区缩回 24px → 用例同样红灯(均已实测,随后原样还原)。
2026-09-11 14:00:32 +08:00