diff --git a/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md b/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md index f7a20de50..ac55c4af5 100644 --- a/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md +++ b/docs/technical/【技术方案】AI游戏创作智能体App实施计划-2026-06-24.md @@ -14,6 +14,7 @@ - Run 控制参考:借鉴 Harbour 的控制平面思想,只吸收 `run lifecycle`、activity/output stream、context bundle、kill/retry/resume 等本地运行治理能力;不引入 Harbour 的多租户后台、调度 UI、通用 shell workflow 或远程 runner 作为 v1 依赖。 - 本地工程参考:借鉴 Godcoder 的本地产物 checkpoint / diff / restore、上下文安全过滤、轻量项目索引、项目级写锁和项目级权限策略;不引入通用 IDE 插件、云工作区或任意代码代理。 - 代码组织:桌面客户端入口保持为薄组合层。前端把认证、Tauri 桥接、Runtime 配置、Agent Runtime 展示和项目摘要分别放入 `src/app`、`src/services` 与 `src/features`;Rust 项目能力和测试按功能域使用目录模块;界面测试与真实 Runtime E2E 使用薄 suite registry / entry 保留原执行顺序。后续拆分必须保持公开导出、命令契约、测试名称和行为不变,不能用 `include!`、整文件文本拼接或只移动到另一个超大文件代替真实模块边界。 +- 源码门禁:`check:native-shells` 等源码扫描必须跟随真实模块归属;入口组合层只验证受控组件的挂载关系,具体实现由所属模块单独验证。模块拆分后不得为了满足旧字符串扫描把实现搬回 `App.tsx`,也不得用跨文件文本拼接代替组件归属检查。 ## 开发态 Project Supervisor 纯聊天独立窗口 diff --git a/scripts/check-native-shells.mjs b/scripts/check-native-shells.mjs index 10941faf1..c25060c25 100644 --- a/scripts/check-native-shells.mjs +++ b/scripts/check-native-shells.mjs @@ -26,6 +26,18 @@ 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 aiGameCreatorProjectDevelopmentSource = fs.readFileSync( 'apps/ai-game-creator-shell/src/view/project-development/index.tsx', 'utf8', @@ -1937,31 +1949,53 @@ function assertAiGameCreatorShellUserDevBoundary() { 'function isDeveloperMode()', 'if (!import.meta.env.DEV)', "return params.has('dev') || window.location.hash === '#dev';", + ]) { + if (!aiGameCreatorShellAppModelSource.includes(snippet)) { + throw new Error( + `AI game creator developer mode boundary drifted: missing ${snippet}`, + ); + } + } + for (const snippet of [ + 'projectSupervisorOnly ? false : isDeveloperMode()', "{devMode ? (", 'className="developer-pane"', - 'className="chat-pane"', ]) { if (!aiGameCreatorShellAppSource.includes(snippet)) { throw new Error(`AI game creator user/dev UI boundary drifted: missing ${snippet}`); } } + if ( + !aiGameCreatorShellAppSource.includes(' match.index ?? -1); + const previewFrameCount = [ + ...aiGameCreatorShellDeveloperProjectPanelsSource.matchAll(/ index < devModeBranchIndex || index < developerPaneIndex, ) ) { - throw new Error('AI game creator preview iframe must stay inside the dev-only pane'); + throw new Error('AI game creator preview panels must stay inside the dev-only pane'); } const clientPreviewFrameCount = [