@pinepaper.studio/mcp-server 1.6.28 → 1.6.30

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 (85) hide show
  1. package/README.md +79 -0
  2. package/SECURITY.md +2 -3
  3. package/dist/agent/export-manager.js +125 -125
  4. package/dist/assets/repositories/fontawesome.d.ts.map +1 -1
  5. package/dist/assets/repositories/fontawesome.js +2 -1
  6. package/dist/assets/repositories/fontawesome.js.map +1 -1
  7. package/dist/assets/repositories/iconify.d.ts.map +1 -1
  8. package/dist/assets/repositories/iconify.js +4 -3
  9. package/dist/assets/repositories/iconify.js.map +1 -1
  10. package/dist/browser/puppeteer-controller.d.ts +40 -0
  11. package/dist/browser/puppeteer-controller.d.ts.map +1 -1
  12. package/dist/browser/puppeteer-controller.js +176 -24
  13. package/dist/browser/puppeteer-controller.js.map +1 -1
  14. package/dist/build-info.json +2 -2
  15. package/dist/cli.js +54 -54
  16. package/dist/execution/canvas-state.js +25 -25
  17. package/dist/i18n/locales/en.js +22 -22
  18. package/dist/i18n/locales/fil.js +44 -44
  19. package/dist/i18n/locales/is.js +22 -22
  20. package/dist/i18n/locales/ur.js +22 -22
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +5574 -5568
  23. package/dist/index.js.map +1 -1
  24. package/dist/ontology/upstream-vocabulary.d.ts +2 -2
  25. package/dist/ontology/upstream-vocabulary.js +6 -6
  26. package/dist/ontology/vocabulary.d.ts.map +1 -1
  27. package/dist/ontology/vocabulary.js +2 -0
  28. package/dist/ontology/vocabulary.js.map +1 -1
  29. package/dist/tools/craft-tools.js +18 -18
  30. package/dist/tools/definitions.d.ts.map +1 -1
  31. package/dist/tools/definitions.js +2832 -2823
  32. package/dist/tools/definitions.js.map +1 -1
  33. package/dist/tools/effect-check.d.ts +1 -1
  34. package/dist/tools/effect-check.d.ts.map +1 -1
  35. package/dist/tools/effect-check.js +68 -68
  36. package/dist/tools/effect-check.js.map +1 -1
  37. package/dist/tools/engine-lists.d.ts +3 -3
  38. package/dist/tools/engine-lists.js +3 -3
  39. package/dist/tools/engine-methods.d.ts.map +1 -1
  40. package/dist/tools/engine-methods.js +4 -1
  41. package/dist/tools/engine-methods.js.map +1 -1
  42. package/dist/tools/engine-surface.d.ts +1 -1
  43. package/dist/tools/engine-surface.d.ts.map +1 -1
  44. package/dist/tools/engine-surface.js +19 -4
  45. package/dist/tools/engine-surface.js.map +1 -1
  46. package/dist/tools/handlers/font.js +22 -22
  47. package/dist/tools/handlers/generate.d.ts +2 -2
  48. package/dist/tools/handlers/generate.d.ts.map +1 -1
  49. package/dist/tools/handlers/generate.js +5 -4
  50. package/dist/tools/handlers/generate.js.map +1 -1
  51. package/dist/tools/handlers.d.ts.map +1 -1
  52. package/dist/tools/handlers.js +57 -18
  53. package/dist/tools/handlers.js.map +1 -1
  54. package/dist/tools/lane.d.ts +8 -2
  55. package/dist/tools/lane.d.ts.map +1 -1
  56. package/dist/tools/lane.js +86 -67
  57. package/dist/tools/lane.js.map +1 -1
  58. package/dist/tools/p5-compat/p5-helpers.d.ts +6 -17
  59. package/dist/tools/p5-compat/p5-helpers.d.ts.map +1 -1
  60. package/dist/tools/p5-compat/p5-helpers.js +349 -342
  61. package/dist/tools/p5-compat/p5-helpers.js.map +1 -1
  62. package/dist/tools/shape-params.d.ts +2 -2
  63. package/dist/tools/shape-params.d.ts.map +1 -1
  64. package/dist/tools/shape-params.js +5 -2
  65. package/dist/tools/shape-params.js.map +1 -1
  66. package/dist/tools/stick-vocabulary.d.ts +1 -1
  67. package/dist/tools/stick-vocabulary.js +1 -1
  68. package/dist/tools/timeline.js +82 -82
  69. package/dist/types/code-generator.d.ts.map +1 -1
  70. package/dist/types/code-generator.js +6646 -5853
  71. package/dist/types/code-generator.js.map +1 -1
  72. package/dist/types/schemas.d.ts +13 -0
  73. package/dist/types/schemas.d.ts.map +1 -1
  74. package/dist/types/schemas.js +6 -0
  75. package/dist/types/schemas.js.map +1 -1
  76. package/dist/utils/safe-fetch.d.ts +8 -0
  77. package/dist/utils/safe-fetch.d.ts.map +1 -1
  78. package/dist/utils/safe-fetch.js +125 -34
  79. package/dist/utils/safe-fetch.js.map +1 -1
  80. package/dist/vendor/design/device-mockup-generator.js +167 -150
  81. package/dist/vendor/design/recursive-subdivision-generator.js +107 -107
  82. package/dist/vendor/design/textile-weave-generator.js +429 -429
  83. package/dist/vendor/design/ui-kit-runtime.js +674 -674
  84. package/manifest.json +1 -1
  85. package/package.json +7 -4
@@ -21,7 +21,7 @@
21
21
  */
22
22
  export declare const LANE_TOOL_NAMES: readonly ["pinepaper_agent_batch_execute", "pinepaper_keyframe_animate", "pinepaper_pattern", "pinepaper_agent_export", "pinepaper_lint_scene", "pinepaper_event", "pinepaper_clear_canvas", "pinepaper_register_custom_relation"];
23
23
  /** Read by the model before any tool: what the lane is, the order of work, and what it cannot do. */
