@pinepaper.studio/mcp-server 1.5.4 → 1.5.5

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 (36) hide show
  1. package/dist/cli.js +2 -1
  2. package/dist/cli.js.map +1 -1
  3. package/dist/index.js +3 -4
  4. package/dist/index.js.map +1 -1
  5. package/dist/tools/compact-descriptions.d.ts.map +1 -1
  6. package/dist/tools/compact-descriptions.js +0 -1
  7. package/dist/tools/compact-descriptions.js.map +1 -1
  8. package/dist/tools/definitions.d.ts +1 -1
  9. package/dist/tools/definitions.d.ts.map +1 -1
  10. package/dist/tools/definitions.js +19 -546
  11. package/dist/tools/definitions.js.map +1 -1
  12. package/dist/tools/handlers/camera.d.ts.map +1 -1
  13. package/dist/tools/handlers/camera.js +7 -1
  14. package/dist/tools/handlers/camera.js.map +1 -1
  15. package/dist/tools/handlers.d.ts.map +1 -1
  16. package/dist/tools/handlers.js +23 -107
  17. package/dist/tools/handlers.js.map +1 -1
  18. package/dist/tools/minimal-descriptions.d.ts.map +1 -1
  19. package/dist/tools/minimal-descriptions.js +3 -15
  20. package/dist/tools/minimal-descriptions.js.map +1 -1
  21. package/dist/tools/toolkits.d.ts.map +1 -1
  22. package/dist/tools/toolkits.js +4 -21
  23. package/dist/tools/toolkits.js.map +1 -1
  24. package/dist/types/code-generator.d.ts +1 -35
  25. package/dist/types/code-generator.d.ts.map +1 -1
  26. package/dist/types/code-generator.js +107 -500
  27. package/dist/types/code-generator.js.map +1 -1
  28. package/dist/types/schemas.d.ts +9 -622
  29. package/dist/types/schemas.d.ts.map +1 -1
  30. package/dist/types/schemas.js +1 -75
  31. package/dist/types/schemas.js.map +1 -1
  32. package/dist/version.d.ts +11 -0
  33. package/dist/version.d.ts.map +1 -0
  34. package/dist/version.js +18 -0
  35. package/dist/version.js.map +1 -0
  36. package/package.json +1 -1
@@ -134,9 +134,6 @@ Sprite Sheets: pinepaper_sprite_sheet — generate from skeleton poses, play, ex
134
134
  Interaction: pinepaper_interaction — continuous physics behaviors (repel, attract, follow, orbit, slingshot)
135
135
  For interactive storytelling, quizzes, games. trigger_action for state changes (incrementScore, navigate, showFeedback).
136
136
 
137
- Storage: pinepaper_storage — save/load/list/delete projects (IndexedDB persistence)
138
- For multi-project workflows and session recovery.
139
-
140
137
  Data Viz: pinepaper_create_chart — create/update/reconfigure/remove charts (bar, line, scatter, area)
141
138
  Pass data as array of objects + options. Auto-animated with expression-driven oscillation.
142
139
 
@@ -1556,7 +1553,7 @@ USE WHEN:
1556
1553
  - Any animation with specific timing or sequential stages
1557
1554
 
1558
1555
  ANIMATABLE PROPERTIES:
1559
- - position: [x, y] array
1556
+ - position: [x, y] array (a { x, y } object is also accepted and normalized)
1560
1557
  - x, y: Individual coordinates
1561
1558
  - scale: Uniform scale
1562
1559
  - scaleX, scaleY: Axis scaling
@@ -2040,6 +2037,8 @@ ACTIONS:
2040
2037
  Cancel any active animation.
2041
2038
  - state — {}
2042
2039
  Returns { zoom, center, isAnimating }.
2040
+ - fit_view — {}
2041
+ Fit canvas content to the viewport (calls app.fitView()).
2043
2042
 
2044
2043
  EXAMPLES:
2045
2044
  { action: "zoom", direction: "in", level: 2.5 }
