From 26cfd85d25df810ce481c0afd86bce71516cfa2d Mon Sep 17 00:00:00 2001 From: menghao Date: Fri, 31 Jul 2026 15:28:05 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8DAGC=E7=9A=84macOS=E4=B8=B4?= =?UTF-8?q?=E6=97=B6=E8=B7=AF=E5=BE=84=E5=85=BC=E5=AE=B9=20(#125)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 规范化配置回归测试的临时根路径 补充跨平台路径比较技术说明与踩坑记录 Reviewed-on: http://192.168.35.82/git/GenarrativeAI/Genarrative/pulls/125 Co-authored-by: menghao Co-committed-by: menghao --- .../scripts/check-config.mjs | 28 +++++++++++++++++-- .../appSurface/project-development.suite.ts | 20 ++++--------- docs/project-memory/shared-memory/pitfalls.md | 2 ++ ...案】AI游戏创作智能体App实施计划-2026-06-24.md | 3 +- 4 files changed, 34 insertions(+), 19 deletions(-) diff --git a/apps/ai-game-creator-shell/scripts/check-config.mjs b/apps/ai-game-creator-shell/scripts/check-config.mjs index 44053cfe6..2f858797a 100644 --- a/apps/ai-game-creator-shell/scripts/check-config.mjs +++ b/apps/ai-game-creator-shell/scripts/check-config.mjs @@ -436,6 +436,28 @@ async function runConfigWizardRegressionChecks() { path.join(os.tmpdir(), 'genarrative-agc-config-check-'), ); try { + const canonicalTestRoot = fs.realpathSync.native(testRoot); + const realConfigAncestor = path.join(testRoot, 'real-config-ancestor'); + const linkedConfigAncestor = path.join(testRoot, 'linked-config-ancestor'); + fs.mkdirSync(realConfigAncestor); + fs.symlinkSync( + realConfigAncestor, + linkedConfigAncestor, + process.platform === 'win32' ? 'junction' : 'dir', + ); + const missingLinkedConfigDir = path.join( + linkedConfigAncestor, + 'missing-appdata', + ); + assert.equal(fs.existsSync(missingLinkedConfigDir), false); + assert.equal( + await assertSafeGameCreatorConfigDestination(missingLinkedConfigDir), + path.join( + fs.realpathSync.native(realConfigAncestor), + 'missing-appdata', + ), + ); + const gitRoot = path.join(testRoot, 'tracked-repository'); const trackedConfigDir = path.join(gitRoot, 'runtime-config'); fs.mkdirSync(trackedConfigDir, { recursive: true }); @@ -463,7 +485,7 @@ async function runConfigWizardRegressionChecks() { const outsideConfigDir = path.join(testRoot, 'outside-appdata'); assert.equal( await assertSafeGameCreatorConfigDestination(outsideConfigDir), - outsideConfigDir, + path.join(canonicalTestRoot, 'outside-appdata'), ); await assert.rejects( assertSafeGameCreatorConfigDestination(outsideConfigDir, { @@ -476,7 +498,7 @@ async function runConfigWizardRegressionChecks() { await assertSafeGameCreatorConfigDestination(dedicatedConfigDir, { requireDedicatedLeaf: true, }), - dedicatedConfigDir, + path.join(canonicalTestRoot, appIdentifier), ); const injectedNonGitConfigDir = path.join(testRoot, 'injected-non-git'); @@ -489,7 +511,7 @@ async function runConfigWizardRegressionChecks() { 'fatal: not a git repository (or any of the parent directories): .git\n', }), }), - injectedNonGitConfigDir, + path.join(canonicalTestRoot, 'injected-non-git'), ); await assert.rejects( assertSafeGameCreatorConfigDestination( diff --git a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts index b598b7238..6d02ee1b6 100644 --- a/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts +++ b/apps/ai-game-creator-shell/tests/appSurface/project-development.suite.ts @@ -2,20 +2,6 @@ import type { ProjectResourceCanvasLayout, ProjectResourceCanvasPosition, } from '../../../../packages/shared/src/contracts/gameCreationApp'; -import { consumeInitialGameChatMessage } from '../../src/App'; -import type { - AgentRuntimeEventRecord, - AgentRuntimeState, -} from '../../src/app/types'; -import { - collectGameChatResultImages, - collectGameChatRuntimeEvents, - SupervisorChatOnlyView, -} from '../../src/features/project-workspace/SupervisorChatOnlyView'; -import { - RESOURCE_CANVAS_CARD_WIDTH, - RESOURCE_CANVAS_COLUMN_GAP, -} from '../../src/view/project-development/resourceCanvasLayoutModel'; import { consumeInitialGameChatMessage, latestGameChatPlayableRevision, @@ -30,6 +16,10 @@ import { collectGameChatRuntimeEvents, SupervisorChatOnlyView, } from '../../src/features/project-workspace/SupervisorChatOnlyView'; +import { + RESOURCE_CANVAS_CARD_WIDTH, + RESOURCE_CANVAS_COLUMN_GAP, +} from '../../src/view/project-development/resourceCanvasLayoutModel'; import { act, agentRuntimeUserInputRequest, @@ -4241,7 +4231,7 @@ export function registerProjectSupervisorSurfaceTests() { ([command]) => command === 'get_local_game_preview_status', ).length, ).toBeGreaterThan(previewStatusReads); - }); + }, { timeout: 3000 }); expect(driver.readAuthorization()?.authorizationId).toBe( steerAuthorizationId, ); diff --git a/docs/project-memory/shared-memory/pitfalls.md b/docs/project-memory/shared-memory/pitfalls.md index d2f7011fd..c9e24a76e 100644 --- a/docs/project-memory/shared-memory/pitfalls.md +++ b/docs/project-memory/shared-memory/pitfalls.md @@ -3703,6 +3703,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