合并主线并修复画布快速编辑冲突
合并 Godot 项目导入与 AGC 原生 HTTP 能力。 保留图片快速编辑业务 ID 契约并移除退役 redraw 分支。 同步共享决策、画布文档与回归测试。
This commit is contained in:
@@ -64,6 +64,24 @@ const aiGameCreatorShellTauriSource = readSourceTree(
|
||||
'apps/ai-game-creator-shell/src-tauri/src',
|
||||
'.rs',
|
||||
);
|
||||
const aiGameCreatorClientHttpSource = fs.readFileSync(
|
||||
'apps/ai-game-creator-shell/src/services/clientHttp.ts',
|
||||
'utf8',
|
||||
);
|
||||
const aiGameCreatorMainCapability = JSON.parse(
|
||||
fs.readFileSync(
|
||||
'apps/ai-game-creator-shell/src-tauri/capabilities/main.json',
|
||||
'utf8',
|
||||
),
|
||||
);
|
||||
const aiGameCreatorCargoManifestSource = fs.readFileSync(
|
||||
'apps/ai-game-creator-shell/src-tauri/Cargo.toml',
|
||||
'utf8',
|
||||
);
|
||||
const aiGameCreatorViteConfigSource = fs.readFileSync(
|
||||
'apps/ai-game-creator-shell/vite.config.ts',
|
||||
'utf8',
|
||||
);
|
||||
|
||||
const productionShellScanRoots = [
|
||||
'apps/mobile-shell',
|
||||
@@ -2355,6 +2373,46 @@ function assertAiGameCreatorShellUserDevBoundary() {
|
||||
'AI game creator dev shell must keep local preview iframe access for the developer window',
|
||||
);
|
||||
}
|
||||
if (
|
||||
!aiGameCreatorClientHttpSource.includes(
|
||||
"'https://dev.genarrative.world'",
|
||||
) ||
|
||||
!aiGameCreatorClientHttpSource.includes("transport: 'tauri-http'") ||
|
||||
!aiGameCreatorClientHttpSource.includes('target.origin !==')
|
||||
) {
|
||||
throw new Error(
|
||||
'AI game creator release dev API transport boundary drifted',
|
||||
);
|
||||
}
|
||||
if (
|
||||
!aiGameCreatorCargoManifestSource.includes('tauri-plugin-http = "2.5.9"') ||
|
||||
!aiGameCreatorShellTauriSource.includes('tauri_plugin_http::init()')
|
||||
) {
|
||||
throw new Error(
|
||||
'AI game creator release must register the native HTTP plugin',
|
||||
);
|
||||
}
|
||||
if (
|
||||
!aiGameCreatorViteConfigSource.includes("dedupe: ['react', 'react-dom']")
|
||||
) {
|
||||
throw new Error(
|
||||
'AI game creator monorepo build must dedupe React runtime packages',
|
||||
);
|
||||
}
|
||||
const httpPermission = (aiGameCreatorMainCapability.permissions ?? []).find(
|
||||
(permission) =>
|
||||
typeof permission === 'object' &&
|
||||
permission?.identifier === 'http:default',
|
||||
);
|
||||
if (
|
||||
!httpPermission ||
|
||||
JSON.stringify(httpPermission.allow ?? []) !==
|
||||
JSON.stringify([{ url: 'https://dev.genarrative.world/api/*' }])
|
||||
) {
|
||||
throw new Error(
|
||||
'AI game creator native HTTP scope must stay limited to the dev API',
|
||||
);
|
||||
}
|
||||
|
||||
for (const snippet of [
|
||||
'function isDeveloperMode()',
|
||||
@@ -2369,11 +2427,13 @@ function assertAiGameCreatorShellUserDevBoundary() {
|
||||
}
|
||||
for (const snippet of [
|
||||
'projectSupervisorOnly ? false : isDeveloperMode()',
|
||||
"{devMode ? (",
|
||||
'{devMode ? (',
|
||||
'className="developer-pane"',
|
||||
]) {
|
||||
if (!aiGameCreatorShellAppSource.includes(snippet)) {
|
||||
throw new Error(`AI game creator user/dev UI boundary drifted: missing ${snippet}`);
|
||||
throw new Error(
|
||||
`AI game creator user/dev UI boundary drifted: missing ${snippet}`,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (
|
||||
@@ -2391,13 +2451,20 @@ function assertAiGameCreatorShellUserDevBoundary() {
|
||||
const previewFrameCount = [
|
||||
...aiGameCreatorShellDeveloperProjectPanelsSource.matchAll(/<iframe\b/g),
|
||||
].length;
|
||||
const devModeBranchIndex = aiGameCreatorShellAppSource.indexOf('{devMode ? (');
|
||||
const developerPaneIndex = aiGameCreatorShellAppSource.indexOf('className="developer-pane"');
|
||||
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');
|
||||
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');
|
||||
throw new Error(
|
||||
'AI game creator developer project panels mount count drifted',
|
||||
);
|
||||
}
|
||||
if (
|
||||
devModeBranchIndex < 0 ||
|
||||
@@ -2406,7 +2473,9 @@ function assertAiGameCreatorShellUserDevBoundary() {
|
||||
(index) => index < devModeBranchIndex || index < developerPaneIndex,
|
||||
)
|
||||
) {
|
||||
throw new Error('AI game creator preview panels must stay inside the dev-only pane');
|
||||
throw new Error(
|
||||
'AI game creator preview panels must stay inside the dev-only pane',
|
||||
);
|
||||
}
|
||||
// 上面几条只约束 DeveloperProjectPanels 自身的 iframe 数量和挂载位置,管不到 App.tsx
|
||||
// 直接内嵌 iframe 的情况——预览必须一律委托给客户端工作台,外壳自己不持有预览框。
|
||||
|
||||
Reference in New Issue
Block a user