@pinepaper.studio/mcp-server 1.6.27 → 1.6.28
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 +85 -2
- package/SECURITY.md +4 -3
- package/dist/build-info.json +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -3
- 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/tools/choreograph.d.ts.map +1 -1
- package/dist/tools/choreograph.js +7 -0
- package/dist/tools/choreograph.js.map +1 -1
- package/dist/tools/definitions.d.ts.map +1 -1
- package/dist/tools/definitions.js +35 -18
- package/dist/tools/definitions.js.map +1 -1
- package/dist/tools/engine-lists.d.ts +11 -4
- package/dist/tools/engine-lists.d.ts.map +1 -1
- package/dist/tools/engine-lists.js +49 -4
- 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 +1 -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 +16 -4
- package/dist/tools/engine-surface.js.map +1 -1
- package/dist/tools/export-file-receipt.d.ts +21 -0
- package/dist/tools/export-file-receipt.d.ts.map +1 -1
- package/dist/tools/export-file-receipt.js +36 -13
- package/dist/tools/export-file-receipt.js.map +1 -1
- package/dist/tools/handlers/export.d.ts.map +1 -1
- package/dist/tools/handlers/export.js +6 -2
- package/dist/tools/handlers/export.js.map +1 -1
- package/dist/tools/handlers/generate.js +2 -2
- package/dist/tools/handlers/generate.js.map +1 -1
- package/dist/tools/handlers.d.ts +5 -0
- package/dist/tools/handlers.d.ts.map +1 -1
- package/dist/tools/handlers.js +13 -0
- package/dist/tools/handlers.js.map +1 -1
- package/dist/tools/lane.d.ts +7 -3
- package/dist/tools/lane.d.ts.map +1 -1
- package/dist/tools/lane.js +20 -5
- package/dist/tools/lane.js.map +1 -1
- package/dist/tools/scene-cache-export.d.ts.map +1 -1
- package/dist/tools/scene-cache-export.js +8 -4
- package/dist/tools/scene-cache-export.js.map +1 -1
- package/dist/tools/shape-params.d.ts +2 -2
- package/dist/tools/shape-params.js +2 -2
- package/dist/tools/stick-vocabulary.d.ts +1 -1
- package/dist/tools/stick-vocabulary.js +1 -1
- package/dist/tools/toolkits.d.ts +1 -1
- package/dist/tools/toolkits.d.ts.map +1 -1
- package/dist/tools/toolkits.js +8 -2
- package/dist/tools/toolkits.js.map +1 -1
- package/dist/types/code-generator.d.ts.map +1 -1
- package/dist/types/code-generator.js +103 -10
- package/dist/types/code-generator.js.map +1 -1
- package/dist/types/schemas.d.ts +27 -2
- package/dist/types/schemas.d.ts.map +1 -1
- package/dist/types/schemas.js +7 -23
- package/dist/types/schemas.js.map +1 -1
- package/dist/utils/asset-paths.d.ts.map +1 -1
- package/dist/utils/asset-paths.js +11 -0
- package/dist/utils/asset-paths.js.map +1 -1
- package/dist/utils/capabilities.d.ts +15 -0
- package/dist/utils/capabilities.d.ts.map +1 -0
- package/dist/utils/capabilities.js +63 -0
- package/dist/utils/capabilities.js.map +1 -0
- package/dist/utils/env.d.ts.map +1 -1
- package/dist/utils/env.js +2 -1
- package/dist/utils/env.js.map +1 -1
- package/manifest.json +18 -2
- package/package.json +1 -1
|
@@ -14,7 +14,7 @@ import { TOOL_TAGS } from './toolkits.js';
|
|
|
14
14
|
import { STICK_GAITS, STICK_POSES, STICK_SEQUENCES, STICK_EXPRESSIONS, STICK_PROPS } from './stick-vocabulary.js';
|
|
15
15
|
import { AgentBatchOperationTypeSchema, GeneratorNameSchema, ItemTypeSchema } from '../types/schemas.js';
|
|
16
16
|
import { expressionGrammarText } from './expression-grammar.js';
|
|
17
|
-
import { DESIGN_MEDIA, DESIGN_MEDIA_APPLY, FILTER_TYPES, FILTER_DOCS, LINEAGE_KINDS, STYLED_SCENE_STYLES, STYLED_SCENE_STYLE_INFO, PATTERN_KINDS } from './engine-lists.js';
|
|
17
|
+
import { DESIGN_MEDIA, DESIGN_MEDIA_APPLY, FILTER_TYPES, FILTER_DOCS, LINEAGE_KINDS, STYLED_SCENE_STYLES, STYLED_SCENE_STYLE_INFO, PATTERN_KINDS, ANIMATION_TYPES, ANIMATION_WAVEFORMS, ANIMATION_ORIGINS } from './engine-lists.js';
|
|
18
18
|
import { EffectTypeSchema, AgentExportFormatSchema, RelationTypeSchema, SimpleAnimationTypeSchema, EasingSchema, KEYFRAME_EASINGS, EASING_DESCRIPTIONS, KEYFRAME_EASING_JSON_SCHEMA, GEOMETRY_OPERATIONS, THREAD_STITCHES, } from '../types/schemas.js';
|
|
19
19
|
/**
|
|
20
20
|
* Vocabulary lists derived from Zod schemas so tool descriptions stay in
|
|
@@ -1640,7 +1640,7 @@ warp (optional): chained parametric warp(s) — displace each sampled point by {
|
|
|
1640
1640
|
|
|
1641
1641
|
RETURNS: { success, kind, itemId } — itemId is the created path. Bad expressions / empty ranges return { success:false, error }.
|
|
1642
1642
|
|
|
1643
|
-
To make an item TRAVEL along an equation curve (instead of drawing it), use pinepaper_add_relation relationType moves_along_path with params.equation
|
|
1643
|
+
To make an item TRAVEL along an equation curve (instead of drawing it), use pinepaper_add_relation relationType moves_along_path with params.equation. The same flipY applies there: by default y is math-up, so the item rides the curve mirrored about cy compared with screen coordinates (y down). Pass flipY: false to author the curve in screen coordinates.
|
|
1644
1644
|
|
|
1645
1645
|
EXAMPLES:
|
|
1646
1646
|
- Sine wave: { kind: "function", expr: "sin(x/40) * 60", min: -300, max: 300, style: { strokeColor: "#4f46e5" } }
|
|
@@ -3461,6 +3461,8 @@ PARAMS: { eps? (bounds-match tolerance px, default 4), cap? (max suggestions, de
|
|
|
3461
3461
|
MOVES_ALONG_PATH — ride a path (a hand tracing a stroke, a car on a road):
|
|
3462
3462
|
- sourceId: the item that moves. The path comes from ONE of: targetId (or params.pathId) naming a PATH ITEM, sampled into points for you; params.path as points [[x, y], …]; or params.equation.
|
|
3463
3463
|
- params.duration: seconds for one traversal (or pass speed directly, 1 ≈ 150 px/s). params.delay: seconds on the timeline before it starts; until then the item waits at the path start. params.offset: [dx, dy] added to the point on the path — set it to (centre - pen tip) so a hand image's TIP, not its centre, rides the stroke. closed (loop back to the start; default from the path item), phase (0–1 start point), easing (linear | easeIn | easeOut | easeInOut | sine | bounce | pingpong), signal (deterministic, frame-rate-invariant — prefer it for export).
|
|
3464
|
+
- The item travels at CONSTANT SPEED along the route: the fraction of the duration elapsed is the fraction of the route's LENGTH covered, not of the equation's parameter or of the point count. Where the curve is long it moves the same speed as where it is short; easing reshapes that progress. For a route timed by the parameter instead, key the position with pinepaper_keyframe_animate.
|
|
3465
|
+
- params.equation is in math coordinates with y UP (flipY: true by default), placed at cx, cy: on screen the curve is mirrored about cy. Write flipY: false to author it in screen coordinates (y down).
|
|
3464
3466
|
- With no path from any of those it is refused, not accepted as a still item.
|
|
3465
3467
|
|
|
3466
3468
|
USE WHEN:
|
|
@@ -3531,7 +3533,7 @@ RELATION COMPATIBILITY:
|
|
|
3531
3533
|
Text→Text: font blend
|
|
3532
3534
|
Cross-type: particle denoising transition
|
|
3533
3535
|
- 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|easeOut|easeInOut), deformLines.
|
|
3534
|
-
- 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).
|
|
3536
|
+
- 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 equation, speed, closed, phase, easing (linear|easeIn|easeOut|easeInOut|sine|bounce|pingpong).
|
|
3535
3537
|
|
|
3536
3538
|
GEOMETRIC 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:
|
|
3537
3539
|
- is_midpoint_of: source = midpoint(target, params.other). params.other = id of the second endpoint (B).
|
|
@@ -3672,15 +3674,17 @@ USE WHEN:
|
|
|
3672
3674
|
{
|
|
3673
3675
|
name: 'pinepaper_register_custom_relation',
|
|
3674
3676
|
annotations: {
|
|
3675
|
-
title: 'Register Custom Relation',
|
|
3677
|
+
title: 'Register Custom Relation (needs PINEPAPER_ALLOW_CODE)',
|
|
3676
3678
|
readOnlyHint: false,
|
|
3677
3679
|
destructiveHint: false,
|
|
3678
3680
|
idempotentHint: false,
|
|
3679
3681
|
openWorldHint: false,
|
|
3680
3682
|
},
|
|
3681
|
-
description: `
|
|
3683
|
+
description: `SECURITY SWITCH: needs a server started with PINEPAPER_ALLOW_CODE=1 (off by default; only the person running the server can turn it on). Otherwise it is refused and nothing runs.
|
|
3682
3684
|
|
|
3683
|
-
|
|
3685
|
+
PARAMS ARE DEFINITIONS, not values: { gap: { type: 'number', default: 60, min: 0 } } (type is number | string | boolean | array | object). Once registered, the name is a valid relationType for pinepaper_add_relation in this session.
|
|
3686
|
+
|
|
3687
|
+
Register a custom relation type with compute and apply functions. For motion without code, use time_expression.
|
|
3684
3688
|
|
|
3685
3689
|
USE WHEN:
|
|
3686
3690
|
- Creating physics-based behaviors (attraction, repulsion, collision)
|
|
@@ -3743,13 +3747,15 @@ applyFunction: \`
|
|
|
3743
3747
|
{
|
|
3744
3748
|
name: 'pinepaper_execute_custom_code',
|
|
3745
3749
|
annotations: {
|
|
3746
|
-
title: 'Execute Custom Code',
|
|
3750
|
+
title: 'Execute Custom Code (needs PINEPAPER_ALLOW_CODE)',
|
|
3747
3751
|
readOnlyHint: false,
|
|
3748
3752
|
destructiveHint: true,
|
|
3749
3753
|
idempotentHint: false,
|
|
3750
3754
|
openWorldHint: true,
|
|
3751
3755
|
},
|
|
3752
|
-
description: `
|
|
3756
|
+
description: `SECURITY SWITCH: needs a server started with PINEPAPER_ALLOW_CODE=1 (off by default; only the person running the server can turn it on). Otherwise it is refused and nothing runs.
|
|
3757
|
+
|
|
3758
|
+
Execute arbitrary JavaScript code in the PinePaper context.
|
|
3753
3759
|
|
|
3754
3760
|
USE WHEN:
|
|
3755
3761
|
- Advanced Paper.js operations not covered by other tools
|
|
@@ -3849,6 +3855,9 @@ ANIMATION TYPES (18 — the list the driver actually switches on):
|
|
|
3849
3855
|
- scrollLeft / scrollRight / scrollUp / scrollDown: Continuous scroll, wrapping
|
|
3850
3856
|
- path: Travel along an assigned path
|
|
3851
3857
|
- typewriter: Character-by-character reveal
|
|
3858
|
+
- ripple: An opacity wave. On a GROUP it sweeps through the children outward from origin, each a little later; on a single item it pulses the item.
|
|
3859
|
+
- undulate: A vertical lift wave, swept through a group's children the same way (intensity 0.4 ≈ 14 px).
|
|
3860
|
+
ripple and undulate take waveform (the shape of one cycle) and origin (where the wave starts on a group). SVG and Lottie exports draw them static; export MP4, WebM or GIF to keep the wave.
|
|
3852
3861
|
|
|
3853
3862
|
There is NO 'slide'. An unknown type is stored and then ignored — the item sits still while its data claims otherwise, and the call still reports success — so use the exact names above.`,
|
|
3854
3863
|
inputSchema: {
|
|
@@ -3857,7 +3866,7 @@ There is NO 'slide'. An unknown type is stored and then ignored — the item sit
|
|
|
3857
3866
|
itemId: { type: 'string', description: 'Registry ID of the item' },
|
|
3858
3867
|
animationType: {
|
|
3859
3868
|
type: 'string',
|
|
3860
|
-
enum: [
|
|
3869
|
+
enum: [...ANIMATION_TYPES],
|
|
3861
3870
|
description: 'Type of animation',
|
|
3862
3871
|
},
|
|
3863
3872
|
speed: {
|
|
@@ -3872,6 +3881,8 @@ There is NO 'slide'. An unknown type is stored and then ignored — the item sit
|
|
|
3872
3881
|
type: 'number',
|
|
3873
3882
|
description: 'Animation start delay in seconds.',
|
|
3874
3883
|
},
|
|
3884
|
+
waveform: { type: 'string', enum: [...ANIMATION_WAVEFORMS], description: 'ripple / undulate: the shape of one cycle (default sine).' },
|
|
3885
|
+
origin: { type: 'string', enum: [...ANIMATION_ORIGINS], description: 'ripple / undulate on a group: where the wave starts (default center).' },
|
|
3875
3886
|
},
|
|
3876
3887
|
required: ['itemId', 'animationType'],
|
|
3877
3888
|
},
|
|
@@ -3914,7 +3925,7 @@ ANIMATABLE PROPERTIES:
|
|
|
3914
3925
|
- strokeColor: Color string
|
|
3915
3926
|
- strokeWidth, width, height, radius, shadowBlur, shadowColor: Numbers / colours
|
|
3916
3927
|
- fontSize: Number
|
|
3917
|
-
- 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).
|
|
3928
|
+
- 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). fontWeight 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.
|
|
3918
3929
|
- 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.
|
|
3919
3930
|
The authoritative list for a given item is pinepaper_get_animatable_properties — ask it rather than guessing.
|
|
3920
3931
|
|
|
@@ -3924,7 +3935,7 @@ ${EASING_LINES}
|
|
|
3924
3935
|
- 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.
|
|
3925
3936
|
COUNTERS: 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.
|
|
3926
3937
|
|
|
3927
|
-
HOLD 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 the cut. For a whole layer 'on twos', set stepTiming on the item (create_item / modify_item).
|
|
3938
|
+
HOLD 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 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.
|
|
3928
3939
|
|
|
3929
3940
|
Every 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.
|
|
3930
3941
|
|
|
@@ -4860,6 +4871,7 @@ KINDS:
|
|
|
4860
4871
|
- phase_wave — members move on a sine, each a phase later than the one before. params: property ('y' default, 'x', 'rotation', 'opacity'), amplitude (px, degrees or 0..1), period (seconds per cycle), wavelength (members per full cycle), phase (radians). window { from, to } limits when it plays; time counts from \`from\`.
|
|
4861
4872
|
- stagger — each member's animationDelay, derived from its place. params: step (s between neighbours), start (s), order: index | reverse | center | edges.
|
|
4862
4873
|
- ring / orbit (the same motion) — members spaced evenly round a circle that turns. params: center ([x, y] or {x, y}; default 960, 540), target (an item id or name: the centre follows it), radius (px, default 200), period (seconds per turn, default 6), phase (RADIANS, the first member's angle), direction (1 clockwise, -1 or 'ccw'). Each member's own position is overwritten while it plays and comes back when the pattern is removed. window as for phase_wave.
|
|
4874
|
+
- STACKING. phase_wave patterns on the same member and property add their offsets to one shared base on the current studio, so sequenced windows combine without drift (an older studio re-based them on each other's writes and could leave the member displaced: there, give a member one pattern per property and sequence by modifying its params and window). ring and orbit write the member's absolute position, so two of them on one member conflict: give each member one ring or orbit.
|
|
4863
4875
|
|
|
4864
4876
|
MEMBERS — by names (a '*' matches any run: "letter-*"), ids, or a tag, in the order they are given; an array is taken as ids or names. A name that matches nothing is reported in the result, not ignored.
|
|
4865
4877
|
|
|
@@ -8069,6 +8081,7 @@ SPEC:
|
|
|
8069
8081
|
UNITS (a number, or a [min, max] range picked per particle where it says range):
|
|
8070
8082
|
- count: particles per burst, at most 10000 on the current studio (2000 on older studios) — a larger count is drawn at the cap and the reply warns with the number drawn. For more, add a second burst at the same t.
|
|
8071
8083
|
- speed: px/s (range). angle: degrees, 0 = right, 90 = down (range). gravity: px/s². lifetime: seconds (range, > 0). size: px (range).
|
|
8084
|
+
- gravity, drag, friction, opacity, sizeEnd and jitter also take a range on the current studio, sampled per particle; an older studio draws the midpoint and warns emitter-range-not-read.
|
|
8072
8085
|
- fadeIn / fadeOut: SECONDS at the start / end of each particle's life. fadeOut is capped at that particle's lifetime (a 0.5 s life cannot fade for 2 s; it fades over its whole life instead), and the current studio warns when it caps one. Omitted (or fade: 'linear'), the particle fades linearly over its WHOLE life; fade: 'none' turns both off.
|
|
8073
8086
|
- spin: DEGREES PER SECOND, positive = clockwise on screen (range; spinAlternate flips every other particle). It turns rect, confetti, star and dash particles; a circle has no orientation, so spin on circles shows nothing (the current studio warns when every particle is a circle).
|
|
8074
8087
|
- jitter: PIXELS — on the current studio each particle is displaced up to ±jitter px on each axis from its path, at full size from birth; jitterGrow: true keeps the older ramp (zero at birth, the full ±jitter at the end of life). Older studios (before jitterGrow) displace up to ±jitter/2, growing from 0 at birth. jitterHz: how many times a second that offset is re-rolled (0, the default, keeps one offset per particle).
|
|
@@ -8088,8 +8101,10 @@ EXAMPLE — confetti at 2 s:
|
|
|
8088
8101
|
},
|
|
8089
8102
|
{
|
|
8090
8103
|
name: 'pinepaper_render_hook',
|
|
8091
|
-
annotations: { title: 'Render Hook', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
8092
|
-
description: `
|
|
8104
|
+
annotations: { title: 'Render Hook (register needs PINEPAPER_ALLOW_CODE)', readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
8105
|
+
description: `SECURITY SWITCH: register needs a server started with PINEPAPER_ALLOW_CODE=1 (off by default; only the person running the server can turn it on). list and unregister always work.
|
|
8106
|
+
|
|
8107
|
+
Custom per-frame drawing that a saved scene CARRIES: SOURCE TEXT, compiled and run under the governor's loop guards with seeded Math, saved in the project document, the template and undo, and re-installed on load. (A raw function added with code is not saved — pinepaper_export_scene { full: true } names any such as unserialized.)
|
|
8093
8108
|
|
|
8094
8109
|
ACTIONS:
|
|
8095
8110
|
- register: { id, source, layer? ('above' | 'below'), deterministic? (true), seed? } — source evaluates to (ctx, t, info) => {}: ctx in canvas coordinates, t the scene time in seconds, info { width, height, frame, seed }. 'above' draws over every item, 'below' under them. deterministic reseeds Math.random from (seed, frame) each call, so a frame always draws the same.
|
|
@@ -8149,7 +8164,7 @@ EXAMPLE — a ball comes to life and crosses the frame:
|
|
|
8149
8164
|
sound: { description: "true, or {pop?, whoosh?, contact?, shake? (catalogue name or false), gain? 0..1}: a sound on every pop, launch, landing and shake.", oneOf: [{ type: 'boolean' }, { type: 'object', additionalProperties: true }] },
|
|
8150
8165
|
beats: {
|
|
8151
8166
|
type: 'array',
|
|
8152
|
-
description: 'Beats in time order: [{at, verb, to?, duration?, height?, times?, decay?, arc?, edge?, from?, amount?, hold?, intensity?}].',
|
|
8167
|
+
description: 'Beats in time order: [{at, verb, to?, duration?, height?, times?, decay?, arc?, edge?, from?, amount?, hold?, intensity?}]. intensity is the amplitude of shake in px; no other verb reads it.',
|
|
8153
8168
|
items: {
|
|
8154
8169
|
type: 'object',
|
|
8155
8170
|
properties: {
|
|
@@ -9069,7 +9084,7 @@ VERIFY MOTION BEFORE YOU RENDER. An export takes seconds to minutes and shows yo
|
|
|
9069
9084
|
loop: { anyOf: [{ type: 'boolean' }, { type: 'integer', minimum: 0, maximum: 1000 }], description: 'gif / apng: true = loop forever, false / 0 / 1 = play once, n = play n times (email clients often want a few plays, not forever). Refused on video formats — see SEAMLESS LOOPS.' },
|
|
9070
9085
|
broadcast: { type: 'boolean', description: 'mp4 only: broadcast-safe — BT.709, limited range (16-235), tagged bt709, constant bitrate with an 8 Mbps floor at 720p+ (4 below). result.video reports what the encoder did.' },
|
|
9071
9086
|
frames: { type: 'integer', minimum: 1, maximum: 36000, description: 'Animated formats: exactly this many frames instead of duration. A duration makes ceil(duration x fps) frames (7.91667 s at 24 fps is 191, not 190), so use frames for frame-exact segments.' },
|
|
9072
|
-
deterministic: { type: 'boolean', description: 'mp4 / webm: byte-identical
|
|
9087
|
+
deterministic: { type: 'boolean', description: 'mp4 / webm: pins the container timestamps. WebM then comes out byte-identical; an MP4\'s encoded bytes can still differ run to run (the H.264 encoder is not bit-exact), so compare MP4s by the receipt\'s frameDigest, which is the same for the same frames, not by sha256.' },
|
|
9073
9088
|
motionBlur: {
|
|
9074
9089
|
type: 'object',
|
|
9075
9090
|
description: 'mp4 / webm: real motion blur. Each frame is rendered `subframes` times across the shutter and averaged, so fast movement smears instead of strobing. Costs subframes× the render time: run estimateOnly first (it reports renders and renderCost). The result carries motionBlur (what the exporter applied).',
|
|
@@ -9208,13 +9223,15 @@ EXAMPLE RESPONSE:
|
|
|
9208
9223
|
{
|
|
9209
9224
|
name: 'pinepaper_p5_draw',
|
|
9210
9225
|
annotations: {
|
|
9211
|
-
title: 'p5.js Draw',
|
|
9226
|
+
title: 'p5.js Draw (needs PINEPAPER_ALLOW_CODE)',
|
|
9212
9227
|
readOnlyHint: false,
|
|
9213
9228
|
destructiveHint: false,
|
|
9214
9229
|
idempotentHint: false,
|
|
9215
9230
|
openWorldHint: false,
|
|
9216
9231
|
},
|
|
9217
|
-
description: `
|
|
9232
|
+
description: `SECURITY SWITCH: needs a server started with PINEPAPER_ALLOW_CODE=1 (off by default; only the person running the server can turn it on). Otherwise it is refused and nothing runs.
|
|
9233
|
+
|
|
9234
|
+
Execute p5.js-style drawing code on the PinePaper canvas.
|
|
9218
9235
|
|
|
9219
9236
|
AI assistants can use familiar p5.js syntax - the code is translated to Paper.js automatically.
|
|
9220
9237
|
This is a SUBSET of p5.js functions optimized for static drawings.
|
|
@@ -9675,7 +9692,7 @@ VERBOSITY:
|
|
|
9675
9692
|
toolkit: {
|
|
9676
9693
|
type: 'string',
|
|
9677
9694
|
description: 'Toolkit profile: core (default), full, agent, diagram, map, font, minimal, lane',
|
|
9678
|
-
enum: ['core', 'full', 'agent', 'diagram', 'map', 'font', 'minimal', 'lane'],
|
|
9695
|
+
enum: ['core', 'full', 'agent', 'diagram', 'map', 'font', 'minimal', 'lane', 'edit'],
|
|
9679
9696
|
},
|
|
9680
9697
|
load: {
|
|
9681
9698
|
type: 'array',
|