修复客户端预览所有权门禁
Project CI / Frontend tests (pull_request) Successful in 3m49s
Project CI / Backend tests (pull_request) Successful in 3m56s
Project CI / Repository checks (pull_request) Successful in 55s
Project CI / Native shell tests (pull_request) Failing after 11m8s

让 Native shell 检查识别共享 LocalGamePreviewFrame 的唯一物理 iframe
校验项目开发与总控对话视图分别委托共享预览组件
同步校验抽取后的 URL 安全与 sandbox 契约位置
This commit is contained in:
2026-07-30 19:15:28 +08:00
parent 296b21521d
commit 3318be3da0
+29 -3
View File
@@ -42,6 +42,14 @@ const aiGameCreatorProjectDevelopmentSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/view/project-development/index.tsx',
'utf8',
);
const aiGameCreatorLocalGamePreviewFrameSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/features/project-workspace/LocalGamePreviewFrame.tsx',
'utf8',
);
const aiGameCreatorSupervisorChatOnlyViewSource = fs.readFileSync(
'apps/ai-game-creator-shell/src/features/project-workspace/SupervisorChatOnlyView.tsx',
'utf8',
);
const aiGameCreatorPreviewRustSource = fs.readFileSync(
'apps/ai-game-creator-shell/src-tauri/src/preview.rs',
'utf8',
@@ -2409,20 +2417,38 @@ function assertAiGameCreatorShellUserDevBoundary() {
}
const clientPreviewFrameCount = [
...aiGameCreatorProjectDevelopmentSource.matchAll(/<iframe\b/g),
...aiGameCreatorLocalGamePreviewFrameSource.matchAll(/<iframe\b/g),
].length;
if (clientPreviewFrameCount !== 1) {
throw new Error(
'AI game creator client workbench must own exactly one local preview frame',
);
}
const projectDevelopmentPreviewMountCount = [
...aiGameCreatorProjectDevelopmentSource.matchAll(
/<LocalGamePreviewFrame\b/g,
),
].length;
const supervisorChatPreviewMountCount = [
...aiGameCreatorSupervisorChatOnlyViewSource.matchAll(
/<LocalGamePreviewFrame\b/g,
),
].length;
if (
projectDevelopmentPreviewMountCount !== 1 ||
supervisorChatPreviewMountCount !== 1
) {
throw new Error(
'AI game creator client views must delegate preview rendering to the shared local preview frame',
);
}
for (const snippet of [
'function resolveEmbeddedPreviewUrl(',
"url.protocol !== 'http:' || url.hostname !== '127.0.0.1'",
'sandbox="allow-scripts allow-same-origin allow-forms allow-pointer-lock"',
'src={embeddedPreviewUrl}',
'src={embeddedUrl}',
]) {
if (!aiGameCreatorProjectDevelopmentSource.includes(snippet)) {
if (!aiGameCreatorLocalGamePreviewFrameSource.includes(snippet)) {
throw new Error(
`AI game creator embedded preview boundary drifted: missing ${snippet}`,
);