WIP: AGC 资源画布与替换改造 V3.0 #316

Draft
suzmii wants to merge 131 commits from feat/agc-canvas-resource-workbench-v3 into master
8 changed files with 55 additions and 6979 deletions
Showing only changes of commit 9fd5b99972 - Show all commits
@@ -111,6 +111,7 @@ const allowedUncalledTauriCommands = [
'chat_with_game_creator_agent',
'check_ui_editor_font_glyph_coverage',
'create_ui_design_resource',
'normalize_local_project_raster_resource',
'open_game_creator_launcher_window',
'open_game_creator_workspace_window',
'read_direct_project_conversation',
File diff suppressed because it is too large Load Diff
@@ -1,82 +0,0 @@
const COMMIT_ID_SUFFIX =
/--[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
const WINDOWS_RESERVED_NAMES = new Set([
'CON',
'PRN',
'AUX',
'NUL',
'COM1',
'COM2',
'COM3',
'COM4',
'COM5',
'COM6',
'COM7',
'COM8',
'COM9',
'LPT1',
'LPT2',
'LPT3',
'LPT4',
'LPT5',
'LPT6',
'LPT7',
'LPT8',
'LPT9',
]);
const FORBIDDEN_FILE_NAME_CHARACTERS = '/\\:*?"<>|';
function isForbiddenFileNameCharacter(value: string) {
const code = value.codePointAt(0) ?? 0;
return (
code <= 0x1f ||
code === 0x7f ||
FORBIDDEN_FILE_NAME_CHARACTERS.includes(value)
);
}
function sanitizeAssetBaseName(value: string, fallback: string) {
const normalized = value
.normalize('NFC')
.split('')
.filter((character) => !isForbiddenFileNameCharacter(character))
.join('');
const bounded = Array.from(normalized)
.slice(0, 80)
.join('')
.replace(/[. ]+$/u, '');
if (
bounded.length === 0 ||
WINDOWS_RESERVED_NAMES.has(bounded.split('.')[0]?.toUpperCase() ?? '')
) {
return fallback;
}
return bounded;
}
export function canonicalAssetBaseName(
localPath: string,
fallback = '画布素材',
) {
const fileName = localPath.split(/[\\/]/u).filter(Boolean).pop() ?? '';
let stem = fileName.replace(/\.[^.]+$/u, '');
let next = stem.replace(COMMIT_ID_SUFFIX, '');
while (next !== stem) {
stem = next;
next = stem.replace(COMMIT_ID_SUFFIX, '');
}
return sanitizeAssetBaseName(next, fallback);
}
export function isValidAssetCanvasName(name: string) {
if (
name.length === 0 ||
Array.from(name).length > 80 ||
Array.from(name).some(isForbiddenFileNameCharacter) ||
/[. ]$/u.test(name) ||
WINDOWS_RESERVED_NAMES.has(name.split('.')[0]?.toUpperCase() ?? '')
) {
return false;
}
return true;
}
File diff suppressed because it is too large Load Diff
@@ -5444,7 +5444,6 @@ iframe.preview-frame {
box-shadow: var(--platform-nav-active-shadow);
}
.game-workbench-stage[data-resource-view-state^='resources.asset-canvas'],
.game-workbench-stage[data-resource-view-state='resources.ui-editor'] {
grid-template-rows: auto minmax(0, 1fr);
}
@@ -5455,12 +5454,6 @@ iframe.preview-frame {
min-height: 0;
}
.game-workbench-stage[data-resource-view-state^='resources.asset-canvas']
> .asset-canvas-surface {
grid-row: 2;
min-height: 0;
}
.game-workbench-toolbar {
position: relative;
display: flex;
File diff suppressed because it is too large Load Diff
@@ -11,26 +11,13 @@ export type LocalProjectResourceEditKind =
| 'agent-result'
| 'version';
export type ProjectResourceEditCapability =
| {
route: 'image-canvas';
sourceAssetId: string;
normalizeSource: false;
mediaType: 'image/png' | 'image/jpeg' | 'image/webp';
}
| {
route: 'image-canvas';
sourceAssetId: null;
normalizeSource: true;
mediaType: 'image/png' | 'image/jpeg' | 'image/webp';
}
| {
route: 'derive';
editKind: LocalProjectResourceEditKind;
sourceMediaType: string;
semanticNotice: string | null;
generationMode?: 'create' | 'derive';
};
export type ProjectResourceEditCapability = {
route: 'derive';
editKind: LocalProjectResourceEditKind;
sourceMediaType: string;
semanticNotice: string | null;
generationMode?: 'create' | 'derive';
};
const extensionMediaTypes: Record<string, string> = {
png: 'image/png',
@@ -140,21 +127,6 @@ export function resolveProjectResourceEditCapability(
}
const mediaType = canonicalProjectedResourceMediaType(resource);
if (['image/png', 'image/jpeg', 'image/webp'].includes(mediaType)) {
return resource.manifestAssetId
? {
route: 'image-canvas',
sourceAssetId: resource.manifestAssetId,
normalizeSource: false,
mediaType: mediaType as 'image/png' | 'image/jpeg' | 'image/webp',
}
: {
route: 'image-canvas',
sourceAssetId: null,
normalizeSource: true,
mediaType: mediaType as 'image/png' | 'image/jpeg' | 'image/webp',
};
}
if (mediaType === 'image/svg+xml') {
return {
route: 'derive',