@@ -2052,7 +2051,7 @@ EXAMPLES:
2052
2051
  properties: {
2053
2052
  action: {
2054
2053
  type: 'string',
2055
- enum: ['zoom', 'pan', 'move_to', 'reset', 'stop', 'state'],
2054
+ enum: ['zoom', 'pan', 'move_to', 'reset', 'stop', 'state', 'fit_view'],
2056
2055
  description: 'Camera action to perform',
2057
2056
  },
2058
2057
  direction: {
@@ -2592,38 +2591,6 @@ ACTIONS:
2592
2591
  required: ['action'],
2593
2592
  },
2594
2593
  },
2595
- {
2596
- name: 'pinepaper_view',
2597
- annotations: {
2598
- title: 'View',
2599
- readOnlyHint: false,
2600
- destructiveHint: false,
2601
- idempotentHint: false,
2602
- openWorldHint: false,
2603
- },
2604
- description: `View control — fit view to content or get current view state.
2605
-
2606
- ACTIONS:
2607
- - fit: Fit view to content or canvas bounds. Params: mode (content|canvas), padding (number)
2608
- - get_state: Get current view state (zoom, center, bounds)`,
2609
- inputSchema: {
2610
- type: 'object',
2611
- properties: {
2612
- action: {
2613
- type: 'string',
2614
- enum: ['fit', 'get_state'],
2615
- description: 'View action',
2616
- },
2617
- mode: {
2618
- type: 'string',
2619
- enum: ['content', 'canvas'],
2620
- description: 'Fit mode (for fit action)',
2621
- },
2622
- padding: { type: 'number', description: 'Padding around content in pixels (default: 20)' },
2623
- },
2624
- required: ['action'],
2625
- },
2626
- },
2627
2594
  {
2628
2595
  name: 'pinepaper_background',
2629
2596
  annotations: {
@@ -2696,7 +2663,7 @@ ACTIONS:
2696
2663
  },
2697
2664
  },
2698
2665
  // ---------------------------------------------------------------------------
2699
- // DEFORMATION, SPRITE SHEETS, STORAGE, INTERACTION
2666
+ // DEFORMATION, SPRITE SHEETS, INTERACTION
2700
2667
  // ---------------------------------------------------------------------------
2701
2668
  {
2702
2669
  name: 'pinepaper_deform',
@@ -2806,37 +2773,6 @@ ACTIONS:
2806
2773
  required: ['action'],
2807
2774
  },
2808
2775
  },
