修复资源画布溢出与模板资源投影
Project CI / Backend tests (pull_request) Failing after 10s
Project CI / Repository checks (pull_request) Failing after 10s
Project CI / Frontend tests (pull_request) Successful in 3m3s
Project CI / Native shell tests (pull_request) Successful in 10m23s

闭合资源画布横向收缩链并增加内部滚动条

过滤任务产物通配模板避免生成无效资源卡

补充布局与资源投影回归测试

同步工作台文档与共享排障记忆
This commit is contained in:
2026-08-07 10:53:41 +08:00
parent 53e37ea361
commit 8a4b71bf8e
8 changed files with 114 additions and 3 deletions
+33 -1
View File
@@ -3736,6 +3736,7 @@ iframe.preview-frame {
.game-workbench-stage {
position: relative;
display: grid;
grid-template-columns: minmax(0, 1fr);
grid-template-rows: auto auto minmax(0, 1fr);
}
@@ -3840,7 +3841,9 @@ iframe.preview-frame {
.game-resource-manager {
display: flex;
flex-direction: column;
min-width: 0;
min-height: 0;
overflow: hidden;
}
.game-resource-search {
@@ -3894,14 +3897,43 @@ iframe.preview-frame {
.game-resource-canvas {
position: relative;
flex: 1;
width: 100%;
min-width: 0;
min-height: 0;
padding: 12px;
overflow: auto;
overflow-x: auto;
overflow-y: auto;
scrollbar-color: #d5a089 #f7e7df;
scrollbar-width: thin;
background-color: #fffdfa;
background-image: radial-gradient(#eaded8 0.8px, transparent 0.8px);
background-size: 18px 18px;
}
.game-resource-canvas::-webkit-scrollbar {
width: 10px;
height: 12px;
}
.game-resource-canvas::-webkit-scrollbar-track {
border-radius: 999px;
background: #f7e7df;
}
.game-resource-canvas::-webkit-scrollbar-thumb {
border: 2px solid #f7e7df;
border-radius: 999px;
background: #d5a089;
}
.game-resource-canvas::-webkit-scrollbar-thumb:hover {
background: #c98566;
}
.game-resource-canvas::-webkit-scrollbar-corner {
background: #f7e7df;
}
.game-resource-canvas-content {
position: relative;
display: grid;
@@ -58,6 +58,11 @@ function fileName(path: string) {
return path.split(/[\\/]/u).filter(Boolean).pop() || path;
}
function isConcreteTaskArtifactPath(path: string) {
const normalizedPath = path.trim();
return normalizedPath.length > 0 && !/[*?\[\]{}]/u.test(normalizedPath);
}
export function classifyProjectedResource(input: {
path: string;
mediaType: string;
@@ -119,6 +124,9 @@ export function projectResourcesFromReadModels(
continue;
}
for (const path of task.artifacts) {
if (!isConcreteTaskArtifactPath(path)) {
continue;
}
const category = classifyProjectedResource({ path, mediaType: '' });
if (!category || category === 'audio') {
continue;
@@ -56,6 +56,10 @@ describe('项目资源投影', () => {
'memory/game-design.md',
'assets/ui-preview.svg',
'build/game.bundle',
'.agent/passes/pass-*/groups/design/director.md',
'memory/draft?.md',
'assets/[ab].png',
'memory/{draft,final}.md',
];
audioTask.status = 'completed';
audioTask.artifacts = ['audio/unregistered-bgm.wav'];
@@ -151,6 +155,10 @@ describe('项目资源投影', () => {
[
'task:design-foundation:build/game.bundle',
'task:audio-asset-plan:audio/unregistered-bgm.wav',
'task:design-foundation:.agent/passes/pass-*/groups/design/director.md',
'task:design-foundation:memory/draft?.md',
'task:design-foundation:assets/[ab].png',
'task:design-foundation:memory/{draft,final}.md',
'asset:unknown-binary',
'attachment:imports/archive.zip',
].includes(id),
@@ -1,3 +1,6 @@
import { readFileSync } from 'node:fs';
import { resolve } from 'node:path';
import { describe, expect, it } from 'vitest';
import {
@@ -6,6 +9,38 @@ import {
} from '../../../packages/shared/src/contracts/gameCreationApp';
describe('resource canvas layout contract', () => {
it('keeps wide resource content inside an explicitly scrollable stage column', () => {
const styles = readFileSync(
resolve(process.cwd(), 'apps/ai-game-creator-shell/src/styles.css'),
'utf8',
);
const stageRule = styles.match(
/\.game-workbench-stage\s*\{([^}]*)\}/s,
);
const managerRule = styles.match(
/\.game-resource-manager\s*\{([^}]*)\}/s,
);
const canvasRule = styles.match(
/\.game-resource-canvas\s*\{([^}]*)\}/s,
);
expect(stageRule?.[1]).toContain(
'grid-template-columns: minmax(0, 1fr);',
);
expect(managerRule?.[1]).toContain('min-width: 0;');
expect(managerRule?.[1]).toContain('overflow: hidden;');
expect(canvasRule?.[1]).toContain('width: 100%;');
expect(canvasRule?.[1]).toContain('min-width: 0;');
expect(canvasRule?.[1]).toContain('overflow-x: auto;');
expect(canvasRule?.[1]).toContain('overflow-y: auto;');
expect(styles).toMatch(
/\.game-resource-canvas::-webkit-scrollbar\s*\{[^}]*height:\s*12px/s,
);
expect(styles).toMatch(
/\.game-resource-canvas::-webkit-scrollbar-thumb\s*\{[^}]*background:\s*#d5a089/s,
);
});
it('keeps revisions inside the JSON safe integer range', () => {
const maxRevision = GAME_CREATION_RESOURCE_LAYOUT_MAX_SAFE_REVISION;
expect(JSON.parse(JSON.stringify({ revision: maxRevision }))).toEqual({