@pinepaper.studio/mcp-server 1.6.29 → 1.6.31
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.de.md +1 -1
- package/README.es.md +1 -1
- package/README.fr.md +1 -1
- package/README.hi.md +1 -1
- package/README.ja.md +1 -1
- package/README.ko.md +1 -1
- package/README.md +104 -1
- package/README.pt-BR.md +1 -1
- package/README.zh-CN.md +1 -1
- package/SECURITY.md +15 -0
- package/dist/browser/puppeteer-controller.d.ts +40 -0
- package/dist/browser/puppeteer-controller.d.ts.map +1 -1
- package/dist/browser/puppeteer-controller.js +179 -27
- package/dist/browser/puppeteer-controller.js.map +1 -1
- package/dist/build-info.json +2 -2
- package/dist/i18n/i18n-manager.d.ts.map +1 -1
- package/dist/i18n/i18n-manager.js +57 -3
- package/dist/i18n/i18n-manager.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -9
- package/dist/index.js.map +1 -1
- package/dist/ontology/upstream-vocabulary.d.ts +2 -2
- package/dist/ontology/upstream-vocabulary.js +2 -2
- package/dist/ontology/vocabulary.d.ts.map +1 -1
- package/dist/ontology/vocabulary.js +2 -0
- package/dist/ontology/vocabulary.js.map +1 -1
- package/dist/tools/batch-op-names.d.ts +27 -0
- package/dist/tools/batch-op-names.d.ts.map +1 -0
- package/dist/tools/batch-op-names.js +102 -0
- package/dist/tools/batch-op-names.js.map +1 -0
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +31 -22
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/effect-check.d.ts +1 -1
- package/dist/tools/effect-check.d.ts.map +1 -1
- package/dist/tools/effect-check.js.map +1 -1
- package/dist/tools/engine-lists.d.ts +6 -3
- package/dist/tools/engine-lists.d.ts.map +1 -1
- package/dist/tools/engine-lists.js +16 -3
- package/dist/tools/engine-lists.js.map +1 -1
- package/dist/tools/engine-methods.d.ts.map +1 -1
- package/dist/tools/engine-methods.js +3 -0
- package/dist/tools/engine-methods.js.map +1 -1
- package/dist/tools/engine-surface.d.ts +1 -1
- package/dist/tools/engine-surface.d.ts.map +1 -1
- package/dist/tools/engine-surface.js +20 -4
- package/dist/tools/engine-surface.js.map +1 -1
- package/dist/tools/handlers/generate.d.ts +2 -2
- package/dist/tools/handlers/generate.d.ts.map +1 -1
- package/dist/tools/handlers/generate.js +4 -4
- package/dist/tools/handlers/generate.js.map +1 -1
- package/dist/tools/handlers.d.ts +7 -0
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +70 -3
- package/dist/tools/handlers.js.map +1 -1
- package/dist/tools/lane.d.ts +8 -2
- package/dist/tools/lane.d.ts.map +1 -1
- package/dist/tools/lane.js +22 -3
- package/dist/tools/lane.js.map +1 -1
- package/dist/tools/p5-compat/p5-helpers.d.ts +6 -17
- package/dist/tools/p5-compat/p5-helpers.d.ts.map +1 -1
- package/dist/tools/p5-compat/p5-helpers.js +8 -1
- package/dist/tools/p5-compat/p5-helpers.js.map +1 -1
- package/dist/tools/shape-params.d.ts +2 -2
- package/dist/tools/shape-params.d.ts.map +1 -1
- package/dist/tools/shape-params.js +5 -2
- package/dist/tools/shape-params.js.map +1 -1
- package/dist/tools/stick-vocabulary.d.ts +1 -1
- package/dist/tools/stick-vocabulary.js +1 -1
- package/dist/types/code-generator.d.ts +17 -1
- package/dist/types/code-generator.d.ts.map +1 -1
- package/dist/types/code-generator.js +187 -90
- package/dist/types/code-generator.js.map +1 -1
- package/dist/types/schemas.d.ts +11 -0
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +5 -1
- package/dist/types/schemas.js.map +1 -1
- package/dist/utils/capabilities.d.ts.map +1 -1
- package/dist/utils/capabilities.js +3 -1
- package/dist/utils/capabilities.js.map +1 -1
- package/dist/utils/env.d.ts +47 -6
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +52 -6
- package/dist/utils/env.js.map +1 -1
- package/dist/utils/safe-fetch.d.ts +1 -0
- package/dist/utils/safe-fetch.d.ts.map +1 -1
- package/dist/utils/safe-fetch.js +3 -4
- package/dist/utils/safe-fetch.js.map +1 -1
- package/manifest.json +2 -2
- package/package.json +2 -2
|
@@ -3422,9 +3422,10 @@ EXAMPLE: { itemId: 'item_7', color: '#00b140', threshold: 60, smoothing: 12 }`,
|
|
|
3422
3422
|
idempotentHint: true,
|
|
3423
3423
|
openWorldHint: false,
|
|
3424
3424
|
},
|
|
3425
|
-
description: ("Audit the LIVE scene's relational structure (FxTool S12-E2) — read-only, nothing is changed. Answers \"is this scene composed with relations, or just a pile of absolutely-positioned items?\" and proposes fixes.\n\nRETURNS:\n- relations: every relation bound — [{ from, fromName?, to, type, params }], the first 200 (relationCount says how many when there are more). Use it to find the relation to change, then a batch relation op with update: true.\n- customRelations: each pinepaper_register_custom_relation definition
|
|
3426
|
-
"
|
|
3427
|
-
"
|
|
3425
|
+
description: ("Audit the LIVE scene's relational structure (FxTool S12-E2) — read-only, nothing is changed. Answers \"is this scene composed with relations, or just a pile of absolutely-positioned items?\" and proposes fixes.\n\nRETURNS:\n- relations: every relation bound — [{ from, fromName?, to, type, params }], the first 200 (relationCount says how many when there are more). Relations bound by a name pattern (\"dot-*\") are listed once per group in edit.groups instead (groupedRelations counts them). Use it to find the relation to change, then a batch relation op with update: true.\n- customRelations: each pinepaper_register_custom_relation definition the scene uses (name, params; computeFunction / app" +
|
|
3426
|
+
"lyFunction with withSource: true). registeredUnused names any registered that no relation uses.\n- edit: the exact ops that change this scene (per relation, per group with add / remove member ops, per custom motion). With only: 'edit' the reply is just this section.\n- density: { itemCount, relationalItemCount, relationalDensity (0..1 — fraction of items touching the relation graph), edgeCount, componentCount }. A low relationalDensity means items are placed by hardcoded coordinates and won't hold together if something moves.\n- suggestions: structural relations for unrelated item pairs that ALREADY sit in a structural configuration — [{ from, to, type (on_top_of/below/beside/inside/center" +
|
|
3427
|
+
"ed_on/aligned_with), params, confidence }], ranked by confidence. Apply the good ones with pinepaper_add_relation to make the layout robust.\n\nUSE WHEN:\n- After building a scene, to check it's relation-driven rather than coordinate-driven\n- To discover which items SHOULD be related (labels on shapes, a badge on a card, stacked elements) but aren't\n- Before export, as a composition-quality gate\n\nPARAMS: { eps? (bounds-match tolerance px, default 4), cap? (max suggestions, default 20), only? ('edit'), withSource? (custom relation source, default false) }"
|
|
3428
|
+
|
|
3428
3429
|
|
|
3429
3430
|
|
|
3430
3431
|
|
|
@@ -3441,6 +3442,8 @@ EXAMPLE: { itemId: 'item_7', color: '#00b140', threshold: 60, smoothing: 12 }`,
|
|
|
3441
3442
|
properties: {
|
|
3442
3443
|
eps: { type: 'number', description: 'Bounds-match tolerance in px for structural-configuration detection (default 4).' },
|
|
3443
3444
|
cap: { type: 'number', description: 'Max suggestions to return, ranked by confidence (default 20).' },
|
|
3445
|
+
only: { type: 'string', enum: ['edit'], description: "'edit': return only the edit section (the ops that change this scene)." },
|
|
3446
|
+
withSource: { type: 'boolean', description: "Include each custom relation's computeFunction / applyFunction source (default false)." },
|
|
3444
3447
|
},
|
|
3445
3448
|
},
|
|
3446
3449
|
},
|
|
@@ -3471,13 +3474,14 @@ EXAMPLE: { itemId: 'item_7', color: '#00b140', threshold: 60, smoothing: 12 }`,
|
|
|
3471
3474
|
"tem.data, so the text can quote live state (\"Score: {score}\") instead of a literal fixed when you authored it.\n · on_event_increment (params: property, by) / on_event_toggle — counters and flip-flops.\n · on_event_fire_after (params: delay, timeline) — chain one beat to the next.\n · on_event_fire_if (params: predicate, event, else?) — the only reaction that TESTS graph state rather than mutating it. When the source fires it evaluates params.predicate and pulses the EVENT params.event if it holds (params.else if not); its target is not fired, so the visible change comes from a reaction on that second event. params.predicate is an ExpressionIR object, not a string: { op:'const', value" +
|
|
3472
3475
|
" } · { op:'cmp', cmp: eq|neq|gt|gte|lt|lte, a, b } · { op:'logic', logic: and|or|not, args:[…] } · { op:'graph', read: data|active|visible, item, property } (data reads item.data[property]). A string predicate, or no event, is refused.\n · on_event_add_relation / on_event_remove_relation — the scene rewires itself.\n · on_event_play_sound (source = the EVENT, target null; params: sound, gain?, note?) — play a sound when the event fires: a catalogue name (effect, drum or instrument; aliases accepted) or a define_sfx spec; gain is a multiplier capped at full scale; note is for instruments (default C5). An unknown sound is refused with the catalogue. Wire a click sound as on_click_fire (but" +
|
|
3473
3476
|
"ton → event) + on_event_play_sound (event → null). For a sound at a TIME, pinepaper_event create { at: seconds | [seconds] } fires the event on the timeline (and in video exports); a scene chain's cutSound puts one on every cut. LIMITS: the exported widget player does not run timed triggers, and a browser may block sound until the viewer's first click or key.\n · on_event_store_set / on_event_store_increment / restores_from — persistent state. The target is a store node whose id is the storage SCOPE, so two stores in a scene and two widgets on a page do not collide. restores_from is the read half and fires ONCE at load.\n- Proximity (pointer over an item): on_enter_* / on_exit_* mirror th" +
|
|
3474
|
-
"e on_event_* reactions above (set_color, set_property, set_property_from_template, set_visibility, set_data, increment, toggle) — hover states without a single line of script.\n- Exclusive state: exclusive_group makes at most one member active
|
|
3475
|
-
"
|
|
3476
|
-
"
|
|
3477
|
-
"
|
|
3478
|
-
"
|
|
3479
|
-
"
|
|
3480
|
-
"
|
|
3477
|
+
"e on_event_* reactions above (set_color, set_property, set_property_from_template, set_visibility, set_data, increment, toggle) — hover states without a single line of script.\n- Exclusive state: exclusive_group makes at most one member active — tabs, steppers, quiz cards. MEMBERSHIP is pairwise: bind exclusive_group from one member to each other member with the same relationOptions.groupName (default '_default'); nothing else adds an item to the group. Being active has NO LOOK OF ITS OWN: give each member on_enter_set_property / on_exit_set_property (say opacity 1 / 0.3), with the member as both source and target, and those reactions draw the change, in exports too. on_event_set_active ac" +
|
|
3478
|
+
"tivates its target. on_event_step_active moves the active member by relationOptions.delta (default +1) for next / previous arrows, wrapping unless wrap: false; a current studio runs it with no target, an older one needs a targetId (any item, e.g. one member) and is refused without one, and its relationOptions.items only sets the step order of items already in the group. menubar_group is the same grouping WITHOUT the mutex.\n\nThere are 80 relation types and this list names the families rather than every member. For the live catalogue — what exists in THIS build, with definitions — call pinepaper_query_capabilities { kind: 'relation' }, which reads the engine's registry rather than a list w" +
|
|
3479
|
+
"ritten down here.\n\nRELATION COMPATIBILITY:\n- Universal relations (position-based) work with ALL item types including imported SVGs/images:\n orbits, follows, attached_to, maintains_distance, points_at, mirrors, parallax, bounds_to\n- morphs_to has type-specific behavior:\n Path→Path: point interpolation\n Circle→Circle: radius interpolation\n Text→Text: font blend\n Cross-type: particle denoising transition\n- group_morphs_to: pair-by-index morph between two paper.Groups (any two — graph vertices+edges, letter collages, dashboard clusters). Path.Line children deform via endpoints; other children translate; excess children fade. Params: duration, hold, loop, easing (linear|easeIn|ea" +
|
|
3480
|
+
"seOut|easeInOut), deformLines.\n- moves_along_path: self-relation (targetId=null); item is driven along a path. Source the path EITHER from params.path (array of {x,y} or [x,y]) OR from params.equation (S10 B5) — a math curve the item TRAVERSES, sampled deterministically on the Expression IR: params.equation = { kind: function|parametric|fourier|preset, expr | xExpr/yExpr | harmonics | preset, min, max, samples, scale, cx, cy, flipY, warp } (same equation contract as pinepaper_equation_path, but origin is cx/cy, default 0). y is MATH-UP by default (flipY: true): on screen the curve is mirrored about cy, so a curve written in screen coordinates (y down) needs flipY: false. Params: path OR e" +
|
|
3481
|
+
"quation, speed, closed, phase, easing (linear|easeIn|easeOut|easeInOut|sine|bounce|pingpong).\n\nGEOMETRIC CONSTRUCTION CONSTRAINTS (Layer 2) — the source item is RE-DERIVED every frame from its anchor item(s), so dragging an anchor updates the dependent live (GeoGebra-style), and the construction persists as relation graph data (edit it by editing relations, not by re-running code). Anchor A is the relation target; extra anchors ride in params:\n- is_midpoint_of: source = midpoint(target, params.other). params.other = id of the second endpoint (B).\n- lies_on_line: source held on the line target→params.other at fraction params.t (0=A, 1=B; default 0.5). params.other (B), params.t.\n- is_c" +
|
|
3482
|
+
"entroid_of: source = centroid(target, ...params.others). params.others = array of the remaining point ids.\n- is_circumcenter_of: source = circumcenter(target, params.other1, params.other2); holds position when the three anchors are collinear. params.other1 (B), params.other2 (C).\n- concentric_with: source stays centered on the target (shared center).\n- construction_reveal: self-relation (targetId=null); opacity 0→1 starting at params.revealAt (timeline seconds) over params.fadeIn seconds — loop- and scrub-correct. Pair with pinepaper_construction_sequence to reveal a figure one step at a time.\n\nPROCEDURAL / DETERMINISTIC BINDING (Expression IR — S10 G1) — bind a property to another pr" +
|
|
3483
|
+
"operty or to a math function of time. Pass params.signal:true to route through the pure, seed/frame-deterministic signal interpreter (replay-stable — same time → identical output); omit it for the per-frame compute fallback.\n- driven_by: source's sourceProperty = target's targetProperty * multiplier + offset (optionally clamped). sourceProperty ∈ x|y|rotation|opacity|scale|strokeWidth|fillColor|strokeColor; targetProperty ∈ x|y|rotation|opacity|scale. For fillColor/strokeColor the (clamped 0..1) driven value interpolates colorFrom→colorTo — so a relation drives COLOR. NEEDS a target (the property source). params: sourceProperty, targetProperty, multiplier, offset, clamp {min,max}, colorFr" +
|
|
3484
|
+
"om, colorTo, signal. e.g. tint a dot by a planet's x: sourceProperty 'fillColor', targetProperty 'x', colorFrom '#0055ff', colorTo '#ff3300', signal true.\n- time_expression: self-relation (targetId=null); the source's params.property (x, y, rotation, opacity or scale) is driven by a formula of t (scene time) and v (params.baseValue). params: property (default 'y'), expression (e.g. 'sin(t*2)*50 + v'), baseValue, signal (true also evaluates it as a pure f(t) via the Expression IR). The formula grammar: " +
|
|
3481
3485
|
String(expressionGrammarText()) +
|
|
3482
3486
|
". A name outside it, or a wrong argument count, is refused by name: it would parse to nothing and the item would not move.\n\nEVENT-DRIVEN SCENE CHAINS (S11) — build a LONG scene as a graph of timed events, not a keyframe track. First make events with pinepaper_event (action:'create' → eventId). The relations below have an EVENT as their sourceId; firing the event runs the reaction. Chain beats over animation time with on_event_fire_after (timeline:'canvas'), have beats mutate the scene with on_event_add_relation, then kick it off with pinepaper_event action:'pulse'. Because canvas-timed fires are on the animation clock, the whole chain is scrub-, loop-, and replay-stable.\n- on_event_fire" +
|
|
3483
3487
|
"_after: sourceId=event, targetId=the NEXT event. When source fires, pulse target after params.delay ms. params.timeline: 'canvas' (animation clock — use for scene chains) | 'wall' (real setTimeout). This is the chaining primitive.\n- on_event_fire_if: sourceId=event, targetId=any item (it is not fired). params.event = the event to pulse when params.predicate holds, params.else = the one when it does not. A branch is two relations: A —on_event_fire_if { predicate, event: B }→ any item; B —on_event_set_color→ lamp. Example predicate, \"score is at least 3\": { op:'cmp', cmp:'gte', a:{ op:'graph', read:'data', item:'item_3', property:'score' }, b:{ op:'const', value:3 } }.\n- on_event_add_rel" +
|
|
@@ -3571,7 +3575,6 @@ String(expressionGrammarText()) +
|
|
|
3571
3575
|
|
|
3572
3576
|
|
|
3573
3577
|
|
|
3574
|
-
|
|
3575
3578
|
|
|
3576
3579
|
|
|
3577
3580
|
),
|
|
@@ -3588,7 +3591,7 @@ String(expressionGrammarText()) +
|
|
|
3588
3591
|
},
|
|
3589
3592
|
relationType: {
|
|
3590
3593
|
type: 'string',
|
|
3591
|
-
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
3594
|
+
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_step_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
3592
3595
|
description: 'Type of relationship. A name registered with pinepaper_register_custom_relation in this session is accepted too.',
|
|
3593
3596
|
},
|
|
3594
3597
|
params: {
|
|
@@ -3631,7 +3634,7 @@ USE WHEN:
|
|
|
3631
3634
|
targetId: { type: 'string', description: 'Target item ID' },
|
|
3632
3635
|
relationType: {
|
|
3633
3636
|
type: 'string',
|
|
3634
|
-
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
3637
|
+
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_step_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
3635
3638
|
description: 'Specific relation type to remove (optional - removes all if not specified)',
|
|
3636
3639
|
},
|
|
3637
3640
|
},
|
|
@@ -3659,7 +3662,7 @@ USE WHEN:
|
|
|
3659
3662
|
itemId: { type: 'string', description: 'Item to query relations for' },
|
|
3660
3663
|
relationType: {
|
|
3661
3664
|
type: 'string',
|
|
3662
|
-
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
3665
|
+
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_step_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
3663
3666
|
description: 'Filter by relation type (optional)',
|
|
3664
3667
|
},
|
|
3665
3668
|
direction: {
|
|
@@ -3900,9 +3903,9 @@ USE WHEN:
|
|
|
3900
3903
|
"survives into the design graph, save/reload and widget export, which keyframes generated from a formula do not describe.\n- 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.\n- 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 N" +
|
|
3901
3904
|
"O 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).\n\n- 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" +
|
|
3902
3905
|
", 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.\n\nKeyframes 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.\n\nANIMATABLE PROPERTIES:\n- position: [x, y] array (a { x, y } object is also accepted and normalized)\n- x, y: Individual coordinates\n- scale: Uniform scale\n- scaleX, scaleY: Axis scaling\n- rotation: Degrees\n- opacity: 0-1\n- fillColor: Color string\n- strokeColor: Color string\n- strokeWidth, width, height, radius, shadowBlur" +
|
|
3903
|
-
", shadowColor: Numbers / colours\n- fontSize: Number\n- TEXT (current studio): fontStyle ('normal' / 'italic' / 'oblique', discrete — switches at the next key), textAlign ('left' / 'center' / 'right', discrete; the anchor stays put), lineHeight (px, or a multiple of fontSize up to 5), letterSpacing (px, or a CSS length such as '0.1em'). An older studio stores these keys without drawing them; the result names any it did not animate (ignoredProperties).
|
|
3904
|
-
"s length), trimOffset (shifts the visible window along it), dashArray. A draw-on is trimEnd 0 -> 1.\nThe authoritative list for a given item is pinepaper_get_animatable_properties — ask it rather than guessing.\n\nEASING — BY DEFAULT IT SHAPES THE SEGMENT ARRIVING AT THE KEYFRAME IT IS ON.\nThe move from keyframe A to keyframe B is eased by B's easing, not A's. So by default the FIRST keyframe's easing has no effect (no segment arrives at it) — a Ken Burns with
|
|
3905
|
-
"
|
|
3906
|
+
", shadowColor: Numbers / colours\n- fontSize: Number\n- skewX, skewY (current studio): degrees, clamped to ±89; they combine with rotation and scale. An older studio stores them without drawing and the result names them in ignoredProperties; there, a shear is a transform matrix track.\n- TEXT (current studio): fontStyle ('normal' / 'italic' / 'oblique', discrete — switches at the next key), textAlign ('left' / 'center' / 'right', discrete; the anchor stays put), lineHeight (px, or a multiple of fontSize up to 5), letterSpacing (px, or a CSS length such as '0.1em'). An older studio stores these keys without drawing them; the result names any it did not animate (ignoredProperties). fontWeigh" +
|
|
3907
|
+
"t keys STEP: a font with fixed weights switches from one weight to the next once, partway through the move, and does not ramp. Key fontSize or scale for a smooth change.\n- STROKE DRAW-ON (paths): trimStart, trimEnd (0-1 of the path's length), trimOffset (shifts the visible window along it), dashArray. A draw-on is trimEnd 0 -> 1.\nThe authoritative list for a given item is pinepaper_get_animatable_properties — ask it rather than guessing.\n\nEASING — BY DEFAULT IT SHAPES THE SEGMENT ARRIVING AT THE KEYFRAME IT IS ON.\nThe move from keyframe A to keyframe B is eased by B's easing, not A's. So by default the FIRST keyframe's easing has no effect (no segment arrives at it) — a Ken Burns with" +
|
|
3908
|
+
" easing only on its first key plays linear. Put the easing on the key you are moving TO, or pass easingAt: 'departure' for the other reading: each key's easing shapes the move LEAVING it, so the first key's easing eases the first move (current studio; an older one reads arrival and the result says so). 'hold' / 'step' stay on the key they mark either way.\n" +
|
|
3906
3909
|
String(EASING_LINES) +
|
|
3907
3910
|
"\n- or a custom cubic-bezier [x1, y1, x2, y2] — x in 0..1, y may exceed 0..1 for overshoot. keyframe_animate and camera_animate only.\nCOUNTERS: a text item with a counter (create_item / modify_item counter) also animates the numeric property counterValue, drawn through the counter's format — keyframe it to shape a count by hand (hold on a number, then race). Its keys override the counter's own from / to.\n\nHOLD KEYS (where the studio has them): interpolation: 'hold' on a key holds ITS value until the next key, then cuts — no in-between. Easing 'hold' / 'step' on the ARRIVING key does the same. A studio without hold keys refuses rather than interpolate; there, two keys a frame apart make " +
|
|
3908
3911
|
"the cut. For a whole layer 'on twos', set stepTiming on the item (create_item / modify_item). A DISCRETE change (a bar turning red at 2 s, a label switching colour) needs this too: without hold / step every key ramps from the one before it, so the colour fades across the whole gap instead of switching. This applies to batch keyframe ops the same way.\n\nEvery easing renders exactly in video, GIF and APNG. Lottie and CSS get the closest single Bézier: springPlayful loses its wobble, and the in-out quart/quint/expo/circ curves are within 2–4 %. SMIL is exact for springs and those four.\n\nCLIP WINDOW (optional — Premiere/Canva-style clip behavior):\n- timeOffset: Shift the whole clip in canv" +
|
|
@@ -3945,6 +3948,7 @@ String(EASING_LINES) +
|
|
|
3945
3948
|
|
|
3946
3949
|
|
|
3947
3950
|
|
|
3951
|
+
|
|
3948
3952
|
|
|
3949
3953
|
|
|
3950
3954
|
),
|
|
@@ -4607,7 +4611,7 @@ Needs a studio that publishes the item-side table; without one, the tool says so
|
|
|
4607
4611
|
target: { type: 'string', description: 'Name of target item' },
|
|
4608
4612
|
type: {
|
|
4609
4613
|
type: 'string',
|
|
4610
|
-
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
4614
|
+
enum: ['orbits', 'follows', 'attached_to', 'maintains_distance', 'points_at', 'mirrors', 'parallax', 'bounds_to', 'anchored_in_world', 'spring_follow', 'repels', 'attracts', 'wiggle', 'animates', 'grows_from', 'staggered_with', 'indicates', 'circumscribes', 'wave_through', 'morphs_to', 'group_morphs_to', 'moves_along_path', 'construction_reveal', 'triggers_animation', 'syncs_with', 'tours', 'synced_to_audio', 'localizes_sound', 'expresses', 'camera_follows', 'camera_animates', 'is_midpoint_of', 'lies_on_line', 'is_centroid_of', 'is_circumcenter_of', 'concentric_with', 'driven_by', 'time_expression', 'on_click_fire', 'on_pointer_enter_fire', 'on_pointer_exit_fire', 'on_key_fire', 'on_event_fire_after', 'on_event_fire_if', 'on_event_add_relation', 'on_event_remove_relation', 'on_event_set_color', 'on_event_set_property', 'on_event_set_property_from_template', 'on_event_set_visibility', 'on_event_set_active', 'on_event_step_active', 'on_event_set_data', 'on_event_increment', 'on_event_toggle', 'on_event_store_set', 'on_event_store_increment', 'on_event_play_sound', 'looks_at', 'reacts_to', 'drag_to_turn', 'on_enter_set_color', 'on_enter_set_property', 'on_enter_set_property_from_template', 'on_enter_set_visibility', 'on_enter_set_data', 'on_enter_increment', 'on_enter_toggle', 'on_exit_set_color', 'on_exit_set_property', 'on_exit_set_property_from_template', 'on_exit_set_visibility', 'on_exit_set_data', 'on_exit_increment', 'on_exit_toggle', 'exclusive_group', 'menubar_group', 'restores_from', 'on_top_of', 'below', 'beside', 'inside', 'centered_on', 'aligned_with', 'part_of', 'connects_to', 'attached_to_tail', 'head_points_to'],
|
|
4611
4615
|
},
|
|
4612
4616
|
params: {
|
|
4613
4617
|
type: 'object',
|
|
@@ -8738,10 +8742,10 @@ EXAMPLES:
|
|
|
8738
8742
|
"S may fail).\n\nONTOLOGY PREFLIGHT: Before code generation, this tool validates itemType, relationType, effectType, and generatorName against the canonical PinePaper vocabulary. A typo (e.g. \"circel\") returns a structured VALIDATION_ERROR with the operation index, the offending field, the canonical valid list, and a suggested fix — fix and retry rather than guessing. Pass skipValidation: true to bypass when intentionally using experimental vocabulary.\n\nWORKFLOW:\n1. pinepaper_agent_start_job → 2. the craft tools that fit the brief (styled_scene, story, character, text_style, compose…) → 3. pinepaper_agent_batch_execute (the primitive glue, in one call) → 4. pinepaper_agent_end_job (scr" +
|
|
8739
8743
|
"eenshot for validation)\nAfter validation: user reviews screenshot → feedback → modify/recreate as needed.\n\nOPERATION TYPES (" +
|
|
8740
8744
|
String(AgentBatchOperationTypeSchema.options.length) +
|
|
8741
|
-
") — use in this order:\n\nCANVAS SETUP:\n set_canvas_size — {width, height} or {preset: \"instagram-post\"|\"instagram-story\"|\"youtube-thumbnail\"|\"tiktok\"|\"full-hd-1080p\"|...} (studio preset keys, not platform names; an unknown one is refused with the list)\n set_background — {backgroundColor: \"#hex\"}\n execute_generator — {generatorName,
|
|
8742
|
-
"
|
|
8743
|
-
"
|
|
8744
|
-
"
|
|
8745
|
+
") — use in this order:\nEach op also takes its standalone tool's names: params (relation, apply_effect, execute_generator), preset / options (apply_mask), region (execute_generator), intensity / speed / delay / waveform / origin (animate, at the top or in animationOptions), and a modify op's changes flat beside itemId. The reply lists what it translated.\n\nCANVAS SETUP:\n set_canvas_size — {width, height} or {preset: \"instagram-post\"|\"instagram-story\"|\"youtube-thumbnail\"|\"tiktok\"|\"full-hd-1080p\"|...} (studio preset keys, not platform names; an unknown one is refused with the list)\n set_background — {backgroundColor: \"#hex\"}\n execute_generator — {generatorName, generatorPa" +
|
|
8746
|
+
"rams} → fills canvas with procedural art (paints WITHOUT fully registering items — see get_items; custom generator names need skipValidation:true)\n Generators: drawBokeh, drawGradientMesh, drawWaves, drawSunburst, drawSunsetScene, drawGrid, drawCircuit, drawPattern, drawStackedCircles, drawGeometricAbstract, drawWindField, drawFluidFlow, drawOrganicFlow, drawNoiseTexture, drawGlobeWireframe\n PineMath: drawFunctionPlot (y=f(x) plots), drawParametricCurve (x(t),y(t)), drawSimulation (pendulum, Lorenz, spring-mass), drawSpectrumAnalyzer (FFT), draw3DSurface (torus, sphere, Klein bottle)\n\nITEMS:\n create — {itemType, position: {x,y} or [x,y], properties}\n itemType: text, circle," +
|
|
8747
|
+
" rectangle, star, triangle, polygon, ellipse, path, line, arc, pentagon, hexagon, diamond, arrow, heart\n Properties per type:\n text: {content, fontSize, fontFamily, color, fontWeight}\n circle: {radius, color, strokeColor, strokeWidth}\n rectangle: {width, height, color, cornerRadius}\n star: {radius1, radius2, points, color}\n ellipse: {radiusX, radiusY, color}\n triangle/polygon: {width/sides, height/radius, color}\n All: opacity, shadowColor, shadowBlur, blendMode, strokeColor, strokeWidth\n modify — {itemId, properties} — instant reposition/restyle. To MOVE an item, set {x,y} here (a one-shot position change, not an animation).\n delete — {itemId" +
|
|
8748
|
+
"}\n group — {itemIds: [\"$0\",\"$1\",...], groupName} — combine the parts of a composite object into ONE draggable/animatable entity. ALWAYS group a specific named object (car, robot, house, character) after creating its parts. Returns {groupId}, and the group takes the next \"$N\" like a create; safe — user can ungroup. Do NOT group a whole scene whose pieces move independently.\n\nANIMATION:\n animate — Loop animation: {itemId, animationType, animationOptions}\n animationType: " +
|
|
8745
8749
|
String(SIMPLE_ANIMATION_TYPES_LIST) +
|
|
8746
8750
|
"\n keyframe_animate — Timed animation: {itemId, keyframes: [{time, properties, easing}], duration, loop, append}. Replaces the item's track unless append: true (or mode: 'merge', the studio's spelling); two ops on one item in a batch are merged into one.\n Animatable properties: opacity, scale, scaleX, scaleY, x, y, rotation, fillColor, strokeColor, strokeWidth, width, height, radius, fontSize, trimStart/trimEnd/trimOffset (path draw-on)\n Easing (on the keyframe being moved TO): " +
|
|
8747
8751
|
String(KEYFRAME_EASINGS_LIST) +
|
|
@@ -8812,6 +8816,7 @@ String(EFFECT_TYPES_LIST) +
|
|
|
8812
8816
|
|
|
8813
8817
|
|
|
8814
8818
|
|
|
8819
|
+
|
|
8815
8820
|
|
|
8816
8821
|
|
|
8817
8822
|
),
|
|
@@ -8951,6 +8956,10 @@ String(EFFECT_TYPES_LIST) +
|
|
|
8951
8956
|
type: 'boolean',
|
|
8952
8957
|
description: 'Skip the ontology preflight that catches vocabulary typos before browser execution (default: false). Only set true when knowingly using experimental values.',
|
|
8953
8958
|
},
|
|
8959
|
+
verbose: {
|
|
8960
|
+
type: 'boolean',
|
|
8961
|
+
description: 'One result entry per operation. By default an entry that only echoes the id, type and position you sent is left out (itemIds lists every id; resultsOmitted counts them); failures and anything with a note are kept.',
|
|
8962
|
+
},
|
|
8954
8963
|
},
|
|
8955
8964
|
required: ['operations'],
|
|
8956
8965
|
},
|