2809
- {
2810
- name: 'pinepaper_storage',
2811
- annotations: {
2812
- title: 'Storage',
2813
- readOnlyHint: false,
2814
- destructiveHint: true,
2815
- idempotentHint: false,
2816
- openWorldHint: false,
2817
- },
2818
- description: `Persistent project storage via IndexedDB.
2819
-
2820
- ACTIONS:
2821
- - save: Save current project. Params: name, thumbnail (bool)
2822
- - load: Load project onto canvas. Params: projectId
2823
- - list: List all saved projects
2824
- - delete: Delete a saved project. Params: projectId`,
2825
- inputSchema: {
2826
- type: 'object',
2827
- properties: {
2828
- action: {
2829
- type: 'string',
2830
- enum: ['save', 'load', 'list', 'delete'],
2831
- description: 'Storage action',
2832
- },
2833
- projectId: { type: 'string', description: 'Project ID (for load/delete)' },
2834
- name: { type: 'string', description: 'Project name (for save)' },
2835
- thumbnail: { type: 'boolean', description: 'Auto-capture thumbnail on save' },
2836
- },
2837
- required: ['action'],
2838
- },
2839
- },
2840
2776
  {
2841
2777
  name: 'pinepaper_interaction',
2842
2778
  annotations: {
@@ -2935,7 +2871,7 @@ Params: title (page title), download (bool)`,
2935
2871
  },
2936
2872
  },
2937
2873
  // ---------------------------------------------------------------------------
2938
- // LAYER 5 — BLUEPRINTS: TEMPLATE TOOLS
2874
+ // DOMAIN: TEMPLATE TOOL
2939
2875
  // ---------------------------------------------------------------------------
2940
2876
  {
2941
2877
  name: 'pinepaper_apply_template',
@@ -2962,19 +2898,8 @@ MODES:
2962
2898
  2. LOAD MODE: Provide a templateId to apply that template
2963
2899
 
2964
2900
  TEMPLATE CATEGORIES (13):
2965
- - social-media: Social media post/story layouts
2966
- - meme: Meme templates and formats
2967
- - business: Business cards, letterheads, presentations
2968
- - education: Educational diagrams, worksheets
2969
- - creative: Artistic and creative compositions
2970
- - tech: Technology-themed designs
2971
- - global: International and multicultural designs
2972
- - indigenous: Indigenous art-inspired patterns
2973
- - seasonal: Holiday and seasonal themes
2974
- - masking: Mask reveal effect demonstrations
2975
- - scenes: Pre-built animated scenes
2976
- - diagrams: Flowchart and diagram starters
2977
- - maps: Geographic visualization templates
2901
+ - social-media, meme, business, education, creative, tech, global,
2902
+ indigenous, seasonal, masking, scenes, diagrams, maps
2978
2903
 
2979
2904
  EXAMPLES:
2980
2905
  - List all templates: { "listOnly": true }
@@ -4065,33 +3990,6 @@ EXAMPLES:
4065
3990
  required: ['collageId', 'animationType'],
4066
3991
  },
4067
3992
  },
4068
- {
4069
- name: 'pinepaper_get_letter_collage_options',
4070
- annotations: {
4071
- title: 'Get Letter Collage Options',
4072
- readOnlyHint: true,
4073
- destructiveHint: false,
4074
- idempotentHint: true,
4075
- openWorldHint: false,
4076
- },
4077
- description: `[Utility] Get available styles, palettes, and gradient options for letter collages.
4078
-
4079
- USE WHEN:
4080
- - Learning available letter collage styles
4081
- - Discovering palette options
4082
- - Exploring gradient possibilities
4083
- - Building UI for collage creation
4084
-
4085
- RETURNS:
4086
- - styles: All available style types
4087
- - tilePalettes: Grouped by category (game, vibrant, soft, natural, etc.)
4088
- - gradientPalettes: Available gradient color schemes
4089
- - gradientDirections: Direction options for gradients`,
4090
- inputSchema: {
4091
- type: 'object',
4092
- properties: {},
4093
- },
4094
- },
4095
3993
  // ---------------------------------------------------------------------------
4096
3994
  // DOMAIN: GENERATOR TOOLS
4097
3995
  // ---------------------------------------------------------------------------
@@ -4317,409 +4215,6 @@ Filters can be stacked - call multiple times to combine effects.`,
4317
4215
  },
4318
4216
  },
4319
4217
  // ---------------------------------------------------------------------------
