@pinepaper.studio/mcp-server 1.6.11 → 1.6.12

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.
Files changed (48) hide show
  1. package/README.md +57 -0
  2. package/dist/tools/compact-descriptions.js +1 -1
  3. package/dist/tools/compact-descriptions.js.map +1 -1
  4. package/dist/tools/definitions.d.ts.map +1 -1
  5. package/dist/tools/definitions.js +139 -47
  6. package/dist/tools/definitions.js.map +1 -1
  7. package/dist/tools/engine-methods.d.ts.map +1 -1
  8. package/dist/tools/engine-methods.js +3 -0
  9. package/dist/tools/engine-methods.js.map +1 -1
  10. package/dist/tools/engine-surface.d.ts +1 -1
  11. package/dist/tools/engine-surface.d.ts.map +1 -1
  12. package/dist/tools/engine-surface.js +20 -5
  13. package/dist/tools/engine-surface.js.map +1 -1
  14. package/dist/tools/minimal-descriptions.js +1 -1
  15. package/dist/tools/minimal-descriptions.js.map +1 -1
  16. package/dist/tools/shape-params.d.ts +36 -0
  17. package/dist/tools/shape-params.d.ts.map +1 -0
  18. package/dist/tools/shape-params.js +159 -0
  19. package/dist/tools/shape-params.js.map +1 -0
  20. package/dist/tools/stick-vocabulary.d.ts +26 -0
  21. package/dist/tools/stick-vocabulary.d.ts.map +1 -0
  22. package/dist/tools/stick-vocabulary.js +102 -0
  23. package/dist/tools/stick-vocabulary.js.map +1 -0
  24. package/dist/types/code-generator.d.ts.map +1 -1
  25. package/dist/types/code-generator.js +419 -50
  26. package/dist/types/code-generator.js.map +1 -1
  27. package/dist/types/schemas.d.ts +97 -26
  28. package/dist/types/schemas.d.ts.map +1 -1
  29. package/dist/types/schemas.js +18 -11
  30. package/dist/types/schemas.js.map +1 -1
  31. package/dist/vendor/design/design-systems-dtcg.d.ts +9 -0
  32. package/dist/vendor/design/design-systems-dtcg.d.ts.map +1 -1
  33. package/dist/vendor/design/design-systems-dtcg.js +53 -1
  34. package/dist/vendor/design/design-systems-dtcg.js.map +1 -1
  35. package/dist/vendor/design/device-mockup-generator.d.ts +83 -0
  36. package/dist/vendor/design/device-mockup-generator.d.ts.map +1 -0
  37. package/dist/vendor/design/device-mockup-generator.js +634 -0
  38. package/dist/vendor/design/device-mockup-generator.js.map +1 -0
  39. package/dist/vendor/design/recursive-subdivision-generator.d.ts +79 -0
  40. package/dist/vendor/design/recursive-subdivision-generator.d.ts.map +1 -0
  41. package/dist/vendor/design/recursive-subdivision-generator.js +319 -0
  42. package/dist/vendor/design/recursive-subdivision-generator.js.map +1 -0
  43. package/dist/vendor/design/textile-weave-generator.d.ts +140 -0
  44. package/dist/vendor/design/textile-weave-generator.d.ts.map +1 -0
  45. package/dist/vendor/design/textile-weave-generator.js +568 -0
  46. package/dist/vendor/design/textile-weave-generator.js.map +1 -0
  47. package/manifest.json +1 -1
  48. package/package.json +8 -2
package/README.md CHANGED
@@ -217,6 +217,63 @@ If you do not want an agent executing anything, `code` mode is a first-class pat
217
217
  - Puppeteer mode launches Chrome with `--no-sandbox` and `--disable-setuid-sandbox`. That is routine for headless automation and it does weaken Chrome's own process sandbox. If that matters where you are running it, use `code` mode or put the server in a container.
218
218
  - Puppeteer itself is an **optional** peer dependency, kept out of the default tree precisely because a headless browser plus an install script is what scanners flag hardest. Install it only if you want the executing mode.
219
219
 
