Commit Graph

193 Commits

Author SHA1 Message Date
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
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
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
suzmii 29b99f213d 删除资源画布左侧的栏目大纲导航:切栏目改由总览卡片、所有资源入口与下一页承担
- index.tsx:整条删除 `ResourceBookOutlineNav` 组件(`.game-resource-outline` / `aria-label="资源栏目大纲"` / 栏目图标 + 栏目文字 + 未读红点)以及栏目页与「所有资源」页两处挂载点;`ResourceBookAllResourcesPage` 不再接收只服务导航的 `unreadCategories` / `onOpen`。
- index.tsx:一并清掉只服务这条导航的「未读红点」状态链(`unreadResourceCategoryState`、`resourceCategorySnapshotRef`、`resourceIdsByCategory`、`viewedResourceCategory` 与对应 effect),不留死代码、不留墓碑注释。
- styles.css:删除全部 `.game-resource-outline*` 规则(悬浮 Dock、常态/悬停态、图标列宽、`.game-resource-outline-label`、`.game-resource-outline-unread`,共 106 行)。
- 保留未动:分区栏目本身、栏目标题栏、资源卡、总览缩略卡片、第 0 张「所有资源」入口、「所有资源」汇总页、搜索、总览、快速编辑与选中工具条。
- 测试:切栏目 helper(appSurface/project-development、appSurface/home、resourceRename、resourceVersionSwitch)改为走「资源总览」缩略卡片(需要时先点「收起资源」回总览),不再点导航;栏目顺序断言改钉在总览缩略卡片的 `aria-label` 序列上(第 0 张「所有资源」+ 固定七栏目),断言内容未放宽。
- 测试:按「四不写」删除只守这条导航的断言——大纲常态可读性的 CSS 声明用例、大纲条目图标/文字的 DOM 用例(该用例保留其中与搜索浮层相关的断言并改名)、未读红点用例(该用例保留"只登记游戏代码的项目照常分页并落在待归类"的部分并改名)、空项目与「所有资源」页里的导航存在性断言。
- 测试:新增反向守卫 + 切栏目链路用例(`has no outline nav and keeps every section reachable through the remaining entries`):断言 `资源栏目大纲` 标签、`.game-resource-outline` 类名与对应 `<nav>` 都不再渲染,并逐条走通总览缩略卡片(含空栏目)→ 下一页 → 标题栏「资源总览」→ 「所有资源」入口往返。
- 测试:`preserves independent art viewports across sort and workbench mode switches` 保留全部原断言,只去掉排序模式切换后那些"点当前栏目"的空操作往返(旧导航点在同栏目上是提前返回,改 helper 后变成真实往返,会在 jsdom 里触发重新 fit)。
2026-09-11 13:54:12 +08:00
suzmii 66bb240115 进项目时按内存 registry 核对预览活体,陈旧记录不再冒充可运行预览
- 新增 features/app-shell/sessionPreview.ts 的 resolveSessionPreviewOnProjectOpen:进入项目时问一次 get_local_game_preview_status(内存 registry 是活体的唯一真相),确实 running 才把它作为本次会话的预览;记录写着 running 而 registry 没有活体时判为陈旧,复用现役 stop_local_game_preview 把落盘记录对齐成 stopped,并同时把会话 manifest 按真相投影成 stopped(否则运行入口会继续拿着打不开的 URL 渲染运行画面)。
- useHomeProjectCreation.ts:enterProjectDevelopment 改为 async,先做这次核对再进工作台,并按核对结果决定会话预览与 manifest 投影;三个调用点(新建项目、创建项目、打开项目)都改为 await。
- preview.rs:同一个项目重启预览时,旧 registry 身份的收尾不再覆盖刚落盘的 running——只有当旧预览属于**另一个项目**时才替它收尾。此前同项目重启会把刚写进去的 running 覆盖成 stopped,下次进项目便丢掉"预览在跑"这条事实(记录反方向失真)。
- preview.rs:stop_local_game_preview_for_root 在没有活体可停、但落盘记录仍是 running 时也把记录收尾成 stopped(stop 的语义变成"真的停干净,包括记录"),因此陈旧记录既可由进入项目触发对齐,也可由用户显式停止对齐。
- tests/project.rs:新增三条 Rust 定向用例——同项目重启后记录仍为 running 且端口是新预览的;换项目启动时旧项目记录写 stopped、新项目写 running;registry 无活体而记录写着 running 时 stop 会把记录对齐成 stopped。
- tests/sessionPreview.test.ts(新增):五条用例覆盖活体优先、陈旧记录对齐并投影、registry 不可读按没有在跑处理、记录本来不是 running 时不发多余停止命令、无 invoke 时零请求。变异验证:把活体核对去掉(直接信落盘记录)→「registry 里没有活体时不给会话预览」与「registry 不可读」两条立即红灯(已实测)。
- project-development.suite.ts:把「打开项目不查预览状态」那条断言改为「恰好核对一次预览活体」,并保留邻近的 start_local_game_preview 必须为 0 的断言——被新行为取代的是"从不核验","开项目不偷偷启动预览"这条原意一字未改。
- PRD §4.1:状态机按当前实现改写(进入项目一律落到 resource-overview;run 的自动进入只认内存 registry 的活体确认;落盘 preview 是记录而非活体,陈旧记录不触发切换也不参与渲染),并把退出收尾一并写进该节说明。
2026-09-11 12:27:31 +08:00
suzmii 3ed567d99a 运行视图的自动切换只认会话内确认过的预览
- index.tsx:自动切运行的那条 effect 从「合并后的预览 URL」收窄为「会话预览 URL」(resolveEmbeddedPreviewUrl(previewOverride))。manifest.preview 是"上次留下的一条落盘记录":预览服务器是进程内线程、非 Linux 端口还是随机临时端口,客户端退出后记录仍会写着 running,照着它自动切视图就是把用户丢进一个打不开的运行界面。运行入口(运行 tab、播放按钮)与 runAvailable 一行未动,PRD §4.1「运行入口不可用时仍允许点击…但不切换状态」继续成立。
- useHomeProjectCreation.ts:enterProjectDevelopment 不再把 context.manifest.preview 播种成本次会话的预览(改为 null)。会话预览此后只由活体确认(下一提交)与本次会话里 preview.start / preview.status 的返回值经 onPreviewChange 回流两处写入。
- 有意接受的代价:「回到仍在运行的预览」从自动变成用户点一下「运行」;下一提交会把"确实还在跑"这条路径按活体确认接回自动进入。
- project-development.suite.ts:新增两条用例——① 仅 manifest.preview 为 running(不传 preview)时初始仍是「资源管理」、运行 tab 仍可用、点一下仍能进运行视图;② 会话预览为 running 时自动切到运行表现层。
- 变异验证:把这条 effect 还原成读合并后的 URL(即撤掉本次收窄),用例①立即红灯(已实测)。
2026-09-11 12:07:44 +08:00
suzmii 28bb5800ea 资源总览去掉大标题旁的副标题
- 删除资源总览标题栏里那颗副标题的**两个分支**:`${canvasResources.length} 项正式与候选资源` 与空项目时的 `从资源栏目开始整理资源`
- 位置:`apps/ai-game-creator-shell/src/view/project-development/index.tsx` 的 `<header className="game-resource-book-main-heading">`(基线 364492de3 的 5867-5871 行那颗 `<span>`,标题栏自 5863 行起)
- 同步删除只服务于它的 `.game-resource-book-main-heading > span` 样式,模块内不再留墓碑规则
- 该文案没有承载 `aria-label` 等语义(区域语义一直在容器的 `aria-label="资源总览"` 上),因此不需要把语义迁移到容器,也没有改成"更短的说明"
- 全量计数没有丢:同一次改动后由总览第 0 张「所有资源」卡的计数徽标承载,仍是同一份画布投影
- 卡片内部的说明/装饰文案(「打开 UI 交互」「打开角色与对象」「1 个直接子版本」等)保持不动
- 断言:资源总览标题栏整段 `textContent` 恰为「资源总览」(精确相等,不放宽成 `not.toContain`),并复核总览第 0 张卡与「文档」栏目卡的内部文案仍在
- 既有用例没有任何一条断言过这段副标题文案(全仓检索只命中源文件),因此没有"按文案已删更新"或"按四不写删除"的对象;本用例是补上的正向合同断言
2026-09-11 11:28:59 +08:00
suzmii 1cc9a23815 资源总览新增「所有资源」汇总卡与全部资源页
- 渲染层新增 `RESOURCE_BOOK_ALL_TARGET = 'all'` 特殊项:跨端契约 `ProjectResourceCanvasCategory` 不加 `'all'`,sidecar schema 不升版,落盘布局的 `section` 也不会出现它
- 资源总览第 0 张卡即「所有资源」:排在全部栏目卡之前,复用同一套缩略图类名/圆角/底色/阴影与栏目标题栏组件,不新增卡片样式
- 该卡的计数徽标取全量资源数,口径等于各栏目计数之和(同一份画布投影,不另算一套)
- 画本场景的栏目顺序与资源分组各多一个渲染层入口;`buildResourceBookScenePlan` 对特殊项只出计数与标题栏,不铺卡片,避免同一张资源卡在总览里挂载两份(`data-resource-card-id` 查询与 FLIP 的 `card:*` 键都会撞车)
- 新增「所有资源」页:栏目大纲 + 收起资源按钮 + 按栏目分组的滚动卡片网格;卡片复用栏目页同一颗渲染器与卡宽高,容器与网格样式补齐在 styles.css
- 该页的卡片显式关掉拖拽(卡片坐标不属于任何栏目画布,写回会污染布局 sidecar),保留选中/播放/菜单交互,并把光标与 `touch-action: pan-y` 交给滚动容器
- 栏目大纲抽成 `ResourceBookOutlineNav`,栏目页与全部资源页共用同一条入口带;渲染出的 DOM 与抽取前一致
- `renderResourceBookCard` 增加可选 `draggable` 参数,`ResourceCard` 的三个移动端指针回调改为可选
- 断言:总览存在「所有资源」卡且为第 0 张、计数等于全量资源数且等于各栏目计数之和、点它进入的页面按栏目分组且每组都挂真实资源卡、场景计划里特殊项不出卡片且整份计划无重复卡片键、全部资源页分组只保留非空栏目且保持总览顺序
- 既有「N 项」徽标断言从全文档文本查找收窄到 character 栏自己的标题栏(新增第 0 张卡后同文案会撞车,收窄而非放宽)
2026-09-11 11:21:03 +08:00
suzmii 6cc929e47d 修复陶泥儿对话外框没把输入区包住:外框底边不再与输入区重合
- 根因:`.project-supervisor-message-list` 在文件末尾还留着一条同选择器、同权重的
  `bottom: 156px`("列表在上、输入区在下"那版两盒布局的残留)。它按"后写胜出"把上一轮
  bdb07c141 改的 `bottom: 0` 悄悄顶掉,外框底边落在输入区腰上、输入区下半截露在框外,
  真机上看到的就是"消息区外框底边与输入区压在一起、外框没把输入区完整包住"。