4320
- // DOMAIN: INTERACTIVE TRIGGER TOOLS
4321
- // ---------------------------------------------------------------------------
4322
- {
4323
- name: 'pinepaper_add_trigger',
4324
- annotations: {
4325
- title: 'Add Trigger',
4326
- readOnlyHint: false,
4327
- destructiveHint: false,
4328
- idempotentHint: false,
4329
- openWorldHint: false,
4330
- },
4331
- description: `Add an interactive trigger to an item. Triggers execute actions when events occur.
4332
-
4333
- USE WHEN:
4334
- - Making items clickable
4335
- - Adding hover effects
4336
- - Creating drag interactions
4337
- - Building interactive tutorials/quizzes
4338
- - Timeline-based triggers
4339
-
4340
- TRIGGER EVENTS:
4341
- - click: When item is clicked
4342
- - hover_enter: When mouse enters item
4343
- - hover_exit: When mouse leaves item
4344
- - drag_start: When item drag begins
4345
- - drag_move: While item is being dragged
4346
- - drag_end: When item drag ends
4347
- - timeline: At specific time in animation
4348
- - scene_enter: When scene becomes active
4349
- - scene_exit: When scene deactivates
4350
- - animation_end: When item's animation completes
4351
- - quiz_answer: When quiz answer is submitted
4352
-
4353
- ACTION TYPES:
4354
- - show: Make target item visible
4355
- - hide: Hide target item
4356
- - toggle_visibility: Toggle target visibility
4357
- - play_animation: Start animation on target
4358
- - stop_animation: Stop animation on target
4359
- - navigate: Navigate to scene or URL
4360
- - update_property: Change item property
4361
- - set_variable: Set a scene variable
4362
- - submit_answer: Submit quiz answer
4363
- - increment_score: Add to quiz score
4364
- - reset_quiz: Reset quiz state
4365
-
4366
- EXAMPLES:
4367
- - Click to show: {itemId: "button_1", event: "click", actions: [{type: "show", targetItemId: "panel_1"}]}
4368
- - Hover to animate: {itemId: "star_1", event: "hover_enter", actions: [{type: "play_animation", targetItemId: "star_1", animationType: "pulse"}]}
4369
- - Click to navigate: {itemId: "next_btn", event: "click", actions: [{type: "navigate", url: "#scene2"}]}`,
4370
- inputSchema: {
4371
- type: 'object',
4372
- properties: {
4373
- itemId: {
4374
- type: 'string',
4375
- description: 'Item to attach trigger to',
4376
- },
4377
- event: {
4378
- type: 'string',
4379
- enum: ['click', 'hover_enter', 'hover_exit', 'drag_start', 'drag_move', 'drag_end', 'timeline', 'scene_enter', 'scene_exit', 'animation_end', 'quiz_answer'],
4380
- description: 'Event that fires the trigger',
4381
- },
4382
- actions: {
4383
- type: 'array',
4384
- items: {
4385
- type: 'object',
4386
- properties: {
4387
- type: {
4388
- type: 'string',
4389
- enum: ['show', 'hide', 'toggle_visibility', 'play_animation', 'stop_animation', 'navigate', 'update_property', 'set_variable', 'submit_answer', 'increment_score', 'reset_quiz'],
4390
- description: 'Action type',
4391
- },
4392
- targetItemId: {
4393
- type: 'string',
4394
- description: 'Target item for the action',
4395
- },
4396
- animationType: {
4397
- type: 'string',
4398
- description: 'Animation type for play_animation',
4399
- },
4400
- property: {
4401
- type: 'string',
4402
- description: 'Property name for update_property',
4403
- },
4404
- value: {
4405
- description: 'Value for update_property or set_variable',
4406
- },
4407
- variableName: {
4408
- type: 'string',
4409
- description: 'Variable name for set_variable',
4410
- },
4411
- url: {
4412
- type: 'string',
4413
- description: 'URL or scene ID for navigate',
4414
- },
4415
- points: {
4416
- type: 'number',
4417
- description: 'Points for increment_score',
4418
- },
4419
- },
4420
- required: ['type'],
4421
- },
4422
- description: 'Actions to execute when triggered',
4423
- },
4424
- condition: {
4425
- type: 'string',
4426
- description: 'Optional condition expression (e.g., "$score > 10")',
4427
- },
4428
- timelineOffset: {
4429
- type: 'number',
4430
- description: 'Time offset in ms for timeline triggers',
4431
- },
4432
- },
4433
- required: ['itemId', 'event', 'actions'],
4434
- },
4435
- },
4436
- {
4437
- name: 'pinepaper_remove_trigger',
4438
- annotations: {
4439
- title: 'Remove Trigger',
4440
- readOnlyHint: false,
4441
- destructiveHint: true,
4442
- idempotentHint: true,
4443
- openWorldHint: false,
4444
- },
4445
- description: `Remove triggers from an item.
4446
-
4447
- USE WHEN:
4448
- - Disabling interactivity on an item
4449
- - Cleaning up triggers before adding new ones
4450
- - Removing specific event handlers
4451
-
4452
- OPTIONS:
4453
- - Remove specific event: {itemId: "button_1", event: "click"}
4454
- - Remove all triggers: {itemId: "button_1", removeAll: true}`,
4455
- inputSchema: {
4456
- type: 'object',
4457
- properties: {
4458
- itemId: {
4459
- type: 'string',
4460
- description: 'Item to remove triggers from',
4461
- },
4462
- event: {
4463
- type: 'string',
4464
- enum: ['click', 'hover_enter', 'hover_exit', 'drag_start', 'drag_move', 'drag_end', 'timeline', 'scene_enter', 'scene_exit', 'animation_end', 'quiz_answer'],
4465
- description: 'Specific event to remove (optional)',
4466
- },
4467
- removeAll: {
4468
- type: 'boolean',
4469
- description: 'Remove all triggers from item',
4470
- },
4471
- },
4472
- required: ['itemId'],
4473
- },
4474
- },
4475
- {
4476
- name: 'pinepaper_query_triggers',
4477
- annotations: {
4478
- title: 'Query Triggers',
4479
- readOnlyHint: true,
4480
- destructiveHint: false,
4481
- idempotentHint: true,
4482
- openWorldHint: false,
4483
- },
4484
- description: `[Utility] List all triggers on the canvas or for a specific item.
4485
-
4486
- USE WHEN:
4487
- - Inspecting existing interactivity
4488
- - Debugging trigger behavior
4489
- - Understanding scene's interactive elements
4490
-
4491
- EXAMPLES:
4492
- - All triggers: {}
4493
- - Triggers on specific item: {itemId: "button_1"}
4494
- - Filter by event type: {event: "click"}`,
4495
- inputSchema: {
4496
- type: 'object',
4497
- properties: {
4498
- itemId: {
4499
- type: 'string',
4500
- description: 'Filter triggers by item ID',
4501
- },
4502
- event: {
4503
- type: 'string',
4504
- enum: ['click', 'hover_enter', 'hover_exit', 'drag_start', 'drag_move', 'drag_end', 'timeline', 'scene_enter', 'scene_exit', 'animation_end', 'quiz_answer'],
4505
- description: 'Filter by event type',
4506
- },
4507
- },
4508
- },
4509
- },
4510
- // ---------------------------------------------------------------------------
4511
- // DOMAIN: QUIZ/LMS TOOLS
4512
- // ---------------------------------------------------------------------------
4513
- {
4514
- name: 'pinepaper_create_quiz',
4515
- annotations: {
4516
- title: 'Create Quiz',
4517
- readOnlyHint: false,
4518
- destructiveHint: false,
4519
- idempotentHint: false,
4520
- openWorldHint: false,
4521
- },
4522
- description: `Create an interactive quiz with questions, answers, and scoring.
4523
-
4524
- USE WHEN:
4525
- - Building educational content
4526
- - Creating assessments
4527
- - Adding gamification elements
4528
- - Making interactive learning modules
4529
-
4530
- QUESTION TYPES:
4531
- - multiple-choice: Single correct answer from options
4532
- - multiple-select: Multiple correct answers
4533
- - drag-drop: Drag items to correct zones
4534
- - matching: Match pairs of items
4535
- - sequencing: Put items in correct order
4536
- - hotspot: Click correct area on image
4537
- - true-false: True or false question
4538
-
4539
- FEEDBACK:
4540
- Each question can have:
4541
- - correctFeedback: Message shown on correct answer
4542
- - incorrectFeedback: Message shown on wrong answer
4543
- - partialFeedback: Message for partially correct (multi-select)
4544
-
4545
- SCORING:
4546
- - Each question has a points value
4547
- - passingScore: Minimum score to pass
4548
- - showScore: Display score during quiz
4549
- - allowRetry: Allow retrying incorrect answers
4550
-
4551
- EXAMPLE:
4552
- {
4553
- "title": "Geography Quiz",
4554
- "questions": [
4555
- {
4556
- "type": "multiple-choice",
4557
- "prompt": "What is the capital of France?",
4558
- "options": [
4559
- {"id": "a", "label": "London"},
4560
- {"id": "b", "label": "Paris", "isCorrect": true},
4561
- {"id": "c", "label": "Berlin"}
4562
- ],
4563
- "points": 10,
4564
- "correctFeedback": "Correct! Paris is the capital.",
4565
- "incorrectFeedback": "Sorry, the correct answer is Paris."
4566
- }
4567
- ],
4568
- "passingScore": 70,
4569
- "showScore": true
4570
- }`,
4571
- inputSchema: {
4572
- type: 'object',
4573
- properties: {
4574
- title: {
4575
- type: 'string',
4576
- description: 'Quiz title',
4577
- },
4578
- questions: {
4579
- type: 'array',
4580
- items: {
4581
- type: 'object',
4582
- properties: {
4583
- type: {
4584
- type: 'string',
4585
- enum: ['multiple-choice', 'multiple-select', 'drag-drop', 'matching', 'sequencing', 'hotspot', 'true-false'],
4586
- description: 'Question type',
4587
- },
4588
- prompt: {
4589
- type: 'string',
4590
- description: 'Question text',
4591
- },
4592
- options: {
4593
- type: 'array',
4594
- items: {
4595
- type: 'object',
4596
- properties: {
4597
- id: { type: 'string' },
4598
- label: { type: 'string' },
4599
- isCorrect: { type: 'boolean' },
4600
- },
4601
- },
4602
- description: 'Answer options',
4603
- },
4604
- points: {
4605
- type: 'number',
4606
- description: 'Points for correct answer',
4607
- },
4608
- correctFeedback: {
4609
- type: 'string',
4610
- description: 'Feedback for correct answer',
4611
- },
4612
- incorrectFeedback: {
4613
- type: 'string',
4614
- description: 'Feedback for incorrect answer',
4615
- },
4616
- draggableItems: {
4617
- type: 'array',
4618
- items: { type: 'string' },
4619
- description: 'Item IDs that can be dragged (for drag-drop)',
4620
- },
4621
- dropZones: {
4622
- type: 'array',
4623
- items: {
4624
- type: 'object',
4625
- properties: {
4626
- id: { type: 'string' },
4627
- correctItems: { type: 'array', items: { type: 'string' } },
4628
- },
4629
- },
4630
- description: 'Drop zones with correct items (for drag-drop)',
4631
- },
4632
- },
4633
- required: ['type', 'prompt', 'points'],
4634
- },
4635
- description: 'Quiz questions',
4636
- },
4637
- passingScore: {
4638
- type: 'number',
4639
- description: 'Minimum percentage to pass (0-100)',
4640
- },
4641
- showScore: {
4642
- type: 'boolean',
4643
- description: 'Display score during quiz',
4644
- },
4645
- allowRetry: {
4646
- type: 'boolean',
4647
- description: 'Allow retrying incorrect answers',
4648
- },
4649
- shuffleQuestions: {
4650
- type: 'boolean',
4651
- description: 'Randomize question order',
4652
- },
4653
- shuffleOptions: {
4654
- type: 'boolean',
4655
- description: 'Randomize answer options',
4656
- },
4657
- },
4658
- required: ['questions'],
4659
- },
4660
- },
4661
- {
4662
- name: 'pinepaper_get_quiz_state',
4663
- annotations: {
4664
- title: 'Get Quiz State',
4665
- readOnlyHint: true,
4666
- destructiveHint: false,
4667
- idempotentHint: true,
4668
- openWorldHint: false,
4669
- },
4670
- description: `[Utility] Get the current state of an active quiz.
4671
-
4672
- USE WHEN:
4673
- - Checking quiz progress
4674
- - Getting current score
4675
- - Reviewing answered questions
4676
- - Debugging quiz behavior
4677
-
4678
- RETURNS:
4679
- - quizId: Quiz identifier
4680
- - currentQuestion: Current question index
4681
- - totalQuestions: Total number of questions
4682
- - score: Current score
4683
- - maxScore: Maximum possible score
4684
- - answers: Array of submitted answers
4685
- - passed: Whether passing score achieved (if complete)
4686
- - complete: Whether quiz is finished`,
4687
- inputSchema: {
4688
- type: 'object',
4689
- properties: {
4690
- quizId: {
4691
- type: 'string',
4692
- description: 'Quiz ID (optional, uses active quiz if not specified)',
4693
- },
4694
- },
4695
- },
4696
- },
4697
- {
4698
- name: 'pinepaper_reset_quiz',
4699
- annotations: {
4700
- title: 'Reset Quiz',
4701
- readOnlyHint: false,
4702
- destructiveHint: true,
4703
- idempotentHint: true,
4704
- openWorldHint: false,
4705
- },
4706
- description: `Reset a quiz to its initial state.
4707
-
4708
- USE WHEN:
4709
- - Restarting a quiz
4710
- - Clearing quiz progress
4711
- - Allowing user to retake quiz`,
4712
- inputSchema: {
4713
- type: 'object',
4714
- properties: {
4715
- quizId: {
4716
- type: 'string',
4717
- description: 'Quiz ID (optional, uses active quiz if not specified)',
4718
- },
4719
- },
4720
- },
4721
- },
4722
- // ---------------------------------------------------------------------------
4723
4218
  // INFRASTRUCTURE: QUERY TOOLS
