合并 master 6c956605:保留 #605 与 #600 两侧改动
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m16s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 6m1s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m18s
Project CI / Frontend tests (pull_request) Successful in 3m42s
Project CI / Backend tests (pull_request) Successful in 8m8s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m44s
Project CI / Repository checks (pull_request) Successful in 7m16s
Project CI / Native shell tests (pull_request) Successful in 9m14s
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Successful in 7m16s
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Successful in 6m1s
Project CI / AI game creator shell Rust crates (pull_request) Successful in 4m18s
Project CI / Frontend tests (pull_request) Successful in 3m42s
Project CI / Backend tests (pull_request) Successful in 8m8s
Project CI / AI game creator shell web tests (pull_request) Successful in 2m44s
Project CI / Repository checks (pull_request) Successful in 7m16s
Project CI / Native shell tests (pull_request) Successful in 9m14s
- 目的:用户准备合并 PR #607,先把 head 更新到包含最新 origin/master(6c956605,含 #615 顶栏布局、#619 折叠箭头、作品管理与 Phaser4 发布等) - 冲突仅 docs/project-memory/shared-memory/pitfalls.md(两边都在文件顶部加条目):保留本分支三条(输入区不留常驻状态行 / 档位改 popover 滑块 / #600 输入区叠压)与 master 四条(随包 plugins feature 门禁、worktrees 下 Vite 被忽略规则排除、同工作树并发 dev 栈、Windows 阻塞模态用例挂死 runner) - 其余文件自动合并:#605 的 useImperativeHandle/insertReferences/注册活跃输入区与本分支的 presentation="slider"/modelLabel/errorPresentation="toast"/onUnavailable/ComposerModelNoticeToast 并存;project-development.suite.ts 的 [data-resource-reference-id] 引用插入断言与 composer 几何 gap: 8px 断言并存 - 合并后复跑:npm run agc:typecheck 通过;chatDialogFrameLayout + appSurface + activeChatComposer + resourceCanvasChatReferenceDrop 共 224 passed / 9 skipped;eslint(改动文件)通过;prettier --check 通过;check:encoding 通过;check:spacetime-schema 通过;git diff --check 干净
This commit is contained in:
@@ -26,6 +26,42 @@
|
||||
- **判据/取证**:`apps/ai-game-creator-shell/tests/chatDialogFrameLayout.test.ts` 用层叠求值钉住三层几何与操作排 `grid-row: 2 / position: static`、输入盒最高高度算式(12+160+6+28+0+8+28+12 = 254);`tests/appSurface/project-development.suite.ts` 钉住 composer 的 `gap: 8px`。真实渲染对照见 #600 PR:同一夹具在 495/438/360/296/280px 面板 × 空 / 长多行 / 队列+提示 四态下,改前 2~4 处相交(含文字被提示盖住),改后 0 处相交、0 处溢出。
|
||||
- **关联**:`apps/ai-game-creator-shell/src/styles.css`(文件末尾「输入区工具栏与状态提示」区块)、`docs/【功能说明】AGC聊天AI润色与发送前提醒-2026-09-10.md`。
|
||||
|
||||
## 2026-10-03 AGC 随包 plugins 的 feature 档位必须与消费方一致,且门禁会因 build.rs 未重跑而假通过
|
||||
|
||||
- **现象**:Windows 本机 `npm run check:generated-bindings`(`npm run lint` 链内,`scripts/check-repository-ci.sh` 的 Repository checks 也走它)在 `build.rs:167:29` panic:`插件随包资源校验失败:随包插件存在未声明文件:.../src-tauri/resources/plugins/agc-godot-editor/native/gdextension/bin/win-x64/agc_godot_editor.dll(目标 x86_64-pc-windows-msvc 与当前 feature 组合不允许;请先执行随包资源准备步骤)`;树上换成 `agc-unity-editor/dotnet/publish/win-x64/Agc.Unity.Attach.exe` 时报同一类错。反向还有更隐蔽的形态:门禁 2 秒就 exit 0 说「通过」,但 tree 上其实带着编辑器产物。
|
||||
- **原因**:`apps/ai-game-creator-shell/src-tauri/resources/plugins/` 是 gitignored 但被 dev / 发布 / 门禁多流程共用的目录,它的**档位**(staging 里放了哪些编辑器产物)必须与本次 cargo 调用实际生效的 feature 组合一致。`apps/ai-game-creator-shell/src-tauri/Cargo.toml` 的 `[features] default =` 是空的,而 `scripts/check-generated-bindings.mjs` 对 AGC 用的是裸 `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml export_bindings`(**不带任何 feature**);`build.rs` 按「当前 TARGET + 已启用 `CARGO_FEATURE_*`」构造 plugins 允许集合,于是为 windows 编辑器 feature 准备的 `origin: prepared` / `libraryStaging` 产物全成了「未声明文件」。
|
||||
- **关键坑(假通过)**:`resources/**` **不是**构建脚本声明的输入(设计如此,避免每次资源变化都重编),所以缓存命中的 `cargo test` **根本不会重跑 `build.rs`**,校验被整个跳过。实测:树上带着未声明的 unity 产物时,门禁仍以 2.33 秒 exit 0「通过」;`touch apps/ai-game-creator-shell/src-tauri/build.rs` 强制重跑后才暴露。
|
||||
- **处理(现行口径)**:校验 / 无 feature 的消费方先复位到 featureless:`npm run agc:bundled-resources:prepare -- --features=`。要带编辑器能力的本地 AGC:`npm run agc:bundled-resources:prepare -- --target x86_64-pc-windows-msvc --features=cocos-editor-execute,unity-editor-execute,godot-editor-execute`(`cocos-editor-bridge.dll` 的 native payload 另需 `cocos-editor-injection`)。要求门禁**真校验**过,先 `touch apps/ai-game-creator-shell/src-tauri/build.rs` 再跑门禁。
|
||||
- **判据/取证**:复位后强制重跑那次输出 `生成绑定校验通过:shared-contracts(1 个文件)` / `生成绑定校验通过:ai-game-creator-shell(104 个文件)` / `生成绑定校验通过:合计 105 个文件与 Rust 声明一致`(exit 0)。featureless 判据:`resources/plugins` 只有各插件 `plugin.json` + `src/`(cocos 另有 `panels/`),不存在 `Agc.Unity.Attach.exe` / `agc_godot_editor.dll` / `cocos-editor-bridge.dll`。
|
||||
- **边界**:这是同一工作树里多人共享的档位——featureless 是无 feature 构建与并发 cargo 运行的前提,带编辑器产物会让它们失败,反之亦然。`prepare-bundled-resources.mjs` 的原子替换要 rename `resources/plugins`,撞上外部目录句柄会 `EPERM` 并把 staging 留在 `resources/plugins-staging-<pid>-<hex>`(`.gitignore:61` 已声明该模式),确认无并发进程后重试即可。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/build.rs`(`validate_staged_plugins` / `validate_prepared_payloads`)、`src-tauri/build_support/package-layout.json`、`apps/ai-game-creator-shell/scripts/{prepare-bundled-resources.mjs,cargo-features.mjs}`、`scripts/check-generated-bindings.mjs`;另见本文件「随包资源的写入方按产物来源分界」「AGC 随包资源的布局只能改声明文件」「构建期 staging 撞上不装 npm 依赖的 Linux 门禁」三条。
|
||||
|
||||
## 2026-10-03 工作树位于 `.worktrees/` 下时前端 Vite 被自己的忽略规则整棵排除:改代码不热更
|
||||
|
||||
- **现象**:在 `.worktrees/<name>/` 里的工作树改主站或后台前端源码,浏览器看不到任何更新;重启 Vite 也不生效(本轮有人重启 3 次才发现不是缓存问题)。
|
||||
- **原因**:根 `vite.config.ts`(`ignoredWatchGlobs`,约 461-468 行)与 `apps/admin-web/vite.config.ts`(约 19-24 行)的忽略列表都含 `'**/.worktrees/**'`。工作树本身就在 `.worktrees/` 目录下,该 glob 会匹配工作树内的**每一个文件**,等于把整个项目排除出 watch——不报错、不提示,只是永远不触发 HMR / 重建。
|
||||
- **影响面**:主站 web 与 admin-web 都中招(两者共用这条规则);`npm run dev:web` 走 `scripts/vite-cli.mjs`,它只是转发到 Vite 自带 bin、用的是同一份根配置,所以经 CLI 入口启动也一样。`apps/ai-game-creator-shell/vite.config.ts` 只忽略 `'**/src-tauri/target/**'`,**不受影响**。
|
||||
- **处理方向(本轮未改配置)**:忽略规则必须只排除**其它** worktree 而放行当前 root——例如按真实仓库根计算,形如只忽略 `<repoRoot>/.worktrees/*/` 且显式排除当前 root;或当项目 root 自身已落在 `.worktrees/` 内时不注入该条。不要保留无条件的 `'**/.worktrees/**'`。
|
||||
- **验证方向**:修改 `src/**` 一句话后,主站与 admin-web 各自应打印 HMR 更新(修改后立即生效),而不是只在重启后才生效;必要时打印生效的 watch 忽略集合确认不再覆盖当前 root。
|
||||
- **关联**:`vite.config.ts`、`apps/admin-web/vite.config.ts`、`apps/ai-game-creator-shell/vite.config.ts`、`scripts/vite-cli.mjs`。
|
||||
|
||||
## 2026-10-03 同一工作树并发拉起多份 dev 栈:`.app/dev-stack.json` 互相覆盖,启动兜底清扫会反杀健康栈
|
||||
|
||||
- **现象**:在同一工作树里再开一个 `npm run dev` 之后,AGC 侧报「后端归属校验失败」,或前端代理连到别的端口(「后端端口记错」);更严重的是新会话启动后,`8082` / `8083` 上原本健康的后端被清掉,旧会话随即报连接失败。
|
||||
- **原因**:`.app/dev-stack.json` 是**全工作树单文件**(`scripts/dev.mjs` 的 `resolveDevStackStatePath()` → `<repoRoot>/.app/dev-stack.json`,`scripts/dev-all.mjs` 与若干 e2e 脚本也读它),每个 `DevRunner` 都整份覆写快照,端口、SpacetimeDB data-dir 与 instance id 只保留最后写入者,于是两份并发栈互相覆盖实例信息。同时 `dev.mjs` 在启动/退出时会按身份兜底清扫 `stopWindowsWorktreeBackendProcesses`(`api-server.exe` 绝对路径 + SpacetimeDB `--data-dir`),这是**按工作树**而不是按会话匹配的:其它会话留下的半死栈一旦重启,就会把当前健康栈一并收走。
|
||||
- **处理(现行口径)**:同一工作树保持**单栈**;确需并发时用显式端口参数(`--api-port` / `--web-port` / `--admin-web-port` / `--spacetime-port` 等)错开,并接受状态文件只有一个「最后写入者」。清理残留必须按**端口 → PID → 命令行**确认归属,再杀该 PID 的整棵进程树;不要 `taskkill /IM node.exe`(会误伤其它会话与 IDE 的 Node 进程)。
|
||||
- **排查顺序**:先比对 `.app/dev-stack.json` 的 status / 端口与实际监听(`Get-NetTCPConnection -State Listen -LocalPort ...`)是否一致,再用 `Get-CimInstance Win32_Process` 按本工作树 `server-rs\target\debug\api-server.exe` 路径与 SpacetimeDB `--data-dir` 核对归属;不要因为 `/healthz` 返回 200 就认定后端属于当前会话。
|
||||
- **关联**:`scripts/dev.mjs`(`resolveDevStackStatePath` / `stopWindowsWorktreeBackendProcesses`)、`scripts/dev-windows-process.mjs`、`scripts/dev-all.mjs`、`scripts/check-game-distribution-ratings-e2e.mjs`;另见本文件「`npm run agc` 的 Ctrl+C 不能只依赖 shell 包装层与端口健康检查」与 `docs/【开发运维】本地开发验证与生产运维-2026-05-15.md`。
|
||||
|
||||
## 2026-10-03 Windows 上会弹阻塞模态的启动失败用例挂死本机分片 runner
|
||||
|
||||
- **现象**:Windows 本机 `npm run ai-game-creator-shell:check:rust:shell -- --shard-index=3/4` 长时间无进展(可到 2400s 超时);单独跑那条用例同样超时——进程还在、CPU 不再增长、也没有子进程,形态很像「测试死锁」或「分片器坏了」。
|
||||
- **原因**:`apps/ai-game-creator-shell/src-tauri/src/main.rs:2042` 的 `startup_log_slot_fail_without_path_still_reports_instead_of_going_silent` 调 `StartupLogSlot::fail()`(约 1854 行),而 `fail()` 会走 `show_startup_error_dialog()`;Windows 实现(约 1740 行)用的是 `MessageBoxW(..., MB_OK | MB_ICONERROR | MB_SETFOREGROUND)`,是**阻塞模态**,没有人点「确定」就永不返回。`STARTUP_ERROR_DIALOG_SHOWN`(约 1534 行)只在同一个进程内保证「只弹一次」,对测试用例没有任何豁免。分片 runner 用 `--exact <名单> --test-threads=1` 串行执行,一条挂死就整片挂死。
|
||||
- **影响面**:Linux CI 走非 Windows 分支(约 1778 行)只写 stderr,**不受影响**;这是本机专属现象,不要据此判定 Rust 代码或分片规则有问题。
|
||||
- **处理(本机绕过)**:改用等价分块跑,而不是整片上阵——同一个测试二进制、同一 `--exact <名单>` 与 `--test-threads=1` argv、同一 TMPDIR 隔离,把这条阻塞用例排除或单独限定。
|
||||
- **判据/取证**:单独执行 `cargo test --manifest-path apps/ai-game-creator-shell/src-tauri/Cargo.toml --bin genarrative-ai-game-creator-shell -- --exact startup_log_slot_fail_without_path_still_reports_instead_of_going_silent --test-threads=1` 本机同样挂住;对照非 Windows 分支只产生 stderr 文案。
|
||||
- **关联**:`apps/ai-game-creator-shell/src-tauri/src/main.rs`、`apps/ai-game-creator-shell/scripts/run-rust-shell-test-shards.mjs`;另见本文件「AGC 壳 Rust 套件按「一片一 job」拆分,且分片必须自校验覆盖」条中此前记为「本机跑到约 20 分钟后长时间无进展」的同一现象。
|
||||
|
||||
## 2026-10-03 AGC 画布「引用」死按钮:window 事件的消费者挂在一个只在另一条链路赋值的 ref 上
|
||||
|
||||
- **现象**(Issue 602):AGC 资源画布选中一张已登记素材,选中工具条点「引用」(图标 `@`、可见文案与 `title` 都是「引用」)没有任何反应——聊天输入框里不出现 `@素材名` 芯片,也没有任何提示。普通项目(`directProjectMode`)必现,立项策划项目(`planningStartMode`)复现不出来;把素材卡拖到对话栏的批量引用同样没反应。
|
||||
|
||||
Reference in New Issue
Block a user