@pinepaper.studio/mcp-server 1.6.9 → 1.6.10
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 +118 -3
- package/dist/agent/export-manager.d.ts.map +1 -1
- package/dist/agent/export-manager.js +5 -3
- package/dist/agent/export-manager.js.map +1 -1
- package/dist/browser/puppeteer-controller.d.ts.map +1 -1
- package/dist/browser/puppeteer-controller.js +128 -3
- package/dist/browser/puppeteer-controller.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +31 -3
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/engine-surface.d.ts +30 -0
- package/dist/tools/engine-surface.d.ts.map +1 -0
- package/dist/tools/engine-surface.js +1188 -0
- package/dist/tools/engine-surface.js.map +1 -0
- package/dist/tools/handlers/font.d.ts.map +1 -1
- package/dist/tools/handlers/font.js +77 -10
- package/dist/tools/handlers/font.js.map +1 -1
- package/dist/tools/handlers.d.ts +16 -0
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +117 -4
- package/dist/tools/handlers.js.map +1 -1
- package/dist/types/code-generator.d.ts.map +1 -1
- package/dist/types/code-generator.js +363 -80
- package/dist/types/code-generator.js.map +1 -1
- package/dist/types/schemas.d.ts +44 -39
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +19 -3
- package/dist/types/schemas.js.map +1 -1
- package/manifest.json +1 -1
- package/package.json +5 -2
|
@@ -3117,6 +3117,14 @@ USE WHEN:
|
|
|
3117
3117
|
- Prototyping new features
|
|
3118
3118
|
- A scene whose repetition is the point: dozens of items built in a loop. This is the cheapest route by an order of magnitude — a 63-item animated scene is ~4k characters here against ~147k as keyframe tool calls — because the loop collapses the repetition instead of restating it per item. Synchronous build work is bounded by the governor's 4s deadline, which such a scene fits easily.
|
|
3119
3119
|
|
|
3120
|
+
ENGINE SEMANTICS THAT BITE RAW-JS AUTHORS. The tool schemas protect tool callers from these; writing JS opts out of that protection, and each of these fails SILENTLY:
|
|
3121
|
+
- app.create() returns a Paper.js item whose .id is a NUMBER. The id every tool and relation wants is the STRING at item.data.registryId ('item_1'). Passing the number to addAnimation throws "Cannot create property 'data' on number".
|
|
3122
|
+
- app.create() with an unknown type returns undefined and creates nothing — 'rect' is not 'rectangle'. The schema catches that for tool callers; a loop does not.
|
|
3123
|
+
- app.addAnimation(id, keyframeArray, options) takes a real ARRAY. A JSON string installs nothing, silently, and the scene exports frozen. It also returns without error on an id that does not resolve.
|
|
3124
|
+
- Keyframes live at item.data.keyframes. app.keyframeItems is not the live store, so probing it reports false negatives.
|
|
3125
|
+
- transformOrigin is IGNORED by the keyframe engine: rotation always pivots on the item centre. For true joint pivots use pinepaper_rigging bones, or keyframe computed x/y per joint.
|
|
3126
|
+
- Bone angles are RADIANS in the engine and relative to the parent, though pinepaper_rigging converts degrees for you — that conversion is the tool's, not the engine's.
|
|
3127
|
+
|
|
3120
3128
|
WHAT THE CHEAP ROUTE COSTS, so the choice is deliberate: items built and animated in raw JS carry NO behavioral record. No graph edge, nothing SMIL or widget export can lift, nothing the ontology can read — the scene renders and cannot describe itself. Relations are the canonical behavior surface here, so for motion that is a function of time prefer pinepaper_add_relation with 'time_expression' (still ~5.7x cheaper than keyframes), and for a whole group moving together staggered_with or wave_through. Reach for a loop when the geometry is procedural, not merely to avoid the typing.
|
|
3121
3129
|
|
|
3122
3130
|
AVAILABLE GLOBALS:
|
|
@@ -3247,6 +3255,8 @@ BEFORE AUTHORING DENSE TRACKS — three routes are cheaper, and two of them keep
|
|
|
3247
3255
|
- PER-ITEM VARIATION across many items → staggered_with or wave_through express the whole group in ONE call. That collapses the 63-fold repetition a per-item time_expression still pays for.
|
|
3248
3256
|
- GENUINELY PROCEDURAL scenes → pinepaper_execute_custom_code with app.create + app.addAnimation (which attaches keyframe tracks programmatically, so the keyframes are generated rather than typed), at 4k characters for the same scene — cheapest by an order of magnitude, because a loop collapses the repetition entirely. The trade is real and worth making deliberately: raw JS leaves NO behavioral record — no graph edge, nothing SMIL or widget export can lift, nothing the ontology can read. Scene building fits the governor's 4s synchronous deadline easily (it is the injected loop guards, not the 10s async-tail budget, that bites a build loop).
|
|
3249
3257
|
|
|
3258
|
+
- TEXT THAT CHANGES OVER TIME -> 'content' IS keyframeable, and it is DISCRETE: it holds the current word until the next keyframe and does not tween. One thing worth knowing before you build a cascade out of it. A cascade of N words is N keyframes you have to write out, which is the reason to prefer the call below rather than any limitation. For the common case prefer pinepaper_execute_custom_code with app.textSequence(itemOrId, words, { interval }): ONE item cycling its words in one call, against one item per word with opacity tracks faking the cut. It returns { ok: false, reason } on an id it cannot resolve.
|
|
3259
|
+
|
|
3250
3260
|
Keyframes are for motion that is AUTHORED, not computed. A track of hundreds of entries produced from a formula is the signal that one of the three above is the right route.
|
|
3251
3261
|
|
|
3252
3262
|
ANIMATABLE PROPERTIES:
|
|
@@ -3563,7 +3573,9 @@ Requires maskType and keyframes array.`,
|
|
|
3563
3573
|
idempotentHint: true,
|
|
3564
3574
|
openWorldHint: false,
|
|
3565
3575
|
},
|
|
3566
|
-
description: `[Utility]
|
|
3576
|
+
description: `[Utility] MASK properties only, despite the name: which properties each MASK TYPE can animate.
|
|
3577
|
+
|
|
3578
|
+
If you are asking what you can animate on a canvas ITEM, this is the wrong tool and its name will not tell you so. The item-side list lives in pinepaper_keyframe_animate's ANIMATABLE PROPERTIES section, and two entries there are DISCRETE rather than interpolated - content and blendMode hold their value until the next keyframe instead of blending toward it. Treating content as tweenable is what makes every word in a cycler appear half a beat early.`,
|
|
3567
3579
|
inputSchema: {
|
|
3568
3580
|
type: 'object',
|
|
3569
3581
|
properties: {},
|
|
@@ -6346,9 +6358,15 @@ ACTIONS:
|
|
|
6346
6358
|
idempotentHint: false,
|
|
6347
6359
|
openWorldHint: false,
|
|
6348
6360
|
},
|
|
6349
|
-
description: `
|
|
6361
|
+
description: `Fonts: which ones you can USE, and authoring new ones.
|
|
6350
6362
|
|
|
6351
|
-
|
|
6363
|
+
Most of this tool is glyph authoring — drawing a typeface. If you just want to know what font families are available to set on a text item, that is ONE action:
|
|
6364
|
+
|
|
6365
|
+
- list_available — { category?, loadedOnly? } every family the studio can render, with whether its file is loaded yet
|
|
6366
|
+
- check — { name, text? } is this family really there, and can it draw THIS string? Pass the text: a font with four glyphs is installed and will still render most characters in the fallback face, and that second answer is the one that decides the pixels. Do NOT rely on document.fonts.check() — it returns true for a family that does not exist.
|
|
6367
|
+
- fallbacks — {} which text items on the canvas are silently drawing in something other than the family they asked for
|
|
6368
|
+
|
|
6369
|
+
ACTIONS (authoring):
|
|
6352
6370
|
- show_studio — {} open the Font Studio UI
|
|
6353
6371
|
- set_name — { name } name the in-progress font
|
|
6354
6372
|
- get_required_chars — { set?: string } list chars to draw (default: minimum)
|
|
@@ -6371,6 +6389,7 @@ ACTIONS:
|
|
|
6371
6389
|
action: {
|
|
6372
6390
|
type: 'string',
|
|
6373
6391
|
enum: [
|
|
6392
|
+
'list_available', 'check', 'fallbacks',
|
|
6374
6393
|
'show_studio', 'set_name', 'get_required_chars', 'get_status',
|
|
6375
6394
|
'create_glyph', 'create_space', 'remove_glyph', 'set_metrics',
|
|
6376
6395
|
'export', 'load_into_document', 'export_data', 'import_data',
|
|
@@ -6378,6 +6397,9 @@ ACTIONS:
|
|
|
6378
6397
|
],
|
|
6379
6398
|
description: 'Font Studio action',
|
|
6380
6399
|
},
|
|
6400
|
+
text: { type: 'string', description: 'check: the string you intend to draw. Without it you learn only whether the family is installed, not whether it has glyphs for your characters.' },
|
|
6401
|
+
category: { type: 'string', description: 'list_available: narrow to one category (e.g. display, serif, mono).' },
|
|
6402
|
+
loadedOnly: { type: 'boolean', description: 'list_available: only families whose font file has already loaded. Unloaded ones still render once the studio fetches them.' },
|
|
6381
6403
|
name: { type: 'string', description: 'Font name (set_name)' },
|
|
6382
6404
|
set: { type: 'string', description: 'Character set name (get_required_chars; default "minimum")' },
|
|
6383
6405
|
character: { type: 'string', description: 'Single-character glyph identifier (create_glyph, remove_glyph)' },
|
|
@@ -7664,6 +7686,12 @@ Held exports last until released, or until a LATER export needs the space — an
|
|
|
7664
7686
|
},
|
|
7665
7687
|
description: `Smart export with automatic format detection and platform optimization.
|
|
7666
7688
|
|
|
7689
|
+
WHAT quality ACTUALLY SETS, because it bundles three things and only one of them is "quality": draft = 15fps / 72dpi / compression 0.6, standard = 30fps / 150dpi / 0.85, high = 60fps / 300dpi / 0.95. So asking for high DOUBLES the frame count and the render time against standard. Override either half directly - fps for frame rate, scale for resolution - and leave quality to mean compression.
|
|
7690
|
+
|
|
7691
|
+
DOES THIS SURVIVE EXPORT? It is a PATH fact, not a per-feature one, so the rule is short and does not go stale as capabilities land: IF IT TICKS INSIDE THE ENGINE'S UPDATE LOOP, IT EXPORTS. Loop animations, relations, keyframes, generators and camera moves all do - measured frame-by-frame, not assumed. What does NOT survive is anything driven by the wall clock outside that loop, or anything on the realtime recorder path.
|
|
7692
|
+
|
|
7693
|
+
If exported frames look frozen, check the SAMPLING before believing it: a loop animation at animationSpeed 1 has a one-second period, so two frames a whole second apart are identical by design. Compare frames that are not a whole number of periods apart.
|
|
7694
|
+
|
|
7667
7695
|
PLATFORMS & OPTIMAL FORMATS:
|
|
7668
7696
|
| Platform | Dimensions | Static | Animated |
|
|
7669
7697
|
|-----------------|------------|--------|----------|
|