4724
4219
  // ---------------------------------------------------------------------------
4725
4220
  {
@@ -5341,7 +4836,11 @@ EFFECTS:
5341
4836
  PLAYBACK:
5342
4837
  play_timeline — {action: "play"|"stop"|"seek", duration, loop}
5343
4838
 
5344
- VARIABLE REFERENCES: "$0", "$1" etc. reference items by creation order within the batch.
4839
+ VARIABLE REFERENCES: "$0", "$1" etc. reference items by creation order within the batch. Place ALL create ops before any ops that reference them so the indices stay stable.
4840
+
4841
+ ANIMATION NOTES:
4842
+ - keyframe_animate position accepts [x, y] or { x, y } (normalized). fillColor/strokeColor accept rgba() for alpha. The create "opacity" and "blendMode" props are applied to the item.
4843
+ - For MP4/GIF export the keyframe timeline is rendered once across the duration; author motion to fill the clip and use loop:false. Looping item-animations (loop:true) are not advanced by the exporter and render frozen.
5345
4844
 
5346
4845
  EXAMPLE — Animated sky scene with timed reveals:
5347
4846
  {operations: [
@@ -5521,6 +5020,12 @@ EXAMPLES:
5521
5020
  enum: ['canvas', 'camera'],
5522
5021
  description: 'Output framing. "canvas" (default) renders the full canvas. "camera" renders only the first-keyframe viewport of a camera_animates walkthrough — video formats only.',
5523
5022
  },
5023
+ duration: {
5024
+ type: 'number',
5025
+ minimum: 0.5,
5026
+ maximum: 60,
5027
+ description: 'Video duration in seconds for mp4/webm/gif (default 5, max 60). Static formats ignore this. If you set play_timeline to N seconds, pass the same N here.',
5028
+ },
5524
5029
  },
5525
5030
  required: ['platform'],
5526
5031
  },