220
+ ## What's new in 1.6.12
221
+
222
+ ### Fixed: images could not be imported at all
223
+
224
+ Two separate bugs meant no photo could be placed into a scene over MCP.
225
+
226
+ `pinepaper_import_image` failed on **every** URL with a syntax error before it ran — an apostrophe in one of its own error messages closed a string early. And `pinepaper_import_svg` with an external `<image href>` reported success, created nothing, and then broke **every later export** in the session with "Tainted canvases may not be exported", including scenes that never touched the image; only a page reload recovered it.
227
+
228
+ SVGs now have their remote images fetched and inlined before importing. One that can't be fetched has its element removed and the removal named in `imageWarnings` — a missing picture is visible and recoverable, a tainted canvas is neither.
229
+
230
+ ### Fixed: parameters that were accepted and then ignored
231
+
232
+ A tool that takes a parameter, validates it, and drops it is worse than one that refuses it, because the caller has no way to tell. This release removes every instance found:
233
+
234
+ - **Ellipses** took `radiusX`/`radiusY` — the pair documented in this package's own examples — and built the default size instead. They now map to the axes the engine reads.
235
+ - **`pinepaper_stick`** accepted eight: `propSide: 'right'` put the prop in the *left* hand (the engine compares against `'L'`/`'R'`), `walk: true` walked nowhere, expression beats keyed `name` were dropped entirely, and `facing` did nothing on a figure — it is now refused by name rather than ignored.
236
+ - **`pinepaper_load_map`** accepted seven the engine never reads. Style keys nest under `styles` and are spelled differently there; `enableHover`/`enableClick` are `interactive`/`selectable`.
237
+ - **`hoverStroke`** was documented by the engine and implemented nowhere; it now reaches the renderer.
238
+
239
+ `pinepaper_agent_end_job` also reported the canvas as **2233×1472** for a 1920×1080 artboard — it was reading the backing store, whose ratio to the artboard is not the device pixel ratio and so cannot be divided back out. It reports the artboard now.
240
+
241
+ ### New: `anchor` — say which corner your x/y meant
242
+
243
+ Position has always been the bounding-box **centre**. Anything that computed a layout box authored the **top-left**, so passing those coordinates displaced every item by half its own size. `anchor: 'top-left'` (also `top-right`, `bottom-left`, `bottom-right`, `center`) states which corner you meant, applied after size and rotation so it uses the item's real box. A misspelled anchor is now refused rather than silently falling back to centre.
244
+
245
+ ### New: figures that act, and exports that tell you what they cost
246
+
247
+ `pinepaper_stick` gained `gait` (9 named walks — `trudge` leans away from where it's going, `sneak` crouches), `poses` as a track over time, and named `sequence`s. Every valid name is read from the engine's own kit, so the list cannot drift.
248
+
249
+ Exports now report what **this scene** loses to the format you chose — a PNG of an animated scene is one frame, a GIF drops the soundtrack — on both `estimateOnly` and a real export. It appears only when there is something to lose: its absence is a statement about your scene, not a claim that the format is lossless.
250
+
251
+ ### Fixed: discovery
252
+
253
+ `pinepaper_list_generators` reported **3 generators when the engine has 74**, and dropped the parameters it promised to list. The batch tool advertised 15 of those 74, so 59 working generators were invisible to anyone reading it. All lists now come from one source.
254
+
255
+ Loading a template that carries clipped character parts now warns when the studio dropped them, and says not to save over the template — the file is still intact until you do.
256
+
257
+ ### Documentation: shapes described a fraction of what they accept
258
+
259
+ `triangle` was documented as taking `color` and nothing else, while the engine accepts width, height, and either `kind` (`'right'`, `'equilateral'`, `'obtuse'`…) or exact interior `angles` and builds the triangle by the law of sines. `polygon` accepts an explicit **vertex list** for irregular shapes. `ellipse` and `heart` were `color`-only. Six of the eight speech bubbles take `cornerRadius`. And **every** item type accepts a `label` — a string, or a full config with position, offset, font and colour — so captioning no longer needs a second call and hand-computed coordinates.
260
+
261
+ Two silent fallbacks are now stated: an angle set the engine rejects gives you the default isosceles with no error, and the vertex-list polygon uses absolute coordinates and ignores `position`.
262
+
263
+ ### Fixed: exporting without naming a platform ignored your canvas
264
+
265
+ `platform` defaults to `auto`, but `auto` wasn't a real preset — the lookup fell through to the `web` preset, so an export that named no platform silently rendered **800×600** over whatever size your canvas actually was. Measured: three exports of a 960×540 canvas all came back 800×600, which reads from outside as a dimension mismatch with nothing saying the canvas had been replaced.
266
+
267
+ `auto` now means the canvas's own size, read at export time, with the preset kept only as a fallback for older studios. Naming a platform still uses its preset exactly as before — and `platform` is no longer required, so you can export at your canvas size without picking a preset that overrides it.
268
+
269
+ ### Fixed: `fps` and `scale` were accepted but undiscoverable
270
+
271
+ Both parameters worked and were documented in the tool's own text, but were missing from the machine-readable schema — which is the only part a model actually reads. So callers were told to use them and had no way to find them. Published now, along with `quality`'s description admitting that it carries a **frame rate** (15/30/60) as well as compression.
272
+
273
+ ### Three design generators are now included
274
+
275
+ `device-mockup`, `recursive-subdivision` and `textile-weave` existed upstream but had never been copied into the package.
276
+
220
277
  ## What's new in 1.6.11
221
278
 
222
279
  ### Fixed: modifying an item could edit a different one
@@ -106,7 +106,7 @@ SHAPE TYPES: ${DIAGRAM_SHAPES}.`,
106
106
  // -------------------------------------------------------------------------
107
107
  // agent_export
108
108
  // -------------------------------------------------------------------------
109
- pinepaper_agent_export: `Export as MP4, GIF, PNG, SVG, or PDF. Formats: svg, png, gif, mp4, webm, pdf. Quality: draft, standard, high. Framing: canvas (default) or camera (camera_animates viewport — video formats only).`,
109
+ pinepaper_agent_export: `Export as MP4, GIF, PNG, SVG, or PDF. Formats: svg, png, gif, mp4, webm, pdf. Quality: draft, standard, high — compression, and a default frame rate (15/30/60) that fps overrides. Video size control is scale 0.1-1, not a bitrate; scale 0.5 + quality draft is the fast preview. Framing: canvas (default) or camera (camera_animates viewport — video formats only).`,
110
110
  // -------------------------------------------------------------------------
111
111
  // design_system
112
112
  // -------------------------------------------------------------------------
@@ -1 +1 @@
1
- {"version":3,"file":"compact-descriptions.js","sourceRoot":"","sources":["../../src/tools/compact-descriptions.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"compact-descriptions.js","sourceRoot":"","sources":["../../src/tools/compact-descriptions.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAwB/C,eAAO,MAAM,cAAc,6kbAyK+G,CAAC;AAW3I,eAAO,MAAM,eAAe,EAAE,IAAI,EA8wQjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAE5D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,EAAE,CAO3D;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,EAAE,CAQrE"}
1
+ {"version":3,"file":"definitions.d.ts","sourceRoot":"","sources":["../../src/tools/definitions.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AA0B/C,eAAO,MAAM,cAAc,6kbAyK+G,CAAC;AAW3I,eAAO,MAAM,eAAe,EAAE,IAAI,EAw2QjC,CAAC;AAEF;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAE5D;AAED;;GAEG;AACH,wBAAgB,YAAY,IAAI,MAAM,EAAE,CAEvC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,IAAI,EAAE,CAO3D;AAED;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAC;AAE9D;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,aAAa,GAAG,IAAI,EAAE,CAQrE"}
@@ -9,6 +9,8 @@
9
9
  */
10
10
  import { COMPACT_DESCRIPTIONS } from './compact-descriptions.js';
11
11
  import { MINIMAL_DESCRIPTIONS } from './minimal-descriptions.js';
12
+ import { STICK_GAITS, STICK_POSES, STICK_SEQUENCES, STICK_EXPRESSIONS, STICK_PROPS } from './stick-vocabulary.js';
13
+ import { GeneratorNameSchema, ItemTypeSchema } from '../types/schemas.js';
12
14
  import { EffectTypeSchema, SimpleAnimationTypeSchema, GEOMETRY_OPERATIONS, THREAD_STITCHES, } from '../types/schemas.js';
13
15
  /**
14
16
  * Vocabulary lists derived from Zod schemas so tool descriptions stay in
@@ -380,13 +382,64 @@ For requests like "draw a witch", "draw a cat face", "draw a person", or any det
380
382
  - DO NOT attempt pixel-level character drawing with paths
381
383
 
382
384
  ITEM TYPES:
385
+
386
+ EVERY type below also takes an anchor, which says WHICH CORNER your x/y meant.
387
+ Position is the bounding-box CENTRE by default. Anything that computed a layout
388
+ box — a design system, or any CSS-shaped mental model — authored the TOP-LEFT
389
+ instead, and passing those coordinates straight in displaces every item by half
390
+ its own size. anchor: 'top-left' (also top-right, bottom-left, bottom-right,
391
+ center; origin is an alias for the parameter) fixes that without you computing
392
+ bounds you cannot know until the item exists. It is applied after size and
393
+ rotation, so it uses the item's real box.
394
+
395
+ EVERY type below also takes a label, which wraps the item in a labelled group —
396
+ you do not need a second create call and a hand-computed position to caption a
397
+ shape. A string is the short form; the object form places and styles it:
398
+ label: { content: 'Start', position: 'top', offset: [0, 10], fontSize: 14,
399
+ fontFamily: 'Inter, sans-serif', color: '#ffffff', backgroundColor: null }.
400
+ position takes center (default), top, bottom, left, right or a corner. Use
401
+ label.position for placement: it works here today, and where the sibling
402
+ labelPosition spelling is also accepted, label.position wins.
403
+ Labelling a text item gives you TWO text items in the group — the body and the
404
+ label. That is what you want for a caption; it is a surprise if you expected
405
+ the label to replace the content.
406
+
383
407
  - text: Text content with font styling (properties: content, fontSize, color, fontFamily)
384
408
  - circle: Circular shape (properties: radius, color, strokeColor, strokeWidth)
385
409
  - star: Star shape (properties: radius1, radius2, points, color)
410
+ radius1 is the OUTER radius and is what sizes the star; radius or
411
+ width/height size it equally well. radius2 is read ONLY as a ratio to
412
+ radius1 (inner/outer, default 0.4), so radius2 passed WITHOUT radius1 is
413
+ ignored completely and you get the default waist. innerRadiusRatio sets that
414
+ same waist directly and needs no radii at all. points defaults to 5.
415
+ A star is always radially symmetric — given width and height it uses the
416
+ smaller — and the size you give is the radius BOX, the circle the tips
417
+ touch. The visible bounds are never larger than that box and usually
418
+ smaller — they fill it only when points is a multiple of 4.
386
419
  - rectangle: Rectangle (properties: width, height, color, cornerRadius)
387
- - triangle: Triangular shape (properties: color)
420
+ - triangle: Triangular shape (properties: width, height, color, angles, kind)
421
+ Defaults to a 100x86 isosceles. For any OTHER triangle, do not hand-build it
422
+ from a path — name it: kind: 'right' | 'equilateral' | 'isosceles' |
423
+ 'obtuse' | 'acute' | 'scalene', or give exact interior angles in degrees,
424
+ angles: [30, 60] (the third is inferred) or [30, 60, 90]. Angles that nearly
425
+ sum to 180 are normalized, so rounding is safe. With angles or kind the
426
+ triangle scales UNIFORMLY into the width x height box — the angles are fixed
427
+ and win, so one axis comes out smaller than requested. That is the only way
428
+ to keep a 'right' triangle actually right.
429
+ An angle set the engine cannot use — fewer than two entries, or any angle
430
+ outside 0.5-179.5 degrees — falls back to the default isosceles SILENTLY,
431
+ with no error. If you asked for a right triangle and got an isosceles one,
432
+ the angles were rejected.
388
433
  - polygon: Regular polygon with N sides (properties: sides, radius, color)
389
- - ellipse: Oval shape (properties: color)
434
+ points additionally accepts an explicit VERTEX LIST — [[x, y], ...] or
435
+ [{x, y}, ...], three or more, in canvas coordinates — which builds that
436
+ exact, possibly IRREGULAR polygon and ignores sides. Reach for this before
437
+ path when the outline is straight-edged. A plain number in points is not a
438
+ vertex list and falls through to sides (default 6).
439
+ In the vertex-list form the coordinates are ABSOLUTE canvas coordinates and
440
+ position is ignored — the polygon lands where its points say, not where you
441
+ positioned it. Offset the points yourself, or use sides + radius + position.
442
+ - ellipse: Oval shape (properties: width, height, color) — defaults to 100x60
390
443
  - path: Custom path with segments or SVG data (properties: segments, pathData, strokeColor, fillColor, closed, smooth)
391
444
  - line: Line between two points (properties: from, to, strokeColor, strokeWidth)
392
445
  - arc: Curved arc through three points (properties: from, through, to, strokeColor)
@@ -394,18 +447,27 @@ ITEM TYPES:
394
447
  - hexagon: Regular 6-sided polygon (properties: radius, color)
395
448
  - diamond: 4-sided diamond/rhombus (properties: radius, color)
396
449
  - arrow: Right-pointing block arrow (properties: width, height, color)
397
- - heart: Heart shape (properties: color)
450
+ - heart: Heart shape (properties: width, height, color) — defaults to 80x80
398
451
  - disk: Filled disk — the region inside a circle (properties: radius, color)
399
452
  - circle-outline: The circle CURVE — stroked, no interior (properties: radius,
400
453
  strokeColor, strokeWidth)
401
454
  - arrow-right: Alias for arrow — the same definition under the name the shape
402
- grids use. Identical output; both are listed because both are accepted.
455
+ grids use. Identical output and the same width, height and color; both are
456
+ listed because both are accepted.
403
457
 
404
458
  SPEECH AND ANNOTATION SHAPES — the engine draws these; use one instead of
405
459
  hand-building an outline from a path. All take width, height and color, and the
406
- descriptions below are the engine's own. The six with a tail also take
407
- tailDirection (bottom-left | bottom-right | bottom | top-left | top-right | top
408
- | left | right) and tailSize (0-1, default 0.35):
460
+ descriptions below are the engine's own. Three further parameters are each
461
+ read by six of these eight shapes, and THE THREE SIXES ARE NOT THE SAME SIX —
462
+ a shape missing from a list ignores that parameter silently, so check before
463
+ you pass it:
464
+ cornerRadius — speech-bubble, speech-bubble-pointed, comment-box,
465
+ callout-box, double-bubble, quote-bubble
466
+ tailDirection (bottom-left | bottom-right | bottom | top-left | top-right |
467
+ top | left | right) — speech-bubble, speech-bubble-square,
468
+ speech-bubble-pointed, thought-bubble, comment-box, callout-box
469
+ tailSize (0-1, default 0.35) — speech-bubble, speech-bubble-square,
470
+ speech-bubble-pointed, comment-box, callout-box, double-bubble
409
471
  - speech-bubble: Classic round speech bubble with triangular tail.
410
472
  - speech-bubble-square: Rectangular speech bubble with sharp corners and
411
473
  pointed tail.
@@ -2310,7 +2372,9 @@ A partial composition reports as a failure with the elements that did not create
2310
2372
  name: 'pinepaper_stick',
2311
2373
  description: `The vendored stick-figure kit — a rigged figure posed, walking, travelling, holding a prop, with a garment and hair, plus the set it stands on and among.
2312
2374
 
2313
- A different construction from pinepaper_character, which places a figure from the DESIGN GRAPH by concept ("pp:Pigeon"). This is the stick kit specifically, and its options — pose, walk, travel, prop, garment, trouser, hair, expression and a timeline of expressions — were discoverable only by reading the engine's source.
2375
+ A different construction from pinepaper_character, which places a figure from the DESIGN GRAPH by concept ("pp:Pigeon"). This is the stick kit specifically.
2376
+
2377
+ TO MAKE IT ACT, not just stand: gait is how it walks and is never just walking; poses is the body over time, [{at, pose}]; sequence is a named track of those. Pass gait and travel in the SAME call to cross the frame — they share one track and two calls fight over it. A mistyped gait, pose or sequence comes back NAMED in warnings with the valid list, and the figure is still built.
2314
2378
 
2315
2379
  action 'figure' builds the figure. action 'set' builds the floor, the wall and the objects around it, so a figure has somewhere to be.
2316
2380
 
@@ -2323,26 +2387,48 @@ The geometry is vendored from mcp-cloud, which makes this a three-repo artifact:
2323
2387
  kind: { type: 'string', description: 'figure: which figure. set: which piece of the kit.' },
2324
2388
  at: { type: 'object', description: '{ x?, y? } — where it goes.' },
2325
2389
  scale: { type: 'number', description: 'Size multiplier.' },
2326
- facing: { type: 'string', enum: ['left', 'right'], description: 'Which way the figure looks.' },
2327
- pose: { type: 'string', description: "figure: a named pose from the kit's POSES." },
2390
+ facing: { type: 'string', enum: ['left', 'right'], description: "set: which way a CHAIR faces. A figure has none and passing it here is refused — a figure faces the way it travels." },
2391
+ pose: { type: 'string', enum: [...STICK_POSES], description: 'figure: ONE pose, held.' },
2328
2392
  poseAt: { type: 'number', description: 'figure: seconds at which that pose is struck.' },
2329
- expression: { type: 'string', description: 'figure: one facial expression.' },
2330
- expressions: { type: 'array', items: { type: 'object' }, description: 'figure: [{ at, name }] — expressions over time.' },
2331
- walk: { anyOf: [{ type: 'boolean' }, { type: 'object' }], description: 'figure: a walk cycle.' },
2332
- travel: { type: 'object', description: 'figure: move across the scene while walking, rather than walking in place.' },
2333
- prop: { type: 'string', description: 'figure: something held in hand.' },
2334
- propSide: { type: 'string', enum: ['left', 'right'], description: 'figure: which hand.' },
2335
- garment: { type: 'string', description: 'figure: clothing.' },
2336
- trouser: { type: 'string', description: 'figure: legwear.' },
2337
- hair: { type: 'string', description: 'figure: hair style.' },
2393
+ poses: {
2394
+ type: 'array',
2395
+ description: 'figure: THE BODY OVER TIME — [{at: seconds, pose: name}]. The counterpart of expressions, and the difference between a figure that acts and one that holds a single attitude while captions do the work.',
2396
+ items: { type: 'object', properties: { at: { type: 'number' }, pose: { type: 'string', enum: [...STICK_POSES] } }, required: ['at', 'pose'] },
2397
+ },
2398
+ gait: { type: 'string', enum: [...STICK_GAITS], description: 'figure: HOW it walks, and it is never just walking — trudge leans away from where it is going, sneak crouches, tiptoe raises the cadence. Pass travel in the SAME call to cross the frame; they share one track.' },
2399
+ gaitSeconds: { type: 'number', description: 'figure: how long the gait runs. Defaults to durationSeconds.' },
2400
+ gaitFrom: { type: 'number', description: 'figure: when the gait starts, in seconds.' },
2401
+ sequence: { type: 'string', enum: [...STICK_SEQUENCES], description: 'figure: a named pose track. Shorthand that resolves to beats and joins any poses you also pass.' },
2402
+ sequenceFrom: { type: 'number', description: 'figure: when the sequence starts (default 0).' },
2403
+ sequenceSeconds: { type: 'number', description: 'figure: how long it spans (default 4).' },
2404
+ expression: { type: 'string', enum: [...STICK_EXPRESSIONS], description: 'figure: one face. An unknown name costs the face, not the figure.' },
2405
+ expressions: {
2406
+ type: 'array',
2407
+ description: 'figure: faces over time — [{at: seconds, expression: name}]. Pass durationSeconds with these or the last face lasts one second.',
2408
+ items: { type: 'object', properties: { at: { type: 'number' }, expression: { type: 'string', enum: [...STICK_EXPRESSIONS] } }, required: ['at', 'expression'] },
2409
+ },
2410
+ walk: {
2411
+ anyOf: [{ type: 'boolean' }, { type: 'array', items: { type: 'object', properties: { seconds: { type: 'number' }, from: { type: 'number' } } } }],
2412
+ description: 'figure: walk cycles — true for one default cycle, or [{seconds, from}] for several. For anything other than a plain walk, use gait.',
2413
+ },
2414
+ travel: {
2415
+ type: 'array',
2416
+ description: 'figure: waypoints [{t, x, y}] carrying the figure across the scene rather than walking in place. FEWER THAN TWO IS IGNORED. Pass walk or gait in the same call or it slides without moving its legs.',
2417
+ items: { type: 'object', properties: { t: { type: 'number' }, x: { type: 'number' }, y: { type: 'number' } }, required: ['t', 'x', 'y'] },
2418
+ },
2419
+ prop: { type: 'string', enum: [...STICK_PROPS], description: 'figure: something held in hand.' },
2420
+ propSide: { type: 'string', enum: ['L', 'R'], description: "figure: which hand. 'left'/'right' are accepted and normalised." },
2421
+ garment: { type: 'string', description: 'figure: clothing colour.' },
2422
+ trouser: { type: 'string', description: 'figure: legwear colour.' },
2423
+ hair: { type: 'string', description: 'figure: hair colour.' },
2338
2424
  withHair: { type: 'boolean', description: 'figure: draw hair at all.' },
2339
- groundY: { type: 'number', description: 'The y the figure stands on.' },
2340
- surfaceY: { type: 'number', description: 'The y a set object sits on.' },
2341
- durationSeconds: { type: 'number', description: 'figure: length of the performance.' },
2342
- object: { type: 'object', description: 'set: the object spec.' },
2343
- items: { type: 'array', items: { type: 'object' }, description: 'set: several pieces at once.' },
2344
- floor: { anyOf: [{ type: 'boolean' }, { type: 'object' }], description: 'set: draw a floor.' },
2345
- wall: { anyOf: [{ type: 'boolean' }, { type: 'object' }], description: 'set: draw a wall.' },
2425
+ groundY: { type: 'number', description: 'set: the y a ROOM floor sits at.' },
2426
+ surfaceY: { type: 'number', description: 'set: the y a TABLETOP object sits on.' },
2427
+ durationSeconds: { type: 'number', description: 'figure: when the tracks end, on the same clock as expressions, poses and travel.' },
2428
+ object: { type: 'string', description: "set: the NAME of the thing to put on a surface, with kind 'tabletop'." },
2429
+ items: { type: 'number', description: 'set: how many things stand on a shelf (default 3). A COUNT, not a list.' },
2430
+ floor: { type: 'string', description: "set: the floor COLOUR, for kind 'room'." },
2431
+ wall: { type: 'string', description: "set: the wall COLOUR, for kind 'room'." },
2346
2432
  },
