From 6c7033221d820be01c13fb3430ebc487a08d1bb9 Mon Sep 17 00:00:00 2001 From: Suzumiya Date: Sun, 4 Oct 2026 00:11:25 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=20#599=20=E8=87=AA=E5=AE=A1?= =?UTF-8?q?=E5=9B=9E=E5=BD=92=E7=94=A8=E4=BE=8B=EF=BC=9A=E7=94=A8=E6=88=B7?= =?UTF-8?q?=E5=B7=B2=E5=88=87=E5=88=B0=E5=88=AB=E7=9A=84=E5=B7=A5=E4=BD=9C?= =?UTF-8?q?=E5=8C=BA=E6=97=B6=E5=90=8E=E5=8F=B0=E6=94=B9=E5=90=8D=E4=B8=8D?= =?UTF-8?q?=E5=8A=AB=E6=8C=81=E4=B8=8A=E4=B8=8B=E6=96=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增用例 does not hijack the project the user already moved to when the AI name lands:后台 AI 名称落定时若当前项目上下文已是另一个工作区(看门狗解围后打开别项目走同一条「上下文已被接管」判据),只重检刚建工作区的最近项目行,不把用户切走的上下文换成刚建的工作区。 - 该用例经反向证伪:临时去掉 applyAutomaticProjectName 的项目路径守卫后失败(projectName 由 另一个项目 变成 星河远征),随后已还原源码。 - 自审复核结论(无代码改动):entrySettled 在预检失败、建项失败、看门狗让位、进项目失败、成功五条路径都由建项主体的 finally 落定;看门狗与后台 creation 竞速没有重复 rememberRecentWorkspace、没有未捕获拒绝;expectedName 取建项回传的 manifest.name(与宿主落盘同源,宿主侧 trim 为 no-op);新命令已注册且旧 rename_local_game_project 的调用方未受影响。 - 定向验证:homeProjectNamingAsync 10 passed;appSurface 两条相关用例 passed;cargo conditional_project_rename_tests 5 passed;cargo fmt --check 与 npm run agc:typecheck 通过。 --- .../tests/homeProjectNamingAsync.test.tsx | 47 +++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/apps/ai-game-creator-shell/tests/homeProjectNamingAsync.test.tsx b/apps/ai-game-creator-shell/tests/homeProjectNamingAsync.test.tsx index 73c964683..c23103b50 100644 --- a/apps/ai-game-creator-shell/tests/homeProjectNamingAsync.test.tsx +++ b/apps/ai-game-creator-shell/tests/homeProjectNamingAsync.test.tsx @@ -318,3 +318,50 @@ it('never starts automatic naming for the 做方案 flow', async () => { await naming.promise; }); }); + +it('does not hijack the project the user already moved to when the AI name lands', async () => { + const naming = deferred(); + const { result, refreshRecentWorkspace } = mount({ + naming: naming.promise, + conditionalRename: async () => ({ + renamed: true, + manifest: createGameCreationAppManifest(PROJECT_ID, SUGGESTED_NAME), + revision: 1, + }), + }); + + await act(async () => { + await createAutomatically(result); + }); + + // 用户已经切到另一个工作区(看门狗解围后打开别项目走的是同一条「上下文已被别人接管」判据)。 + await act(async () => { + result.current.setCurrentProjectContext({ + projectPath: 'C:/test/other-project', + projectName: '另一个项目', + projectKind: 'web', + manifest: createGameCreationAppManifest('other-project', '另一个项目'), + projectRevision: 3, + creationType: null, + startMode: null, + initialPrompt: '', + attachments: [], + recentRunStatus: null, + recentRunStopReason: null, + createdAt: 1, + }); + }); + + await act(async () => { + naming.resolve(SUGGESTED_NAME); + await naming.promise; + }); + + // 后台改名不能把用户当前所在的项目上下文换成刚建好的那个工作区。 + expect(result.current.currentProjectContext?.projectPath).toBe( + 'C:/test/other-project', + ); + expect(result.current.currentProjectContext?.projectName).toBe('另一个项目'); + // 但刚刚建好的工作区确实改名了:最近项目行照旧按目录重检。 + expect(refreshRecentWorkspace).toHaveBeenCalledWith(PROJECT_PATH); +});