合并 master:运行页入口收口并入 DirectProject 重构
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (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

- 保留 master 的 DirectProject / ProjectChat 重构与测试重组:原 appSurface 的 project-commands / project-preview / supervisor-runtime 三个 suite 已被 master 删除,接受删除并把相关断言重写到 tests/previewActivation.test.tsx 等新用例
- 本分支改动重放到 master 结构:运行与预览成功的反馈改走 onRunNotice toast(带 tone),对话区不再写过程提示
- 运行页顶栏统一:预览地址改成「在浏览器打开」按钮,版本入口搬进同一动作区复用同一套按钮皮,状态行与预览地址小字退役
- 生成任务入口、面板与锚点不在运行页渲染,placement 里的 run 档一并删除
- 手工合并 App.tsx / WorkspaceLauncher.tsx / model.ts / check-config.mjs / decision-log / pitfalls,并把两条决策记录与一条排障记录补进 master 版本文档
This commit is contained in:
2026-09-22 12:50:19 +08:00
300 changed files with 10652 additions and 57627 deletions
+1 -90
View File
@@ -26,18 +26,6 @@ const aiGameCreatorShellAppSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/App.tsx',
'utf8',
);
const aiGameCreatorShellAppModelSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/features/app-shell/model.ts',
'utf8',
);
const aiGameCreatorShellProjectWorkspaceChatPaneSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/features/project-workspace/ProjectWorkspaceChatPane.tsx',
'utf8',
);
const aiGameCreatorShellDeveloperProjectPanelsSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/features/project-workspace/DeveloperProjectPanels.tsx',
'utf8',
);
const aiGameCreatorLocalGamePreviewFrameSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/features/project-workspace/LocalGamePreviewFrame.tsx',
'utf8',
@@ -2623,71 +2611,7 @@ function assertAiGameCreatorShellUserDevBoundary() {
);
}
for (const snippet of [
'function isDeveloperMode()',
'if (!import.meta.env.DEV)',
"return params.has('dev') || window.location.hash === '#dev';",
]) {
if (!sourceIncludesSnippet(aiGameCreatorShellAppModelSource, snippet)) {
throw new Error(
`AI game creator developer mode boundary drifted: missing ${snippet}`,
);
}
}
for (const snippet of [
'projectSupervisorOnly ? false : isDeveloperMode()',
'{devMode ? (',
'className="developer-pane"',
]) {
if (!sourceIncludesSnippet(aiGameCreatorShellAppSource, snippet)) {
throw new Error(
`AI game creator user/dev UI boundary drifted: missing ${snippet}`,
);
}
}
if (
!aiGameCreatorShellAppSource.includes('<ProjectWorkspaceChatPane') ||
!aiGameCreatorShellProjectWorkspaceChatPaneSource.includes(
'className="chat-pane"',
)
) {
throw new Error('AI game creator user chat pane boundary drifted');
}
const developerProjectPanelIndexes = [
...aiGameCreatorShellAppSource.matchAll(/<DeveloperProjectPanels\b/g),
].map((match) => match.index ?? -1);
const previewFrameCount = [
...aiGameCreatorShellDeveloperProjectPanelsSource.matchAll(/<iframe\b/g),
].length;
const devModeBranchIndex =
aiGameCreatorShellAppSource.indexOf('{devMode ? (');
const developerPaneIndex = aiGameCreatorShellAppSource.indexOf(
'className="developer-pane"',
);
if (previewFrameCount !== 1) {
throw new Error(
'AI game creator developer pane preview frame count drifted',
);
}
if (developerProjectPanelIndexes.length !== 1) {
throw new Error(
'AI game creator developer project panels mount count drifted',
);
}
if (
devModeBranchIndex < 0 ||
developerPaneIndex < 0 ||
developerProjectPanelIndexes.some(
(index) => index < devModeBranchIndex || index < developerPaneIndex,
)
) {
throw new Error(
'AI game creator preview panels must stay inside the dev-only pane',
);
}
// 上面几条只约束 DeveloperProjectPanels 自身的 iframe 数量和挂载位置,管不到 App.tsx
// 直接内嵌 iframe 的情况——预览必须一律委托给客户端工作台,外壳自己不持有预览框。
// 预览必须一律委托给客户端工作台,外壳自己不持有预览框。
if ([...aiGameCreatorShellAppSource.matchAll(/<iframe\b/g)].length !== 0) {
throw new Error(
'AI game creator app shell must delegate preview iframe to the client workbench',
@@ -2781,19 +2705,6 @@ function assertAiGameCreatorShellUserDevBoundary() {
'AI game creator normal startup must not automatically open a developer window',
);
}
for (const snippet of [
'fn open_project_supervisor_chat_window(',
'#[cfg(not(debug_assertions))]',
'项目总控对话窗口仅在开发构建中可用',
'index.html?supervisor-chat&projectPath=',
]) {
if (!sourceIncludesSnippet(aiGameCreatorShellTauriSource, snippet)) {
throw new Error(
`AI game creator supervisor chat window must stay developer-only: ${snippet}`,
);
}
}
const workspaceWindowCommandIndex = aiGameCreatorShellTauriSource.indexOf(
'fn open_game_creator_workspace_window(',
);