24
- export declare const LANE_INSTRUCTIONS = "PinePaper Studio, agent lane: eight tools that build an animated scene on a live canvas and export it to a file.\n\nORDER OF WORK:\n1. pinepaper_agent_batch_execute: ONE call with the canvas size, the background, every item, their keyframes and any relations.\n2. pinepaper_lint_scene: check the scene before exporting (text running off the frame, unrelated items).\n3. pinepaper_agent_export: format, duration and fps for a video. It returns the file path and the file's sha256 (a small SVG comes back inline).\nUse pinepaper_keyframe_animate to re-key one item afterwards, and pinepaper_pattern to move many named items with one declaration.\nSomething that happens AT a time or ON a click (show, hide, recolour): make the event with pinepaper_event first, then bind it in the batch with relation ops.\nTo start over, call pinepaper_clear_canvas: it empties the canvas and ids start again at item_1, so the same batch gives the same ids.\nMOTION THAT IS A FUNCTION OF TIME (a bob, a pulse, a sweep, a wave) is a relation, not keyframes: a track of hundreds of keys computed from a formula is the sign of the wrong route.\n- One item: a relation op {\"type\":\"relation\",\"sourceId\":\"$0\",\"relationType\":\"time_expression\",\"relationOptions\":{\"property\":\"y\",\"expression\":\"360 + 40*sin(2*PI*t)\"}} with no targetId; property is x, y, rotation, opacity or scale.\n- Many items, each offset (a wave across dots): define it once with pinepaper_register_custom_relation (on a server started with PINEPAPER_ALLOW_CODE=1), its formula reading params.index, and bind it to a name pattern (sourceId \"dot-*\"): each member gets index and count. Adding members later is the same op again.\n\nUNITS: pixels, top-left origin, y down; time in seconds; angles in degrees; colours as \"#rrggbb\".\nEvery call acts on the live canvas at once: re-sending a batch ADDS its items again (clear first to replay it). A failed atomic batch removes the items it made, so fix it and send it again (edits it made to items that already existed stay: the result says so).\nReport a tool error as it is; do not write HTML or other code instead of these tools.\nThis lane is for scenes built from shapes, text, keyframes and relations. For characters, styled scenes, maps, diagrams or sound, the full surface is PINEPAPER_TOOLKIT=agent.";
24
+ export declare const LANE_INSTRUCTIONS: string;
25
25
  interface LaneTool {
26
26
  description: string;
27
27
  inputSchema: Record<string, unknown>;
@@ -35,8 +35,14 @@ interface ToolLike {
35
35
  /** The edit profile (#43): an agent changing a scene that exists reads it with lint, changes it with the batch. */
36
36
  export declare const EDIT_TOOL_NAMES: readonly ["pinepaper_lint_scene", "pinepaper_agent_batch_execute", "pinepaper_register_custom_relation", "pinepaper_agent_export"];
37
37
  /** Read by an editing agent before any tool. */
38
- export declare const EDIT_INSTRUCTIONS = "PinePaper Studio, edit profile: four tools for changing a scene that is already on the canvas.\n\n1. pinepaper_lint_scene first. Its edit section lists every relation and custom motion with the exact op that changes it, and for a group bound by a name pattern (\"dot-*\"), the ops that add or remove a member.\n2. Send those ops, with your values, in ONE pinepaper_agent_batch_execute call.\n3. pinepaper_agent_export to render; perScene: true on a scene chain renders only what changed.\nChange a custom motion's formula by sending its pinepaper_register_custom_relation call again with the new body (the server must be started with PINEPAPER_ALLOW_CODE=1).\nUnits: pixels, top-left origin, y down; seconds; degrees. Report a tool error as it is.";
38
+ export declare const EDIT_INSTRUCTIONS = "PinePaper Studio, edit profile: four tools for changing a scene that is already on the canvas.\n\n1. pinepaper_lint_scene { only: 'edit' } first. Its edit section lists every relation and custom motion with the exact op that changes it, complete as given (you do not need the batch op schema to send it), and for a group bound by a name pattern (\"dot-*\"), the ops that add or remove a member.\n2. Send those ops, with your values, in ONE pinepaper_agent_batch_execute call.\n3. pinepaper_agent_export to render; perScene: true on a scene chain renders only what changed.\nChange a custom motion's formula by sending its pinepaper_register_custom_relation call again with the new body (the server must be started with PINEPAPER_ALLOW_CODE=1).\nUnits: pixels, top-left origin, y down; seconds; degrees. Report a tool error as it is.";
39
39
  /** The lane (or another set of lane tools): in order, each shown with its lane description and schema. */
40
+ /**
41
+ * The edit profile's batch description (#43). The lane's is 6 KB of op examples for BUILDING a scene; an editing
42
+ * agent sends the ops lint_scene hands it, so it gets those rules and the few shapes an edit adds, nothing more.
43
+ * The schema is the lane's, unchanged.
44
+ */
45
+ export declare const EDIT_BATCH_DESCRIPTION: string;
40
46
  export declare function applyLane<T extends ToolLike>(tools: T[], names?: readonly string[]): T[];
41
47
  /** The contract an agent loads for the lane: the instructions plus the lane tools as tools/list sends them. */
42
48
  export declare function laneContractText(tools: ToolLike[]): string;
@@ -1 +1 @@
1
- {"version":3,"file":"lane.d.ts","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oOASlB,CAAC;AAKX,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,sxEAgBiJ,CAAC;AAEhL,UAAU,QAAQ;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAqBD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAiMnF,CAAC;AAEF,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,mHAAmH;AACnH,eAAO,MAAM,eAAe,oIAKlB,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,gvBAM0D,CAAC;AAEzF,0GAA0G;AAC1G,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,GAAE,SAAS,MAAM,EAAoB,GAAG,CAAC,EAAE,CASzG;AAED,+GAA+G;AAC/G,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAE1D"}
1
+ {"version":3,"file":"lane.d.ts","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAIH;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oOASlB,CAAC;AAKX,qGAAqG;AACrG,eAAO,MAAM,iBAAiB,EAAE,MAgB+I,CAAC;AAEhL,UAAU,QAAQ;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAqBD,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,CAAC,CAmMnF,CAAC;AAEF,UAAU,QAAQ;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,mHAAmH;AACnH,eAAO,MAAM,eAAe,oIAKlB,CAAC;AAEX,gDAAgD;AAChD,eAAO,MAAM,iBAAiB,q0BAM0D,CAAC;AAEzF,0GAA0G;AAC1G;;;;GAIG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAQ+I,CAAC;AAIrL,wBAAgB,SAAS,CAAC,CAAC,SAAS,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,KAAK,GAAE,SAAS,MAAM,EAAoB,GAAG,CAAC,EAAE,CAWzG;AAED,+GAA+G;AAC/G,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,QAAQ,EAAE,GAAG,MAAM,CAE1D"}
@@ -33,23 +33,23 @@ export const LANE_TOOL_NAMES = [
33
33
  /** The one keyframe shape, said once and used by both tools that take keyframes. */
34
34
  const KEYFRAME_RULE = `A keyframe is {"time": seconds, "properties": {…}, "easing"?: name}. The values go INSIDE properties, never beside time: {"time":1,"properties":{"opacity":1}}, not {"time":1,"opacity":1} (refused). easing shapes the move ARRIVING at that key: linear (default), easeIn, easeOut, easeInOut, easeOutBack, easeInOutCubic, easeOutBounce, spring, hold. Before its first key an item holds the first key's values; after its last, the last key's. Keyable: x, y (the centre), opacity, scale, scaleX, scaleY, rotation (degrees), fillColor, strokeColor, strokeWidth, width, height, radius, fontSize, trimEnd (0→1 draws a path on).`;
35
35
  /** Read by the model before any tool: what the lane is, the order of work, and what it cannot do. */
36
- export const LANE_INSTRUCTIONS = `PinePaper Studio, agent lane: eight tools that build an animated scene on a live canvas and export it to a file.
37
-
38
- ORDER OF WORK:
39
- 1. pinepaper_agent_batch_execute: ONE call with the canvas size, the background, every item, their keyframes and any relations.
40
- 2. pinepaper_lint_scene: check the scene before exporting (text running off the frame, unrelated items).
41
- 3. pinepaper_agent_export: format, duration and fps for a video. It returns the file path and the file's sha256 (a small SVG comes back inline).
42
- Use pinepaper_keyframe_animate to re-key one item afterwards, and pinepaper_pattern to move many named items with one declaration.
43
- Something that happens AT a time or ON a click (show, hide, recolour): make the event with pinepaper_event first, then bind it in the batch with relation ops.
44
- To start over, call pinepaper_clear_canvas: it empties the canvas and ids start again at item_1, so the same batch gives the same ids.
45
- MOTION THAT IS A FUNCTION OF TIME (a bob, a pulse, a sweep, a wave) is a relation, not keyframes: a track of hundreds of keys computed from a formula is the sign of the wrong route.
46
- - One item: a relation op {"type":"relation","sourceId":"$0","relationType":"time_expression","relationOptions":{"property":"y","expression":"360 + 40*sin(2*PI*t)"}} with no targetId; property is x, y, rotation, opacity or scale.
47
- - Many items, each offset (a wave across dots): define it once with pinepaper_register_custom_relation (on a server started with PINEPAPER_ALLOW_CODE=1), its formula reading params.index, and bind it to a name pattern (sourceId "dot-*"): each member gets index and count. Adding members later is the same op again.
48
-
49
- UNITS: pixels, top-left origin, y down; time in seconds; angles in degrees; colours as "#rrggbb".
50
- Every call acts on the live canvas at once: re-sending a batch ADDS its items again (clear first to replay it). A failed atomic batch removes the items it made, so fix it and send it again (edits it made to items that already existed stay: the result says so).
51
- Report a tool error as it is; do not write HTML or other code instead of these tools.
52
- This lane is for scenes built from shapes, text, keyframes and relations. For characters, styled scenes, maps, diagrams or sound, the full surface is PINEPAPER_TOOLKIT=agent.`;
36
+ export const LANE_INSTRUCTIONS = ("PinePaper Studio, agent lane: eight tools that build an animated scene on a live canvas and export it to a file.\n\nORDER OF WORK:\n1. pinepaper_agent_batch_execute: ONE call with the canvas size, the background, every item, their keyframes and any relations.\n2. pinepaper_lint_scene: check the scene before exporting (text running off the frame, unrelated items).\n3. pinepaper_agent_export: format, duration and fps for a video. It returns the file path and the file's sha256 (a small SVG comes back inline).\nUse pinepaper_keyframe_animate to re-key one item afterwards, and pinepaper_pattern to move many named items with one declaration.\nSomething that happens AT a time or ON a click (show," +
37
+ " hide, recolour): make the event with pinepaper_event first, then bind it in the batch with relation ops.\nTo start over, call pinepaper_clear_canvas: it empties the canvas and ids start again at item_1, so the same batch gives the same ids.\nMOTION THAT IS A FUNCTION OF TIME (a bob, a pulse, a sweep, a wave) is a relation, not keyframes: a track of hundreds of keys computed from a formula is the sign of the wrong route.\n- One item: a relation op {\"type\":\"relation\",\"sourceId\":\"$0\",\"relationType\":\"time_expression\",\"relationOptions\":{\"property\":\"y\",\"expression\":\"360 + 40*sin(2*PI*t)\"}} with no targetId; property is x, y, rotation, opacity or scale.\n- Many items, each " +
38
+ "offset (a wave across dots): define it once with pinepaper_register_custom_relation (on a server started with PINEPAPER_ALLOW_CODE=1), its formula reading params.index, and bind it to a name pattern (sourceId \"dot-*\"): each member gets index and count. Adding members later is the same op again.\n\nUNITS: pixels, top-left origin, y down; time in seconds; angles in degrees; colours as \"#rrggbb\".\nEvery call acts on the live canvas at once: re-sending a batch ADDS its items again (clear first to replay it). A failed atomic batch removes the items it made, so fix it and send it again (edits it made to items that already existed stay: the result says so).\nReport a tool error as it is; do n" +
39
+ "ot write HTML or other code instead of these tools.\nThis lane is for scenes built from shapes, text, keyframes and relations. For characters, styled scenes, maps, diagrams or sound, the full surface is PINEPAPER_TOOLKIT=agent."
40
+
41
+
42
+
43
+
44
+
45
+
46
+
47
+
48
+
49
+
50
+
51
+
52
+ );
53
53
  const POSITION = {
54
54
  type: 'object',
55
55
  properties: { x: { type: 'number' }, y: { type: 'number' } },
@@ -69,37 +69,37 @@ const KEYFRAMES = {
69
69
  };
70
70
  export const LANE_TOOLS = {
71
71
  pinepaper_agent_batch_execute: {
72
- description: `Build the scene in ONE call: canvas, background, items, keyframes, relations. Ops run in order. "$0", "$1", … are the items THIS call made, in op order (create and group ops are numbered; a group of "$0","$1" made next is "$2"). The result lists their ids in itemIds; use those ids in later calls.
73
-
74
- Each line is a correct op:
75
- {"type":"set_canvas_size","width":1920,"height":1080}
76
- {"type":"set_background","backgroundColor":"#0b1026"}
77
- {"type":"create","itemType":"text","position":{"x":200,"y":130},"properties":{"content":"SIGNAL / NOISE","fontSize":72,"color":"#ffffff","anchor":"top-left","name":"title"}}
78
- {"type":"create","itemType":"circle","position":{"x":300,"y":600},"properties":{"radius":40,"color":"#22d3ee","name":"dot"}}
79
- {"type":"create","itemType":"rectangle","position":{"x":260,"y":900},"properties":{"width":120,"height":280,"color":"#38bdf8","anchor":"bottom-left","name":"bar-1"}}
80
- {"type":"keyframe_animate","itemId":"$0","keyframes":[{"time":0,"properties":{"opacity":0}},{"time":1,"properties":{"opacity":1}}]}
81
- {"type":"keyframe_animate","itemId":"$1","keyframes":[{"time":1,"properties":{"x":300}},{"time":7,"properties":{"x":1620},"easing":"easeInOut"}]}
82
- {"type":"relation","sourceId":"$1","targetId":"$2","relationType":"orbits","relationOptions":{"radius":260,"speed":0.1667}}
83
- {"type":"modify","itemId":"item_3","properties":{"color":"#f472b6"}}
84
- {"type":"timeline","defaults":{"ease":"power2.out"},"tweens":[{"to":"bar-*","from":{"scaleY":0},"vars":{"scaleY":1},"duration":0.8,"at":0.5,"stagger":0.15}]}
85
- {"type":"relation","sourceId":"item_9","targetId":"$0","relationType":"on_event_set_visibility","relationOptions":{"visible":true}}
86
- {"type":"relation","sourceId":"$1","targetId":"item_9","relationType":"on_click_fire"}
87
-
88
- RULES (each one has cost a failed build):
89
- - position {x,y} goes at the op's top level. Everything else about the item goes INSIDE properties: a text's words are properties.content, and so are fontSize, color, radius, width, height, opacity, name and anchor.
90
- - position is the item's CENTRE. A text grows both ways from it, so a title whose centre sits near an edge runs off the frame and the video shows "IGNAL / NOISE". When a spec gives a corner ("top-left at (200, 130)"), pass properties.anchor: "top-left" (or top-right, bottom-left, bottom-right). A bar that grows up from a baseline: anchor "bottom-left" at the baseline, key height.
91
- - ${KEYFRAME_RULE}
92
- - Two keyframe_animate ops on one item in a batch are merged into one track.
93
- - A timeline op is GSAP's timeline as JSON, compiled onto keyframe tracks: tweens [{to: a name, id, "$N", array or "bar-*"; vars: end values; from: start values; duration; at: seconds, "<", ">" or "+=0.2"; stagger; ease: "power2.out", "none", "back.out"…; repeat; yoyo}]. There x and y are OFFSETS from where the item was created, as in GSAP; scaleY on a bottom-anchored item holds its baseline; drawSVG "0%"→"100%" draws a path on. Every track lasts the whole timeline. What it cannot carry is refused by name; each tween gets a receipt. An item takes keys from a timeline or keyframe_animate ops, not both.
94
- - Name every item (properties.name). pinepaper_pattern selects members by name, e.g. "bar-*".
95
- - properties.id chooses an item's id ("dot"), so a replay after pinepaper_clear_canvas addresses the same ids.
96
- - A shape with a strokeColor and no color is an outline.
97
- - Relations: orbits {radius, speed (turns per second), direction, phaseDegrees}, follows {offset, smoothing}, attached_to {offset}, points_at, moves_along_path {path:[{x,y},…], speed}, time_expression {property, expression} (no targetId; the formula grammar: ${expressionGrammarText()}). sourceId moves; targetId is what it moves relative to. A name pattern as sourceId ("dot-*") binds every item named like it, in name order, each with index and count added to relationOptions; send the same op again after adding members and they join, with index and count updated. update: true changes the relationOptions of a relation already bound (same sourceId, targetId, relationType) instead of adding one.
98
- - Events (item_9 above is an eventId from pinepaper_event): an event → item relation is a reaction, run each time it fires: on_event_set_visibility {visible: true|false}, on_event_set_color {color}, on_event_set_property {property, value}. An item → event relation fires it: on_click_fire, on_pointer_enter_fire, on_key_fire {key}. An item a reaction reveals starts hidden: properties.visible false.
99
- - set_canvas_size comes first; a video exports at the canvas size.
100
- - The call is LIVE: sending it twice makes every item twice. atomic (default) stops at the first failure and removes every item the call created, so the canvas holds no half batch: fix the op it names and send it again. Edits to items that already existed are not undone; the result says what was removed.
101
-
102
- itemType: text, circle, rectangle, ellipse, star, triangle, polygon, line, arc, path, hexagon, diamond, arrow, heart.`,
72
+ description: ("Build the scene in ONE call: canvas, background, items, keyframes, relations. Ops run in order. \"$0\", \"$1\", … are the items THIS call made, in op order (create and group ops are numbered; a group of \"$0\",\"$1\" made next is \"$2\"). The result lists their ids in itemIds; use those ids in later calls.\n\nEach line is a correct op:\n{\"type\":\"set_canvas_size\",\"width\":1920,\"height\":1080}\n{\"type\":\"set_background\",\"backgroundColor\":\"#0b1026\"}\n{\"type\":\"create\",\"itemType\":\"text\",\"position\":{\"x\":200,\"y\":130},\"properties\":{\"content\":\"SIGNAL / NOISE\",\"fontSize\":72,\"color\":\"#ffffff\",\"anchor\":\"top-left\",\"name\":\"title\"}}\n{\"type\":\"create\",\"i" +
73
+ "temType\":\"circle\",\"position\":{\"x\":300,\"y\":600},\"properties\":{\"radius\":40,\"color\":\"#22d3ee\",\"name\":\"dot\"}}\n{\"type\":\"create\",\"itemType\":\"rectangle\",\"position\":{\"x\":260,\"y\":900},\"properties\":{\"width\":120,\"height\":280,\"color\":\"#38bdf8\",\"anchor\":\"bottom-left\",\"name\":\"bar-1\"}}\n{\"type\":\"keyframe_animate\",\"itemId\":\"$0\",\"keyframes\":[{\"time\":0,\"properties\":{\"opacity\":0}},{\"time\":1,\"properties\":{\"opacity\":1}}]}\n{\"type\":\"keyframe_animate\",\"itemId\":\"$1\",\"keyframes\":[{\"time\":1,\"properties\":{\"x\":300}},{\"time\":7,\"properties\":{\"x\":1620},\"easing\":\"easeInOut\"}]}\n{\"type\":\"relation\",\"sourceId\":\"$1\"," +
74
+ "\"targetId\":\"$2\",\"relationType\":\"orbits\",\"relationOptions\":{\"radius\":260,\"speed\":0.1667}}\n{\"type\":\"modify\",\"itemId\":\"item_3\",\"properties\":{\"color\":\"#f472b6\"}}\n{\"type\":\"timeline\",\"defaults\":{\"ease\":\"power2.out\"},\"tweens\":[{\"to\":\"bar-*\",\"from\":{\"scaleY\":0},\"vars\":{\"scaleY\":1},\"duration\":0.8,\"at\":0.5,\"stagger\":0.15}]}\n{\"type\":\"relation\",\"sourceId\":\"item_9\",\"targetId\":\"$0\",\"relationType\":\"on_event_set_visibility\",\"relationOptions\":{\"visible\":true}}\n{\"type\":\"relation\",\"sourceId\":\"$1\",\"targetId\":\"item_9\",\"relationType\":\"on_click_fire\"}\n\nRULES (each one has cost a failed build):\n- position {x,y} go" +
75
+ "es at the op's top level. Everything else about the item goes INSIDE properties: a text's words are properties.content, and so are fontSize, color, radius, width, height, opacity, name and anchor.\n- position is the item's CENTRE. A text grows both ways from it, so a title whose centre sits near an edge runs off the frame and the video shows \"IGNAL / NOISE\". When a spec gives a corner (\"top-left at (200, 130)\"), pass properties.anchor: \"top-left\" (or top-right, bottom-left, bottom-right). A bar that grows up from a baseline: anchor \"bottom-left\" at the baseline, key height.\n- " +
76
+ String(KEYFRAME_RULE) +
77
+ "\n- Two keyframe_animate ops on one item in a batch are merged into one track.\n- A timeline op is GSAP's timeline as JSON, compiled onto keyframe tracks: tweens [{to: a name, id, \"$N\", array or \"bar-*\"; vars: end values; from: start values; duration; at: seconds, \"<\", \">\" or \"+=0.2\"; stagger; ease: \"power2.out\", \"none\", \"back.out\"…; repeat; yoyo}]. There x and y are OFFSETS from where the item was created, as in GSAP; scaleY on a bottom-anchored item holds its baseline; drawSVG \"0%\"→\"100%\" draws a path on. Every track lasts the whole timeline. What it cannot carry is refused by name; each tween gets a receipt. An item takes keys from a timeline or keyframe_animate ops," +
78
+ " not both.\n- Name every item (properties.name). pinepaper_pattern selects members by name, e.g. \"bar-*\".\n- properties.id chooses an item's id (\"dot\"), so a replay after pinepaper_clear_canvas addresses the same ids.\n- A shape with a strokeColor and no color is an outline.\n- Relations: orbits {radius, speed (turns per second), direction, phaseDegrees}, follows {offset, smoothing}, attached_to {offset}, points_at, moves_along_path {path:[{x,y},…], speed}, time_expression {property, expression} (no targetId; the formula grammar: " +
79
+ String(expressionGrammarText()) +
80
+ "). sourceId moves; targetId is what it moves relative to. A name pattern as sourceId (\"dot-*\") binds every item named like it, in name order, each with index and count added to relationOptions; send the same op again after adding members and they join, with index and count updated. update: true changes the relationOptions of a relation already bound (same sourceId, targetId, relationType) instead of adding one.\n- Events (item_9 above is an eventId from pinepaper_event): an event → item relation is a reaction, run each time it fires: on_event_set_visibility {visible: true|false}, on_event_set_color {color}, on_event_set_property {property, value}. An item → event relation fires it: on_cl" +
81
+ "ick_fire, on_pointer_enter_fire, on_key_fire {key}. An item a reaction reveals starts hidden: properties.visible false.\n- set_canvas_size comes first; a video exports at the canvas size.\n- The call is LIVE: sending it twice makes every item twice. atomic (default) stops at the first failure and removes every item the call created, so the canvas holds no half batch: fix the op it names and send it again. Edits to items that already existed are not undone; the result says what was removed.\n\nitemType: text, circle, rectangle, ellipse, star, triangle, polygon, line, arc, path, hexagon, diamond, arrow, heart."
82
+
83
+
84
+
85
+
86
+
87
+
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+
100
+
101
+
102
+ ),
103
103
  inputSchema: {
104
104
  type: 'object',
105
105
  properties: {
@@ -154,16 +154,16 @@ EXAMPLE: {"itemId":"item_2","keyframes":[{"time":1,"properties":{"x":300}},{"tim
154
154
  },
155
155
  },
156
156
  pinepaper_pattern: {
157
- description: `Move many NAMED items with one stored declaration instead of a track on each. Change a parameter once and every member follows; remove it and they go back.
157
+ description: ("Move many NAMED items with one stored declaration instead of a track on each. Change a parameter once and every member follows; remove it and they go back.\n\nKINDS:\n- phase_wave: members move on a sine, each a phase after the last. params: property (\"y\" default, \"x\", \"rotation\", \"opacity\"), amplitude (px, degrees or 0..1), period (seconds a cycle), wavelength (members a cycle). window {from, to} in seconds limits when it plays.\n- stagger: each member's start is delayed by its place. params: step (seconds between neighbours), start, order (index, reverse, center, edges).\nmembers: {\"names\": \"bar-*\"} ('*' matches any run), or an array of ids. A name that matches nothing is rep" +
158
+ "orted.\nA relation between two items (orbits, follows) is a relation op in pinepaper_agent_batch_execute, not a pattern.\n\nACTIONS: create (id, kind, members, params) · modify (id + what changes) · remove (id) · list · get (id).\nEXAMPLE: {\"action\":\"create\",\"id\":\"wave\",\"kind\":\"phase_wave\",\"members\":{\"names\":\"bar-*\"},\"params\":{\"amplitude\":12,\"period\":1.2,\"wavelength\":5}}"
159
+
160
+
161
+
162
+
158
163
 
159
- KINDS:
160
- - phase_wave: members move on a sine, each a phase after the last. params: property ("y" default, "x", "rotation", "opacity"), amplitude (px, degrees or 0..1), period (seconds a cycle), wavelength (members a cycle). window {from, to} in seconds limits when it plays.
161
- - stagger: each member's start is delayed by its place. params: step (seconds between neighbours), start, order (index, reverse, center, edges).
162
- members: {"names": "bar-*"} ('*' matches any run), or an array of ids. A name that matches nothing is reported.
163
- A relation between two items (orbits, follows) is a relation op in pinepaper_agent_batch_execute, not a pattern.
164
164
 
165
- ACTIONS: create (id, kind, members, params) · modify (id + what changes) · remove (id) · list · get (id).
166
- EXAMPLE: {"action":"create","id":"wave","kind":"phase_wave","members":{"names":"bar-*"},"params":{"amplitude":12,"period":1.2,"wavelength":5}}`,
165
+
166
+ ),
167
167
  inputSchema: {
168
168
  type: 'object',
169
169
  properties: {
@@ -184,12 +184,12 @@ EXAMPLE: {"action":"create","id":"wave","kind":"phase_wave","members":{"names":"
184
184
  },
185
185
  },
186
186
  pinepaper_agent_export: {
187
- description: `Render the scene to a file and return where it is.
187
+ description: ("Render the scene to a file and return where it is.\n\nA video needs format, duration and fps: {\"format\":\"mp4\",\"duration\":8,\"fps\":30}. duration defaults to 5 s, so an 8 s piece without it is cut at 5. The file is the canvas size; leave platform out. A still: {\"format\":\"png\",\"time\":4}.\nAn 8 s 1080p video takes a few minutes to render: wait for this call, and do not send it again while it runs.\n\nRETURNS \"File: <path>\", plus file {sha256, bytes}: the sha256 of the file on disk. MP4 and WebM add frameDigest and frames, a digest of every rendered frame (two renders of the same scene agree frame for frame when their frameDigest agrees); unreadFrames counts frames the digest cou" +
188
+ "ld not read. A small SVG comes back inline, with no file. video.frames {fed, distinct} says whether anything moved. fidelity.warnings names what the format could not carry. A failed export is an error naming the reason; it never reports a file it did not write."
189
+
188
190
 
189
- A video needs format, duration and fps: {"format":"mp4","duration":8,"fps":30}. duration defaults to 5 s, so an 8 s piece without it is cut at 5. The file is the canvas size; leave platform out. A still: {"format":"png","time":4}.
190
- An 8 s 1080p video takes a few minutes to render: wait for this call, and do not send it again while it runs.
191
191
 
192
- RETURNS "File: <path>", plus file {sha256, bytes}: the sha256 of the file on disk. MP4 and WebM add frameDigest and frames, a digest of every rendered frame (two renders of the same scene agree frame for frame when their frameDigest agrees); unreadFrames counts frames the digest could not read. A small SVG comes back inline, with no file. video.frames {fed, distinct} says whether anything moved. fidelity.warnings names what the format could not carry. A failed export is an error naming the reason; it never reports a file it did not write.`,
192
+ ),
193
193
  inputSchema: {
194
194
  type: 'object',
195
195
  properties: {
@@ -227,11 +227,11 @@ A TIMED event fires itself at scene times, in the preview and in every video exp
227
227
  inputSchema: { type: 'object', properties: {} },
228
228
  },
229
229
  pinepaper_register_custom_relation: {
230
- description: `Needs a server started with PINEPAPER_ALLOW_CODE=1 (its bodies are JavaScript); otherwise it is refused, and time_expression relation ops do the motion instead. Define a relation of your own, then bind it in pinepaper_agent_batch_execute with relation ops: relationType is its name, relationOptions its params, targetId optional (leave it out when the motion needs no other item). One definition drives many items: bind it to a name pattern (sourceId "dot-*", each member gets index and count), and change a param later with one relation op with update: true. pinepaper_lint_scene lists the relations bound and the definitions registered. It lasts for this session: register it again after a restart.
230
+ description: ("Needs a server started with PINEPAPER_ALLOW_CODE=1 (its bodies are JavaScript); otherwise it is refused, and time_expression relation ops do the motion instead. Define a relation of your own, then bind it in pinepaper_agent_batch_execute with relation ops: relationType is its name, relationOptions its params, targetId optional (leave it out when the motion needs no other item). One definition drives many items: bind it to a name pattern (sourceId \"dot-*\", each member gets index and count), and change a param later with one relation op with update: true. pinepaper_lint_scene lists the relations bound and the definitions registered. It lasts for this session: register it again after a rest" +
231
+ "art.\n\ncomputeFunction is a function BODY that gets fromPosition, toPosition, params, delta and time (scene seconds) and returns what apply needs. applyFunction is a body that gets item, target, computed and params and changes the item.\n{\"name\":\"bobs\",\"params\":{\"amp\":{\"type\":\"number\",\"default\":40}},\"computeFunction\":\"return {y: 360 + params.amp * Math.sin(Math.PI * time)};\",\"applyFunction\":\"if (computed) item.position.y = computed.y;\"}\nthen in the batch: {\"type\":\"relation\",\"sourceId\":\"$0\",\"relationType\":\"bobs\",\"relationOptions\":{\"amp\":100}}"
232
+
231
233
 
232
- computeFunction is a function BODY that gets fromPosition, toPosition, params, delta and time (scene seconds) and returns what apply needs. applyFunction is a body that gets item, target, computed and params and changes the item.
233
- {"name":"bobs","params":{"amp":{"type":"number","default":40}},"computeFunction":"return {y: 360 + params.amp * Math.sin(Math.PI * time)};","applyFunction":"if (computed) item.position.y = computed.y;"}
234
- then in the batch: {"type":"relation","sourceId":"$0","relationType":"bobs","relationOptions":{"amp":100}}`,
234
+ ),
235
235
  inputSchema: {
236
236
  type: 'object',
237
237
  properties: {
@@ -245,11 +245,13 @@ then in the batch: {"type":"relation","sourceId":"$0","relationType":"bobs","rel
245
245
  },
246
246
  },
247
247
  pinepaper_lint_scene: {
248
- description: `Check the live scene before exporting; read-only. Returns relations (every relation bound: from, fromName, to, type, params; the first 200), customRelations (each pinepaper_register_custom_relation definition, as given), warnings (a text that runs past the frame edge, by item, side and pixels, where the studio reports it), density (how many items are tied together by relations) and suggestions (relations that would hold the layout together: {from, to, type, params}). Fix a clipped text by moving its centre in with a modify op in pinepaper_agent_batch_execute ({"type":"modify","itemId":"item_1","properties":{"x":474}}: the centre is the left edge plus half the width), or delete it and create it again with properties.anchor; a modify does not read anchor.`,
248
+ description: ("Check the live scene before exporting; read-only. Returns relations (every relation bound: from, fromName, to, type, params; the first 200), customRelations (each pinepaper_register_custom_relation definition the scene uses; its source only with withSource: true), edit (the exact ops that change the scene; only: 'edit' returns just these, which is all an edit needs), warnings (a text that runs past the frame edge, by item, side and pixels, where the studio reports it), density (how many items are tied together by relations) and suggestions (relations that would hold the layout together: {from, to, type, params}). Fix a clipped text by moving its centre in with a modify op in pinepaper_agen" + "t_batch_execute ({\"type\":\"modify\",\"itemId\":\"item_1\",\"properties\":{\"x\":474}}: the centre is the left edge plus half the width), or delete it and create it again with properties.anchor; a modify does not read anchor."),
249
249
  inputSchema: {
250
250
  type: 'object',
251
251
  properties: {
252
252
  cap: { type: 'number', description: 'max suggestions (default 20)' },
253
+ only: { type: 'string', enum: ['edit'], description: "'edit': only the ops that change this scene" },
254
+ withSource: { type: 'boolean', description: 'include custom relation source (default false)' },
253
255
  },
254
256
  },
255
257
  },
@@ -264,20 +266,37 @@ export const EDIT_TOOL_NAMES = [
264
266
  /** Read by an editing agent before any tool. */
265
267
  export const EDIT_INSTRUCTIONS = `PinePaper Studio, edit profile: four tools for changing a scene that is already on the canvas.
266
268
 
267
- 1. pinepaper_lint_scene first. Its edit section lists every relation and custom motion with the exact op that changes it, and for a group bound by a name pattern ("dot-*"), the ops that add or remove a member.
269
+ 1. pinepaper_lint_scene { only: 'edit' } first. Its edit section lists every relation and custom motion with the exact op that changes it, complete as given (you do not need the batch op schema to send it), and for a group bound by a name pattern ("dot-*"), the ops that add or remove a member.
268
270
  2. Send those ops, with your values, in ONE pinepaper_agent_batch_execute call.
269
271
  3. pinepaper_agent_export to render; perScene: true on a scene chain renders only what changed.
270
272
  Change a custom motion's formula by sending its pinepaper_register_custom_relation call again with the new body (the server must be started with PINEPAPER_ALLOW_CODE=1).
271
273
  Units: pixels, top-left origin, y down; seconds; degrees. Report a tool error as it is.`;
272
274
  /** The lane (or another set of lane tools): in order, each shown with its lane description and schema. */
275
+ /**
276
+ * The edit profile's batch description (#43). The lane's is 6 KB of op examples for BUILDING a scene; an editing
277
+ * agent sends the ops lint_scene hands it, so it gets those rules and the few shapes an edit adds, nothing more.
278
+ * The schema is the lane's, unchanged.
279
+ */
280
+ export const EDIT_BATCH_DESCRIPTION = ("Change the scene in ONE call. Send the ops pinepaper_lint_scene { only: 'edit' } gave you, as given, with your values in relationOptions; they are complete (a group's change, addMember and removeMember ops included). Ops run in order; \"$0\", \"$1\" are the items this call made.\n\nOther shapes an edit may need:\n{\"type\":\"modify\",\"itemId\":\"dot-3\",\"properties\":{\"x\":480,\"color\":\"#ff5252\"}}\n{\"type\":\"delete\",\"itemId\":\"dot-3\"}\n{\"type\":\"create\",\"itemType\":\"circle\",\"position\":[480,300],\"properties\":{\"radius\":10,\"name\":\"dot-21\"}}\n{\"type\":\"keyframe_animate\",\"itemId\":\"title\",\"keyframes\":[{\"time\":0,\"properties\":{\"opacity\":0}},{\"time\":1,\"" +
281
+ "properties\":{\"opacity\":1}}]}\nA relation op with update: true changes that relation's options in place; without it, a second relation is added.\nUnits: pixels, top-left origin, y down; seconds; degrees. atomic (default true): a failure undoes the whole call. The reply lists failures and notes; verbose: true lists every op."
282
+
283
+
284
+
285
+
286
+
287
+
288
+ );
289
+ const EDIT_DESCRIPTIONS = { pinepaper_agent_batch_execute: EDIT_BATCH_DESCRIPTION };
273
290
  export function applyLane(tools, names = LANE_TOOL_NAMES) {
274
291
  const byName = new Map(tools.map((t) => [t.name, t]));
292
+ const edit = names === EDIT_TOOL_NAMES;
275
293
  const out = [];
276
294
  for (const name of names) {
277
295
  const tool = byName.get(name);
278
296
  if (!tool)
279
297
  continue;
280
- out.push({ ...tool, description: LANE_TOOLS[name].description, inputSchema: LANE_TOOLS[name].inputSchema });
298
+ const description = (edit && EDIT_DESCRIPTIONS[name]) || LANE_TOOLS[name].description;
299
+ out.push({ ...tool, description, inputSchema: LANE_TOOLS[name].inputSchema });
281
300
  }
282
301
  return out;
283
302
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lane.js","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"lane.js","sourceRoot":"","sources":["../../src/tools/lane.ts"],"names":[],"mappings":"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"}
@@ -1,25 +1,14 @@
1
- /**
2
- * p5.js Compatibility Helpers for PinePaper
3
- *
4
- * This module provides p5.js-style drawing functions that wrap Paper.js.
5
- * These helpers are injected into the browser context to allow Claude
6
- * to use familiar p5.js syntax when drawing on the PinePaper canvas.
7
- *
8
- * SUPPORTED FUNCTIONS (v1.3.1):
9
- * - Shapes: circle, ellipse, rect, line, triangle, quad, arc, point
10
- * - Style: fill, noFill, stroke, noStroke, strokeWeight, background
11
- * - Math: random, map, constrain, dist, lerp, radians, degrees
12
- * - Canvas: width, height
13
- * - Mode: rectMode, ellipseMode
14
- * - Constants: PI, TWO_PI, HALF_PI, QUARTER_PI, CENTER, CORNER
15
- */
16
1
  /**
17
2
  * Browser-side p5.js compatibility helpers.
18
3
  * This code is injected into the PinePaper page context and run there as a script.
19
4
  */
20
- export declare const P5_HELPERS = "\n(function() {\n // Prevent double-initialization\n if (window._p5Initialized) {\n console.log('[p5-compat] Already initialized');\n return;\n }\n\n // ==========================================================================\n // STATE MANAGEMENT\n // ==========================================================================\n\n window._p5State = {\n fillColor: '#ffffff',\n strokeColor: '#000000',\n strokeWidth: 1,\n rectMode: 'corner',\n ellipseMode: 'center'\n };\n\n // ==========================================================================\n // CONSTANTS\n // ==========================================================================\n\n window.PI = Math.PI;\n window.TWO_PI = Math.PI * 2;\n window.HALF_PI = Math.PI / 2;\n window.QUARTER_PI = Math.PI / 4;\n\n window.CENTER = 'center';\n window.CORNER = 'corner';\n\n // ==========================================================================\n // CANVAS PROPERTIES\n // ==========================================================================\n\n Object.defineProperty(window, 'width', {\n get: function() {\n return paper.view ? paper.view.size.width : 800;\n },\n configurable: true\n });\n\n Object.defineProperty(window, 'height', {\n get: function() {\n return paper.view ? paper.view.size.height : 600;\n },\n configurable: true\n });\n\n // ==========================================================================\n // MATH UTILITIES\n // ==========================================================================\n\n window.random = function(min, max) {\n if (arguments.length === 0) {\n return Math.random();\n } else if (arguments.length === 1) {\n if (Array.isArray(min)) {\n // random(array) - return random element\n return min[Math.floor(Math.random() * min.length)];\n }\n // random(max) - return 0 to max\n return Math.random() * min;\n } else {\n // random(min, max)\n return Math.random() * (max - min) + min;\n }\n };\n\n window.map = function(value, start1, stop1, start2, stop2) {\n return start2 + (stop2 - start2) * ((value - start1) / (stop1 - start1));\n };\n\n window.constrain = function(value, min, max) {\n return Math.min(Math.max(value, min), max);\n };\n\n window.dist = function(x1, y1, x2, y2) {\n return Math.sqrt((x2 - x1) * (x2 - x1) + (y2 - y1) * (y2 - y1));\n };\n\n window.lerp = function(start, stop, amount) {\n return start + (stop - start) * amount;\n };\n\n window.radians = function(degrees) {\n return degrees * Math.PI / 180;\n };\n\n window.degrees = function(radians) {\n return radians * 180 / Math.PI;\n };\n\n // ==========================================================================\n // STYLE FUNCTIONS\n // ==========================================================================\n\n /**\n * Parse color arguments into a valid color string.\n * Supports: fill(gray), fill(r,g,b), fill(r,g,b,a), fill('#hex')\n */\n function parseColor(args) {\n if (args.length === 0) return null;\n\n if (args.length === 1) {\n var val = args[0];\n if (typeof val === 'string') {\n return val;\n } else if (typeof val === 'number') {\n // Grayscale\n return 'rgb(' + val + ', ' + val + ', ' + val + ')';\n }\n } else if (args.length === 3) {\n // RGB\n return 'rgb(' + args[0] + ', ' + args[1] + ', ' + args[2] + ')';\n } else if (args.length === 4) {\n // RGBA (p5 uses 0-255 for alpha, CSS uses 0-1)\n return 'rgba(' + args[0] + ', ' + args[1] + ', ' + args[2] + ', ' + (args[3] / 255) + ')';\n }\n\n return null;\n }\n\n window.fill = function() {\n var color = parseColor(Array.prototype.slice.call(arguments));\n window._p5State.fillColor = color;\n };\n\n window.noFill = function() {\n window._p5State.fillColor = null;\n };\n\n window.stroke = function() {\n var color = parseColor(Array.prototype.slice.call(arguments));\n window._p5State.strokeColor = color;\n };\n\n window.noStroke = function() {\n window._p5State.strokeColor = null;\n };\n\n window.strokeWeight = function(weight) {\n window._p5State.strokeWidth = weight;\n };\n\n window.background = function() {\n var color = parseColor(Array.prototype.slice.call(arguments));\n if (color && typeof app !== 'undefined' && app.setBackgroundColor) {\n app.setBackgroundColor(color);\n }\n };\n\n // ==========================================================================\n // MODE FUNCTIONS\n // ==========================================================================\n\n window.rectMode = function(mode) {\n window._p5State.rectMode = mode.toLowerCase();\n };\n\n window.ellipseMode = function(mode) {\n window._p5State.ellipseMode = mode.toLowerCase();\n };\n\n // ==========================================================================\n // SHAPE FUNCTIONS\n // ==========================================================================\n\n /**\n * Apply current style state to an item\n */\n function applyStyle(item) {\n if (window._p5State.fillColor) {\n item.fillColor = window._p5State.fillColor;\n }\n if (window._p5State.strokeColor) {\n item.strokeColor = window._p5State.strokeColor;\n item.strokeWidth = window._p5State.strokeWidth;\n }\n }\n\n /**\n * Register item with PinePaper's ItemRegistry\n */\n function registerItem(item, type) {\n if (typeof app !== 'undefined' && app.registerItem) {\n app.registerItem(item, type, { source: 'p5' });\n }\n return item;\n }\n\n /**\n * Draw a circle\n * circle(x, y, diameter)\n */\n window.circle = function(x, y, d) {\n var item = new paper.Path.Circle({\n center: [x, y],\n radius: d / 2\n });\n applyStyle(item);\n return registerItem(item, 'circle');\n };\n\n /**\n * Draw an ellipse\n * ellipse(x, y, width, [height])\n */\n window.ellipse = function(x, y, w, h) {\n h = h !== undefined ? h : w;\n var mode = window._p5State.ellipseMode;\n var center = mode === 'center' ? [x, y] : [x + w / 2, y + h / 2];\n\n var item = new paper.Path.Ellipse({\n center: center,\n size: [w, h]\n });\n applyStyle(item);\n return registerItem(item, 'ellipse');\n };\n\n /**\n * Draw a rectangle\n * rect(x, y, width, height, [cornerRadius])\n */\n window.rect = function(x, y, w, h, r) {\n var mode = window._p5State.rectMode;\n var point = mode === 'center' ? [x - w / 2, y - h / 2] : [x, y];\n\n var options = {\n point: point,\n size: [w, h]\n };\n\n if (r !== undefined && r > 0) {\n options.radius = r;\n }\n\n var item = new paper.Path.Rectangle(options);\n applyStyle(item);\n return registerItem(item, 'rectangle');\n };\n\n /**\n * Draw a line\n * line(x1, y1, x2, y2)\n */\n window.line = function(x1, y1, x2, y2) {\n var item = new paper.Path.Line({\n from: [x1, y1],\n to: [x2, y2]\n });\n // Lines typically don't have fill\n if (window._p5State.strokeColor) {\n item.strokeColor = window._p5State.strokeColor;\n item.strokeWidth = window._p5State.strokeWidth;\n }\n return registerItem(item, 'line');\n };\n\n /**\n * Draw a triangle\n * triangle(x1, y1, x2, y2, x3, y3)\n */\n window.triangle = function(x1, y1, x2, y2, x3, y3) {\n var item = new paper.Path({\n segments: [[x1, y1], [x2, y2], [x3, y3]],\n closed: true\n });\n applyStyle(item);\n return registerItem(item, 'triangle');\n };\n\n /**\n * Draw a quadrilateral\n * quad(x1, y1, x2, y2, x3, y3, x4, y4)\n */\n window.quad = function(x1, y1, x2, y2, x3, y3, x4, y4) {\n var item = new paper.Path({\n segments: [[x1, y1], [x2, y2], [x3, y3], [x4, y4]],\n closed: true\n });\n applyStyle(item);\n return registerItem(item, 'quad');\n };\n\n /**\n * Draw an arc\n * arc(x, y, width, height, startAngle, stopAngle)\n * Note: p5.js uses radians by default\n */\n window.arc = function(x, y, w, h, start, stop) {\n // Calculate the arc using Paper.js\n var cx = x;\n var cy = y;\n var rx = w / 2;\n var ry = h / 2;\n\n // Convert from p5's angle system to Paper.js\n // p5 uses radians where 0 is right, PI/2 is down\n var startDeg = start * 180 / Math.PI;\n var stopDeg = stop * 180 / Math.PI;\n\n // Create arc using path segments\n var item = new paper.Path.Arc({\n from: [\n cx + rx * Math.cos(start),\n cy + ry * Math.sin(start)\n ],\n through: [\n cx + rx * Math.cos((start + stop) / 2),\n cy + ry * Math.sin((start + stop) / 2)\n ],\n to: [\n cx + rx * Math.cos(stop),\n cy + ry * Math.sin(stop)\n ]\n });\n\n applyStyle(item);\n return registerItem(item, 'arc');\n };\n\n /**\n * Draw a point (tiny circle)\n * point(x, y)\n */\n window.point = function(x, y) {\n var size = window._p5State.strokeWidth || 1;\n var item = new paper.Path.Circle({\n center: [x, y],\n radius: size / 2\n });\n // Points use stroke color as fill\n if (window._p5State.strokeColor) {\n item.fillColor = window._p5State.strokeColor;\n }\n return registerItem(item, 'point');\n };\n\n // ==========================================================================\n // INITIALIZATION COMPLETE\n // ==========================================================================\n\n window._p5Initialized = true;\n console.log('[p5-compat] p5.js compatibility layer loaded (v1.3.1)');\n console.log('[p5-compat] Available: circle, ellipse, rect, line, triangle, quad, arc, point');\n console.log('[p5-compat] Style: fill, noFill, stroke, noStroke, strokeWeight, background');\n console.log('[p5-compat] Math: random, map, constrain, dist, lerp, radians, degrees');\n})();\n";
5
+ export declare const P5_HELPERS: string;
21
6
  /**
22
- * Generate code that initializes p5 helpers and executes user code
7
+ * Generate code that initializes p5 helpers and runs the caller's p5-style code in the studio page.
8
+ *
9
+ * SECURITY BOUNDARY: this runs caller-written JavaScript, so it is off unless the person running the server started it
10
+ * with PINEPAPER_ALLOW_CODE=1 (utils/capabilities.ts). The handler refuses first; this refuses again, so no other path
11
+ * can produce the code with the switch off. The code runs in the browser page, never in the server process.
23
12
  */
24
13
  export declare function generateP5DrawCode(userCode: string): string;
25
14
  //# sourceMappingURL=p5-helpers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"p5-helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/p5-compat/p5-helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;GAGG;AACH,eAAO,MAAM,UAAU,ouTA+VtB,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAuB3D"}
1
+ {"version":3,"file":"p5-helpers.d.ts","sourceRoot":"","sources":["../../../src/tools/p5-compat/p5-helpers.ts"],"names":[],"mappings":"AAiBA;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,MA+VxB,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAwB3D"}