pmx-canvas 0.1.17 → 0.1.19

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.
package/docs/cli.md ADDED
@@ -0,0 +1,140 @@
1
+ # CLI reference
2
+
3
+ The CLI is the shell-native way to run and control PMX Canvas. It targets
4
+ `http://localhost:4313` by default — override with `PMX_CANVAS_URL` or
5
+ `PMX_CANVAS_PORT` when the server runs elsewhere.
6
+
7
+ ## Server lifecycle
8
+
9
+ ```bash
10
+ pmx-canvas # Start canvas, open browser
11
+ pmx-canvas --demo # Start with the project-tour demo board
12
+ pmx-canvas --port=8080 # Custom port
13
+ pmx-canvas --no-open # Headless (for agents/CI)
14
+ pmx-canvas --theme=light # dark | light | high-contrast
15
+ pmx-canvas --mcp # Run as MCP server (stdio)
16
+ pmx-canvas --webview-automation # Start headless Bun.WebView session
17
+ pmx-canvas open # Open the current workbench in a browser
18
+ ```
19
+
20
+ ### Daemon mode
21
+
22
+ Run detached with pid/log tracking instead of holding a terminal:
23
+
24
+ ```bash
25
+ pmx-canvas serve --daemon --no-open --wait-ms=20000 # Start detached, wait for health
26
+ pmx-canvas serve status # Inspect daemon health + pid
27
+ pmx-canvas serve stop # Stop the daemon for this port
28
+ ```
29
+
30
+ ## Nodes and edges
31
+
32
+ ```bash
33
+ pmx-canvas node add --type webpage --url https://example.com/docs
34
+ pmx-canvas node add --type web-artifact --title "Dashboard" --app-file ./App.tsx
35
+ pmx-canvas node add --type graph --graph-type bar --data-file ./metrics.json --x-key label --y-key value
36
+ pmx-canvas node add --type graph --graph-type bar --data '[{"x":"a","y":1}]' --x-key x --y-key y
37
+ pmx-canvas graph add --graph-type bar --data '[{"x":"a","y":1}]' --x-key x --y-key y # Alias
38
+ pmx-canvas node add --help --type webpage --json # Schema for one type
39
+
40
+ pmx-canvas external-app add --kind excalidraw --title "Diagram"
41
+
42
+ pmx-canvas edge add --from-search "DVT O3 — GitOps" --to-search "deep work trend" --type relation
43
+ ```
44
+
45
+ `--from-search` / `--to-search` must each resolve to exactly one node — broad
46
+ queries fail rather than guess. Use the full visible title.
47
+
48
+ CLI create commands return the created node shape with normalized title,
49
+ content, and geometry, which makes scripting stacked layouts and batch
50
+ follow-ups easier.
51
+
52
+ ### Graph height flags
53
+
54
+ Graph height flags split by target:
55
+
56
+ - `--node-height` / `--nodeHeight` — the canvas node frame
57
+ - `--chart-height` — the chart content inside the node
58
+ - `--height` — accepted as a frame-height compatibility alias
59
+
60
+ For MCP/HTTP payloads, use `nodeHeight` for the frame and `height` for chart
61
+ content.
62
+
63
+ ## Discovery and validation
64
+
65
+ ```bash
66
+ pmx-canvas node schema --type json-render --component Table --summary
67
+ pmx-canvas validate # Layout validation
68
+ pmx-canvas validate spec --type json-render --spec-file ./dashboard.json --summary
69
+ ```
70
+
71
+ The schema commands surface the running server's data, which is strictly
72
+ better than guessing flags or payloads.
73
+
74
+ ## Batch and arrange
75
+
76
+ ```bash
77
+ pmx-canvas batch --file ./canvas-ops.json
78
+ ```
79
+
80
+ See [HTTP API → batch](http-api.md#batch-operations) for the operation
81
+ schema; the same JSON works for the CLI batch file.
82
+
83
+ ## Web artifacts
84
+
85
+ ```bash
86
+ pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --deps recharts --include-logs
87
+ ```
88
+
89
+ Failed or empty CLI bundles print `ok: false`, exit non-zero, and do not
90
+ create a canvas node.
91
+
92
+ ## Watch (semantic deltas)
93
+
94
+ `pmx-canvas watch` consumes the SSE stream and emits compact semantic deltas
95
+ for agents that need low-token updates instead of full layout snapshots. It
96
+ filters noise from harmless moves and reports meaningful events such as pins,
97
+ node additions/removals, group changes, edge connections, and moves that
98
+ change spatial clustering.
99
+
100
+ ```bash
101
+ pmx-canvas watch --events context-pin,move-end
102
+ pmx-canvas watch --json --events context-pin --max-events 1
103
+ ```
104
+
105
+ ## Focus
106
+
107
+ ```bash
108
+ pmx-canvas focus <node-id> # Pan viewport to a node
109
+ pmx-canvas focus <node-id> --no-pan # Select/raise without panning
110
+ ```
111
+
112
+ ## WebView automation
113
+
114
+ Drive a headless Bun.WebView (Chromium or WebKit) pointed at the workbench:
115
+
116
+ ```bash
117
+ pmx-canvas webview status
118
+ pmx-canvas webview start --backend chrome --width 1440 --height 900
119
+ pmx-canvas webview evaluate --expression "document.title"
120
+ pmx-canvas webview resize --width 1280 --height 800
121
+ pmx-canvas webview screenshot --output ./canvas.png
122
+ pmx-canvas webview stop
123
+ ```
124
+
125
+ Use WebView for visual annotation inspection. Agent-readable canvas context only
126
+ reports annotation targets and bounds; it does not describe whether the human
127
+ drew an arrow, line, circle, or other shape. Inspect `.annotation-layer path` or
128
+ take a screenshot when the drawn form matters.
129
+
130
+ Humans draw with the pen toolbar button and remove marks with the eraser button.
131
+ If an agent already knows the annotation ID from context, it can remove it through
132
+ MCP with `canvas_remove_annotation`.
133
+
134
+ ## When to reach for the CLI
135
+
136
+ - Direct terminal control without MCP wiring
137
+ - Shell scripts and CI-friendly automation
138
+ - Schema-driven discovery from the running server
139
+ - Local debugging of canvas, webview, and screenshot flows
140
+ - A control surface that covers normal canvas work without MCP wiring
@@ -0,0 +1,61 @@
1
+ ---
2
+ id: eval-20260424-001
3
+ pattern-key: pmx-canvas.cli-e2e-fresh-workspace
4
+ source: pmx-canvas-0.1.2-e2e-cli-coverage-report
5
+ promoted-rule: "Fresh-workspace CLI coverage must verify node creation, parseable JSON, web-artifact failure behavior, external apps, arrange/validate, and focus no-pan before release."
6
+ promoted-to: package.json test:e2e-cli
7
+ created: 2026-04-24
8
+ last-run: 2026-04-25
9
+ last-result: pass
10
+ ---
11
+
12
+ # PMX Canvas CLI E2E Coverage Eval
13
+
14
+ ## What This Tests
15
+
16
+ Prevents regressions in the published-agent CLI flows that caused the 0.1.2 E2E report failures.
17
+
18
+ ## Precondition
19
+
20
+ - Bun is installed.
21
+ - The repo has been built with `bun run build` when client/browser assets changed.
22
+ - Network is available for the hosted Excalidraw MCP preset and web-artifact dependency install.
23
+ - Port `4567` is free, or `PMX_CANVAS_E2E_PORT` is set to a free port.
24
+
25
+ ## Verification Method
26
+
27
+ Command check:
28
+
29
+ ```bash
30
+ bun run test:e2e-cli
31
+ ```
32
+
33
+ The command runs `scripts/e2e-cli-coverage.sh`, which creates a fresh temp workspace, starts the local PMX Canvas CLI server, and verifies:
34
+
35
+ - `layout` and `node list` emit JSON parseable by Python's `json` module.
36
+ - Core node types can be created through the CLI, including two webpage input paths.
37
+ - Graph nodes accept `--data` as an alias for `--data-json`.
38
+ - All graph variants create successfully: line, bar, pie, area, scatter, radar, stacked-bar, composed.
39
+ - Simple and dashboard-shaped json-render specs create successfully.
40
+ - Generic `node add --type mcp-app` is rejected with guidance.
41
+ - `external-app add --kind excalidraw` creates a tool-backed app node.
42
+ - Broken web-artifact builds return `ok: false`, exit non-zero, and do not create a node.
43
+ - One successful web-artifact build emits a substantial bundled React/Recharts app, opens a node, and browser-verifies the real app content renders in the iframe.
44
+ - `focus --no-pan` selects without viewport panning.
45
+ - `arrange --layout grid` and `validate` agree on a valid layout.
46
+ - Search can find artifact nodes and `status` reports expected graph/json-render/web-artifact counts.
47
+
48
+ ## Expected Result
49
+
50
+ **Pass:** `PMX Canvas CLI E2E coverage passed` and exit code 0.
51
+
52
+ **Fail:** Any command exits non-zero, JSON parsing fails, an assertion fails, or the server does not become healthy.
53
+
54
+ ## Recovery Action
55
+
56
+ If this eval fails:
57
+
58
+ 1. Re-run with `PMX_CANVAS_E2E_KEEP_WORKDIR=1 bun run test:e2e-cli` to preserve the temp workspace.
59
+ 2. Inspect the preserved `.pmx-canvas/` state and `pmx-canvas.log` printed by the script.
60
+ 3. Fix the failing CLI/server path and add or update the narrower unit regression.
61
+ 4. Re-run `bun run test:e2e-cli`, then `bun run test:all` before release.
@@ -0,0 +1,191 @@
1
+ # HTTP API reference
2
+
3
+ REST endpoints for all canvas operations + an SSE event stream. Works from
4
+ any language. Default base URL: `http://localhost:4313`.
5
+
6
+ ## Canvas state
7
+
8
+ ```bash
9
+ # Get canvas state
10
+ curl http://localhost:4313/api/canvas/state
11
+
12
+ # Search nodes
13
+ curl "http://localhost:4313/api/canvas/search?q=auth"
14
+
15
+ # Validate the current layout
16
+ curl http://localhost:4313/api/canvas/validate
17
+
18
+ # Inspect running-server schemas
19
+ curl http://localhost:4313/api/canvas/schema
20
+
21
+ # Validate a json-render spec without creating a node
22
+ curl -X POST http://localhost:4313/api/canvas/schema/validate \
23
+ -H "Content-Type: application/json" \
24
+ -d '{"type":"json-render","spec":{"root":"card","elements":{"card":{"type":"Card","props":{"title":"Preview"},"children":[]}}}}'
25
+ ```
26
+
27
+ ## Nodes
28
+
29
+ ```bash
30
+ # Add a node
31
+ curl -X POST http://localhost:4313/api/canvas/node \
32
+ -H "Content-Type: application/json" \
33
+ -d '{"type":"markdown","title":"Hello","content":"# World"}'
34
+
35
+ # Add an html node (sandboxed iframe)
36
+ curl -X POST http://localhost:4313/api/canvas/node \
37
+ -H "Content-Type: application/json" \
38
+ -d '{"type":"html","title":"Chart","html":"<canvas id=\"c\"></canvas><script src=\"https://cdn.jsdelivr.net/npm/chart.js\"></script><script>/* ... */</script>"}'
39
+ ```
40
+
41
+ ## Edges
42
+
43
+ ```bash
44
+ # Add an edge
45
+ curl -X POST http://localhost:4313/api/canvas/edge \
46
+ -H "Content-Type: application/json" \
47
+ -d '{"from":"node-1","to":"node-2","type":"flow","label":"next"}'
48
+
49
+ # Add an edge by unique search match instead of explicit IDs
50
+ curl -X POST http://localhost:4313/api/canvas/edge \
51
+ -H "Content-Type: application/json" \
52
+ -d '{"fromSearch":"DVT O3 — GitOps","toSearch":"deep work trend","type":"relation"}'
53
+ ```
54
+
55
+ Search-based edge creation is intentionally strict: `fromSearch` and
56
+ `toSearch` must each resolve to exactly one node. Broad queries that match
57
+ multiple nodes fail; use the full visible title.
58
+
59
+ ## Annotations
60
+
61
+ ```bash
62
+ # Add a freehand annotation. The default/currentColor stroke follows the active theme.
63
+ curl -X POST http://localhost:4313/api/canvas/annotation \
64
+ -H "Content-Type: application/json" \
65
+ -d '{"points":[{"x":100,"y":120},{"x":220,"y":120}],"color":"currentColor","width":4}'
66
+
67
+ # Remove an annotation
68
+ curl -X DELETE http://localhost:4313/api/canvas/annotation/ann-123
69
+ ```
70
+
71
+ Agent-readable context reports annotation IDs, targets, and bounds. Use WebView
72
+ inspection or screenshots when the drawn shape matters.
73
+
74
+ ## Pins
75
+
76
+ ```bash
77
+ # Pin nodes for agent context
78
+ curl -X POST http://localhost:4313/api/canvas/context-pins \
79
+ -H "Content-Type: application/json" \
80
+ -d '{"nodeIds":["node-1","node-2"]}'
81
+
82
+ # Get pinned context
83
+ curl http://localhost:4313/api/canvas/pinned-context
84
+ ```
85
+
86
+ ## Diagrams (Excalidraw preset)
87
+
88
+ ```bash
89
+ curl -X POST http://localhost:4313/api/canvas/diagram \
90
+ -H "Content-Type: application/json" \
91
+ -d '{"elements":[{"type":"rectangle","id":"r1","x":60,"y":60,"width":180,"height":80,"roundness":{"type":3},"backgroundColor":"#a5d8ff","fillStyle":"solid","label":{"text":"Hello","fontSize":18}}],"title":"Diagram"}'
92
+ ```
93
+
94
+ ## SSE event stream
95
+
96
+ ```bash
97
+ curl -N http://localhost:4313/api/workbench/events
98
+ ```
99
+
100
+ The browser, the CLI `watch` command, and the MCP resource notifications
101
+ all consume this stream. Auto-reconnect with exponential backoff.
102
+
103
+ ## Time travel
104
+
105
+ ```bash
106
+ curl -X POST http://localhost:4313/api/canvas/undo
107
+ curl -X POST http://localhost:4313/api/canvas/redo
108
+ curl http://localhost:4313/api/canvas/history
109
+ ```
110
+
111
+ ## WebView automation
112
+
113
+ ```bash
114
+ # Start WebView automation
115
+ curl -X POST http://localhost:4313/api/workbench/webview/start \
116
+ -H "Content-Type: application/json" \
117
+ -d '{"backend":"chrome","width":1280,"height":800}'
118
+
119
+ # Evaluate JS in the active WebView session
120
+ curl -X POST http://localhost:4313/api/workbench/webview/evaluate \
121
+ -H "Content-Type: application/json" \
122
+ -d '{"expression":"document.title"}'
123
+
124
+ # Resize the active WebView session
125
+ curl -X POST http://localhost:4313/api/workbench/webview/resize \
126
+ -H "Content-Type: application/json" \
127
+ -d '{"width":1440,"height":900}'
128
+
129
+ # Capture a screenshot
130
+ curl -X POST http://localhost:4313/api/workbench/webview/screenshot \
131
+ -H "Content-Type: application/json" \
132
+ -d '{"format":"png"}' \
133
+ --output canvas.png
134
+ ```
135
+
136
+ ## Batch operations
137
+
138
+ Build a canvas in one shot. Earlier results can be referenced from later
139
+ operations via `$assigned-name.field`.
140
+
141
+ ```bash
142
+ curl -X POST http://localhost:4313/api/canvas/batch \
143
+ -H "Content-Type: application/json" \
144
+ -d '{"operations":[{"op":"node.add","assign":"a","args":{"type":"markdown","title":"A"}},{"op":"group.create","args":{"title":"Frame","childIds":["$a.id"]}}]}'
145
+ ```
146
+
147
+ Supported operations:
148
+
149
+ - `node.add`, `node.update`
150
+ - `graph.add`
151
+ - `edge.add`
152
+ - `group.create`, `group.add`, `group.remove`
153
+ - `pin.set`, `pin.add`, `pin.remove`
154
+ - `snapshot.save`
155
+ - `arrange`
156
+
157
+ `node.add` supports `type: "webpage"` inside batch. The batch itself still
158
+ succeeds when the webpage node is created but the fetch fails; the
159
+ per-operation result includes `fetch: { ok, error? }` plus a top-level
160
+ `error` field for the fetch problem.
161
+
162
+ Example with assignments:
163
+
164
+ ```json
165
+ {
166
+ "operations": [
167
+ {
168
+ "op": "graph.add",
169
+ "assign": "wins",
170
+ "args": {
171
+ "title": "Major wins",
172
+ "graphType": "bar",
173
+ "data": [
174
+ { "label": "Docs", "value": 5 },
175
+ { "label": "Tests", "value": 8 }
176
+ ],
177
+ "xKey": "label",
178
+ "yKey": "value"
179
+ }
180
+ },
181
+ {
182
+ "op": "group.create",
183
+ "assign": "frame",
184
+ "args": {
185
+ "title": "Quarterly graphs",
186
+ "childIds": ["$wins.id"]
187
+ }
188
+ }
189
+ ]
190
+ }
191
+ ```
package/docs/mcp.md ADDED
@@ -0,0 +1,135 @@
1
+ # MCP reference
2
+
3
+ PMX Canvas ships an MCP stdio server with **41 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_diagram` | Hand-drawn diagram via the hosted Excalidraw MCP App (preset alias for `canvas_open_mcp_app`) |
32
+ | `canvas_open_mcp_app` | Open any [MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps) server's `ui://` resource as an iframe node |
33
+ | `canvas_describe_schema` | Describe the running server's create schemas, examples, and json-render catalog |
34
+ | `canvas_validate_spec` | Validate a json-render spec or graph payload without creating a node |
35
+ | `canvas_refresh_webpage_node` | Re-fetch and update a webpage node from its stored URL |
36
+ | `canvas_add_json_render_node` | Create a native json-render node from a validated spec |
37
+ | `canvas_add_graph_node` | Create a native graph node (line, bar, pie, area, scatter, radar, stacked-bar, composed) |
38
+ | `canvas_build_web_artifact` | Build a bundled HTML artifact and open it on the canvas |
39
+ | `canvas_update_node` | Update content, position, size, collapsed state |
40
+ | `canvas_remove_node` | Remove a node and its edges |
41
+ | `canvas_get_layout` | Get full canvas state |
42
+ | `canvas_get_node` | Get a single node by ID |
43
+ | `canvas_remove_annotation` | Remove a human-drawn annotation by ID |
44
+ | `canvas_add_edge` | Connect two nodes |
45
+ | `canvas_remove_edge` | Remove a connection |
46
+ | `canvas_arrange` | Auto-arrange (grid/column/flow) |
47
+ | `canvas_validate` | Validate collisions, containment, and missing edge endpoints |
48
+ | `canvas_focus_node` | Pan viewport to a node; use CLI `focus --no-pan` when you only need to select/raise |
49
+ | `canvas_pin_nodes` | Pin nodes to include in agent context |
50
+ | `canvas_clear` | Clear all nodes and edges |
51
+ | `canvas_snapshot` | Save current canvas as a named snapshot |
52
+ | `canvas_list_snapshots` | List saved snapshots, bounded to the newest 20 by default |
53
+ | `canvas_gc_snapshots` | Delete old snapshots while keeping the newest N |
54
+ | `canvas_restore` | Restore canvas from a saved snapshot |
55
+ | `canvas_delete_snapshot` | Delete a saved snapshot |
56
+ | `canvas_search` | Find nodes by title/content keywords |
57
+ | `canvas_undo` | Undo the last canvas mutation |
58
+ | `canvas_redo` | Redo the last undone mutation |
59
+ | `canvas_diff` | Compare current canvas vs a saved snapshot |
60
+ | `canvas_create_group` | Create a group containing specified nodes |
61
+ | `canvas_group_nodes` | Add nodes to an existing group |
62
+ | `canvas_ungroup` | Release all children from a group |
63
+ | `canvas_batch` | Run a batch of canvas operations with `$ref` support |
64
+ | `canvas_webview_status` | Get Bun.WebView automation status for the workbench |
65
+ | `canvas_webview_start` | Start or replace the Bun.WebView automation session |
66
+ | `canvas_webview_stop` | Stop the active Bun.WebView automation session |
67
+ | `canvas_evaluate` | Evaluate JavaScript in the active workbench automation session |
68
+ | `canvas_resize` | Resize the active workbench automation viewport |
69
+ | `canvas_screenshot` | Capture a screenshot from the active workbench automation session |
70
+
71
+ ## Resources
72
+
73
+ Individual bundled skills are also readable at `canvas://skills/<name>`.
74
+
75
+ | Resource | Description |
76
+ |----------|-------------|
77
+ | `canvas://pinned-context` | Content of pinned nodes + nearby unpinned neighbors |
78
+ | `canvas://schema` | Running-server create schemas and json-render catalog metadata |
79
+ | `canvas://layout` | Full canvas state (all nodes, edges, viewport) |
80
+ | `canvas://summary` | Compact overview: counts, pinned titles, viewport |
81
+ | `canvas://spatial-context` | Proximity clusters, reading order, pinned neighborhoods |
82
+ | `canvas://history` | Mutation history timeline with undo/redo position |
83
+ | `canvas://code-graph` | Auto-detected file dependency graph (JS/TS, Python, Go, Rust) |
84
+ | `canvas://skills` | Index of bundled agent skills + per-skill content at `canvas://skills/<name>` |
85
+
86
+ ## Change notifications
87
+
88
+ The MCP server emits `notifications/resources/updated` whenever canvas state
89
+ changes:
90
+
91
+ - Pin changes notify `canvas://pinned-context`
92
+ - All mutations notify `canvas://layout`, `canvas://summary`,
93
+ `canvas://spatial-context`, `canvas://history`, and `canvas://code-graph`
94
+
95
+ This closes the human-to-agent loop: spatial curation in the browser becomes
96
+ an immediate signal in the agent's context.
97
+
98
+ ## Annotation Visibility
99
+
100
+ Human-drawn canvas annotations are rendered as browser SVG ink. MCP resources
101
+ keep annotation context compact: agents see annotation counts, bounds, and target
102
+ summaries such as the node or empty canvas region that was marked, but not the
103
+ raw stroke geometry or visual shape.
104
+
105
+ Annotations are a browser-visible markup layer. Use the pen toolbar button to
106
+ draw and the eraser toolbar button to remove an annotation again; agents can also
107
+ remove a known annotation ID with `canvas_remove_annotation`.
108
+
109
+ Use WebView automation when an agent needs to actually see annotations as drawn.
110
+ For example, inspect `.annotation-layer path` with `canvas_evaluate` or capture a
111
+ `canvas_screenshot` to distinguish an arrow from a line, circle, or highlight.
112
+
113
+ ## Node-type routing
114
+
115
+ MCP node creation uses dedicated tools for structured node families. Read
116
+ `mcp.nodeTypeRouting` from `canvas_describe_schema` / `canvas://schema` when
117
+ in doubt:
118
+
119
+ - `json-render` → `canvas_add_json_render_node`
120
+ - `graph` → `canvas_add_graph_node`
121
+ - `html` → `canvas_add_html_node`
122
+ - `web-artifact` → `canvas_build_web_artifact`
123
+ - `mcp-app` → `canvas_open_mcp_app`
124
+ - `group` → `canvas_create_group`
125
+ - Basic nodes (`markdown`, `status`, `file`, `image`, `webpage`) →
126
+ `canvas_add_node`
127
+
128
+ ## CLI/MCP alignment
129
+
130
+ CLI and MCP are kept aligned for the main canvas operations: node and edge
131
+ creation, graph/json-render/html nodes, web artifacts, external apps, groups,
132
+ batch builds, layout validation, snapshots, search, focus, pins, undo/redo,
133
+ semantic watch streams, WebView automation, and daemon/server control where
134
+ it applies. A few agent-native capabilities — resource subscriptions and
135
+ `canvas_diff` — remain MCP-only.