pmx-canvas 0.1.1 → 0.1.3

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 (36) hide show
  1. package/CHANGELOG.md +131 -0
  2. package/Readme.md +35 -8
  3. package/dist/canvas/index.js +70 -70
  4. package/dist/types/client/nodes/ExtAppFrame.d.ts +13 -1
  5. package/dist/types/client/state/canvas-store.d.ts +2 -1
  6. package/dist/types/client/types.d.ts +3 -0
  7. package/dist/types/server/bundled-skills.d.ts +40 -0
  8. package/dist/types/server/diagram-presets.d.ts +13 -0
  9. package/dist/types/server/index.d.ts +6 -1
  10. package/dist/types/server/web-artifacts.d.ts +1 -0
  11. package/dist/types/shared/ext-app-tool-result.d.ts +12 -0
  12. package/package.json +2 -1
  13. package/skills/pmx-canvas/SKILL.md +26 -5
  14. package/skills/pmx-canvas/references/installing-pmx-canvas.md +66 -0
  15. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +10 -0
  16. package/skills/web-artifacts-builder/scripts/init-artifact.sh +1 -1
  17. package/src/cli/agent.ts +78 -7
  18. package/src/cli/index.ts +22 -2
  19. package/src/client/App.tsx +2 -1
  20. package/src/client/canvas/CanvasNode.tsx +3 -2
  21. package/src/client/canvas/ExpandedNodeOverlay.tsx +6 -1
  22. package/src/client/nodes/ExtAppFrame.tsx +183 -38
  23. package/src/client/state/canvas-store.ts +63 -1
  24. package/src/client/state/sse-bridge.ts +5 -0
  25. package/src/client/types.ts +12 -0
  26. package/src/mcp/server.ts +92 -6
  27. package/src/server/bundled-skills.ts +143 -0
  28. package/src/server/canvas-operations.ts +57 -8
  29. package/src/server/canvas-schema.ts +2 -1
  30. package/src/server/diagram-presets.ts +219 -4
  31. package/src/server/index.ts +22 -10
  32. package/src/server/server.ts +172 -45
  33. package/src/server/web-artifacts/scripts/bundle-artifact.sh +10 -0
  34. package/src/server/web-artifacts/scripts/init-artifact.sh +1 -1
  35. package/src/server/web-artifacts.ts +83 -3
  36. package/src/shared/ext-app-tool-result.ts +25 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,137 @@
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.3] - 2026-04-25
7
+
8
+ CLI hardening release with full MCP parity for the new affordances. Closes
9
+ gaps surfaced by the v0.1.2 fresh-install E2E (silent web-artifact failures,
10
+ generic `mcp-app` confusion, viewport-hijacking focus), persists Excalidraw
11
+ edits across iframe remounts, and ships a new `test:e2e-cli` coverage eval.
12
+
13
+ ### Added
14
+
15
+ - `pmx-canvas external-app add --kind excalidraw` for tool-backed Excalidraw
16
+ nodes, with optional `--elements-json` / `--elements-file` / position +
17
+ size flags.
18
+ - `pmx-canvas web-artifact build --deps <csv|json>` and matching HTTP
19
+ `deps?: string[]` for adding npm dependencies before bundling. Validated
20
+ against npm-name format; flags and shell metacharacters are rejected. The
21
+ web-artifact scaffold now bundles `recharts` by default.
22
+ **MCP:** `canvas_build_web_artifact` accepts `deps` for parity.
23
+ - `pmx-canvas focus <id> --no-pan` (and HTTP `noPan: true`) selects/raises
24
+ a node without moving the viewport. The HTTP response gains
25
+ `panned: boolean`; the SSE `canvas-focus-node` event payload gains
26
+ `noPan`. **MCP:** `canvas_focus_node` accepts `noPan` for parity. **SDK:**
27
+ `c.focusNode(id, { noPan? })` returns `{ focused, panned } | null`.
28
+ - `pmx-canvas node add --type graph --data <json>` as an alias for
29
+ `--data-json`.
30
+ - `bun run test:e2e-cli` (`scripts/e2e-cli-coverage.sh` +
31
+ `docs/evals/e2e-cli-coverage.md`) — fresh-workspace CLI coverage eval.
32
+ - `skills/pmx-canvas/references/installing-pmx-canvas.md` install reference
33
+ for first-run agents.
34
+
35
+ ### Changed
36
+
37
+ - `pmx-canvas node add --type mcp-app …` is now rejected with guidance
38
+ pointing at `web-artifact build` or `external-app add` instead of creating
39
+ an empty node.
40
+ - `pmx-canvas web-artifact build` exits non-zero with `ok: false` JSON on
41
+ bundle failure and does not create a canvas node.
42
+ - `pmx-canvas status` buckets hosted artifact `mcp-app` nodes under
43
+ `web-artifact`.
44
+ - Grid arrange spaces columns by the widest movable node so wide artifacts
45
+ do not overlap; `POST /api/canvas/arrange` returns `validation` +
46
+ `collisions` when the resulting layout has overlaps.
47
+
48
+ ### Fixed
49
+
50
+ - Excalidraw edits made in fullscreen are now persisted into a replayable
51
+ `toolResult` and survive iframe remounts
52
+ (`POST /api/ext-app/model-context`).
53
+ - Web-artifact builds fail loudly instead of emitting a zero-byte HTML when
54
+ Parcel/html-inline produce empty output (`bundle-artifact.sh` exits early
55
+ on missing/empty Parcel output).
56
+
57
+ ### Internal
58
+
59
+ - Web-artifact dep installer now uses `bash -c` instead of `bash -lc`, so
60
+ the user's login profile (`~/.bashrc`/`~/.zshrc`) cannot perturb installs.
61
+ - Removed the redundant post-copy bundle-size check (the script-side check
62
+ already guarantees a non-empty source; CLAUDE.md TypeScript Guardrail #3).
63
+ - New unit coverage in `cli-node`, `server-api`, `web-artifacts`, and
64
+ `canvas-operations` test suites.
65
+
66
+ [0.1.3]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.3
67
+
68
+ ## [0.1.2] - 2026-04-24
69
+
70
+ Follow-up to 0.1.1 driven by fresh-install review feedback. Two validation /
71
+ UX bugs, one long-tail stability fix in the MCP App host, plus new agent
72
+ ergonomics (version flag, skill discovery).
73
+
74
+ ### Added
75
+
76
+ - **`pmx-canvas --version` / `-v`.** Prints the installed package version and
77
+ exits. Version is read from the sibling `package.json` so it stays accurate
78
+ whether the CLI is invoked via `bunx`, a global npm install, or a repo-local
79
+ `bun run` — no hard-coded string, no build step required.
80
+ - **`canvas://skills` MCP resource.** Agent skills bundled with the npm install
81
+ (`skills/<name>/SKILL.md`) are now discoverable through MCP. The `canvas://skills`
82
+ resource returns a JSON index (name, description, per-skill URI), and each
83
+ skill is addressable individually at `canvas://skills/<name>`. The
84
+ `canvas_build_web_artifact` tool description now explicitly points agents at
85
+ `canvas://skills/web-artifacts-builder` for the full workflow, stack choices,
86
+ and anti-slop design guidelines.
87
+
88
+ ### Fixed
89
+
90
+ - **`image` node no longer accepts non-image file paths.** Creating an image
91
+ node with a path like `report.pptx` previously stored the path silently
92
+ with no `mimeType`; the server now rejects the request with a 400 and a
93
+ helpful message listing the accepted extensions (png, jpg, jpeg, gif, svg,
94
+ webp, bmp, avif, ico). `data:` URIs are validated against `image/*` media
95
+ types. Use `type="file"` or `type="webpage"` for non-image sources.
96
+ - **`web-artifact` init is more resilient on machines with tight process
97
+ limits.** `init-artifact.sh` and `bundle-artifact.sh` now spawn in their
98
+ own POSIX process group so timeouts and failures kill every descendant
99
+ (pnpm, bun, parcel, swc, lmdb) instead of leaving orphans that accumulate
100
+ FDs and eventually produce `fork: Resource temporarily unavailable`. pnpm's
101
+ internal child concurrency is capped to 2 via
102
+ `pnpm_config_child_concurrency` so the ~30-package shadcn install doesn't
103
+ blow past macOS's default `ulimit -u`. Failure responses now include the
104
+ last 20 lines of stderr (falling back to stdout) so the cause of an exit
105
+ code is visible directly in the API response rather than requiring a manual
106
+ re-run of the shell script.
107
+ - **MCP App (`mcp-app` / Excalidraw) state sync.** Edits saved by an MCP App
108
+ widget now propagate via SSE to other clients hosting the same app node
109
+ (fixes Excalidraw losing multi-client sync). The host also suppresses
110
+ echo-back re-renders when a layout update mints a new `toolResult`
111
+ reference with unchanged content — so a widget's own `callServerTool` call
112
+ no longer causes its UI to re-render mid-interaction.
113
+ - **MCP App inline-mode click safety.** The ext-app iframe in inline mode is
114
+ now covered by a transparent `ext-app-preview-catcher` overlay that opens
115
+ the fullscreen view on click, rather than letting stray canvas clicks
116
+ reach the widget. Agents / users interact with widgets in the expanded
117
+ overlay (via MCP tools or direct click); inline mode stays a safe
118
+ preview.
119
+
120
+ ### Internal
121
+
122
+ - New unit tests: `image` node validation (accepted extensions, URL + data
123
+ URI paths, rejected non-image extensions, rejected non-image data URIs)
124
+ and `canvas://skills` discovery (loader resolves the packaged skills
125
+ directory, index is stable-sorted, individual skill contents resolve,
126
+ unknown names return null).
127
+ - Shared `extAppToolResultsMatch` helper in `src/shared/ext-app-tool-result.ts`
128
+ for structural equality between `CallToolResult` values, used by the host
129
+ ExtAppFrame to dedupe SSE-delivered tool results.
130
+ - E2E: Counter-fixture test updated for the new expand-to-interact
131
+ interaction model (opens the `.ext-app-preview-catcher` overlay, finds
132
+ the iframe in `.expanded-overlay-panel`, force-clicks the in-widget button
133
+ to tolerate the widget's auto-resize settling).
134
+
135
+ [0.1.2]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.2
136
+
6
137
  ## [0.1.1] - 2026-04-24
7
138
 
8
139
  ### Changed
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
  ```