pmx-canvas 0.1.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 (226) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/LICENSE +21 -0
  3. package/Readme.md +865 -0
  4. package/dist/canvas/global.css +3173 -0
  5. package/dist/canvas/index.js +183 -0
  6. package/dist/json-render/index.css +2 -0
  7. package/dist/json-render/index.js +389 -0
  8. package/dist/types/cli/agent.d.ts +13 -0
  9. package/dist/types/cli/index.d.ts +2 -0
  10. package/dist/types/cli/watch.d.ts +5 -0
  11. package/dist/types/client/App.d.ts +1 -0
  12. package/dist/types/client/canvas/AttentionHistory.d.ts +1 -0
  13. package/dist/types/client/canvas/AttentionToast.d.ts +1 -0
  14. package/dist/types/client/canvas/CanvasNode.d.ts +8 -0
  15. package/dist/types/client/canvas/CanvasViewport.d.ts +8 -0
  16. package/dist/types/client/canvas/CommandPalette.d.ts +4 -0
  17. package/dist/types/client/canvas/ContextMenu.d.ts +24 -0
  18. package/dist/types/client/canvas/ContextPinBar.d.ts +1 -0
  19. package/dist/types/client/canvas/ContextPinHud.d.ts +1 -0
  20. package/dist/types/client/canvas/DockedNode.d.ts +4 -0
  21. package/dist/types/client/canvas/EdgeLayer.d.ts +8 -0
  22. package/dist/types/client/canvas/ExpandedNodeOverlay.d.ts +1 -0
  23. package/dist/types/client/canvas/FocusFieldLayer.d.ts +1 -0
  24. package/dist/types/client/canvas/Minimap.d.ts +23 -0
  25. package/dist/types/client/canvas/SelectionBar.d.ts +1 -0
  26. package/dist/types/client/canvas/ShortcutOverlay.d.ts +3 -0
  27. package/dist/types/client/canvas/SnapshotPanel.d.ts +7 -0
  28. package/dist/types/client/canvas/snap-guides.d.ts +23 -0
  29. package/dist/types/client/canvas/use-node-drag.d.ts +15 -0
  30. package/dist/types/client/canvas/use-node-resize.d.ts +15 -0
  31. package/dist/types/client/canvas/use-pan-zoom.d.ts +16 -0
  32. package/dist/types/client/ext-app/bridge.d.ts +161 -0
  33. package/dist/types/client/icons.d.ts +70 -0
  34. package/dist/types/client/index.d.ts +1 -0
  35. package/dist/types/client/nodes/ContextNode.d.ts +34 -0
  36. package/dist/types/client/nodes/ExtAppFrame.d.ts +18 -0
  37. package/dist/types/client/nodes/FileNode.d.ts +5 -0
  38. package/dist/types/client/nodes/GroupNode.d.ts +6 -0
  39. package/dist/types/client/nodes/ImageNode.d.ts +10 -0
  40. package/dist/types/client/nodes/InlineFormatBar.d.ts +7 -0
  41. package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +14 -0
  42. package/dist/types/client/nodes/LedgerNode.d.ts +4 -0
  43. package/dist/types/client/nodes/MarkdownNode.d.ts +6 -0
  44. package/dist/types/client/nodes/McpAppNode.d.ts +4 -0
  45. package/dist/types/client/nodes/MdFormatBar.d.ts +8 -0
  46. package/dist/types/client/nodes/PromptNode.d.ts +5 -0
  47. package/dist/types/client/nodes/ResponseNode.d.ts +5 -0
  48. package/dist/types/client/nodes/StatusNode.d.ts +4 -0
  49. package/dist/types/client/nodes/StatusSummary.d.ts +4 -0
  50. package/dist/types/client/nodes/TraceNode.d.ts +4 -0
  51. package/dist/types/client/nodes/WebpageNode.d.ts +5 -0
  52. package/dist/types/client/nodes/image-warnings.d.ts +6 -0
  53. package/dist/types/client/nodes/inline-editor-commands.d.ts +11 -0
  54. package/dist/types/client/nodes/md-format.d.ts +25 -0
  55. package/dist/types/client/state/attention-bridge.d.ts +3 -0
  56. package/dist/types/client/state/attention-store.d.ts +25 -0
  57. package/dist/types/client/state/canvas-store.d.ts +74 -0
  58. package/dist/types/client/state/intent-bridge.d.ts +158 -0
  59. package/dist/types/client/state/sse-bridge.d.ts +5 -0
  60. package/dist/types/client/theme/tokens.d.ts +27 -0
  61. package/dist/types/client/types.d.ts +40 -0
  62. package/dist/types/client/utils/ext-app-tool-result.d.ts +1 -0
  63. package/dist/types/client/utils/placement.d.ts +1 -0
  64. package/dist/types/client/utils/platform.d.ts +2 -0
  65. package/dist/types/json-render/catalog.d.ts +815 -0
  66. package/dist/types/json-render/charts/components.d.ts +54 -0
  67. package/dist/types/json-render/charts/definitions.d.ts +103 -0
  68. package/dist/types/json-render/charts/extra-components.d.ts +58 -0
  69. package/dist/types/json-render/charts/extra-definitions.d.ts +181 -0
  70. package/dist/types/json-render/renderer/index.d.ts +16 -0
  71. package/dist/types/json-render/schema.d.ts +46 -0
  72. package/dist/types/json-render/server.d.ts +55 -0
  73. package/dist/types/mcp/server.d.ts +22 -0
  74. package/dist/types/server/agent-context.d.ts +21 -0
  75. package/dist/types/server/artifact-paths.d.ts +3 -0
  76. package/dist/types/server/canvas-operations.d.ts +154 -0
  77. package/dist/types/server/canvas-provenance.d.ts +13 -0
  78. package/dist/types/server/canvas-schema.d.ts +49 -0
  79. package/dist/types/server/canvas-serialization.d.ts +25 -0
  80. package/dist/types/server/canvas-state.d.ts +174 -0
  81. package/dist/types/server/canvas-validation.d.ts +33 -0
  82. package/dist/types/server/chart-template.d.ts +29 -0
  83. package/dist/types/server/code-graph.d.ts +67 -0
  84. package/dist/types/server/context-cards.d.ts +24 -0
  85. package/dist/types/server/diagram-presets.d.ts +28 -0
  86. package/dist/types/server/ext-app-call-registry.d.ts +16 -0
  87. package/dist/types/server/ext-app-tool-result.d.ts +1 -0
  88. package/dist/types/server/file-watcher.d.ts +16 -0
  89. package/dist/types/server/index.d.ts +243 -0
  90. package/dist/types/server/mcp-app-candidate.d.ts +25 -0
  91. package/dist/types/server/mcp-app-host.d.ts +65 -0
  92. package/dist/types/server/mcp-app-runtime.d.ts +47 -0
  93. package/dist/types/server/mutation-history.d.ts +105 -0
  94. package/dist/types/server/placement.d.ts +37 -0
  95. package/dist/types/server/server.d.ts +103 -0
  96. package/dist/types/server/spatial-analysis.d.ts +87 -0
  97. package/dist/types/server/trace-manager.d.ts +48 -0
  98. package/dist/types/server/web-artifacts.d.ts +50 -0
  99. package/dist/types/server/webpage-node.d.ts +25 -0
  100. package/dist/types/shared/auto-arrange.d.ts +29 -0
  101. package/dist/types/shared/ext-app-tool-result.d.ts +9 -0
  102. package/dist/types/shared/placement.d.ts +26 -0
  103. package/dist/types/shared/semantic-attention.d.ts +97 -0
  104. package/package.json +109 -0
  105. package/skills/data-analysis/SKILL.md +324 -0
  106. package/skills/doc-coauthoring/SKILL.md +375 -0
  107. package/skills/frontend-design/SKILL.md +45 -0
  108. package/skills/json-render-codegen/SKILL.md +112 -0
  109. package/skills/json-render-core/SKILL.md +265 -0
  110. package/skills/json-render-ink/SKILL.md +273 -0
  111. package/skills/json-render-mcp/SKILL.md +132 -0
  112. package/skills/json-render-react/SKILL.md +264 -0
  113. package/skills/json-render-shadcn/SKILL.md +159 -0
  114. package/skills/playwright-cli/SKILL.md +67 -0
  115. package/skills/pmx-canvas/SKILL.md +668 -0
  116. package/skills/pmx-canvas/evals/evals.json +186 -0
  117. package/skills/pmx-canvas-testing/SKILL.md +78 -0
  118. package/skills/published-consumer-e2e/SKILL.md +43 -0
  119. package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +241 -0
  120. package/skills/web-artifacts-builder/SKILL.md +80 -0
  121. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +167 -0
  122. package/skills/web-artifacts-builder/scripts/init-artifact.sh +425 -0
  123. package/skills/web-artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  124. package/skills/web-design-guidelines/SKILL.md +39 -0
  125. package/src/cli/agent.ts +2144 -0
  126. package/src/cli/index.ts +622 -0
  127. package/src/cli/watch.ts +88 -0
  128. package/src/client/App.tsx +507 -0
  129. package/src/client/canvas/AttentionHistory.tsx +81 -0
  130. package/src/client/canvas/AttentionToast.tsx +19 -0
  131. package/src/client/canvas/CanvasNode.tsx +363 -0
  132. package/src/client/canvas/CanvasViewport.tsx +590 -0
  133. package/src/client/canvas/CommandPalette.tsx +302 -0
  134. package/src/client/canvas/ContextMenu.tsx +601 -0
  135. package/src/client/canvas/ContextPinBar.tsx +25 -0
  136. package/src/client/canvas/ContextPinHud.tsx +22 -0
  137. package/src/client/canvas/DockedNode.tsx +66 -0
  138. package/src/client/canvas/EdgeLayer.tsx +280 -0
  139. package/src/client/canvas/ExpandedNodeOverlay.tsx +260 -0
  140. package/src/client/canvas/FocusFieldLayer.tsx +107 -0
  141. package/src/client/canvas/Minimap.tsx +301 -0
  142. package/src/client/canvas/SelectionBar.tsx +69 -0
  143. package/src/client/canvas/ShortcutOverlay.tsx +69 -0
  144. package/src/client/canvas/SnapshotPanel.tsx +236 -0
  145. package/src/client/canvas/snap-guides.ts +170 -0
  146. package/src/client/canvas/use-node-drag.ts +51 -0
  147. package/src/client/canvas/use-node-resize.ts +59 -0
  148. package/src/client/canvas/use-pan-zoom.ts +191 -0
  149. package/src/client/ext-app/bridge.ts +542 -0
  150. package/src/client/icons.tsx +424 -0
  151. package/src/client/index.tsx +7 -0
  152. package/src/client/nodes/ContextNode.tsx +412 -0
  153. package/src/client/nodes/ExtAppFrame.tsx +509 -0
  154. package/src/client/nodes/FileNode.tsx +256 -0
  155. package/src/client/nodes/GroupNode.tsx +39 -0
  156. package/src/client/nodes/ImageNode.tsx +160 -0
  157. package/src/client/nodes/InlineFormatBar.tsx +169 -0
  158. package/src/client/nodes/InlineMarkdownEditor.tsx +123 -0
  159. package/src/client/nodes/LedgerNode.tsx +37 -0
  160. package/src/client/nodes/MarkdownNode.tsx +359 -0
  161. package/src/client/nodes/McpAppNode.tsx +85 -0
  162. package/src/client/nodes/MdFormatBar.tsx +109 -0
  163. package/src/client/nodes/PromptNode.tsx +597 -0
  164. package/src/client/nodes/ResponseNode.tsx +153 -0
  165. package/src/client/nodes/StatusNode.tsx +84 -0
  166. package/src/client/nodes/StatusSummary.tsx +38 -0
  167. package/src/client/nodes/TraceNode.tsx +120 -0
  168. package/src/client/nodes/WebpageNode.tsx +288 -0
  169. package/src/client/nodes/image-warnings.ts +95 -0
  170. package/src/client/nodes/inline-editor-commands.ts +37 -0
  171. package/src/client/nodes/md-format.ts +206 -0
  172. package/src/client/state/attention-bridge.ts +328 -0
  173. package/src/client/state/attention-store.ts +73 -0
  174. package/src/client/state/canvas-store.ts +631 -0
  175. package/src/client/state/intent-bridge.ts +315 -0
  176. package/src/client/state/sse-bridge.ts +965 -0
  177. package/src/client/theme/global.css +3173 -0
  178. package/src/client/theme/tokens.ts +72 -0
  179. package/src/client/types-shims.d.ts +5 -0
  180. package/src/client/types.ts +81 -0
  181. package/src/client/utils/ext-app-tool-result.ts +4 -0
  182. package/src/client/utils/placement.ts +4 -0
  183. package/src/client/utils/platform.ts +2 -0
  184. package/src/json-render/catalog.ts +256 -0
  185. package/src/json-render/charts/components.tsx +198 -0
  186. package/src/json-render/charts/definitions.ts +81 -0
  187. package/src/json-render/charts/extra-components.tsx +267 -0
  188. package/src/json-render/charts/extra-definitions.ts +145 -0
  189. package/src/json-render/renderer/index.css +174 -0
  190. package/src/json-render/renderer/index.tsx +86 -0
  191. package/src/json-render/schema.ts +62 -0
  192. package/src/json-render/server.ts +597 -0
  193. package/src/mcp/server.ts +1377 -0
  194. package/src/server/agent-context.ts +242 -0
  195. package/src/server/artifact-paths.ts +17 -0
  196. package/src/server/canvas-operations.ts +1279 -0
  197. package/src/server/canvas-provenance.ts +243 -0
  198. package/src/server/canvas-schema.ts +432 -0
  199. package/src/server/canvas-serialization.ts +95 -0
  200. package/src/server/canvas-state.ts +1134 -0
  201. package/src/server/canvas-validation.ts +114 -0
  202. package/src/server/chart-template.ts +449 -0
  203. package/src/server/code-graph.ts +370 -0
  204. package/src/server/context-cards.ts +31 -0
  205. package/src/server/diagram-presets.ts +71 -0
  206. package/src/server/ext-app-call-registry.ts +77 -0
  207. package/src/server/ext-app-tool-result.ts +4 -0
  208. package/src/server/file-watcher.ts +121 -0
  209. package/src/server/index.ts +647 -0
  210. package/src/server/mcp-app-candidate.ts +174 -0
  211. package/src/server/mcp-app-host.ts +814 -0
  212. package/src/server/mcp-app-runtime.ts +459 -0
  213. package/src/server/mutation-history.ts +350 -0
  214. package/src/server/placement.ts +125 -0
  215. package/src/server/server.ts +3846 -0
  216. package/src/server/spatial-analysis.ts +356 -0
  217. package/src/server/trace-manager.ts +333 -0
  218. package/src/server/web-artifacts/scripts/bundle-artifact.sh +167 -0
  219. package/src/server/web-artifacts/scripts/init-artifact.sh +426 -0
  220. package/src/server/web-artifacts/scripts/shadcn-components.tar.gz +0 -0
  221. package/src/server/web-artifacts.ts +442 -0
  222. package/src/server/webpage-node.ts +328 -0
  223. package/src/shared/auto-arrange.ts +439 -0
  224. package/src/shared/ext-app-tool-result.ts +76 -0
  225. package/src/shared/placement.ts +81 -0
  226. package/src/shared/semantic-attention.ts +598 -0
