pmx-canvas 0.1.2 → 0.1.4

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 (42) hide show
  1. package/CHANGELOG.md +144 -0
  2. package/Readme.md +35 -8
  3. package/dist/canvas/index.js +69 -69
  4. package/dist/json-render/index.css +1 -1
  5. package/dist/json-render/index.js +1 -1
  6. package/dist/types/client/nodes/ExtAppFrame.d.ts +12 -0
  7. package/dist/types/client/state/canvas-store.d.ts +2 -1
  8. package/dist/types/client/types.d.ts +3 -0
  9. package/dist/types/json-render/charts/components.d.ts +2 -1
  10. package/dist/types/server/canvas-serialization.d.ts +1 -0
  11. package/dist/types/server/diagram-presets.d.ts +13 -0
  12. package/dist/types/server/ext-app-lookup.d.ts +22 -0
  13. package/dist/types/server/index.d.ts +8 -1
  14. package/dist/types/server/web-artifacts.d.ts +1 -0
  15. package/package.json +2 -1
  16. package/skills/pmx-canvas/SKILL.md +35 -10
  17. package/skills/pmx-canvas/references/installing-pmx-canvas.md +66 -0
  18. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +10 -0
  19. package/skills/web-artifacts-builder/scripts/init-artifact.sh +1 -1
  20. package/src/cli/agent.ts +114 -21
  21. package/src/cli/index.ts +3 -1
  22. package/src/client/App.tsx +2 -1
  23. package/src/client/canvas/CanvasNode.tsx +3 -2
  24. package/src/client/canvas/ExpandedNodeOverlay.tsx +6 -1
  25. package/src/client/nodes/ExtAppFrame.tsx +97 -26
  26. package/src/client/state/canvas-store.ts +63 -1
  27. package/src/client/state/sse-bridge.ts +19 -4
  28. package/src/client/types.ts +12 -0
  29. package/src/json-render/charts/components.tsx +6 -4
  30. package/src/json-render/charts/extra-components.tsx +5 -5
  31. package/src/json-render/renderer/index.css +14 -0
  32. package/src/mcp/server.ts +44 -5
  33. package/src/server/canvas-operations.ts +43 -5
  34. package/src/server/canvas-schema.ts +16 -14
  35. package/src/server/canvas-serialization.ts +19 -1
  36. package/src/server/diagram-presets.ts +219 -4
  37. package/src/server/ext-app-lookup.ts +49 -0
  38. package/src/server/index.ts +33 -25
  39. package/src/server/server.ts +199 -45
  40. package/src/server/web-artifacts/scripts/bundle-artifact.sh +10 -0
  41. package/src/server/web-artifacts/scripts/init-artifact.sh +1 -1
  42. package/src/server/web-artifacts.ts +44 -1
