pmx-canvas 0.1.18 → 0.1.20

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 (70) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/Readme.md +19 -6
  3. package/dist/canvas/global.css +35 -2
  4. package/dist/canvas/index.js +70 -69
  5. package/dist/json-render/index.js +109 -109
  6. package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
  7. package/dist/types/client/icons.d.ts +2 -0
  8. package/dist/types/client/state/canvas-store.d.ts +2 -0
  9. package/dist/types/client/types.d.ts +2 -1
  10. package/dist/types/json-render/charts/components.d.ts +5 -1
  11. package/dist/types/json-render/renderer/index.d.ts +1 -0
  12. package/dist/types/json-render/server.d.ts +1 -0
  13. package/dist/types/mcp/canvas-access.d.ts +3 -0
  14. package/dist/types/server/canvas-operations.d.ts +4 -0
  15. package/dist/types/server/canvas-schema.d.ts +19 -3
  16. package/dist/types/server/canvas-serialization.d.ts +1 -0
  17. package/dist/types/server/canvas-state.d.ts +8 -2
  18. package/dist/types/server/html-primitives.d.ts +34 -0
  19. package/dist/types/server/index.d.ts +19 -0
  20. package/docs/RELEASE.md +153 -0
  21. package/docs/bun-webview-integration.md +296 -0
  22. package/docs/cli.md +143 -0
  23. package/docs/evals/e2e-cli-coverage.md +61 -0
  24. package/docs/http-api.md +201 -0
  25. package/docs/mcp.md +137 -0
  26. package/docs/node-types.md +272 -0
  27. package/docs/plans/.gitkeep +0 -0
  28. package/docs/plans/plan-001-semantic-watch-mvp.md +335 -0
  29. package/docs/plans/plan-002-human-attention-layer-design-spec.md +679 -0
  30. package/docs/plans/plan-003-human-attention-layer-implementation-plan.md +572 -0
  31. package/docs/reactive-canvas-proposal.md +578 -0
  32. package/docs/release-review-0.1.0.md +38 -0
  33. package/docs/screenshot.png +0 -0
  34. package/docs/screenshots/demo-workbench-dark.png +0 -0
  35. package/docs/screenshots/demo-workbench-light.png +0 -0
  36. package/docs/screenshots/welcome-dark.png +0 -0
  37. package/docs/screenshots/welcome-light.png +0 -0
  38. package/docs/sdk.md +103 -0
  39. package/package.json +2 -1
  40. package/skills/pmx-canvas/SKILL.md +8 -0
  41. package/src/cli/agent.ts +167 -5
  42. package/src/client/App.tsx +20 -1
  43. package/src/client/canvas/AnnotationLayer.tsx +33 -12
  44. package/src/client/canvas/CanvasViewport.tsx +88 -7
  45. package/src/client/canvas/CommandPalette.tsx +1 -1
  46. package/src/client/canvas/ContextMenu.tsx +2 -2
  47. package/src/client/canvas/ExpandedNodeOverlay.tsx +7 -1
  48. package/src/client/icons.tsx +13 -0
  49. package/src/client/nodes/McpAppNode.tsx +12 -4
  50. package/src/client/state/canvas-store.ts +15 -5
  51. package/src/client/state/sse-bridge.ts +4 -3
  52. package/src/client/theme/global.css +35 -2
  53. package/src/client/types.ts +2 -1
  54. package/src/json-render/charts/components.tsx +41 -7
  55. package/src/json-render/charts/extra-components.tsx +13 -12
  56. package/src/json-render/renderer/index.tsx +1 -0
  57. package/src/json-render/server.ts +3 -1
  58. package/src/mcp/canvas-access.ts +25 -0
  59. package/src/mcp/server.ts +85 -27
  60. package/src/server/agent-context.ts +17 -0
  61. package/src/server/canvas-operations.ts +91 -38
  62. package/src/server/canvas-schema.ts +83 -3
  63. package/src/server/canvas-serialization.ts +9 -2
  64. package/src/server/canvas-state.ts +27 -9
  65. package/src/server/demo-state.json +1143 -0
  66. package/src/server/demo.ts +25 -777
  67. package/src/server/html-primitives.ts +990 -0
  68. package/src/server/index.ts +43 -2
  69. package/src/server/server.ts +140 -14
  70. package/src/server/spatial-analysis.ts +3 -3