@@ -5581,38 +5086,6 @@ EXAMPLE RESPONSE:
5581
5086
  },
5582
5087
  },
5583
5088
  // ---------------------------------------------------------------------------
5584
- // LAYER 1 — ATOMS: CANVAS PRESETS TOOL
5585
- // ---------------------------------------------------------------------------
5586
- {
5587
- name: 'pinepaper_get_canvas_presets',
5588
- annotations: {
5589
- title: 'Get Canvas Presets',
5590
- readOnlyHint: true,
5591
- destructiveHint: false,
5592
- idempotentHint: true,
5593
- openWorldHint: false,
5594
- },
5595
- description: `[Utility] List all available canvas presets with their dimensions.
5596
-
5597
- USE WHEN:
5598
- - Setting up canvas for specific platforms (YouTube, Instagram, TikTok, etc.)
5599
- - Discovering available size presets
5600
- - Planning content dimensions
5601
- - Building UI for size selection
5602
-
5603
- PRESETS BY CATEGORY:
5604
- - Video: youtube-thumbnail, youtube-short, tiktok, hd-720p, full-hd-1080p
5605
- - Social: instagram-story, instagram-post, facebook-post, twitter-post, linkedin-post, pinterest-pin
5606
- - Presentation: presentation-16x9, presentation-4x3
5607
-
5608
- RETURNS:
5609
- Array of presets with: key, name, width, height, aspectRatio, category`,
5610
- inputSchema: {
5611
- type: 'object',
5612
- properties: {},
5613
- },
5614
- },
5615
- // ---------------------------------------------------------------------------
5616
5089
  // COMPATIBILITY: P5.JS TOOLS
5617
5090
  // ---------------------------------------------------------------------------
5618
5091
  {