@efectoapp/mcp-server 0.1.0
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 +244 -0
- package/dist/index.d.ts +23 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +93 -0
- package/dist/index.js.map +1 -0
- package/dist/tools/discovery.d.ts +21 -0
- package/dist/tools/discovery.d.ts.map +1 -0
- package/dist/tools/discovery.js +141 -0
- package/dist/tools/discovery.js.map +1 -0
- package/dist/tools/images.d.ts +20 -0
- package/dist/tools/images.d.ts.map +1 -0
- package/dist/tools/images.js +143 -0
- package/dist/tools/images.js.map +1 -0
- package/dist/tools/output.d.ts +21 -0
- package/dist/tools/output.d.ts.map +1 -0
- package/dist/tools/output.js +287 -0
- package/dist/tools/output.js.map +1 -0
- package/dist/tools/state.d.ts +122 -0
- package/dist/tools/state.d.ts.map +1 -0
- package/dist/tools/state.js +943 -0
- package/dist/tools/state.js.map +1 -0
- package/package.json +58 -0
|
@@ -0,0 +1,943 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* State Building Tools
|
|
4
|
+
*
|
|
5
|
+
* Tools for creating and modifying poster state:
|
|
6
|
+
* - create_poster: Initialize a new poster
|
|
7
|
+
* - set_background: Configure background layer
|
|
8
|
+
* - add_layer: Add a layer to the poster
|
|
9
|
+
* - modify_layer: Modify an existing layer
|
|
10
|
+
* - apply_effect: Apply main effect (ASCII, dither, etc.)
|
|
11
|
+
* - add_postprocess: Add post-processing effect
|
|
12
|
+
*
|
|
13
|
+
* All state follows the LayerShareState contract for API compatibility.
|
|
14
|
+
*/
|
|
15
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
16
|
+
exports.stateTools = void 0;
|
|
17
|
+
exports.resetState = resetState;
|
|
18
|
+
exports.getCurrentState = getCurrentState;
|
|
19
|
+
exports.handleStateTool = handleStateTool;
|
|
20
|
+
// Current poster state (single poster for now)
|
|
21
|
+
let currentPoster = null;
|
|
22
|
+
// Reset state (useful for testing)
|
|
23
|
+
function resetState() {
|
|
24
|
+
currentPoster = null;
|
|
25
|
+
}
|
|
26
|
+
// Get current state
|
|
27
|
+
function getCurrentState() {
|
|
28
|
+
return currentPoster;
|
|
29
|
+
}
|
|
30
|
+
// Generate unique ID
|
|
31
|
+
function generateId() {
|
|
32
|
+
return `layer_${Date.now()}_${Math.random().toString(36).substring(2, 11)}`;
|
|
33
|
+
}
|
|
34
|
+
// Create default background layer
|
|
35
|
+
function createDefaultBackgroundLayer(backgroundColor) {
|
|
36
|
+
return {
|
|
37
|
+
id: 'bg',
|
|
38
|
+
name: 'Background',
|
|
39
|
+
type: 'background',
|
|
40
|
+
visible: true,
|
|
41
|
+
locked: false,
|
|
42
|
+
transform: {
|
|
43
|
+
x: 0,
|
|
44
|
+
y: 0,
|
|
45
|
+
width: 1,
|
|
46
|
+
height: 1,
|
|
47
|
+
rotation: 0,
|
|
48
|
+
opacity: 1,
|
|
49
|
+
},
|
|
50
|
+
contentType: 'solid',
|
|
51
|
+
solidColor: backgroundColor,
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
// Tool definitions
|
|
55
|
+
exports.stateTools = [
|
|
56
|
+
{
|
|
57
|
+
name: 'create_poster',
|
|
58
|
+
description: 'Create a new poster with specified aspect ratio. Always starts with a background layer at index 0.',
|
|
59
|
+
inputSchema: {
|
|
60
|
+
type: 'object',
|
|
61
|
+
properties: {
|
|
62
|
+
aspectRatio: {
|
|
63
|
+
type: 'string',
|
|
64
|
+
enum: ['16:9', '9:16', '1:1', '4:3', 'full'],
|
|
65
|
+
description: 'Canvas aspect ratio (default: 9:16 for portrait poster)',
|
|
66
|
+
default: '9:16',
|
|
67
|
+
},
|
|
68
|
+
backgroundColor: {
|
|
69
|
+
type: 'string',
|
|
70
|
+
description: 'Background color in hex format (e.g., "#1a1a1a")',
|
|
71
|
+
default: '#1a1a1a',
|
|
72
|
+
},
|
|
73
|
+
},
|
|
74
|
+
required: [],
|
|
75
|
+
},
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
name: 'set_background',
|
|
79
|
+
description: 'Configure the background layer (always at index 0). Can be solid color, image, or video.',
|
|
80
|
+
inputSchema: {
|
|
81
|
+
type: 'object',
|
|
82
|
+
properties: {
|
|
83
|
+
type: {
|
|
84
|
+
type: 'string',
|
|
85
|
+
enum: ['solid', 'image', 'video'],
|
|
86
|
+
description: 'Background content type',
|
|
87
|
+
default: 'solid',
|
|
88
|
+
},
|
|
89
|
+
color: {
|
|
90
|
+
type: 'string',
|
|
91
|
+
description: 'Solid background color in hex (for type: solid)',
|
|
92
|
+
},
|
|
93
|
+
imageUrl: {
|
|
94
|
+
type: 'string',
|
|
95
|
+
description: 'Image URL (for type: image)',
|
|
96
|
+
},
|
|
97
|
+
videoUrl: {
|
|
98
|
+
type: 'string',
|
|
99
|
+
description: 'Video URL (for type: video)',
|
|
100
|
+
},
|
|
101
|
+
objectFit: {
|
|
102
|
+
type: 'string',
|
|
103
|
+
enum: ['cover', 'contain'],
|
|
104
|
+
description: 'How media fills the canvas',
|
|
105
|
+
default: 'cover',
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
required: [],
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
name: 'add_layer',
|
|
113
|
+
description: 'Add a new layer to the poster. Layers are added above existing layers.',
|
|
114
|
+
inputSchema: {
|
|
115
|
+
type: 'object',
|
|
116
|
+
properties: {
|
|
117
|
+
type: {
|
|
118
|
+
type: 'string',
|
|
119
|
+
enum: ['text', 'image', 'video'],
|
|
120
|
+
description: 'Type of layer to add',
|
|
121
|
+
},
|
|
122
|
+
name: { type: 'string', description: 'Layer name' },
|
|
123
|
+
// Transform properties (normalized 0-1 coordinates relative to canvas)
|
|
124
|
+
x: { type: 'number', description: 'X position (-1 to 1, 0 is center)', default: 0 },
|
|
125
|
+
y: { type: 'number', description: 'Y position (-1 to 1, 0 is center)', default: 0 },
|
|
126
|
+
width: { type: 'number', description: 'Width (0-1 relative to canvas)', default: 1 },
|
|
127
|
+
height: { type: 'number', description: 'Height (0-1 relative to canvas)', default: 1 },
|
|
128
|
+
rotation: { type: 'number', description: 'Rotation in degrees', default: 0 },
|
|
129
|
+
opacity: { type: 'number', description: 'Opacity 0-1', default: 1 },
|
|
130
|
+
// Text layer properties
|
|
131
|
+
content: { type: 'string', description: 'Text content (required for text layers)' },
|
|
132
|
+
fontFamily: { type: 'string', description: 'Font family name', default: 'DM Sans' },
|
|
133
|
+
fontSize: { type: 'number', description: 'Font size in pixels', default: 48 },
|
|
134
|
+
fontWeight: { type: 'string', enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], description: 'Font weight', default: 'bold' },
|
|
135
|
+
color: { type: 'string', description: 'Text color in hex', default: '#ffffff' },
|
|
136
|
+
textAlign: { type: 'string', enum: ['left', 'center', 'right'], description: 'Text alignment', default: 'center' },
|
|
137
|
+
letterSpacing: { type: 'number', description: 'Letter spacing in pixels', default: 0 },
|
|
138
|
+
lineHeight: { type: 'number', description: 'Line height multiplier', default: 1.2 },
|
|
139
|
+
// Image/Video properties
|
|
140
|
+
mediaUrl: { type: 'string', description: 'Media URL (required for image/video layers)' },
|
|
141
|
+
objectFit: { type: 'string', enum: ['cover', 'contain'], description: 'Object fit mode', default: 'cover' },
|
|
142
|
+
},
|
|
143
|
+
required: ['type'],
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: 'modify_layer',
|
|
148
|
+
description: 'Modify an existing layer by ID',
|
|
149
|
+
inputSchema: {
|
|
150
|
+
type: 'object',
|
|
151
|
+
properties: {
|
|
152
|
+
layerId: { type: 'string', description: 'ID of the layer to modify' },
|
|
153
|
+
// Transform properties
|
|
154
|
+
x: { type: 'number', description: 'X position' },
|
|
155
|
+
y: { type: 'number', description: 'Y position' },
|
|
156
|
+
width: { type: 'number', description: 'Width' },
|
|
157
|
+
height: { type: 'number', description: 'Height' },
|
|
158
|
+
rotation: { type: 'number', description: 'Rotation in degrees' },
|
|
159
|
+
opacity: { type: 'number', description: 'Opacity 0-1' },
|
|
160
|
+
visible: { type: 'boolean', description: 'Layer visibility' },
|
|
161
|
+
locked: { type: 'boolean', description: 'Layer lock state' },
|
|
162
|
+
name: { type: 'string', description: 'Layer name' },
|
|
163
|
+
// Text layer properties
|
|
164
|
+
content: { type: 'string' },
|
|
165
|
+
fontFamily: { type: 'string' },
|
|
166
|
+
fontSize: { type: 'number' },
|
|
167
|
+
fontWeight: { type: 'string' },
|
|
168
|
+
color: { type: 'string' },
|
|
169
|
+
textAlign: { type: 'string' },
|
|
170
|
+
letterSpacing: { type: 'number' },
|
|
171
|
+
lineHeight: { type: 'number' },
|
|
172
|
+
// Media properties
|
|
173
|
+
mediaUrl: { type: 'string' },
|
|
174
|
+
objectFit: { type: 'string' },
|
|
175
|
+
},
|
|
176
|
+
required: ['layerId'],
|
|
177
|
+
},
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
name: 'apply_effect',
|
|
181
|
+
description: 'Apply or update the main effect (ASCII, dither, halftone, glitch, or art effect). Only one main effect can be active at a time.',
|
|
182
|
+
inputSchema: {
|
|
183
|
+
type: 'object',
|
|
184
|
+
properties: {
|
|
185
|
+
effectId: {
|
|
186
|
+
type: 'string',
|
|
187
|
+
enum: [
|
|
188
|
+
'none',
|
|
189
|
+
// ASCII
|
|
190
|
+
'ascii-standard', 'ascii-blocks', 'ascii-braille', 'ascii-hatching',
|
|
191
|
+
'ascii-matrix', 'ascii-technical', 'ascii-dense', 'ascii-minimal',
|
|
192
|
+
// Dither
|
|
193
|
+
'dither-floyd-steinberg', 'dither-atkinson', 'dither-jarvis-judice-ninke',
|
|
194
|
+
'dither-stucki', 'dither-burkes', 'dither-sierra', 'dither-two-row-sierra',
|
|
195
|
+
'dither-sierra-lite', 'color-separation',
|
|
196
|
+
// Halftone
|
|
197
|
+
'halftone-mono', 'halftone-cmyk',
|
|
198
|
+
// Glitch
|
|
199
|
+
'glitch-chromatic', 'glitch-digital', 'glitch-vhs', 'glitch-weird',
|
|
200
|
+
// Art
|
|
201
|
+
'art-kuwahara', 'art-crosshatch', 'art-lineart', 'art-engraving', 'art-stipple',
|
|
202
|
+
// Special
|
|
203
|
+
'special-warp',
|
|
204
|
+
],
|
|
205
|
+
description: 'Effect ID to apply',
|
|
206
|
+
},
|
|
207
|
+
enabled: { type: 'boolean', description: 'Whether effect is enabled', default: true },
|
|
208
|
+
// ASCII effect settings
|
|
209
|
+
cellSize: { type: 'number', description: 'Cell size for ASCII effects (4-32)', default: 8 },
|
|
210
|
+
color: { type: 'boolean', description: 'Enable color mode for ASCII', default: true },
|
|
211
|
+
invert: { type: 'boolean', description: 'Invert ASCII effect', default: false },
|
|
212
|
+
// Dither effect settings
|
|
213
|
+
pixelation: { type: 'number', description: 'Pixelation level for dither (1-10)', default: 3 },
|
|
214
|
+
colors: { type: 'array', items: { type: 'string' }, description: 'Color palette for dither' },
|
|
215
|
+
// Halftone effect settings
|
|
216
|
+
dotSize: { type: 'number', description: 'Dot size for halftone effects' },
|
|
217
|
+
// Glitch effect settings
|
|
218
|
+
intensity: { type: 'number', description: 'Glitch intensity (0-1)' },
|
|
219
|
+
speed: { type: 'number', description: 'Glitch animation speed' },
|
|
220
|
+
},
|
|
221
|
+
required: ['effectId'],
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
name: 'add_postprocess',
|
|
226
|
+
description: 'Add a post-processing effect that stacks on top of the main effect',
|
|
227
|
+
inputSchema: {
|
|
228
|
+
type: 'object',
|
|
229
|
+
properties: {
|
|
230
|
+
type: {
|
|
231
|
+
type: 'string',
|
|
232
|
+
enum: [
|
|
233
|
+
'scanlines', 'vignette', 'chromatic-aberration', 'curvature',
|
|
234
|
+
'grain', 'noise', 'pixelate', 'wave', 'rgb-glitch', 'brightness-contrast',
|
|
235
|
+
'color-tint', 'palette', 'jitter', 'bloom', 'dot-screen', 'sepia',
|
|
236
|
+
'grid', 'light-beams', 'warp', 'motion-blur',
|
|
237
|
+
],
|
|
238
|
+
description: 'Post-process type',
|
|
239
|
+
},
|
|
240
|
+
enabled: { type: 'boolean', description: 'Whether effect is enabled', default: true },
|
|
241
|
+
// Common settings (type-specific settings vary)
|
|
242
|
+
intensity: { type: 'number', description: 'Effect intensity' },
|
|
243
|
+
// Scanlines
|
|
244
|
+
count: { type: 'number', description: 'Number of scanlines' },
|
|
245
|
+
// Vignette
|
|
246
|
+
radius: { type: 'number', description: 'Vignette radius' },
|
|
247
|
+
// Chromatic aberration
|
|
248
|
+
strength: { type: 'number', description: 'Aberration strength' },
|
|
249
|
+
angle: { type: 'number', description: 'Aberration angle' },
|
|
250
|
+
// Grain
|
|
251
|
+
size: { type: 'number', description: 'Grain size' },
|
|
252
|
+
speed: { type: 'number', description: 'Animation speed' },
|
|
253
|
+
// Brightness/Contrast
|
|
254
|
+
brightness: { type: 'number', description: 'Brightness adjustment' },
|
|
255
|
+
contrast: { type: 'number', description: 'Contrast adjustment' },
|
|
256
|
+
saturation: { type: 'number', description: 'Saturation adjustment' },
|
|
257
|
+
hue: { type: 'number', description: 'Hue rotation' },
|
|
258
|
+
},
|
|
259
|
+
required: ['type'],
|
|
260
|
+
},
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
name: 'remove_layer',
|
|
264
|
+
description: 'Remove a layer by ID. Cannot remove the background layer.',
|
|
265
|
+
inputSchema: {
|
|
266
|
+
type: 'object',
|
|
267
|
+
properties: {
|
|
268
|
+
layerId: { type: 'string', description: 'ID of the layer to remove' },
|
|
269
|
+
},
|
|
270
|
+
required: ['layerId'],
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
{
|
|
274
|
+
name: 'get_state',
|
|
275
|
+
description: 'Get the current poster state as LayerShareState JSON (for debugging or verification)',
|
|
276
|
+
inputSchema: {
|
|
277
|
+
type: 'object',
|
|
278
|
+
properties: {},
|
|
279
|
+
required: [],
|
|
280
|
+
},
|
|
281
|
+
},
|
|
282
|
+
];
|
|
283
|
+
/**
|
|
284
|
+
* Get effect settings key from effectId
|
|
285
|
+
*/
|
|
286
|
+
function getEffectSettingsKey(effectId) {
|
|
287
|
+
if (effectId.startsWith('ascii-'))
|
|
288
|
+
return 'ascii';
|
|
289
|
+
if (effectId.startsWith('dither-') || effectId === 'color-separation')
|
|
290
|
+
return 'dither';
|
|
291
|
+
if (effectId === 'halftone-mono')
|
|
292
|
+
return 'monoHalftone';
|
|
293
|
+
if (effectId === 'halftone-cmyk')
|
|
294
|
+
return 'cmykHalftone';
|
|
295
|
+
if (effectId === 'glitch-chromatic')
|
|
296
|
+
return 'chromatic';
|
|
297
|
+
if (effectId.startsWith('glitch-'))
|
|
298
|
+
return 'glitch';
|
|
299
|
+
if (effectId === 'art-kuwahara')
|
|
300
|
+
return 'kuwahara';
|
|
301
|
+
if (effectId === 'art-crosshatch')
|
|
302
|
+
return 'crosshatch';
|
|
303
|
+
if (effectId === 'art-lineart')
|
|
304
|
+
return 'lineart';
|
|
305
|
+
if (effectId === 'art-engraving')
|
|
306
|
+
return 'engraving';
|
|
307
|
+
if (effectId === 'art-stipple')
|
|
308
|
+
return 'stipple';
|
|
309
|
+
if (effectId === 'special-warp')
|
|
310
|
+
return 'sinewarp';
|
|
311
|
+
if (effectId === 'none')
|
|
312
|
+
return null;
|
|
313
|
+
return null;
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Handle state tool calls
|
|
317
|
+
*/
|
|
318
|
+
async function handleStateTool(name, args) {
|
|
319
|
+
const params = args || {};
|
|
320
|
+
switch (name) {
|
|
321
|
+
case 'create_poster': {
|
|
322
|
+
const aspectRatio = params.aspectRatio || '9:16';
|
|
323
|
+
const backgroundColor = params.backgroundColor || '#1a1a1a';
|
|
324
|
+
currentPoster = {
|
|
325
|
+
canvas: { aspectRatio, backgroundColor },
|
|
326
|
+
layers: [createDefaultBackgroundLayer(backgroundColor)],
|
|
327
|
+
postProcesses: [],
|
|
328
|
+
};
|
|
329
|
+
return {
|
|
330
|
+
content: [
|
|
331
|
+
{
|
|
332
|
+
type: 'text',
|
|
333
|
+
text: JSON.stringify({
|
|
334
|
+
success: true,
|
|
335
|
+
message: 'Poster created with background layer',
|
|
336
|
+
canvas: currentPoster.canvas,
|
|
337
|
+
layerCount: currentPoster.layers.length,
|
|
338
|
+
}, null, 2),
|
|
339
|
+
},
|
|
340
|
+
],
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
case 'set_background': {
|
|
344
|
+
if (!currentPoster) {
|
|
345
|
+
return {
|
|
346
|
+
content: [{ type: 'text', text: 'Error: No poster created. Use create_poster first.' }],
|
|
347
|
+
};
|
|
348
|
+
}
|
|
349
|
+
// Background is always at index 0
|
|
350
|
+
const bgLayer = currentPoster.layers[0];
|
|
351
|
+
if (bgLayer.type !== 'background') {
|
|
352
|
+
return {
|
|
353
|
+
content: [{ type: 'text', text: 'Error: Background layer not found at index 0' }],
|
|
354
|
+
};
|
|
355
|
+
}
|
|
356
|
+
const contentType = params.type || 'solid';
|
|
357
|
+
bgLayer.contentType = contentType;
|
|
358
|
+
if (contentType === 'solid') {
|
|
359
|
+
if (params.color) {
|
|
360
|
+
bgLayer.solidColor = params.color;
|
|
361
|
+
currentPoster.canvas.backgroundColor = params.color;
|
|
362
|
+
}
|
|
363
|
+
delete bgLayer.inputMedia;
|
|
364
|
+
}
|
|
365
|
+
else if (contentType === 'image' && params.imageUrl) {
|
|
366
|
+
bgLayer.inputMedia = {
|
|
367
|
+
mediaUrl: params.imageUrl,
|
|
368
|
+
mediaType: 'image',
|
|
369
|
+
brightness: 1,
|
|
370
|
+
contrast: 1,
|
|
371
|
+
saturation: 1,
|
|
372
|
+
objectFit: params.objectFit || 'cover',
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
else if (contentType === 'video' && params.videoUrl) {
|
|
376
|
+
bgLayer.inputMedia = {
|
|
377
|
+
mediaUrl: params.videoUrl,
|
|
378
|
+
mediaType: 'video',
|
|
379
|
+
brightness: 1,
|
|
380
|
+
contrast: 1,
|
|
381
|
+
saturation: 1,
|
|
382
|
+
objectFit: params.objectFit || 'cover',
|
|
383
|
+
};
|
|
384
|
+
}
|
|
385
|
+
return {
|
|
386
|
+
content: [
|
|
387
|
+
{
|
|
388
|
+
type: 'text',
|
|
389
|
+
text: JSON.stringify({
|
|
390
|
+
success: true,
|
|
391
|
+
message: 'Background updated',
|
|
392
|
+
background: bgLayer,
|
|
393
|
+
}, null, 2),
|
|
394
|
+
},
|
|
395
|
+
],
|
|
396
|
+
};
|
|
397
|
+
}
|
|
398
|
+
case 'add_layer': {
|
|
399
|
+
if (!currentPoster) {
|
|
400
|
+
return {
|
|
401
|
+
content: [{ type: 'text', text: 'Error: No poster created. Use create_poster first.' }],
|
|
402
|
+
};
|
|
403
|
+
}
|
|
404
|
+
const layerType = params.type;
|
|
405
|
+
if (!layerType) {
|
|
406
|
+
return {
|
|
407
|
+
content: [{ type: 'text', text: 'Error: Layer type is required' }],
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
if (layerType === 'background') {
|
|
411
|
+
return {
|
|
412
|
+
content: [{ type: 'text', text: 'Error: Use set_background to modify the background layer' }],
|
|
413
|
+
};
|
|
414
|
+
}
|
|
415
|
+
const layerId = generateId();
|
|
416
|
+
const baseLayer = {
|
|
417
|
+
id: layerId,
|
|
418
|
+
type: layerType,
|
|
419
|
+
name: params.name || `${layerType.charAt(0).toUpperCase() + layerType.slice(1)} Layer`,
|
|
420
|
+
visible: true,
|
|
421
|
+
locked: false,
|
|
422
|
+
transform: {
|
|
423
|
+
x: params.x ?? 0,
|
|
424
|
+
y: params.y ?? 0,
|
|
425
|
+
width: params.width ?? 1,
|
|
426
|
+
height: params.height ?? 1,
|
|
427
|
+
rotation: params.rotation ?? 0,
|
|
428
|
+
opacity: params.opacity ?? 1,
|
|
429
|
+
},
|
|
430
|
+
};
|
|
431
|
+
let layer;
|
|
432
|
+
if (layerType === 'text') {
|
|
433
|
+
layer = {
|
|
434
|
+
...baseLayer,
|
|
435
|
+
type: 'text',
|
|
436
|
+
content: params.content || 'Text',
|
|
437
|
+
fontFamily: params.fontFamily || 'DM Sans',
|
|
438
|
+
fontSize: params.fontSize || 48,
|
|
439
|
+
fontWeight: params.fontWeight || 'bold',
|
|
440
|
+
color: params.color || '#ffffff',
|
|
441
|
+
textAlign: params.textAlign || 'center',
|
|
442
|
+
letterSpacing: params.letterSpacing ?? 0,
|
|
443
|
+
lineHeight: params.lineHeight ?? 1.2,
|
|
444
|
+
};
|
|
445
|
+
}
|
|
446
|
+
else if (layerType === 'image') {
|
|
447
|
+
if (!params.mediaUrl) {
|
|
448
|
+
return {
|
|
449
|
+
content: [{ type: 'text', text: 'Error: mediaUrl is required for image layers' }],
|
|
450
|
+
};
|
|
451
|
+
}
|
|
452
|
+
layer = {
|
|
453
|
+
...baseLayer,
|
|
454
|
+
type: 'image',
|
|
455
|
+
mediaUrl: params.mediaUrl,
|
|
456
|
+
objectFit: params.objectFit || 'cover',
|
|
457
|
+
brightness: 1,
|
|
458
|
+
contrast: 1,
|
|
459
|
+
saturation: 1,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
else if (layerType === 'video') {
|
|
463
|
+
if (!params.mediaUrl) {
|
|
464
|
+
return {
|
|
465
|
+
content: [{ type: 'text', text: 'Error: mediaUrl is required for video layers' }],
|
|
466
|
+
};
|
|
467
|
+
}
|
|
468
|
+
layer = {
|
|
469
|
+
...baseLayer,
|
|
470
|
+
type: 'video',
|
|
471
|
+
mediaUrl: params.mediaUrl,
|
|
472
|
+
objectFit: params.objectFit || 'cover',
|
|
473
|
+
brightness: 1,
|
|
474
|
+
contrast: 1,
|
|
475
|
+
saturation: 1,
|
|
476
|
+
loop: true,
|
|
477
|
+
playbackSpeed: 1,
|
|
478
|
+
};
|
|
479
|
+
}
|
|
480
|
+
else {
|
|
481
|
+
layer = baseLayer;
|
|
482
|
+
}
|
|
483
|
+
currentPoster.layers.push(layer);
|
|
484
|
+
return {
|
|
485
|
+
content: [
|
|
486
|
+
{
|
|
487
|
+
type: 'text',
|
|
488
|
+
text: JSON.stringify({
|
|
489
|
+
success: true,
|
|
490
|
+
message: 'Layer added',
|
|
491
|
+
layer,
|
|
492
|
+
totalLayers: currentPoster.layers.length,
|
|
493
|
+
}, null, 2),
|
|
494
|
+
},
|
|
495
|
+
],
|
|
496
|
+
};
|
|
497
|
+
}
|
|
498
|
+
case 'modify_layer': {
|
|
499
|
+
if (!currentPoster) {
|
|
500
|
+
return {
|
|
501
|
+
content: [{ type: 'text', text: 'Error: No poster created. Use create_poster first.' }],
|
|
502
|
+
};
|
|
503
|
+
}
|
|
504
|
+
const layerId = params.layerId;
|
|
505
|
+
if (!layerId) {
|
|
506
|
+
return {
|
|
507
|
+
content: [{ type: 'text', text: 'Error: layerId is required' }],
|
|
508
|
+
};
|
|
509
|
+
}
|
|
510
|
+
const layerIndex = currentPoster.layers.findIndex((l) => l.id === layerId);
|
|
511
|
+
if (layerIndex < 0) {
|
|
512
|
+
return {
|
|
513
|
+
content: [{ type: 'text', text: `Error: Layer not found: ${layerId}` }],
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
const layer = currentPoster.layers[layerIndex];
|
|
517
|
+
// Update transform properties
|
|
518
|
+
const transformKeys = ['x', 'y', 'width', 'height', 'rotation', 'opacity'];
|
|
519
|
+
for (const key of transformKeys) {
|
|
520
|
+
if (params[key] !== undefined) {
|
|
521
|
+
layer.transform[key] = params[key];
|
|
522
|
+
}
|
|
523
|
+
}
|
|
524
|
+
// Update base properties
|
|
525
|
+
if (params.visible !== undefined)
|
|
526
|
+
layer.visible = params.visible;
|
|
527
|
+
if (params.locked !== undefined)
|
|
528
|
+
layer.locked = params.locked;
|
|
529
|
+
if (params.name !== undefined)
|
|
530
|
+
layer.name = params.name;
|
|
531
|
+
// Update text layer properties
|
|
532
|
+
if (layer.type === 'text') {
|
|
533
|
+
const textLayer = layer;
|
|
534
|
+
if (params.content !== undefined)
|
|
535
|
+
textLayer.content = params.content;
|
|
536
|
+
if (params.fontFamily !== undefined)
|
|
537
|
+
textLayer.fontFamily = params.fontFamily;
|
|
538
|
+
if (params.fontSize !== undefined)
|
|
539
|
+
textLayer.fontSize = params.fontSize;
|
|
540
|
+
if (params.fontWeight !== undefined)
|
|
541
|
+
textLayer.fontWeight = params.fontWeight;
|
|
542
|
+
if (params.color !== undefined)
|
|
543
|
+
textLayer.color = params.color;
|
|
544
|
+
if (params.textAlign !== undefined)
|
|
545
|
+
textLayer.textAlign = params.textAlign;
|
|
546
|
+
if (params.letterSpacing !== undefined)
|
|
547
|
+
textLayer.letterSpacing = params.letterSpacing;
|
|
548
|
+
if (params.lineHeight !== undefined)
|
|
549
|
+
textLayer.lineHeight = params.lineHeight;
|
|
550
|
+
}
|
|
551
|
+
// Update media layer properties (flat structure)
|
|
552
|
+
if (layer.type === 'image' || layer.type === 'video') {
|
|
553
|
+
const mediaLayer = layer;
|
|
554
|
+
if (params.mediaUrl !== undefined)
|
|
555
|
+
mediaLayer.mediaUrl = params.mediaUrl;
|
|
556
|
+
if (params.objectFit !== undefined)
|
|
557
|
+
mediaLayer.objectFit = params.objectFit;
|
|
558
|
+
}
|
|
559
|
+
return {
|
|
560
|
+
content: [
|
|
561
|
+
{
|
|
562
|
+
type: 'text',
|
|
563
|
+
text: JSON.stringify({
|
|
564
|
+
success: true,
|
|
565
|
+
message: 'Layer modified',
|
|
566
|
+
layer,
|
|
567
|
+
}, null, 2),
|
|
568
|
+
},
|
|
569
|
+
],
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
case 'apply_effect': {
|
|
573
|
+
if (!currentPoster) {
|
|
574
|
+
return {
|
|
575
|
+
content: [{ type: 'text', text: 'Error: No poster created. Use create_poster first.' }],
|
|
576
|
+
};
|
|
577
|
+
}
|
|
578
|
+
const effectId = params.effectId;
|
|
579
|
+
if (!effectId) {
|
|
580
|
+
return {
|
|
581
|
+
content: [{ type: 'text', text: 'Error: effectId is required' }],
|
|
582
|
+
};
|
|
583
|
+
}
|
|
584
|
+
if (effectId === 'none') {
|
|
585
|
+
delete currentPoster.effect;
|
|
586
|
+
return {
|
|
587
|
+
content: [
|
|
588
|
+
{
|
|
589
|
+
type: 'text',
|
|
590
|
+
text: JSON.stringify({ success: true, message: 'Effect removed' }, null, 2),
|
|
591
|
+
},
|
|
592
|
+
],
|
|
593
|
+
};
|
|
594
|
+
}
|
|
595
|
+
const settingsKey = getEffectSettingsKey(effectId);
|
|
596
|
+
const effect = {
|
|
597
|
+
effectId,
|
|
598
|
+
enabled: params.enabled ?? true,
|
|
599
|
+
};
|
|
600
|
+
// Build effect-specific settings with proper defaults matching LayerShareState
|
|
601
|
+
if (settingsKey === 'ascii') {
|
|
602
|
+
// Extract style from effectId (e.g., "ascii-standard" -> "standard")
|
|
603
|
+
const style = effectId.replace('ascii-', '');
|
|
604
|
+
effect.ascii = {
|
|
605
|
+
style,
|
|
606
|
+
cellSize: params.cellSize ?? 9,
|
|
607
|
+
invert: params.invert ?? false,
|
|
608
|
+
color: params.color ?? true,
|
|
609
|
+
charRotation: false,
|
|
610
|
+
postfx: {
|
|
611
|
+
preset: 'none',
|
|
612
|
+
scanlineIntensity: 0,
|
|
613
|
+
scanlineCount: 200,
|
|
614
|
+
targetFPS: 0,
|
|
615
|
+
jitterIntensity: 0,
|
|
616
|
+
jitterSpeed: 1,
|
|
617
|
+
mouseGlowEnabled: false,
|
|
618
|
+
mouseGlowRadius: 200,
|
|
619
|
+
mouseGlowIntensity: 1.5,
|
|
620
|
+
vignetteIntensity: 0,
|
|
621
|
+
vignetteRadius: 0.8,
|
|
622
|
+
colorPalette: 'original',
|
|
623
|
+
curvature: 0,
|
|
624
|
+
aberrationStrength: 0,
|
|
625
|
+
noiseIntensity: 0,
|
|
626
|
+
noiseScale: 1,
|
|
627
|
+
noiseSpeed: 1,
|
|
628
|
+
waveAmplitude: 0,
|
|
629
|
+
waveFrequency: 10,
|
|
630
|
+
waveSpeed: 1,
|
|
631
|
+
glitchIntensity: 0,
|
|
632
|
+
glitchFrequency: 0,
|
|
633
|
+
brightnessAdjust: 0,
|
|
634
|
+
contrastAdjust: 1,
|
|
635
|
+
},
|
|
636
|
+
};
|
|
637
|
+
}
|
|
638
|
+
else if (settingsKey === 'dither') {
|
|
639
|
+
// Extract pattern from effectId (e.g., "dither-floyd-steinberg" -> "floydSteinberg")
|
|
640
|
+
const patternMap = {
|
|
641
|
+
'dither-floyd-steinberg': 'floydSteinberg',
|
|
642
|
+
'dither-atkinson': 'atkinson',
|
|
643
|
+
'dither-jarvis-judice-ninke': 'jarvisJudiceNinke',
|
|
644
|
+
'dither-stucki': 'stucki',
|
|
645
|
+
'dither-burkes': 'burkes',
|
|
646
|
+
'dither-sierra': 'sierra',
|
|
647
|
+
'dither-two-row-sierra': 'twoRowSierra',
|
|
648
|
+
'dither-sierra-lite': 'sierraLite',
|
|
649
|
+
'color-separation': 'floydSteinberg',
|
|
650
|
+
};
|
|
651
|
+
effect.dither = {
|
|
652
|
+
pattern: patternMap[effectId] || 'floydSteinberg',
|
|
653
|
+
pixelation: params.pixelation ?? 3,
|
|
654
|
+
paletteId: 'noir',
|
|
655
|
+
colors: params.colors ?? ['#000000', '#ffffff'],
|
|
656
|
+
brightness: params.brightness ?? 1,
|
|
657
|
+
contrast: params.contrast ?? 1.2,
|
|
658
|
+
threshold: 1.0,
|
|
659
|
+
bloomEnabled: false,
|
|
660
|
+
bloomIntensity: 0.5,
|
|
661
|
+
bloomRadius: 8,
|
|
662
|
+
};
|
|
663
|
+
}
|
|
664
|
+
else if (settingsKey === 'monoHalftone') {
|
|
665
|
+
effect.monoHalftone = {
|
|
666
|
+
colorBack: '#f2f1e8',
|
|
667
|
+
colorFront: '#2b2b2b',
|
|
668
|
+
originalColors: false,
|
|
669
|
+
gridType: 'square',
|
|
670
|
+
dotType: 'circle',
|
|
671
|
+
inverted: false,
|
|
672
|
+
size: params.dotSize ?? 0.3,
|
|
673
|
+
radius: 0.5,
|
|
674
|
+
contrast: 1.2,
|
|
675
|
+
spread: 0.3,
|
|
676
|
+
grainMixer: 0.0,
|
|
677
|
+
grainOverlay: 0.0,
|
|
678
|
+
};
|
|
679
|
+
}
|
|
680
|
+
else if (settingsKey === 'cmykHalftone') {
|
|
681
|
+
effect.cmykHalftone = {
|
|
682
|
+
colorBack: '#f5f5f0',
|
|
683
|
+
colorC: '#00aeef',
|
|
684
|
+
colorM: '#ec008c',
|
|
685
|
+
colorY: '#fff200',
|
|
686
|
+
colorK: '#231f20',
|
|
687
|
+
size: params.dotSize ?? 0.3,
|
|
688
|
+
gridNoise: 0.0,
|
|
689
|
+
type: 'ink',
|
|
690
|
+
softness: 0.0,
|
|
691
|
+
contrast: 1.2,
|
|
692
|
+
intensity: 1.0,
|
|
693
|
+
angleOffset: 0.0,
|
|
694
|
+
misregistration: 0.0,
|
|
695
|
+
spread: 0.3,
|
|
696
|
+
gainC: 1.0,
|
|
697
|
+
gainM: 1.0,
|
|
698
|
+
gainY: 1.0,
|
|
699
|
+
gainK: 1.0,
|
|
700
|
+
floodC: 0.0,
|
|
701
|
+
floodM: 0.0,
|
|
702
|
+
floodY: 0.0,
|
|
703
|
+
floodK: 0.0,
|
|
704
|
+
grainMixer: 0.0,
|
|
705
|
+
grainSize: 1.0,
|
|
706
|
+
grainOverlay: 0.0,
|
|
707
|
+
};
|
|
708
|
+
}
|
|
709
|
+
else if (settingsKey === 'chromatic') {
|
|
710
|
+
effect.chromatic = {
|
|
711
|
+
shape: 'dot',
|
|
712
|
+
radius: 4,
|
|
713
|
+
rotateR: 15,
|
|
714
|
+
rotateG: 75,
|
|
715
|
+
rotateB: 0,
|
|
716
|
+
scatter: 0,
|
|
717
|
+
blending: 1,
|
|
718
|
+
blendingMode: 'linear',
|
|
719
|
+
greyscale: false,
|
|
720
|
+
};
|
|
721
|
+
}
|
|
722
|
+
else if (settingsKey === 'glitch') {
|
|
723
|
+
effect.glitch = {
|
|
724
|
+
// VHS glitch defaults
|
|
725
|
+
grain: 0.4,
|
|
726
|
+
glitchBlocks: 0.5,
|
|
727
|
+
rgbShift: 0.85,
|
|
728
|
+
scanlines: 0.85,
|
|
729
|
+
noise: 0.3,
|
|
730
|
+
distortion: 0.85,
|
|
731
|
+
// Digital glitch defaults
|
|
732
|
+
blockSize: 0.5,
|
|
733
|
+
displacement: 0.5,
|
|
734
|
+
blockOpacity: 1.0,
|
|
735
|
+
colorSplit: 0.5,
|
|
736
|
+
lineTear: 0.5,
|
|
737
|
+
pixelate: 0.3,
|
|
738
|
+
// Weird glitch defaults
|
|
739
|
+
glitchChance: 0.2,
|
|
740
|
+
glitchSpeed: 7.0,
|
|
741
|
+
sliceDensity: 14.0,
|
|
742
|
+
sliceStrength: 0.38,
|
|
743
|
+
shakeStrength: 0.02,
|
|
744
|
+
chromaOffset: 0.016,
|
|
745
|
+
noiseStrength: 0.2,
|
|
746
|
+
colorFlashStrength: 0.4,
|
|
747
|
+
scanlineStrength: 0.18,
|
|
748
|
+
localWarpStrength: 0.14,
|
|
749
|
+
flipChance: 0.15,
|
|
750
|
+
// Shared
|
|
751
|
+
speed: params.speed ?? 1,
|
|
752
|
+
animated: true,
|
|
753
|
+
};
|
|
754
|
+
}
|
|
755
|
+
else if (settingsKey === 'kuwahara') {
|
|
756
|
+
effect.kuwahara = {
|
|
757
|
+
radius: 4,
|
|
758
|
+
alpha: 25,
|
|
759
|
+
sharpness: 0.5,
|
|
760
|
+
sectors: 8,
|
|
761
|
+
saturation: 1.0,
|
|
762
|
+
quantize: 0,
|
|
763
|
+
};
|
|
764
|
+
}
|
|
765
|
+
else if (settingsKey === 'crosshatch') {
|
|
766
|
+
effect.crosshatch = {
|
|
767
|
+
spacing: 12,
|
|
768
|
+
thickness: 2,
|
|
769
|
+
angle: 45,
|
|
770
|
+
contrast: 1.0,
|
|
771
|
+
edgeStrength: 1.0,
|
|
772
|
+
wave: 0.33,
|
|
773
|
+
waveFreq: 3,
|
|
774
|
+
lineWeight: 0,
|
|
775
|
+
inkColor: '#1a1a1a',
|
|
776
|
+
paperColor: '#f5f5dc',
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
else if (settingsKey === 'lineart') {
|
|
780
|
+
effect.lineart = {
|
|
781
|
+
threshold: 0.15,
|
|
782
|
+
thickness: 2,
|
|
783
|
+
softness: 0,
|
|
784
|
+
fillOpacity: 0,
|
|
785
|
+
invert: false,
|
|
786
|
+
wave: 0.05,
|
|
787
|
+
waveFreq: 3,
|
|
788
|
+
lineWeight: 0,
|
|
789
|
+
lineColor: '#1a1a1a',
|
|
790
|
+
fillColor: '#808080',
|
|
791
|
+
backgroundColor: '#ffffff',
|
|
792
|
+
};
|
|
793
|
+
}
|
|
794
|
+
else if (settingsKey === 'engraving') {
|
|
795
|
+
effect.engraving = {
|
|
796
|
+
lineFrequency: 80,
|
|
797
|
+
lineWeight: 0.5,
|
|
798
|
+
contrast: 1.0,
|
|
799
|
+
wave: 0.1,
|
|
800
|
+
waveFreq: 3,
|
|
801
|
+
inkColor: '#1a1a1a',
|
|
802
|
+
paperColor: '#f5f5dc',
|
|
803
|
+
};
|
|
804
|
+
}
|
|
805
|
+
else if (settingsKey === 'stipple') {
|
|
806
|
+
effect.stipple = {
|
|
807
|
+
dotDensity: 0.5,
|
|
808
|
+
dotSize: 2,
|
|
809
|
+
contrast: 1.0,
|
|
810
|
+
randomness: 0.5,
|
|
811
|
+
inkColor: '#1a1a1a',
|
|
812
|
+
paperColor: '#f5f5dc',
|
|
813
|
+
};
|
|
814
|
+
}
|
|
815
|
+
else if (settingsKey === 'sinewarp') {
|
|
816
|
+
effect.sinewarp = {
|
|
817
|
+
speed: 0.5,
|
|
818
|
+
scale: 4,
|
|
819
|
+
amplitude: 0.5,
|
|
820
|
+
bumpIntensity: 0.05,
|
|
821
|
+
specularPower: 12,
|
|
822
|
+
color: true,
|
|
823
|
+
textureScale: 1,
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
currentPoster.effect = effect;
|
|
827
|
+
return {
|
|
828
|
+
content: [
|
|
829
|
+
{
|
|
830
|
+
type: 'text',
|
|
831
|
+
text: JSON.stringify({
|
|
832
|
+
success: true,
|
|
833
|
+
message: 'Effect applied',
|
|
834
|
+
effect,
|
|
835
|
+
}, null, 2),
|
|
836
|
+
},
|
|
837
|
+
],
|
|
838
|
+
};
|
|
839
|
+
}
|
|
840
|
+
case 'add_postprocess': {
|
|
841
|
+
if (!currentPoster) {
|
|
842
|
+
return {
|
|
843
|
+
content: [{ type: 'text', text: 'Error: No poster created. Use create_poster first.' }],
|
|
844
|
+
};
|
|
845
|
+
}
|
|
846
|
+
const ppType = params.type;
|
|
847
|
+
if (!ppType) {
|
|
848
|
+
return {
|
|
849
|
+
content: [{ type: 'text', text: 'Error: Post-process type is required' }],
|
|
850
|
+
};
|
|
851
|
+
}
|
|
852
|
+
const ppId = `pp_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
|
|
853
|
+
const settings = {};
|
|
854
|
+
// Extract relevant settings based on type
|
|
855
|
+
const settingKeys = [
|
|
856
|
+
'intensity', 'count', 'radius', 'strength', 'angle', 'size', 'speed',
|
|
857
|
+
'brightness', 'contrast', 'saturation', 'hue',
|
|
858
|
+
];
|
|
859
|
+
for (const key of settingKeys) {
|
|
860
|
+
if (params[key] !== undefined) {
|
|
861
|
+
settings[key] = params[key];
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
const postProcess = {
|
|
865
|
+
id: ppId,
|
|
866
|
+
type: ppType,
|
|
867
|
+
enabled: params.enabled ?? true,
|
|
868
|
+
settings,
|
|
869
|
+
};
|
|
870
|
+
currentPoster.postProcesses.push(postProcess);
|
|
871
|
+
return {
|
|
872
|
+
content: [
|
|
873
|
+
{
|
|
874
|
+
type: 'text',
|
|
875
|
+
text: JSON.stringify({
|
|
876
|
+
success: true,
|
|
877
|
+
message: 'Post-process added',
|
|
878
|
+
postProcess,
|
|
879
|
+
totalPostProcesses: currentPoster.postProcesses.length,
|
|
880
|
+
}, null, 2),
|
|
881
|
+
},
|
|
882
|
+
],
|
|
883
|
+
};
|
|
884
|
+
}
|
|
885
|
+
case 'remove_layer': {
|
|
886
|
+
if (!currentPoster) {
|
|
887
|
+
return {
|
|
888
|
+
content: [{ type: 'text', text: 'Error: No poster created. Use create_poster first.' }],
|
|
889
|
+
};
|
|
890
|
+
}
|
|
891
|
+
const layerId = params.layerId;
|
|
892
|
+
if (!layerId) {
|
|
893
|
+
return {
|
|
894
|
+
content: [{ type: 'text', text: 'Error: layerId is required' }],
|
|
895
|
+
};
|
|
896
|
+
}
|
|
897
|
+
const layerIndex = currentPoster.layers.findIndex((l) => l.id === layerId);
|
|
898
|
+
if (layerIndex < 0) {
|
|
899
|
+
return {
|
|
900
|
+
content: [{ type: 'text', text: `Error: Layer not found: ${layerId}` }],
|
|
901
|
+
};
|
|
902
|
+
}
|
|
903
|
+
if (layerIndex === 0) {
|
|
904
|
+
return {
|
|
905
|
+
content: [{ type: 'text', text: 'Error: Cannot remove background layer' }],
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
currentPoster.layers.splice(layerIndex, 1);
|
|
909
|
+
return {
|
|
910
|
+
content: [
|
|
911
|
+
{
|
|
912
|
+
type: 'text',
|
|
913
|
+
text: JSON.stringify({
|
|
914
|
+
success: true,
|
|
915
|
+
message: 'Layer removed',
|
|
916
|
+
remainingLayers: currentPoster.layers.length,
|
|
917
|
+
}, null, 2),
|
|
918
|
+
},
|
|
919
|
+
],
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
case 'get_state': {
|
|
923
|
+
if (!currentPoster) {
|
|
924
|
+
return {
|
|
925
|
+
content: [{ type: 'text', text: 'No poster created yet. Use create_poster first.' }],
|
|
926
|
+
};
|
|
927
|
+
}
|
|
928
|
+
return {
|
|
929
|
+
content: [
|
|
930
|
+
{
|
|
931
|
+
type: 'text',
|
|
932
|
+
text: JSON.stringify(currentPoster, null, 2),
|
|
933
|
+
},
|
|
934
|
+
],
|
|
935
|
+
};
|
|
936
|
+
}
|
|
937
|
+
default:
|
|
938
|
+
return {
|
|
939
|
+
content: [{ type: 'text', text: `Unknown state tool: ${name}` }],
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
}
|
|
943
|
+
//# sourceMappingURL=state.js.map
|