package/docs/mcp.md ADDED
@@ -0,0 +1,137 @@
1
+ # MCP reference
2
+
3
+ PMX Canvas ships an MCP stdio server with **42 tools** + **8 core resources**,
4
+ plus per-skill resources at `canvas://skills/<name>`. The server emits
5
+ `notifications/resources/updated` when canvas state changes — humans pin
6
+ nodes in the browser, agents are notified immediately.
7
+
8
+ ## Connect
9
+
10
+ Add to your agent's MCP config:
11
+
12
+ ```json
13
+ {
14
+ "mcpServers": {
15
+ "canvas": {
16
+ "command": "bunx",
17
+ "args": ["pmx-canvas", "--mcp"]
18
+ }
19
+ }
20
+ }
21
+ ```
22
+
23
+ The canvas auto-starts on first tool call.
24
+
25
+ ## Tools
26
+
27
+ | Tool | Description |
28
+ |------|-------------|
29
+ | `canvas_add_node` | Add a node (markdown, status, context, file, webpage, html, etc.) |
30
+ | `canvas_add_html_node` | Create an `html` node from a self-contained HTML/JS document (sandboxed iframe) |
31
+ | `canvas_add_html_primitive` | Create a reusable generated HTML communication primitive as a sandboxed `html` node |
32
+ | `canvas_add_diagram` | Hand-drawn diagram via the hosted Excalidraw MCP App (preset alias for `canvas_open_mcp_app`) |
33
+ | `canvas_open_mcp_app` | Open any [MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) server's `ui://` resource as an iframe node |
34
+ | `canvas_describe_schema` | Describe the running server's create schemas, examples, json-render catalog, and HTML primitive catalog |
35
+ | `canvas_validate_spec` | Validate a json-render spec, graph payload, or HTML primitive payload without creating a node |
36
+ | `canvas_refresh_webpage_node` | Re-fetch and update a webpage node from its stored URL |
37
+ | `canvas_add_json_render_node` | Create a native json-render node from a validated spec |
38
+ | `canvas_add_graph_node` | Create a native graph node (line, bar, pie, area, scatter, radar, stacked-bar, composed) |
39
+ | `canvas_build_web_artifact` | Build a bundled HTML artifact and open it on the canvas |
40
+ | `canvas_update_node` | Update content, position, size, collapsed state |
41
+ | `canvas_remove_node` | Remove a node and its edges |
42
+ | `canvas_get_layout` | Get full canvas state |
43
+ | `canvas_get_node` | Get a single node by ID |
44
+ | `canvas_remove_annotation` | Remove a human-drawn annotation by ID |
45
+ | `canvas_add_edge` | Connect two nodes |
46
+ | `canvas_remove_edge` | Remove a connection |
47
+ | `canvas_arrange` | Auto-arrange (grid/column/flow) |
48
+ | `canvas_validate` | Validate collisions, containment, and missing edge endpoints |
49
+ | `canvas_focus_node` | Pan viewport to a node; use CLI `focus --no-pan` when you only need to select/raise |
50
+ | `canvas_pin_nodes` | Pin nodes to include in agent context |
51
+ | `canvas_clear` | Clear all nodes and edges |
52
+ | `canvas_snapshot` | Save current canvas as a named snapshot |
53
+ | `canvas_list_snapshots` | List saved snapshots, bounded to the newest 20 by default |
54
+ | `canvas_gc_snapshots` | Delete old snapshots while keeping the newest N |
55
+ | `canvas_restore` | Restore canvas from a saved snapshot |
56
+ | `canvas_delete_snapshot` | Delete a saved snapshot |
57
+ | `canvas_search` | Find nodes by title/content keywords |
58
+ | `canvas_undo` | Undo the last canvas mutation |
59
+ | `canvas_redo` | Redo the last undone mutation |
60
+ | `canvas_diff` | Compare current canvas vs a saved snapshot |
61
+ | `canvas_create_group` | Create a group containing specified nodes |
62
+ | `canvas_group_nodes` | Add nodes to an existing group |
63
+ | `canvas_ungroup` | Release all children from a group |
64
+ | `canvas_batch` | Run a batch of canvas operations with `$ref` support |
65
+ | `canvas_webview_status` | Get Bun.WebView automation status for the workbench |
66
+ | `canvas_webview_start` | Start or replace the Bun.WebView automation session |
67
+ | `canvas_webview_stop` | Stop the active Bun.WebView automation session |
68
+ | `canvas_evaluate` | Evaluate JavaScript in the active workbench automation session |
69
+ | `canvas_resize` | Resize the active workbench automation viewport |
70
+ | `canvas_screenshot` | Capture a screenshot from the active workbench automation session |
71
+
72
+ ## Resources
73
+
74
+ Individual bundled skills are also readable at `canvas://skills/<name>`.
75
+
76
+ | Resource | Description |
77
+ |----------|-------------|
78
+ | `canvas://pinned-context` | Content of pinned nodes + nearby unpinned neighbors |
79
+ | `canvas://schema` | Running-server create schemas and json-render catalog metadata |
80
+ | `canvas://layout` | Full canvas state (all nodes, edges, viewport) |
81
+ | `canvas://summary` | Compact overview: counts, pinned titles, viewport |
82
+ | `canvas://spatial-context` | Proximity clusters, reading order, pinned neighborhoods |
83
+ | `canvas://history` | Mutation history timeline with undo/redo position |
84
+ | `canvas://code-graph` | Auto-detected file dependency graph (JS/TS, Python, Go, Rust) |
85
+ | `canvas://skills` | Index of bundled agent skills + per-skill content at `canvas://skills/<name>` |
86
+
87
+ ## Change notifications
88
+
89
+ The MCP server emits `notifications/resources/updated` whenever canvas state
90
+ changes:
91
+
92
+ - Pin changes notify `canvas://pinned-context`
93
+ - All mutations notify `canvas://layout`, `canvas://summary`,
94
+ `canvas://spatial-context`, `canvas://history`, and `canvas://code-graph`
95
+
96
+ This closes the human-to-agent loop: spatial curation in the browser becomes
97
+ an immediate signal in the agent's context.
98
+
99
+ ## Annotation Visibility
100
+
101
+ Human-drawn canvas annotations are rendered as browser SVG ink. MCP resources
102
+ keep annotation context compact: agents see annotation counts, bounds, and target
103
+ summaries such as the node or empty canvas region that was marked, but not the
104
+ raw stroke geometry or visual shape.
105
+
106
+ Annotations are a browser-visible markup layer. Use the pen toolbar button to
107
+ draw and the eraser toolbar button to remove an annotation again; agents can also
108
+ remove a known annotation ID with `canvas_remove_annotation`.
109
+
110
+ Use WebView automation when an agent needs to actually see annotations as drawn.
111
+ For example, inspect `.annotation-layer path` with `canvas_evaluate` or capture a
112
+ `canvas_screenshot` to distinguish an arrow from a line, circle, or highlight.
113
+
114
+ ## Node-type routing
115
+
116
+ MCP node creation uses dedicated tools for structured node families. Read
117
+ `mcp.nodeTypeRouting` from `canvas_describe_schema` / `canvas://schema` when
118
+ in doubt:
119
+
120
+ - `json-render` → `canvas_add_json_render_node`
121
+ - `graph` → `canvas_add_graph_node`
122
+ - `html-primitive` → `canvas_add_html_primitive`
123
+ - `html` → `canvas_add_html_node`
124
+ - `web-artifact` → `canvas_build_web_artifact`
125
+ - `mcp-app` → `canvas_open_mcp_app`
126
+ - `group` → `canvas_create_group`
127
+ - Basic nodes (`markdown`, `status`, `file`, `image`, `webpage`) →
128
+ `canvas_add_node`
129
+
130
+ ## CLI/MCP alignment
131
+
132
+ CLI and MCP are kept aligned for the main canvas operations: node and edge
133
+ creation, graph/json-render/html/html-primitive nodes, web artifacts, external apps, groups,
134
+ batch builds, layout validation, snapshots, search, focus, pins, undo/redo,
135
+ semantic watch streams, WebView automation, and daemon/server control where
136
+ it applies. A few agent-native capabilities — resource subscriptions and
137
+ `canvas_diff` — remain MCP-only.
@@ -0,0 +1,272 @@
1
+ # Node types
2
+
3
+ Canvas nodes are typed. Each type has a dedicated renderer, schema, and (for
4
+ structured types) a dedicated MCP tool. This page is the user-facing reference
5
+ for what each type is for and how to create one. For tool/HTTP/SDK signatures,
6
+ see [MCP tools](mcp.md), [HTTP API](http-api.md), and [SDK](sdk.md).
7
+
8
+ ## Overview
9
+
10
+ | Type | Purpose |
11
+ |------|---------|
12
+ | `markdown` | Rich markdown with rendered preview |
13
+ | `status` | Compact status indicator (phase, message, elapsed time) |
14
+ | `context` | Context cards, token usage, workspace grounding |
15
+ | `ledger` | Execution ledger summary |
16
+ | `trace` | Agent trace pills (tool calls, subagent activity) |
17
+ | `file` | Live file viewer with auto-update on disk changes |
18
+ | `image` | Image viewer (file paths, data URIs, URLs) |
19
+ | `webpage` | Persisted webpage snapshot with stored URL, extracted text, refresh |
20
+ | `mcp-app` | Tool-backed hosted MCP App iframes (Excalidraw, etc.) |
21
+ | `json-render` | Structured UI from JSON specs (cards, tables, forms) |
22
+ | `graph` | Charts (line, bar, pie, area, scatter, radar, stacked-bar, composed) |
23
+ | `html` | Self-contained HTML/JS in a sandboxed iframe |
24
+ | `web-artifact` | Bundled React/Tailwind artifact (full single-file app) |
25
+ | `group` | Spatial container/frame around other nodes |
26
+
27
+ Thread node types `prompt` and `response` exist internally for agent
28
+ conversation rendering and are not created through public APIs.
29
+
30
+ ## Choosing the right visual tier
31
+
32
+ Three rendering tiers cover increasing levels of complexity. Pick the lowest
33
+ that fits the work — each step adds capability and bundle weight.
34
+
35
+ | Tier | Type | Use when | Bundle weight |
36
+ |------|------|----------|---------------|
37
+ | 1 | `json-render` | You can describe the UI as a spec (forms, tables, dashboards from a component catalog) | None — runtime already loaded |
38
+ | 2 | `html` | You have/can write self-contained HTML+JS (Chart.js, D3, custom widgets, interactive demos) | None — sandboxed iframe |
39
+ | 3 | `web-artifact` | You need a full React/Tailwind app with shadcn components, routing, or shared state | Build step |
40
+
41
+ ## File nodes
42
+
43
+ File nodes display project files with line numbers and language detection.
44
+ When an agent edits a file through its normal tools, the canvas node updates
45
+ automatically via `fs.watch()`.
46
+
47
+ ```ts
48
+ canvas_add_node({ type: 'file', content: 'src/server/index.ts' })
49
+ ```
50
+
51
+ ## Image nodes
52
+
53
+ Image nodes display local paths, remote URLs, and data URIs. File-backed and
54
+ HTTP(S)-backed images preserve provenance so agents can tell where evidence
55
+ came from. Nodes can carry validation status or warnings.
56
+
57
+ ```ts
58
+ canvas_add_node({
59
+ type: 'image',
60
+ content: 'artifacts/dashboard.png',
61
+ data: {
62
+ validationStatus: 'passed',
63
+ validationMessage: 'Screenshot matches the requested dashboard state.',
64
+ },
65
+ })
66
+ ```
67
+
68
+ ## Webpage nodes
69
+
70
+ Webpage nodes store the source URL on the node, fetch the page server-side,
71
+ and cache extracted text for search, pins, and agent context. Saved canvases
72
+ keep enough information for an agent to refresh the node from the original
73
+ URL later.
74
+
75
+ ```ts
76
+ canvas_add_node({ type: 'webpage', url: 'https://example.com/docs' })
77
+ canvas_refresh_webpage_node({ id: 'node-abc123' })
78
+ ```
79
+
80
+ ## MCP App nodes
81
+
82
+ `mcp-app` nodes embed other MCP servers' UI resources (`ui://...`) directly
83
+ on the canvas as sandboxed iframes. Any server implementing the
84
+ [MCP Apps extension](https://modelcontextprotocol.io/docs/extensions/apps)
85
+ can be opened with `canvas_open_mcp_app`.
86
+
87
+ Generic `pmx-canvas node add --type mcp-app` is intentionally rejected —
88
+ these nodes need tool/session metadata. Use `canvas_open_mcp_app` (or the
89
+ `canvas_add_diagram` Excalidraw preset) instead.
90
+
91
+ ### Excalidraw preset (hand-drawn diagrams)
92
+
93
+ [Excalidraw](https://github.com/excalidraw/excalidraw-mcp) ships a hosted MCP
94
+ server at `https://mcp.excalidraw.com/mcp`. PMX Canvas exposes a one-call
95
+ preset:
96
+
97
+ ```ts
98
+ canvas_add_diagram({
99
+ elements: [
100
+ { type: 'rectangle', id: 'a', x: 80, y: 120, width: 180, height: 80,
101
+ roundness: { type: 3 }, backgroundColor: '#a5d8ff', fillStyle: 'solid',
102
+ label: { text: 'Agent', fontSize: 18 } },
103
+ { type: 'rectangle', id: 'b', x: 380, y: 120, width: 180, height: 80,
104
+ roundness: { type: 3 }, backgroundColor: '#d0bfff', fillStyle: 'solid',
105
+ label: { text: 'PMX Canvas', fontSize: 18 } },
106
+ { type: 'arrow', id: 'a1', x: 260, y: 160, width: 120, height: 0,
107
+ startBinding: { elementId: 'a' }, endBinding: { elementId: 'b' },
108
+ label: { text: 'adds nodes' } },
109
+ ],
110
+ title: 'Agent → Canvas',
111
+ });
112
+ ```
113
+
114
+ For any other MCP App, call `canvas_open_mcp_app` directly with the server's
115
+ transport, tool name, and arguments.
116
+
117
+ ## json-render nodes
118
+
119
+ `json-render` nodes turn structured JSON specs into rendered UI panels
120
+ (dashboards, tables, forms, cards) without writing HTML. PMX Canvas ships the
121
+ [`@json-render/*`](https://www.npmjs.com/package/@json-render/core) runtime
122
+ and component catalog (core + react + shadcn).
123
+
124
+ ```ts
125
+ canvas_add_json_render_node({
126
+ title: 'Deploy status',
127
+ spec: {
128
+ root: 'card',
129
+ elements: {
130
+ card: { type: 'Card', props: { title: 'Deploy' }, children: ['status'] },
131
+ status: { type: 'Badge', props: { variant: 'default', text: 'Healthy' } },
132
+ },
133
+ },
134
+ });
135
+ ```
136
+
137
+ `Badge` uses shadcn variants: `default`, `secondary`, `destructive`,
138
+ `outline`. Older saved specs using `label` or status variants such as
139
+ `success`/`warning` are normalized during validation.
140
+
141
+ Use `canvas_describe_schema` / `canvas_validate_spec` to introspect the
142
+ component catalog before building a spec.
143
+
144
+ ## HTML nodes
145
+
146
+ `html` nodes render a self-contained HTML/JS document in a sandboxed iframe.
147
+ They sit between `json-render` (no custom JS) and `web-artifact` (full bundled
148
+ React app) — perfect for Chart.js, D3, custom widgets, and any HTML you can
149
+ write or paste.
150
+
151
+ The sandbox runs with `allow-scripts` only — no same-origin access, no
152
+ top-level navigation, no form submission. Inline `<script>` and CDN
153
+ `<script src>` both work. The canvas auto-injects its theme tokens
154
+ (`--c-*` and `--color-*` aliases) into the iframe `<head>` so artifacts can
155
+ match the active theme.
156
+
157
+ ```ts
158
+ canvas_add_html_node({
159
+ title: 'Cost projection',
160
+ html: '<canvas id="c"></canvas><script src="https://cdn.jsdelivr.net/npm/chart.js"></script><script>...</script>',
161
+ })
162
+ ```
163
+
164
+ A fragment without `<html>`/`<head>` is wrapped in a full document
165
+ automatically. Default size is 720×640.
166
+
167
+ ### HTML primitives
168
+
169
+ `html-primitive` is a virtual schema type that creates a normal sandboxed
170
+ `html` node from a reusable communication template. Use it when a long markdown
171
+ answer would be easier to review as an option grid, implementation timeline,
172
+ review sheet, PR writeup, code walkthrough, system map, design sheet,
173
+ component gallery, interaction prototype, flowchart, SVG illustration set,
174
+ explainer, status report, incident report, triage board, config editor, or
175
+ prompt tuner.
176
+
177
+ ```ts
178
+ canvas_add_html_primitive({
179
+ kind: 'choice-grid',
180
+ title: 'Implementation options',
181
+ data: {
182
+ items: [
183
+ { title: 'Small patch', summary: 'Least disruption.', pros: ['Fast'], cons: ['Less flexible'] },
184
+ ],
185
+ },
186
+ });
187
+ ```
188
+
189
+ HTTP callers may post either `{ "type": "html-primitive", "kind": "choice-grid", "data": ... }`
190
+ or `{ "type": "html", "primitive": "choice-grid", "data": ... }`. The stored
191
+ node remains `type: "html"` with `data.htmlPrimitive`, `data.primitiveData`, and
192
+ the generated `data.html` payload.
193
+
194
+ ## Web artifacts
195
+
196
+ A **web artifact** is a single-file, fully bundled HTML app (React + Tailwind
197
+ + shadcn) the agent builds from TSX source. Use it when the work calls for a
198
+ real interactive app — charts, forms, mini-dashboards — beyond what a static
199
+ node or `html` snippet can express.
200
+
201
+ `canvas_build_web_artifact` takes source strings (`App.tsx`, optional
202
+ `index.css`, `main.tsx`, `index.html`, plus extra files), runs the bundled
203
+ web-artifacts-builder scripts, writes the self-contained HTML to
204
+ `.pmx-canvas/artifacts/<slug>.html`, and (by default) opens it in the canvas.
205
+
206
+ ```bash
207
+ pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --deps recharts --include-logs
208
+ ```
209
+
210
+ The scaffold includes `recharts`. Pass `--deps name,name2` for additional
211
+ package dependencies. Failed or empty CLI bundles print `ok: false`, exit
212
+ non-zero, and do not create a canvas node.
213
+
214
+ The matching agent skill is at
215
+ [`skills/web-artifacts-builder/SKILL.md`](../skills/web-artifacts-builder/SKILL.md).
216
+
217
+ ## Groups
218
+
219
+ Groups are spatial containers that visually contain other nodes. They render
220
+ as dashed-border frames with a title bar and optional accent color.
221
+
222
+ - Select 2+ nodes and click "Group" in the selection bar
223
+ - Right-click a group to ungroup
224
+ - Collapsing a group hides children and shows a summary
225
+ - By default, group creation preserves the children's current positions and
226
+ expands the frame around them
227
+ - Pass `childLayout` to auto-pack children (`grid`, `column`, `flow`)
228
+ - Pass explicit `x`, `y`, `width`, and `height` to create a manual frame and
229
+ lay children out inside it
230
+
231
+ ```ts
232
+ canvas_create_group({ title: 'Auth Module', childIds: ['node-1', 'node-2'], color: '#4a9eff' })
233
+ ```
234
+
235
+ ## Edge types
236
+
237
+ All edges support labels, styles (solid/dashed/dotted), and animation.
238
+
239
+ | Type | Use case |
240
+ |------|----------|
241
+ | `flow` | Sequential steps, data flow |
242
+ | `depends-on` | Dependencies between tasks |
243
+ | `relation` | General relationships |
244
+ | `references` | Cross-references, evidence links |
245
+
246
+ ## Schema-driven discovery
247
+
248
+ Agents don't have to guess node shapes. The running server exposes its create
249
+ schemas, json-render component catalog, and node-type examples:
250
+
251
+ - `canvas_describe_schema` / `GET /api/canvas/schema` — list all node-create
252
+ schemas, required fields, json-render components, HTML primitives, and sample payloads
253
+ - `canvas_validate_spec` / `POST /api/canvas/schema/validate` — validate a
254
+ json-render spec, graph payload, or HTML primitive payload **without** creating a node
255
+ - `canvas_validate` / `GET /api/canvas/validate` — validate the current
256
+ layout for collisions, containment, and missing edge endpoints
257
+ - `canvas://schema` — the same data as an MCP resource
258
+
259
+ The CLI's `node schema` / `validate spec` subcommands surface the same data
260
+ from the terminal.
261
+
262
+ MCP node creation uses dedicated tools for structured node families. Read
263
+ `mcp.nodeTypeRouting` from `canvas_describe_schema` when in doubt:
264
+ `json-render` → `canvas_add_json_render_node`,
265
+ `graph` → `canvas_add_graph_node`,
266
+ `html-primitive` → `canvas_add_html_primitive`,
267
+ `html` → `canvas_add_html_node`,
268
+ `web-artifact` → `canvas_build_web_artifact`,
269
+ `mcp-app` → `canvas_open_mcp_app`,
270
+ `group` → `canvas_create_group`.
271
+ Basic nodes (`markdown`, `status`, `file`, `image`, `webpage`) use
272
+ `canvas_add_node`.
File without changes