- styles.css:把那条残留规则换成对话框盒子的最终几何(top/right/bottom/left 全 0,
  `padding-bottom` 与 `scroll-padding-bottom` 都是 256px)。它位置在文件靠后,同权重后写
  胜出,顺带把 `:has(.plan-gdd-surface, .planning-lane-runtime-strip)` 给列表留的
  `padding-bottom: 12px` 压回去,滚到底时最后一条消息不会被输入区盖住。
- styles.css:输入区补上第四条边——`max-height: calc(100% - 24px)`(24px = 上下各 12px)。
  左右下三边仍显式内缩 12px,上边由 max-height 兜底,于是外框完整包住输入区:四条边都不
  与外框描边重合,底边留出 12px 边距(外框底边 0 / 输入区底边 12px)。
- styles.css:窄屏(≤760px)改成一个模型——外框画在列表与输入区共同的父节点
  `.project-supervisor-conversation` 上,列表撤掉自己那只框(框里不套框),输入区回到
  文档流,靠外框 12px 内边距四周留白、随列高增长不溢出。原来那条窄屏输入区规则权重低于
  `.project-supervisor-composer.is-direct-codex` 那条,其实一直是死声明,这次才真正生效。
- tests/chatDialogFrameLayout.test.ts:新增用例,先按真实层叠(媒体查询是否命中 -> 特异性
  -> 源码顺序)求生效值,再断言外框四边归 0、输入区四边内缩同一个值、底边与左右留白严格
  大于 0、留白 256 = 12px 内缩 + 228px 输入区最高高度 + 16px 间距(228 由编辑器
  max-height 140、输入框行距 8、操作排 28px 方钮、输入框下内边距 4、输入区上下内边距 16、
  操作条 2 + 30 方钮逐项从真实声明里算出来),以及窄屏下外框/列表/输入区各自落位、输入区
  仍在外框节点子树里且交互控件原位。
- tests/appSurface/project-development.suite.ts:把那条按"第一条匹配规则"取值、用 230 估
  算的留白断言同步成按声明算出的 228 与实际间距 16,并注明层叠生效值的守卫在新用例里。
- 变异验证:输入区 `bottom: 12px -> 0`(还原"贴死重合")时新断言失败;外框
  `bottom: 0 -> 156px`(还原上一轮残留)时"外框底边必须严格低于输入区底边"失败(-144)。
- 说明:本机无无头浏览器、vitest 未开 `css: true`,像素级观感只能真机复核;这里钉的是
  层叠生效的声明级几何关系与"输入区仍在外框节点的子树里"。
2026-09-11 10:36:45 +08:00
suzmii e3616a44cc 补逐栏目断言:资源总览每个非空栏目都必须挂载真实卡片本体
上一轮把「总览其它栏目不画卡片」的回归结论建立在推理上(identity map 由全量投影构建 ⇒ 不会有卡片因身份缺失而不挂载)。本轮把它变成实测。