2347
2433
  required: ['action'],
2348
2434
  },
@@ -6729,18 +6815,7 @@ COMMON PARAMS (all generators):
6729
6815
  properties: {
6730
6816
  generatorName: {
6731
6817
  type: 'string',
6732
- enum: [
6733
- 'drawSunburst', 'drawSunsetScene', 'drawGrid', 'drawStackedCircles',
6734
- 'drawCircuit', 'drawWaves', 'drawPattern',
6735
- 'drawBokeh', 'drawGradientMesh', 'drawGeometricAbstract', 'drawWindField',
6736
- 'drawFluidFlow', 'drawOrganicFlow', 'drawNoiseTexture',
6737
- 'drawGlobeWireframe',
6738
- 'drawFunctionPlot', 'drawParametricCurve', 'drawSimulation',
6739
- 'drawSpectrumAnalyzer', 'draw3DSurface',
6740
- 'drawTruchet', 'drawHalftone', 'drawRibbons',
6741
- 'drawFormulaArt', 'drawParametricCollection', 'drawShaderArt', 'drawYeganehMountains',
6742
- 'drawBlobs', 'drawLowPoly', 'drawPeaks', 'drawScatter', 'drawStackedWaves', 'draw3DParametricCurve',
6743
- ],
6818
+ enum: [...GeneratorNameSchema.options],
6744
6819
  description: 'Generator name',
6745
6820
  },
6746
6821
  params: {
@@ -7581,14 +7656,14 @@ EXAMPLE — Animated sky scene with timed reveals:
7581
7656
  backgroundColor: { type: 'string', description: 'For set_background: hex color' },
7582
7657
  generatorName: {
7583
7658
  type: 'string',
7584
- enum: ['drawSunburst', 'drawSunsetScene', 'drawGrid', 'drawWaves', 'drawCircuit', 'drawStackedCircles', 'drawPattern', 'drawBokeh', 'drawGradientMesh', 'drawGeometricAbstract', 'drawWindField', 'drawFluidFlow', 'drawOrganicFlow', 'drawNoiseTexture', 'drawGlobeWireframe'],
7659
+ enum: [...GeneratorNameSchema.options],
7585
7660
  description: 'For execute_generator: generator name',
7586
7661
  },
7587
7662
  generatorParams: { type: 'object', description: 'For execute_generator: parameters' },
7588
7663
  // Items
7589
7664
  itemType: {
7590
7665
  type: 'string',
7591
- enum: ['text', 'circle', 'rectangle', 'star', 'triangle', 'polygon', 'ellipse', 'path', 'line', 'arc', 'pentagon', 'hexagon', 'diamond', 'arrow', 'heart'],
7666
+ enum: [...ItemTypeSchema.options],
7592
7667
  description: 'For create: item type',
7593
7668
  },
7594
7669
  position: {
@@ -7754,14 +7829,16 @@ EXAMPLES:
7754
7829
  - {platform: "instagram", format: "mp4"} — force MP4
7755
7830
  - {platform: "web", format: "svg"} — animated SVG
7756
7831
  - {platform: "youtube", format: "mp4", framing: "camera"} — render only what the camera frames during the walkthrough
7757
- - {platform: "youtube", format: "mp4", duration: 30, estimateOnly: true} — how big would that be? (renders nothing)`,
7832
+ - {platform: "youtube", format: "mp4", duration: 30, estimateOnly: true} — how big would that be, and what would it lose? (renders nothing)
7833
+
7834
+ Every export answers the second question too: where this scene loses something to the format you chose, the result carries "fidelity" naming it. Its ABSENCE means this scene has nothing that format would drop — not that the format is lossless.`,
7758
7835
  inputSchema: {
7759
7836
  type: 'object',
7760
7837
  properties: {
7761
7838
  platform: {
7762
7839
  type: 'string',
7763
- enum: ['instagram', 'instagram-story', 'tiktok', 'youtube', 'youtube-thumbnail', 'twitter', 'linkedin', 'web', 'print-a4', 'print-letter'],
7764
- description: 'Target platform for export',
7840
+ enum: ['auto', 'instagram', 'instagram-story', 'tiktok', 'youtube', 'youtube-thumbnail', 'twitter', 'linkedin', 'web', 'print-a4', 'print-letter'],
7841
+ description: "Target platform, which sets the output DIMENSIONS. 'auto' (the default) renders the canvas at its own size — use it when the canvas is already the size you want, otherwise a preset REPLACES your dimensions. Every other value forces that platform's frame regardless of the canvas.",
7765
7842
  },
7766
7843
  format: {
7767
7844
  type: 'string',
@@ -7780,7 +7857,19 @@ EXAMPLES:
7780
7857
  quality: {
7781
7858
  type: 'string',
7782
7859
  enum: ['draft', 'standard', 'high'],
7783
- description: 'Export quality level (default: standard)',
7860
+ description: 'Compression level (default: standard). It ALSO carries a default frame rate — draft 15, standard 30, high 60 — so "high" doubles the frame count and the render time against "standard" unless you set fps yourself. Set fps and scale to control those halves directly and leave quality meaning compression.',
7861
+ },
7862
+ fps: {
7863
+ type: 'integer',
7864
+ minimum: 1,
7865
+ maximum: 120,
7866
+ description: 'Video only: frames per second, overriding whatever `quality` implies. File size is bitrate x duration and does not move with fps, but the picture gets fewer bits per frame at a higher one.',
7867
+ },
7868
+ scale: {
7869
+ type: 'number',
7870
+ minimum: 0.1,
7871
+ maximum: 1,
7872
+ description: 'Video only: render at this fraction of the platform preset dimensions (0.1-1). The engine derives its encode target from RESOLUTION, so this is the size control — there is no bitrate to set, and halving the frame roughly quarters the pixels and the file. It is also the preview knob: scale 0.5 with quality "draft" is the fast look-check before committing to a full render. Rounded to even dimensions, which H.264 requires.',
7784
7873
  },
7785
7874
  framing: {
7786
7875
  type: 'string',
@@ -7789,7 +7878,7 @@ EXAMPLES:
7789
7878
  },
7790
7879
  estimateOnly: {
7791
7880
  type: 'boolean',
7792
- description: 'Preflight only — return the estimated file size for these exact settings and render nothing. Modeled for mp4/webm/gif; png/pdf/svg report confidence "none" (no dimension-based model exists for them); wav reports confidence "exact", because uncompressed PCM size is arithmetic.',
7881
+ description: 'Preflight only — return the estimated file size for these exact settings and render nothing. Modeled for mp4/webm/gif; png/pdf/svg report confidence "none" (no dimension-based model exists for them); wav reports confidence "exact", because uncompressed PCM size is arithmetic. Also answers what THIS scene would lose to this format — a png of an animated scene is one frame, a gif drops the soundtrack — under "fidelity", which is present only when there is something to lose.',
7793
7882
  },
7794
7883
  duration: {
7795
7884
  type: 'number',
@@ -7798,7 +7887,10 @@ EXAMPLES:
7798
7887
  description: 'Video duration in seconds for mp4/webm/gif (default 5). Max 60 for mp4/webm; GIF is capped at 15 because it has no bitrate target, so size scales with frames × dimensions — use mp4/webm for longer clips. Static formats ignore this. If you set play_timeline to N seconds, pass the same N here.',
7799
7888
  },
7800
7889
  },
7801
- required: ['platform'],
7890
+ // Nothing is required: platform defaults to 'auto', which is the canvas's
7891
+ // own size. Requiring it forced every caller to pick a preset, and a
7892
+ // preset silently replaces the dimensions they had already chosen.
7893
+ required: [],
7802
7894
  },
7803
7895
  },
7804
7896
  {
@@ -8196,7 +8288,7 @@ QUERIES (14):
8196
8288
  Listing:
8197
8289
  - list_types: All item types (filter by category, includeAbstract)
8198
8290
  - list_edges: All relation/edge types (filter by category)
8199
- - list_generators: the BUILT-IN background generators, from a fixed table in the engine. It is not a view of what is registered: a generator you registered at runtime will never appear here, and neither will a custom draw function. Use it to discover the built-ins and their parameters, not to check whether something exists.
8291
+ - list_generators: every generator the engine can run — the built-ins AND the registry, merged and awaited, which on a current studio is about 74 rather than the 3 this once reported. A generator you registered at runtime DOES appear. A custom draw function passed to execute_generator does not, because it was never registered; that is the one gap. If the registry chunk has not finished loading the result says partial: true and names the retry rather than presenting the built-ins as the whole set, and an older studio that cannot merge the registry answers with the built-ins under that same flag.
8200
8292
  - list_effects: All visual effect types
8201
8293
  - list_patterns: All detected design patterns
8202
8294
  - list_math_functions: All math functions used in animations