@@ -0,0 +1,668 @@
1
+ ---
2
+ name: pmx-canvas
3
+ description: >
4
+ Spatial canvas workbench for visual thinking — nodes, edges, groups on an infinite 2D canvas
5
+ with pan/zoom, minimap, and real-time sync. Use this skill whenever you need to lay out
6
+ information spatially: investigation boards, architecture diagrams, dependency maps, task plans,
7
+ status dashboards, file relationship views, or any scenario where a flat list or text wall
8
+ isn't enough. Also use when the user mentions "canvas", "board", "diagram", "spatial layout",
9
+ "visual map", "node graph", or wants to see how things connect. The canvas is your extended
10
+ working memory — pin nodes to curate context, read spatial arrangement to understand intent.
11
+ ---
12
+
13
+ # PMX Canvas — Agent Skill
14
+
15
+ PMX Canvas is a spatial canvas workbench you control through MCP tools or HTTP API. It renders an
16
+ infinite 2D canvas in the browser with nodes, edges, groups, pan/zoom, and a minimap. State lives
17
+ on the server and survives browser refresh.
18
+
19
+ The canvas is your extended working memory. Humans pin nodes to curate context; you read that
20
+ curation through MCP resources. Spatial arrangement is communication — proximity means
21
+ relatedness, clusters imply grouping, reading order (top-left to bottom-right) implies sequence.
22
+
23
+ ## When to Use
24
+
25
+ - **Investigation boards** — lay out files, logs, stack traces, and findings spatially while debugging
26
+ - **Architecture diagrams** — show system components and their relationships
27
+ - **Plans & task tracking** — create task nodes with dependencies and color-coded status
28
+ - **Status dashboards** — display build results, test output, deployment state
29
+ - **Context maps** — show how code, configs, and data flow connect
30
+ - **Code dependency graphs** — visualize file imports and module relationships
31
+ - **Comparison views** — place options side by side for the human to evaluate
32
+ - **Any time spatial layout helps** — when a flat list or text wall is not enough
33
+
34
+ ## Starting the Canvas
35
+
36
+ The canvas auto-starts on first MCP tool call when running in MCP mode (`pmx-canvas --mcp`).
37
+ For manual start:
38
+
39
+ ```bash
40
+ pmx-canvas # Start and open browser (port 4313)
41
+ pmx-canvas --no-open # Start without opening browser (for agents)
42
+ pmx-canvas --port=8080 # Custom port
43
+ pmx-canvas --demo # Start with sample content
44
+ pmx-canvas --theme=light # Light theme
45
+ ```
46
+
47
+ Start the canvas once per session, then reuse it. Use `--no-open` when running as an agent — the
48
+ human can open the browser URL themselves.
49
+
50
+ ## Browser Workflows
51
+
52
+ The browser is not just a passive view. Human interactions on the canvas persist back to the
53
+ server and become part of the authoritative canvas state.
54
+
55
+ - Double-click empty canvas — create a markdown note at that position
56
+ - Shift+drag on empty canvas — lasso-select multiple nodes
57
+ - Selection bar actions — when nodes are selected, the browser exposes `Pin as context`,
58
+ `Group`, `Connect`, and `Clear`
59
+ - Right-click a node — open the node context menu for focus, collapse, pinning, connecting,
60
+ refresh/open actions, and other type-specific operations
61
+ - Right-click a group node — recolor the group using preset swatches or a custom color picker,
62
+ and ungroup its children
63
+ - Drag-and-drop files or URLs — add file, image, markdown, or webpage nodes directly
64
+ - Paste URLs — create webpage nodes from the clipboard
65
+
66
+ Use browser interactions when the human is actively curating spatial layout. Use MCP or the CLI
67
+ when you need deterministic scripted changes or you are acting without a visible browser.
68
+
69
+ ## Agent CLI
70
+
71
+ PMX Canvas also ships an agent-native CLI that talks to the running HTTP server and returns JSON.
72
+ Use it when MCP is not available but you still want structured, scriptable canvas operations.
73
+
74
+ ```bash
75
+ pmx-canvas --help # Top-level help
76
+ pmx-canvas serve --daemon --no-open # Detached daemon with health output
77
+ pmx-canvas serve status # Daemon health + pid status
78
+ pmx-canvas serve stop # Stop the daemon for this port/pid file
79
+ pmx-canvas layout # Full canvas state
80
+ pmx-canvas status # Quick summary
81
+ pmx-canvas node add --type markdown --title "Plan"
82
+ pmx-canvas node add --type webpage --url https://example.com/docs
83
+ pmx-canvas node add --type web-artifact --title "Dashboard" --app-file ./App.tsx
84
+ pmx-canvas node add --help --type webpage --json
85
+ pmx-canvas node schema --type json-render --component Table --summary
86
+ pmx-canvas node list --type file --ids
87
+ pmx-canvas edge add --from node-a --to node-b --type depends-on
88
+ pmx-canvas search "auth"
89
+ pmx-canvas open
90
+ pmx-canvas arrange --layout flow
91
+ pmx-canvas validate spec --type json-render --spec-file ./dashboard.json --summary
92
+ pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --include-logs
93
+ pmx-canvas pin --list
94
+ pmx-canvas snapshot save --name "before-refactor"
95
+ pmx-canvas code-graph
96
+ pmx-canvas spatial
97
+ ```
98
+
99
+ ### CLI command groups
100
+
101
+ - `node add|list|get|update|remove` — manage nodes
102
+ - `node schema` — inspect running-server create schemas and canonical examples, with `--summary`, `--field`, and `--component` filters
103
+ - `edge add|list|remove` — manage edges
104
+ - Search-based edge selectors must be specific enough to resolve exactly one node. Queries like
105
+ `"DVT O3"` can be ambiguous; prefer the full visible title such as `"DVT O3 — GitOps"`.
106
+ - `search`, `layout`, `status`, `arrange`, `focus` — inspect and navigate the canvas
107
+ - `open` — open the current workbench in the browser
108
+ - `pin --list|--clear|<ids...>` — manage context pins
109
+ - `undo`, `redo`, `history` — time travel
110
+ - `snapshot save|list|restore|delete` — manage snapshots
111
+ - `group create|add|remove` — manage groups
112
+ - `clear --yes` — destructive clear with explicit confirmation
113
+ - `validate spec` — validate json-render specs and graph payloads without creating nodes
114
+ - `serve status|stop` — inspect and stop daemonized servers started with `serve --daemon`
115
+ - `code-graph`, `spatial` — analysis commands
116
+
117
+ Current caveat:
118
+ - `mcp-app` grouping is not fully uniform yet. Web artifact app nodes have grouped reliably, but
119
+ Excalidraw app nodes have shown inconsistent `group add` behavior and weaker rediscoverability
120
+ through search later in the session. When you plan to curate an app-heavy comparison area,
121
+ capture node IDs immediately after creation and verify membership with `node get --summary`,
122
+ `layout --summary`, or the browser selection state instead of relying on search alone.
123
+ - Some `mcp-app` creation flows are still awkward to address immediately after creation. If a
124
+ diagram/app flow gives you a session-oriented result first, resolve the final canvas node from
125
+ live layout or `node list --type mcp-app` before you try to group it, wire edges to it, or
126
+ revisit it later.
127
+
128
+ The CLI targets `http://localhost:4313` by default. Override with `PMX_CANVAS_URL` or
129
+ `PMX_CANVAS_PORT` when the canvas is running elsewhere.
130
+
131
+ ## Core Concepts
132
+
133
+ ### Node Types
134
+
135
+ | Type | Purpose | When to use |
136
+ |------|---------|-------------|
137
+ | `markdown` | Rich formatted content | Explanations, documentation, notes, findings |
138
+ | `status` | Compact color-coded indicator | Progress tracking, build/test results, task state |
139
+ | `file` | Live file viewer (auto-watches) | Show source code with live updates on file change |
140
+ | `image` | Image display | Screenshots, diagrams, charts |
141
+ | `context` | Context card | Key context the human should see |
142
+ | `ledger` | Log/ledger viewer | Structured log data, audit trails |
143
+ | `trace` | Trace/timeline viewer | Execution traces, timelines |
144
+ | `mcp-app` | Hosted app/embed frame | Embedded MCP apps or external app content |
145
+ | `json-render` | Native structured UI panel | Dashboards, forms, tables, interactive layouts from json-render specs |
146
+ | `graph` | Native chart panel | Line, bar, pie, area, scatter, radar, stacked-bar, and composed charts rendered inside the canvas |
147
+ | `group` | Spatial container/frame | Visually group related nodes together |
148
+ | `prompt` | Prompt thread root | Canvas-native prompt entry points for agent conversations |
149
+ | `response` | Prompt reply / streamed answer | Agent responses linked to prompt threads |
150
+
151
+ ### Edge Types
152
+
153
+ | Type | Purpose | Example label |
154
+ |------|---------|---------------|
155
+ | `flow` | Sequential/directional | "then", "calls", "triggers" |
156
+ | `depends-on` | Dependency | "requires", "blocks" |
157
+ | `relation` | General relationship | "related to", "similar to" |
158
+ | `references` | Cross-reference | "see also", "documented in" |
159
+
160
+ Edges support `style` (solid/dashed/dotted) and `animated` flag. Always use descriptive labels.
161
+
162
+ **Edge direction convention:** `from` is the source/dependent, `to` is the target/dependency.
163
+ So `from: A, to: B, type: "depends-on"` means "A depends on B." For `flow` edges, the arrow
164
+ points from `from` to `to`, indicating sequence or data flow direction.
165
+
166
+ **Style conventions:** Use `solid` for active/satisfied relationships, `dashed` for blocked or
167
+ pending dependencies, and `dotted` for weak/optional relationships. Use `animated: true` to
168
+ draw visual attention to critical paths.
169
+
170
+ ### Colors (Semantic)
171
+
172
+ Use color consistently to convey meaning:
173
+ - **Green** (`#22c55e`) — success, done, healthy
174
+ - **Yellow** (`#eab308`) — in progress, warning, attention needed
175
+ - **Red** (`#ef4444`) — error, blocked, failing
176
+ - **Blue** (`#3b82f6`) — informational, neutral highlight
177
+ - **Gray** (`#6b7280`) — queued, pending, inactive, not yet started
178
+ - **Purple** (`#a855f7`) — special, notable, review needed
179
+
180
+ ## MCP Tools Reference
181
+
182
+ ### Node Operations
183
+
184
+ **`canvas_add_node`** — Add a node to the canvas
185
+ - `type` (required): node type (see table above)
186
+ - `title`: short, scannable title
187
+ - `content`: for most types, this is markdown text. For `file` type, pass the **file path**
188
+ (e.g., `"src/auth/login.ts"`) — the server auto-loads the file content and watches for changes.
189
+ For `image` type, pass a file path, URL, or data URI.
190
+ - `x`, `y`: position (auto-placed if omitted — prefer omitting for auto-layout)
191
+ - `width`, `height`: dimensions (sensible defaults provided)
192
+ - `color`: semantic color
193
+ - `metadata`: arbitrary JSON
194
+ - Returns: `{ id: "<node-id>" }` — capture this ID for edges and groups
195
+
196
+ **`canvas_update_node`** — Update an existing node
197
+ - `id` (required): node to update
198
+ - Any of: `title`, `content`, `color`, `x`, `y`, `width`, `height`, `collapsed`, `metadata`
199
+ - Use to update status nodes as work progresses
200
+
201
+ **`canvas_remove_node`** — Remove a node and all its connected edges
202
+ - `id` (required): node to remove
203
+ - Clean up nodes that are no longer relevant
204
+
205
+ **`canvas_get_node`** — Get a single node's full data
206
+ - `id` (required): node to retrieve
207
+
208
+ **`canvas_add_json_render_node`** — Add a native json-render node
209
+ - Required: `title`, `spec`
210
+ - The `spec` must be a complete json-render object with `root`, `elements`, and optional `state`
211
+ - Use this when you want a structured UI panel rendered directly inside PMX Canvas
212
+
213
+ **`canvas_add_graph_node`** — Add a native graph/chart node
214
+ - Required: `graphType`, `data`
215
+ - Supports `line`, `bar`, `pie`, `area`, `scatter`, `radar`, `stacked-bar`, and `composed`
216
+ graph types (aliases accepted)
217
+ - Use `xKey`/`yKey` for line, bar, area, and scatter graphs
218
+ - Use `zKey` for scatter bubble size
219
+ - Use `nameKey`/`valueKey` for pie graphs
220
+ - Use `axisKey` plus `metrics` for radar graphs
221
+ - Use `series` for stacked-bar graphs
222
+ - Use `barKey`/`lineKey` plus optional `barColor`/`lineColor` for composed graphs
223
+ - Uses the native json-render chart catalog under the hood
224
+
225
+ **`canvas_describe_schema`** — Inspect the running server's create schemas and canonical examples
226
+ - Use this before generating structured payloads when you need the authoritative current shape
227
+
228
+ **`canvas_validate_spec`** — Validate a json-render spec or graph payload without creating a node
229
+ - Returns the normalized json-render spec the server would accept
230
+ - Use this when you want a dry run before creating a `json-render` or `graph` node
231
+
232
+ **Batch graph creation**
233
+ - Use `graph.add` inside `canvas_batch` / `pmx-canvas batch` when you need a graph node as part of
234
+ a larger one-shot build.
235
+ - It accepts the same shape as `canvas_add_graph_node`: `graphType`, `data`, optional `title`,
236
+ `xKey`, `yKey`, `zKey`, `nameKey`, `valueKey`, `axisKey`, `metrics`, `series`, `barKey`,
237
+ `lineKey`, `aggregate`, `color`, `barColor`, `lineColor`, `height`, `x`, `y`, `width`, and
238
+ `nodeHeight`.
239
+
240
+ ### Edge Operations
241
+
242
+ **`canvas_add_edge`** — Connect two nodes
243
+ - `from`, `to` (required): source and target node IDs
244
+ - `fromSearch`, `toSearch`: optional search-based selectors when you do not have IDs. Each search
245
+ query must resolve to exactly one node or the edge creation fails with an ambiguity error.
246
+ - `type`: edge type (default: `relation`)
247
+ - `label`: descriptive relationship label
248
+ - `style`: `solid`, `dashed`, or `dotted`
249
+ - `animated`: boolean for visual emphasis
250
+
251
+ **`canvas_remove_edge`** — Remove a connection
252
+ - `id` (required): edge to remove
253
+
254
+ ### Layout & Navigation
255
+
256
+ **`canvas_get_layout`** — Get full canvas state (all nodes, edges, viewport)
257
+ - Use to understand current canvas state before making changes
258
+
259
+ **`canvas_arrange`** — Auto-arrange all nodes
260
+ - `layout`: `grid` (default), `column`, or `flow`
261
+ - Use `grid` for dashboards and architecture overviews, `column` for vertical lists, `flow`
262
+ for horizontal sequences and dependency chains
263
+ - Call after adding multiple nodes
264
+ - For tiered/layered layouts (e.g., gateway → services → data stores), use `canvas_update_node`
265
+ with explicit `x`/`y` coordinates after auto-arrange to fine-tune the topology
266
+
267
+ **`canvas_focus_node`** — Pan viewport to center on a specific node
268
+ - `id` (required): node to focus
269
+ - Good for drawing the human's attention
270
+
271
+ ### Groups
272
+
273
+ **`canvas_create_group`** — Create a visual container
274
+ - `title`: group label
275
+ - `childIds`: array of node IDs to include
276
+ - `color`: group border/background color
277
+ - Auto-sizes to fit children
278
+
279
+ **`canvas_group_nodes`** — Add nodes to an existing group
280
+ - `groupId`, `childIds` (required)
281
+
282
+ **`canvas_ungroup`** — Release children from a group
283
+ - `groupId` (required): group to dissolve
284
+
285
+ ### Grouped Comparison Boards
286
+
287
+ Use groups as named comparison areas, not just visual boxes.
288
+
289
+ - Create the comparison frame first with `canvas_create_group` or `pmx-canvas group create`, then
290
+ add charts, artifacts, and diagrams into that area deliberately.
291
+ - Prefer graph nodes for fast capability demos and side-by-side comparisons. They are lightweight,
292
+ validate quickly, and are easier to regenerate.
293
+ - Prefer web artifacts when the board needs a richer narrative UI, custom interaction, or a more
294
+ polished presentation layer than a graph or json-render node can provide.
295
+ - Use Excalidraw for sketching and flow diagrams, but treat it as less reliable than web-artifact
296
+ app nodes for grouping and rediscovery until `mcp-app` grouping parity is fixed.
297
+ - Native node types are still the most agent-friendly. Graph nodes are the strongest comparison
298
+ primitive today, web artifacts are good but heavier, and Excalidraw / other `mcp-app` nodes are
299
+ useful but still the weakest operationally for create, rediscover, group, and reconnect flows.
300
+ - Leave larger spacing between major regions than you think you need. The spatial analyzer still
301
+ tends to read dense boards as one giant cluster unless groups and gaps are both clear.
302
+ - If you are expanding a board incrementally, verify each add-to-group step instead of assuming
303
+ the node joined the area. Comparison workflows depend on reliable “add this thing to the region
304
+ I’m already building.”
305
+
306
+ Current product caveats for grouped comparison boards:
307
+ - `mcp-app` grouping parity is inconsistent. Web artifacts have grouped cleanly; Excalidraw has
308
+ not always behaved the same way.
309
+ - Search/discoverability for external app nodes can degrade over time in-session, so node IDs are
310
+ safer than title-based rediscovery for follow-up grouping or focus operations.
311
+ - `mcp-app` nodes are less inspectable than native nodes. For graph nodes you can reason from
312
+ structured config, but app nodes often only tell you that an app exists unless you also inspect
313
+ nearby markdown, file, or graph context.
314
+ - Long-running web artifact builds can exceed a short command timeout. When using them in an
315
+ agent workflow, prefer progress-aware handling and avoid assuming a timeout means failure.
316
+
317
+ ### Search & Discovery
318
+
319
+ **`canvas_search`** — Find nodes by title or content keywords
320
+ - `query` (required): search text
321
+ - Returns matches with relevance ranking and content snippets
322
+ - Use instead of parsing full layout when looking for specific nodes
323
+
324
+ ### Context Pinning
325
+
326
+ **`canvas_pin_nodes`** — Manage pinned context
327
+ - `nodeIds` (required): array of node IDs
328
+ - `mode`: `set` (replace all pins), `add` (add to pins), `remove` (remove from pins)
329
+ - Pinned nodes are the primary human-to-agent communication channel
330
+ - When a human pins nodes in the browser, they're telling you "pay attention to these"
331
+ - Best default pin set for agent collaboration: one intent-setting markdown node plus 1-3 concrete
332
+ output nodes
333
+ - Graph, file, and markdown pins usually carry richer usable context than `mcp-app` pins
334
+ - Artifact and Excalidraw pins still matter as intent signals, but pair them with a markdown or
335
+ graph pin when you want the agent to understand what is inside the app, not just that it matters
336
+
337
+ ### History & Snapshots
338
+
339
+ **`canvas_undo`** — Undo the last canvas mutation
340
+ **`canvas_redo`** — Redo the last undone mutation
341
+ **`canvas_snapshot`** — Save a named snapshot to disk
342
+ - `name` (required): descriptive snapshot name (e.g., "before-refactor")
343
+ **`canvas_restore`** — Restore canvas from a saved snapshot
344
+ - `id`: snapshot to restore
345
+ **`canvas_diff`** — Compare current canvas against a saved snapshot
346
+ - Shows added, removed, and modified nodes/edges
347
+ - Useful for reviewing what changed during a work session
348
+
349
+ ### Canvas Management
350
+
351
+ **`canvas_clear`** — Remove all nodes and edges
352
+ - **Always call `canvas_snapshot` first** to save a backup before clearing
353
+ - This is irreversible without a prior snapshot
354
+
355
+ ### Diagrams (Excalidraw MCP app preset)
356
+
357
+ **`canvas_add_diagram`** — Draw a hand-drawn diagram on the canvas via the hosted
358
+ [Excalidraw MCP app](https://github.com/excalidraw/excalidraw-mcp)
359
+ - Required: `elements` — an array of Excalidraw elements (rectangles, ellipses, diamonds, arrows,
360
+ text). Can also be a JSON-array string.
361
+ - Optional: `title`, `x`, `y`, `width`, `height`
362
+ - The diagram opens inside an `mcp-app` node with fullscreen editing and draw-on animations
363
+ - Use this when the human needs a quick sketch, architecture diagram, or flowchart and a
364
+ geometric `graph` node would feel too rigid
365
+ - Prefer labeled shapes (`"label": { "text": "..." }` on rectangle/ellipse/diamond) over
366
+ separate text elements — fewer tokens and auto-centered
367
+ - Prefer the pastel fill palette in the Excalidraw `read_me` (light blue/green/orange/...) for
368
+ a consistent look across diagrams
369
+
370
+ ### External MCP apps (bring your own)
371
+
372
+ **`canvas_open_mcp_app`** — Open any external [MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps)
373
+ server's `ui://` resource as an iframe node on the canvas
374
+ - Required: `toolName`, `transport` (`http` URL or `stdio` command)
375
+ - Optional: `serverName`, `toolArguments`, `title`, `x`, `y`, `width`, `height`
376
+ - Use when no dedicated preset exists yet. The Excalidraw preset (`canvas_add_diagram`) is the
377
+ only one today
378
+
379
+ ### Web Artifacts
380
+
381
+ **`canvas_build_web_artifact`** — Build a single-file HTML artifact from React/Tailwind source
382
+ - Required: `title`, `appTsx`
383
+ - Optional: `indexCss`, `mainTsx`, `indexHtml`, extra `files`, `projectPath`, `outputPath`, `includeLogs`
384
+ - By default it opens the result on the canvas as an embedded app node
385
+ - By default it returns compact log summaries; set `includeLogs: true` when you need raw stdout/stderr
386
+ - Use this when the output should be a richer interactive UI than a simple markdown/file/image node
387
+ - Prefer the dedicated `web-artifacts-builder` skill when you need the full React + shadcn workflow
388
+ - Use the `playwright-cli` skill when you need to validate the built artifact in a live browser
389
+
390
+ ### Native Structured UI
391
+
392
+ Use native `json-render` and `graph` nodes when the output should stay fully inside PMX Canvas:
393
+
394
+ 1. Use `canvas_add_json_render_node` for dashboards, forms, summaries, and interactive UI panels
395
+ 2. Use `canvas_add_graph_node` for charts and trend visualizations
396
+ 3. Use the repo-local `json-render-*` skills when you need help authoring or refining the spec itself
397
+ 4. Use `canvas_build_web_artifact` instead when the result needs a full custom React app rather than a schema-driven UI
398
+
399
+ ## MCP Resources
400
+
401
+ These resources give you read access to canvas intelligence. Read them to understand
402
+ what the human has set up and what they're focusing on.
403
+
404
+ | Resource | What it provides |
405
+ |----------|-----------------|
406
+ | `canvas://pinned-context` | Content of pinned nodes + nearby unpinned neighbors |
407
+ | `canvas://schema` | Running-server create schemas and json-render catalog metadata |
408
+ | `canvas://layout` | Full canvas state (viewport, nodes, edges) |
409
+ | `canvas://summary` | Compact overview: node counts by type, pinned titles |
410
+ | `canvas://spatial-context` | Proximity clusters, reading order, pinned neighborhoods |
411
+ | `canvas://history` | Human-readable mutation timeline |
412
+ | `canvas://code-graph` | Auto-detected file import dependencies |
413
+
414
+ ### Reading Spatial Intent
415
+
416
+ The `canvas://spatial-context` resource reveals how the human has organized information:
417
+
418
+ - **Proximity clusters** — Nodes placed near each other form implicit groups. If the human
419
+ placed three files next to each other, those files are related in their mental model.
420
+ - **Reading order** — Nodes sorted top-left to bottom-right, following natural reading flow.
421
+ This implies sequence or priority.
422
+ - **Pinned neighborhoods** — For each pinned node, nearby unpinned nodes are listed. These
423
+ are the human's implicit context — things they consider related to what they pinned.
424
+ - **Board density matters** — On a dense board, spatial context can still read like one large
425
+ gallery unless groups and spacing separate the major regions clearly.
426
+
427
+ Use this spatial intelligence to understand what the human is thinking without them having to
428
+ explain it explicitly.
429
+
430
+ ## HTTP API Reference
431
+
432
+ All POST/PATCH endpoints accept `Content-Type: application/json`. Default base URL: `http://localhost:4313`
433
+
434
+ | Method | Endpoint | Purpose |
435
+ |--------|----------|---------|
436
+ | GET | `/api/canvas/state` | Full canvas state |
437
+ | POST | `/api/canvas/node` | Add node |
438
+ | PATCH | `/api/canvas/node/<id>` | Update node |
439
+ | DELETE | `/api/canvas/node/<id>` | Remove node |
440
+ | POST | `/api/canvas/edge` | Add edge |
441
+ | DELETE | `/api/canvas/edge` | Remove edge (`{ "edge_id": "..." }`) |
442
+ | GET | `/api/canvas/snapshots` | List snapshots |
443
+ | POST | `/api/canvas/snapshots` | Save snapshot |
444
+ | POST | `/api/canvas/snapshots/<id>` | Restore snapshot |
445
+ | DELETE | `/api/canvas/snapshots/<id>` | Delete snapshot |
446
+ | POST | `/api/canvas/context-pins` | Replace pinned nodes |
447
+ | GET | `/api/canvas/pinned-context` | Get current pins with neighborhood context |
448
+ | GET | `/api/canvas/search?q=...` | Search nodes |
449
+ | POST | `/api/canvas/json-render` | Create a native json-render node |
450
+ | POST | `/api/canvas/graph` | Create a native graph node |
451
+ | GET | `/api/canvas/schema` | Get running-server create schemas, examples, and json-render catalog metadata |
452
+ | POST | `/api/canvas/schema/validate` | Validate a json-render spec or graph payload without creating a node |
453
+ | GET | `/api/canvas/json-render/view?nodeId=...` | View a native json-render or graph node |
454
+ | POST | `/api/canvas/web-artifact` | Build a bundled web artifact and optionally open it on canvas |
455
+ | POST | `/api/canvas/group` | Create group |
456
+ | POST | `/api/canvas/group/add` | Add nodes to group |
457
+ | POST | `/api/canvas/group/ungroup` | Ungroup |
458
+ | POST | `/api/canvas/arrange` | Auto-arrange |
459
+ | POST | `/api/canvas/focus` | Center viewport on node |
460
+ | POST | `/api/canvas/clear` | Clear canvas |
461
+ | POST | `/api/canvas/update` | Batch update positions |
462
+ | GET | `/api/canvas/spatial-context` | Spatial clusters and reading order |
463
+ | POST | `/api/canvas/undo` | Undo |
464
+ | POST | `/api/canvas/redo` | Redo |
465
+ | GET | `/api/canvas/history` | Mutation history |
466
+ | GET | `/api/canvas/code-graph` | File dependency graph |
467
+ | GET | `/api/workbench/events` | SSE event stream |
468
+
469
+ ## Workflow Patterns
470
+
471
+ ### Responding to Pinned Context
472
+
473
+ When the human pins nodes, they're telling you what matters. This is the most important
474
+ collaboration pattern:
475
+
476
+ 1. Read `canvas://pinned-context` — get the content of pinned nodes and their neighborhoods
477
+ 2. Read `canvas://spatial-context` — understand how the whole canvas is organized
478
+ 3. Optionally read `canvas://summary` — see pinned nodes in the context of the full canvas
479
+ 4. Interpret what you find:
480
+ - What types are the pinned nodes? (files = code focus, status = progress, markdown = concepts)
481
+ - Are they clustered together (single focus) or spread across the canvas (multi-topic)?
482
+ - What unpinned nodes are nearby? These are the human's implicit context
483
+ - What's the reading order? Top-left to bottom-right suggests sequence or priority
484
+ - If an `mcp-app` node is pinned, treat it as “important but partially opaque” and use nearby
485
+ graph/file/markdown nodes to recover the missing semantic detail
486
+ 5. Respond by summarizing what you see, what you think the human is focusing on, and ask
487
+ if they'd like you to act on it (add related nodes, investigate further, etc.)
488
+
489
+ **When to use `pinned-context` vs `spatial-context`:**
490
+ - `canvas://pinned-context` — "what did the human explicitly pin, and what's near those pins?"
491
+ - `canvas://spatial-context` — "how is the entire canvas organized spatially?"
492
+ - Read both when you need the full picture; read just `pinned-context` for quick pin checks.
493
+
494
+ ### Investigation Board
495
+
496
+ When debugging, lay out evidence spatially to see connections:
497
+
498
+ 1. Create a root node describing the bug/issue
499
+ 2. Add evidence nodes: logs, stack traces, relevant code files (use `file` nodes for source)
500
+ 3. Connect evidence to root with `references` edges
501
+ 4. Add a hypothesis node, connect with `flow` edge
502
+ 5. As you investigate, add findings and update connections
503
+ 6. Use `status` nodes to track what you've checked
504
+ 7. Group evidence nodes together, and investigation tasks together
505
+ 8. Arrange with `flow` layout, then fine-tune positions if needed
506
+
507
+ ```
508
+ Bug Report ──references──> Error Logs
509
+ │ │
510
+ │ references
511
+ │ ▼
512
+ └──flow──> Hypothesis ──flow──> Fix
513
+
514
+ flow
515
+
516
+ Verification
517
+ ```
518
+
519
+ ### Architecture Diagram
520
+
521
+ Show system components and how they interact:
522
+
523
+ 1. Create `markdown` nodes for each service/component (include port, tech stack in content)
524
+ 2. Use `flow` edges for data flow, `depends-on` for dependencies — always label edges
525
+ 3. Group related services with `canvas_create_group` (e.g., "Application Services", "Data Layer")
526
+ 4. Use colors: green for healthy, yellow for degraded, red for down
527
+ 5. Arrange with `grid` layout initially
528
+ 6. For tiered architectures, fine-tune with explicit `x`/`y` via `canvas_update_node` to show
529
+ layers (e.g., gateway at top, services in middle, data stores at bottom)
530
+ 7. Connect pipeline stages with `flow` edges where applicable
531
+
532
+ ### Task Plan with Dependencies
533
+
534
+ Track work items and their relationships:
535
+
536
+ 1. Create `status` nodes for each task
537
+ 2. Color-code: green=done, yellow=in-progress, red=blocked, gray=queued, blue=ready/available
538
+ 3. Connect with `depends-on` edges — use `dashed` style for blocked dependencies, `solid` for
539
+ satisfied ones
540
+ 4. Update status nodes as work progresses using `canvas_update_node`
541
+ 5. Arrange with `flow` layout to show the dependency chain left-to-right
542
+ 6. Group related tasks if the plan has distinct phases
543
+
544
+ ### Code Exploration
545
+
546
+ Understand a codebase by visualizing file relationships:
547
+
548
+ 1. Add `file` nodes for key source files (content auto-loads and live-updates)
549
+ 2. The code graph auto-detects imports and creates `depends-on` edges automatically — you
550
+ don't need to manually add import-based edges. You can still add manual edges for
551
+ conceptual relationships beyond imports (e.g., "middleware validates using jwt")
552
+ 3. Read `canvas://code-graph` for dependency analysis: central files, isolated files
553
+ 4. Group related files with `canvas_create_group` (e.g., "Auth Module", "API Routes")
554
+ 5. Pin important files so the human sees them highlighted
555
+ 6. Arrange with `grid` layout after adding files
556
+
557
+ ### Interactive Artifact Builds
558
+
559
+ When the user wants a real browser app instead of static notes:
560
+
561
+ 1. Use the `web-artifacts-builder` skill if the UI needs React state, routing, or shadcn-style components
562
+ 2. Build with `canvas_build_web_artifact`
563
+ 3. Keep `openInCanvas` enabled unless the user explicitly wants only the output file
564
+ 4. Use the returned `projectPath` as the reusable source workspace for iterations
565
+ 5. Use the returned `path` for sharing or for opening the generated artifact outside the canvas
566
+ 6. Use the `playwright-cli` skill if you need to verify the artifact route or embedded app behavior in a browser
567
+
568
+ ### Status Dashboard
569
+
570
+ Monitor ongoing processes:
571
+
572
+ 1. Create `status` nodes for each metric/process
573
+ 2. Use semantic colors: green=passing, yellow=running, red=failing, gray=queued
574
+ 3. Connect sequential pipeline stages with `flow` edges (label: "then", "triggers")
575
+ 4. Update nodes in-place as state changes using `canvas_update_node` — never delete and recreate,
576
+ as that loses position and edges
577
+ 5. Arrange with `grid` layout
578
+ 6. The human sees real-time updates via SSE
579
+
580
+ ### Before/After Comparison
581
+
582
+ Show two states side by side for the human to compare:
583
+
584
+ 1. Take a snapshot before changes: `canvas_snapshot` with name "before-X"
585
+ 2. Make changes to the canvas
586
+ 3. Use `canvas_diff` to show what changed
587
+ 4. Or: create two groups ("Before" and "After") with corresponding nodes
588
+
589
+ ### Save and Start Fresh
590
+
591
+ When the human wants to explore a different approach without losing current work:
592
+
593
+ 1. **First**, save the current state: `canvas_snapshot` with a descriptive name
594
+ 2. **Then** clear: `canvas_clear` (never clear without snapshotting first)
595
+ 3. Set up the new workspace with initial nodes
596
+ 4. Tell the human the snapshot name and that `canvas_restore` can bring everything back
597
+
598
+ ## Best Practices
599
+
600
+ 1. **Start once, reuse always.** Don't restart the canvas for each task. Build on the
601
+ existing canvas state.
602
+
603
+ 2. **Titles are scannable.** Keep titles short (3-6 words). Put details in content.
604
+
605
+ 3. **Label every edge.** Unlabeled edges lose meaning. "depends on", "calls", "blocks"
606
+ are all more useful than a bare arrow.
607
+
608
+ 4. **Auto-arrange after batch adds.** When adding multiple nodes, call `canvas_arrange`
609
+ once at the end, not after each node.
610
+
611
+ 5. **Update in place.** Use `canvas_update_node` to change status, content, or color.
612
+ Don't delete and recreate — that loses position and edges.
613
+
614
+ 6. **Clean up.** Remove nodes that are no longer relevant. A cluttered canvas is worse
615
+ than no canvas.
616
+
617
+ 7. **Read before writing.** Check `canvas://layout` or `canvas_get_layout` before adding
618
+ nodes to avoid duplicates and understand the current state.
619
+
620
+ 8. **Use pinning.** When you want the human to focus on specific nodes, pin them.
621
+ When the human pins nodes, read `canvas://pinned-context` to see what they care about.
622
+ Prefer one intent-setting markdown pin plus a small set of concrete output pins over pinning a
623
+ whole gallery.
624
+
625
+ 9. **Snapshot before destructive changes.** Before clearing or major reorganization,
626
+ save a snapshot so you can restore if needed.
627
+
628
+ 10. **Prefer MCP tools over HTTP.** When running as an MCP server, use the canvas tools
629
+ directly rather than shelling out to curl. The tools handle all the details.
630
+
631
+ 11. **Use groups for visual organization.** When 3+ nodes are related, wrap them in a
632
+ group to make the relationship visible at a glance.
633
+
634
+ 12. **Use file nodes for source code.** File nodes auto-watch for changes and update
635
+ live. This is better than pasting code into markdown nodes.
636
+
637
+ 13. **Comparison boards need structure, not just content.** For galleries and evaluations, use a
638
+ named group, give the area breathing room, and keep related charts/artifacts inside that
639
+ region instead of letting them drift into the main cluster.
640
+
641
+ 14. **Capture external app IDs immediately.** For Excalidraw and other `mcp-app` nodes, store the
642
+ returned node ID or pin the node right away. Search/title rediscovery is less reliable there
643
+ than for markdown, graph, or file nodes.
644
+
645
+ 15. **Pair app nodes with explainers.** If you create or pin a web artifact or Excalidraw node,
646
+ add a nearby markdown, graph, or file node that explains what the app is for. This makes
647
+ pinned context far more useful to later agents.
648
+
649
+ ## Persistence
650
+
651
+ Canvas state auto-saves to `.pmx-canvas/state.json` on every mutation (debounced 500ms). State
652
+ loads automatically on server start. The file is git-committable — spatial knowledge
653
+ persists across sessions.
654
+
655
+ Snapshots save to `.pmx-canvas/snapshots/`. Web artifacts land in `.pmx-canvas/artifacts/`.
656
+ Legacy `.pmx-canvas.json` and `.pmx-canvas-snapshots/` are auto-migrated on first boot.
657
+
658
+ ## Real-Time Collaboration
659
+
660
+ The canvas supports real-time human-agent collaboration:
661
+
662
+ - **Human pins nodes in browser** → agent reads `canvas://pinned-context`
663
+ - **Agent adds/updates nodes** → human sees changes instantly via SSE
664
+ - **Human moves/groups nodes** → spatial arrangement communicates intent
665
+ - **Agent reads spatial context** → understands implicit relationships
666
+
667
+ This bidirectional flow means the canvas is a shared workspace, not just an output display.
668
+ Pay attention to what the human is doing on the canvas — their spatial choices are meaningful.