- 新增 `appSurface > mounts a real card body in every non-empty resource section overview`:自带 manifest,把 `category` 显式写死,让 `character` / `audio` / `document` / `unclassified` / `version` 五个栏目同时非空(外加空的 `ui-interaction` / `scene`),再逐栏目断言 `.game-resource-book-scene-card[data-resource-book-category=…]` 内存在 `.game-resource-card` 本体,并用 `.game-resource-card` 的 `data-resource-card-id` 回查投影结果,证明卡片确实落在被断言的栏目(不是靠「有子节点」这种恒真守卫蒙过去)。`audio` 刻意保持 `idle`(音频不接受可见性预取),用来证明卡片挂载不依赖预览是否已就绪。
- 自带 manifest 而不是改共用 fixture:`addSectionResources` 的四个资产被同一测试后续多处断言引用(例如 `选中资源:待归类 section.md`),给它补 `category` 会把 `section.md` 从「待归类」挪进「文档」,连带打挂那些既有断言。新用例因此只新增、不改动既有断言。
- 分类字段名踩坑记录:manifest 资产上的字段名是 `category`,不是 `assetCategory`(`assetCategory` 是前端投影后的 `ProjectResource` 字段)。先写成 `assetCategory` 时它被静默忽略,`gameCreationAppAssetCategory` 只能按 `kind` 派生,`design-document` / `game-code` 都不是 canonical kind,于是 `section.md` 落在「待归类」、`document` 栏目为空。
- 变异验证(本断言的价值所在):把 `resources` 改回 `activePageResources`(即回到回归状态)后,本用例与既有 `uses one full-page canvas per resource section with dependency-only guide lines` **双双失败**(`expected null not to be null`);恢复后两者通过。断言确实守住了这条回归。
- 验证:`npm run test -- apps/ai-game-creator-shell/tests` 81 files passed,1172 passed / 4 skipped / 0 failed;typecheck exit 0;eslint 与 prettier 干净;check:encoding 4374 文件;`git diff --check` 干净。本轮只改测试文件,`src/**` 与 HEAD 逐字节一致(变异验证后已还原并核对)。
2026-09-11 01:59:21 +08:00
suzmii 7fa61231ae AGC 资源画布两条过期断言跟上新合同,并补项目切换的预览缓存清理行为断言
- appSurface > renders one body-first card system:把原先钉「全局只读 1 次」的断言收窄成「同一身份不因重复请求新增物理读取」——热预取之后先让 IntersectionObserver 再报一次可见、再打开一次详情,读取次数必须与快照一致;并先钉住快照非空且读取目标都是 assets/hero.png,避免空集恒真。60d8b8fbb 把热预取改成只喂当前栏目后,用例里每进出一次「角色与对象」都会重读该栏目的可见卡(该 commit 已明确接受这个代价),全局总次数会随进出次数漂移;「同一身份同时只读一次」是 PRD 里真实存在的合同,比总次数更精确,没有放宽。
- appSurface > keeps the resource preview version cache wired and cleared on project switch:60d8b8fbb 删掉了从未被写入的 resourcePreviewVersionByResourceId 死接线(只被 new Map() 初始化与清空,previewVersionByResourceId 恒为空串),断言守的 prop 与其清空语句都已不存在,按「四不写」删除这条形态断言;用例改名 clears the resource preview cache and cancels the old preview scope on project switch。
- 同用例把意图从源码正则换成可执行行为断言(原断言只证明接线存在,不证明缓存真被清):渲染 A 项目并等卡片预览落到 Blob URL 后切到 B 项目,断言 ① 旧卡片预览的 Blob URL 被撤销、② 旧 scope 的在途读取按旧 scopeId 取消、③ 同一资源以新项目身份与新 scopeId 重新读取。
- 变异验证在 %TEMP% 下的独立 worktree 沙箱里做(未改本工作树产品代码):去掉预览 Hook 里 loaded 早退 → 第二条用例失败(同身份读取 6→7);去掉 cancelLocalProjectResourcePreviewScope(previousScopeId) → 第三条 ② 失败;切项目不复用新 scopeId → ③ 失败;拆掉两条撤销 Blob URL 的路径 → ① 失败。
- 未改 uses one full-page canvas per resource section with dependency-only guide lines:沙箱实验证明只把预览 Hook 入参从 activePageResources 换回 canvasResources,该用例即整体通过。它守的「总览逐栏绘制各栏目真实卡片」是被 60d8b8fbb 意外收窄的(renderResourceBookCard 在 identityByResourceId 缺该资源时返回 null,而该 map 从该 commit 起只覆盖当前栏目;其 commit message 只声明了预取口径与重读代价,未声明总览不再绘制其它栏目卡片),属产品回归,已上报,不以改断言掩盖。
- 门禁:ai-game-creator-shell:typecheck exit 0;apps/ai-game-creator-shell/tests 1 failed / 1170 passed / 4 skipped(唯一失败即上面上报的回归;改前 3 failed / 1168 passed);src/components/image-editor 1385 passed;check:encoding 4374 文件;git diff --check 干净。
2026-09-11 01:33:10 +08:00
suzmii bdb07c141b 聊天输入区收回对话框内部
- 根因:`.project-supervisor-surface.is-direct-codex` 下消息列表与输入区是两只各自带边框、
  各自绝对定位的盒子——列表 `bottom: 104px`、输入区 `bottom: 0; left/right: 0`,两盒上下
  紧贴。输入区自己那只盒子的左右描边与列表的左右描边接成两条贯穿整栏的竖线,加上列表
  只留 24px 底部内边距,最后一条消息还会被不透明的输入区盖住。观感就是"输入框紧挨着
  对话框、两侧有突兀竖条"。
- styles.css:消息列表(direct-codex)改为铺满整个会话区(`bottom: 104px` → `0`),它自己
  那只带描边和圆角的盒子就是"对话框";`padding-bottom` 与 `scroll-padding-bottom` 由 24px
  提到 256px,给框内输入区留出位置(256 ≈ 输入区最高 230px + 12px 内缩 + 约 14px 间距)。
- styles.css:输入区(direct-codex,含同类选择器共两条绝对定位规则)由贴边改为框内内聚
  区块:左右下三边各内缩 12px,圆角 14px 收到与外框同一档 12px;边框、底色、阴影继续用
  既有 token(`--platform-surface-border` / `--platform-input-fill`),不新增配色。
- 不改交互语义:输入区仍是同一棵 DOM(编辑器、@ 引用、AI 润色、模型选择、提交按钮全部
  原位),只改它在对话框里的落点与留白。
- project-development.suite.ts:新增守卫——对话框盒子四边归 0、输入区三边内缩同一个值、
  仍是绝对定位且保留边框与底色、消息列表留白 ≥ 输入区最高高度 + 内缩且与
  `scroll-padding-bottom` 同值、编辑器 min/max 高度就是留白算式的来源;并同步既有那条
  钉 `bottom: 104px` 的断言为 `bottom: 0`。
- 说明:本机无无头浏览器、vitest 未开 `css: true`,像素级观感只能靠真机复核;这里钉的是
  声明级几何关系与"输入区仍在同一棵渲染树里"。
