同步 pitfalls 中失效的 ACL 桩名称并补注入点说明
- pitfalls.md:把「测试超时补充」里引用的 persistenceOptions 改为当前实际使用的 skippedWindowsAclOptions,避免文档指向已不存在的名称。 - pitfalls.md:补一句 prepareSwarmTestRuntimeConfig 暴露的可选 secureWindowsPath 注入点、默认 null 走真实实现,以及单次调用最多加固 3 次的事实。
This commit is contained in:
@@ -4166,7 +4166,7 @@
|
||||
- 处理:GUI 与 `npm run agc:config` 共用系统 AppData `game-creator.config.json`,终端隐藏输入 API Key 并禁止 `--api-key`;更新时保留 `agentLlm`、`editorApi`、`mcpServers` 等其它配置,POSIX 权限维持目录 `0700` / 文件 `0600` 并原子替换。显式 `--config-dir` 必须以 `world.genarrative.ai-game-creator` 为独立叶目录,不能让向导对 `/tmp`、AppData 根或共享目录整体 chmod / 重建 DACL。隐藏输入调用 `stdin.resume()` 后必须记住原 pause 状态,在成功、取消、异常和 `SIGINT / SIGTERM / SIGHUP` 路径恢复 raw mode 并 `pause()`,信号恢复后重发;只移除 `data` listener 会让 `--configure-only`、配置检查失败或 Ctrl+C 保持活动 stdin。缺配置时仅 TTY 人工会话可询问进入向导,非 TTY 立即失败并提示配置命令。
|
||||
- Windows 密钥复制:`mode: 0o600` 和 POSIX `chmod` 在 Windows 上不能代替 DACL。隔离 AppData 目录必须先设置仅当前用户、禁止继承的 DACL;目标配置文件先以空文件创建并收紧 DACL,之后才允许把 API Key 字节写入。先 `copyFile` 再依赖 Rust 只读检查或事后收紧会留下密钥暴露窗口,也可能因继承 ACL 不满足 Runtime 合同而在首次 `--llm-status` 失败。
|
||||
- Windows PowerShell 参数:不要把 DACL 目标路径和目录标记直接追加在 `powershell.exe -Command <script>` 后;Windows Node `spawn` 会让 PowerShell 5.1 把这些值拼入命令文本,带空格的临时路径会被拆分并使 `GetFullPath($args[0])` 失败。当前实现只通过子进程私有环境变量传入路径和布尔值,并由真实 Windows `npm run agc:typecheck` 覆盖 DACL 回归。
|
||||
- 测试超时补充:配置向导的读路径和写路径都会加固私有目录与配置文件,`readGameCreatorWizardConfigState` 与 `writeGameCreatorConfigAtomically` 只要没拿到 `secureWindowsPath` 桩,Windows 上每次调用就各自拉起真实 `powershell.exe`(本机实测约 `0.6s` / 次)。只给写路径传桩、漏掉读路径时,单条用例会累计 `9` 次加固、耗时约 `5.5s`,稳定撞上 vitest 默认 `5000ms` 上限并报 `Test timed out in 5000ms`(不是断言失败)。凡只校验配置分层优先级、不校验 ACL 的用例,读写路径必须带上同一份 `persistenceOptions`,把用例耗时从秒级压回 `39ms` 量级;确实要覆盖私有 ACL 的用例才保留真实加固,并自行留足超时预算。
|
||||
- 测试超时补充:配置向导的读路径和写路径都会加固私有目录与配置文件,`readGameCreatorWizardConfigState` 与 `writeGameCreatorConfigAtomically` 只要没拿到 `secureWindowsPath` 桩,Windows 上每次调用就各自拉起真实 `powershell.exe`(本机实测约 `0.6s` / 次)。只给写路径传桩、漏掉读路径时,单条用例会累计 `9` 次加固、耗时约 `5.5s`,稳定撞上 vitest 默认 `5000ms` 上限并报 `Test timed out in 5000ms`(不是断言失败)。凡只校验配置分层优先级、不校验 ACL 的用例,读写路径必须带上同一份 `skippedWindowsAclOptions` 桩,把用例耗时从秒级压回 `24ms` 量级;确实要覆盖私有 ACL 的用例才保留真实加固,并自行留足超时预算。隔离 Swarm 运行配置的入口 `prepareSwarmTestRuntimeConfig` 按同一范式暴露了可选第三参 `{ secureWindowsPath }`,默认 `null` 时仍走真实实现,生产调用点保持单参调用;一次调用在双配置文件场景最多加固 3 次,不传桩时同样会稳定吃掉秒级预算。
|
||||
- 跨平台临时路径比较:macOS 的 `os.tmpdir()` 可返回 `/var/folders/...`,而 `realpath` 会返回同一目录的 `/private/var/folders/...`;Windows 也可存在驱动器号大小写、junction 或链接解析差异。测试安全路径函数时,fixture 期望值必须基于平台原生 `realpath` 后的根目录构造,不能直接与 `mkdtemp` 的逻辑路径字符串严格比较。不能只依赖开发机自带的路径别名;CI 应创建真实父目录、指向它的符号链接(Windows 使用 junction)和不存在的叶目录,断言安全函数返回真实父目录下的叶路径。`realpath` 和全部断言都应放在 `try/finally` 内,确保失败也能清理 fixture。
|
||||
- 超时与进程树:`setTimeout` 后只对直接 Cargo PID 调一次 `kill()` 不是硬超时;Cargo 启动的 CLI / Runner 仍可能持有 stdio,使 `close` 永远不返回,清理阶段也可能无界等待。POSIX 必须创建独立进程组并按负 PID 终止,Windows 必须使用 `taskkill /T`;宽限期后升级强杀,Runner shutdown 和清理另设短硬超时。重复 Ctrl+C 也必须升级,不能一直被自定义 signal handler 吞掉。
|
||||
- 模式拆分:自动化使用默认的 `agc:test:chat`,由脚本投递固定植物塔防需求;正式产物、最新 revision 静态检查和 Runtime 浏览器验收通过后立即收束并清理,不启动持续 preview。`agc:test:chat:manual` 不注入 `--task`,用于多轮 stdin 手工聊天,并保留 preview 直到显式退出;不能用 EOF 或是否存在 `game/index.html` 猜测当前模式。
|
||||
@@ -5107,3 +5107,13 @@
|
||||
- 原因:AGC 在 `view/project-development/index.tsx:5405-5417` 挂 `ImageCanvasSelectedLayerToolbarView` 时把 `onOpenRedrawPanel`(`:5406`)与 `onOpenCharacterAnimationPanel`(`:5416`)传成了**空回调**(同一处另有 6 个空回调:`onOpenCropExpandPanel` / `onRemoveBackground` / `onPerfectPixel` / `onSplitIconSpritesheet` / `onExtractUiDesignAssets` / `onDownloadLayer`),但 `features/resource-canvas/resourceCanvasToolbarModel.ts` 的 `resolveResourceCanvasToolbarActions` **仍然把 `redraw` 放进了 supportedActions**:图片/视频/音频只要 `canDeriveFromResource` 就加 `redraw`,`assetKind === 'character'` 再加 `character-animation`。于是这两个动作**渲染出来了但没人接**;其余动作没进集合,按钮不渲染,所以线上只在这两处暴露。
|
||||
- 处理方向(尚未修):要么给这两个动作接上真实链路,要么把它们从 `resolveResourceCanvasToolbarActions` 的返回集合里去掉。判据是「渲染出来的动作必须真的能跑通」,而不是「先把按钮显示出来」。
|
||||
- 关联:`apps/ai-game-creator-shell/src/view/project-development/index.tsx`、`apps/ai-game-creator-shell/src/features/resource-canvas/resourceCanvasToolbarModel.ts`、`src/components/image-editor/ImageCanvasSelectedLayerToolbarView.tsx`(`:87-90` 判定、`:300-311` 图片分支「改造」、`:289-300` 「角色动画」)。
|
||||
|
||||
## AGC 资源画本的流式工具条必须抬到画本场景之上(2026-09-10)
|
||||
|
||||
- 现象:资源搜索框在真实 UI 里恒定不可见,`searchText` 的唯一写入方点不到,连带「清除搜索并定位」(只在搜索把刚提交资源挡掉时出现)整条链路成了死代码;门禁全绿。
|
||||
- 原因一(堆叠顺序):资源卡与栏目标题栏都画在铺满资源区的 `.game-resource-book-scene`(`position: absolute; z-index: 20`,子画布态还有一层不透明的 `::before` 点阵底)里,而搜索框、平台资源筛选条、`game-resource-live-notice` 都是 `.game-resource-book-manager` 的**流式子节点**;按绘制顺序,定位元素(含 `z-index: auto` 的 `.game-resource-book-main`)整体盖在流内内容之上。所以这些工具条即使恢复 `display: flex` 也只是"画了但看不见、点不到",必须和右下角缩放 Dock 一样 `position: relative; z-index: 40` 才能浮到场景之上。
|
||||
- 原因二(何时被关掉):`display: none` 是 PR #193 重排工作台时改的(原始提交 `3a8dff140` 里是 `display: flex`),不是设计选择。
|
||||
- 门禁为什么抓不到:既有用例用 `screen.getByLabelText('搜索项目资源')` + `fireEvent.change`;`getByLabelText` 默认**不校验可见性**,`display: none` 的元素照样命中并成功改值。AGC 的 vitest 也没有开 `css: true`、`styles.css` 不会被加载,所以 `toBeVisible()` 在 AGC 里是**恒真的假守卫**——可见性只能读 CSS 源文件做声明级断言(现有口径见 `apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts` 的 `styleRuleBody` 断言),交互链路另用真实 DOM 用例覆盖。
|
||||
- 处理:搜索框恢复 `display: flex`,常态 `align-self: center` 居中(总览态标题在左上、分页态栏目标题栏左右两端都有内容,只有中段是空的),与缩放 Dock 同级 `z-index: 40`;提示条同样抬到场景之上。
|
||||
- 同批修复(大纲):栏目大纲常态是 `opacity: 0.68` + `scale(0.86)` + 全透明底 + `svg { width: 0 }`,常态只剩 11px 文字,用户认不出那是分区入口;现在常态就给 Dock 底板、14px 栏目图标和 12px 栏目文字并高亮当前栏目,悬停/键盘聚焦只做同一套 token 的加强。**注意**:`docs/technical/【技术方案】GameAgent资源自由画板与快速编辑-2026-08-20.md` 的「操作边界」与「验收」两条仍写着"常态缩小、只露栏目文字",该文件当时有其它未提交改动,本批没有一并改,需要后续同步。
|
||||
- 关联:`apps/ai-game-creator-shell/src/styles.css`、`apps/ai-game-creator-shell/src/view/project-development/index.tsx`、`apps/ai-game-creator-shell/tests/projectResourceLiveIntegration.test.tsx`。
|
||||
|
||||
Reference in New Issue
Block a user