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.
- package/CHANGELOG.md +131 -0
- package/Readme.md +35 -8
- package/dist/canvas/index.js +70 -70
- package/dist/types/client/nodes/ExtAppFrame.d.ts +13 -1
- package/dist/types/client/state/canvas-store.d.ts +2 -1
- package/dist/types/client/types.d.ts +3 -0
- package/dist/types/server/bundled-skills.d.ts +40 -0
- package/dist/types/server/diagram-presets.d.ts +13 -0
- package/dist/types/server/index.d.ts +6 -1
- package/dist/types/server/web-artifacts.d.ts +1 -0
- package/dist/types/shared/ext-app-tool-result.d.ts +12 -0
- package/package.json +2 -1
- package/skills/pmx-canvas/SKILL.md +26 -5
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +66 -0
- package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +10 -0
- package/skills/web-artifacts-builder/scripts/init-artifact.sh +1 -1
- package/src/cli/agent.ts +78 -7
- package/src/cli/index.ts +22 -2
- package/src/client/App.tsx +2 -1
- package/src/client/canvas/CanvasNode.tsx +3 -2
- package/src/client/canvas/ExpandedNodeOverlay.tsx +6 -1
- package/src/client/nodes/ExtAppFrame.tsx +183 -38
- package/src/client/state/canvas-store.ts +63 -1
- package/src/client/state/sse-bridge.ts +5 -0
- package/src/client/types.ts +12 -0
- package/src/mcp/server.ts +92 -6
- package/src/server/bundled-skills.ts +143 -0
- package/src/server/canvas-operations.ts +57 -8
- package/src/server/canvas-schema.ts +2 -1
- package/src/server/diagram-presets.ts +219 -4
- package/src/server/index.ts +22 -10
- package/src/server/server.ts +172 -45
- package/src/server/web-artifacts/scripts/bundle-artifact.sh +10 -0
- package/src/server/web-artifacts/scripts/init-artifact.sh +1 -1
- package/src/server/web-artifacts.ts +83 -3
- 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` |
|
|
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
|
|
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:
|
|
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
|
```
|