@pinepaper.studio/mcp-server 1.4.2 → 1.5.0

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 (199) hide show
  1. package/README.md +213 -18
  2. package/dist/__tests__/fixtures/mock-generators.d.ts +147 -0
  3. package/dist/__tests__/fixtures/mock-generators.d.ts.map +1 -1
  4. package/dist/__tests__/fixtures/mock-generators.js +85 -0
  5. package/dist/__tests__/fixtures/mock-generators.js.map +1 -1
  6. package/dist/agent/export-manager.d.ts +77 -0
  7. package/dist/agent/export-manager.d.ts.map +1 -0
  8. package/dist/agent/export-manager.js +455 -0
  9. package/dist/agent/export-manager.js.map +1 -0
  10. package/dist/agent/index.d.ts +9 -0
  11. package/dist/agent/index.d.ts.map +1 -0
  12. package/dist/agent/index.js +12 -0
  13. package/dist/agent/index.js.map +1 -0
  14. package/dist/agent/session-manager.d.ts +109 -0
  15. package/dist/agent/session-manager.d.ts.map +1 -0
  16. package/dist/agent/session-manager.js +311 -0
  17. package/dist/agent/session-manager.js.map +1 -0
  18. package/dist/agent/types.d.ts +385 -0
  19. package/dist/agent/types.d.ts.map +1 -0
  20. package/dist/agent/types.js +141 -0
  21. package/dist/agent/types.js.map +1 -0
  22. package/dist/browser/index.d.ts +1 -1
  23. package/dist/browser/index.d.ts.map +1 -1
  24. package/dist/browser/index.js +1 -1
  25. package/dist/browser/index.js.map +1 -1
  26. package/dist/browser/puppeteer-controller.d.ts +89 -5
  27. package/dist/browser/puppeteer-controller.d.ts.map +1 -1
  28. package/dist/browser/puppeteer-controller.js +412 -11
  29. package/dist/browser/puppeteer-controller.js.map +1 -1
  30. package/dist/cli.js +3 -2
  31. package/dist/cli.js.map +1 -1
  32. package/dist/i18n/locales/ar.d.ts.map +1 -1
  33. package/dist/i18n/locales/ar.js +37 -0
  34. package/dist/i18n/locales/ar.js.map +1 -1
  35. package/dist/i18n/locales/base.d.ts.map +1 -1
  36. package/dist/i18n/locales/base.js +49 -0
  37. package/dist/i18n/locales/base.js.map +1 -1
  38. package/dist/i18n/locales/bn.d.ts.map +1 -1
  39. package/dist/i18n/locales/bn.js +10 -0
  40. package/dist/i18n/locales/bn.js.map +1 -1
  41. package/dist/i18n/locales/cs.d.ts.map +1 -1
  42. package/dist/i18n/locales/cs.js +10 -0
  43. package/dist/i18n/locales/cs.js.map +1 -1
  44. package/dist/i18n/locales/da.d.ts.map +1 -1
  45. package/dist/i18n/locales/da.js +10 -0
  46. package/dist/i18n/locales/da.js.map +1 -1
  47. package/dist/i18n/locales/de.d.ts.map +1 -1
  48. package/dist/i18n/locales/de.js +107 -0
  49. package/dist/i18n/locales/de.js.map +1 -1
  50. package/dist/i18n/locales/el.d.ts.map +1 -1
  51. package/dist/i18n/locales/el.js +10 -0
  52. package/dist/i18n/locales/el.js.map +1 -1
  53. package/dist/i18n/locales/en.d.ts.map +1 -1
  54. package/dist/i18n/locales/en.js +162 -0
  55. package/dist/i18n/locales/en.js.map +1 -1
  56. package/dist/i18n/locales/es.d.ts.map +1 -1
  57. package/dist/i18n/locales/es.js +106 -0
  58. package/dist/i18n/locales/es.js.map +1 -1
  59. package/dist/i18n/locales/fa.d.ts.map +1 -1
  60. package/dist/i18n/locales/fa.js +10 -0
  61. package/dist/i18n/locales/fa.js.map +1 -1
  62. package/dist/i18n/locales/fi.d.ts.map +1 -1
  63. package/dist/i18n/locales/fi.js +10 -0
  64. package/dist/i18n/locales/fi.js.map +1 -1
  65. package/dist/i18n/locales/fil.d.ts.map +1 -1
  66. package/dist/i18n/locales/fil.js +10 -0
  67. package/dist/i18n/locales/fil.js.map +1 -1
  68. package/dist/i18n/locales/fr.d.ts.map +1 -1
  69. package/dist/i18n/locales/fr.js +37 -0
  70. package/dist/i18n/locales/fr.js.map +1 -1
  71. package/dist/i18n/locales/gu.d.ts.map +1 -1
  72. package/dist/i18n/locales/gu.js +10 -0
  73. package/dist/i18n/locales/gu.js.map +1 -1
  74. package/dist/i18n/locales/he.d.ts.map +1 -1
  75. package/dist/i18n/locales/he.js +10 -0
  76. package/dist/i18n/locales/he.js.map +1 -1
  77. package/dist/i18n/locales/hi.d.ts.map +1 -1
  78. package/dist/i18n/locales/hi.js +37 -0
  79. package/dist/i18n/locales/hi.js.map +1 -1
  80. package/dist/i18n/locales/hu.d.ts.map +1 -1
  81. package/dist/i18n/locales/hu.js +10 -0
  82. package/dist/i18n/locales/hu.js.map +1 -1
  83. package/dist/i18n/locales/id.d.ts.map +1 -1
  84. package/dist/i18n/locales/id.js +108 -0
  85. package/dist/i18n/locales/id.js.map +1 -1
  86. package/dist/i18n/locales/is.d.ts.map +1 -1
  87. package/dist/i18n/locales/is.js +10 -0
  88. package/dist/i18n/locales/is.js.map +1 -1
  89. package/dist/i18n/locales/it.d.ts.map +1 -1
  90. package/dist/i18n/locales/it.js +108 -0
  91. package/dist/i18n/locales/it.js.map +1 -1
  92. package/dist/i18n/locales/ja.d.ts.map +1 -1
  93. package/dist/i18n/locales/ja.js +108 -0
  94. package/dist/i18n/locales/ja.js.map +1 -1
  95. package/dist/i18n/locales/kn.d.ts.map +1 -1
  96. package/dist/i18n/locales/kn.js +10 -0
  97. package/dist/i18n/locales/kn.js.map +1 -1
  98. package/dist/i18n/locales/ko.d.ts.map +1 -1
  99. package/dist/i18n/locales/ko.js +37 -0
  100. package/dist/i18n/locales/ko.js.map +1 -1
  101. package/dist/i18n/locales/ml.d.ts.map +1 -1
  102. package/dist/i18n/locales/ml.js +10 -0
  103. package/dist/i18n/locales/ml.js.map +1 -1
  104. package/dist/i18n/locales/mr.d.ts.map +1 -1
  105. package/dist/i18n/locales/mr.js +10 -0
  106. package/dist/i18n/locales/mr.js.map +1 -1
  107. package/dist/i18n/locales/ms.d.ts.map +1 -1
  108. package/dist/i18n/locales/ms.js +10 -0
  109. package/dist/i18n/locales/ms.js.map +1 -1
  110. package/dist/i18n/locales/nl.d.ts.map +1 -1
  111. package/dist/i18n/locales/nl.js +108 -0
  112. package/dist/i18n/locales/nl.js.map +1 -1
  113. package/dist/i18n/locales/no.d.ts.map +1 -1
  114. package/dist/i18n/locales/no.js +10 -0
  115. package/dist/i18n/locales/no.js.map +1 -1
  116. package/dist/i18n/locales/pa.d.ts.map +1 -1
  117. package/dist/i18n/locales/pa.js +10 -0
  118. package/dist/i18n/locales/pa.js.map +1 -1
  119. package/dist/i18n/locales/pl.d.ts.map +1 -1
  120. package/dist/i18n/locales/pl.js +108 -0
  121. package/dist/i18n/locales/pl.js.map +1 -1
  122. package/dist/i18n/locales/pt-BR.d.ts.map +1 -1
  123. package/dist/i18n/locales/pt-BR.js +108 -0
  124. package/dist/i18n/locales/pt-BR.js.map +1 -1
  125. package/dist/i18n/locales/pt.d.ts.map +1 -1
  126. package/dist/i18n/locales/pt.js +10 -0
  127. package/dist/i18n/locales/pt.js.map +1 -1
  128. package/dist/i18n/locales/ro.d.ts.map +1 -1
  129. package/dist/i18n/locales/ro.js +10 -0
  130. package/dist/i18n/locales/ro.js.map +1 -1
  131. package/dist/i18n/locales/ru.d.ts.map +1 -1
  132. package/dist/i18n/locales/ru.js +108 -0
  133. package/dist/i18n/locales/ru.js.map +1 -1
  134. package/dist/i18n/locales/sv.d.ts.map +1 -1
  135. package/dist/i18n/locales/sv.js +10 -0
  136. package/dist/i18n/locales/sv.js.map +1 -1
  137. package/dist/i18n/locales/ta.d.ts.map +1 -1
  138. package/dist/i18n/locales/ta.js +10 -0
  139. package/dist/i18n/locales/ta.js.map +1 -1
  140. package/dist/i18n/locales/te.d.ts.map +1 -1
  141. package/dist/i18n/locales/te.js +10 -0
  142. package/dist/i18n/locales/te.js.map +1 -1
  143. package/dist/i18n/locales/th.d.ts.map +1 -1
  144. package/dist/i18n/locales/th.js +108 -0
  145. package/dist/i18n/locales/th.js.map +1 -1
  146. package/dist/i18n/locales/tl.d.ts.map +1 -1
  147. package/dist/i18n/locales/tl.js +10 -0
  148. package/dist/i18n/locales/tl.js.map +1 -1
  149. package/dist/i18n/locales/tr.d.ts.map +1 -1
  150. package/dist/i18n/locales/tr.js +108 -0
  151. package/dist/i18n/locales/tr.js.map +1 -1
  152. package/dist/i18n/locales/uk.d.ts.map +1 -1
  153. package/dist/i18n/locales/uk.js +108 -0
  154. package/dist/i18n/locales/uk.js.map +1 -1
  155. package/dist/i18n/locales/ur.d.ts.map +1 -1
  156. package/dist/i18n/locales/ur.js +10 -0
  157. package/dist/i18n/locales/ur.js.map +1 -1
  158. package/dist/i18n/locales/vi.d.ts.map +1 -1
  159. package/dist/i18n/locales/vi.js +108 -0
  160. package/dist/i18n/locales/vi.js.map +1 -1
  161. package/dist/i18n/locales/zh-CN.d.ts.map +1 -1
  162. package/dist/i18n/locales/zh-CN.js +108 -0
  163. package/dist/i18n/locales/zh-CN.js.map +1 -1
  164. package/dist/i18n/locales/zh-TW.d.ts.map +1 -1
  165. package/dist/i18n/locales/zh-TW.js +108 -0
  166. package/dist/i18n/locales/zh-TW.js.map +1 -1
  167. package/dist/index.d.ts +3 -0
  168. package/dist/index.d.ts.map +1 -1
  169. package/dist/index.js +2717 -147
  170. package/dist/index.js.map +1 -1
  171. package/dist/prompts/index.d.ts +39 -0
  172. package/dist/prompts/index.d.ts.map +1 -0
  173. package/dist/prompts/index.js +254 -0
  174. package/dist/prompts/index.js.map +1 -0
  175. package/dist/tools/compact-descriptions.d.ts +9 -0
  176. package/dist/tools/compact-descriptions.d.ts.map +1 -0
  177. package/dist/tools/compact-descriptions.js +260 -0
  178. package/dist/tools/compact-descriptions.js.map +1 -0
  179. package/dist/tools/definitions.d.ts +12 -0
  180. package/dist/tools/definitions.d.ts.map +1 -1
  181. package/dist/tools/definitions.js +4921 -957
  182. package/dist/tools/definitions.js.map +1 -1
  183. package/dist/tools/handlers.d.ts.map +1 -1
  184. package/dist/tools/handlers.js +985 -17
  185. package/dist/tools/handlers.js.map +1 -1
  186. package/dist/tools/index.d.ts +2 -1
  187. package/dist/tools/index.d.ts.map +1 -1
  188. package/dist/tools/index.js +1 -1
  189. package/dist/tools/index.js.map +1 -1
  190. package/dist/types/code-generator.d.ts +233 -1
  191. package/dist/types/code-generator.d.ts.map +1 -1
  192. package/dist/types/code-generator.js +2578 -26
  193. package/dist/types/code-generator.js.map +1 -1
  194. package/dist/types/schemas.d.ts +5438 -805
  195. package/dist/types/schemas.d.ts.map +1 -1
  196. package/dist/types/schemas.js +1135 -4
  197. package/dist/types/schemas.js.map +1 -1
  198. package/manifest.json +106 -2
  199. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -11,92 +11,127 @@
11
11
  */
12
12
  import { Server } from '@modelcontextprotocol/sdk/server/index.js';