package/CHANGELOG.md CHANGED
@@ -3,6 +3,150 @@
3
3
  All notable changes to `pmx-canvas` are documented here. This project follows
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
+ ## [0.1.4] - 2026-04-26
7
+
8
+ Graph/CLI ergonomics + canvas-node taxonomy hardening. Three threads:
9
+ (1) full graph payload surface (`zKey`, `axisKey`, `metrics`, `series`,
10
+ `barKey`/`lineKey`, `barColor`/`lineColor`) reaches CLI/MCP/HTTP/batch with
11
+ both kebab-case and camelCase flag aliases, (2) `mcp-app` nodes serialize a
12
+ `kind` discriminator so agents can target `web-artifact` / `external-app` /
13
+ `mcp-app` subtypes without inspecting `data`, (3) the long-standing
14
+ `ext-app-ext-app-…` double-prefix bug on node IDs is fixed with explicit
15
+ `nodeId` propagation through SSE.
16
+
17
+ ### Added
18
+
19
+ - Serialized `kind` discriminator on every canvas node. `mcp-app` nodes now
20
+ surface as `web-artifact`, `external-app`, or `mcp-app` so agents can
21
+ filter via `node list --type web-artifact` or
22
+ `--type external-app` directly.
23
+ - Full graph payload surface on MCP, HTTP `validate-spec`, and `batch`:
24
+ `zKey`, `axisKey`, `metrics`, `series`, `barKey`, `lineKey`, `barColor`,
25
+ `lineColor`. Radar (`metrics`), stacked-bar (`series`), and composed
26
+ (`barKey`/`lineKey`) configs are now uniformly addressable.
27
+ - CLI camelCase aliases for graph flags: `--graphType`, `--xKey`, `--yKey`,
28
+ `--zKey`, `--axisKey`, `--barKey`, `--lineKey`, `--barColor`,
29
+ `--lineColor`, alongside existing kebab-case forms. Same fields land in
30
+ `canvas_validate_spec` and `canvas_batch`.
31
+ - `id` field on `external-app add` / `canvas_open_mcp_app` /
32
+ `canvas_add_diagram` responses (alias for the canvas node ID, matches
33
+ HTTP).
34
+ - `viewerType: 'web-artifact'` persisted on web-artifact mcp-app nodes for
35
+ authoritative `kind` classification.
36
+
37
+ ### Changed
38
+
39
+ - `SerializedCanvasNode` now includes `kind: string` (additive; consumers
40
+ grouping by `type === 'mcp-app'` should switch to `kind`).
41
+ - `canvas://summary` `typeCounts` keys are derived from `kind`, not `type` —
42
+ `mcp-app` totals split into `web-artifact` / `external-app` / `mcp-app`.
43
+ - Charts wrap with type-specific CSS modifier classes
44
+ (`pmx-chart--line/--bar/--pie/--area/--scatter/--radar/--stacked-bar/--composed`)
45
+ and per-type minimum widths, so axes don't clip in narrow nodes.
46
+ - `canvas-schema.ts` cleanup based on the v0.1.4 review:
47
+ - `nodeHeight` no longer aliases `height` (collision with the chart-content
48
+ `height` field). Use `--node-height` going forward; `--height` always
49
+ means chart content height.
50
+ - `stdin` removed from the `data` and `appTsx` aliases — `--stdin` is an
51
+ input-mode (read from pipe), not a flag synonym. Behavior unchanged;
52
+ schema is now accurate.
53
+
54
+ ### Fixed
55
+
56
+ - Excalidraw / external-app node IDs no longer double-prefix to
57
+ `ext-app-ext-app-…`. The canvas node ID retains the `ext-app-` prefix; the
58
+ `toolCallId` is the random suffix only.
59
+ - SSE `ext-app-open` / `ext-app-update` / `ext-app-result` events now carry
60
+ an explicit `nodeId` so the client and server agree on node identity even
61
+ after the ID-format change.
62
+ - `getCanvasNodeKind` precedence reordered so a future URL-only web-artifact
63
+ (no `data.path`) still classifies correctly via `viewerType`. The legacy
64
+ `hostMode + path` heuristic is now an explicitly-documented backwards-compat
65
+ fallback for canvas state.json files persisted before v0.1.4.
66
+
67
+ ### Internal
68
+
69
+ - `findCanvasExtAppNodeId` extracted into `src/server/ext-app-lookup.ts` and
70
+ shared between `src/server/index.ts` and `src/server/server.ts` (was
71
+ duplicated; drift risk eliminated).
72
+ - `shouldReplayAppToolResult` documented with explicit intent: only `isError`
73
+ or `structuredContent` results overwrite the bootstrap-replay
74
+ `toolResult`, so a plain-text `read_checkpoint`-style return doesn't
75
+ clobber widget state on reload.
76
+ - E2E coverage now exercises camelCase graph flags and asserts the
77
+ single-prefix node-ID fix.
78
+ - New unit coverage:
79
+ - `kind` discriminator across fresh, URL-only, legacy, ext-app, and
80
+ plain-mcp-app paths (6 tests).
81
+ - Camel-case graph flags in CLI.
82
+ - Full-surface graph validation in MCP `canvas_validate_spec`.
83
+ - Single-prefix node-ID round-trip in `external-app add`.
84
+ - Post-restart text-tool replay semantics.
85
+
86
+ [0.1.4]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.4
87
+
88
+ ## [0.1.3] - 2026-04-25
89
+
90
+ CLI hardening release with full MCP parity for the new affordances. Closes
91
+ gaps surfaced by the v0.1.2 fresh-install E2E (silent web-artifact failures,
92
+ generic `mcp-app` confusion, viewport-hijacking focus), persists Excalidraw
93
+ edits across iframe remounts, and ships a new `test:e2e-cli` coverage eval.
94
+
95
+ ### Added
96
+
97
+ - `pmx-canvas external-app add --kind excalidraw` for tool-backed Excalidraw
98
+ nodes, with optional `--elements-json` / `--elements-file` / position +
99
+ size flags.
100
+ - `pmx-canvas web-artifact build --deps <csv|json>` and matching HTTP
101
+ `deps?: string[]` for adding npm dependencies before bundling. Validated
102
+ against npm-name format; flags and shell metacharacters are rejected. The
103
+ web-artifact scaffold now bundles `recharts` by default.
104
+ **MCP:** `canvas_build_web_artifact` accepts `deps` for parity.
105
+ - `pmx-canvas focus <id> --no-pan` (and HTTP `noPan: true`) selects/raises
106
+ a node without moving the viewport. The HTTP response gains
107
+ `panned: boolean`; the SSE `canvas-focus-node` event payload gains
108
+ `noPan`. **MCP:** `canvas_focus_node` accepts `noPan` for parity. **SDK:**
109
+ `c.focusNode(id, { noPan? })` returns `{ focused, panned } | null`.
110
+ - `pmx-canvas node add --type graph --data <json>` as an alias for
111
+ `--data-json`.
112
+ - `bun run test:e2e-cli` (`scripts/e2e-cli-coverage.sh` +
113
+ `docs/evals/e2e-cli-coverage.md`) — fresh-workspace CLI coverage eval.
114
+ - `skills/pmx-canvas/references/installing-pmx-canvas.md` install reference
115
+ for first-run agents.
116
+
117
+ ### Changed
118
+
119
+ - `pmx-canvas node add --type mcp-app …` is now rejected with guidance
120
+ pointing at `web-artifact build` or `external-app add` instead of creating
121
+ an empty node.
122
+ - `pmx-canvas web-artifact build` exits non-zero with `ok: false` JSON on
123
+ bundle failure and does not create a canvas node.
124
+ - `pmx-canvas status` buckets hosted artifact `mcp-app` nodes under
125
+ `web-artifact`.
126
+ - Grid arrange spaces columns by the widest movable node so wide artifacts
127
+ do not overlap; `POST /api/canvas/arrange` returns `validation` +
128
+ `collisions` when the resulting layout has overlaps.
129
+
130
+ ### Fixed
131
+
132
+ - Excalidraw edits made in fullscreen are now persisted into a replayable
133
+ `toolResult` and survive iframe remounts
134
+ (`POST /api/ext-app/model-context`).
135
+ - Web-artifact builds fail loudly instead of emitting a zero-byte HTML when
136
+ Parcel/html-inline produce empty output (`bundle-artifact.sh` exits early
137
+ on missing/empty Parcel output).
138
+
139
+ ### Internal
140
+
141
+ - Web-artifact dep installer now uses `bash -c` instead of `bash -lc`, so
142
+ the user's login profile (`~/.bashrc`/`~/.zshrc`) cannot perturb installs.
143
+ - Removed the redundant post-copy bundle-size check (the script-side check
144
+ already guarantees a non-empty source; CLAUDE.md TypeScript Guardrail #3).
145
+ - New unit coverage in `cli-node`, `server-api`, `web-artifacts`, and
146
+ `canvas-operations` test suites.
147
+
148
+ [0.1.3]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.3
149
+
6
150
  ## [0.1.2] - 2026-04-24
7
151
 
8
152
  Follow-up to 0.1.1 driven by fresh-install review feedback. Two validation /
package/Readme.md CHANGED
@@ -28,6 +28,7 @@ The published SDK entrypoint is Bun-first: `import { createCanvas } from 'pmx-ca
28
28
 
29
29
  ```bash
30
30
  bunx pmx-canvas # Start canvas, open browser
31
+ bunx pmx-canvas serve --daemon --no-open --wait-ms=20000
31
32
  bunx pmx-canvas --demo # Start with sample nodes
32
33
  bunx pmx-canvas --mcp # Run as MCP server
33
34
  ```
@@ -143,9 +144,9 @@ The canvas auto-starts on first tool call. Works with Claude Code, Cursor, Winds
143
144
  | `file` | Live file viewer with auto-update on disk changes |
144
145
  | `image` | Image viewer (file paths, data URIs, URLs) |
145
146
  | `webpage` | Persisted webpage snapshot with stored URL, extracted text, and refresh support |
146
- | `mcp-app` | Hosted MCP app iframes (Excalidraw, Chart.js, etc.) -- see [MCP app nodes](#mcp-app-nodes) |
147
+ | `mcp-app` | Tool-backed hosted MCP app iframes (Excalidraw, web artifacts, etc.) -- see [MCP app nodes](#mcp-app-nodes) |
147
148
  | `json-render` | Structured UI from JSON specs |
148
- | `graph` | Line, bar, and pie charts |
149
+ | `graph` | Line, bar, pie, area, scatter, radar, stacked-bar, and composed charts |
149
150
  | `group` | Spatial container/frame that contains other nodes |
150
151
 
151
152
  Thread node types `prompt` and `response` are used internally for agent conversation
@@ -185,6 +186,10 @@ canvas_refresh_webpage_node({ id: 'node-abc123' })
185
186
  sandboxed iframes. Any server that implements the [MCP Apps extension](https://modelcontextprotocol.io/docs/extensions/apps)
186
187
  can be opened as a node with `canvas_open_mcp_app`.
187
188
 
189
+ Generic `pmx-canvas node add --type mcp-app` is intentionally rejected because these nodes need
190
+ tool/session metadata. Use `pmx-canvas web-artifact build` for bundled React artifacts or
191
+ `pmx-canvas external-app add --kind excalidraw` for the Excalidraw preset.
192
+
188
193
  #### Recommended: Excalidraw (hand-drawn diagrams)
189
194
 
190
195
  [Excalidraw](https://github.com/excalidraw/excalidraw-mcp) ships a hosted MCP server at
@@ -196,6 +201,10 @@ supports fullscreen editing when you want to expand it into a larger workspace.
196
201
  PMX Canvas ships a preset so an agent can open an Excalidraw diagram in one call, without wiring
197
202
  the transport by hand:
198
203
 
204
+ ```bash
205
+ pmx-canvas external-app add --kind excalidraw --title "Agent to Canvas"
206
+ ```
207
+
199
208
  ```typescript
200
209
  canvas_add_diagram({
201
210
  elements: [
@@ -229,7 +238,8 @@ canvas_open_mcp_app({
229
238
 
230
239
  The canvas runs the tool against the remote MCP server, renders the returned `ui://` resource in
231
240
  a sandboxed iframe node, and keeps the resource's CSP + permission hints intact. Resize, drag,
232
- and pin the node like any other canvas node.
241
+ and pin the node like any other canvas node. Edits made in expanded/fullscreen mode are persisted
242
+ back into the node model context and replayed when the iframe remounts.
233
243
 
234
244
  ### Json-render nodes
235
245
 
@@ -266,9 +276,13 @@ self-contained HTML to `.pmx-canvas/artifacts/<slug>.html`, and (by default) ope
266
276
 
267
277
  ```bash
268
278
  pmx-canvas node add --type web-artifact --title "Dashboard" --app-file ./App.tsx
269
- pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --include-logs
279
+ pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --deps recharts --include-logs
270
280
  ```
271
281
 
282
+ The scaffold includes `recharts` for chart-heavy artifacts. Pass `--deps name,name2` for any
283
+ additional package dependencies before bundling. Failed or empty CLI bundles print `ok: false`,
284
+ exit non-zero, and do not create a canvas node.
285
+
272
286
  The matching agent skill is at [skills/web-artifacts-builder/SKILL.md](skills/web-artifacts-builder/SKILL.md).
273
287
 
274
288
  ### Groups
@@ -494,7 +508,7 @@ layout validation, graph/json-render nodes, group control, snapshots, and search
494
508
  | `canvas_validate_spec` | Validate a json-render spec or graph payload without creating a node |
495
509
  | `canvas_refresh_webpage_node` | Re-fetch and update a webpage node from its stored URL |
496
510
  | `canvas_add_json_render_node` | Create a native json-render node from a validated spec |
497
- | `canvas_add_graph_node` | Create a native graph node (line, bar, pie) |
511
+ | `canvas_add_graph_node` | Create a native graph node (line, bar, pie, area, scatter, radar, stacked-bar, composed) |
498
512
  | `canvas_build_web_artifact` | Build a bundled HTML artifact and open it on the canvas |
499
513
  | `canvas_update_node` | Update content, position, size, collapsed state |
500
514
  | `canvas_remove_node` | Remove a node and its edges |
@@ -504,7 +518,7 @@ layout validation, graph/json-render nodes, group control, snapshots, and search
504
518
  | `canvas_remove_edge` | Remove a connection |
505
519
  | `canvas_arrange` | Auto-arrange (grid/column/flow) |
506
520
  | `canvas_validate` | Validate collisions, containment, and missing edge endpoints |
507
- | `canvas_focus_node` | Pan viewport to a node |
521
+ | `canvas_focus_node` | Pan viewport to a node; use CLI `focus --no-pan` when you only need to select/raise |
508
522
  | `canvas_pin_nodes` | Pin nodes to include in agent context |
509
523
  | `canvas_clear` | Clear all nodes and edges |
510
524
  | `canvas_snapshot` | Save current canvas as a named snapshot |
@@ -706,6 +720,9 @@ await canvas.stopAutomationWebView();
706
720
 
707
721
  The CLI is the equally recommended shell-native way to run and control PMX Canvas.
708
722
 
723
+ The CLI targets `http://localhost:4313` by default. Override with `PMX_CANVAS_URL` or
724
+ `PMX_CANVAS_PORT` when the server runs elsewhere.
725
+
709
726
  ```bash
710
727
  pmx-canvas # Start canvas, open browser
711
728
  pmx-canvas --demo # Start with sample nodes
@@ -721,13 +738,16 @@ pmx-canvas open # Open the current workbench in a browser
721
738
  pmx-canvas node add --type webpage --url https://example.com/docs
722
739
  pmx-canvas node add --type web-artifact --title "Dashboard" --app-file ./App.tsx
723
740
  pmx-canvas node add --help --type webpage --json
741
+ pmx-canvas external-app add --kind excalidraw --title "Diagram"
724
742
  pmx-canvas node add --type graph --graph-type bar --data-file ./metrics.json --x-key label --y-key value
743
+ pmx-canvas node add --type graph --graph-type bar --data '[{"x":"a","y":1}]' --x-key x --y-key y
725
744
  pmx-canvas node schema --type json-render --component Table --summary
726
745
  pmx-canvas edge add --from-search "DVT O3 — GitOps" --to-search "deep work trend" --type relation
727
746
  pmx-canvas batch --file ./canvas-ops.json
728
747
  pmx-canvas validate
748
+ pmx-canvas focus <node-id> --no-pan
729
749
  pmx-canvas validate spec --type json-render --spec-file ./dashboard.json --summary
730
- pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --include-logs
750
+ pmx-canvas web-artifact build --title "Dashboard" --app-file ./App.tsx --deps recharts --include-logs
731
751
  pmx-canvas webview status # Show WebView automation status
732
752
  pmx-canvas webview start --backend chrome --width 1440 --height 900
733
753
  pmx-canvas webview evaluate --expression "document.title"
@@ -808,9 +828,15 @@ bun run dev:portless:demo # Same, with demo nodes
808
828
  bun run test # Unit tests
809
829
  bun run test:coverage # Unit tests with text summary + coverage/lcov.info
810
830
  bun run test:e2e # Playwright end-to-end tests
811
- bun run test:all # All tests
831
+ bun run test:e2e-cli # Fresh-workspace CLI coverage eval
832
+ bun run test:all # Unit tests + browser smoke
812
833
  ```
813
834
 
835
+ `bun run test:e2e-cli` starts a local server in a fresh temp workspace and verifies the CLI flows
836
+ from the durable eval in [docs/evals/e2e-cli-coverage.md](docs/evals/e2e-cli-coverage.md):
837
+ parseable JSON, node creation, graph `--data`, web-artifact failure handling, Excalidraw external
838
+ apps, `focus --no-pan`, arrange/validate, and status subtype reporting.
839
+
814
840
  ## Release
815
841
 
816
842
  Use this sequence before publishing a new version:
@@ -818,6 +844,7 @@ Use this sequence before publishing a new version:
818
844
  ```bash
819
845
  bun install --frozen-lockfile
820
846
  bun run release:check
847
+ bun run test:e2e-cli
821
848
  bun run release:smoke
822
849
  bun run pack:dry-run
823
850
  ```