2026-09-11 01:00:10 +08:00
suzmii 3bd4daf5d5 补「回到资源总览」命中区域的守卫断言
- 成因回填:分页态标题栏右端的「资源总览」(回到资源总览)按钮点不动,是常驻工具条带 `.game-resource-book-tools` 造成的——它是横跨整行、`z-index: 40` 的绝对定位层,正好盖在栏目标题栏那条带(`z-index: 30`)上,把按钮的命中区域整段吃掉。上一提交撤掉这条带后问题已消失,本次只补守卫,不改实现。
- project-development.suite.ts:新增声明级守卫,钉住浮层提示层(`.game-resource-book-notices`)与返回按钮所在标题栏的层级关系——提示层 `z-index` 高于标题栏(提示要看得见),因此容器必须 `pointer-events: none`、只有提示条自己 `pointer-events: auto`;提示条顶边 ≥ 标题栏 `min-height`,连视觉重叠都不发生;并反向断言常驻工具条带在 styles.css 与 index.tsx 里都已不存在(变异实测:把容器改回 `pointer-events: auto` 该用例立即红灯)。
- project-development.suite.ts:新增渲染级守卫——附件导入失败条在场(提示层挂载)时进入分页态,断言返回按钮不在提示层容器内、不是 disabled,点击后 `data-resource-book-view` 回到 `main` 且「资源总览」region 在场。
- 说明:jsdom 不做布局命中判定,像素级"是否被盖住"只能由声明级的层级/命中声明 + 真机复核确认;渲染级用例钉的是"提示层在场时返回入口仍然渲染、可点、并真的接在返回总览上"。
2026-09-11 00:57:52 +08:00
suzmii f7831348c6 搜索栏改成「临时叫出」的浮层,并撤掉为它引入的工具条带
- index.tsx:搜索框不再常驻。常态只在右下角缩放 Dock 末尾留一颗搜索按钮(复用 `game-resource-book-zoom-button`),`Ctrl/Cmd+F` 或点它把浮层叫出来;关闭走本仓既有浮层口径——直接复用美术画布的 `useImageCanvasFloatingOptionDismiss`(Esc / 点外部,Escape 在 document 上截断,不会连带触发画布清选中)。
- index.tsx:浮层打开后自动聚焦搜索框,`resourceSearchRef` 不再是死 ref(PRD「焦点落到资源搜索框」的入口接上了)。
- index.tsx:搜索语义零改动——`setSearchText`、`visibleResources` 过滤、「清除搜索并定位」原样保留;浮层收起不清条件(`type=search` 的原生 Esc 清空被 preventDefault 挡掉),条件生效时 Dock 搜索按钮带 `is-active` 高亮,用户看得出"当前有搜索"。
- index.tsx:撤掉常驻搜索条连带的那条排布带——删除 `resourceBookToolsRef`、`resourceBookToolsHeight`、`resourceCanvasSceneSize()`、ResizeObserver 测高 effect,以及缩放锚点 / 滚轮锚点里减掉工具条带的两处算式;`resourceBookSceneSize` 重新等于管理区盒子。
- index.tsx:状态提示与附件导入失败条移出排布带,落到新的浮层容器 `game-resource-book-notices`(顶部绝对定位,不占流内高度)。
- styles.css:`.game-resource-manager` 去掉 `padding-top: var(--game-resource-book-tools-height)`,`.game-resource-book-scene` 恢复 `inset: 0`,删除 `.game-resource-book-tools` 规则与窄屏 560px 那条只为常驻搜索框写的宽度规则;搜索框改为贴右下角 Dock 向上展开的浮层(`bottom: 58px` = Dock 的 14px + 34px 高 + 10px 间隙,`z-index: 40`)。
- styles.css:新增 `.game-resource-book-notices` 浮层与 `.game-resource-book-zoom-button.is-active`(复用 Dock 按钮的 hover 色,不新增配色 token)。
- tests/appSurface/harness.ts:新增 `openResourceSearch()`——按产品入口打开浮层再返回输入框,`getByLabelText` 在浮层未打开时直接抛错,堵掉"元素在但点不到"那类假绿。
- tests/appSurface/project-development.suite.ts:重写搜索可见性守卫为「浮层不落在标题栏那条带上」(管理区不再有 padding-top、场景 `inset: 0`、浮层底边 ≥ Dock 底边 + Dock 高度、浮层不带 top、提示层顶边 ≥ 标题栏高度),新增浮层开合用例(按钮 / Ctrl+F 打开、焦点落在输入框、Esc 与点外部收起都不清条件),并把既有 5 处搜索用例改为先叫出浮层。
- tests/projectResourceLiveIntegration.test.tsx:「清除搜索并定位」用例改为重新叫出浮层读条件与清空后的值。
- 验证:新增的两条断言已用变异实测不是恒真守卫——去掉自动聚焦、或让关闭顺手清条件,对应用例都会红灯。
2026-09-11 00:56:52 +08:00
suzmii c5df56d855 补齐资源 kind 别名表:ui 归 UI 交互,game-* 归代码,animation 归角色
- TS 侧 GAME_CREATION_APP_LEGACY_ASSET_KINDS 补 5 条别名:ui → ui-design、game-entry/game-script/game-style → code、animation → character-animation、asset → image
- Rust 侧 canonical_game_creation_app_asset_kind 同步补齐同一批别名,两侧必须成对维护
- 按拍板口径不往 GAME_CREATION_APP_CANONICAL_ASSET_KINDS 加新 kind,避免出现 ui 与 ui-design 两个同义 kind
- 保持 art-spritesheet-slice → icon → ui-interaction 不动
- 补注释写明别名表的职责是「线上值 → canonical」而非仅收历史遗留,画板导出等现役写入侧同样要在这里收口
- 新增 assetKindCanonicalMapping.test.ts:解析 Rust 源码交叉钉住两侧 canonical 目录与别名映射逐条一致,并逐条断言已拍板的 kind → canonical → 栏目口径
- 新增 resourceCardPreviewRealManifest.test.ts:按真机 manifest 逐条形状可执行地数出预览分支与栏目分布(raster-image 52 / placeholder 8 / code 1;unclassified 58 / ui-interaction 2 / scene 1)
- 真机取证用例同时钉住「别名只救新登记、不救存量」:57 条 ui 的落盘 category 仍是 unclassified,需读时重派生或一次性回填才能归位
- 修正两条按旧错误栏目断言的既有用例:kind=ui 的上传图归「UI 交互」、animation 视频归「角色与对象」
2026-09-10 21:18:55 +08:00
suzmii 2fefb373d1 修复 AGC 资源搜索框与栏目标题栏挤在同一水平带的重叠
- styles.css:新增 `.game-resource-book-tools` 工具条带,搜索框、筛选条与状态提示在里面按流式排布;`.game-resource-search` 去掉 `margin: 10px 12px 0`,尺寸与间距交给工具条带。
- styles.css:`.game-resource-manager` 加 `padding-top: var(--game-resource-book-tools-height, 0px)`,`.game-resource-book-scene` 的 `inset: 0` 改成同一变量让出顶边;管理区与画本场景共用一条实测高度,两者不再落在同一条排布带上(总览态标题栏与分页态栏目标题栏都整体下移)。
- styles.css:`@media (max-width: 560px)` 下搜索框独占整行,窄屏筛选条换行时工具条带变高、场景按实测高度继续下移,不靠 z-index 硬压。
- styles.css:更新工具条带注释,说明 `z-index: 40` 仍保留(高于场景的 20),作用只剩"工具条内容溢出时不被画本盖住"。
- index.tsx:把画本场景以外的流式工具条包进 `game-resource-book-tools`,搜索框挂 `resourceBookToolsRef`,用 ResizeObserver 实测 `offsetTop + offsetHeight` 写入 `--game-resource-book-tools-height`;搜索、筛选、「清除搜索并定位」与 `resourceSearchRef` 全部零改动。
- index.tsx:新增 `resourceCanvasSceneSize()`,视口居中、「适应内容」、总览入场中心、滚轮与缩放锚点都按"管理区盒子减掉工具条带"计算,不再按"场景一直顶到管理区顶端"排布;`handleResourceBookWheel` 与 `zoomResourceBookBy` 补上新增依赖。
- index.tsx:`measureResourceBookOverview()` 改用画本场景自己的 rect 作为总览栏目矩形原点,场景盒子上移后栏目矩形与世界坐标仍严格同源。
- project-development.suite.ts:在既有 CSS 声明级守卫里补断言——管理区 `padding-top` 与场景 `inset` 必须指向同一个 `--game-resource-book-tools-height` 变量,工具条带是绝对定位的独立排布行,栏目标题栏 z-index 低于工具条带;选择器加行首断言,避免误取 `.game-workbench-stage > .game-resource-manager`。
- project-development.suite.ts:在栏目大纲用例里补真实渲染的 DOM 归属断言——搜索框的父链不得命中画本场景或资源总览层,工具条带是管理区直接子节点;该断言在改动前失败、改动后通过,已用"把工具条带类名改掉"的变异验证它不是恒真假守卫。
2026-09-10 21:12:30 +08:00
suzmii dde860716e 修复资源卡片媒体预览发不出请求:线上 category 改回原生读取分支
- 新增 projectResourceMediaPreviewCategory:从卡片预览类型派生原生侧线上 category(art / audio),与画布分区栏目轴解耦
- read_local_project_media_preview 调用点不再传 job.resource.category:该字段自 6 类资产分类轴落地后是画布栏目(unclassified / ui-interaction / …),传给原生侧会被 read_local_project_media_preview_at 以「媒体预览类别只支持 art 或 audio」直接拒绝
- 该回归导致所有走媒体分支的卡片(GIF / SVG / AVIF / BMP / MP4 / WebM / MOV 与音频)读不出预览,只显示占位图标
- previewReadErrorMessage 与 resourceReadKindLabel 改用卡片预览类型判定文案,不再依赖已换语义的 category
- 废弃 useProjectResourceCardPreviews 对 projectResourceDisplayKind 的引用,错误文案与读取路由共用同一分类口径
- 预览 Hook 用例补「扩展名图片按 art 分支发出请求」与「音频仅在播放意图后按 audio 分支发出请求」两条断言,直接钉住原生侧线上取值
- 应用层媒体用例补 icon.svg 的 category 必须是 art 的断言,并修正原先描述「媒体读取改传画布栏目」的过期注释
2026-09-10 20:59:22 +08:00
suzmii 2f8753f597 AGC 资源画布切换为 6 类资产分类加项目版本栏目(阶段二:投影轴与栏目表落地)
- 契约层把 ProjectResourceCanvasPosition.section 加宽为 PersistedProjectResourceCanvasSection 并删除旧 ProjectResourceCanvasSection 联合
- 七个分区类型消费点改用 ProjectResourceCanvasCategory:投影、布局模型、布局 Hook、分区高度、依赖图层与画布历史
- RESOURCE_CANVAS_SECTION_ORDER 改为 PROJECT_RESOURCE_CANVAS_SECTIONS,删除 RESOURCE_CANVAS_VISIBLE_SECTION_ORDER
- reconcileResourceCanvasLayout 接入读时归一化:旧栏目值按资源当前分区改写 section,坐标与手动标记原样保留
- 归并后的布局与原布局逐项不同,由既有协调路径判定 changed 并写回一次新分区,不引入迁移脚本
- 投影层五个资源入表点统一走 projectResourceCanvasCategory:项目版本独立成栏、Agent 回执归文档、其余按资产分类
- 新增 projectResourceDisplayKind 收敛 manifest 资产 subtype 即 kind 的显示类型口径,projectResourceTypeLabel 不再依赖旧栏目
- 卡片预览、编辑分流、媒体工具条、预览文案与画布历史快照改用显示类型与新分区,历史快照入栈时收窄到现行分区
- index.tsx 删除可见栏目导入与 visibleCategoryOrder,栏目标签由资源筛选唯一中文口径派生并补齐 7 栏
- index.tsx 补齐 7 栏默认视口与 7 个栏目图标(新增 LayoutGrid、Users、PackageOpen,移除已无用的 Code2)
- index.tsx 删除 canvasResources 的 code 过滤:只登记游戏代码的项目现在落在待归类栏目并正常显示卡片
- 新增只登记游戏代码项目的 UI 回归用例,覆盖栏目大纲、默认落地栏目与代码卡片渲染
- 测试夹具按新分区轴迁移,新增旧栏目 sidecar 读时归并用例与栏目顺序用例
- 共享测试 harness 的资源卡查询正则允许栏目标签自带空格(UI 交互)
- 同步 PRD 与共享记忆决策记录的栏目口径描述
2026-09-10 20:41:19 +08:00
suzmii eda34187fc 修复 AGC 资源栏目大纲常态不可读:恢复 Dock 底板、栏目图标与完整文字
- styles.css:`.game-resource-outline` 常态从 `opacity: 0.68` + `scale(0.86)` + 透明底 + 无阴影,改回完整尺寸(`opacity: 1`、`transform: translateY(-50%)`)并给现有视觉语言的 Dock 底板(`--platform-subpanel-border` 边框 + `--platform-nav-fill` 背景 + 与右下角缩放 Dock 同款阴影 + `blur(6px)`)。
- styles.css:`.game-resource-outline button` 常态列宽由 `0 minmax(0,1fr)` 改为 `18px minmax(0,1fr)`、`gap: 6px`,栏目图标常态 width 14px / opacity 1,不再只在悬停时才出现。
- styles.css:栏目文字 11px → 12px;当前栏目(`.is-active`)常态就带 `--platform-nav-active-*` 的边框、底色和阴影,用户一眼能认出当前分区。
- styles.css:悬停/键盘聚焦保留为同一套 token 的加强(更深的边框、`--platform-nav-active-shadow`、`blur(10px)`),不再靠"常态缩到只剩文字"表达层级。
- 不改交互语义:大纲仍然是 `openResourceBookChild` 的入口,按钮 key、aria-label、aria-current 与未读小圆点全部保持原样。
- 测试:新增 CSS 声明级断言,钉住常态不降透明度、不 scale、有底板,图标常态 14px 且文字 12px(jsdom 不加载 styles.css,可见性只能钉声明)。
- 测试:新增 DOM 用例,断言每条栏目入口同时具备图标与栏目文字,且切换栏目后当前项带 `aria-current="page"`。
- 文档:同步《GameAgent资源自由画板与快速编辑》的「操作边界」与「验收」两条,把"常态缩小、只露栏目文字"改成"常态即可读可点",并同步 pitfalls 里的对应口径。
2026-09-10 20:11:09 +08:00
suzmii 9196ba3c96 修复 AGC 资源画本框选没有任何颜色:给画本场景根补共享画布根类
- index.tsx:`ResourceBookScene` 的场景根 `.game-resource-book-scene` 补上 `genarrative-image-canvas` 类,让共享 `SelectionOverlay` 的框选 token 有定义它的祖先。
- 根因:共享选择框的 `border: 1px solid var(--genarrative-image-canvas-selection-border)` / `background: var(--genarrative-image-canvas-selection-fill)` 没有 fallback,这两个 token 只声明在 `packages/image-canvas-react/src/styles.css` 的 `.genarrative-image-canvas` 根类里,而该根类由共享 `CanvasViewport` 渲染;AGC 只渲染 `SelectionOverlay`、从不渲染根类,声明在计算值阶段被整条丢弃,用户框选时看不到任何选择框。
- 安全性:该根类只有 3 条自定义属性声明、无布局副作用,加 className 不改布局。
- 测试:新增真实 `pointerdown` / `pointermove` 框选用例,断言选择框存在、内联几何非空,且最近的 `.genarrative-image-canvas` 祖先就是画本场景根;去掉根类后该用例失败(已实测)。
- 测试:新增 CSS 声明级断言,钉住根类的描边/底色 token 存在且非透明,消费端仍按 var() 取值(jsdom 拿不到计算色,这里只能钉声明)。
- pitfalls.md:补记"复用共享画布子组件要自己渲染根类"的排查口径。
2026-09-10 20:00:42 +08:00
suzmii 7e6f7555eb 修复 AGC 资源搜索框被 display: none 误关导致的搜索链路死代码
- styles.css:`.game-resource-search` 的 `display: none` 恢复成 `display: flex`(原始提交 3a8dff140 里就是 flex,PR #193 重排工作台时被改成 none),并补 `position: relative; z-index: 40`、常态 `align-self: center`、与右下角缩放 Dock 同款的浮层阴影。
- styles.css:`.game-resource-live-notice` 同样补 `position: relative; z-index: 40`;「清除搜索并定位」按钮只在这条提示条里,提示条被画本场景盖住时搜索链路依旧是断的。
- 根因(堆叠顺序):资源卡与栏目标题栏都画在 `.game-resource-book-scene`(absolute + z-index 20,子画布态还有一层不透明点阵底)里,而搜索框与提示条是 `.game-resource-book-manager` 的流式子节点;定位元素按绘制顺序整体盖在流内内容之上,所以只放开 display 等于"画了但看不见、点不到"。
- 可见性口径:AGC 的 vitest 没开 `css: true`、不加载 styles.css,`toBeVisible()` 在这里是恒真的假守卫;新增的守卫按本仓既有口径读 CSS 源文件做声明级断言(不是 display:none、z-index 高于画本场景)。
- 行为用例:总览态输入即过滤总览摞上的卡片;分页画布态同一搜索条件继续生效、清空后卡片恢复,证明这条链路确实由搜索框驱动。
- 端到端用例:搜索条件挡掉刚提交的新素材时保留条件并提示,点「清除搜索并定位」后清空搜索并定位选中新素材。
2026-09-10 19:59:52 +08:00
suzmii cb76aadb48 AGC 输入区三处观感修复:AI 润色归位、@ 面板筛选条单行、引用 chip 原子化
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 3m5s
Project CI / Native shell tests (pull_request) Successful in 18m26s
- styles.css:把 direct-codex composer 下广播式的 `.project-supervisor-composer button` 规则
  收窄到 `.project-supervisor-submit-button`(含 svg 那条与 media query 里那条),
  并给 `.resource-reference-input-actions` 补 `grid-column: 1 / -1` 让输入区操作排独占一行
- styles.css:`.resource-reference-input-actions` / `.resource-reference-input-at` 撤掉绝对定位,
  操作排回到网格文档流,与输入框右下角对齐,不再浮在文本区中间
- styles.css:`.resource-reference-input-polish` 与 `.resource-reference-input-restore` 并入
  `@` 按钮同一条尺寸规则(28px 方钮、8px 圆角、同 hover/disabled 观感)
- styles.css:输入区状态行(润色中/润色失败)改为与应用排同一行,不再单独占一行顶高 22.8px
- styles.css:direct-codex 输入框 padding 收为 `12px 15px 6px`,窄屏 `10px 12px 6px`
- styles.css:`.resource-reference-chip` 的 `×` 删除按钮不再被 broadcast 规则摘出 chip
- PlatformSegmentedTabs.tsx:分段页签 item 加 `whitespace-nowrap`,中文不再逐字竖排
- packages/shared/styles.css:补 `.scrollbar-hide` 实现(该类名一直被 `layout="scroll"` 引用但仓库未定义)
- ResourceReferenceNode.tsx:`getTextContent()` 改为单个 U+FFFC 占位符并显式实现
  `getTextContentSize()`,引用成为真正的原子内联节点(1 个引用 = 1 个字符)
- tests/resourceReferenceInput.test.tsx:新增「1 个引用 = 1 个字符」与「chip 自带删除、一次删净」两条断言
- tests/appSurface/project-development.suite.ts:把 composer 按钮样式断言收窄到提交按钮,
  并新增一条反向断言,钉住「广播到 composer 下所有 button」的规则不再出现
2026-09-10 19:05:57 +08:00
suzmii 8f96b05f6e 资源画布工具条接回下载按钮:走资源面板同一条真链路并收紧放行判据
- index.tsx 把资源面板的保存流程抽成共用 saveProjectResourcesToDisk(原生保存对话框 + save_local_project_asset_file),资源面板改为委派调用,不再有第二份保存实现

- index.tsx 工具条 onDownloadLayer 由空回调改为调用该共用 handler,回执写进 resourceWorkbenchNotice;不可导出的资源仍直接返回

- resourceCanvasToolbarModel.ts 把 download 加回 supportedActions,判据是 isResourceCanvasExportable(拿不到本地文件路径就不渲染),不按媒体类型放行

- resourceCanvasToolbarModel.test.ts 期望值随判据重算为 [quick-edit, download] 或 [download],并补 download 放行与拒绝两侧用例(空 path、虚拟版本条目)

- project-development.suite.ts 音频工具条按钮集合断言更新为 [分类与标签, 重命名, 下载按钮],并新增两条真链路断言:工具条下载打到 save_local_project_asset_file、资源面板下载仍打到同一命令

- appSurface.test.ts 在入口文件 mock 原生对话框,只替代用户选择目标路径这一步;放别处注册会晚于真实模块实例化
2026-09-10 18:05:15 +08:00
suzmii ecca7050b5 音频资源工具条断言改判据:不再要求渲染空回调的改造按钮
- project-development.suite.ts 的音频工具条断言由「必须存在改造按钮」改为「不得存在改造按钮」+「按钮集合精确等于分类与标签、重命名」

- fed17ea08 已按共享记忆 pitfalls.md 的判据(渲染出来的动作必须真的能跑通)把 redraw 与 character-animation 移出 supportedActions,音频分支只剩宿主编排层真实接通的分类与标签、重命名,原断言断言的是被该提交推翻的旧合同

- 新断言比旧断言更严:除钉住音频分支仍在渲染,还钉住整条工具条的按钮集合,避免再出现点了没反应的假按钮
2026-09-10 17:53:15 +08:00
suzmii f247a5106a 收敛资源画布交互复刻的测试:清理详情面板遗留断言,门禁回到基线
删除用例 keeps the resource toolbar and canvas interactive while a non-modal detail card is open:该用例断言的「非模态详情卡」已被 C3 合同取消,按四不写删除

新增用例「资源卡 chrome 只保留选中按钮与当前版本边框」,接住被删用例里仍然有效的卡片 chrome 断言(无基础描边、is-current-version 边框、选中按钮样式)

版本卡与 Agent 回执卡没有美术画布动作,断言改为选中反馈(aria-pressed)而不是工具条

blocked.md 的策略失败提示原本渲染在已删除的详情面板里,断言随之移除

快速编辑测试的 fixture 增加栅格美术资产(includeArt 参数),不改动其它用例的 manifest
2026-09-10 15:29:15 +08:00
suzmii bd36587e0a 资源画布交互 1:1 复刻美术画布:点卡选中并浮出工具条,移除资源详情面板与全屏编辑路由
新增 features/resource-canvas:资源卡到美术画布 CanvasLayer 的适配、工具条动作可用性判定、C5 当前版本绑定判定、快速编辑草稿工厂与 AGC 宿主 chrome 样式

资源卡点击改为选中(Shift/Ctrl/Meta 多选),选中后在卡片旁复用 ImageCanvasSelectedLayerToolbarView 浮出工具条

快速编辑复用 ImageCanvasQuickEditPanelView 浮层面板,先调 normalize_local_project_raster_resource 正规化任务产物,再走 derive_local_project_resource(editKind=image-reference) 产出新素材,失败重试复用同一 operationId/idempotencyKey

删除 resourceEditorRoute 全链路(ResourceEditSurface 路由、openResourceEditor、handleResourceCardOpenEditor、cancelResourceEditor、submitResourceEdit)与资源详情面板(focusedResource 状态/引用/浮层 JSX/CSS 断言)

分类与标签入口搬到选中工具条;UI 资源保留「UI 编辑器」入口并从工具条打开

移除 apps/ai-game-creator-shell/scripts/check-config.mjs 中 normalize_local_project_raster_resource 的过渡 allowlist 条目

为共享工具条组件新增 opt-in 的 supportedActions/extraActions(默认 null/undefined,网页端行为不变)

AGC vite-env.d.ts 补 wx/ReactNativeWebView/WeixinJSBridge 跨端全局声明;hostBridge fail 回调补显式 unknown 类型

测试:资源卡查询 helper 由资源详情按钮改为选中按钮,清理详情面板断言,画布空白左键改为框选后平移用例改用中键
2026-09-10 15:19:17 +08:00
suzmii 53afc85319 修正 AGC 测试按新的 Lexical 聊天输入区驱动与断言
- appSurface/harness 补齐三处 jsdom 缺口:ClipboardEvent、DragEvent、Range.prototype.getBoundingClientRect;否则 Lexical 的粘贴通路直接抛 ReferenceError / TypeError
- appSurface/harness 的 submitChat 改为 async:全选并让编辑器吸收选区、清空、走产品真实 paste 通路写入,再让出一帧让 React 追平 draft,最后点发送
- 新增 composerText / composerValue / composerDisabled / setComposerText 助手,按原生控件与 Lexical contenteditable 两种 DOM 口径读写输入区
- 15 个测试文件中 116 处 toHaveProperty('value', …) 断言等义改写为 await composerText() / await composerValue();1 处 placeholder 断言改查输入区占位文案;2 处 disabled 断言改用 composerDisabled(同时覆盖 data-disabled 与 contenteditable=false);9 处 fireEvent.change 写入改用 setComposerText
- 328 处 submitChat 调用补 await,9 个非 async 用例补 async
- Godot 输入区键盘语义用例按 Lexical 实际行为改写:Shift+Enter 与组合态 Enter 由编辑器消化并插入换行、不发送、草稿保留
- 未改动 src 下任何产品代码,未放宽或删除断言
2026-09-10 11:46:02 +08:00
suzmii 691d0a8ce6 修正 AGC 资源卡测试查询的资源详情按钮选择器歧义
- appSurface/harness 新增 getResourceDetailButton / findResourceDetailButton / queryResourceDetailButton,按产品可访问名模板「打开资源详情:<分类标签> <资源文件名>」精确匹配,不再用会同时命中 @ 引用按钮的文件名正则
- project-development.suite 的 23 处资源卡按钮查询改用精确查询助手
- home.suite 的 7 处资源卡按钮查询改用精确查询助手
- projectResourceLiveIntegration.test 的 /rules\.md/ 按钮查询改用精确查询助手
- 未改动 src 下任何产品代码,未放宽任何断言
2026-09-10 10:15:50 +08:00
suzmii 4582231b78 合并 C3:资源画本转场改为真实元素 FLIP
- 合入 feat/agc-canvas-real-flip(resourceBookController 重写为同节点 FLIP、新增 sync 可中断重基、删除 ResourceBookTransitionLayer)
- 冲突解决:index.tsx 的 resourceBookLayout 导入取 C3 版(buildResourceBookScenePlan 等),去掉已被收进内部的旧 helper 导入避免未使用
- 冲突解决:资源自由画板文档的验证命令合并两侧并去掉已删除的 assetCanvasSurface.test.tsx
2026-09-09 21:24:13 +08:00
suzmii 4fb0de2c94 C3 资源画本转场改为真实元素 FLIP
- resourceBookController 重写为真实元素 FLIP:begin 在提交前记录 First,play 测 Last 后给同一节点加反向 transform,sync 按布局签名做可中断重基
- 转场进行中重基用剩余时长(下限 80ms),空闲布局变化用完整 420ms,预览图尺寸晚到的二次布局变化不再瞬移
- 宿主节点几何基准改存 world 局部坐标,平移和缩放不会让上一次的干净矩形过期
- 不可见节点钉在 First 淡出、挂载节点淡入;搜索/排序导致的卸载保留一帧淡出;返回总览时源栏目未回到摞上的卡片按子画布布局淡出
- 新增 buildResourceBookScenePlan 渲染计划,渲染、转场签名与淡出集合共用同一份数据
- 删除 ResourceBookTransitionLayer 与克隆快照逻辑,清理 styles.css 的转场层和 data-book-motion 隐藏规则
- 重写 resourceBookController.test.ts,补 resourceBookLayout/resourceBookModel 用例与 appSurface 同节点断言
- 同步技术方案转场段与 pitfalls 经验条目
2026-09-09 20:24:10 +08:00
suzmii 05d4d6d1d3 删除 asset-canvas 测试并同步资源派生测试口径
- 删除 tests/assetCanvasSurface.test.tsx(4310 行,63 个用例全部属于草稿画布 Surface)
- projectResourceLiveIntegration.test.tsx 删除 AssetCanvasSurface mock、discover/recover 两个命令 stub、normalize_local_project_raster_resource stub、TaskImageWorkbench 与 4 个草稿精修用例;保留文档资源走资源编辑的用例
- project-development.suite.ts 把 showRunUnavailableHint 源码护栏正则去掉 !assetCanvasRoute,并把"in-place refine 预览失效"用例改写为仍有效的 preview version 装配与项目切换清理
- resourceEditModel.test.ts 把 PNG/WebP 两例从 image-canvas 改为 derive + image-reference,并移除 normalizeSource 断言
2026-09-09 20:05:07 +08:00
suzmii 1abbbadb07 合并最新 master 到 AGC V3 资源画布分支
- 合入 origin/master 67 个提交(含 #285 无限画布图标模糊修复、#307 客户端常用设置读写卡顿修复等)
- index.tsx 冲突按 V3 画本结构解决:保留 resourceBook 画布场景,未采用 master 的 CanvasWorld 包装
- 原因:game-resource-page-world 现仅承载依赖连线层,CanvasWorld 使用固定 12000 世界尺寸,会破坏按内容自适应的边界
- 保留 AtSign 图标导入(V3 引用输入区使用)
- 合并后 npm run ai-game-creator-shell:typecheck 通过
2026-09-09 18:12:09 +08:00
lhk229 04128eb661 Merge branch 'master' into feat/design_agent_simple
Project CI / Repository checks (pull_request) Has been cancelled
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 (push) Successful in 2m48s
Project CI / Frontend tests (push) Successful in 3m26s
Project CI / Backend tests (push) Successful in 7m17s
Project CI / Native shell tests (push) Successful in 19m27s
2026-09-09 16:34:16 +08:00
k88936 7288c6f641 Fix/修复无限画布图标文字模糊 (#285)
Project CI / Repository checks (push) Successful in 2m59s
Project CI / Frontend tests (push) Successful in 3m29s
Project CI / Backend tests (push) Successful in 8m37s
Project CI / Native shell tests (push) Successful in 20m55s
closes #279
closes #284

实现: 从2(暂定)倍放大绘制的画布scale 0.5* 真正的scale

before:
![shotmd-1788579338.jpg](/attachments/9d44ec5e-454c-449b-86bc-b2131fbbc8cc)
![shotmd-1788578910.jpg](/attachments/c9da61a2-b467-43eb-a5de-e5e4d5cb8f70)

after:
![shotmd-1788580930.jpg](/attachments/f1f06e8e-90bf-45e2-a30b-a63ccc308c19)
![shotmd-1788583400.jpg](/attachments/c48ca741-e470-42b3-8030-064e0579f63a)
svg看起来stroke窄了一点点, 可以接受

Reviewed-on: #285
2026-09-09 16:32:43 +08:00
suzmii 6d3d24df5e 合并 #283 资源画本画布实现
合入 feat/game-agent-canvas-resource-workbench-v2 的完整画布实现:资源画本控制器/模型/视口/布局、转场层、资源分页缓存与自动聚焦修复、资源总览卡片预览懒加载
保留本分支已有的聊天素材引用改动(引用输入区、@ 引用按钮、运行画面点选)
解决 index.tsx 状态声明与 pitfalls.md 文档冲突;styles.css 去重后仅保留一份画本视觉层
2026-09-09 15:43:32 +08:00
lhk229 852d9af483 合并最新 master
Project CI / Repository checks (pull_request) Successful in 2m44s
Project CI / Backend tests (pull_request) Successful in 13m7s
Project CI / Frontend tests (pull_request) Successful in 13m55s
Project CI / Native shell tests (pull_request) Failing after 29m47s
同步远端主线至 b129589e7

保留当前分支的 V1 清理与主线文档和测试更新
2026-09-09 06:06:35 +00:00
lhk229 310091d28e 合并最新 master
Project CI / Repository checks (pull_request) Failing after 9s
Project CI / Backend tests (pull_request) Failing after 9s
Project CI / Frontend tests (pull_request) Successful in 6m0s
Project CI / Native shell tests (pull_request) Has been cancelled
同步主线 DirectProject 历史与 Markdown 展示改动

保留策划 V2 退役方案文档索引
2026-09-09 05:49:33 +00:00
suzmii 07fc26953a 修复AGC模型目录同步的加载态与保存竞态
Project CI / Repository checks (pull_request) Successful in 2m56s
Project CI / Frontend tests (pull_request) Successful in 3m45s
Project CI / Backend tests (pull_request) Failing after 4m34s
Project CI / Native shell tests (pull_request) Failing after 7m54s
- ConversationModelSelect:目录同步与配置读取/写回失败时统一在 finally 收起加载态,避免选择器永久卡在 busy、无法切换或刷新
- ConversationModelSelect:配置读取失败单独提示「读取客户端配置失败」,不再误报为模型目录加载失败
- ConversationModelSelect:配置写回串行化,发送前校验等待在途保存并读取最新配置,避免保存中放行旧选择、或用旧快照覆盖刚完成的选择
- ConversationModelSelect:服务端未返回 revision 时按目录已变化处理,避免界面停止刷新
- ProjectSupervisorView:提交前模型校验期间禁用输入框与发送按钮,避免重复提交与校验窗口内编辑丢失
- 测试:补充配置读取失败恢复、保存中发送前校验等待、目录请求去重用例;修正依赖配置读取时序的 appSurface 用例
- 文档:修正首页入口「按需加载」与实现不符的描述
2026-09-09 12:00:10 +08:00
suzmii 2942489575 Merge remote-tracking branch 'origin/master' into feat/agc-client-sync-llm-config
Project CI / Repository checks (pull_request) Successful in 2m49s
Project CI / Frontend tests (pull_request) Successful in 3m26s
Project CI / Native shell tests (pull_request) Failing after 4m12s
Project CI / Backend tests (pull_request) Failing after 4m13s
# Conflicts:
#	apps/ai-game-creator-shell/src/features/project-workspace/ConversationModelSelect.tsx
#	apps/ai-game-creator-shell/src/features/project-workspace/ProjectSupervisorView.tsx
#	apps/ai-game-creator-shell/tests/conversationModelSelect.test.tsx
#	docs/technical/【技术方案】AGC后台模型别名与对话选择-2026-09-05.md
2026-09-09 10:04:05 +08:00
suzmii a0e6a83691 修复 AGC 模型选择入口、交互与默认模型回退 (#299)
Project CI / Repository checks (push) Successful in 2m19s
Project CI / Frontend tests (push) Successful in 3m32s
Project CI / Native shell tests (push) Failing after 19m48s
Project CI / Backend tests (push) Failing after 7m10s
### 背景

AGC 后台已支持维护 LLM 模型目录(`agc_model_catalog`),客户端此前只在项目右侧对话浮出模型选择,且存在几个体验问题:

1. 首页聊天框架缺少模型选择入口;
2. 首次进入项目时,右侧模型选择器「点不动」(被 disabled);
3. 模型选择下拉失去焦点不自动收起;
4. 默认模型缺少可视标识;
5. 已保存的选择被后台停用/移除后,客户端显示「请选择模型」,未自动回退默认模型;首页因懒加载在打开前也一直显示「选择模型」。

### 改动内容(完整变更集)

- **首页聊天框架新增模型选择入口**,复用项目右侧对话的 `ConversationModelSelect`;上传按钮在左,模型选择器与发送按钮在右(同一组,模型选择器紧挨发送按钮)。
- **修复首次进入项目时右侧模型选择器点不动**:选择器不再因目录加载(`busy`)或对话进行中(`controlBusy`)被禁用;切换模型只写回客户端配置并作用于后续轮次,发送仍由 `controlBusy` / `modelReady` 把关。
- **模型下拉支持点击外部 / Esc 自动收起**:给组件容器挂 ref,监听 `document` 的 `mousedown` 与 `keydown`,点击容器外或按 Esc 即收起(仅在展开时挂监听)。
- **默认模型增加「默认」标识**:组件记录 `defaultModelId`,在下拉选项中给默认模型显示小标签;亮暗主题自适应。
- **模型选择始终回退默认模型**:已保存选择仍可用时沿用;被停用/移除或从未选择时回退到后台默认模型并写回配置;只有默认模型本身不可用才走错误分流。首页由「懒加载」改为「挂载即加载」,触发按钮直接落在默认模型上,不再出现「选择模型」空态。
- **清理**:移除组件中已无调用方的 `lazy` 加载路径。
- **文档**:同步更新 `【技术方案】AGC后台模型别名与对话选择-2026-09-05.md`(首页入口、对话进行中可切换模型、失焦收起等行为)。

### 关键交互/行为说明

- 触发按钮永远显示模型名(默认或当前选择),不再出现「选择模型」占位,除非默认模型不可用。
- 模型下拉的加载中、刷新、选中态沿用原有交互;默认模型有「默认」标签,便于识别。
- 首页模型选择器不改动「开启创作」门控:目录不可用时仍可创建项目并走后台默认项。

### 验证

- `npm run test -- apps/ai-game-creator-shell/tests/conversationModelSelect.test.tsx` -> 7/7 通过
- `npm run test -- apps/ai-game-creator-shell/tests/appSurface.test.ts` -> 386/386 通过
- `npm run ai-game-creator-shell:typecheck` 通过
- `npm run check:encoding`(4309 文件)通过
- `git diff --check` 通过

### 影响范围与注意事项

- 变更集中在 AGC 客户端(`apps/ai-game-creator-shell`),不涉及 SpacetimeDB schema / 后端接口 / 契约。
- `GET /api/llm/models` 语义不变(仍只返回启用项 + 默认项),本次不改后端。
- 模型下拉在窄屏的换行/遮挡,以及「默认」标签对比度,建议在真机确认一下观感(单测只覆盖逻辑)。

### 关联

- 无关联 Issue;本 PR 独立提交。

---------

Co-authored-by: 段舒康 <kdletters@qq.com>
Reviewed-on: #299
Co-authored-by: 董羽秦 <suzmii@qq.com>
Co-committed-by: 董羽秦 <suzmii@qq.com>
2026-09-08 22:05:15 +08:00
k88936 d3f5d0a355 feat/AGC codex的工具调用 持久化处理 (#282)
Project CI / Repository checks (push) Successful in 2m7s
Project CI / Frontend tests (push) Successful in 2m46s
Project CI / Backend tests (push) Failing after 3m53s
Project CI / Native shell tests (push) Failing after 3m50s
重构directproject的thread持久化,  保存response items用来恢复thread

修改了DirectProject的对话jsonl格式,  不兼容不迁移. (测试需要手动清理旧对话jsonl文件)

AGC显式写入user msg, 对codex 返回的user msg忽略
清理原来的上下文滑动窗口, 因为codex内部会自动compact

工具调用后重启,继续对话:
![shotmd-1788579616.jpg](/attachments/8350c924-9498-47cd-b3da-8be6b79696f9)

close #249
close #277

---------

Co-authored-by: 段舒康 <kdletters@qq.com>
Reviewed-on: #282
Co-authored-by: 王德宇 <kvtodev@outlook.com>
Co-committed-by: 王德宇 <kvtodev@outlook.com>
2026-09-08 22:04:37 +08:00
k88936 01e057d047 Feat/AGC对话渲染markdown (#281)
Project CI / Repository checks (push) Successful in 3m24s
Project CI / Frontend tests (push) Successful in 3m37s
Project CI / Backend tests (push) Failing after 4m13s
Project CI / Native shell tests (push) Failing after 4m11s
before:
 ![image.png](/attachments/ca6f46f7-dcbd-4132-bad2-cf5c83c49096)

after:
 ![shotmd-1788500615.jpg](/attachments/719539a1-9dfb-412a-a9b9-298547b1791c)
![shotmd-1788500598.jpg](/attachments/4656815f-caca-4325-bca3-b29fe5742b6e)

考虑到在AGC场景下不是很有理由, 暂不实现链接, 图片, 内嵌html

---------

Co-authored-by: 段舒康 <kdletters@qq.com>
Reviewed-on: #281
Co-authored-by: 王德宇 <kvtodev@outlook.com>
Co-committed-by: 王德宇 <kvtodev@outlook.com>
2026-09-08 22:03:37 +08:00
lhk229 14d76419b8 修复策划回答身份绑定与迟到恢复结果覆盖
Project CI / Repository checks (pull_request) Successful in 2m48s
Project CI / Backend tests (pull_request) Successful in 6m28s
Project CI / Native shell tests (pull_request) Failing after 13m45s
Project CI / Frontend tests (pull_request) Successful in 44m47s
在既有回合锁内核对问题与会话身份,保留已完成回合重放。
前端回答携带卡片问题标识,hydrate 写回前检查请求序列和项目路径。
补充后端与界面回归测试,同步技术合同与项目决策。
2026-09-08 13:25:24 +00:00