13
13
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
14
- import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
15
- import { PINEPAPER_TOOLS } from './tools/definitions.js';
14
+ import { CallToolRequestSchema, ListToolsRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
15
+ import { PINEPAPER_TOOLS, getToolsForVerbosity } from './tools/definitions.js';
16
16
  import { handleToolCall, getExecutionMode } from './tools/handlers.js';
17
17
  import { initI18n, DEFAULT_LOCALE, } from './i18n/index.js';
18
+ import { PROMPTS, getPromptMessages } from './prompts/index.js';
18
19
  // =============================================================================
19
20
  // SERVER INFO
20
21
  // =============================================================================
21
22
  const SERVER_INFO = {
22
23
  name: 'pinepaper-mcp',
23
- version: '1.4.0',
24
+ version: '1.5.0',
24
25
  description: 'MCP Server for PinePaper Studio - Create animated graphics with AI',
25
26
  };
26
27
  // =============================================================================
27
28
  // RESOURCES (Documentation & Examples)
28
29
  // =============================================================================
29
30
  const RESOURCES = [
31
+ // === CORE GUIDES (Start here) ===
30
32
  {
31
33
  uri: 'pinepaper://docs/getting-started',
32
- name: 'Getting Started Guide',
33
- description: 'Introduction to PinePaper MCP tools',
34
+ name: '🚀 Getting Started',
35
+ description: 'START HERE: Tool categories, quick examples, and how to find the right tools',
36
+ mimeType: 'text/markdown',
37
+ },
38
+ {
39
+ uri: 'pinepaper://docs/templates',
40
+ name: '📋 Templates Guide',
41
+ description: 'Pre-built templates with animations ready - just change content. Check here first!',
42
+ mimeType: 'text/markdown',
43
+ },
44
+ // === FEATURE GUIDES (How to use each feature) ===
45
+ {
46
+ uri: 'pinepaper://docs/map-tools',
47
+ name: '🗺️ Maps Guide',
48
+ description: 'Create USA state maps, world maps, choropleth coloring, and animated map regions',
49
+ mimeType: 'text/markdown',
50
+ },
51
+ {
52
+ uri: 'pinepaper://docs/diagrams',
53
+ name: '📊 Diagrams Guide',
54
+ description: 'Create flowcharts, UML diagrams, network diagrams, and auto-layout',
55
+ mimeType: 'text/markdown',
56
+ },
57
+ {
58
+ uri: 'pinepaper://docs/masks',
59
+ name: '🎭 Masks Guide',
60
+ description: 'Create reveal effects: wipes, iris, curtains, and custom animated masks',
34
61
  mimeType: 'text/markdown',
35
62
  },
36
63
  {
37
64
  uri: 'pinepaper://docs/relations',
38
- name: 'Relations Guide',
39
- description: 'How to use relations for behavior-driven animation',
65
+ name: '🔄 Animation Guide',
66
+ description: 'Animate with relations: orbit, follow, attached, bounce, and more',
40
67
  mimeType: 'text/markdown',
41
68
  },
42
69
  {
43
70
  uri: 'pinepaper://docs/generators',
44
- name: 'Background Generators',
45
- description: 'Available procedural background generators',
71
+ name: '🎨 Backgrounds Guide',
72
+ description: 'Create procedural backgrounds: 14 generators including sunburst, grid, waves, bokeh, gradient mesh, wind field, noise textures',
46
73
  mimeType: 'text/markdown',
47
74
  },
48
75
  {
49
- uri: 'pinepaper://docs/custom-paths',
50
- name: 'Custom Paths Guide',
51
- description: 'Advanced path creation with SVG, Paper.js paths, and animations',
76
+ uri: 'pinepaper://docs/effects-and-filters',
77
+ name: '✨ Effects Guide',
78
+ description: 'Add visual effects: sparkle, blast, filters, and post-processing',
52
79
  mimeType: 'text/markdown',
53
80
  },
54
81
  {
55
- uri: 'pinepaper://docs/mathematical-patterns',
56
- name: 'Mathematical Patterns',
57
- description: 'Create spirals, waves, fractals, geometric patterns, and physics simulations',
82
+ uri: 'pinepaper://docs/customization',
83
+ name: '🔧 Customization Guide',
84
+ description: 'How to adapt templates, create custom designs, and handle any user request',
58
85
  mimeType: 'text/markdown',
59
86
  },
87
+ // === EXAMPLES (Copy-paste workflows) ===
60
88
  {
61
- uri: 'pinepaper://docs/effects-and-filters',
62
- name: 'Effects & Filters Guide',
63
- description: 'Complete reference for visual effects, filters, and post-processing',
89
+ uri: 'pinepaper://examples/us-states-animated',
90
+ name: '🇺🇸 US States Animated',
91
+ description: 'EXAMPLE: Create a US map with random colors that animate in a loop',
64
92
  mimeType: 'text/markdown',
65
93
  },
66
94
  {
67
- uri: 'pinepaper://docs/interactive-animations',
68
- name: 'Interactive Animations',
69
- description: 'Create game-like behaviors with follows, bounds, and dynamic interactions',
95
+ uri: 'pinepaper://examples/world-population-map',
96
+ name: '🌍 World Population Map',
97
+ description: 'EXAMPLE: Choropleth map with population data and color scale',
70
98
  mimeType: 'text/markdown',
71
99
  },
72
100
  {
73
- uri: 'pinepaper://docs/paperjs-in-pinepaper',
74
- name: 'Paper.js in PinePaper',
75
- description: 'Write Paper.js code directly in PinePaper - API reference and examples',
101
+ uri: 'pinepaper://examples/flowchart',
102
+ name: '📋 Flowchart Example',
103
+ description: 'EXAMPLE: Create a decision flowchart with auto-layout',
76
104
  mimeType: 'text/markdown',
77
105
  },
78
106
  {
79
107
  uri: 'pinepaper://examples/solar-system',
80
- name: 'Solar System Example',
81
- description: 'Create an animated solar system with custom paths, orbital rings, and planetary details',
108
+ name: '🪐 Solar System',
109
+ description: 'EXAMPLE: Orbiting planets with relations',
82
110
  mimeType: 'text/markdown',
83
111
  },
84
112
  {
85
- uri: 'pinepaper://examples/logo-animation',
86
- name: 'Logo Animation Example',
87
- description: 'Animate a company logo with entrance effects and continuous motion',
113
+ uri: 'pinepaper://examples/reveal-animation',
114
+ name: '🎬 Reveal Animation',
115
+ description: 'EXAMPLE: Text reveal with mask animations',
88
116
  mimeType: 'text/markdown',
89
117
  },
90
118
  {
91
- uri: 'pinepaper://examples/data-visualization',
92
- name: 'Data Visualization Example',
93
- description: 'Create animated charts, graphs, and infographics',
119
+ uri: 'pinepaper://docs/fonts',
120
+ name: 'Guide: Font Studio',
121
+ description: 'Create custom hand-drawn fonts with Font Studio tools',
94
122
  mimeType: 'text/markdown',
95
123
  },
124
+ // === ADVANCED (For developers) ===
96
125
  {
97
- uri: 'pinepaper://examples/particle-systems',
98
- name: 'Particle Systems Example',
99
- description: 'Build particle effects like fireworks, snow, and starfields',
126
+ uri: 'pinepaper://docs/custom-paths',
127
+ name: 'Advanced: Custom Paths',
128
+ description: 'SVG paths, Paper.js paths, and path animations',
129
+ mimeType: 'text/markdown',
130
+ },
131
+ {
132
+ uri: 'pinepaper://docs/paperjs-in-pinepaper',
133
+ name: 'Advanced: Paper.js API',
134
+ description: 'Write Paper.js code directly for full control',
100
135
  mimeType: 'text/markdown',
101
136
  },
102
137
  ];
@@ -105,70 +140,457 @@ const RESOURCE_CONTENTS = {
105
140
 
106
141
  ## Overview
107
142
 
108
- PinePaper is a canvas-based animation tool. This MCP server lets you create and animate graphics using natural language.
143
+ PinePaper is a canvas-based animation tool with 121 tools for creating animated graphics, custom fonts, maps, diagrams, and more. This guide helps you find the right tools.
109
144
 
110
- ## Quick Start
145
+ ## FIRST: Check Templates
111
146
 
112
- 1. **Connect to browser**: Use \`pinepaper_browser_connect\` to launch PinePaper Studio
113
- 2. **Clear the canvas**: Use \`pinepaper_clear_canvas\` or \`pinepaper_refresh_page\` to start fresh
114
- 3. **Create items**: Use \`pinepaper_create_item\` to add text, shapes, or graphics
115
- 4. **Add animation**: Use \`pinepaper_add_relation\` for behavior-based animation
116
- 5. **Verify**: Use \`pinepaper_browser_screenshot\` to see your work
117
- 6. **Export**: Use \`pinepaper_export_svg\` to save your work
147
+ PinePaper Studio includes pre-built templates for common use cases. **Templates already have animations configured** - you just change the content!
118
148
 
119
- ## IMPORTANT: Welcome Template
149
+ **Before building from scratch, consider:**
150
+ - Is there a template that matches this use case?
151
+ - Can I modify an existing template instead of building new?
152
+ - Templates save time: just update text, colors, or data
153
+
154
+ **Use \`pinepaper_create_scene\` for complex animated scenes** - it's 4-8x faster than individual tool calls:
155
+
156
+ \`\`\`
157
+ pinepaper_create_scene
158
+ backgroundColor: "#0a0a0a"
159
+ items:
160
+ - name: "sun", itemType: "circle", position: {x: 400, y: 300}, properties: {radius: 50, color: "#fbbf24"}
161
+ - name: "earth", itemType: "circle", position: {x: 550, y: 300}, properties: {radius: 20, color: "#3b82f6"}
162
+ relations:
163
+ - source: "earth", target: "sun", type: "orbits", params: {radius: 150, speed: 0.5}
164
+ animations:
165
+ - target: "sun", type: "pulse", speed: 0.3
166
+ \`\`\`
167
+
168
+ ## Tool Categories at a Glance
169
+
170
+ | Category | Use When | Key Tools |
171
+ |----------|----------|-----------|
172
+ | **Scenes** | Multi-item animated scenes | \`pinepaper_create_scene\` (FASTEST) |
173
+ | **Maps** | US states, world maps, choropleth | \`pinepaper_load_map\`, \`pinepaper_apply_data_colors\`, \`pinepaper_animate_map_regions\` |
174
+ | **Shapes** | Circles, stars, text, rectangles | \`pinepaper_create_item\` |
175
+ | **Animation** | Orbiting, following, pulsing | \`pinepaper_add_relation\`, \`pinepaper_animate\` |
176
+ | **Masks** | Reveal effects, wipes, transitions | \`pinepaper_apply_animated_mask\` |
177
+ | **Diagrams** | Flowcharts, UML, connections | \`pinepaper_create_diagram_shape\`, \`pinepaper_connect\` |
178
+ | **Backgrounds** | Patterns, gradients, generators | \`pinepaper_execute_generator\` |
179
+
180
+ ## Quick Examples
181
+
182
+ ### Create a US Map with Animated Colors
183
+ \`\`\`
184
+ 1. pinepaper_load_map mapId: "usa", options: { projection: "albers" }
185
+ 2. pinepaper_apply_data_colors data: { "CA": 100, "TX": 80, "NY": 70 }, options: { colorScale: "blues" }
186
+ 3. pinepaper_animate_map_wave duration: 10, loop: true, colors: ["#ef4444", "#22c55e", "#3b82f6"]
187
+ \`\`\`
188
+
189
+ ### Create Orbiting Animation (Using create_scene - Recommended)
190
+ \`\`\`
191
+ pinepaper_create_scene
192
+ items:
193
+ - name: "sun", itemType: "circle", position: {x: 400, y: 300}, properties: {radius: 50, color: "#fbbf24"}
194
+ - name: "planet", itemType: "circle", position: {x: 550, y: 300}, properties: {radius: 15, color: "#3b82f6"}
195
+ relations:
196
+ - source: "planet", target: "sun", type: "orbits"
197
+ \`\`\`
198
+
199
+ ### Create Reveal Animation
200
+ \`\`\`
201
+ 1. pinepaper_create_item type: "text", params: { x: 400, y: 300, content: "Hello", fontSize: 48 }
202
+ 2. pinepaper_apply_animated_mask itemId: "item_1", preset: "wipeLeft", options: { duration: 0.5 }
203
+ \`\`\`
204
+
205
+ ## Quick Start
206
+
207
+ Agent mode connects automatically on first tool call. Just start creating!
120
208
 
121
- First-time visitors to PinePaper Studio see a **welcome template** with example items on the canvas. Before creating your own content:
209
+ 1. **Check templates first** - existing designs just need content changes
210
+ 2. **Use \`pinepaper_create_scene\`** for multi-item animated scenes (fastest)
211
+ 3. **Or create items individually**: \`pinepaper_create_item\` for shapes/text
212
+ 4. **Add animation**: \`pinepaper_add_relation\` for behavior-based animation
213
+ 5. **Verify**: \`pinepaper_browser_screenshot\` to see your work
214
+ 6. **Export**: \`pinepaper_export_svg\` to save
122
215
 
123
- ### To Clear the Welcome Template:
124
- - **Option 1**: Use \`pinepaper_clear_canvas\` to remove all items
125
- - **Option 2**: Use \`pinepaper_refresh_page\` to reload the page (most reliable)
126
- - After clearing, verify with \`pinepaper_get_items\` that the canvas is empty
216
+ ## IMPORTANT: Welcome Template
127
217
 
128
- The welcome template only appears once. After refreshing or clearing, it won't appear again.
218
+ First-time visitors see a welcome template. Clear it with:
219
+ - \`pinepaper_clear_canvas\` - removes all items
220
+ - \`pinepaper_agent_reset\` - quick reset
129
221
 
130
222
  ## Key Concepts
131
223
 
132
224
  ### Items
133
- Everything on the canvas is an item with a registry ID (e.g., "item_1"). Use this ID to reference items in other operations.
134
-
135
- **Creating Items:**
136
- - Use \`pinepaper_create_item\` with \`itemType\` (text, circle, star, rectangle, etc.)
137
- - Specify \`position\` as {x, y} coordinates
138
- - Add \`properties\` for styling (color, fontSize, radius, etc.)
139
-
140
- ### Relations (Primary Animation Method)
141
- Relations describe HOW items behave relative to each other. This is the **recommended way** to create animations:
142
- - \`orbits\`: Circular motion around another item
143
- - \`follows\`: Move toward another item with smoothing
144
- - \`attached_to\`: Fixed offset from parent item
145
- - \`points_at\`: Rotate to face another item
146
- - \`maintains_distance\`: Keep fixed distance from target
147
-
148
- **Verifying Animations:**
149
- After adding a relation, use \`pinepaper_browser_screenshot\` to verify the animation is working. Check that:
150
- 1. Items are positioned correctly
151
- 2. Animation is visibly moving (take multiple screenshots at intervals)
152
- 3. The relation appears in \`pinepaper_query_relations\`
153
-
154
- ### Deleting Items
155
- - Use \`pinepaper_delete_item\` with the item's registry ID
156
- - Use \`pinepaper_get_items\` first to find item IDs
157
- - If deletion fails, try \`pinepaper_clear_canvas\` to remove everything
158
-
159
- ### Generators
160
- Procedural backgrounds like sunburst, waves, grid patterns.
161
-
162
- ## Example Workflow
163
-
164
- \`\`\`
165
- 1. Connect: pinepaper_browser_connect
166
- 2. Clear canvas: pinepaper_clear_canvas (removes welcome template)
167
- 3. Verify empty: pinepaper_get_items (should return count: 0)
168
- 4. Create sun: pinepaper_create_item type=circle, color=#fbbf24, radius=60
169
- 5. Create earth: pinepaper_create_item type=circle, color=#3b82f6, radius=20
170
- 6. Add orbit: pinepaper_add_relation earth orbits sun, radius=150
171
- 7. Screenshot: pinepaper_browser_screenshot (verify animation)
225
+ Everything on canvas has a registry ID (e.g., "item_1"). Use this ID for animations and modifications.
226
+
227
+ ### Relations (Animation)
228
+ Describe behavior between items:
229
+ - \`orbits\`: Circular motion around target
230
+ - \`follows\`: Move toward target with smoothing
231
+ - \`attached_to\`: Fixed offset from parent
232
+ - \`points_at\`: Rotate to face target
233
+
234
+ ### Maps
235
+ Built-in maps: \`world\`, \`worldHighRes\`, \`usa\` (US states)
236
+ Load with \`pinepaper_load_map\`, animate with \`pinepaper_animate_map_regions\` or \`pinepaper_animate_map_wave\`
237
+
238
+ ### Masks
239
+ Reveal effects: wipeLeft, wipeRight, wipeUp, wipeDown, iris, irisOut, star, heart, curtainHorizontal, curtainVertical, cinematic, diagonalWipe, revealUp, revealDown
240
+ Apply with \`pinepaper_apply_animated_mask\`
241
+
242
+ ## Agent Workflow (Recommended)
243
+
244
+ For AI agents, use the batch pipeline for maximum efficiency:
245
+
246
+ 1. \`pinepaper_agent_start_job\` — clear canvas, set preset → returns canvasSize {width, height} for positioning
247
+ 2. \`pinepaper_agent_batch_execute\` — ONE call with ALL operations (12 types: canvas, background, generators, items, animations, keyframes, relations, masks, effects, playback)
248
+ 3. \`pinepaper_agent_end_job\` — returns screenshot for user validation
249
+ 4. User reviews → modify specific items or start new job
250
+
251
+ See the \`pinepaper_agent_batch_execute\` tool description for full operation reference.
252
+
253
+ **Note:** Diagrams (flowcharts, UML) use their own tools — \`pinepaper_create_diagram_shape\` + \`pinepaper_connect\` — not batch_execute. See \`pinepaper://docs/diagrams\`.
254
+
255
+ ## Detailed Guides
256
+
257
+ - Maps: Read \`pinepaper://docs/map-tools\`
258
+ - Diagrams: Read \`pinepaper://docs/diagrams\`
259
+ - Masks: Read \`pinepaper://docs/masks\`
260
+ - Relations: Read \`pinepaper://docs/relations\`
261
+ - Generators: Read \`pinepaper://docs/generators\`
262
+ - Fonts: Read \`pinepaper://docs/fonts\`
263
+ - Customization: Read \`pinepaper://docs/customization\`
264
+ `,
265
+ 'pinepaper://docs/customization': `# Customization Guide
266
+
267
+ **Intent:** Learn how to handle any user design request by combining tools, adapting templates, and creating custom solutions.
268
+
269
+ ## Understanding User Requests
270
+
271
+ Users will ask for varied graphics. Here's how to approach any request:
272
+
273
+ ### Step 1: Identify the Category
274
+
275
+ | Request Type | Primary Tools | Example |
276
+ |-------------|---------------|---------|
277
+ | Map visualization | \`load_map\`, \`apply_data_colors\` | "Show sales by state" |
278
+ | Animated logo | \`create_item\`, \`add_relation\` | "Make my logo pulse" |
279
+ | Infographic | \`create_diagram_shape\`, \`connect\` | "Create a flowchart" |
280
+ | Social media | \`set_canvas_size\`, \`create_item\` | "Instagram post" |
281
+ | Data chart | \`create_item\` (rectangles for bars) | "Bar chart of values" |
282
+ | Reveal/intro | \`apply_animated_mask\` | "Text wipe animation" |
283
+
284
+ ### Step 2: Choose Your Approach
285
+
286
+ | Complexity | Approach | When |
287
+ |------------|----------|------|
288
+ | Simple | Single tools | One shape, one animation |
289
+ | Medium | \`create_scene\` | Multiple items with relations |
290
+ | Complex | Step-by-step tools | Custom logic, conditional design |
291
+
292
+ ## Customization Patterns
293
+
294
+ ### Pattern 1: Color Scheme Changes
295
+
296
+ User: "Make it blue instead of red"
297
+
298
+ \`\`\`
299
+ // Original
300
+ pinepaper_create_item itemType: "circle" properties: {color: "#ef4444"}
301
+
302
+ // Customized - change color property
303
+ pinepaper_create_item itemType: "circle" properties: {color: "#3b82f6"}
304
+ \`\`\`
305
+
306
+ **Common color palettes:**
307
+ | Theme | Colors |
308
+ |-------|--------|
309
+ | Professional | #1e293b, #3b82f6, #f8fafc |
310
+ | Vibrant | #ef4444, #fbbf24, #22c55e, #3b82f6 |
311
+ | Pastel | #fecaca, #fef08a, #bbf7d0, #bfdbfe |
312
+ | Dark mode | #0f172a, #1e293b, #334155, #f8fafc |
313
+
314
+ ### Pattern 2: Size and Position Adjustments
315
+
316
+ User: "Make it bigger" or "Center it"
317
+
318
+ \`\`\`
319
+ // Get canvas size first
320
+ pinepaper_get_canvas_size → {width: 800, height: 600}
321
+
322
+ // Center position = (width/2, height/2)
323
+ pinepaper_create_item itemType: "text" position: {x: 400, y: 300}
324
+ properties: {content: "Centered", fontSize: 48}
325
+
326
+ // Make bigger - increase radius, fontSize, width/height
327
+ pinepaper_modify_item itemId: "item_1" properties: {scale: 1.5}
328
+ \`\`\`
329
+
330
+ ### Pattern 3: Animation Speed/Style Changes
331
+
332
+ User: "Make it faster" or "Smoother animation"
333
+
334
+ \`\`\`
335
+ // Faster orbit
336
+ pinepaper_add_relation sourceId: "item_1" targetId: "item_2" relationType: "orbits"
337
+ params: {speed: 2.0} // Higher = faster
338
+
339
+ // Smoother following
340
+ pinepaper_add_relation sourceId: "item_1" targetId: "item_2" relationType: "follows"
341
+ params: {smoothing: 0.95} // Higher = smoother (0-1)
342
+
343
+ // Different easing for masks
344
+ pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft"
345
+ options: {easing: "easeInOut"} // linear, easeIn, easeOut, easeInOut, bounce
346
+ \`\`\`
347
+
348
+ ### Pattern 4: Adding Text to Any Design
349
+
350
+ User: "Add a title" or "Label the items"
351
+
352
+ \`\`\`
353
+ // Title at top
354
+ pinepaper_create_item itemType: "text" position: {x: 400, y: 50}
355
+ properties: {content: "My Title", fontSize: 36, fontWeight: "bold", color: "#ffffff"}
356
+
357
+ // Label attached to item (moves with it)
358
+ pinepaper_create_item itemType: "text" position: {x: 400, y: 280}
359
+ properties: {content: "Earth", fontSize: 14, color: "#94a3b8"}
360
+ → label_1
361
+
362
+ pinepaper_add_relation sourceId: "label_1" targetId: "earth" relationType: "attached_to"
363
+ params: {offset: [0, -30]} // Above the item
364
+ \`\`\`
365
+
366
+ ### Pattern 5: Creating Data-Driven Graphics
367
+
368
+ User: "Show these numbers as a chart"
369
+
370
+ \`\`\`
371
+ // Bar chart from data
372
+ // Data: [10, 25, 15, 30, 20]
373
+
374
+ // Bar 1 (height proportional to value)
375
+ pinepaper_create_item itemType: "rectangle" position: {x: 150, y: 350}
376
+ properties: {width: 40, height: 100, color: "#3b82f6"} // height = value * scale
377
+
378
+ // Bar 2
379
+ pinepaper_create_item itemType: "rectangle" position: {x: 210, y: 275}
380
+ properties: {width: 40, height: 250, color: "#3b82f6"}
381
+
382
+ // Continue for each data point...
383
+ // Position x increases by spacing, height = value * multiplier
384
+ \`\`\`
385
+
386
+ ### Pattern 6: Responsive Canvas Sizes
387
+
388
+ User: "Make it for Instagram" or "YouTube thumbnail"
389
+
390
+ \`\`\`
391
+ // Set canvas FIRST, then position items relative to it
392
+ pinepaper_set_canvas_size preset: "instagram-post" // 1080x1080
393
+
394
+ // Now center = (540, 540)
395
+ pinepaper_create_item itemType: "text" position: {x: 540, y: 540}
396
+ properties: {content: "Centered!", fontSize: 64}
397
+ \`\`\`
398
+
399
+ **Common presets:**
400
+ | Preset | Size | Use |
401
+ |--------|------|-----|
402
+ | instagram-post | 1080x1080 | Square posts |
403
+ | instagram-story | 1080x1920 | Stories, Reels |
404
+ | youtube-thumbnail | 1280x720 | Video thumbnails |
405
+ | twitter-post | 1200x675 | Twitter/X images |
406
+
407
+ ### Pattern 7: Complex Animations with Multiple Relations
408
+
409
+ User: "Make planets orbit the sun with moons"
410
+
411
+ \`\`\`
412
+ pinepaper_create_scene
413
+ backgroundColor: "#0a0a0a"
414
+ items:
415
+ - name: "sun", itemType: "circle", position: {x: 400, y: 300}
416
+ properties: {radius: 50, color: "#fbbf24"}
417
+ - name: "earth", itemType: "circle", position: {x: 550, y: 300}
418
+ properties: {radius: 20, color: "#3b82f6"}
419
+ - name: "moon", itemType: "circle", position: {x: 580, y: 300}
420
+ properties: {radius: 6, color: "#9ca3af"}
421
+ - name: "mars", itemType: "circle", position: {x: 650, y: 300}
422
+ properties: {radius: 15, color: "#ef4444"}
423
+ relations:
424
+ - source: "earth", target: "sun", type: "orbits", params: {radius: 150, speed: 0.5}
425
+ - source: "moon", target: "earth", type: "orbits", params: {radius: 30, speed: 2}
426
+ - source: "mars", target: "sun", type: "orbits", params: {radius: 250, speed: 0.3}
427
+ animations:
428
+ - target: "sun", type: "pulse", speed: 0.3
429
+ \`\`\`
430
+
431
+ ## Handling Edge Cases
432
+
433
+ ### User Provides Specific Colors
434
+ Always use their exact hex codes:
435
+ \`\`\`
436
+ User: "Use #FF5733 for the background"
437
+ → properties: {color: "#FF5733"}
438
+ \`\`\`
439
+
440
+ ### User Wants Something Not Directly Supported
441
+ Combine tools creatively:
442
+ \`\`\`
443
+ User: "3D cube effect"
444
+ → Create 3 parallelograms with offset positions and colors
445
+ Use paths with segments to draw isometric shapes
446
+ \`\`\`
447
+
448
+ ### User Changes Mind Mid-Design
449
+ Use modify and delete:
450
+ \`\`\`
451
+ pinepaper_modify_item itemId: "item_1" properties: {color: "#new_color"}
452
+ pinepaper_delete_item itemId: "item_2"
453
+ \`\`\`
454
+
455
+ ### Performance with Many Items
456
+ Use batch operations:
457
+ \`\`\`
458
+ pinepaper_batch_create items: [{...}, {...}, {...}] // Instead of multiple create_item calls
459
+ \`\`\`
460
+
461
+ ## Decision Tree for Any Request
462
+
463
+ \`\`\`
464
+ Is it a MAP? → pinepaper_load_map
465
+ Is it a DIAGRAM/FLOWCHART? → pinepaper_create_diagram_shape + pinepaper_connect
466
+ Is it ANIMATED? → pinepaper_add_relation or pinepaper_animate
467
+ Is it a REVEAL/INTRO? → pinepaper_apply_animated_mask
468
+ Is it DATA VISUALIZATION? → Create shapes proportional to data values
469
+ Is it a BACKGROUND? → pinepaper_execute_generator
470
+ Otherwise → pinepaper_create_item for shapes/text
471
+ \`\`\`
472
+
473
+ ## Example: Complete Custom Request
474
+
475
+ User: "Create an animated infographic showing 3 steps with arrows"
476
+
477
+ \`\`\`
478
+ // 1. Set canvas
479
+ pinepaper_set_canvas_size preset: "presentation-16x9"
480
+
481
+ // 2. Create step boxes
482
+ pinepaper_create_diagram_shape shapeType: "process" position: {x: 300, y: 400}
483
+ label: "Step 1: Research" style: {fillColor: "#3b82f6"} → item_1
484
+
485
+ pinepaper_create_diagram_shape shapeType: "process" position: {x: 600, y: 400}
486
+ label: "Step 2: Design" style: {fillColor: "#8b5cf6"} → item_2
487
+
488
+ pinepaper_create_diagram_shape shapeType: "process" position: {x: 900, y: 400}
489
+ label: "Step 3: Build" style: {fillColor: "#22c55e"} → item_3
490
+
491
+ // 3. Connect with arrows
492
+ pinepaper_connect sourceItemId: "item_1" targetItemId: "item_2"
493
+ routing: "direct" animated: true
494
+
495
+ pinepaper_connect sourceItemId: "item_2" targetItemId: "item_3"
496
+ routing: "direct" animated: true
497
+
498
+ // 4. Add title
499
+ pinepaper_create_item itemType: "text" position: {x: 600, y: 150}
500
+ properties: {content: "Our Process", fontSize: 48, fontWeight: "bold"}
501
+
502
+ // 5. Apply reveal animations
503
+ pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft"
504
+ options: {startTime: 0, duration: 0.4}
505
+
506
+ pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeLeft"
507
+ options: {startTime: 0.3, duration: 0.4}
508
+
509
+ pinepaper_apply_animated_mask itemId: "item_3" preset: "wipeLeft"
510
+ options: {startTime: 0.6, duration: 0.4}
511
+ \`\`\`
512
+
513
+ ## Key Principles
514
+
515
+ 1. **Understand first** - What is the user trying to achieve?
516
+ 2. **Start simple** - Use the most direct tool for the job
517
+ 3. **Build incrementally** - Add complexity one step at a time
518
+ 4. **Verify with screenshots** - \`pinepaper_browser_screenshot\` after each major step
519
+ 5. **Offer alternatives** - If something can't be done exactly, suggest similar approaches
520
+ `,
521
+ 'pinepaper://docs/templates': `# Templates & Timed Animation Guide
522
+
523
+ ## Apply a Template
524
+
525
+ \`pinepaper_list_templates\` — browse available pre-built templates.
526
+ \`pinepaper_apply_template\` — load a template by name. Animations are pre-configured.
527
+ After applying: modify text/colors with \`pinepaper_modify_item\`, then export.
528
+
529
+ ## Template Categories
530
+
531
+ | Category | Examples |
532
+ |----------|----------|
533
+ | Map | US Election, World Data, Travel Route |
534
+ | Animation | Solar System, Logo Reveal, Text Intro, Particle Burst |
535
+ | Diagram | Flowchart, Org Chart, Network |
536
+ | Social Media | YouTube Thumbnail (1280x720), Instagram Story (1080x1920), TikTok |
537
+
538
+ ## Modifying Templates
539
+
540
+ Change safely: \`properties.content\`, \`properties.color\`, \`backgroundColor\`, positions, sizes.
541
+ Preserve: \`relations\` array, \`animations\` array, item \`name\` values (relations reference these).
542
+
543
+ ## Building Timed Animations (4 steps)
544
+
545
+ For invitations, intros, promos, reveals — any timed animation:
546
+
547
+ **1. Create items** — \`pinepaper_create_scene\` with all items. Timed reveals: set \`opacity: 0\`.
548
+ Items get sequential IDs: first = \`item_1\`, second = \`item_2\`, etc.
549
+
550
+ **2. Animate items** — ONE \`pinepaper_execute_custom_code\` call with all animations:
551
+ \`\`\`
552
+ app.addAnimation(registryId, keyframes, options)
553
+ registryId: 'item_1'
554
+ keyframes: [{time: 0, properties: {opacity: 0}, easing: 'easeInOut'},
555
+ {time: 1, properties: {opacity: 1}}]
556
+ options: {duration: number, loop?: boolean, pingPong?: boolean}
557
+ \`\`\`
558
+ Animatable properties: \`opacity\`, \`scale\`, \`scaleX\`, \`scaleY\`, \`x\`, \`y\`, \`rotation\`, \`fillColor\`, \`strokeColor\`, \`fontSize\`.
559
+ Stagger items by offsetting \`time\` values across items.
560
+
561
+ **3. Play** — \`pinepaper_play_timeline\`
562
+
563
+ **4. Export** — \`pinepaper_agent_export\` (SVG/PNG/GIF/MP4/WebM/PDF)
564
+
565
+ ## Text Reveal Pattern
566
+
567
+ Create text items, then apply mask reveals with staggered start times:
568
+ \`\`\`
569
+ pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft" options: {duration: 0.5}
570
+ pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeLeft" options: {startTime: 0.3, duration: 0.5}
571
+ \`\`\`
572
+ Mask presets: wipeLeft, wipeRight, wipeUp, wipeDown, iris, irisOut, star, heart, curtainHorizontal, curtainVertical, cinematic, diagonalWipe, revealUp, revealDown.
573
+
574
+ ## Advanced Capabilities (via execute_custom_code)
575
+
576
+ **Time-scoped relations** — relation active only during a time window:
577
+ \`\`\`
578
+ app.addRelation(sourceId, targetId, type, {startTime: 2, endTime: 5, autoRemove: true, ...params})
579
+ \`\`\`
580
+
581
+ **Keyframe priority** — when keyframes and relations target the same property:
582
+ \`\`\`
583
+ app.addRelation(sourceId, targetId, type, {relationBehavior: 'keyframeFirst', ...params})
584
+ \`\`\`
585
+
586
+ **Per-item timing** — offset an item into the global timeline:
587
+ \`\`\`
588
+ app.setTimeOffset(registryId, offsetSeconds)
589
+ \`\`\`
590
+
591
+ **Atomic relation replace** — swap relation params without remove+add:
592
+ \`\`\`
593
+ app.replaceRelation(sourceId, targetId, type, newParams)
172
594
  \`\`\`
173
595
  `,
174
596
  'pinepaper://docs/relations': `# Relations Guide
@@ -226,6 +648,101 @@ Stay within target's bounds.
226
648
  - \`padding\`: Inner padding
227
649
  - \`bounce\`: Bounce off edges
228
650
 
651
+ ### morphs_to
652
+ Smoothly transform source shape into target shape over time.
653
+ - \`duration\`: Morph duration in seconds (default: 1)
654
+ - \`hideTarget\`: Hide target item since it's just a shape reference (default: true)
655
+ - \`removeTargetOnComplete\`: Delete target after morph completes (default: false)
656
+ - \`easing\`: Timing function ('linear', 'easeIn', 'easeOut', 'easeInOut')
657
+
658
+ **Usage patterns:**
659
+ \`\`\`
660
+ // Default: Circle morphs to star's shape, star stays hidden
661
+ pinepaper_add_relation sourceId: "circle" targetId: "star" relationType: "morphs_to"
662
+ params: {duration: 1}
663
+
664
+ // Clean up: Delete star after morph completes
665
+ pinepaper_add_relation sourceId: "circle" targetId: "star" relationType: "morphs_to"
666
+ params: {duration: 1, removeTargetOnComplete: true}
667
+
668
+ // Both visible: Keep star visible (you'll see two stars at end)
669
+ pinepaper_add_relation sourceId: "circle" targetId: "star" relationType: "morphs_to"
670
+ params: {duration: 1, hideTarget: false}
671
+ \`\`\`
672
+
673
+ **Great for:** Logo animations, shape transitions, loading indicators, morphing icons
674
+
675
+ ### camera_follows
676
+ Camera pans to follow a target item (like Manim MovingCameraScene).
677
+ - \`smoothing\`: 0-1 (higher = smoother following)
678
+ - \`offset\`: [x, y] offset from target
679
+ - \`zoom\`: Zoom level to maintain
680
+ - \`deadzone\`: Pixels before camera starts moving
681
+ - \`bounds\`: {minX, maxX, minY, maxY} camera movement limits
682
+
683
+ \`\`\`
684
+ // Camera follows the player character
685
+ pinepaper_add_relation sourceId: "camera" targetId: "player" relationType: "camera_follows"
686
+ params: {smoothing: 0.9, zoom: 1.5, deadzone: 50}
687
+ \`\`\`
688
+
689
+ **Great for:** Game-like scenes, following animations, focus tracking
690
+
691
+ ### camera_animates
692
+ Keyframe-based camera zoom and pan animations. Use the special "camera" virtual item.
693
+ - \`keyframes\`: Array of keyframe objects with time, zoom, center, easing
694
+ - \`duration\`: Total animation duration in seconds
695
+ - \`loop\`: Whether to loop the animation
696
+ - \`delay\`: Delay before starting
697
+
698
+ **Keyframe properties:**
699
+ - \`time\`: Normalized time 0-1
700
+ - \`zoom\`: Zoom level (1 = normal, 2 = 2x zoom in)
701
+ - \`center\`: [x, y] pan center position
702
+ - \`easing\`: Easing function for this keyframe
703
+
704
+ \`\`\`
705
+ // Cinematic zoom and pan sequence
706
+ pinepaper_add_relation sourceId: "camera" targetId: "camera" relationType: "camera_animates"
707
+ params:
708
+ duration: 5
709
+ loop: false
710
+ keyframes:
711
+ - time: 0, zoom: 1, center: [400, 300], easing: "easeOut"
712
+ - time: 0.3, zoom: 1.5, center: [200, 200], easing: "easeInOut"
713
+ - time: 0.7, zoom: 2, center: [600, 400], easing: "easeInOut"
714
+ - time: 1, zoom: 1, center: [400, 300], easing: "easeIn"
715
+ \`\`\`
716
+
717
+ **Great for:** Cinematic intros, presentations, dramatic reveals, tour animations
718
+
719
+ ## Camera API (Direct Code)
720
+
721
+ For simpler camera control, use the \`app.camera\` helper API:
722
+
723
+ \`\`\`javascript
724
+ // Zoom
725
+ app.camera.zoomIn(1.5, 0.5); // Zoom to 1.5x over 0.5 seconds
726
+ app.camera.zoomOut(0.5, 0.5); // Zoom out to 0.5x
727
+
728
+ // Pan
729
+ app.camera.panTo(200, 300, 1); // Pan to coordinates
730
+ app.camera.panBy(100, 0, 0.5); // Pan right by 100px
731
+ app.camera.panLeft(50, 0.3); // Pan left
732
+ app.camera.panRight(50, 0.3); // Pan right
733
+ app.camera.panUp(50, 0.3); // Pan up
734
+ app.camera.panDown(50, 0.3); // Pan down
735
+
736
+ // Combined
737
+ app.camera.moveTo(200, 300, 2, 1); // Pan to (200,300) and zoom to 2x
738
+
739
+ // Control
740
+ app.camera.reset(0.5); // Reset to default
741
+ app.camera.stop(); // Stop current animation
742
+ app.camera.getState(); // Returns { zoom, center: [x, y] }
743
+ app.camera.isAnimating(); // Check if animating
744
+ \`\`\`
745
+
229
746
  ## Verifying Animations Are Working
230
747
 
231
748
  After adding a relation, **always verify** that the animation is actually running:
@@ -268,44 +785,136 @@ addRelation(label, planet, 'attached_to', { offset: [0, -30] })
268
785
 
269
786
  The label will follow the planet as it orbits the star!
270
787
  `,
271
- 'pinepaper://docs/generators': `# Background Generators
788
+ 'pinepaper://docs/generators': `# Background Generators Guide
789
+
790
+ **Intent:** Create procedural backgrounds with 14 generators covering patterns, effects, organic flows, particles, and textures.
272
791
 
273
- Procedural backgrounds that create dynamic patterns.
792
+ ## Key Tool
274
793
 
275
- ## Available Generators
794
+ \`\`\`
795
+ pinepaper_execute_generator
796
+ generatorName: "drawSunburst"
797
+ params: { rayCount: 16, colors: ["#fbbf24", "#f59e0b"], animated: true }
798
+ \`\`\`
799
+
800
+ ## Classic Generators (7)
276
801
 
277
802
  ### drawSunburst
278
- Radial rays from center.
279
- - \`rayCount\`: Number of rays (default: 16)
280
- - \`colors\`: Array of ray colors
281
- - \`bgColor\`: Background color
282
- - \`animated\`: Enable rotation
803
+ Radial rays from center — energy, attention-grabbing backgrounds.
804
+ - **Core:** rayCount (16), colors, bgColor, animated
805
+ - **Enhanced:** opacity, rayGap (degrees between rays), gradientRays (radial gradient per ray)
283
806
 
284
807
  ### drawSunsetScene
285
- Animated sunset with clouds.
286
- - \`sunColor\`: Sun fill color
287
- - \`skyColors\`: Array for gradient
288
- - \`cloudCount\`: Number of clouds
808
+ Animated sunset with clouds — calm, atmospheric.
809
+ - **Core:** sunColor, skyColors, cloudCount
810
+ - **Enhanced:** skyOpacity, starCount, starColor, reflectionEnabled, reflectionOpacity
289
811
 
290
812
  ### drawGrid
291
- Geometric grid patterns.
292
- - \`gridType\`: 'lines', 'dots', or 'squares'
293
- - \`spacing\`: Cell size
294
- - \`lineColor\`: Grid color
813
+ Lines, dots, or squares — clean, technical, modern.
814
+ - **Core:** gridType (lines|dots|squares), spacing (40), lineColor, bgColor, lineWidth
815
+ - **Enhanced:** opacity, gap (pixel gap), randomRotation, colorMode (checkerboard|gradient|random|rows|columns), strokeColor, strokeWidth
295
816
 
296
817
  ### drawWaves
297
- Layered wave pattern.
298
- - \`waveCount\`: Number of layers
299
- - \`colors\`: Wave colors
300
- - \`amplitude\`: Wave height
301
- - \`animated\`: Animate waves
818
+ Layered wave pattern — organic, flowing.
819
+ - **Core:** waveCount (5), colors, amplitude (50), frequency (2), bgColor, animated
820
+ - **Enhanced:** opacity, fill (fill between waves), fillOpacity, amplitudeVariation, blendMode
302
821
 
303
822
  ### drawCircuit
304
- Tech circuit board.
305
- - \`lineColor\`: Circuit lines
306
- - \`nodeColor\`: Junction color
307
- - \`density\`: 0-1 complexity
308
- - \`animated\`: Enable bolt effect
823
+ Circuit board pattern — futuristic, digital.
824
+ - **Core:** lineColor, nodeColor, bgColor, density (0-1), animated, boltColor
825
+ - **Enhanced:** traceOpacity, nodeOpacity, diagonalPaths (45-degree traces), chipDensity (auto|none|low|medium|high)
826
+
827
+ ### drawStackedCircles
828
+ Overlapping circles with distribution algorithms.
829
+ - **Core:** count (8), colors, distribution (random|poisson|golden)
830
+ - **Enhanced:** opacityMin/opacityMax, blendMode, strokeWidth, strokeColor, sizeGradient, animationType (pulse|float|none)
831
+
832
+ ### drawPattern
833
+ Geometric shapes in orbit rings.
834
+ - **Core:** patternType, size, color, bgColor
835
+ - **Enhanced:** opacity, blendMode, layers (1-5 concentric rings), layerScaleDecay
836
+
837
+ ## New Generators (7)
838
+
839
+ ### drawBokeh (effects)
840
+ Soft-focus circles — dreamy, photographic depth-of-field.
841
+ \`\`\`
842
+ params: { count: 30, colors: ["#f472b6", "#818cf8", "#34d399"], bgColor: "#0f172a",
843
+ shadowBlur: 20, distribution: "poisson", driftAnimation: true }
844
+ \`\`\`
845
+
846
+ ### drawGradientMesh (organic)
847
+ Radial gradient blobs with screen blending — modern, vibrant.
848
+ \`\`\`
849
+ params: { colors: ["#ec4899", "#8b5cf6", "#06b6d4"], blobCount: 5,
850
+ blendMode: "screen", drift: true }
851
+ \`\`\`
852
+
853
+ ### drawGeometricAbstract (geometric)
854
+ Mixed translucent shapes with blend modes — artistic, contemporary.
855
+ \`\`\`
856
+ params: { colors: ["#f43f5e", "#3b82f6", "#10b981"], shapeCount: 12,
857
+ blendMode: "multiply", rotation: true }
858
+ \`\`\`
859
+
860
+ ### drawWindField (particles)
861
+ Directional wind particles with noise turbulence — weather, motion.
862
+ \`\`\`
863
+ params: { particleCount: 200, colors: ["#e0f2fe", "#bae6fd"], direction: 45,
864
+ turbulence: 0.5, trailLength: 30, speed: 1.5 }
865
+ \`\`\`
866
+
867
+ ### drawFluidFlow (organic)
868
+ Sinusoidal stream paths with depth layering — liquid, flowing.
869
+ \`\`\`
870
+ params: { streamCount: 8, colors: ["#67e8f9", "#a78bfa", "#f9a8d4"],
871
+ depthLayers: 3, speed: 0.8 }
872
+ \`\`\`
873
+
874
+ ### drawOrganicFlow (organic)
875
+ Aurora/silk layers — natural, ethereal glow.
876
+ \`\`\`
877
+ params: { layerCount: 4, colors: ["#34d399", "#6ee7b7", "#a7f3d0"],
878
+ blendMode: "screen", fillToBottom: true, animated: true }
879
+ \`\`\`
880
+
881
+ ### drawNoiseTexture (textures)
882
+ Perlin/grain/stipple noise — subtle, textured.
883
+ \`\`\`
884
+ params: { noiseType: "perlin", colors: ["#94a3b8", "#64748b"],
885
+ scale: 0.01, density: 0.7, animated: true }
886
+ \`\`\`
887
+ noiseType options: perlin, grain, stipple
888
+
889
+ ## Quick Mood Guide
890
+
891
+ | Mood | Generators |
892
+ |------|-----------|
893
+ | Dreamy/soft | drawBokeh, drawGradientMesh, drawOrganicFlow |
894
+ | Techy/modern | drawCircuit, drawGrid, drawWindField |
895
+ | Nature/warm | drawSunsetScene, drawSunburst, drawWaves |
896
+ | Abstract | drawGeometricAbstract, drawFluidFlow, drawNoiseTexture |
897
+ | Decorative | drawPattern, drawStackedCircles |
898
+
899
+ ## Combining Generators with Items
900
+
901
+ \`\`\`
902
+ // Background + content on top
903
+ pinepaper_execute_generator
904
+ generatorName: "drawBokeh"
905
+ params: {count: 20, colors: ["#f472b6", "#818cf8"], shadowBlur: 25}
906
+
907
+ pinepaper_create_item itemType: "text" position: {x: 400, y: 300}
908
+ properties: {content: "Welcome", fontSize: 72, color: "#ffffff"}
909
+ \`\`\`
910
+
911
+ ## Best Practices
912
+
913
+ 1. **Call generator first** — before creating items
914
+ 2. **Use complementary colors** — items should contrast with background
915
+ 3. **Consider animation performance** — animated generators + many animated items can slow down
916
+ 4. **Match themes** — sunburst for energy, waves for calm, circuit for tech, bokeh for elegance, noise for texture
917
+ 5. **Use blendMode** — "screen" brightens, "multiply" darkens, great for layered effects
309
918
  `,
310
919
  'pinepaper://docs/custom-paths': `# Custom Paths Guide
311
920
 
@@ -593,8 +1202,7 @@ Create an animated solar system featuring custom paths, orbital rings, and plane
593
1202
  ## Step 1: Canvas Setup
594
1203
 
595
1204
  \`\`\`
596
- pinepaper_browser_connect
597
- pinepaper_clear_canvas
1205
+ pinepaper_clear_canvas # Browser auto-connects in agent mode
598
1206
  pinepaper_set_background_color color: "#0a0a1a"
599
1207
  \`\`\`
600
1208
 
@@ -2341,8 +2949,7 @@ An animated company logo featuring:
2341
2949
  ## Step 1: Canvas Setup
2342
2950
 
2343
2951
  \`\`\`
2344
- pinepaper_browser_connect
2345
- pinepaper_clear_canvas
2952
+ pinepaper_clear_canvas # Browser auto-connects in agent mode
2346
2953
  pinepaper_set_background_color color: "#0f172a"
2347
2954
  pinepaper_set_canvas_size width: 800 height: 600
2348
2955
  \`\`\`
@@ -2581,8 +3188,7 @@ Create animated charts and infographics that bring data to life.
2581
3188
 
2582
3189
  ### Step 1: Setup
2583
3190
  \`\`\`
2584
- pinepaper_browser_connect
2585
- pinepaper_clear_canvas
3191
+ pinepaper_clear_canvas # Browser auto-connects in agent mode
2586
3192
  pinepaper_set_background_color color: "#1f2937"
2587
3193
  \`\`\`
2588
3194
 
@@ -2903,8 +3509,7 @@ Build dynamic particle effects like fireworks, starfields, snow, and fire.
2903
3509
 
2904
3510
  ### Step 1: Create Background
2905
3511
  \`\`\`
2906
- pinepaper_browser_connect
2907
- pinepaper_clear_canvas
3512
+ pinepaper_clear_canvas # Browser auto-connects in agent mode
2908
3513
  pinepaper_set_background_color color: "#000011"
2909
3514
  \`\`\`
2910
3515
 
@@ -3183,29 +3788,1969 @@ pinepaper_animate_item itemId: "bubble4" animationType: "wobble" speed: 0.7
3183
3788
  | Dust | Tiny circles, slow fade, random positions |
3184
3789
  | Confetti | Small rectangles, rotate + bounce, rainbow colors |
3185
3790
  `,
3186
- };
3187
- // =============================================================================
3188
- // SERVER CREATION
3189
- // =============================================================================
3190
- export async function createServer(options = {}) {
3191
- // Initialize i18n with specified locale
3192
- const locale = options.locale || detectLocaleFromEnvironment();
3193
- const i18n = await initI18n(locale);
3194
- const server = new Server(SERVER_INFO, {
3195
- capabilities: {
3196
- tools: {},
3197
- resources: {},
3198
- },
3199
- });
3200
- // ---------------------------------------------------------------------------
3791
+ 'pinepaper://docs/map-tools': `# Map Tools Guide
3792
+
3793
+ Create geographic visualizations with world maps, choropleth coloring, markers, and labels.
3794
+
3795
+ ## Available Maps
3796
+
3797
+ | Map | Description | Region ID Format |
3798
+ |-----|-------------|------------------|
3799
+ | \`world\` | World countries (110m) | Full names: "United States of America", "France" |
3800
+ | \`worldHighRes\` | World countries (50m, detailed) | Full names |
3801
+ | \`usa\` | US states | State codes: "CA", "TX", "NY" |
3802
+
3803
+ ## Projections
3804
+
3805
+ | Projection | Best For |
3806
+ |------------|----------|
3807
+ | \`naturalEarth\` | World maps (recommended) |
3808
+ | \`mercator\` | Web-style maps |
3809
+ | \`equalEarth\` | Equal-area comparisons |
3810
+ | \`orthographic\` | Globe/3D sphere view |
3811
+ | \`albers\` | USA maps (recommended) |
3812
+ | \`stereographic\` | Polar regions |
3813
+
3814
+ ## Loading Maps
3815
+
3816
+ \`\`\`
3817
+ // Load world map with Natural Earth projection
3818
+ pinepaper_load_map mapId: "world"
3819
+ options:
3820
+ projection: "naturalEarth"
3821
+ quality: "balanced"
3822
+ fillColor: "#e5e7eb"
3823
+ strokeColor: "#9ca3af"
3824
+ enableHover: true
3825
+
3826
+ // Load USA with Albers projection
3827
+ pinepaper_load_map mapId: "usa"
3828
+ options:
3829
+ projection: "albers"
3830
+ quality: "professional"
3831
+ \`\`\`
3832
+
3833
+ ## Highlighting Regions
3834
+
3835
+ \`\`\`
3836
+ // Highlight countries (use full names for world map)
3837
+ pinepaper_highlight_regions
3838
+ regionIds: ["United States of America", "Canada", "Mexico"]
3839
+ options:
3840
+ fillColor: "#3b82f6"
3841
+ strokeColor: "#1d4ed8"
3842
+ animate: true
3843
+
3844
+ // Highlight US states (use state codes)
3845
+ pinepaper_highlight_regions
3846
+ regionIds: ["CA", "TX", "NY", "FL"]
3847
+ options:
3848
+ fillColor: "#22c55e"
3849
+
3850
+ // Remove highlights
3851
+ pinepaper_unhighlight_regions regionIds: "all"
3852
+ \`\`\`
3853
+
3854
+ ## Choropleth (Data-Driven Colors)
3855
+
3856
+ \`\`\`
3857
+ // Population data visualization
3858
+ pinepaper_apply_data_colors
3859
+ data:
3860
+ "California": 39538223
3861
+ "Texas": 29145505
3862
+ "Florida": 21538187
3863
+ "New York": 20201249
3864
+ options:
3865
+ colorScale: "blues"
3866
+ showLegend: true
3867
+ legendPosition: "bottom-right"
3868
+ legendTitle: "Population"
3869
+ \`\`\`
3870
+
3871
+ ### Color Scales
3872
+ - \`blues\` - Light to dark blue
3873
+ - \`greens\` - Light to dark green
3874
+ - \`reds\` - Light to dark red
3875
+ - \`oranges\` - Light to dark orange
3876
+ - \`purples\` - Light to dark purple
3877
+ - \`heat\` - Yellow to red heat map
3878
+
3879
+ ## Map Markers
3880
+
3881
+ \`\`\`
3882
+ // Add marker at coordinates
3883
+ pinepaper_add_marker
3884
+ lat: 37.7749
3885
+ lon: -122.4194
3886
+ label: "San Francisco"
3887
+ color: "#ef4444"
3888
+ size: 8
3889
+ pulse: true
3890
+
3891
+ // Add marker with different shape
3892
+ pinepaper_add_marker
3893
+ lat: 40.7128
3894
+ lon: -74.0060
3895
+ label: "New York"
3896
+ shape: "pin"
3897
+ \`\`\`
3898
+
3899
+ ### Marker Shapes
3900
+ - \`circle\` - Simple circle (default)
3901
+ - \`pin\` - Map pin icon
3902
+ - \`star\` - Star shape
3903
+
3904
+ ## Map Labels
3905
+
3906
+ \`\`\`
3907
+ // Add labels to all visible regions
3908
+ pinepaper_add_map_labels
3909
+ options:
3910
+ fontSize: 10
3911
+ fontColor: "#374151"
3912
+ labelType: "name"
3913
+
3914
+ // Add labels to specific regions
3915
+ pinepaper_add_map_labels
3916
+ regions: ["California", "Texas"]
3917
+ options:
3918
+ labelType: "code"
3919
+ \`\`\`
3920
+
3921
+ ### Label Types
3922
+ - \`name\` - Full region name
3923
+ - \`code\` - Region code (e.g., "CA")
3924
+ - \`value\` - Data value (after applyDataColors)
3925
+
3926
+ ## Map Navigation
3927
+
3928
+ \`\`\`
3929
+ // Pan to coordinates
3930
+ pinepaper_pan_map lat: 50 lon: 10 animate: true duration: 1
3931
+
3932
+ // Zoom in
3933
+ pinepaper_zoom_map level: 2 animate: true
3934
+ \`\`\`
3935
+
3936
+ ## Importing Custom Maps
3937
+
3938
+ \`\`\`
3939
+ // Import from URL
3940
+ pinepaper_import_custom_map
3941
+ url: "https://example.com/custom-boundaries.geojson"
3942
+ options:
3943
+ projection: "mercator"
3944
+
3945
+ // Import GeoJSON directly
3946
+ pinepaper_import_custom_map
3947
+ geoJson: { "type": "FeatureCollection", "features": [...] }
3948
+ options:
3949
+ projection: "naturalEarth"
3950
+ \`\`\`
3951
+
3952
+ ## Example: US Population Map
3953
+
3954
+ \`\`\`
3955
+ // 1. Load USA map
3956
+ pinepaper_load_map mapId: "usa"
3957
+ options:
3958
+ projection: "albers"
3959
+ quality: "professional"
3960
+ fillColor: "#e5e7eb"
3961
+ strokeColor: "#9ca3af"
3962
+ strokeWidth: 0.5
3963
+ enableHover: true
3964
+
3965
+ // 2. Apply population data
3966
+ pinepaper_apply_data_colors
3967
+ data:
3968
+ "CA": 39538223
3969
+ "TX": 29145505
3970
+ "FL": 21538187
3971
+ "NY": 20201249
3972
+ "PA": 13002700
3973
+ "IL": 12812508
3974
+ "OH": 11799448
3975
+ "GA": 10711908
3976
+ options:
3977
+ colorScale: "blues"
3978
+ showLegend: true
3979
+ legendTitle: "Population"
3980
+
3981
+ // 3. Add major city markers
3982
+ pinepaper_add_marker lat: 34.0522 lon: -118.2437 label: "Los Angeles" pulse: true
3983
+ pinepaper_add_marker lat: 40.7128 lon: -74.0060 label: "New York" pulse: true
3984
+ pinepaper_add_marker lat: 41.8781 lon: -87.6298 label: "Chicago" pulse: true
3985
+
3986
+ // 4. Export final map
3987
+ pinepaper_export_map
3988
+ \`\`\`
3989
+
3990
+ ## Example: World Comparison
3991
+
3992
+ \`\`\`
3993
+ // 1. Load world map
3994
+ pinepaper_load_map mapId: "worldHighRes"
3995
+ options:
3996
+ projection: "naturalEarth"
3997
+ quality: "balanced"
3998
+ fillColor: "#f3f4f6"
3999
+ strokeColor: "#d1d5db"
4000
+
4001
+ // 2. Highlight regions of interest
4002
+ pinepaper_highlight_regions
4003
+ regionIds: ["United States of America", "China", "Japan", "Germany", "United Kingdom"]
4004
+ options:
4005
+ fillColor: "#3b82f6"
4006
+ animate: true
4007
+
4008
+ // 3. Add capital markers
4009
+ pinepaper_add_marker lat: 38.9072 lon: -77.0369 label: "Washington DC"
4010
+ pinepaper_add_marker lat: 39.9042 lon: 116.4074 label: "Beijing"
4011
+ pinepaper_add_marker lat: 35.6762 lon: 139.6503 label: "Tokyo"
4012
+ pinepaper_add_marker lat: 52.5200 lon: 13.4050 label: "Berlin"
4013
+ pinepaper_add_marker lat: 51.5074 lon: -0.1278 label: "London"
4014
+ \`\`\`
4015
+
4016
+ ## Hit Testing
4017
+
4018
+ \`\`\`
4019
+ // Find region at canvas coordinates
4020
+ pinepaper_get_region_at_point x: 400 y: 300
4021
+ // Returns: { regionId, regionName, properties }
4022
+ \`\`\`
4023
+
4024
+ ## Region Animations
4025
+
4026
+ Animate map regions with keyframe-based color transitions:
4027
+
4028
+ \`\`\`
4029
+ // Animate specific regions with keyframes
4030
+ pinepaper_animate_map_regions
4031
+ duration: 8
4032
+ loop: true
4033
+ regions:
4034
+ "USA":
4035
+ - time: 0, fillColor: "#ef4444"
4036
+ - time: 4, fillColor: "#22c55e"
4037
+ - time: 8, fillColor: "#ef4444"
4038
+ "France":
4039
+ - time: 0, fillColor: "#3b82f6"
4040
+ - time: 8, fillColor: "#fbbf24"
4041
+
4042
+ // Wave animation across all regions
4043
+ pinepaper_animate_map_wave
4044
+ duration: 10
4045
+ loop: true
4046
+ colors: ["#ef4444", "#fbbf24", "#22c55e", "#3b82f6"]
4047
+ waveDirection: "horizontal"
4048
+
4049
+ // Stop animations
4050
+ pinepaper_stop_map_animations
4051
+ pinepaper_stop_map_animations regions: ["USA", "France"] resetColors: true
4052
+
4053
+ // Query animated regions
4054
+ pinepaper_get_animated_map_regions
4055
+ \`\`\`
4056
+
4057
+ ## CSV Export & Import
4058
+
4059
+ Export and import map state via CSV for data-driven workflows:
4060
+
4061
+ \`\`\`
4062
+ // Export region data as CSV
4063
+ pinepaper_export_map_region_csv
4064
+ includeHighlighted: true
4065
+ includeColors: true
4066
+ download: true
4067
+ filename: "map-export.csv"
4068
+
4069
+ // Import CSV to update regions
4070
+ pinepaper_import_map_region_csv
4071
+ csvText: "regionId,fillColor,highlighted\\nUSA,#22c55e,1\\nFrance,#3b82f6,0"
4072
+ applyColors: true
4073
+ applyHighlight: true
4074
+ \`\`\`
4075
+
4076
+ ## Programmatic Selection
4077
+
4078
+ Control region selection programmatically:
4079
+
4080
+ \`\`\`
4081
+ // Select regions
4082
+ pinepaper_select_map_regions regionIds: ["USA", "Canada", "Mexico"]
4083
+
4084
+ // Deselect specific regions
4085
+ pinepaper_deselect_map_regions regionIds: ["USA"]
4086
+
4087
+ // Deselect all
4088
+ pinepaper_deselect_map_regions
4089
+
4090
+ // Query highlighted regions
4091
+ pinepaper_get_highlighted_map_regions
4092
+ \`\`\`
4093
+ `,
4094
+ 'pinepaper://examples/world-population-map': `# World Population Map Example
4095
+
4096
+ Create an animated choropleth map showing world population data with country highlights and major city markers.
4097
+
4098
+ ## Final Result
4099
+
4100
+ A beautiful world map showing population density by color intensity, with pulsing markers on major capitals.
4101
+
4102
+ ---
4103
+
4104
+ ## Step 1: Set Up Canvas and Background
4105
+
4106
+ \`\`\`
4107
+ // Set dark background for contrast
4108
+ pinepaper_set_background_color color: "#1a1a2e"
4109
+
4110
+ // Set canvas size for presentation
4111
+ pinepaper_set_canvas_size preset: "presentation-16x9"
4112
+ \`\`\`
4113
+
4114
+ ---
4115
+
4116
+ ## Step 2: Load World Map
4117
+
4118
+ \`\`\`
4119
+ pinepaper_load_map mapId: "worldHighRes"
4120
+ options:
4121
+ projection: "naturalEarth"
4122
+ quality: "professional"
4123
+ fillColor: "#374151"
4124
+ strokeColor: "#4b5563"
4125
+ strokeWidth: 0.3
4126
+ enableHover: true
4127
+ hoverFill: "#6b7280"
4128
+ \`\`\`
4129
+
4130
+ ---
4131
+
4132
+ ## Step 3: Apply Population Data (Choropleth)
4133
+
4134
+ \`\`\`
4135
+ pinepaper_apply_data_colors
4136
+ data:
4137
+ "China": 1412
4138
+ "India": 1408
4139
+ "United States of America": 332
4140
+ "Indonesia": 276
4141
+ "Pakistan": 229
4142
+ "Brazil": 215
4143
+ "Nigeria": 218
4144
+ "Bangladesh": 169
4145
+ "Russia": 144
4146
+ "Mexico": 130
4147
+ "Japan": 125
4148
+ "Ethiopia": 120
4149
+ "Philippines": 113
4150
+ "Egypt": 104
4151
+ "Vietnam": 99
4152
+ "Germany": 84
4153
+ "Turkey": 85
4154
+ "Iran": 87
4155
+ "Thailand": 70
4156
+ "United Kingdom": 67
4157
+ "France": 68
4158
+ "Italy": 59
4159
+ "South Africa": 60
4160
+ "Tanzania": 63
4161
+ "Kenya": 54
4162
+ "South Korea": 52
4163
+ "Colombia": 51
4164
+ "Spain": 47
4165
+ "Argentina": 46
4166
+ "Algeria": 45
4167
+ "Sudan": 45
4168
+ "Ukraine": 41
4169
+ "Iraq": 42
4170
+ "Poland": 38
4171
+ "Canada": 38
4172
+ "Morocco": 37
4173
+ "Saudi Arabia": 35
4174
+ "Peru": 33
4175
+ "Malaysia": 33
4176
+ "Australia": 26
4177
+ options:
4178
+ colorScale: "blues"
4179
+ showLegend: true
4180
+ legendPosition: "bottom-right"
4181
+ legendTitle: "Population (millions)"
4182
+ \`\`\`
4183
+
4184
+ ---
4185
+
4186
+ ## Step 4: Highlight Top 5 Countries
4187
+
4188
+ \`\`\`
4189
+ pinepaper_highlight_regions
4190
+ regionIds: ["China", "India", "United States of America", "Indonesia", "Pakistan"]
4191
+ options:
4192
+ strokeColor: "#fbbf24"
4193
+ strokeWidth: 2
4194
+ animate: true
4195
+ \`\`\`
4196
+
4197
+ ---
4198
+
4199
+ ## Step 5: Add Capital City Markers
4200
+
4201
+ \`\`\`
4202
+ // Beijing - China
4203
+ pinepaper_add_marker lat: 39.9042 lon: 116.4074
4204
+ label: "Beijing"
4205
+ color: "#ef4444"
4206
+ size: 10
4207
+ pulse: true
4208
+
4209
+ // New Delhi - India
4210
+ pinepaper_add_marker lat: 28.6139 lon: 77.2090
4211
+ label: "New Delhi"
4212
+ color: "#ef4444"
4213
+ size: 10
4214
+ pulse: true
4215
+
4216
+ // Washington DC - USA
4217
+ pinepaper_add_marker lat: 38.9072 lon: -77.0369
4218
+ label: "Washington DC"
4219
+ color: "#ef4444"
4220
+ size: 8
4221
+ pulse: true
4222
+
4223
+ // Jakarta - Indonesia
4224
+ pinepaper_add_marker lat: -6.2088 lon: 106.8456
4225
+ label: "Jakarta"
4226
+ color: "#f59e0b"
4227
+ size: 8
4228
+ pulse: true
4229
+
4230
+ // Islamabad - Pakistan
4231
+ pinepaper_add_marker lat: 33.6844 lon: 73.0479
4232
+ label: "Islamabad"
4233
+ color: "#f59e0b"
4234
+ size: 8
4235
+ pulse: true
4236
+ \`\`\`
4237
+
4238
+ ---
4239
+
4240
+ ## Step 6: Add Title
4241
+
4242
+ \`\`\`
4243
+ pinepaper_create_item itemType: "text"
4244
+ position: {x: 640, y: 50}
4245
+ properties:
4246
+ content: "World Population 2024"
4247
+ fontSize: 36
4248
+ fontFamily: "Inter, sans-serif"
4249
+ fontWeight: "bold"
4250
+ color: "#ffffff"
4251
+ \`\`\`
4252
+
4253
+ ---
4254
+
4255
+ ## Step 7: Export
4256
+
4257
+ \`\`\`
4258
+ pinepaper_export_svg
4259
+ pinepaper_export_map
4260
+ \`\`\`
4261
+
4262
+ ---
4263
+
4264
+ ## Variations
4265
+
4266
+ ### Heat Map Version
4267
+ \`\`\`
4268
+ pinepaper_apply_data_colors
4269
+ data: { ... }
4270
+ options:
4271
+ colorScale: "heat"
4272
+ showLegend: true
4273
+ \`\`\`
4274
+
4275
+ ### Regional Focus (Asia)
4276
+ \`\`\`
4277
+ pinepaper_pan_map lat: 35 lon: 100 animate: true duration: 2
4278
+ pinepaper_zoom_map level: 2.5 animate: true
4279
+ \`\`\`
4280
+ `,
4281
+ 'pinepaper://examples/us-election-map': `# US Election Map Example
4282
+
4283
+ Build an interactive US election results visualization with state-by-state coloring and key battleground state highlights.
4284
+
4285
+ ## Final Result
4286
+
4287
+ A classic red/blue election map with swing states highlighted and electoral vote counts.
4288
+
4289
+ ---
4290
+
4291
+ ## Step 1: Set Up Canvas
4292
+
4293
+ \`\`\`
4294
+ pinepaper_set_background_color color: "#f8fafc"
4295
+ pinepaper_set_canvas_size preset: "presentation-16x9"
4296
+ \`\`\`
4297
+
4298
+ ---
4299
+
4300
+ ## Step 2: Load USA Map
4301
+
4302
+ \`\`\`
4303
+ pinepaper_load_map mapId: "usa"
4304
+ options:
4305
+ projection: "albers"
4306
+ quality: "professional"
4307
+ fillColor: "#e2e8f0"
4308
+ strokeColor: "#94a3b8"
4309
+ strokeWidth: 1
4310
+ enableHover: true
4311
+ enableClick: true
4312
+ \`\`\`
4313
+
4314
+ ---
4315
+
4316
+ ## Step 3: Color Democratic States (Blue)
4317
+
4318
+ \`\`\`
4319
+ pinepaper_highlight_regions
4320
+ regionIds: ["CA", "WA", "OR", "NV", "CO", "NM", "MN", "IL", "VA", "MD", "DE", "NJ", "CT", "RI", "MA", "VT", "NH", "ME", "NY", "HI"]
4321
+ options:
4322
+ fillColor: "#2563eb"
4323
+ strokeColor: "#1d4ed8"
4324
+ \`\`\`
4325
+
4326
+ ---
4327
+
4328
+ ## Step 4: Color Republican States (Red)
4329
+
4330
+ \`\`\`
4331
+ pinepaper_highlight_regions
4332
+ regionIds: ["TX", "OK", "KS", "NE", "SD", "ND", "MT", "WY", "ID", "UT", "AZ", "AK", "MO", "AR", "LA", "MS", "AL", "TN", "KY", "WV", "IN", "OH", "SC", "FL"]
4333
+ options:
4334
+ fillColor: "#dc2626"
4335
+ strokeColor: "#b91c1c"
4336
+ \`\`\`
4337
+
4338
+ ---
4339
+
4340
+ ## Step 5: Highlight Swing States
4341
+
4342
+ \`\`\`
4343
+ // Key battleground states with gold border
4344
+ pinepaper_highlight_regions
4345
+ regionIds: ["PA", "MI", "WI", "GA", "NC", "AZ"]
4346
+ options:
4347
+ strokeColor: "#fbbf24"
4348
+ strokeWidth: 3
4349
+ animate: true
4350
+ \`\`\`
4351
+
4352
+ ---
4353
+
4354
+ ## Step 6: Add Electoral Vote Labels
4355
+
4356
+ \`\`\`
4357
+ // California - 54 votes
4358
+ pinepaper_add_marker lat: 36.7783 lon: -119.4179
4359
+ label: "54"
4360
+ color: "#2563eb"
4361
+ size: 12
4362
+
4363
+ // Texas - 40 votes
4364
+ pinepaper_add_marker lat: 31.9686 lon: -99.9018
4365
+ label: "40"
4366
+ color: "#dc2626"
4367
+ size: 12
4368
+
4369
+ // Florida - 30 votes
4370
+ pinepaper_add_marker lat: 27.6648 lon: -81.5158
4371
+ label: "30"
4372
+ color: "#dc2626"
4373
+ size: 10
4374
+
4375
+ // New York - 28 votes
4376
+ pinepaper_add_marker lat: 42.1657 lon: -74.9481
4377
+ label: "28"
4378
+ color: "#2563eb"
4379
+ size: 10
4380
+
4381
+ // Pennsylvania - 19 votes (swing)
4382
+ pinepaper_add_marker lat: 41.2033 lon: -77.1945
4383
+ label: "19"
4384
+ color: "#fbbf24"
4385
+ size: 10
4386
+ pulse: true
4387
+
4388
+ // Michigan - 15 votes (swing)
4389
+ pinepaper_add_marker lat: 44.3148 lon: -85.6024
4390
+ label: "15"
4391
+ color: "#fbbf24"
4392
+ size: 9
4393
+ pulse: true
4394
+
4395
+ // Georgia - 16 votes (swing)
4396
+ pinepaper_add_marker lat: 32.1656 lon: -82.9001
4397
+ label: "16"
4398
+ color: "#fbbf24"
4399
+ size: 9
4400
+ pulse: true
4401
+ \`\`\`
4402
+
4403
+ ---
4404
+
4405
+ ## Step 7: Add Title and Legend
4406
+
4407
+ \`\`\`
4408
+ // Title
4409
+ pinepaper_create_item itemType: "text"
4410
+ position: {x: 640, y: 40}
4411
+ properties:
4412
+ content: "US Presidential Election Results"
4413
+ fontSize: 32
4414
+ fontWeight: "bold"
4415
+ color: "#1e293b"
4416
+
4417
+ // Legend - Democratic
4418
+ pinepaper_create_item itemType: "rectangle"
4419
+ position: {x: 100, y: 550}
4420
+ properties:
4421
+ width: 20
4422
+ height: 20
4423
+ color: "#2563eb"
4424
+
4425
+ pinepaper_create_item itemType: "text"
4426
+ position: {x: 130, y: 550}
4427
+ properties:
4428
+ content: "Democratic"
4429
+ fontSize: 14
4430
+ color: "#1e293b"
4431
+
4432
+ // Legend - Republican
4433
+ pinepaper_create_item itemType: "rectangle"
4434
+ position: {x: 250, y: 550}
4435
+ properties:
4436
+ width: 20
4437
+ height: 20
4438
+ color: "#dc2626"
4439
+
4440
+ pinepaper_create_item itemType: "text"
4441
+ position: {x: 280, y: 550}
4442
+ properties:
4443
+ content: "Republican"
4444
+ fontSize: 14
4445
+ color: "#1e293b"
4446
+
4447
+ // Legend - Swing State
4448
+ pinepaper_create_item itemType: "rectangle"
4449
+ position: {x: 400, y: 550}
4450
+ properties:
4451
+ width: 20
4452
+ height: 20
4453
+ color: "#fbbf24"
4454
+
4455
+ pinepaper_create_item itemType: "text"
4456
+ position: {x: 430, y: 550}
4457
+ properties:
4458
+ content: "Swing State"
4459
+ fontSize: 14
4460
+ color: "#1e293b"
4461
+ \`\`\`
4462
+
4463
+ ---
4464
+
4465
+ ## Step 8: Add Vote Totals
4466
+
4467
+ \`\`\`
4468
+ // Electoral vote boxes
4469
+ pinepaper_create_item itemType: "rectangle"
4470
+ position: {x: 200, y: 100}
4471
+ properties:
4472
+ width: 150
4473
+ height: 80
4474
+ color: "#2563eb"
4475
+ cornerRadius: 8
4476
+
4477
+ pinepaper_create_item itemType: "text"
4478
+ position: {x: 200, y: 90}
4479
+ properties:
4480
+ content: "270"
4481
+ fontSize: 36
4482
+ fontWeight: "bold"
4483
+ color: "#ffffff"
4484
+
4485
+ pinepaper_create_item itemType: "text"
4486
+ position: {x: 200, y: 120}
4487
+ properties:
4488
+ content: "Electoral Votes"
4489
+ fontSize: 12
4490
+ color: "#bfdbfe"
4491
+
4492
+ // Republican votes
4493
+ pinepaper_create_item itemType: "rectangle"
4494
+ position: {x: 1080, y: 100}
4495
+ properties:
4496
+ width: 150
4497
+ height: 80
4498
+ color: "#dc2626"
4499
+ cornerRadius: 8
4500
+
4501
+ pinepaper_create_item itemType: "text"
4502
+ position: {x: 1080, y: 90}
4503
+ properties:
4504
+ content: "268"
4505
+ fontSize: 36
4506
+ fontWeight: "bold"
4507
+ color: "#ffffff"
4508
+
4509
+ pinepaper_create_item itemType: "text"
4510
+ position: {x: 1080, y: 120}
4511
+ properties:
4512
+ content: "Electoral Votes"
4513
+ fontSize: 12
4514
+ color: "#fecaca"
4515
+ \`\`\`
4516
+
4517
+ ---
4518
+
4519
+ ## Step 9: Export
4520
+
4521
+ \`\`\`
4522
+ pinepaper_export_svg
4523
+ \`\`\`
4524
+ `,
4525
+ 'pinepaper://examples/travel-route-map': `# Travel Route Map Example
4526
+
4527
+ Visualize a travel itinerary across Europe with city markers, connecting routes, and animated journey highlights.
4528
+
4529
+ ## Final Result
4530
+
4531
+ An elegant travel map showing a European tour with cities connected by animated paths.
4532
+
4533
+ ---
4534
+
4535
+ ## Step 1: Set Up Canvas
4536
+
4537
+ \`\`\`
4538
+ pinepaper_set_background_color color: "#0f172a"
4539
+ pinepaper_set_canvas_size preset: "presentation-16x9"
4540
+ \`\`\`
4541
+
4542
+ ---
4543
+
4544
+ ## Step 2: Load World Map (Focused on Europe)
4545
+
4546
+ \`\`\`
4547
+ pinepaper_load_map mapId: "worldHighRes"
4548
+ options:
4549
+ projection: "mercator"
4550
+ quality: "professional"
4551
+ fillColor: "#1e293b"
4552
+ strokeColor: "#334155"
4553
+ strokeWidth: 0.5
4554
+ center: [10, 50]
4555
+ enableHover: true
4556
+ \`\`\`
4557
+
4558
+ ---
4559
+
4560
+ ## Step 3: Zoom to Europe
4561
+
4562
+ \`\`\`
4563
+ pinepaper_pan_map lat: 48 lon: 10 animate: true duration: 1
4564
+ pinepaper_zoom_map level: 4 animate: true duration: 1
4565
+ \`\`\`
4566
+
4567
+ ---
4568
+
4569
+ ## Step 4: Highlight Countries on Itinerary
4570
+
4571
+ \`\`\`
4572
+ pinepaper_highlight_regions
4573
+ regionIds: ["United Kingdom", "France", "Germany", "Italy", "Spain"]
4574
+ options:
4575
+ fillColor: "#334155"
4576
+ strokeColor: "#60a5fa"
4577
+ strokeWidth: 1
4578
+ animate: true
4579
+ \`\`\`
4580
+
4581
+ ---
4582
+
4583
+ ## Step 5: Add City Markers (The Journey)
4584
+
4585
+ \`\`\`
4586
+ // Day 1-3: London
4587
+ pinepaper_add_marker lat: 51.5074 lon: -0.1278
4588
+ label: "London"
4589
+ color: "#f59e0b"
4590
+ size: 12
4591
+ shape: "pin"
4592
+ pulse: true
4593
+
4594
+ // Day 4-5: Paris
4595
+ pinepaper_add_marker lat: 48.8566 lon: 2.3522
4596
+ label: "Paris"
4597
+ color: "#f59e0b"
4598
+ size: 12
4599
+ shape: "pin"
4600
+ pulse: true
4601
+
4602
+ // Day 6-7: Berlin
4603
+ pinepaper_add_marker lat: 52.5200 lon: 13.4050
4604
+ label: "Berlin"
4605
+ color: "#f59e0b"
4606
+ size: 12
4607
+ shape: "pin"
4608
+ pulse: true
4609
+
4610
+ // Day 8-10: Rome
4611
+ pinepaper_add_marker lat: 41.9028 lon: 12.4964
4612
+ label: "Rome"
4613
+ color: "#f59e0b"
4614
+ size: 12
4615
+ shape: "pin"
4616
+ pulse: true
4617
+
4618
+ // Day 11-12: Barcelona
4619
+ pinepaper_add_marker lat: 41.3851 lon: 2.1734
4620
+ label: "Barcelona"
4621
+ color: "#f59e0b"
4622
+ size: 12
4623
+ shape: "pin"
4624
+ pulse: true
4625
+ \`\`\`
4626
+
4627
+ ---
4628
+
4629
+ ## Step 6: Draw Route Lines
4630
+
4631
+ \`\`\`
4632
+ // London to Paris
4633
+ pinepaper_create_item itemType: "line"
4634
+ properties:
4635
+ from: {x: 380, y: 180}
4636
+ to: {x: 420, y: 220}
4637
+ strokeColor: "#60a5fa"
4638
+ strokeWidth: 2
4639
+ dashArray: [5, 5]
4640
+ → route1
4641
+
4642
+ // Paris to Berlin
4643
+ pinepaper_create_item itemType: "line"
4644
+ properties:
4645
+ from: {x: 420, y: 220}
4646
+ to: {x: 520, y: 180}
4647
+ strokeColor: "#60a5fa"
4648
+ strokeWidth: 2
4649
+ dashArray: [5, 5]
4650
+ → route2
4651
+
4652
+ // Berlin to Rome
4653
+ pinepaper_create_item itemType: "line"
4654
+ properties:
4655
+ from: {x: 520, y: 180}
4656
+ to: {x: 500, y: 340}
4657
+ strokeColor: "#60a5fa"
4658
+ strokeWidth: 2
4659
+ dashArray: [5, 5]
4660
+ → route3
4661
+
4662
+ // Rome to Barcelona
4663
+ pinepaper_create_item itemType: "line"
4664
+ properties:
4665
+ from: {x: 500, y: 340}
4666
+ to: {x: 380, y: 330}
4667
+ strokeColor: "#60a5fa"
4668
+ strokeWidth: 2
4669
+ dashArray: [5, 5]
4670
+ → route4
4671
+ \`\`\`
4672
+
4673
+ ---
4674
+
4675
+ ## Step 7: Animate Routes
4676
+
4677
+ \`\`\`
4678
+ pinepaper_animate_item itemId: "route1" animationType: "pulse" speed: 2
4679
+ pinepaper_animate_item itemId: "route2" animationType: "pulse" speed: 2
4680
+ pinepaper_animate_item itemId: "route3" animationType: "pulse" speed: 2
4681
+ pinepaper_animate_item itemId: "route4" animationType: "pulse" speed: 2
4682
+ \`\`\`
4683
+
4684
+ ---
4685
+
4686
+ ## Step 8: Add Day Numbers
4687
+
4688
+ \`\`\`
4689
+ // London days
4690
+ pinepaper_create_item itemType: "text"
4691
+ position: {x: 360, y: 160}
4692
+ properties:
4693
+ content: "Days 1-3"
4694
+ fontSize: 10
4695
+ color: "#94a3b8"
4696
+
4697
+ // Paris days
4698
+ pinepaper_create_item itemType: "text"
4699
+ position: {x: 440, y: 235}
4700
+ properties:
4701
+ content: "Days 4-5"
4702
+ fontSize: 10
4703
+ color: "#94a3b8"
4704
+
4705
+ // Berlin days
4706
+ pinepaper_create_item itemType: "text"
4707
+ position: {x: 540, y: 165}
4708
+ properties:
4709
+ content: "Days 6-7"
4710
+ fontSize: 10
4711
+ color: "#94a3b8"
4712
+
4713
+ // Rome days
4714
+ pinepaper_create_item itemType: "text"
4715
+ position: {x: 520, y: 355}
4716
+ properties:
4717
+ content: "Days 8-10"
4718
+ fontSize: 10
4719
+ color: "#94a3b8"
4720
+
4721
+ // Barcelona days
4722
+ pinepaper_create_item itemType: "text"
4723
+ position: {x: 360, y: 345}
4724
+ properties:
4725
+ content: "Days 11-12"
4726
+ fontSize: 10
4727
+ color: "#94a3b8"
4728
+ \`\`\`
4729
+
4730
+ ---
4731
+
4732
+ ## Step 9: Add Title and Decorations
4733
+
4734
+ \`\`\`
4735
+ // Title
4736
+ pinepaper_create_item itemType: "text"
4737
+ position: {x: 640, y: 40}
4738
+ properties:
4739
+ content: "European Adventure 2024"
4740
+ fontSize: 28
4741
+ fontWeight: "bold"
4742
+ color: "#f8fafc"
4743
+
4744
+ // Subtitle
4745
+ pinepaper_create_item itemType: "text"
4746
+ position: {x: 640, y: 70}
4747
+ properties:
4748
+ content: "12 Days • 5 Cities • 1 Amazing Journey"
4749
+ fontSize: 14
4750
+ color: "#94a3b8"
4751
+
4752
+ // Airplane icon at start
4753
+ pinepaper_create_item itemType: "text"
4754
+ position: {x: 340, y: 180}
4755
+ properties:
4756
+ content: "✈️"
4757
+ fontSize: 20
4758
+ \`\`\`
4759
+
4760
+ ---
4761
+
4762
+ ## Step 10: Add Summary Box
4763
+
4764
+ \`\`\`
4765
+ // Summary background
4766
+ pinepaper_create_item itemType: "rectangle"
4767
+ position: {x: 1100, y: 300}
4768
+ properties:
4769
+ width: 180
4770
+ height: 200
4771
+ color: "#1e293b"
4772
+ cornerRadius: 12
4773
+ strokeColor: "#334155"
4774
+ strokeWidth: 1
4775
+
4776
+ // Summary title
4777
+ pinepaper_create_item itemType: "text"
4778
+ position: {x: 1100, y: 230}
4779
+ properties:
4780
+ content: "Trip Summary"
4781
+ fontSize: 14
4782
+ fontWeight: "bold"
4783
+ color: "#f8fafc"
4784
+
4785
+ // Stats
4786
+ pinepaper_create_item itemType: "text"
4787
+ position: {x: 1100, y: 260}
4788
+ properties:
4789
+ content: "📍 5 Cities"
4790
+ fontSize: 12
4791
+ color: "#94a3b8"
4792
+
4793
+ pinepaper_create_item itemType: "text"
4794
+ position: {x: 1100, y: 285}
4795
+ properties:
4796
+ content: "📅 12 Days"
4797
+ fontSize: 12
4798
+ color: "#94a3b8"
4799
+
4800
+ pinepaper_create_item itemType: "text"
4801
+ position: {x: 1100, y: 310}
4802
+ properties:
4803
+ content: "🛫 4 Flights"
4804
+ fontSize: 12
4805
+ color: "#94a3b8"
4806
+
4807
+ pinepaper_create_item itemType: "text"
4808
+ position: {x: 1100, y: 335}
4809
+ properties:
4810
+ content: "🏨 11 Nights"
4811
+ fontSize: 12
4812
+ color: "#94a3b8"
4813
+ \`\`\`
4814
+
4815
+ ---
4816
+
4817
+ ## Step 11: Export
4818
+
4819
+ \`\`\`
4820
+ pinepaper_export_svg
4821
+ \`\`\`
4822
+
4823
+ ---
4824
+
4825
+ ## Variations
4826
+
4827
+ ### Animated Route Reveal
4828
+ Use keyframe animations to reveal the route step by step:
4829
+ \`\`\`
4830
+ pinepaper_keyframe_animate itemId: "route1"
4831
+ keyframes:
4832
+ - time: 0, properties: {opacity: 0}
4833
+ - time: 1, properties: {opacity: 1}
4834
+
4835
+ pinepaper_keyframe_animate itemId: "route2"
4836
+ keyframes:
4837
+ - time: 1, properties: {opacity: 0}
4838
+ - time: 2, properties: {opacity: 1}
4839
+ \`\`\`
4840
+
4841
+ ### Distance Labels
4842
+ Add distance between cities:
4843
+ \`\`\`
4844
+ pinepaper_create_item itemType: "text"
4845
+ position: {x: 400, y: 200}
4846
+ properties:
4847
+ content: "344 km"
4848
+ fontSize: 8
4849
+ color: "#60a5fa"
4850
+ \`\`\`
4851
+ `,
4852
+ 'pinepaper://docs/diagrams': `# Diagrams Guide
4853
+
4854
+ **Intent:** Create flowcharts, UML diagrams, network architectures, and connect any visual elements with smart arrows.
4855
+
4856
+ ## When to Use Diagrams
4857
+
4858
+ Use diagram tools when you need to:
4859
+ - Build flowcharts with decision logic
4860
+ - Create UML diagrams (class, use case)
4861
+ - Design network/architecture diagrams
4862
+ - Connect any items (images, shapes, text) with arrows
4863
+ - Show process flows with animated connectors
4864
+
4865
+ ## Key Tools
4866
+
4867
+ | Tool | Purpose |
4868
+ |------|---------|
4869
+ | \`pinepaper_create_diagram_shape\` | Create flowchart/UML/network shapes |
4870
+ | \`pinepaper_connect\` | Connect items with smart arrows |
4871
+ | \`pinepaper_auto_layout\` | Automatically arrange connected shapes |
4872
+ | \`pinepaper_get_diagram_shapes\` | List available shape types |
4873
+ | \`pinepaper_diagram_mode\` | Enable/disable diagram editing mode |
4874
+
4875
+ ## Shape Types
4876
+
4877
+ ### Flowchart Shapes
4878
+ | Shape | Use For |
4879
+ |-------|---------|
4880
+ | \`process\` | Actions, steps (rectangle) |
4881
+ | \`decision\` | Yes/No branching (diamond) |
4882
+ | \`terminal\` | Start/End points (rounded) |
4883
+ | \`data\` | Input/Output (parallelogram) |
4884
+ | \`document\` | Documents (wavy bottom) |
4885
+ | \`database\` | Data storage (cylinder) |
4886
+ | \`preparation\` | Setup steps (hexagon) |
4887
+
4888
+ ### UML Shapes
4889
+ | Shape | Use For |
4890
+ |-------|---------|
4891
+ | \`uml-class\` | Class definitions |
4892
+ | \`uml-usecase\` | Use case ellipse |
4893
+ | \`uml-actor\` | Stick figure actor |
4894
+
4895
+ ### Network Shapes
4896
+ | Shape | Use For |
4897
+ |-------|---------|
4898
+ | \`cloud\` | Cloud services |
4899
+ | \`server\` | Server/computer |
4900
+
4901
+ ## Creating a Flowchart
4902
+
4903
+ \`\`\`
4904
+ // Step 1: Create shapes
4905
+ pinepaper_create_diagram_shape
4906
+ shapeType: "terminal"
4907
+ position: {x: 400, y: 100}
4908
+ label: "Start"
4909
+ style: {fillColor: "#22c55e"}
4910
+ → item_1
4911
+
4912
+ pinepaper_create_diagram_shape
4913
+ shapeType: "process"
4914
+ position: {x: 400, y: 200}
4915
+ label: "Process Data"
4916
+ → item_2
4917
+
4918
+ pinepaper_create_diagram_shape
4919
+ shapeType: "decision"
4920
+ position: {x: 400, y: 320}
4921
+ label: "Valid?"
4922
+ style: {fillColor: "#fbbf24"}
4923
+ → item_3
4924
+
4925
+ pinepaper_create_diagram_shape
4926
+ shapeType: "terminal"
4927
+ position: {x: 400, y: 440}
4928
+ label: "End"
4929
+ style: {fillColor: "#ef4444"}
4930
+ → item_4
4931
+
4932
+ // Step 2: Connect shapes
4933
+ pinepaper_connect
4934
+ sourceItemId: "item_1"
4935
+ targetItemId: "item_2"
4936
+ routing: "orthogonal"
4937
+
4938
+ pinepaper_connect
4939
+ sourceItemId: "item_2"
4940
+ targetItemId: "item_3"
4941
+
4942
+ pinepaper_connect
4943
+ sourceItemId: "item_3"
4944
+ targetItemId: "item_4"
4945
+ label: "Yes"
4946
+ \`\`\`
4947
+
4948
+ ## Connector Options
4949
+
4950
+ ### Routing Styles
4951
+ | Style | Description |
4952
+ |-------|-------------|
4953
+ | \`orthogonal\` | Right-angle paths (default, best for flowcharts) |
4954
+ | \`curved\` | Smooth curved paths |
4955
+ | \`direct\` | Straight line |
4956
+
4957
+ ### Arrow Styles
4958
+ | Style | Description |
4959
+ |-------|-------------|
4960
+ | \`classic\` | Standard arrow (default) |
4961
+ | \`stealth\` | Sleek pointed arrow |
4962
+ | \`sharp\` | Sharp angular arrow |
4963
+ | \`open\` | Outlined arrow |
4964
+ | \`diamond\` | Diamond shape |
4965
+ | \`circle\` | Circle endpoint |
4966
+ | \`none\` | No arrowhead |
4967
+
4968
+ ### Line Styles
4969
+ | Style | Description |
4970
+ |-------|-------------|
4971
+ | \`solid\` | Continuous line |
4972
+ | \`dashed\` | Dashed line |
4973
+ | \`dotted\` | Dotted line |
4974
+
4975
+ ## Connector Example
4976
+
4977
+ \`\`\`
4978
+ pinepaper_connect
4979
+ sourceItemId: "item_1"
4980
+ targetItemId: "item_2"
4981
+ routing: "curved"
4982
+ lineColor: "#3b82f6"
4983
+ lineWidth: 2
4984
+ lineStyle: "dashed"
4985
+ headStyle: "stealth"
4986
+ label: "Yes"
4987
+ animated: true // Bolt effect shows direction
4988
+ \`\`\`
4989
+
4990
+ ## Connecting Any Items
4991
+
4992
+ Diagram connectors work with ANY canvas items, not just diagram shapes:
4993
+
4994
+ \`\`\`
4995
+ // Connect images
4996
+ pinepaper_import_svg url: "https://example.com/icon1.svg" → item_1
4997
+ pinepaper_import_svg url: "https://example.com/icon2.svg" → item_2
4998
+ pinepaper_connect sourceItemId: "item_1" targetItemId: "item_2"
4999
+
5000
+ // Connect text labels
5001
+ pinepaper_create_item itemType: "text" properties: {content: "A"} → item_3
5002
+ pinepaper_create_item itemType: "text" properties: {content: "B"} → item_4
5003
+ pinepaper_connect sourceItemId: "item_3" targetItemId: "item_4"
5004
+ \`\`\`
5005
+
5006
+ ## Auto Layout
5007
+
5008
+ Automatically arrange connected shapes:
5009
+
5010
+ \`\`\`
5011
+ pinepaper_auto_layout
5012
+ direction: "TB" // TB, BT, LR, RL
5013
+ spacing: {horizontal: 80, vertical: 60}
5014
+ \`\`\`
5015
+
5016
+ | Direction | Description |
5017
+ |-----------|-------------|
5018
+ | \`TB\` | Top to Bottom |
5019
+ | \`BT\` | Bottom to Top |
5020
+ | \`LR\` | Left to Right |
5021
+ | \`RL\` | Right to Left |
5022
+ `,
5023
+ 'pinepaper://docs/masks': `# Masks Guide
5024
+
5025
+ **Intent:** Create reveal animations and transitions using animated clipping masks (wipes, iris, curtains, custom shapes).
5026
+
5027
+ ## When to Use Masks
5028
+
5029
+ Use mask tools when you need to:
5030
+ - Reveal text or images with wipe effects
5031
+ - Create iris/zoom reveal animations
5032
+ - Build curtain-style transitions
5033
+ - Design custom reveal sequences
5034
+ - Add cinematic letterbox effects
5035
+
5036
+ ## Key Tools
5037
+
5038
+ | Tool | Purpose |
5039
+ |------|---------|
5040
+ | \`pinepaper_apply_animated_mask\` | Apply reveal animation (preset or custom) |
5041
+ | \`pinepaper_apply_custom_mask\` | Full keyframe control |
5042
+ | \`pinepaper_remove_mask\` | Remove mask from item |
5043
+ | \`pinepaper_get_mask_animations\` | List available presets |
5044
+ | \`pinepaper_get_mask_types\` | List mask shapes |
5045
+ | \`pinepaper_get_animatable_properties\` | Get keyframeable properties |
5046
+ | \`pinepaper_get_available_easings\` | List easing functions |
5047
+
5048
+ ## Animation Presets
5049
+
5050
+ ### Wipe Effects
5051
+ | Preset | Effect |
5052
+ |--------|--------|
5053
+ | \`wipeLeft\` | Reveal from left to right |
5054
+ | \`wipeRight\` | Reveal from right to left |
5055
+ | \`wipeUp\` | Reveal from bottom to top |
5056
+ | \`wipeDown\` | Reveal from top to bottom |
5057
+ | \`diagonalWipe\` | Angled reveal from corner |
5058
+
5059
+ ### Iris Effects
5060
+ | Preset | Effect |
5061
+ |--------|--------|
5062
+ | \`iris\` | Circle expands from center |
5063
+ | \`irisOut\` | Circle shrinks to center (hide) |
5064
+
5065
+ ### Shape Reveals
5066
+ | Preset | Effect |
5067
+ |--------|--------|
5068
+ | \`star\` | Star shape scales up |
5069
+ | \`heart\` | Heart shape scales up |
5070
+
5071
+ ### Curtain Effects
5072
+ | Preset | Effect |
5073
+ |--------|--------|
5074
+ | \`curtainHorizontal\` | Opens from center horizontally |
5075
+ | \`curtainVertical\` | Opens from center vertically |
5076
+ | \`cinematic\` | Letterbox bars animate away |
5077
+
5078
+ ### Text Reveals
5079
+ | Preset | Effect |
5080
+ |--------|--------|
5081
+ | \`revealUp\` | Text slides up within mask |
5082
+ | \`revealDown\` | Text slides down within mask |
5083
+
5084
+ ## Quick Start: Preset Mode
5085
+
5086
+ \`\`\`
5087
+ // Create an item
5088
+ pinepaper_create_item
5089
+ itemType: "text"
5090
+ position: {x: 400, y: 300}
5091
+ properties: {content: "Hello World", fontSize: 48, color: "#ffffff"}
5092
+ → item_1
5093
+
5094
+ // Apply wipe reveal
5095
+ pinepaper_apply_animated_mask
5096
+ itemId: "item_1"
5097
+ preset: "wipeLeft"
5098
+ options:
5099
+ duration: 0.5
5100
+ easing: "easeOut"
5101
+ \`\`\`
5102
+
5103
+ ## Preset Options
5104
+
5105
+ | Option | Type | Default | Description |
5106
+ |--------|------|---------|-------------|
5107
+ | \`startTime\` | number | 0 | Delay before animation starts (seconds) |
5108
+ | \`duration\` | number | 0.8 | Animation duration (seconds) |
5109
+ | \`easing\` | string | "easeOut" | Timing function |
5110
+ | \`reversed\` | boolean | false | Play in reverse (hide instead of reveal) |
5111
+ | \`loop\` | boolean | false | Loop the animation |
5112
+
5113
+ ## Easing Functions
5114
+
5115
+ | Easing | Description |
5116
+ |--------|-------------|
5117
+ | \`linear\` | Constant speed |
5118
+ | \`easeIn\` | Slow start, fast end |
5119
+ | \`easeOut\` | Fast start, slow end |
5120
+ | \`easeInOut\` | Slow start and end |
5121
+ | \`bounce\` | Bouncing effect at end |
5122
+ | \`elastic\` | Spring-like overshoot |
5123
+
5124
+ ## Custom Keyframe Animation
5125
+
5126
+ For full control, define keyframes manually:
5127
+
5128
+ \`\`\`
5129
+ pinepaper_apply_animated_mask
5130
+ itemId: "item_1"
5131
+ maskType: "rectangle"
5132
+ keyframes:
5133
+ - time: 0
5134
+ properties: {x: 200, y: 250, width: 0, height: 100}
5135
+ easing: "linear"
5136
+ - time: 0.5
5137
+ properties: {x: 200, y: 250, width: 100, height: 100}
5138
+ easing: "easeIn"
5139
+ - time: 1
5140
+ properties: {x: 200, y: 250, width: 200, height: 100}
5141
+ easing: "easeOut"
5142
+ \`\`\`
5143
+
5144
+ ## Mask Types
5145
+
5146
+ | Type | Animatable Properties |
5147
+ |------|----------------------|
5148
+ | \`rectangle\` | x, y, width, height, rotation, opacity |
5149
+ | \`circle\` | x, y, radius, scale, opacity |
5150
+ | \`ellipse\` | x, y, radiusX, radiusY, rotation, scale, opacity |
5151
+ | \`star\` | x, y, radius, scale, rotation, opacity |
5152
+ | \`triangle\` | x, y, scale, rotation, opacity |
5153
+ | \`hexagon\` | x, y, scale, rotation, opacity |
5154
+ | \`heart\` | x, y, scale, rotation, opacity |
5155
+ | \`rounded\` | x, y, width, height, cornerRadius, opacity |
5156
+
5157
+ ## Hybrid Mode: Preset + Custom Keyframes
5158
+
5159
+ Combine preset behavior with custom timing:
5160
+
5161
+ \`\`\`
5162
+ pinepaper_apply_animated_mask
5163
+ itemId: "item_1"
5164
+ preset: "iris"
5165
+ keyframes:
5166
+ - time: 0
5167
+ properties: {scale: 0.01}
5168
+ easing: "linear"
5169
+ - time: 0.3
5170
+ properties: {scale: 0.3}
5171
+ easing: "easeIn"
5172
+ - time: 0.7
5173
+ properties: {scale: 0.8}
5174
+ easing: "easeOut"
5175
+ - time: 1
5176
+ properties: {scale: 1}
5177
+ easing: "bounce"
5178
+ \`\`\`
5179
+
5180
+ ## Staggered Text Reveal
5181
+
5182
+ Reveal multiple words with delays:
5183
+
5184
+ \`\`\`
5185
+ // Create words
5186
+ pinepaper_create_item itemType: "text" position: {x: 200, y: 300}
5187
+ properties: {content: "Hello", fontSize: 36} → item_1
5188
+
5189
+ pinepaper_create_item itemType: "text" position: {x: 350, y: 300}
5190
+ properties: {content: "Beautiful", fontSize: 36} → item_2
5191
+
5192
+ pinepaper_create_item itemType: "text" position: {x: 550, y: 300}
5193
+ properties: {content: "World", fontSize: 36} → item_3
5194
+
5195
+ // Apply staggered reveals
5196
+ pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeUp"
5197
+ options: {startTime: 0, duration: 0.3}
5198
+
5199
+ pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeUp"
5200
+ options: {startTime: 0.2, duration: 0.3}
5201
+
5202
+ pinepaper_apply_animated_mask itemId: "item_3" preset: "wipeUp"
5203
+ options: {startTime: 0.4, duration: 0.3}
5204
+ \`\`\`
5205
+
5206
+ ## Removing Masks
5207
+
5208
+ \`\`\`
5209
+ pinepaper_remove_mask itemId: "item_1"
5210
+ \`\`\`
5211
+ `,
5212
+ 'pinepaper://docs/fonts': `# Font Studio Guide
5213
+
5214
+ **Intent:** Create custom hand-drawn fonts by drawing glyphs on a dedicated canvas, then export as OTF files or use directly in PinePaper documents.
5215
+
5216
+ ## Overview
5217
+
5218
+ Font Studio provides 16 tools for creating custom fonts programmatically. You draw each character as a Paper.js path, clean it up, and convert it to a font glyph.
5219
+
5220
+ ## Key Tools
5221
+
5222
+ | Tool | Purpose |
5223
+ |------|---------|
5224
+ | \`pinepaper_font_show_studio\` | Open the Font Studio UI with guide lines |
5225
+ | \`pinepaper_font_set_name\` | Set font family name |
5226
+ | \`pinepaper_font_get_required_chars\` | Get list of characters needed |
5227
+ | \`pinepaper_font_get_status\` | Check completion progress |
5228
+ | \`pinepaper_font_create_glyph\` | Convert a drawn path to a glyph |
5229
+ | \`pinepaper_font_create_space\` | Create the space character |
5230
+ | \`pinepaper_font_remove_glyph\` | Remove a glyph for redrawing |
5231
+ | \`pinepaper_font_set_metrics\` | Configure font metrics (advanced) |
5232
+ | \`pinepaper_font_export\` | Export as OTF file |
5233
+ | \`pinepaper_font_load_into_document\` | Use font in current document |
5234
+ | \`pinepaper_font_export_data\` | Save progress as JSON |
5235
+ | \`pinepaper_font_import_data\` | Resume from saved data |
5236
+ | \`pinepaper_font_clear\` | Reset all glyphs |
5237
+ | \`pinepaper_font_remove_overlap\` | Merge overlapping path strokes |
5238
+ | \`pinepaper_font_correct_direction\` | Fix path winding for fills |
5239
+ | \`pinepaper_font_cleanup_path\` | All-in-one path preparation |
5240
+
5241
+ ## Workflow
5242
+
5243
+ ### Step 1: Open Font Studio
5244
+ \`\`\`
5245
+ pinepaper_font_show_studio
5246
+ \`\`\`
5247
+
5248
+ Opens the interactive Font Studio UI with typography guide lines:
5249
+ - **Cap Height** (Red): Top of capital letters (H, T, A)
5250
+ - **x-Height** (Cyan): Top of lowercase letters (a, e, x)
5251
+ - **Baseline** (Green): Where letters sit
5252
+ - **Descender** (Purple): Below baseline for g, p, y, j
5253
+
5254
+ ### Step 2: Set Font Name
5255
+ \`\`\`
5256
+ pinepaper_font_set_name name: "MyHandwriting"
5257
+ \`\`\`
5258
+
5259
+ ### Step 3: Check Required Characters
5260
+ \`\`\`
5261
+ pinepaper_font_get_required_chars set: "minimum"
5262
+ \`\`\`
5263
+
5264
+ Two character sets available:
5265
+ - **minimum**: A-Z, a-z, 0-9, space (63 chars) - enough for basic text
5266
+ - **standard**: adds punctuation and symbols (90+ chars)
5267
+
5268
+ ### Step 4: Draw and Create Glyphs
5269
+
5270
+ For each character:
5271
+
5272
+ 1. **Draw the character** as a Paper.js path on the canvas
5273
+ 2. **Clean up the path** (recommended):
5274
+ \`\`\`
5275
+ pinepaper_font_cleanup_path pathId: "item_42"
5276
+ \`\`\`
5277
+ 3. **Create the glyph**:
5278
+ \`\`\`
5279
+ pinepaper_font_create_glyph character: "A" pathId: "item_42"
5280
+ \`\`\`
5281
+
5282
+ For the space character (no visible path needed):
5283
+ \`\`\`
5284
+ pinepaper_font_create_space width: 250
5285
+ \`\`\`
5286
+
5287
+ ### Step 5: Check Progress
5288
+ \`\`\`
5289
+ pinepaper_font_get_status
5290
+ \`\`\`
5291
+
5292
+ Returns: font name, total/completed/pending counts, percentage, and character lists.
5293
+
5294
+ ### Step 6: Export
5295
+
5296
+ Export as OTF file:
5297
+ \`\`\`
5298
+ pinepaper_font_export
5299
+ \`\`\`
5300
+
5301
+ Or load directly into the document:
5302
+ \`\`\`
5303
+ pinepaper_font_load_into_document
5304
+ \`\`\`
5305
+
5306
+ ## Path Cleanup Tools
5307
+
5308
+ Before converting a drawn path to a glyph, clean it up for best results:
5309
+
5310
+ | Tool | What It Does |
5311
+ |------|-------------|
5312
+ | \`pinepaper_font_remove_overlap\` | Merges overlapping strokes into one outline |
5313
+ | \`pinepaper_font_correct_direction\` | Fixes winding so fills render correctly |
5314
+ | \`pinepaper_font_cleanup_path\` | Does all cleanup in one call (overlap + direction + smooth) |
5315
+
5316
+ The \`cleanup_path\` tool accepts options:
5317
+ \`\`\`
5318
+ pinepaper_font_cleanup_path
5319
+ pathId: "item_42"
5320
+ removeOverlap: true
5321
+ correctDirection: true
5322
+ smooth: true
5323
+ smoothTolerance: 2.5
5324
+ \`\`\`
5325
+
5326
+ ## Font Metrics (Advanced)
5327
+
5328
+ Configure the font's coordinate system:
5329
+ \`\`\`
5330
+ pinepaper_font_set_metrics
5331
+ unitsPerEm: 1000
5332
+ ascender: 800
5333
+ descender: -200
5334
+ xHeight: 500
5335
+ capHeight: 700
5336
+ \`\`\`
5337
+
5338
+ ## Save and Resume Progress
5339
+
5340
+ Save work-in-progress:
5341
+ \`\`\`
5342
+ pinepaper_font_export_data
5343
+ \`\`\`
5344
+
5345
+ Resume later:
5346
+ \`\`\`
5347
+ pinepaper_font_import_data data: { ... }
5348
+ \`\`\`
5349
+
5350
+ ## Best Practices
5351
+
5352
+ - Keep stroke width consistent across all characters
5353
+ - Uppercase letters should touch the cap height line
5354
+ - Lowercase (except b, d, f, h, k, l, t) stay within x-height
5355
+ - Letters g, j, p, q, y extend below baseline to descender
5356
+ - Always run \`cleanup_path\` before \`create_glyph\` for cleanest results
5357
+ - Use \`get_status\` frequently to track progress
5358
+ - Save progress with \`export_data\` periodically
5359
+ `,
5360
+ 'pinepaper://examples/us-states-animated': `# US States Animated Map Example
5361
+
5362
+ **Intent:** Create a US map with animated color transitions that loop continuously.
5363
+
5364
+ ## What You'll Build
5365
+
5366
+ A USA map where states randomly change colors in a flowing wave animation.
5367
+
5368
+ ## Step 1: Load the Map
5369
+
5370
+ \`\`\`
5371
+ pinepaper_load_map
5372
+ mapId: "usa"
5373
+ options:
5374
+ projection: "albers"
5375
+ quality: "balanced"
5376
+ fillColor: "#e5e7eb"
5377
+ strokeColor: "#9ca3af"
5378
+ \`\`\`
5379
+
5380
+ ## Step 2: Apply Wave Animation
5381
+
5382
+ \`\`\`
5383
+ pinepaper_animate_map_wave
5384
+ duration: 10
5385
+ loop: true
5386
+ colors: ["#ef4444", "#f97316", "#fbbf24", "#22c55e", "#3b82f6", "#8b5cf6"]
5387
+ options:
5388
+ delayBetween: 0.1
5389
+ easing: "easeInOut"
5390
+ \`\`\`
5391
+
5392
+ ## Result
5393
+
5394
+ States will animate through the color palette in a wave pattern, creating a mesmerizing continuous animation.
5395
+
5396
+ ## Alternative: Data-Driven Colors
5397
+
5398
+ Apply colors based on data values:
5399
+
5400
+ \`\`\`
5401
+ pinepaper_apply_data_colors
5402
+ data:
5403
+ "CA": 100
5404
+ "TX": 85
5405
+ "FL": 70
5406
+ "NY": 65
5407
+ "PA": 50
5408
+ "IL": 45
5409
+ "OH": 40
5410
+ options:
5411
+ colorScale: "blues"
5412
+ legend: true
5413
+ legendPosition: "bottom-right"
5414
+ \`\`\`
5415
+
5416
+ ## Alternative: Highlight Specific States
5417
+
5418
+ \`\`\`
5419
+ pinepaper_highlight_regions
5420
+ regionIds: ["CA", "OR", "WA"]
5421
+ options:
5422
+ fillColor: "#22c55e"
5423
+ strokeColor: "#16a34a"
5424
+ animated: true
5425
+ \`\`\`
5426
+
5427
+ ## Key Tools Used
5428
+
5429
+ | Tool | Purpose |
5430
+ |------|---------|
5431
+ | \`pinepaper_load_map\` | Load USA map with Albers projection |
5432
+ | \`pinepaper_animate_map_wave\` | Create looping color animation |
5433
+ | \`pinepaper_apply_data_colors\` | Color by numeric values |
5434
+ | \`pinepaper_highlight_regions\` | Highlight specific states |
5435
+
5436
+ ## Region ID Format
5437
+
5438
+ For USA maps, use 2-letter state codes:
5439
+ - CA, TX, NY, FL, WA, OR, etc.
5440
+
5441
+ ## Export
5442
+
5443
+ \`\`\`
5444
+ pinepaper_export_svg animated: true
5445
+ \`\`\`
5446
+ `,
5447
+ 'pinepaper://examples/flowchart': `# Flowchart Example
5448
+
5449
+ **Intent:** Create a decision flowchart with auto-layout and animated connectors.
5450
+
5451
+ ## What You'll Build
5452
+
5453
+ A simple decision flowchart: Start → Process → Decision → End
5454
+
5455
+ ## Step 1: Create Shapes
5456
+
5457
+ \`\`\`
5458
+ // Start terminal
5459
+ pinepaper_create_diagram_shape
5460
+ shapeType: "terminal"
5461
+ position: {x: 400, y: 80}
5462
+ label: "Start"
5463
+ style: {fillColor: "#22c55e", strokeColor: "#16a34a"}
5464
+ → item_1
5465
+
5466
+ // Process step
5467
+ pinepaper_create_diagram_shape
5468
+ shapeType: "process"
5469
+ position: {x: 400, y: 180}
5470
+ label: "Check Input"
5471
+ style: {fillColor: "#3b82f6", strokeColor: "#2563eb"}
5472
+ → item_2
5473
+
5474
+ // Decision diamond
5475
+ pinepaper_create_diagram_shape
5476
+ shapeType: "decision"
5477
+ position: {x: 400, y: 300}
5478
+ label: "Valid?"
5479
+ style: {fillColor: "#fbbf24", strokeColor: "#f59e0b"}
5480
+ → item_3
5481
+
5482
+ // Success path
5483
+ pinepaper_create_diagram_shape
5484
+ shapeType: "process"
5485
+ position: {x: 250, y: 420}
5486
+ label: "Process Data"
5487
+ style: {fillColor: "#3b82f6", strokeColor: "#2563eb"}
5488
+ → item_4
5489
+
5490
+ // Error path
5491
+ pinepaper_create_diagram_shape
5492
+ shapeType: "process"
5493
+ position: {x: 550, y: 420}
5494
+ label: "Show Error"
5495
+ style: {fillColor: "#ef4444", strokeColor: "#dc2626"}
5496
+ → item_5
5497
+
5498
+ // End terminal
5499
+ pinepaper_create_diagram_shape
5500
+ shapeType: "terminal"
5501
+ position: {x: 400, y: 540}
5502
+ label: "End"
5503
+ style: {fillColor: "#6b7280", strokeColor: "#4b5563"}
5504
+ → item_6
5505
+ \`\`\`
5506
+
5507
+ ## Step 2: Connect Shapes
5508
+
5509
+ \`\`\`
5510
+ // Start to Check
5511
+ pinepaper_connect
5512
+ sourceItemId: "item_1"
5513
+ targetItemId: "item_2"
5514
+ routing: "orthogonal"
5515
+ lineColor: "#374151"
5516
+
5517
+ // Check to Decision
5518
+ pinepaper_connect
5519
+ sourceItemId: "item_2"
5520
+ targetItemId: "item_3"
5521
+ routing: "orthogonal"
5522
+ lineColor: "#374151"
5523
+
5524
+ // Decision Yes path
5525
+ pinepaper_connect
5526
+ sourceItemId: "item_3"
5527
+ targetItemId: "item_4"
5528
+ routing: "orthogonal"
5529
+ lineColor: "#22c55e"
5530
+ label: "Yes"
5531
+
5532
+ // Decision No path
5533
+ pinepaper_connect
5534
+ sourceItemId: "item_3"
5535
+ targetItemId: "item_5"
5536
+ routing: "orthogonal"
5537
+ lineColor: "#ef4444"
5538
+ label: "No"
5539
+
5540
+ // Process to End
5541
+ pinepaper_connect
5542
+ sourceItemId: "item_4"
5543
+ targetItemId: "item_6"
5544
+ routing: "orthogonal"
5545
+ lineColor: "#374151"
5546
+
5547
+ // Error to End
5548
+ pinepaper_connect
5549
+ sourceItemId: "item_5"
5550
+ targetItemId: "item_6"
5551
+ routing: "orthogonal"
5552
+ lineColor: "#374151"
5553
+ \`\`\`
5554
+
5555
+ ## Step 3: Apply Auto-Layout (Optional)
5556
+
5557
+ \`\`\`
5558
+ pinepaper_auto_layout
5559
+ direction: "TB"
5560
+ spacing: {horizontal: 100, vertical: 80}
5561
+ \`\`\`
5562
+
5563
+ ## Adding Animation
5564
+
5565
+ Make connectors animated to show flow direction:
5566
+
5567
+ \`\`\`
5568
+ pinepaper_connect
5569
+ sourceItemId: "item_1"
5570
+ targetItemId: "item_2"
5571
+ animated: true // Bolt effect shows direction
5572
+ lineColor: "#3b82f6"
5573
+ \`\`\`
5574
+
5575
+ ## Key Tools Used
5576
+
5577
+ | Tool | Purpose |
5578
+ |------|---------|
5579
+ | \`pinepaper_create_diagram_shape\` | Create flowchart symbols |
5580
+ | \`pinepaper_connect\` | Draw smart connectors |
5581
+ | \`pinepaper_auto_layout\` | Automatic arrangement |
5582
+
5583
+ ## Shape Reference
5584
+
5585
+ | Shape | Symbol | Use For |
5586
+ |-------|--------|---------|
5587
+ | \`terminal\` | Rounded rectangle | Start/End |
5588
+ | \`process\` | Rectangle | Actions |
5589
+ | \`decision\` | Diamond | Yes/No branching |
5590
+ | \`data\` | Parallelogram | Input/Output |
5591
+ | \`document\` | Wavy rectangle | Documents |
5592
+ `,
5593
+ 'pinepaper://examples/reveal-animation': `# Reveal Animation Example
5594
+
5595
+ **Intent:** Create a text reveal animation using mask effects.
5596
+
5597
+ ## What You'll Build
5598
+
5599
+ Text that reveals with a smooth wipe animation, perfect for intros and titles.
5600
+
5601
+ ## Method 1: Simple Preset
5602
+
5603
+ \`\`\`
5604
+ // Create text
5605
+ pinepaper_create_item
5606
+ itemType: "text"
5607
+ position: {x: 400, y: 300}
5608
+ properties:
5609
+ content: "Welcome"
5610
+ fontSize: 64
5611
+ fontWeight: "bold"
5612
+ color: "#ffffff"
5613
+ → item_1
5614
+
5615
+ // Apply wipe reveal
5616
+ pinepaper_apply_animated_mask
5617
+ itemId: "item_1"
5618
+ preset: "wipeLeft"
5619
+ options:
5620
+ duration: 0.6
5621
+ easing: "easeOut"
5622
+ \`\`\`
5623
+
5624
+ ## Method 2: Staggered Word Reveal
5625
+
5626
+ \`\`\`
5627
+ // Word 1
5628
+ pinepaper_create_item itemType: "text" position: {x: 200, y: 300}
5629
+ properties: {content: "Create", fontSize: 48, color: "#3b82f6"}
5630
+ → item_1
5631
+
5632
+ // Word 2
5633
+ pinepaper_create_item itemType: "text" position: {x: 370, y: 300}
5634
+ properties: {content: "Beautiful", fontSize: 48, color: "#8b5cf6"}
5635
+ → item_2
5636
+
5637
+ // Word 3
5638
+ pinepaper_create_item itemType: "text" position: {x: 580, y: 300}
5639
+ properties: {content: "Graphics", fontSize: 48, color: "#ec4899"}
5640
+ → item_3
5641
+
5642
+ // Staggered reveals
5643
+ pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeUp"
5644
+ options: {startTime: 0, duration: 0.4, easing: "easeOut"}
5645
+
5646
+ pinepaper_apply_animated_mask itemId: "item_2" preset: "wipeUp"
5647
+ options: {startTime: 0.15, duration: 0.4, easing: "easeOut"}
5648
+
5649
+ pinepaper_apply_animated_mask itemId: "item_3" preset: "wipeUp"
5650
+ options: {startTime: 0.3, duration: 0.4, easing: "easeOut"}
5651
+ \`\`\`
5652
+
5653
+ ## Method 3: Iris Reveal for Images
5654
+
5655
+ \`\`\`
5656
+ // Create a shape or import image
5657
+ pinepaper_create_item itemType: "circle" position: {x: 400, y: 300}
5658
+ properties: {radius: 100, color: "#3b82f6"}
5659
+ → item_1
5660
+
5661
+ // Iris reveal from center
5662
+ pinepaper_apply_animated_mask
5663
+ itemId: "item_1"
5664
+ preset: "iris"
5665
+ options:
5666
+ duration: 0.8
5667
+ easing: "easeOut"
5668
+ \`\`\`
5669
+
5670
+ ## Method 4: Cinematic Letterbox
5671
+
5672
+ \`\`\`
5673
+ // Create main content
5674
+ pinepaper_create_item itemType: "rectangle" position: {x: 400, y: 300}
5675
+ properties: {width: 600, height: 300, color: "#1e40af"}
5676
+ → item_1
5677
+
5678
+ // Cinematic reveal (letterbox bars animate away)
5679
+ pinepaper_apply_animated_mask
5680
+ itemId: "item_1"
5681
+ preset: "cinematic"
5682
+ options:
5683
+ duration: 1.2
5684
+ easing: "easeInOut"
5685
+ \`\`\`
5686
+
5687
+ ## Available Presets
5688
+
5689
+ | Preset | Effect | Best For |
5690
+ |--------|--------|----------|
5691
+ | \`wipeLeft\` | Left to right | Text, titles |
5692
+ | \`wipeRight\` | Right to left | Text |
5693
+ | \`wipeUp\` | Bottom to top | Credits, lists |
5694
+ | \`wipeDown\` | Top to bottom | Headers |
5695
+ | \`iris\` | Circle from center | Images, focus |
5696
+ | \`irisOut\` | Circle shrinks | Transitions out |
5697
+ | \`star\` | Star shape reveal | Fun, playful |
5698
+ | \`heart\` | Heart shape reveal | Love themes |
5699
+ | \`curtainHorizontal\` | Opens from center | Stage, dramatic |
5700
+ | \`curtainVertical\` | Opens vertically | Reveals |
5701
+ | \`cinematic\` | Letterbox effect | Film style |
5702
+ | \`diagonalWipe\` | Angled wipe | Dynamic |
5703
+
5704
+ ## Combining with Other Animations
5705
+
5706
+ \`\`\`
5707
+ // Create text
5708
+ pinepaper_create_item itemType: "text" position: {x: 400, y: 300}
5709
+ properties: {content: "Animated!", fontSize: 48}
5710
+ → item_1
5711
+
5712
+ // Apply mask reveal
5713
+ pinepaper_apply_animated_mask itemId: "item_1" preset: "wipeLeft"
5714
+ options: {duration: 0.5}
5715
+
5716
+ // Add pulse animation after reveal
5717
+ pinepaper_animate_item itemId: "item_1" animationType: "pulse" speed: 0.5
5718
+ \`\`\`
5719
+
5720
+ ## Key Tools
5721
+
5722
+ | Tool | Purpose |
5723
+ |------|---------|
5724
+ | \`pinepaper_apply_animated_mask\` | Apply reveal preset |
5725
+ | \`pinepaper_get_mask_animations\` | List all presets |
5726
+ | \`pinepaper_remove_mask\` | Remove mask effect |
5727
+ `,
5728
+ };
5729
+ // =============================================================================
5730
+ // SERVER CREATION
5731
+ // =============================================================================
5732
+ export async function createServer(options = {}) {
5733
+ // Initialize i18n with specified locale
5734
+ const locale = options.locale || detectLocaleFromEnvironment();
5735
+ const verbosity = options.verbosity || detectVerbosityFromEnvironment();
5736
+ const i18n = await initI18n(locale);
5737
+ const tools = getToolsForVerbosity(verbosity);
5738
+ const server = new Server(SERVER_INFO, {
5739
+ capabilities: {
5740
+ tools: {},
5741
+ resources: {},
5742
+ prompts: {},
5743
+ },
5744
+ });
5745
+ // ---------------------------------------------------------------------------
3201
5746
  // TOOL HANDLERS
3202
5747
  // ---------------------------------------------------------------------------
3203
- // List available tools (with optional localization)
5748
+ // List available tools (with optional localization and verbosity)
3204
5749
  server.setRequestHandler(ListToolsRequestSchema, async () => {
3205
5750
  // Tool descriptions are kept in English for AI understanding
3206
- // but can be localized if needed for UI display
5751
+ // Compact mode trims the 13 largest descriptions to save ~5K tokens
3207
5752
  return {
3208
- tools: PINEPAPER_TOOLS,
5753
+ tools,
3209
5754
  };
3210
5755
  });
3211
5756
  // Handle tool calls with i18n support for errors and success messages
@@ -3247,6 +5792,16 @@ export async function createServer(options = {}) {
3247
5792
  ],
3248
5793
  };
3249
5794
  });
