合入 master 并解决模板库分支冲突
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

- directActiveTurns:保留 master 的重试定时器清理与本分支的快照签名去重(两侧在同一位置相邻插入)
- directActiveTurns 测试:合并两侧用例(master 的定时器清理与面板用例 + 本分支的快照引用稳定用例)
- decision-log:两侧新增条目都保留(AGC 模板库约定 + CI 宿主 CPU 上限)
- 冲突后复核:cargo check 0 错误、tsc 通过、33 项前端单测通过、编码 / 文档索引 / diff 检查通过
This commit is contained in:
kdletters
2026-09-17 17:44:29 +08:00
75 changed files with 4331 additions and 247 deletions
@@ -0,0 +1,26 @@
# AGC 对话历史分页恢复实施计划
- Date: 2026-09-16
- Status: awaiting-runtime-acceptance
- Milestone: [AGC 对话历史分页恢复](./【里程碑】AGC对话历史分页恢复-2026-09-16.md)
## 实施
1. 原生历史读取复用逐行解析,增加消息模式,过滤后分页并返回已有原始消息 ID 游标;保持原始接口默认行为和路径权限。
2. 工作台首屏与更早消息读取显式请求消息模式,消费游标;加载代次隔离、单飞与 ID 去重。
3. 合成记录测试复现原始工具页卡住的形状,覆盖旧无 ID、坏行、时间、失败/重复/切项目;临时目录只读重放用户日志。
4. 前端/原生定向测试、类型、Lint、编码、文档和差异检查通过后,更新问题表及 PR 草稿并本地提交。
5. 在临时消息投影中标记历史来源,保留 Runtime 所有权语义;刷新合并时只保留非历史来源的待回读消息。补齐「先加载旧页,再 /history,再翻页」的顺序与去重回归,保持尚未落盘用户输入的保留逻辑。
## 边界与停止条件
不调整 Direct 消息呈现归属、不修未证明的写入丢失、不上传日志、不触碰用户项目。必要 API 变化仅为本地 IPC 可选参数和游标字段;无 OpenAPI、SpacetimeDB 或持久化迁移。远程推送/PR/WIP 操作仍待额外确认。
## 验收证据
- 历史消息模型、回合呈现及分页集成共 24 个前端测试通过;包含真实 App 的首屏/更早页、单飞、失败重试、重叠消息、同项目重新加载及离开再进入的迟到响应。
- 16 个历史原生测试通过;人工日志重放用例在 CI 默认忽略,已在本地单独执行通过。
- 使用用户提供的原始日志运行修复后的原生读取:44 条现存聊天消息(含 2 条用户消息)分 3 页取回,逐项内容与顺序一致,原文件字节未变;未在仓库保存原始日志。
- 工作台/Direct 恢复与画布导航的 8 个定向回归通过。真实客户端重新进入与向上翻页尚待用户验收;本次涉及 Rust IPC,需重新构建并启动原生端。
- 与前面画布/JSON 修复联合复验:119 个前端定向测试、30 个原生测试通过;AGC TypeScript、修改文件 ESLint、编码、文档索引和差异检查通过。
- 状态只覆盖日志中已经证明的分页卡页,不据此宣称其它可能的未落盘消息也已恢复。
@@ -0,0 +1,44 @@
# AGC 画布交互稳定性修复实施计划
- Date: 2026-09-16
- Status: awaiting-runtime-acceptance
- Milestone: [画布交互稳定性修复](./【里程碑】AGC画布交互稳定性修复-2026-09-16.md)
## 修改顺序与边界
1. 将临时诊断收敛成正式回归测试,覆盖窗口 Context 反馈、提示条件和鼠标/触摸板事件。
2. 稳定工作台打开项目的转发回调,保持最新处理器语义,不改项目加载逻辑。
3. 解耦运行提示与选择;在原有画布事件链加入右键平移、菜单边界和中断清理,不另建控制器。
4. 执行定向验证并检查首次加载、平移和原有框选/卡片拖动回归。
## 验证
- 定向 Vitest:窗口工作台、画布交互、布局与原有导航用例。
- 运行提示的源码契约与交互回归同时覆盖:提示仅取决于运行能力和 UI 编辑器路由,不依赖资源选择;选中资源后提示及 `aria-describedby` 保留,点击运行仍不能进入不可用视图。
- AGC `tsc --noEmit`;`npm run check:encoding`、`npm run check:doc-index`、`git diff --check`。
- 真实客户端首次进入和触摸板操作无法以 jsdom 代替;未实测时保持待验收。
## 风险与停止条件
窗口反馈测试必须有更新次数上限,避免未修复代码让测试失控。右键仅接管画布背景/卡片,不抢输入控件与浮层。新增问题只有影响本次验收才扩大范围;不根据猜测修改 B01/B02 的布局与动画。
回滚仅限本批局部补丁;不重置工作树,不覆盖其它修改。完成自动化验证后停在真实客户端验收,不推进额外功能。
## 问题状态
| 编号 | 问题 | 状态与证据 |
| --- | --- | --- |
| B01 | 刷新后首次进入画布元素抖动 | 已优化;用户在本轮反馈未再复现,按用户要求更新状态。不宣称所有布局/动画原因均已排除。 |
| B02 | 初次进入双指平移无效,整理后恢复 | 已优化;用户在本轮反馈未再复现,按用户要求更新状态。隔离组件连续平移通过。 |
| B03 | 快速平移触发更新深度错误 | 已修复已确认的窗口 Context 反馈循环,回归验证收敛;真实操作继续观察。 |
| B04 | 资源选中后运行不可用提示消失 | 已修复,提示与选择解耦,自动化验证通过。 |
| B05 | 对话记录偶发丢失 | 已修复日志复现的历史分页卡点:消息模式过滤后分页、原生游标与读取代次隔离。原生只读重放分 3 页取回全部 44 条现存消息,原文件未变;真实客户端待验收,不扩大为其它未落盘记录已恢复。 |
| B06 | JSON 文档未正确识别展示 | 已按用户确认完成本地修复:合法 UI State 由原生完整校验,卡片显示 UI 设计并进入现有编辑器;普通 JSON 显示 JSON 并可代码预览。自动化验证通过,待重建原生客户端验收;详见 JSON 语义识别实施计划。 |
| C01 | 右键平移,保留左键框选 | 已实现,卡片左键拖动、框选、指针取消/失焦/捕获丢失及控件边界测试通过。 |
## 已取得证据与剩余门禁
- 修复前新增回归测试能检出外壳重复发布、运行提示消失和右键无效;修复后窗口/画布定向测试通过,现有导航、框选、指针点击/取消、UI 编辑器返回平移和素材定位用例通过。
- AGC TypeScript、修改文件 ESLint、编码、文档索引及差异空白检查通过。
- 测试仍有既有 React 列表 key、旧用例 act/IPC 桩告警,未作为本批功能修复扩大范围。
- 用户反馈 B01/B02 本轮未再复现,记为已优化;右键手感与其它真实客户端细节继续观察。对话历史分页与 JSON 双路径均已本地修复并通过定向验证,待重建原生端后真实客户端验收。本计划保持开放。
@@ -0,0 +1,27 @@
# AGC 资源 JSON 语义识别实施计划
- Date: 2026-09-16
- Status: awaiting-runtime-acceptance
- Milestone: [AGC 资源 JSON 语义识别](./【里程碑】AGC资源JSON语义识别-2026-09-16.md)
## 实施边界
1. 原生 UI 持久化模块抽取可复用的内容解析与只读识别;文本预览返回可选的已验证 UI 资产身份。
2. 保留新设计初始化的严格 UI 资产门禁;已有 State 的加载/保存/生成按登记资源和真实文档校验,不依赖标签精确大小写。
3. 前端预览缓存透传识别结果;工作台卡片与编辑器入口消费同一结果,普通 JSON 详情使用代码块。
4. 单元、组件与原生测试覆盖合法/普通/损坏/跨身份/未登记和保存边界;保持先前画布修复。
## 验证与停止条件
- 定向 Vitest、Tauri persistence/resource preview 定向 Rust 测试、AGC TypeScript、修改文件 ESLint、编码、文档索引及 `git diff --check`。
- 不读取或修改用户项目原文件,不将日志或真实对话作为仓库测试夹具。
- 原生构建/真实客户端受环境限制时记录实际证据,不能以 TS 测试代替原生验证。
- 完成上述范围后停止;B05 已有分页卡点证据,本轮不顺带修改历史合同。
## 验证结果
- 92 个前端定向测试通过,覆盖原生结果驱动的卡片/编辑器路由、普通 JSON 代码预览、伪 UI 文本拒绝、读取失败、缓存切项目,以及原有画布导航与指针回归。
- 14 个 UI 持久化原生测试通过,包含有效 State 对多种登记标签的识别/加载/保存、未知 schema/字段与坏结构拒绝、项目/资产身份、普通 JSON 防覆盖及原有恢复/CAS 边界。
- 原生测试在 macOS 默认 `/var` 临时路径触发既有拒绝符号链接门禁;改用真实 `/private/tmp` 后通过,未放宽产品路径安全校验。
- AGC TypeScript、修改文件 ESLint 已通过。测试仍有既有 React key/act 告警及 Rust 未使用代码警告,不影响本批断言。
- 真实客户端的图片/UI State 体验仍待验收。本次包含 Rust 预览字段,必须重新构建并启动原生端,不能仅刷新前端就认为识别结果已更新。
@@ -0,0 +1,14 @@
# 抠图模式联调验收实施计划
依据:[里程碑](./【里程碑】抠图模式联调验收-2026-09-16.md)。
1. 主站修复 worker 对 auto/省略的门禁、空值契约和旧指纹;补接口、队列与 worker 定向测试。
2. 客户端独立核对 schema、参数校验、幂等意图、Skill 与契约说明。
3. 串行请求真实 BgFilter,凭据仅在进程内读取,不输出或落库。
4. 运行 cargo test 的 background_removal、bgfilter、OpenAPI 定向过滤,客户端定向测试;运行 doc-index、encoding、diff 检查。
5. 尝试 npm run dev:api-server 与 healthz smoke;记录真实登录/全链路未验证项。
6. 收敛证据到主规范,删除临时计划。
检查点:先通过契约测试,再开展运行时核验;不因环境缺失修改生产配置。回滚仅限本次局部补丁。
当前收口:主站及客户端修复和定向检查已执行,真实 BgFilter 四组成功及自动检测失败分支已验证;本地 API 启动被现有数据库连接配置阻塞。仅完整登录/队列/资源回写运行时证据尚待补齐,测试凭据和临时日志不得提交。
@@ -0,0 +1,20 @@
# AGC 对话历史分页恢复
- Version: 1
- Status: reviewed
- Date: 2026-09-16
- Parent Spec: [AGC 实施计划:DirectProject 回合展示唯一归属](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)
## 范围与评审
用户已要求修复 B05。已用用户提供的原始日志只读复验:原始切片被工具/推理填满时,聊天投影为空,消息游标不推进。修复聊天读取与分页,不改历史写入、不删除记录、不修改模型上下文,不扩大到其它尚无证据的对话丢失原因。
采用已有切片接口的显式消息模式与原生游标。原始模式缺省行为保持不变,旧无 ID 消息保留;前端以项目和加载代次隔离结果。本轮不包含远程写入。
## 验收
1. 工具/推理密集、末尾无消息、纯工具历史均不产生空页死循环。
2. 消息正文、原始 ID、时间和顺序保持不变,翻页能到达早期用户提问及最终回答,不重复。
3. 连点、请求失败重试、项目切换和同项目重新加载不会污染消息或游标。
4. 原始切片默认模式回归通过,用户日志只读重放可以取回全部现存消息;不把真实日志或对话正文提交到仓库。
5. 加载更早消息后重新读取历史,旧页不出现在最新回复之后;再次翻页保持顺序且不重复。未落盘的实时用户输入不因历史刷新被丢弃。
@@ -0,0 +1,26 @@
# AGC 画布交互稳定性修复
- Version: 1
- Status: reviewed
- Date: 2026-09-16
- Parent Spec: [AGC 实施计划:资源画布交互与工作台状态同步](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)
## 目标与范围
完成工作台标题栏状态更新循环、运行提示随选择消失、右键平移三项本地修复,保持左键框选与卡片拖动。不修改布局算法、持久化和后端;不开远程 Issue/PR、不推送。
## 评审
依据已完成的源码追踪、客户端错误日志及有界复现自检:状态归属仍在窗口与工作台原有边界内;交互修改只影响画布手势;没有数据迁移、权限或 API 变化。用户已确认右键平移及保留左键框选,并授权先尝试本地修复。真实客户端首次进入抖动与触摸板平移仍需另行验收。
## 验收
1. 工作台发布窗口状态后收敛;重复渲染不持续更新或清理,打开项目回调使用最新处理器,卸载清理有效。
2. 选中资源后运行不可用提示仍在,运行能力不变。
3. 子画布空白处及卡片右键平移不改变选择或坐标;左键框选与卡片拖动保留;总览支持右键平移。
4. 指针取消、失去捕获、窗口失焦终止平移;控件与浮层保留原有交互。
5. 连续平移测试、定向测试、类型检查、编码与文档门禁完成并记录限制;B01/B02 仅在真实复测后决定关闭。
## 依赖
当前源码与已安装测试依赖;真实 AGC 客户端验收环境。没有外部写操作依赖。
@@ -0,0 +1,26 @@
# AGC 资源 JSON 语义识别
- Version: 1
- Status: reviewed
- Date: 2026-09-16
- Parent Spec: [AGC 实施计划:文档与代码素材预览](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)
## 目标与边界
按用户确认同时支持普通 JSON 与 UI 设计 JSON:前者显示 JSON 并可代码预览,后者显示 UI 设计并进入原有编辑器。原生侧复用现有文档校验,前端不推断正式状态。不修改 manifest 分类,不迁移用户文件,不改历史分页,不做远程写入。
## 评审
已核对原生受控文本预览、UI State 持久化合同和工作台卡片/编辑器路由。复用完整读取结果识别,未知 schema/坏结构/身份不符均不授予编辑入口;已有 UI 资产的大小写标签不应阻断真实合法 State。新增可选预览字段只承载原生识别结果;不引入新的状态文件或平行编辑器。
## 验收标准
1. 普通 JSON 显示 JSON,不渲染卡面原文,不出现 UI 编辑器入口,显式预览为 JSON 代码块。
2. 完整合法且身份匹配的 UI State 显示 UI 设计并进入现有编辑器;大小写标签或文档标签不影响内容识别。
3. 损坏 JSON、伪 schema、未知字段、坏 State、跨项目/资产、未登记文件不能获得 UI 编辑入口;原文查看或读取错误仍可见。
4. 识别不产生写入;普通 JSON 不能通过编辑器保存或初始化被覆盖。有效已有设计仍支持原有 CAS 保存。
5. 预览缓存能传递原生结果并随资源身份失效;原有卡片、框选/平移和图片预览回归通过。
## 依赖
本地前端与 Tauri 源码、现有测试依赖;真实客户端体验单独验收。
@@ -0,0 +1,14 @@
# 抠图模式联调验收
Version: 1
Status: 自动化与真实上游验收已执行;完整主站链路待本地数据库恢复
Date: 2026-09-16
Parent Spec: ../../technical/【技术方案】AGC抠图模式与背景色透传-2026-09-16.md
交付:证明客户端、External v1、队列和 BgFilter 的模式/颜色契约一致;修正范围内缺漏。
不做:401 专题、部署、主站前端变化、生成角色与图集自动选色行为变化、数据库 schema 修改。
验收:旧请求 complex;flat 三种颜色输入贯通;非法组合入队前 400;幂等包含新意图并保留旧请求指纹;真实服务返回可解码透明 PNG;实际证据与未验证环境分开记录。
依赖:既有方案及前五步代码。
剩余门禁:当前本地 SpacetimeDB 连接拒绝,导致 api-server 启动恢复未就绪。环境恢复后,用 npm run dev:api-server 验证 healthz,再以真实登录客户端提交三种 flat 请求及旧 complex 请求,确认队列完成和资源回写。不得用直连 BgFilter 测试替代此门禁;完成后将结论回写主规范并删除本计划和实施计划。
@@ -3,6 +3,30 @@
> 用途:记录已经确认、会影响后续开发的长期技术/产品/协作决策。短期讨论不要写在这里。
> 当前口径:历史条目的旧路径、旧版本和已退役对象只用于追溯,不构成现行实现依据;如与当前代码或 `docs/README.md` 冲突,以当前代码和最新专题文档为准。
## 2026-09-17 `agc_tools` 媒体资源提示词上限收敛为单一口径,并按 kind 暴露给模型
- 背景:有人反馈「客户端没法由 agent 调用图片快速编辑功能以及背景音乐生成功能」。核查后工具本身都在(`agc_edit_image` / `agc_create_or_derive_resource`),图片快速编辑在 2026-09-14 的真实项目日志里也有成功记录;但存在三类真实缺陷:① `agc_create_or_derive_resource` 的 `prompt` 在 schema 里只声明 4000,真实上限却是按 kind 分的(背景音乐 140、音效 1900、视频/角色动画 4000、图片 32000),MCP 层还额外写死了一条 140 判断,模型从 schema 与 skill 都看不出 140/1900,写一句正常长度的背景音乐描述就当场被拒;② 客户端 UI 用同一口径但会截断并提示,agent 侧却只有硬拒,形成「UI 能做、agent 调不动」的观感;③ `sourceLocalAssetId` 不是已登记资源时只报「不属于当前项目已登记资源」,模型会原地重试而不会先登记。
- 决策一(单一口径):提示词上限只由 `resource_edit_prompt_max_chars` 给出,MCP 工具层、客户端受控工具桥与提交校验全部从它取数;超限文案复用 `resource_edit_prompt_limit_error`,保证模型看到的数字就是真实生效的数字。传输层边界只在信封级生效,不再用一个更小的通用常量先于按 kind 上限误报。
- 决策二(按 kind 暴露):`agc_create_or_derive_resource` 的 schema 用 `allOf[oneOf]` 逐 kind 声明 `prompt.maxLength`(background-music / sound-effect / video+character-animation),顶层 `maxLength` 等于各 kind 上限的最大值,`prompt` 描述里写明每个数字;`agc_edit_image` 继续用图片口径 32000。skill 包 `agc-client-projection`(SKILL.md 与 `references/projection-contract.md`)同步写明四个数字,并说明超限要在本地收敛而不是原样重发。
- 决策三(可执行的前置提示):源资源未登记时统一返回「先用 `agc_list_registered_assets` 选已有 localAssetId;文件只在项目里时先用 `agc_list_project_files` 确认 `assetImportable=true`,再用 `agc_import_account_assets.localPaths` 登记后重试」。本轮不放开「已完成任务产物」在 agent 侧的隐式正规化:登记是带副作用与 revision 推进的事务,必须由模型显式发起。
- 影响范围:`apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs`(上限与文案的唯一口径)、`agent/direct_tool_bridge.rs`(按 kind 判定与未登记源资源提示)、`agent/direct_tools_mcp.rs`(schema 与校验)、`resources/agc-skills/agc-client-projection/**` 与清单指纹(version `2026-08-26.18`)。**未改** `/api/external/v1` 契约与 OpenAPI、SpacetimeDB schema、前端 TS 侧 `resourceEditPromptMaxLength` 数字、客户端 UI 行为。
- 验证方式:新增 `tool_prompt_limits_agree_with_the_client_authority`(四个 kind 的 schema 上限、MCP 校验与客户端权威口径同数字,超限文案带真实上限)、`bridge_resource_prompt_limits_follow_the_client_authority`(工具桥侧同类门禁,含图片编辑的 32000 边界)、`edit_image_tool_reaches_the_platform_image_edit_route` 与 `background_music_tool_reaches_the_platform_audio_route`(MCP 工具层 → 真实工具桥 → 假平台,断言 `/api/editor/images/edits` 与 `/api/editor/audios/background-music/generations` 的路径、Bearer、Idempotency-Key、正文与派生资源落盘,图片编辑正文不得回填 assetKind)、`background_music_prompt_over_the_limit_is_rejected_before_any_bridge_call`(超限在桥请求之前失败)、`unregistered_source_reports_the_registration_follow_up_tools`;`agent::direct_tools_mcp` 22 passed、`agent::skill_pack` 4 passed、`agent::direct_tool_bridge` 17 passed(7 条本机既有失败见下)、`npm run agc:skill-pack:check` 与 `skill-pack:test` 通过。本机 `tempfile::tempdir()` 归属校验失败导致的既有用例(`project::resource_editor` 45 条、`agent::direct_tool_bridge` 7 条)在本轮改动前后**同为失败**(stash 基线复跑确认),与本次无关。
- 关联文档:[AI游戏创作智能体App实施计划](../../technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md)、[踩坑记录](pitfalls.md)。
## 2026-09-16 抠图模式与背景色契约
- External v1 抠图和 AGC `agc_remove_background` 支持 `complex`(语义分割识别前景)与 `flat`(纯色背景抠图);明确纯色背景优先 flat,模式缺省仍为 complex,主站前端保持现有行为。
- flat 的颜色允许 `auto`、`#RRGGBB` 或省略,自动识别完全由 BgFilter 负责。主站只校验、透传,不调用视觉模型选色;complex 携带颜色、非法值和空字符串在入队前拒绝。
- 来源、名称、模式与颜色共同区分客户端请求意图;旧参数调用及旧 External 请求的幂等指纹须保持稳定。
- 权威合同:[AGC 抠图模式与背景色透传](../../technical/【技术方案】AGC抠图模式与背景色透传-2026-09-16.md)。
## 2026-09-16 策划 Agent 工具执行退出项目级写锁并自动接续中断批次
- 背景:策划 Agent 每个 `read_file` / `write_file` / `patch_file` 工具都在执行前竞争全局项目写锁,但同一会话已由 `.agent/design-agent/active.lock` 串行化,工具目标又限定在 `design_artifacts`;项目锁既不覆盖「工具 + 会话 checkpoint」事务,还把进程中断时的 `executing=true` 不确定窗口扩大到等锁与工具执行全程。真机项目出现 `pendingBatch.executing=true`、`function_call` 无配对 output、UI 只显示工作中且无错误的状态。
- 决策:单次策划工具不再竞争项目级写锁,只保留策划命令锁与既有原子写入;GameAgent / DirectProject 的公共项目锁实现与调用不变。重开项目 hydrate 时,若命令锁可获取且当前批次处于 `executing=true`、当前 call 无 output,则自动续跑原回合:为该 call 补写「执行结果未保存」的工具错误、跳过剩余调用并交回 Provider 自愈;不得重放文件副作用,也不要求用户手动重试。
- 验证:新增定向用例证明中断批次自动补齐工具 output、收到后续 assistant 回复、清空 pendingBatch 并结束原 turn,同时目标文件保持未修改(未重放 `patch_file`);策划 Runtime 定向 14 条、策划工具 3 条通过,`cargo fmt --check`、`npm run check:encoding`、`git diff --check` 通过。
- 关联文档:[策划 Agent 生产迁移与工作区浏览](../../technical/【技术方案】策划Agent生产迁移与工作区浏览-2026-09-10.md)。
## 2026-09-16 AGC 同 AppData 多窗口共享 Agent Runner
- 背景:双击或再次启动 AGC 客户端时报「应用启动失败」,启动日志为 `startup.runner.owner-lock.failed details=AI 游戏创作界面已由同一 AppData 目录中的其他进程运行`。原设计(2026-07-27 / 2026-08-23)要求同一 AppData 只有一个 GUI owner,第二个界面进程在 setup 阶段就失败退出。
@@ -8808,3 +8832,11 @@ CI 上 `background_agent_runtime_recovers_stale_running_before_pending_task` 在
- 决策:模板库首页推荐位替换原「灵感推荐」本机图片目录(已删除 `InspirationGallery.tsx` 与 `assets/inspiration/`);左侧导航新增模板库入口,打开独立全屏页。`tauri.conf.json` 的 `img-src` 放行受信任 OSS 主机用于封面图。
- 关联规范:`docs/technical/【技术方案】AGC模板库与模板建项-2026-09-17.md`;开发期计划见 `docs/project-memory/plans/【里程碑】AGC模板库客户端接入-2026-09-17.md` 与对应实施计划。
- 验证:Rust 模板库 8 项定向单测、前端模型 9 项单测、AGC `tsc` 类型检查通过;`templates/index.json` 匿名可读且每个 `zipKey` 回读 SHA-256 与清单一致;发布脚本 `scripts/agc-template-library-publish.mjs` 支持 `--dry-run` 与上传后回读校验。
## 2026-09-16 CI 宿主 CPU 上限:Jenkins 16 核 / Gitea Actions runner 12 核
- 背景:`genarrative-station`(32 逻辑核)上 Jenkins Built-In Node 与 Gitea Actions runner 共用同一宿主。Jenkins `jenkins.service` 原先没有任何 CPU 限制(`cpu.max=max`),构建期 Web / Api / Stdb 三分支并行(Vitest 8 线程 + 两次默认 32 job 的 cargo)把整机顶到 80%~95%;`gitea-runner` 容器 `--cpus=24`(75%)在 push 触发的 CI 波峰里实测峰值 24.8~25.3 核,是同一时间窗里更大的单一消耗方。
- 决策:两路 CI 都设硬上限。Jenkins 侧 `systemctl set-property jenkins.service CPUQuota=1600%`(16 核 / 50%,覆盖 Built-In Node 上所有子构建,立即生效、无需重启,drop-in 落 `/etc/systemd/system.control/jenkins.service.d/50-CPUQuota.conf`)。runner 侧把 `/opt/gitea-stack/compose.yml` 的 `cpus` 由 `"24.0"` 改为 `"12.0"`(12 核 / 37.5%),并用 `docker update --cpus=12 gitea-runner` 让运行中的容器立即生效,不重建容器、不中断在跑 job。
- 边界:Deploy 阶段在远端 dev / release agent 执行,不受该上限约束。调整只动这两处:`systemctl set-property / revert jenkins.service`、`docker update --cpus=<n> gitea-runner` 加同步 compose(备份 `/opt/gitea-stack/compose.yml.bak-<时间戳>`)。
- 验证:限速后 `Genarrative-Full-Build-And-Deploy` #289 / #290 SUCCESS;采样期 Jenkins 峰值 10.2~10.5 核、限流不足 2s(可忽略),runner 峰值 12.07 核且持续出现 throttling,整机回落到 2.6%~19.8%。
- 关联文档:[开发运维](../../【开发运维】本地开发验证与生产运维-2026-05-15.md)。
@@ -4,6 +4,10 @@
## 标准流程
前端测试稳定性验证使用根目录 `npm test`(与 Frontend tests job 相同),保留 Vitest 的 8 worker 上限。涉及异步资源展示时,组件测试必须 mock 所有会触发的网络请求,每次调用创建独立 `Response`,并等待最终 DOM 状态而非仅等待 fetch 被调用。换签 Hook 的测试通过 `vitest.config.ts` 的 include 纳入全量运行;新增测试文件后需确认实际执行名单,命令参数指定文件不会绕过 include 白名单。排查顺序依赖可使用 `npm test -- --sequence.shuffle --sequence.seed=9467`,但不能以重试成功替代失败原因分析。
用例隔离必须包括浏览器状态与 mock 实现:修改 `window.history` 后恢复基线路由;`spyOn(window, 'getSelection')` 等 spy 在用例结束后 restore;`clearAllMocks` 仅清调用记录,不能恢复被上一个用例替换的返回值。顺序打乱暴露的失败应修复泄漏来源,保留原有业务断言。
```text
确认工作树与目标分支 → 读取入口和当前专题 → 查代码真相 → 小步修改 → 定向验证 → 更新当前文档/记忆 → 检查提交边界
```
@@ -47,6 +51,8 @@
## 验证路由
AGC 运行时配置默认值调整时,同步核对 Rust 默认值、分发配置模板、设置弹窗默认草稿和 `runtime-settings.suite.ts` 的恢复默认断言;显式传入旧值的配置读取用例仍验证原值保留,不批量替换测试数据。
AGC 测试构造单 HTML 项目时,必须在初始化之前写入 HTML,避免自动建立 npm 工程;npm 预览和导出测试应提供 dist 产物。已有图片生成 pending/operation 属于持久化恢复合同,修改工具默认参数后仍须验证旧动作恢复不重复提交、不因默认值变化被误判为新意图。
SpacetimeDB 任务统一先读取 `.codex/skills/genarrative-spacetimedb/SKILL.md`;该项目适配层按需调用已安装的官方 `spacetimedb` 插件 skill,插件提供通用 SDK/CLI/MCP 知识,项目 skill 负责 Genarrative 架构边界和验证门禁。
@@ -1,5 +1,34 @@
# 踩坑与排障记录
## 2026-09-17 AGC 输入盒的「推理档」弹层被祖先裁切:要放开裁切而不是挪弹层
- **现象**:窄窗口下(视口 ≤1000px 时右侧对话面板只有 280px 宽)点开输入盒右下角的「推理档」,弹层是个**空盒子**:档位文字(默认 / 低 / 中 / 高 / 最高)整片看不见,只剩一个方框。
- **成因**:推理档是控制排里最靠左的弹层锚点,`.conversation-model-menu` 默认 `right: 0` 贴触发钮右缘**向左**展开;触发钮右边还压着模型选择、语音、发送三颗钮,所以 150px 宽的弹层在 280px 面板里会伸到面板左侧 42px 之外。`.game-workbench-chat`、`.project-supervisor-surface.is-direct-codex`、`.project-supervisor-conversation` 三层各自的 `overflow: hidden` 沿自己的溢出边界裁掉它,而档位文字起点才 14px(面板左内边距 5px + 按钮左内边距 9px),正好落在被裁掉的那半边。
- **处理(用户指定口径)**:不挪弹层位置——只让 direct-codex 那三层不再裁切:`.game-workbench-chat:has(.project-supervisor-composer.is-direct-codex)`、`.game-workbench-chat .project-supervisor-surface.is-direct-codex`、`.game-workbench-chat .project-supervisor-surface.is-direct-codex .project-supervisor-conversation` 三条 `overflow: visible`。弹层的 `right: 0`、尺寸和触发钮锚点全不变,只是允许它盖到左侧资源面板上完整显示。消息列表自带 `overflow-y: auto`(另一轴按规范计算为 auto),消息内容仍由列表自身裁剪。
- **易错点**:① 把弹层改成 `left: 0` 或往右挪也能让它可见,但那是改变展开方向,弹层会跑到触发钮右边(用户明确否决);② 只放开最外层聊天列不够——surface 与 conversation 各自都会裁,三层必须同时放开;③ 只按宽度比大小会误判:280px 面板里控制排本身也超出(发送钮右侧溢出 22px,被窗口右缘吃掉),那不是本条的原因,别顺手去改控制排布局。
- **验证**:`apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts` 的 `keeps the landscape workbench edge-to-edge with internal chat scrolling` 钉住三条 override 声明在场(删掉任一条即红)。真机几何用 playwright-cli 打开一份只含真实 `styles.css` 与真实 composer DOM 的最小复现页实测(视口 1000×700、面板 280px):弹层 rect 修复前后都是 `[-42, 108]`(位置未动),`elementFromPoint` 的命中区间从修复前的 `[2, 108]` 变成整块;档位文字在截图中完整可见。
- **关联**:`apps/ai-game-creator-shell/src/styles.css`(`面板纵向布局(2026-07 Codex 风格改造)` 区块之后)、`apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts`。
## DirectProject 历史不能按工具条目切页再按消息推进游标
原始 `response_item` 历史同时含用户/助手消息、推理与工具输出。若原生每次取 20 个原始条目、前端过滤聊天消息后再找最旧 ID,纯工具页会让消息集合为空且游标不动,看起来历史丢失。聊天读取固定显式请求 `messagesOnly: true`,原生逐行过滤后按消息分页并返回 `oldestItemId`;默认原始模式留给原始条目消费者。无 ID 旧消息保留并扩展到可寻址边界,不能造 ID。前端保留项目与读取代次、单飞及 ID 去重,旧请求的成功、失败与 finally 都不能覆盖新读取;真实日志只在临时目录只读重放,不能提交正文夹具。
## JSON 卡片显示与 UI 编辑能力必须同源
JSON 的文本读取分支不等于卡面应该展示原始 State 摘要。卡片、缩略图及编辑器入口共同消费受控文本预览的 `uiDesignAssetId`;只有原生复用 UI 持久化合同校验 schema、完整 State 和项目/资产身份后才设置它。普通 JSON 保留 JSON 代码预览,不按 `kind: UI/ui` 或 schema 字符串片段猜测编辑能力。已有合法 UI State 的加载/保存不依赖 kind 精确大小写,但新建初始化仍保留正式 UI 资产门禁;缓存与项目切换须保留现有身份隔离。
## 窗口 Context 发布不得依赖每次渲染新建的业务回调
工作台向窗口标题栏发布运行项目时,若 effect 依赖普通函数派生的回调,发布 Context 会重新渲染工作台,进而再次发布并清理,形成更新深度循环。转发入口须稳定,并在提交阶段更新实际处理器引用;发布数据变化与卸载清理分开。回归测试必须组合真实窗口 Provider 和工作台消费者,只有独立画布测试无法覆盖这条反馈链;回归时用有界发布次数阻止测试失控。画布快速操作时暴露的更新深度错误,也须检查外层状态同步,不能直接归因于滚轮频率。
## 2026-09-17 工具 schema 声明的上限与真实校验不一致,会表现成「agent 调不动这个功能」
- **现象**:用户反馈「客户端没法由 agent 调用图片快速编辑功能以及背景音乐生成功能」。查工具目录时两个工具都在(`agc_edit_image`、`agc_create_or_derive_resource`),图片快速编辑在真实项目日志里还有成功记录;但 agent 侧写一句正常长度的背景音乐描述就失败,而客户端 UI 用同一个提示词却只是被截断加提示。
- **原因**:`agc_create_or_derive_resource.prompt` 在 MCP schema 里只声明 `maxLength: 4000`,真实上限按 kind 分(背景音乐 140 / 音效 1900 / 视频、角色动画 4000 / 图片 32000),MCP 层还额外写死一条 `kind == background-music && > 140` 的判断;skill 包没有任何一处写这两个数字。模型从 schema 与 skill 都无法得知 140,于是必然踩一次硬拒。同类隐患还有两处:客户端工具桥用通用 4000 校验 prompt,会把 4000 以上的图片编辑提示词误报成「超出安全边界」;按 kind 校验散落在 MCP 与桥两处,新增类型容易只改一处。
- **处理**:上限收敛到 `resource_edit_prompt_max_chars` 单一权威(工具层、桥、提交校验共用),超限文案复用 `resource_edit_prompt_limit_error`;工具 schema 用 `allOf[oneOf]` 逐 kind 声明 `prompt.maxLength` 并在描述里写明数字;prompt 的传输层边界退到信封级,避免通用常量先于按 kind 上限报错;两端 skill 文档同步写明四个数字。新增 `tool_prompt_limits_agree_with_the_client_authority` 作为门禁:四类 kind 的 schema 上限、桥上限与权威口径必须同数字,且超限文案必须带真实上限。
- **验证**:`cargo test --bin genarrative-ai-game-creator-shell -- --test-threads=1 agent::direct_tools_mcp::tests`(22 passed,含两条走 MCP 工具层 → 真实工具桥 → 假平台的媒体工具契约用例与一条超限零请求用例)、`agent::direct_tool_bridge::tests`(17 passed,含新增的按 kind 上限门禁;另有 7 条本机既有失败)、`agent::skill_pack`(4 passed)、`npm run agc:skill-pack:check`。本机 `tempfile::tempdir()` 归属校验失败会让 `project::resource_editor` 45 条与 `agent::direct_tool_bridge` 7 条既有用例失败,改动前后同为失败,不要据此误判回归。
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/project/resource_editor.rs`、`src-tauri/src/agent/direct_tool_bridge.rs`、`src-tauri/src/agent/direct_tools_mcp.rs`、`src-tauri/resources/agc-skills/agc-client-projection/`。
## 2026-09-16 从 Codex 里启动 AGC 客户端会看到被重定向的 `%APPDATA%`
- **现象**:在 Codex 会话里用 `Start-Process` 启动 `genarrative-ai-game-creator-shell.exe` 做排障时,子进程写 `C:\Users\<user>\AppData\Roaming\world.genarrative.ai-game-creator\...` 的内容会落到 `C:\Users\<user>\AppData\Local\Packages\OpenAI.Codex_2p2nqsd0c76g0\LocalCache\Roaming\...`;同一个 `Test-Path` / `Get-ChildItem` 命中的是重定向视图,只有 `\\?\C:\Users\...` 形式能区分真实路径。