@pinepaper.studio/mcp-server 1.5.0 → 1.5.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +0 -25
- package/dist/agent/export-manager.d.ts.map +1 -1
- package/dist/agent/export-manager.js +24 -14
- package/dist/agent/export-manager.js.map +1 -1
- package/dist/agent/types.d.ts +6 -6
- package/dist/browser/puppeteer-controller.d.ts +5 -1
- package/dist/browser/puppeteer-controller.d.ts.map +1 -1
- package/dist/browser/puppeteer-controller.js +11 -3
- package/dist/browser/puppeteer-controller.js.map +1 -1
- package/dist/cli.js +61 -66
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +145 -122
- package/dist/index.js.map +1 -1
- package/dist/metrics/types.d.ts +3 -1
- package/dist/metrics/types.d.ts.map +1 -1
- package/dist/ontology/design-graph.d.ts +85 -0
- package/dist/ontology/design-graph.d.ts.map +1 -0
- package/dist/ontology/design-graph.js +944 -0
- package/dist/ontology/design-graph.js.map +1 -0
- package/dist/ontology/index.d.ts +11 -0
- package/dist/ontology/index.d.ts.map +1 -0
- package/dist/ontology/index.js +14 -0
- package/dist/ontology/index.js.map +1 -0
- package/dist/ontology/semantic-vocabulary.d.ts +12 -0
- package/dist/ontology/semantic-vocabulary.d.ts.map +1 -0
- package/dist/ontology/semantic-vocabulary.js +26 -0
- package/dist/ontology/semantic-vocabulary.js.map +1 -0
- package/dist/ontology/types.d.ts +255 -0
- package/dist/ontology/types.d.ts.map +1 -0
- package/dist/ontology/types.js +10 -0
- package/dist/ontology/types.js.map +1 -0
- package/dist/ontology/validator.d.ts +36 -0
- package/dist/ontology/validator.d.ts.map +1 -0
- package/dist/ontology/validator.js +374 -0
- package/dist/ontology/validator.js.map +1 -0
- package/dist/ontology/vocabulary.d.ts +34 -0
- package/dist/ontology/vocabulary.d.ts.map +1 -0
- package/dist/ontology/vocabulary.js +395 -0
- package/dist/ontology/vocabulary.js.map +1 -0
- package/dist/prompts/index.d.ts +3 -12
- package/dist/prompts/index.d.ts.map +1 -1
- package/dist/prompts/index.js +5 -96
- package/dist/prompts/index.js.map +1 -1
- package/dist/tools/compact-descriptions.d.ts +3 -3
- package/dist/tools/compact-descriptions.d.ts.map +1 -1
- package/dist/tools/compact-descriptions.js +58 -215
- package/dist/tools/compact-descriptions.js.map +1 -1
- package/dist/tools/definitions.d.ts +6 -4
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +789 -65
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +616 -86
- package/dist/tools/handlers.js.map +1 -1
- package/dist/tools/index.d.ts +3 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +2 -1
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/minimal-descriptions.d.ts +9 -0
- package/dist/tools/minimal-descriptions.d.ts.map +1 -0
- package/dist/tools/minimal-descriptions.js +178 -0
- package/dist/tools/minimal-descriptions.js.map +1 -0
- package/dist/tools/toolkits.d.ts +51 -0
- package/dist/tools/toolkits.d.ts.map +1 -0
- package/dist/tools/toolkits.js +366 -0
- package/dist/tools/toolkits.js.map +1 -0
- package/dist/types/code-generator.d.ts +14 -6
- package/dist/types/code-generator.d.ts.map +1 -1
- package/dist/types/code-generator.js +654 -196
- package/dist/types/code-generator.js.map +1 -1
- package/dist/types/schemas.d.ts +429 -147
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +159 -49
- package/dist/types/schemas.js.map +1 -1
- package/manifest.json +30 -6
- package/package.json +2 -2
|
@@ -14,8 +14,6 @@ AgentStartJobInputSchema, AgentEndJobInputSchema, AgentResetInputSchema, AgentBa
|
|
|
14
14
|
AddTriggerInputSchema, RemoveTriggerInputSchema, QueryTriggersInputSchema,
|
|
15
15
|
// Quiz types
|
|
16
16
|
CreateQuizInputSchema, GetQuizStateInputSchema, ResetQuizInputSchema,
|
|
17
|
-
// Widget export types
|
|
18
|
-
ExportWidgetInputSchema,
|
|
19
17
|
// Letter collage types
|
|
20
18
|
CreateLetterCollageInputSchema, AnimateLetterCollageInputSchema,
|
|
21
19
|
// Map types
|
|
@@ -353,6 +351,12 @@ function generatePlayTimelineCode(action, duration, loop, time) {
|
|
|
353
351
|
// Play keyframe timeline
|
|
354
352
|
app.playKeyframeTimeline(${duration || 5}, ${loop ?? false});
|
|
355
353
|
({ success: true, action: 'play', duration: ${duration || 5}, loop: ${loop ?? false} });
|
|
354
|
+
`.trim();
|
|
355
|
+
case 'pause':
|
|
356
|
+
return `
|
|
357
|
+
// Pause keyframe timeline
|
|
358
|
+
app.pauseKeyframeTimeline();
|
|
359
|
+
({ success: true, action: 'pause' });
|
|
356
360
|
`.trim();
|
|
357
361
|
case 'stop':
|
|
358
362
|
return `
|
|
@@ -1798,11 +1802,11 @@ return { success: true, action: 'seek', time: ${op.time || 0} };
|
|
|
1798
1802
|
const validated = AgentExportInputSchema.parse(input);
|
|
1799
1803
|
const { platform, format, quality } = validated;
|
|
1800
1804
|
const qualityLevel = quality || 'standard';
|
|
1801
|
-
// Quality settings
|
|
1805
|
+
// Quality settings (bitrate in bps for VideoEncoder)
|
|
1802
1806
|
const qualitySettings = {
|
|
1803
|
-
draft: { compression: 0.6, fps: 15, dpi: 72 },
|
|
1804
|
-
standard: { compression: 0.85, fps: 30, dpi: 150 },
|
|
1805
|
-
high: { compression: 0.95, fps: 60, dpi: 300 },
|
|
1807
|
+
draft: { compression: 0.6, fps: 15, dpi: 72, bitrate: 2_000_000 },
|
|
1808
|
+
standard: { compression: 0.85, fps: 30, dpi: 150, bitrate: 5_000_000 },
|
|
1809
|
+
high: { compression: 0.95, fps: 60, dpi: 300, bitrate: 8_000_000 },
|
|
1806
1810
|
}[qualityLevel];
|
|
1807
1811
|
// Platform presets
|
|
1808
1812
|
const platformPresets = {
|
|
@@ -1874,35 +1878,36 @@ return { success: true, action: 'seek', time: ${op.time || 0} };
|
|
|
1874
1878
|
break;
|
|
1875
1879
|
|
|
1876
1880
|
case 'gif':
|
|
1877
|
-
if (app.exportEngine && app.exportEngine.exportGIF) {
|
|
1878
|
-
const blob = await app.exportEngine.exportGIF({ fps: settings.fps, quality: settings.compression, duration: 5 });
|
|
1879
|
-
const reader = new FileReader();
|
|
1880
|
-
const dataUrl = await new Promise(resolve => {
|
|
1881
|
-
reader.onloadend = () => resolve(reader.result);
|
|
1882
|
-
reader.readAsDataURL(blob);
|
|
1883
|
-
});
|
|
1884
|
-
result = { success: true, platform, format: 'gif', data: dataUrl, mimeType: 'image/gif', size: blob.size };
|
|
1885
|
-
} else {
|
|
1886
|
-
result = { success: false, error: 'GIF export not available' };
|
|
1887
|
-
}
|
|
1888
|
-
break;
|
|
1889
|
-
|
|
1890
1881
|
case 'mp4':
|
|
1891
|
-
case 'webm':
|
|
1892
|
-
const
|
|
1893
|
-
|
|
1894
|
-
if (app.exportEngine && app.exportEngine
|
|
1895
|
-
const
|
|
1882
|
+
case 'webm': {
|
|
1883
|
+
const videoMimeType = { mp4: 'video/mp4', webm: 'video/webm', gif: 'image/gif' }[format];
|
|
1884
|
+
// Use _quickExportVideo (delegates to VideoExporter.export internally)
|
|
1885
|
+
if (app.exportEngine && app.exportEngine._quickExportVideo) {
|
|
1886
|
+
const videoResult = await app.exportEngine._quickExportVideo(format, { fps: settings.fps, bitrate: settings.bitrate, duration: 5 }, false);
|
|
1887
|
+
if (videoResult && videoResult.blob) {
|
|
1888
|
+
const reader = new FileReader();
|
|
1889
|
+
const dataUrl = await new Promise(resolve => {
|
|
1890
|
+
reader.onloadend = () => resolve(reader.result);
|
|
1891
|
+
reader.readAsDataURL(videoResult.blob);
|
|
1892
|
+
});
|
|
1893
|
+
result = { success: true, platform, format, data: dataUrl, mimeType: videoMimeType, size: videoResult.blob.size };
|
|
1894
|
+
} else {
|
|
1895
|
+
result = { success: false, error: format.toUpperCase() + ' export returned no data' };
|
|
1896
|
+
}
|
|
1897
|
+
} else if (app.exportEngine && app.exportEngine.videoExporter) {
|
|
1898
|
+
// Fallback: call VideoExporter.export directly
|
|
1899
|
+
const blob = await app.exportEngine.videoExporter.export({ format, fps: settings.fps, bitrate: settings.bitrate, duration: 5 });
|
|
1896
1900
|
const reader = new FileReader();
|
|
1897
1901
|
const dataUrl = await new Promise(resolve => {
|
|
1898
1902
|
reader.onloadend = () => resolve(reader.result);
|
|
1899
1903
|
reader.readAsDataURL(blob);
|
|
1900
1904
|
});
|
|
1901
|
-
result = { success: true, platform, format, data: dataUrl, mimeType, size: blob.size };
|
|
1905
|
+
result = { success: true, platform, format, data: dataUrl, mimeType: videoMimeType, size: blob.size };
|
|
1902
1906
|
} else {
|
|
1903
1907
|
result = { success: false, error: format.toUpperCase() + ' export not available' };
|
|
1904
1908
|
}
|
|
1905
1909
|
break;
|
|
1910
|
+
}
|
|
1906
1911
|
|
|
1907
1912
|
case 'pdf':
|
|
1908
1913
|
if (app.exportEngine && app.exportEngine.exportPDF) {
|
|
@@ -1914,7 +1919,7 @@ return { success: true, action: 'seek', time: ${op.time || 0} };
|
|
|
1914
1919
|
});
|
|
1915
1920
|
result = { success: true, platform, format: 'pdf', data: dataUrl, mimeType: 'application/pdf', size: blob.size, dpi: settings.dpi };
|
|
1916
1921
|
} else {
|
|
1917
|
-
result = { success: false, error: 'PDF export
|
|
1922
|
+
result = { success: false, error: 'PDF export failed' };
|
|
1918
1923
|
}
|
|
1919
1924
|
break;
|
|
1920
1925
|
|
|
@@ -2311,176 +2316,6 @@ quiz.state = {
|
|
|
2311
2316
|
app.historyManager.saveState();
|
|
2312
2317
|
|
|
2313
2318
|
({ success: true, quizId: quiz.id, reset: true });
|
|
2314
|
-
`.trim();
|
|
2315
|
-
}
|
|
2316
|
-
// ===========================================================================
|
|
2317
|
-
// WIDGET EXPORT CODE GENERATORS
|
|
2318
|
-
// ===========================================================================
|
|
2319
|
-
/**
|
|
2320
|
-
* Generate code for exporting widget
|
|
2321
|
-
*/
|
|
2322
|
-
generateExportWidget(input) {
|
|
2323
|
-
const validated = ExportWidgetInputSchema.parse(input);
|
|
2324
|
-
const { format, sizing, interactivity, autoplay, loop, lmsEnabled, width, height } = validated;
|
|
2325
|
-
const sizingMode = sizing || 'responsive';
|
|
2326
|
-
const interactivityLevel = interactivity || 'view';
|
|
2327
|
-
const shouldAutoplay = autoplay !== false;
|
|
2328
|
-
const shouldLoop = loop !== false;
|
|
2329
|
-
const hasLms = lmsEnabled || false;
|
|
2330
|
-
return `
|
|
2331
|
-
// Export widget as ${format}
|
|
2332
|
-
(async function() {
|
|
2333
|
-
const format = '${format}';
|
|
2334
|
-
const sizing = '${sizingMode}';
|
|
2335
|
-
const interactivity = '${interactivityLevel}';
|
|
2336
|
-
const autoplay = ${shouldAutoplay};
|
|
2337
|
-
const loop = ${shouldLoop};
|
|
2338
|
-
const lmsEnabled = ${hasLms};
|
|
2339
|
-
const fixedWidth = ${width || 'null'};
|
|
2340
|
-
const fixedHeight = ${height || 'null'};
|
|
2341
|
-
|
|
2342
|
-
// Capture scene data
|
|
2343
|
-
const sceneData = app.exportSceneData ? JSON.stringify(app.exportSceneData()) : '{}';
|
|
2344
|
-
|
|
2345
|
-
// Get canvas dimensions
|
|
2346
|
-
let canvasWidth = fixedWidth || (app.canvasEl ? app.canvasEl.width : 800);
|
|
2347
|
-
let canvasHeight = fixedHeight || (app.canvasEl ? app.canvasEl.height : 600);
|
|
2348
|
-
|
|
2349
|
-
// Check for animations
|
|
2350
|
-
const items = app.itemRegistry ? app.itemRegistry.getAll() : [];
|
|
2351
|
-
const hasAnimations = items.some(e => e.item.data?.animationType);
|
|
2352
|
-
const hasRelations = app.relationRegistry && app.relationRegistry.getAll().length > 0;
|
|
2353
|
-
const hasQuiz = app.quizManager && app.quizManager.quizzes.length > 0;
|
|
2354
|
-
const hasTriggers = items.some(e => e.item.data?.triggers?.length > 0);
|
|
2355
|
-
|
|
2356
|
-
const metadata = {
|
|
2357
|
-
hasInteractivity: hasTriggers || interactivity === 'full',
|
|
2358
|
-
hasAnimations: hasAnimations || hasRelations,
|
|
2359
|
-
hasQuiz,
|
|
2360
|
-
width: canvasWidth,
|
|
2361
|
-
height: canvasHeight,
|
|
2362
|
-
sizing,
|
|
2363
|
-
interactivity
|
|
2364
|
-
};
|
|
2365
|
-
|
|
2366
|
-
let code = '';
|
|
2367
|
-
let embedCode = '';
|
|
2368
|
-
|
|
2369
|
-
switch (format) {
|
|
2370
|
-
case 'web-component':
|
|
2371
|
-
code = \`<script src="https://cdn.pinepaper.io/widget.js"></script>
|
|
2372
|
-
<pinepaper-widget
|
|
2373
|
-
data-scene='\${sceneData}'
|
|
2374
|
-
data-sizing="\${sizing}"
|
|
2375
|
-
data-interactivity="\${interactivity}"
|
|
2376
|
-
data-autoplay="\${autoplay}"
|
|
2377
|
-
data-loop="\${loop}"
|
|
2378
|
-
\${fixedWidth ? 'width="' + canvasWidth + '"' : ''}
|
|
2379
|
-
\${fixedHeight ? 'height="' + canvasHeight + '"' : ''}
|
|
2380
|
-
></pinepaper-widget>\`;
|
|
2381
|
-
embedCode = code;
|
|
2382
|
-
break;
|
|
2383
|
-
|
|
2384
|
-
case 'standalone-html':
|
|
2385
|
-
code = \`<!DOCTYPE html>
|
|
2386
|
-
<html>
|
|
2387
|
-
<head>
|
|
2388
|
-
<meta charset="UTF-8">
|
|
2389
|
-
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
2390
|
-
<title>PinePaper Widget</title>
|
|
2391
|
-
<script src="https://cdn.pinepaper.io/runtime.js"></script>
|
|
2392
|
-
<style>
|
|
2393
|
-
body { margin: 0; padding: 0; display: flex; justify-content: center; align-items: center; min-height: 100vh; background: #f5f5f5; }
|
|
2394
|
-
.pinepaper-container { \${sizing === 'responsive' ? 'width: 100%; max-width: ' + canvasWidth + 'px;' : sizing === 'fluid' ? 'width: 100%; height: 100%;' : 'width: ' + canvasWidth + 'px; height: ' + canvasHeight + 'px;'} }
|
|
2395
|
-
</style>
|
|
2396
|
-
</head>
|
|
2397
|
-
<body>
|
|
2398
|
-
<div class="pinepaper-container" id="pinepaper-widget"></div>
|
|
2399
|
-
<script>
|
|
2400
|
-
PinePaper.init('#pinepaper-widget', {
|
|
2401
|
-
scene: \${sceneData},
|
|
2402
|
-
autoplay: \${autoplay},
|
|
2403
|
-
loop: \${loop},
|
|
2404
|
-
interactivity: '\${interactivity}'\${hasLms ? ',\\n lms: true' : ''}
|
|
2405
|
-
});
|
|
2406
|
-
</script>
|
|
2407
|
-
</body>
|
|
2408
|
-
</html>\`;
|
|
2409
|
-
embedCode = \`<iframe src="[URL_TO_HOSTED_FILE]" width="\${canvasWidth}" height="\${canvasHeight}" frameborder="0"></iframe>\`;
|
|
2410
|
-
break;
|
|
2411
|
-
|
|
2412
|
-
case 'iframe-embed':
|
|
2413
|
-
const dataUri = 'data:text/html;base64,' + btoa(\`<!DOCTYPE html><html><head><script src="https://cdn.pinepaper.io/runtime.js"></script></head><body><div id="w"></div><script>PinePaper.init('#w',{scene:\${sceneData},autoplay:\${autoplay},loop:\${loop}});</script></body></html>\`);
|
|
2414
|
-
code = dataUri;
|
|
2415
|
-
embedCode = \`<iframe src="\${dataUri}" width="\${canvasWidth}" height="\${canvasHeight}" frameborder="0" allowfullscreen></iframe>\`;
|
|
2416
|
-
break;
|
|
2417
|
-
|
|
2418
|
-
case 'react-component':
|
|
2419
|
-
code = \`import { useEffect, useRef } from 'react';
|
|
2420
|
-
|
|
2421
|
-
export function PinepaperWidget({ className }) {
|
|
2422
|
-
const containerRef = useRef(null);
|
|
2423
|
-
|
|
2424
|
-
useEffect(() => {
|
|
2425
|
-
if (containerRef.current && window.PinePaper) {
|
|
2426
|
-
window.PinePaper.init(containerRef.current, {
|
|
2427
|
-
scene: \${sceneData},
|
|
2428
|
-
autoplay: \${autoplay},
|
|
2429
|
-
loop: \${loop},
|
|
2430
|
-
interactivity: '\${interactivity}'
|
|
2431
|
-
});
|
|
2432
|
-
}
|
|
2433
|
-
}, []);
|
|
2434
|
-
|
|
2435
|
-
return <div ref={containerRef} className={className} style={{ width: '\${sizing === 'fixed' ? canvasWidth + 'px' : '100%'}', height: '\${sizing === 'fixed' ? canvasHeight + 'px' : 'auto'}' }} />;
|
|
2436
|
-
}
|
|
2437
|
-
|
|
2438
|
-
// Usage: <PinepaperWidget className="my-widget" />\`;
|
|
2439
|
-
embedCode = '<PinepaperWidget />';
|
|
2440
|
-
break;
|
|
2441
|
-
|
|
2442
|
-
case 'vue-component':
|
|
2443
|
-
code = \`<template>
|
|
2444
|
-
<div ref="container" :class="className" :style="containerStyle"></div>
|
|
2445
|
-
</template>
|
|
2446
|
-
|
|
2447
|
-
<script setup>
|
|
2448
|
-
import { ref, onMounted, computed } from 'vue';
|
|
2449
|
-
|
|
2450
|
-
const props = defineProps({ className: String });
|
|
2451
|
-
const container = ref(null);
|
|
2452
|
-
|
|
2453
|
-
const containerStyle = computed(() => ({
|
|
2454
|
-
width: '\${sizing === 'fixed' ? canvasWidth + 'px' : '100%'}',
|
|
2455
|
-
height: '\${sizing === 'fixed' ? canvasHeight + 'px' : 'auto'}'
|
|
2456
|
-
}));
|
|
2457
|
-
|
|
2458
|
-
onMounted(() => {
|
|
2459
|
-
if (container.value && window.PinePaper) {
|
|
2460
|
-
window.PinePaper.init(container.value, {
|
|
2461
|
-
scene: \${sceneData},
|
|
2462
|
-
autoplay: \${autoplay},
|
|
2463
|
-
loop: \${loop},
|
|
2464
|
-
interactivity: '\${interactivity}'
|
|
2465
|
-
});
|
|
2466
|
-
}
|
|
2467
|
-
});
|
|
2468
|
-
</script>
|
|
2469
|
-
|
|
2470
|
-
<!-- Usage: <PinepaperWidget class="my-widget" /> -->\`;
|
|
2471
|
-
embedCode = '<PinepaperWidget />';
|
|
2472
|
-
break;
|
|
2473
|
-
}
|
|
2474
|
-
|
|
2475
|
-
return {
|
|
2476
|
-
success: true,
|
|
2477
|
-
format,
|
|
2478
|
-
code,
|
|
2479
|
-
embedCode,
|
|
2480
|
-
sceneData,
|
|
2481
|
-
metadata
|
|
2482
|
-
};
|
|
2483
|
-
})();
|
|
2484
2319
|
`.trim();
|
|
2485
2320
|
}
|
|
2486
2321
|
// ===========================================================================
|
|
@@ -3636,6 +3471,629 @@ ${mask ? ` app.imageTools.applyMask(raster, '${mask}');\n` : ''} const ite
|
|
|
3636
3471
|
})();
|
|
3637
3472
|
`.trim();
|
|
3638
3473
|
}
|
|
3474
|
+
generateManageScenes(input) {
|
|
3475
|
+
const guard = `if (!app.sceneManager) return { error: 'SceneManager not available' };`;
|
|
3476
|
+
switch (input.action) {
|
|
3477
|
+
case 'save':
|
|
3478
|
+
return `
|
|
3479
|
+
// Save current canvas as scene
|
|
3480
|
+
(async function() {
|
|
3481
|
+
${guard}
|
|
3482
|
+
try {
|
|
3483
|
+
const result = await app.sceneManager.saveCurrentAsScene(${JSON.stringify(input.name || 'Untitled Scene')});
|
|
3484
|
+
return { success: true, action: 'save', sceneId: result?.id || result, name: ${JSON.stringify(input.name || 'Untitled Scene')} };
|
|
3485
|
+
} catch (e) {
|
|
3486
|
+
return { error: 'Failed to save scene: ' + e.message };
|
|
3487
|
+
}
|
|
3488
|
+
})();
|
|
3489
|
+
`.trim();
|
|
3490
|
+
case 'load':
|
|
3491
|
+
return `
|
|
3492
|
+
// Load scene
|
|
3493
|
+
(async function() {
|
|
3494
|
+
${guard}
|
|
3495
|
+
try {
|
|
3496
|
+
await app.sceneManager.loadScene(${JSON.stringify(input.sceneId)}${input.transition ? `, { transition: ${JSON.stringify(input.transition)} }` : ''});
|
|
3497
|
+
return { success: true, action: 'load', sceneId: ${JSON.stringify(input.sceneId)}${input.transition ? `, transition: ${JSON.stringify(input.transition)}` : ''} };
|
|
3498
|
+
} catch (e) {
|
|
3499
|
+
return { error: 'Failed to load scene: ' + e.message };
|
|
3500
|
+
}
|
|
3501
|
+
})();
|
|
3502
|
+
`.trim();
|
|
3503
|
+
case 'list':
|
|
3504
|
+
return `
|
|
3505
|
+
// List all scenes
|
|
3506
|
+
(function() {
|
|
3507
|
+
${guard}
|
|
3508
|
+
const scenes = app.sceneManager.listScenes();
|
|
3509
|
+
return { success: true, action: 'list', scenes: scenes, count: scenes.length };
|
|
3510
|
+
})();
|
|
3511
|
+
`.trim();
|
|
3512
|
+
case 'delete':
|
|
3513
|
+
return `
|
|
3514
|
+
// Delete scene
|
|
3515
|
+
(function() {
|
|
3516
|
+
${guard}
|
|
3517
|
+
app.sceneManager.deleteScene(${JSON.stringify(input.sceneId)});
|
|
3518
|
+
return { success: true, action: 'delete', sceneId: ${JSON.stringify(input.sceneId)} };
|
|
3519
|
+
})();
|
|
3520
|
+
`.trim();
|
|
3521
|
+
case 'rename':
|
|
3522
|
+
return `
|
|
3523
|
+
// Rename scene
|
|
3524
|
+
(function() {
|
|
3525
|
+
${guard}
|
|
3526
|
+
app.sceneManager.renameScene(${JSON.stringify(input.sceneId)}, ${JSON.stringify(input.name)});
|
|
3527
|
+
return { success: true, action: 'rename', sceneId: ${JSON.stringify(input.sceneId)}, name: ${JSON.stringify(input.name)} };
|
|
3528
|
+
})();
|
|
3529
|
+
`.trim();
|
|
3530
|
+
case 'duplicate':
|
|
3531
|
+
return `
|
|
3532
|
+
// Duplicate scene
|
|
3533
|
+
(function() {
|
|
3534
|
+
${guard}
|
|
3535
|
+
const result = app.sceneManager.duplicateScene(${JSON.stringify(input.sceneId)});
|
|
3536
|
+
return { success: true, action: 'duplicate', originalId: ${JSON.stringify(input.sceneId)}, newScene: result };
|
|
3537
|
+
})();
|
|
3538
|
+
`.trim();
|
|
3539
|
+
case 'reorder':
|
|
3540
|
+
return `
|
|
3541
|
+
// Reorder scenes
|
|
3542
|
+
(function() {
|
|
3543
|
+
${guard}
|
|
3544
|
+
app.sceneManager.reorderScenes(${JSON.stringify(input.sceneIds)});
|
|
3545
|
+
return { success: true, action: 'reorder', order: ${JSON.stringify(input.sceneIds)} };
|
|
3546
|
+
})();
|
|
3547
|
+
`.trim();
|
|
3548
|
+
case 'info':
|
|
3549
|
+
return `
|
|
3550
|
+
// Get scene info
|
|
3551
|
+
(function() {
|
|
3552
|
+
${guard}
|
|
3553
|
+
const scene = app.sceneManager.getScene(${JSON.stringify(input.sceneId)});
|
|
3554
|
+
if (!scene) return { error: 'Scene not found: ${input.sceneId}' };
|
|
3555
|
+
return { success: true, action: 'info', scene: scene };
|
|
3556
|
+
})();
|
|
3557
|
+
`.trim();
|
|
3558
|
+
case 'export':
|
|
3559
|
+
return `
|
|
3560
|
+
// Export all scenes
|
|
3561
|
+
(function() {
|
|
3562
|
+
${guard}
|
|
3563
|
+
const data = app.sceneManager.exportScenes();
|
|
3564
|
+
return { success: true, action: 'export', data: data };
|
|
3565
|
+
})();
|
|
3566
|
+
`.trim();
|
|
3567
|
+
case 'import':
|
|
3568
|
+
return `
|
|
3569
|
+
// Import scenes
|
|
3570
|
+
(function() {
|
|
3571
|
+
${guard}
|
|
3572
|
+
try {
|
|
3573
|
+
const json = ${JSON.stringify(input.scenesJson)};
|
|
3574
|
+
app.sceneManager.importScenes(json${input.merge !== undefined ? `, { merge: ${input.merge} }` : ''});
|
|
3575
|
+
return { success: true, action: 'import'${input.merge !== undefined ? `, merge: ${input.merge}` : ''} };
|
|
3576
|
+
} catch (e) {
|
|
3577
|
+
return { error: 'Failed to import scenes: ' + e.message };
|
|
3578
|
+
}
|
|
3579
|
+
})();
|
|
3580
|
+
`.trim();
|
|
3581
|
+
default:
|
|
3582
|
+
return `(function() { return { error: 'Unknown manage_scenes action: ${input.action}' }; })();`;
|
|
3583
|
+
}
|
|
3584
|
+
}
|
|
3585
|
+
generateScenePlayback(input) {
|
|
3586
|
+
const guard = `if (!app.sceneManager) return { error: 'SceneManager not available' };`;
|
|
3587
|
+
switch (input.action) {
|
|
3588
|
+
case 'create_chain': {
|
|
3589
|
+
const opts = [];
|
|
3590
|
+
if (input.loop !== undefined)
|
|
3591
|
+
opts.push(`loop: ${input.loop}`);
|
|
3592
|
+
if (input.autoPlay !== undefined)
|
|
3593
|
+
opts.push(`autoPlay: ${input.autoPlay}`);
|
|
3594
|
+
if (input.defaultDuration !== undefined)
|
|
3595
|
+
opts.push(`defaultDuration: ${input.defaultDuration * 1000}`);
|
|
3596
|
+
if (input.defaultTransition !== undefined)
|
|
3597
|
+
opts.push(`defaultTransition: ${JSON.stringify(input.defaultTransition)}`);
|
|
3598
|
+
if (input.transitionDuration !== undefined)
|
|
3599
|
+
opts.push(`transitionDuration: ${input.transitionDuration * 1000}`);
|
|
3600
|
+
const optsStr = opts.length > 0 ? `, { ${opts.join(', ')} }` : '';
|
|
3601
|
+
return `
|
|
3602
|
+
// Create scene chain for sequential playback
|
|
3603
|
+
(function() {
|
|
3604
|
+
${guard}
|
|
3605
|
+
app.sceneManager.createChain(${JSON.stringify(input.sceneIds)}${optsStr});
|
|
3606
|
+
return { success: true, action: 'create_chain', sceneIds: ${JSON.stringify(input.sceneIds)}${input.loop !== undefined ? `, loop: ${input.loop}` : ''}${input.defaultDuration !== undefined ? `, defaultDuration: ${input.defaultDuration}` : ''} };
|
|
3607
|
+
})();
|
|
3608
|
+
`.trim();
|
|
3609
|
+
}
|
|
3610
|
+
case 'play':
|
|
3611
|
+
return `
|
|
3612
|
+
// Play scene chain
|
|
3613
|
+
(async function() {
|
|
3614
|
+
${guard}
|
|
3615
|
+
try {
|
|
3616
|
+
await app.sceneManager.playChain();
|
|
3617
|
+
return { success: true, action: 'play' };
|
|
3618
|
+
} catch (e) {
|
|
3619
|
+
return { error: 'Failed to play chain: ' + e.message };
|
|
3620
|
+
}
|
|
3621
|
+
})();
|
|
3622
|
+
`.trim();
|
|
3623
|
+
case 'pause':
|
|
3624
|
+
return `
|
|
3625
|
+
// Pause scene chain
|
|
3626
|
+
(function() {
|
|
3627
|
+
${guard}
|
|
3628
|
+
app.sceneManager.pauseChain();
|
|
3629
|
+
return { success: true, action: 'pause' };
|
|
3630
|
+
})();
|
|
3631
|
+
`.trim();
|
|
3632
|
+
case 'resume':
|
|
3633
|
+
return `
|
|
3634
|
+
// Resume scene chain
|
|
3635
|
+
(function() {
|
|
3636
|
+
${guard}
|
|
3637
|
+
app.sceneManager.resumeChain();
|
|
3638
|
+
return { success: true, action: 'resume' };
|
|
3639
|
+
})();
|
|
3640
|
+
`.trim();
|
|
3641
|
+
case 'stop':
|
|
3642
|
+
return `
|
|
3643
|
+
// Stop scene chain
|
|
3644
|
+
(function() {
|
|
3645
|
+
${guard}
|
|
3646
|
+
app.sceneManager.stopChain();
|
|
3647
|
+
return { success: true, action: 'stop' };
|
|
3648
|
+
})();
|
|
3649
|
+
`.trim();
|
|
3650
|
+
case 'toggle_loop':
|
|
3651
|
+
return `
|
|
3652
|
+
// Toggle loop mode
|
|
3653
|
+
(function() {
|
|
3654
|
+
${guard}
|
|
3655
|
+
app.sceneManager.setLoop(${input.enabled ?? true});
|
|
3656
|
+
return { success: true, action: 'toggle_loop', enabled: ${input.enabled ?? true} };
|
|
3657
|
+
})();
|
|
3658
|
+
`.trim();
|
|
3659
|
+
case 'jump':
|
|
3660
|
+
return `
|
|
3661
|
+
// Jump to scene index
|
|
3662
|
+
(async function() {
|
|
3663
|
+
${guard}
|
|
3664
|
+
try {
|
|
3665
|
+
await app.sceneManager.jumpToChainIndex(${input.index ?? 0});
|
|
3666
|
+
return { success: true, action: 'jump', index: ${input.index ?? 0} };
|
|
3667
|
+
} catch (e) {
|
|
3668
|
+
return { error: 'Failed to jump to index: ' + e.message };
|
|
3669
|
+
}
|
|
3670
|
+
})();
|
|
3671
|
+
`.trim();
|
|
3672
|
+
default:
|
|
3673
|
+
return `(function() { return { error: 'Unknown scene_playback action: ${input.action}' }; })();`;
|
|
3674
|
+
}
|
|
3675
|
+
}
|
|
3676
|
+
// ===========================================================================
|
|
3677
|
+
// SELECTION, TRANSFORM & HISTORY
|
|
3678
|
+
// ===========================================================================
|
|
3679
|
+
generateSelection(input) {
|
|
3680
|
+
switch (input.action) {
|
|
3681
|
+
case 'select': {
|
|
3682
|
+
const ids = JSON.stringify(input.itemIds || []);
|
|
3683
|
+
const mode = input.mode || 'replace';
|
|
3684
|
+
return `
|
|
3685
|
+
// Select items
|
|
3686
|
+
(function() {
|
|
3687
|
+
const ids = ${ids};
|
|
3688
|
+
if (ids.length === 0) return { error: 'No itemIds provided' };
|
|
3689
|
+
${mode === 'replace' ? 'app.deselectAll();' : ''}
|
|
3690
|
+
const selected = [];
|
|
3691
|
+
for (const id of ids) {
|
|
3692
|
+
const entry = app.itemRegistry.get(id);
|
|
3693
|
+
if (entry && entry.item) {
|
|
3694
|
+
${mode === 'remove' ? 'entry.item.selected = false;' : 'app.select(entry.item);'}
|
|
3695
|
+
selected.push(id);
|
|
3696
|
+
}
|
|
3697
|
+
}
|
|
3698
|
+
return { success: true, action: 'select', mode: '${mode}', selected };
|
|
3699
|
+
})();`.trim();
|
|
3700
|
+
}
|
|
3701
|
+
case 'select_all':
|
|
3702
|
+
return `
|
|
3703
|
+
// Select all items
|
|
3704
|
+
(function() {
|
|
3705
|
+
app.selectAll();
|
|
3706
|
+
const items = app.getSelection().map(i => i.data?.itemId || i.name || i.id);
|
|
3707
|
+
return { success: true, action: 'select_all', count: items.length, items };
|
|
3708
|
+
})();`.trim();
|
|
3709
|
+
case 'deselect_all':
|
|
3710
|
+
return `
|
|
3711
|
+
// Deselect all items
|
|
3712
|
+
(function() {
|
|
3713
|
+
app.deselectAll();
|
|
3714
|
+
return { success: true, action: 'deselect_all' };
|
|
3715
|
+
})();`.trim();
|
|
3716
|
+
case 'get':
|
|
3717
|
+
return `
|
|
3718
|
+
// Get current selection
|
|
3719
|
+
(function() {
|
|
3720
|
+
const items = app.getSelection().map(i => ({
|
|
3721
|
+
itemId: i.data?.itemId || i.name || i.id,
|
|
3722
|
+
type: i.data?.itemType || i.className,
|
|
3723
|
+
bounds: i.bounds ? { x: i.bounds.x, y: i.bounds.y, width: i.bounds.width, height: i.bounds.height } : null
|
|
3724
|
+
}));
|
|
3725
|
+
return { success: true, action: 'get', count: items.length, items };
|
|
3726
|
+
})();`.trim();
|
|
3727
|
+
case 'delete_selected':
|
|
3728
|
+
return `
|
|
3729
|
+
// Delete selected items
|
|
3730
|
+
(function() {
|
|
3731
|
+
const selection = app.getSelection();
|
|
3732
|
+
const deleted = selection.map(i => i.data?.itemId || i.name || i.id);
|
|
3733
|
+
app.deleteSelected();
|
|
3734
|
+
return { success: true, action: 'delete_selected', deleted, count: deleted.length };
|
|
3735
|
+
})();`.trim();
|
|
3736
|
+
default:
|
|
3737
|
+
return `(function() { return { error: 'Unknown selection action: ${input.action}' }; })();`;
|
|
3738
|
+
}
|
|
3739
|
+
}
|
|
3740
|
+
generateTransform(input) {
|
|
3741
|
+
switch (input.action) {
|
|
3742
|
+
case 'nudge': {
|
|
3743
|
+
const dx = input.dx ?? 0;
|
|
3744
|
+
const dy = input.dy ?? 0;
|
|
3745
|
+
return `
|
|
3746
|
+
// Nudge item position
|
|
3747
|
+
(function() {
|
|
3748
|
+
const entry = app.itemRegistry.get(${JSON.stringify(input.itemId || '')});
|
|
3749
|
+
if (!entry || !entry.item) return { error: 'Item not found: ${input.itemId}' };
|
|
3750
|
+
entry.item.position.x += ${dx};
|
|
3751
|
+
entry.item.position.y += ${dy};
|
|
3752
|
+
return { success: true, action: 'nudge', itemId: '${input.itemId}', dx: ${dx}, dy: ${dy}, position: { x: entry.item.position.x, y: entry.item.position.y } };
|
|
3753
|
+
})();`.trim();
|
|
3754
|
+
}
|
|
3755
|
+
case 'flip': {
|
|
3756
|
+
const dir = input.direction || 'horizontal';
|
|
3757
|
+
return `
|
|
3758
|
+
// Flip item ${dir}ly
|
|
3759
|
+
(function() {
|
|
3760
|
+
const entry = app.itemRegistry.get(${JSON.stringify(input.itemId || '')});
|
|
3761
|
+
if (!entry || !entry.item) return { error: 'Item not found: ${input.itemId}' };
|
|
3762
|
+
${dir === 'horizontal' ? 'entry.item.scale(-1, 1);' : 'entry.item.scale(1, -1);'}
|
|
3763
|
+
return { success: true, action: 'flip', itemId: '${input.itemId}', direction: '${dir}' };
|
|
3764
|
+
})();`.trim();
|
|
3765
|
+
}
|
|
3766
|
+
case 'reorder': {
|
|
3767
|
+
const order = input.order || 'bringToFront';
|
|
3768
|
+
const methodMap = {
|
|
3769
|
+
bringToFront: 'bringToFront',
|
|
3770
|
+
sendToBack: 'sendToBack',
|
|
3771
|
+
moveUp: 'moveAbove',
|
|
3772
|
+
moveDown: 'moveBelow',
|
|
3773
|
+
};
|
|
3774
|
+
const method = methodMap[order] || 'bringToFront';
|
|
3775
|
+
const needsSibling = order === 'moveUp' || order === 'moveDown';
|
|
3776
|
+
if (needsSibling) {
|
|
3777
|
+
const siblingExpr = order === 'moveUp' ? 'entry.item.nextSibling' : 'entry.item.previousSibling';
|
|
3778
|
+
return `
|
|
3779
|
+
// Reorder item: ${order}
|
|
3780
|
+
(function() {
|
|
3781
|
+
const entry = app.itemRegistry.get(${JSON.stringify(input.itemId || '')});
|
|
3782
|
+
if (!entry || !entry.item) return { error: 'Item not found: ${input.itemId}' };
|
|
3783
|
+
const sibling = ${siblingExpr};
|
|
3784
|
+
if (sibling) entry.item.${method}(sibling);
|
|
3785
|
+
return { success: true, action: 'reorder', itemId: '${input.itemId}', order: '${order}' };
|
|
3786
|
+
})();`.trim();
|
|
3787
|
+
}
|
|
3788
|
+
return `
|
|
3789
|
+
// Reorder item: ${order}
|
|
3790
|
+
(function() {
|
|
3791
|
+
const entry = app.itemRegistry.get(${JSON.stringify(input.itemId || '')});
|
|
3792
|
+
if (!entry || !entry.item) return { error: 'Item not found: ${input.itemId}' };
|
|
3793
|
+
entry.item.${method}();
|
|
3794
|
+
return { success: true, action: 'reorder', itemId: '${input.itemId}', order: '${order}' };
|
|
3795
|
+
})();`.trim();
|
|
3796
|
+
}
|
|
3797
|
+
default:
|
|
3798
|
+
return `(function() { return { error: 'Unknown transform action: ${input.action}' }; })();`;
|
|
3799
|
+
}
|
|
3800
|
+
}
|
|
3801
|
+
generateHistory(input) {
|
|
3802
|
+
const guard = `if (!app.historyManager) return { error: 'HistoryManager not available' };`;
|
|
3803
|
+
switch (input.action) {
|
|
3804
|
+
case 'undo':
|
|
3805
|
+
return `
|
|
3806
|
+
// Undo last action
|
|
3807
|
+
(function() {
|
|
3808
|
+
${guard}
|
|
3809
|
+
app.historyManager.undo();
|
|
3810
|
+
return { success: true, action: 'undo' };
|
|
3811
|
+
})();`.trim();
|
|
3812
|
+
case 'redo':
|
|
3813
|
+
return `
|
|
3814
|
+
// Redo last undone action
|
|
3815
|
+
(function() {
|
|
3816
|
+
${guard}
|
|
3817
|
+
app.historyManager.redo();
|
|
3818
|
+
return { success: true, action: 'redo' };
|
|
3819
|
+
})();`.trim();
|
|
3820
|
+
case 'get_state':
|
|
3821
|
+
return `
|
|
3822
|
+
// Get history state
|
|
3823
|
+
(function() {
|
|
3824
|
+
${guard}
|
|
3825
|
+
const state = app.historyManager.getState();
|
|
3826
|
+
return { success: true, action: 'get_state', ...state };
|
|
3827
|
+
})();`.trim();
|
|
3828
|
+
default:
|
|
3829
|
+
return `(function() { return { error: 'Unknown history action: ${input.action}' }; })();`;
|
|
3830
|
+
}
|
|
3831
|
+
}
|
|
3832
|
+
// ===========================================================================
|
|
3833
|
+
// IMAGE PROCESSING
|
|
3834
|
+
// ===========================================================================
|
|
3835
|
+
generateImageFilter(input) {
|
|
3836
|
+
const guard = `if (!app.imageTools) return { error: 'ImageTools not available' };`;
|
|
3837
|
+
switch (input.action) {
|
|
3838
|
+
case 'apply':
|
|
3839
|
+
return `
|
|
3840
|
+
// Apply image filter
|
|
3841
|
+
(async function() {
|
|
3842
|
+
${guard}
|
|
3843
|
+
try {
|
|
3844
|
+
const result = await app.imageTools.applyFilter(${JSON.stringify(input.itemId)}, ${JSON.stringify(input.filterName || '')}, ${JSON.stringify(input.params || {})});
|
|
3845
|
+
return { success: true, action: 'apply', itemId: ${JSON.stringify(input.itemId)}, filter: ${JSON.stringify(input.filterName || '')} };
|
|
3846
|
+
} catch (e) {
|
|
3847
|
+
return { error: 'Failed to apply filter: ' + e.message };
|
|
3848
|
+
}
|
|
3849
|
+
})();`.trim();
|
|
3850
|
+
case 'chain':
|
|
3851
|
+
return `
|
|
3852
|
+
// Apply filter chain
|
|
3853
|
+
(async function() {
|
|
3854
|
+
${guard}
|
|
3855
|
+
try {
|
|
3856
|
+
const filters = ${JSON.stringify(input.filters || [])};
|
|
3857
|
+
const result = await app.imageTools.applyFilterChain(${JSON.stringify(input.itemId)}, filters);
|
|
3858
|
+
return { success: true, action: 'chain', itemId: ${JSON.stringify(input.itemId)}, filterCount: filters.length };
|
|
3859
|
+
} catch (e) {
|
|
3860
|
+
return { error: 'Failed to apply filter chain: ' + e.message };
|
|
3861
|
+
}
|
|
3862
|
+
})();`.trim();
|
|
3863
|
+
default:
|
|
3864
|
+
return `(function() { return { error: 'Unknown image_filter action: ${input.action}' }; })();`;
|
|
3865
|
+
}
|
|
3866
|
+
}
|
|
3867
|
+
generateLasso(input) {
|
|
3868
|
+
const guard = `if (!app.imageTools) return { error: 'ImageTools not available' };`;
|
|
3869
|
+
switch (input.action) {
|
|
3870
|
+
case 'activate':
|
|
3871
|
+
return `
|
|
3872
|
+
// Activate lasso selection
|
|
3873
|
+
(async function() {
|
|
3874
|
+
${guard}
|
|
3875
|
+
try {
|
|
3876
|
+
await app.imageTools.activateLasso(${JSON.stringify(input.itemId || '')});
|
|
3877
|
+
return { success: true, action: 'activate', itemId: ${JSON.stringify(input.itemId || '')} };
|
|
3878
|
+
} catch (e) {
|
|
3879
|
+
return { error: 'Failed to activate lasso: ' + e.message };
|
|
3880
|
+
}
|
|
3881
|
+
})();`.trim();
|
|
3882
|
+
case 'apply':
|
|
3883
|
+
return `
|
|
3884
|
+
// Apply lasso selection
|
|
3885
|
+
(async function() {
|
|
3886
|
+
${guard}
|
|
3887
|
+
try {
|
|
3888
|
+
const result = await app.imageTools.applyLasso();
|
|
3889
|
+
return { success: true, action: 'apply' };
|
|
3890
|
+
} catch (e) {
|
|
3891
|
+
return { error: 'Failed to apply lasso: ' + e.message };
|
|
3892
|
+
}
|
|
3893
|
+
})();`.trim();
|
|
3894
|
+
default:
|
|
3895
|
+
return `(function() { return { error: 'Unknown lasso action: ${input.action}' }; })();`;
|
|
3896
|
+
}
|
|
3897
|
+
}
|
|
3898
|
+
generateCutoutStyle(input) {
|
|
3899
|
+
const guard = `if (!app.imageTools) return { error: 'ImageTools not available' };`;
|
|
3900
|
+
switch (input.action) {
|
|
3901
|
+
case 'apply':
|
|
3902
|
+
return `
|
|
3903
|
+
// Apply cutout style
|
|
3904
|
+
(async function() {
|
|
3905
|
+
${guard}
|
|
3906
|
+
try {
|
|
3907
|
+
const result = await app.imageTools.applyCutoutStyle(${JSON.stringify(input.itemId || '')}, ${JSON.stringify(input.preset || '')}, ${JSON.stringify(input.options || {})});
|
|
3908
|
+
return { success: true, action: 'apply', itemId: ${JSON.stringify(input.itemId || '')}, preset: ${JSON.stringify(input.preset || '')} };
|
|
3909
|
+
} catch (e) {
|
|
3910
|
+
return { error: 'Failed to apply cutout style: ' + e.message };
|
|
3911
|
+
}
|
|
3912
|
+
})();`.trim();
|
|
3913
|
+
case 'list':
|
|
3914
|
+
return `
|
|
3915
|
+
// List available cutout styles
|
|
3916
|
+
(function() {
|
|
3917
|
+
${guard}
|
|
3918
|
+
const styles = app.imageTools.getCutoutStyles();
|
|
3919
|
+
return { success: true, action: 'list', styles };
|
|
3920
|
+
})();`.trim();
|
|
3921
|
+
default:
|
|
3922
|
+
return `(function() { return { error: 'Unknown cutout_style action: ${input.action}' }; })();`;
|
|
3923
|
+
}
|
|
3924
|
+
}
|
|
3925
|
+
// ===========================================================================
|
|
3926
|
+
// COMPOSITION & VIEW
|
|
3927
|
+
// ===========================================================================
|
|
3928
|
+
generatePrecomp(input) {
|
|
3929
|
+
switch (input.action) {
|
|
3930
|
+
case 'create': {
|
|
3931
|
+
const opts = {};
|
|
3932
|
+
if (input.name)
|
|
3933
|
+
opts.name = input.name;
|
|
3934
|
+
if (input.loop !== undefined)
|
|
3935
|
+
opts.loop = input.loop;
|
|
3936
|
+
if (input.duration !== undefined)
|
|
3937
|
+
opts.duration = input.duration;
|
|
3938
|
+
return `
|
|
3939
|
+
// Create precomp from items
|
|
3940
|
+
(function() {
|
|
3941
|
+
const itemIds = ${JSON.stringify(input.itemIds || [])};
|
|
3942
|
+
const opts = ${JSON.stringify(opts)};
|
|
3943
|
+
const precomp = app.createPrecomp(itemIds, opts);
|
|
3944
|
+
return { success: true, action: 'create', precompId: precomp?.id || precomp, name: ${JSON.stringify(input.name || '')} };
|
|
3945
|
+
})();`.trim();
|
|
3946
|
+
}
|
|
3947
|
+
case 'add':
|
|
3948
|
+
return `
|
|
3949
|
+
// Add item to precomp
|
|
3950
|
+
(function() {
|
|
3951
|
+
app.addToPrecomp(${JSON.stringify(input.precompId || '')}, ${JSON.stringify(input.itemId || '')});
|
|
3952
|
+
return { success: true, action: 'add', precompId: ${JSON.stringify(input.precompId || '')}, itemId: ${JSON.stringify(input.itemId || '')} };
|
|
3953
|
+
})();`.trim();
|
|
3954
|
+
case 'remove':
|
|
3955
|
+
return `
|
|
3956
|
+
// Remove item from precomp
|
|
3957
|
+
(function() {
|
|
3958
|
+
app.removeFromPrecomp(${JSON.stringify(input.precompId || '')}, ${JSON.stringify(input.itemId || '')});
|
|
3959
|
+
return { success: true, action: 'remove', precompId: ${JSON.stringify(input.precompId || '')}, itemId: ${JSON.stringify(input.itemId || '')} };
|
|
3960
|
+
})();`.trim();
|
|
3961
|
+
default:
|
|
3962
|
+
return `(function() { return { error: 'Unknown precomp action: ${input.action}' }; })();`;
|
|
3963
|
+
}
|
|
3964
|
+
}
|
|
3965
|
+
generateView(input) {
|
|
3966
|
+
switch (input.action) {
|
|
3967
|
+
case 'fit': {
|
|
3968
|
+
const mode = input.mode || 'content';
|
|
3969
|
+
const padding = input.padding ?? 20;
|
|
3970
|
+
return `
|
|
3971
|
+
// Fit view to ${mode}
|
|
3972
|
+
(function() {
|
|
3973
|
+
app.fitView('${mode}', ${padding});
|
|
3974
|
+
return { success: true, action: 'fit', mode: '${mode}', padding: ${padding} };
|
|
3975
|
+
})();`.trim();
|
|
3976
|
+
}
|
|
3977
|
+
case 'get_state':
|
|
3978
|
+
return `
|
|
3979
|
+
// Get current view state
|
|
3980
|
+
(function() {
|
|
3981
|
+
const state = app.getViewState();
|
|
3982
|
+
return { success: true, action: 'get_state', ...state };
|
|
3983
|
+
})();`.trim();
|
|
3984
|
+
default:
|
|
3985
|
+
return `(function() { return { error: 'Unknown view action: ${input.action}' }; })();`;
|
|
3986
|
+
}
|
|
3987
|
+
}
|
|
3988
|
+
generateBackground(input) {
|
|
3989
|
+
switch (input.action) {
|
|
3990
|
+
case 'set': {
|
|
3991
|
+
const mode = input.mode || 'color';
|
|
3992
|
+
if (mode === 'generator') {
|
|
3993
|
+
return `
|
|
3994
|
+
// Set background via generator
|
|
3995
|
+
(async function() {
|
|
3996
|
+
try {
|
|
3997
|
+
await app.executeGenerator(${JSON.stringify(input.generator || '')}, ${JSON.stringify(input.generatorParams || {})});
|
|
3998
|
+
return { success: true, action: 'set', mode: 'generator', generator: ${JSON.stringify(input.generator || '')} };
|
|
3999
|
+
} catch (e) {
|
|
4000
|
+
return { error: 'Failed to set generator background: ' + e.message };
|
|
4001
|
+
}
|
|
4002
|
+
})();`.trim();
|
|
4003
|
+
}
|
|
4004
|
+
if (mode === 'pattern') {
|
|
4005
|
+
return `
|
|
4006
|
+
// Set background pattern
|
|
4007
|
+
(function() {
|
|
4008
|
+
app.setBackgroundPattern(${JSON.stringify(input.pattern || '')});
|
|
4009
|
+
return { success: true, action: 'set', mode: 'pattern', pattern: ${JSON.stringify(input.pattern || '')} };
|
|
4010
|
+
})();`.trim();
|
|
4011
|
+
}
|
|
4012
|
+
// default: color
|
|
4013
|
+
return `
|
|
4014
|
+
// Set background color
|
|
4015
|
+
(function() {
|
|
4016
|
+
app.setBackgroundColor(${JSON.stringify(input.color || '#ffffff')});
|
|
4017
|
+
return { success: true, action: 'set', mode: 'color', color: ${JSON.stringify(input.color || '#ffffff')} };
|
|
4018
|
+
})();`.trim();
|
|
4019
|
+
}
|
|
4020
|
+
case 'clear':
|
|
4021
|
+
return `
|
|
4022
|
+
// Clear background
|
|
4023
|
+
(function() {
|
|
4024
|
+
app.clearBackground();
|
|
4025
|
+
return { success: true, action: 'clear' };
|
|
4026
|
+
})();`.trim();
|
|
4027
|
+
case 'get':
|
|
4028
|
+
return `
|
|
4029
|
+
// Get background info
|
|
4030
|
+
(function() {
|
|
4031
|
+
const bg = app.getBackground();
|
|
4032
|
+
return { success: true, action: 'get', ...bg };
|
|
4033
|
+
})();`.trim();
|
|
4034
|
+
default:
|
|
4035
|
+
return `(function() { return { error: 'Unknown background action: ${input.action}' }; })();`;
|
|
4036
|
+
}
|
|
4037
|
+
}
|
|
4038
|
+
// ===========================================================================
|
|
4039
|
+
// CANVAS QUERIES
|
|
4040
|
+
// ===========================================================================
|
|
4041
|
+
generateQuery(input) {
|
|
4042
|
+
switch (input.action) {
|
|
4043
|
+
case 'get_by_id':
|
|
4044
|
+
return `
|
|
4045
|
+
// Get item details by ID
|
|
4046
|
+
(function() {
|
|
4047
|
+
const entry = app.itemRegistry.get(${JSON.stringify(input.itemId || '')});
|
|
4048
|
+
if (!entry || !entry.item) return { error: 'Item not found: ${input.itemId}' };
|
|
4049
|
+
const item = entry.item;
|
|
4050
|
+
return {
|
|
4051
|
+
success: true, action: 'get_by_id',
|
|
4052
|
+
itemId: ${JSON.stringify(input.itemId || '')},
|
|
4053
|
+
type: item.data?.itemType || item.className,
|
|
4054
|
+
position: { x: item.position.x, y: item.position.y },
|
|
4055
|
+
bounds: item.bounds ? { x: item.bounds.x, y: item.bounds.y, width: item.bounds.width, height: item.bounds.height } : null,
|
|
4056
|
+
visible: item.visible,
|
|
4057
|
+
opacity: item.opacity,
|
|
4058
|
+
rotation: item.rotation,
|
|
4059
|
+
selected: item.selected,
|
|
4060
|
+
};
|
|
4061
|
+
})();`.trim();
|
|
4062
|
+
case 'hit_test': {
|
|
4063
|
+
const tolerance = input.tolerance ?? 5;
|
|
4064
|
+
const all = input.all ?? false;
|
|
4065
|
+
return `
|
|
4066
|
+
// Hit test at point
|
|
4067
|
+
(function() {
|
|
4068
|
+
const point = new paper.Point(${input.x ?? 0}, ${input.y ?? 0});
|
|
4069
|
+
${all
|
|
4070
|
+
? `const results = app.hitTestAll(point, { tolerance: ${tolerance} });
|
|
4071
|
+
const hits = results.map(r => ({
|
|
4072
|
+
itemId: r.item?.data?.itemId || r.item?.name || r.item?.id,
|
|
4073
|
+
type: r.item?.data?.itemType || r.item?.className,
|
|
4074
|
+
point: { x: r.point?.x, y: r.point?.y }
|
|
4075
|
+
}));
|
|
4076
|
+
return { success: true, action: 'hit_test', x: ${input.x ?? 0}, y: ${input.y ?? 0}, hits, count: hits.length };`
|
|
4077
|
+
: `const result = app.hitTest(point, { tolerance: ${tolerance} });
|
|
4078
|
+
if (!result) return { success: true, action: 'hit_test', x: ${input.x ?? 0}, y: ${input.y ?? 0}, hit: null };
|
|
4079
|
+
return {
|
|
4080
|
+
success: true, action: 'hit_test',
|
|
4081
|
+
x: ${input.x ?? 0}, y: ${input.y ?? 0},
|
|
4082
|
+
hit: { itemId: result.item?.data?.itemId || result.item?.name || result.item?.id, type: result.item?.data?.itemType || result.item?.className }
|
|
4083
|
+
};`}
|
|
4084
|
+
})();`.trim();
|
|
4085
|
+
}
|
|
4086
|
+
case 'is_empty':
|
|
4087
|
+
return `
|
|
4088
|
+
// Check if canvas is empty
|
|
4089
|
+
(function() {
|
|
4090
|
+
const items = app.itemRegistry.getAll();
|
|
4091
|
+
return { success: true, action: 'is_empty', empty: items.length === 0, count: items.length };
|
|
4092
|
+
})();`.trim();
|
|
4093
|
+
default:
|
|
4094
|
+
return `(function() { return { error: 'Unknown query action: ${input.action}' }; })();`;
|
|
4095
|
+
}
|
|
4096
|
+
}
|
|
3639
4097
|
}
|
|
3640
4098
|
// Export singleton instance
|
|
3641
4099
|
export const codeGenerator = new PinePaperCodeGenerator();
|