5795
+ // ---------------------------------------------------------------------------
5796
+ // PROMPT HANDLERS
5797
+ // ---------------------------------------------------------------------------
5798
+ server.setRequestHandler(ListPromptsRequestSchema, async () => {
5799
+ return { prompts: PROMPTS };
5800
+ });
5801
+ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
5802
+ const { name, arguments: args } = request.params;
5803
+ return getPromptMessages(name, args);
5804
+ });
3250
5805
  return server;
3251
5806
  }
3252
5807
  // =============================================================================
@@ -3277,6 +5832,13 @@ function detectLocaleFromEnvironment() {
3277
5832
  }
3278
5833
  return DEFAULT_LOCALE;
3279
5834
  }
5835
+ /**
5836
+ * Detect tool description verbosity from environment.
5837
+ * Set PINEPAPER_TOOL_VERBOSITY=compact to use trimmed descriptions (~5K tokens saved).
5838
+ */
5839
+ function detectVerbosityFromEnvironment() {
5840
+ return process.env.PINEPAPER_TOOL_VERBOSITY === 'compact' ? 'compact' : 'verbose';
5841
+ }
3280
5842
  /**
3281
5843
  * Check if a string is a valid supported locale
3282
5844
  */
@@ -3331,19 +5893,27 @@ function isValidLocale(locale) {
3331
5893
  // =============================================================================
3332
5894
  async function main() {
3333
5895
  const locale = detectLocaleFromEnvironment();
3334
- const server = await createServer({ locale });
5896
+ const verbosity = detectVerbosityFromEnvironment();
5897
+ const server = await createServer({ locale, verbosity });
3335
5898
  const transport = new StdioServerTransport();
3336
5899
  console.error('PinePaper MCP Server starting...');
3337
5900
  console.error(`Version: ${SERVER_INFO.version}`);
3338
5901
  console.error(`Locale: ${locale}`);
5902
+ console.error(`Verbosity: ${verbosity}`);
3339
5903
  console.error(`Tools: ${PINEPAPER_TOOLS.length}`);
3340
5904
  console.error(`Resources: ${RESOURCES.length}`);
3341
5905
  await server.connect(transport);
3342
5906
  console.error('PinePaper MCP Server running on stdio');
3343
5907
  }
3344
- // Run if executed directly
3345
- main().catch((error) => {
3346
- console.error('Fatal error:', error);
3347
- process.exit(1);
3348
- });
5908
+ // Run if executed directly (not when imported by cli.ts or other modules)
5909
+ // Check: Node uses process.argv[1], Bun supports import.meta.main
5910
+ const isDirectExecution = typeof import.meta.main === 'boolean'
5911
+ ? import.meta.main
5912
+ : process.argv[1]?.replace(/\\/g, '/').endsWith('index.js');
5913
+ if (isDirectExecution) {
5914
+ main().catch((error) => {
5915
+ console.error('Fatal error:', error);
5916
+ process.exit(1);
5917
+ });
5918
+ }
3349
5919
  //# sourceMappingURL=index.js.map