pmx-canvas 0.2.7 → 0.3.1
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 +148 -1
- package/Readme.md +13 -11
- package/dist/canvas/index.js +2 -2
- package/dist/json-render/index.css +1 -1
- package/dist/types/cli/daemon.d.ts +74 -0
- package/dist/types/cli/watch.d.ts +2 -2
- package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
- package/dist/types/client/canvas/CommandPalette.d.ts +1 -1
- package/dist/types/client/canvas/Minimap.d.ts +1 -1
- package/dist/types/client/nodes/FileNode.d.ts +1 -1
- package/dist/types/client/nodes/ImageNode.d.ts +1 -1
- package/dist/types/client/nodes/InlineFormatBar.d.ts +1 -1
- package/dist/types/client/nodes/MarkdownNode.d.ts +1 -1
- package/dist/types/client/nodes/PromptNode.d.ts +1 -1
- package/dist/types/client/nodes/ResponseNode.d.ts +1 -1
- package/dist/types/mcp/canvas-access.d.ts +0 -7
- package/dist/types/server/ax-state-manager.d.ts +3 -2
- package/dist/types/server/bundled-skills.d.ts +3 -3
- package/dist/types/server/canvas-schema.d.ts +1 -1
- package/dist/types/server/canvas-state.d.ts +2 -0
- package/dist/types/server/ext-app-lookup.d.ts +1 -3
- package/dist/types/server/html-primitives.d.ts +1 -1
- package/dist/types/server/index.d.ts +4 -4
- package/dist/types/server/operations/composites.d.ts +29 -23
- package/dist/types/server/operations/http.d.ts +2 -1
- package/dist/types/server/operations/index.d.ts +1 -1
- package/dist/types/server/operations/ops/ax-read.d.ts +2 -0
- package/dist/types/server/operations/ops/canvas-wire.d.ts +2 -0
- package/dist/types/server/operations/ops/ext-app.d.ts +2 -0
- package/dist/types/shared/ax-intent.d.ts +1 -1
- package/docs/RELEASE.md +23 -8
- package/docs/ax-host-adapter-contract.md +7 -7
- package/docs/ax-state-contract.md +7 -6
- package/docs/bun-webview-integration.md +5 -5
- package/docs/cli.md +1 -1
- package/docs/http-api.md +35 -3
- package/docs/mcp.md +121 -100
- package/docs/node-types.md +45 -35
- package/docs/plans/plan-006-mcp-tool-consolidation.md +3 -1
- package/docs/plans/plan-008-registry-finish.md +2 -0
- package/docs/plans/plan-009-tech-debt-backlog.md +51 -0
- package/docs/screenshot.png +0 -0
- package/docs/tech-debt-assessment-2026-06.md +1 -1
- package/docs/tech-debt-assessment-2026-07.md +135 -0
- package/package.json +5 -2
- package/skills/data-analysis/SKILL.md +3 -3
- package/skills/frontend-design/SKILL.md +3 -2
- package/skills/json-render-mcp/SKILL.md +4 -3
- package/skills/playwright-cli/SKILL.md +1 -1
- package/skills/pmx-canvas/SKILL.md +12 -7
- package/skills/pmx-canvas/evals/evals.json +2 -2
- package/skills/pmx-canvas/references/ax-html-control-surface.md +3 -1
- package/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +2 -2
- package/skills/pmx-canvas/references/full-reference.md +58 -56
- package/skills/pmx-canvas/references/html-primitives.md +3 -3
- package/skills/tufte-viz/SKILL.md +5 -4
- package/skills/web-artifacts-builder/SKILL.md +4 -4
- package/src/cli/agent.ts +1861 -1548
- package/src/cli/daemon.ts +460 -0
- package/src/cli/index.ts +63 -326
- package/src/cli/watch.ts +2 -10
- package/src/client/App.tsx +48 -46
- package/src/client/canvas/AttentionHistory.tsx +11 -1
- package/src/client/canvas/CanvasNode.tsx +41 -29
- package/src/client/canvas/CanvasViewport.tsx +101 -66
- package/src/client/canvas/CommandPalette.tsx +61 -27
- package/src/client/canvas/ContextMenu.tsx +13 -20
- package/src/client/canvas/ContextPinBar.tsx +1 -5
- package/src/client/canvas/ContextPinHud.tsx +1 -6
- package/src/client/canvas/DockedNode.tsx +4 -4
- package/src/client/canvas/EdgeLayer.tsx +37 -36
- package/src/client/canvas/ExpandedNodeOverlay.tsx +69 -45
- package/src/client/canvas/FocusFieldLayer.tsx +20 -22
- package/src/client/canvas/IntentLayer.tsx +31 -14
- package/src/client/canvas/Minimap.tsx +11 -16
- package/src/client/canvas/SelectionBar.tsx +4 -11
- package/src/client/canvas/ShortcutOverlay.tsx +3 -1
- package/src/client/canvas/SnapshotPanel.tsx +77 -95
- package/src/client/canvas/auto-fit.ts +15 -14
- package/src/client/canvas/snap-guides.ts +12 -12
- package/src/client/canvas/use-node-resize.ts +1 -5
- package/src/client/canvas/use-pan-zoom.ts +25 -26
- package/src/client/ext-app/bridge.ts +3 -12
- package/src/client/icons.tsx +63 -20
- package/src/client/nodes/ContextNode.tsx +14 -25
- package/src/client/nodes/ExtAppFrame.tsx +60 -39
- package/src/client/nodes/FileNode.tsx +74 -62
- package/src/client/nodes/GroupNode.tsx +4 -6
- package/src/client/nodes/HtmlNode.tsx +76 -46
- package/src/client/nodes/ImageNode.tsx +18 -27
- package/src/client/nodes/InlineFormatBar.tsx +4 -21
- package/src/client/nodes/InlineMarkdownEditor.tsx +0 -1
- package/src/client/nodes/LedgerNode.tsx +10 -4
- package/src/client/nodes/MarkdownNode.tsx +3 -10
- package/src/client/nodes/McpAppNode.tsx +26 -22
- package/src/client/nodes/MdFormatBar.tsx +10 -7
- package/src/client/nodes/PromptNode.tsx +23 -51
- package/src/client/nodes/ResponseNode.tsx +3 -13
- package/src/client/nodes/StatusNode.tsx +5 -9
- package/src/client/nodes/StatusSummary.tsx +2 -8
- package/src/client/nodes/WebpageNode.tsx +20 -14
- package/src/client/nodes/iframe-document-url.ts +25 -16
- package/src/client/nodes/image-warnings.ts +1 -7
- package/src/client/nodes/md-format.ts +20 -5
- package/src/client/state/attention-bridge.ts +4 -9
- package/src/client/state/attention-store.ts +1 -7
- package/src/client/state/canvas-store.ts +52 -36
- package/src/client/state/intent-bridge.ts +176 -112
- package/src/client/state/intent-store.ts +4 -1
- package/src/client/state/sse-bridge.ts +53 -70
- package/src/json-render/catalog.ts +12 -16
- package/src/json-render/charts/components.tsx +16 -20
- package/src/json-render/charts/extra-components.tsx +8 -16
- package/src/json-render/charts/extra-definitions.ts +1 -2
- package/src/json-render/charts/tufte-components.tsx +37 -20
- package/src/json-render/charts/tufte-definitions.ts +8 -2
- package/src/json-render/renderer/index.tsx +42 -22
- package/src/json-render/schema.ts +6 -3
- package/src/json-render/server.ts +33 -39
- package/src/mcp/canvas-access.ts +40 -121
- package/src/mcp/server.ts +206 -271
- package/src/server/agent-context.ts +63 -36
- package/src/server/ax-context.ts +7 -5
- package/src/server/ax-interaction.ts +176 -43
- package/src/server/ax-state-manager.ts +185 -41
- package/src/server/ax-state.ts +142 -47
- package/src/server/bundled-skills.ts +3 -3
- package/src/server/canvas-db.ts +213 -95
- package/src/server/canvas-operations.ts +177 -120
- package/src/server/canvas-provenance.ts +1 -4
- package/src/server/canvas-schema.ts +500 -102
- package/src/server/canvas-serialization.ts +27 -35
- package/src/server/canvas-state.ts +155 -58
- package/src/server/chart-template.ts +4 -5
- package/src/server/code-graph.ts +20 -7
- package/src/server/diagram-presets.ts +28 -29
- package/src/server/ext-app-lookup.ts +4 -20
- package/src/server/html-node-summary.ts +19 -10
- package/src/server/html-primitives.ts +326 -97
- package/src/server/html-surface.ts +6 -9
- package/src/server/image-source.ts +6 -4
- package/src/server/index.ts +321 -218
- package/src/server/intent-registry.ts +3 -6
- package/src/server/mcp-app-candidate.ts +5 -10
- package/src/server/mcp-app-host.ts +14 -38
- package/src/server/mcp-app-runtime.ts +12 -20
- package/src/server/mutation-history.ts +15 -5
- package/src/server/operations/composites.ts +38 -40
- package/src/server/operations/http.ts +5 -5
- package/src/server/operations/index.ts +7 -1
- package/src/server/operations/invoker.ts +4 -3
- package/src/server/operations/mcp.ts +29 -36
- package/src/server/operations/ops/annotation.ts +122 -10
- package/src/server/operations/ops/app.ts +102 -77
- package/src/server/operations/ops/ax-await.ts +17 -10
- package/src/server/operations/ops/ax-read.ts +347 -0
- package/src/server/operations/ops/ax-shared.ts +2 -7
- package/src/server/operations/ops/ax-state.ts +32 -14
- package/src/server/operations/ops/ax-timeline.ts +32 -19
- package/src/server/operations/ops/ax-work.ts +54 -37
- package/src/server/operations/ops/batch.ts +39 -14
- package/src/server/operations/ops/canvas-wire.ts +91 -0
- package/src/server/operations/ops/edges.ts +37 -25
- package/src/server/operations/ops/ext-app.ts +346 -0
- package/src/server/operations/ops/groups.ts +49 -20
- package/src/server/operations/ops/intent.ts +18 -12
- package/src/server/operations/ops/json-render.ts +239 -98
- package/src/server/operations/ops/nodes.ts +300 -111
- package/src/server/operations/ops/query.ts +62 -33
- package/src/server/operations/ops/snapshots.ts +35 -26
- package/src/server/operations/ops/validate.ts +2 -1
- package/src/server/operations/ops/viewport.ts +60 -16
- package/src/server/operations/ops/webview.ts +44 -18
- package/src/server/operations/registry.ts +2 -3
- package/src/server/operations/types.ts +7 -5
- package/src/server/operations/webview-runner.ts +1 -3
- package/src/server/placement.ts +8 -18
- package/src/server/server.ts +121 -1012
- package/src/server/spatial-analysis.ts +39 -25
- package/src/server/trace-manager.ts +3 -8
- package/src/server/web-artifacts.ts +23 -27
- package/src/server/webpage-node.ts +5 -13
- package/src/shared/auto-arrange.ts +12 -5
- package/src/shared/ax-intent.ts +1 -1
- package/src/shared/content-height-reporter.ts +8 -6
- package/src/shared/ext-app-tool-result.ts +2 -6
- package/src/shared/placement.ts +1 -4
- package/src/shared/semantic-attention.ts +39 -37
- package/src/shared/surface.ts +8 -4
|
@@ -78,8 +78,7 @@ section below.
|
|
|
78
78
|
5. **Signal then mutate (default behavior)** — signal with `canvas_intent { action: "signal", … }`
|
|
79
79
|
to telegraph the move before nearly every mutation, then create with the right composite: `canvas_node` (markdown/status/file/webpage/html
|
|
80
80
|
incl. primitives), `canvas_render` (json-render/graph), `canvas_app` (mcp-app/diagram/
|
|
81
|
-
web-artifact).
|
|
82
|
-
v0.3).
|
|
81
|
+
web-artifact). Use composites — the legacy single-purpose tools were removed in v0.3.0.
|
|
83
82
|
6. **Arrange + validate** — `canvas_view { action: "arrange" }` after batch adds, then
|
|
84
83
|
`canvas_query { action: "validate" }` to catch collisions / dangling edges before finishing.
|
|
85
84
|
7. **Pin through a verified path** — `canvas_pin_nodes` (or the browser "Pin as context" /
|
|
@@ -152,8 +151,13 @@ pmx-canvas serve stop # Stop the daemon for thi
|
|
|
152
151
|
|
|
153
152
|
`serve --daemon` writes a pid file (`.pmx-canvas/daemon-<port>.pid`) and a log file
|
|
154
153
|
(`.pmx-canvas/daemon-<port>.log`); the wait flag blocks until `/health` returns OK so a script
|
|
155
|
-
can rely on the server being responsive when the command returns.
|
|
156
|
-
|
|
154
|
+
can rely on the server being responsive when the command returns. The pid file doubles as the
|
|
155
|
+
spawn lock and records the pid immediately, so a starting-but-not-yet-healthy daemon is already
|
|
156
|
+
addressable by `serve stop`, and a failed startup kills the child — no orphans. If the requested
|
|
157
|
+
port already serves a *different* workspace (or a non-canvas app), `serve --daemon` refuses with
|
|
158
|
+
the owner named and a hint to pick another port; it never reports a foreign daemon as "already
|
|
159
|
+
running". `serve stop` reads the pid file, verifies the pid still looks like a canvas daemon
|
|
160
|
+
(recycled pids read as stale), sends SIGTERM, and cleans up on exit.
|
|
157
161
|
|
|
158
162
|
### Verify workspace identity BEFORE mutating (required)
|
|
159
163
|
|
|
@@ -171,7 +175,9 @@ file, sends SIGTERM, and cleans up on exit.
|
|
|
171
175
|
3. **On mismatch, isolate**: start the intended workspace on an explicit free port —
|
|
172
176
|
`pmx-canvas serve --daemon --no-open --port=<free-port>` — and target that port. (`PMX_CANVAS_PORT`
|
|
173
177
|
alone may still attach to an existing `4313` listener; prefer an explicit `--port`.) Then
|
|
174
|
-
**re-read `/health`** to confirm the workspace now matches.
|
|
178
|
+
**re-read `/health`** to confirm the workspace now matches. `serve --daemon` also enforces
|
|
179
|
+
this itself: pointed at a port owned by another workspace, it exits with an error naming the
|
|
180
|
+
owner instead of attaching to it.
|
|
175
181
|
4. **MCP transport exception:** `pmx-canvas --mcp` launched from an incidental host dir may attach to
|
|
176
182
|
the healthy daemon already on the preferred port when no explicit workspace root is set, so writes
|
|
177
183
|
land in the visible workbench instead of a hidden fallback workspace. Host adapters should set
|
|
@@ -413,16 +419,15 @@ When you do set a color (group/graph), use this palette consistently to convey m
|
|
|
413
419
|
|
|
414
420
|
## MCP Tools Reference
|
|
415
421
|
|
|
416
|
-
PMX Canvas exposes **15 action-discriminated composites** (the recommended surface) plus a
|
|
422
|
+
PMX Canvas exposes **15 action-discriminated composites** (the whole recommended surface) plus a
|
|
417
423
|
set of first-class standalones. The composites fold the older
|
|
418
424
|
single-purpose tools behind an `action` (and, for `canvas_ax_gate`, a `kind`) discriminator —
|
|
419
425
|
**field names are unchanged**; only the tool name + the `action`/`kind` selector differ.
|
|
420
426
|
|
|
421
|
-
> **Legacy single-purpose tools
|
|
422
|
-
> `canvas_update_node`, `canvas_request_approval`, `canvas_add_work_item`, …)
|
|
423
|
-
>
|
|
424
|
-
>
|
|
425
|
-
> re-enumerate the deprecated names.
|
|
427
|
+
> **Legacy single-purpose tools were removed in v0.3.0.** The old names (`canvas_add_node`,
|
|
428
|
+
> `canvas_update_node`, `canvas_request_approval`, `canvas_add_work_item`, …) are no longer
|
|
429
|
+
> registered — use the composites instead. The authoritative legacy→composite mapping table lives
|
|
430
|
+
> in [`docs/mcp.md`](../../../docs/mcp.md) — this skill does not re-enumerate the removed names.
|
|
426
431
|
|
|
427
432
|
### The 15 composites
|
|
428
433
|
|
|
@@ -499,19 +504,19 @@ investigation board" intent, then run the batch with that linked `intentId` (use
|
|
|
499
504
|
### Standalones (first-class — not deprecated)
|
|
500
505
|
|
|
501
506
|
These stay separate by design (trust-boundary, firehose, execution-intent, or not-yet-consolidated
|
|
502
|
-
surfaces): `canvas_batch`, `canvas_pin_nodes`, `canvas_screenshot`,
|
|
503
|
-
`canvas_refresh_webpage_node`, `canvas_ax_interaction`,
|
|
507
|
+
surfaces): `canvas_batch`, `canvas_pin_nodes`, `canvas_screenshot`, `canvas_ax_interaction`,
|
|
504
508
|
`canvas_ingest_activity`, `canvas_invoke_command`, and the snapshot tools (`canvas_snapshot`,
|
|
505
509
|
`canvas_list_snapshots`, `canvas_restore`, `canvas_delete_snapshot`, `canvas_gc_snapshots`,
|
|
506
|
-
`canvas_diff` — a `canvas_snapshot` composite
|
|
510
|
+
`canvas_diff` — deprecated pending a `canvas_snapshot` composite in v0.4; the name collides with
|
|
511
|
+
the current save-snapshot tool, so the composite cannot land additively).
|
|
507
512
|
|
|
508
|
-
> **
|
|
509
|
-
> `Deprecated:` and are **removed in v0.3**): `canvas_open_mcp_app` / `canvas_add_diagram` /
|
|
513
|
+
> **Removed in v0.3.0 → use the composite instead**: `canvas_open_mcp_app` / `canvas_add_diagram` /
|
|
510
514
|
> `canvas_build_web_artifact` → **`canvas_app`**; `canvas_webview_start` / `canvas_webview_status` /
|
|
511
515
|
> `canvas_webview_stop` / `canvas_resize` / `canvas_evaluate` → **`canvas_webview`**;
|
|
512
516
|
> `canvas_add_html_node` / `canvas_add_html_primitive` → **`canvas_node { action:"add", type:"html" }`**
|
|
513
517
|
> (pass `primitive` for a primitive); `canvas_add_node` / `canvas_update_node` / `canvas_remove_node`
|
|
514
518
|
> → **`canvas_node`**; `canvas_remove_annotation` → **`canvas_view { action:"remove-annotation" }`**;
|
|
519
|
+
> `canvas_refresh_webpage_node` → **`canvas_node { action:"update", id, refresh: true }`**;
|
|
515
520
|
> `canvas_validate` (board collisions / containment / dangling edges) → **`canvas_query` `validate`**;
|
|
516
521
|
> `canvas_validate_spec` (json-render / graph spec dry-run) → **`canvas_render` `validate`**.
|
|
517
522
|
|
|
@@ -553,10 +558,10 @@ delete+recreate; preserves edges, pins, position)
|
|
|
553
558
|
|
|
554
559
|
**`canvas_node { action: "get", id }`** — Get a single node's full data by `id`.
|
|
555
560
|
|
|
556
|
-
**`
|
|
561
|
+
**`canvas_view { action: "remove-annotation", id }`** — Remove a human-drawn annotation by `id`. Use when
|
|
557
562
|
context gives you the annotation ID; use WebView first if you need to identify a mark by shape or location.
|
|
558
563
|
|
|
559
|
-
**`
|
|
564
|
+
**`canvas_node { action: "update", id, refresh: true }`** — Re-fetch the URL stored on a `webpage` node
|
|
560
565
|
- `id` (required): webpage node to refresh
|
|
561
566
|
- Optional `url`: replace the stored URL before refreshing (use when the human moved the page)
|
|
562
567
|
- Returns the refreshed node with updated `pageTitle` and cached extracted text
|
|
@@ -569,7 +574,7 @@ context gives you the annotation ID; use WebView first if you need to identify a
|
|
|
569
574
|
// → returns { id: 'node-abc' }
|
|
570
575
|
|
|
571
576
|
// …later, after the human reopens the canvas…
|
|
572
|
-
|
|
577
|
+
canvas_node({ action: 'update', id: 'node-abc', refresh: true })
|
|
573
578
|
// → re-fetches the URL, updates pageTitle + extracted text, keeps the node ID and position
|
|
574
579
|
```
|
|
575
580
|
|
|
@@ -621,7 +626,7 @@ the `tufte-viz` skill (`skills/tufte-viz/SKILL.md`). Key rules:
|
|
|
621
626
|
- For more than ~4 overlapping series, build small multiples (several small graph nodes on a shared
|
|
622
627
|
scale, arranged in a grid/group) instead of one multi-color chart.
|
|
623
628
|
|
|
624
|
-
**`
|
|
629
|
+
**`canvas_app { action: "build-artifact" }`** — Build and optionally open a bundled web artifact
|
|
625
630
|
- Required: `title`, `appTsx` (source string contents, not a file path)
|
|
626
631
|
- CLI `--app-file` reads a file before calling the same build path; MCP callers must pass the source contents
|
|
627
632
|
- Cold builds commonly take 45-60 seconds; use a long client timeout such as 300000 ms or more
|
|
@@ -631,7 +636,7 @@ ID extraction for mixed tool responses:
|
|
|
631
636
|
- Most add-style tools return a flat `id`; web artifacts return `id` plus `nodeId`; snapshots return `id` plus nested `snapshot.id`.
|
|
632
637
|
- Defensive extractor: `const getId = (r) => r.id ?? r.nodeId ?? r.snapshot?.id;`
|
|
633
638
|
|
|
634
|
-
**`
|
|
639
|
+
**`canvas_app { action: "open-mcp-app" }`** — Open a tool-backed external MCP app node
|
|
635
640
|
- Required: `toolName`, `transport`
|
|
636
641
|
- `transport` is either `{ type: "stdio", command, args?, cwd?, env? }` or `{ type: "http", url, headers? }`
|
|
637
642
|
- This is lower-level than `pmx-canvas external-app add --kind excalidraw`; use `canvas_app { action: "diagram" }` for the built-in Excalidraw preset
|
|
@@ -773,35 +778,31 @@ JavaScript inside the workbench page.
|
|
|
773
778
|
|
|
774
779
|
The WebView automation runs on Bun's WebKit-based WebView (macOS) or a headless
|
|
775
780
|
Chromium fallback (Linux). It does **not** open a visible window; it's an
|
|
776
|
-
additional headless renderer attached to the same canvas server, so
|
|
777
|
-
|
|
781
|
+
additional headless renderer attached to the same canvas server, so every action
|
|
782
|
+
below operates on the live canvas state through the `canvas_webview` composite.
|
|
778
783
|
|
|
779
|
-
|
|
780
|
-
> standalone tools below map to `canvas_webview { action: "status" | "start" | "stop" |
|
|
781
|
-
> "evaluate" | "resize" }` respectively. Field names are unchanged.
|
|
782
|
-
|
|
783
|
-
**`canvas_webview_status`** — Inspect the current automation session
|
|
784
|
+
**`canvas_webview { action: "status" }`** — Inspect the current automation session
|
|
784
785
|
- Returns `{ supported, active, headlessOnly, url, backend, width, height, dataStoreDir, startedAt, lastError }`
|
|
785
786
|
(the viewport size is `width` / `height`, not `viewportWidth` / `viewportHeight`)
|
|
786
787
|
- Call before `start` to check whether a session is already alive
|
|
787
788
|
|
|
788
|
-
**`
|
|
789
|
+
**`canvas_webview { action: "start" }`** — Start (or replace) the automation session
|
|
789
790
|
- Optional: `backend` (`webkit` macOS-only, or `chrome`), `width`, `height`
|
|
790
791
|
- The session opens `/workbench` at the canvas URL, waits for the SPA to
|
|
791
|
-
hydrate, and reports back via `
|
|
792
|
+
hydrate, and reports back via `canvas_webview { action: "status" }`
|
|
792
793
|
|
|
793
|
-
**`
|
|
794
|
+
**`canvas_webview { action: "stop" }`** — Tear down the automation session
|
|
794
795
|
|
|
795
|
-
**`
|
|
796
|
+
**`canvas_webview { action: "evaluate" }`** — Run JavaScript inside the workbench page and return the result
|
|
796
797
|
- Required: exactly one of `expression` (single JS expression) or `script` (multi-statement body)
|
|
797
798
|
- `script` is wrapped in an async IIFE, so top-level `await` works inside script bodies
|
|
798
799
|
- Useful for asserting DOM state after a sequence of canvas mutations
|
|
799
|
-
- Do not use `fetch()` inside `
|
|
800
|
-
restrictions can block those requests. Use the matching MCP tools instead.
|
|
800
|
+
- Do not use `fetch()` inside `canvas_webview { action: "evaluate" }` to call PMX HTTP APIs; WebView
|
|
801
|
+
security/CORS restrictions can block those requests. Use the matching MCP tools instead.
|
|
801
802
|
- Example: read the count of rendered `.canvas-node` elements:
|
|
802
803
|
|
|
803
804
|
```typescript
|
|
804
|
-
|
|
805
|
+
canvas_webview({ action: 'evaluate', expression: 'document.querySelectorAll(".canvas-node").length' })
|
|
805
806
|
```
|
|
806
807
|
|
|
807
808
|
Useful workbench selectors:
|
|
@@ -811,19 +812,20 @@ Useful workbench selectors:
|
|
|
811
812
|
to inspect or screenshot annotation shapes; MCP/context resources only expose compact
|
|
812
813
|
annotation target summaries, not the raw visual shape. Humans can remove marks with
|
|
813
814
|
the eraser toolbar button; agents can remove a known annotation ID with
|
|
814
|
-
`
|
|
815
|
+
`canvas_view { action: "remove-annotation" }`.
|
|
815
816
|
- Canvas chrome: `.hud-layer`, `.canvas-toolbar`, `.connection-dot`, `.canvas-bootstrap-card`
|
|
816
817
|
- Nodes do not expose stable `data-node-id` attributes. Use `canvas_query` (`layout` / `search`) or MCP resource data for exact node IDs.
|
|
817
818
|
|
|
818
819
|
Async script example:
|
|
819
820
|
|
|
820
821
|
```typescript
|
|
821
|
-
|
|
822
|
+
canvas_webview({
|
|
823
|
+
action: 'evaluate',
|
|
822
824
|
script: 'const title = await Promise.resolve(document.title); return title;',
|
|
823
825
|
})
|
|
824
826
|
```
|
|
825
827
|
|
|
826
|
-
**`
|
|
828
|
+
**`canvas_webview { action: "resize" }`** — Change the WebView viewport
|
|
827
829
|
- Required: `width`, `height`
|
|
828
830
|
- Use before `canvas_screenshot` when the human needs a specific aspect ratio
|
|
829
831
|
|
|
@@ -831,20 +833,20 @@ canvas_evaluate({
|
|
|
831
833
|
- Optional: `format` (`png` default), `fullPage` (boolean)
|
|
832
834
|
- Returns both an MCP image payload (renderable inline by capable agents) and
|
|
833
835
|
a path under `.pmx-canvas/screenshots/` so the human can view the file
|
|
834
|
-
- Pair with `
|
|
836
|
+
- Pair with `canvas_webview { action: "resize" }` to control the framing
|
|
835
837
|
|
|
836
838
|
Typical flow when you want to show a result:
|
|
837
839
|
|
|
838
840
|
```typescript
|
|
839
|
-
|
|
841
|
+
canvas_webview({ action: 'start', width: 1440, height: 900 });
|
|
840
842
|
// …mutations…
|
|
841
843
|
canvas_screenshot({ fullPage: true });
|
|
842
|
-
|
|
844
|
+
canvas_webview({ action: 'stop' });
|
|
843
845
|
```
|
|
844
846
|
|
|
845
847
|
### Diagrams (Excalidraw MCP app preset)
|
|
846
848
|
|
|
847
|
-
**`
|
|
849
|
+
**`canvas_app { action: "diagram" }`** — Draw a hand-drawn diagram on the canvas via the hosted
|
|
848
850
|
[Excalidraw MCP app](https://github.com/excalidraw/excalidraw-mcp)
|
|
849
851
|
- Required: `elements` — an array of Excalidraw elements (rectangles, ellipses, diamonds, arrows,
|
|
850
852
|
text). Can also be a JSON-array string.
|
|
@@ -868,7 +870,7 @@ canvas_webview_stop();
|
|
|
868
870
|
|
|
869
871
|
### External MCP apps (bring your own)
|
|
870
872
|
|
|
871
|
-
**`
|
|
873
|
+
**`canvas_app { action: "open-mcp-app" }`** — Open any external [MCP Apps](https://modelcontextprotocol.io/docs/extensions/apps)
|
|
872
874
|
server's `ui://` resource as an iframe node on the canvas
|
|
873
875
|
- Required: `toolName`, `transport` (`http` URL or `stdio` command)
|
|
874
876
|
- Optional: `serverName`, `toolArguments`, `title`, `x`, `y`, `width`, `height`
|
|
@@ -877,7 +879,7 @@ server's `ui://` resource as an iframe node on the canvas
|
|
|
877
879
|
|
|
878
880
|
### Web Artifacts
|
|
879
881
|
|
|
880
|
-
**`
|
|
882
|
+
**`canvas_app { action: "build-artifact" }`** — Build a single-file HTML artifact from React/Tailwind source
|
|
881
883
|
- Required: `title`, `appTsx`
|
|
882
884
|
- Optional: `indexCss`, `mainTsx`, `indexHtml`, extra `files`, `projectPath`, `outputPath`, `deps`, `includeLogs`
|
|
883
885
|
- By default it opens the result on the canvas as an embedded app node
|
|
@@ -891,7 +893,7 @@ server's `ui://` resource as an iframe node on the canvas
|
|
|
891
893
|
|
|
892
894
|
### HTML Nodes (Sandboxed iframe)
|
|
893
895
|
|
|
894
|
-
**`
|
|
896
|
+
**`canvas_node { action: "add", type: "html", html }`** — Add a normal self-contained HTML document rendered in a sandboxed iframe
|
|
895
897
|
- Required: `html` (full document or fragment; inline `<script>` and CDN `<script src="...">` are allowed). If `html` is a bare path to an existing local `.html`/`.htm` file, the server reads that file's contents; otherwise it is treated as raw HTML.
|
|
896
898
|
- Optional: `title`, `summary`, `agentSummary`, `presentation`, `slideTitles`, `embeddedNodeIds`, `embeddedUrls`, `x`, `y`, `width` (default 720), `height` (default 640), `strictSize`
|
|
897
899
|
- Iframe sandbox is `allow-scripts` only — no same-origin access, no top-navigation, no forms
|
|
@@ -901,7 +903,7 @@ server's `ui://` resource as an iframe node on the canvas
|
|
|
901
903
|
- Only presentation-marked HTML nodes expose a browser `Present` button. Use it when the HTML is a deck, briefing, or fullscreen review surface; the PMX shell owns the fullscreen overlay and exits via `Esc` or `Exit presentation`.
|
|
902
904
|
- PMX stores a semantic sidecar (`agentSummary`, `contentSummary`, embedded references) so HTML nodes remain understandable in search, pinned context, and spatial context
|
|
903
905
|
|
|
904
|
-
**`
|
|
906
|
+
**`canvas_node { action: "add", type: "html", primitive, data }`** — Generate a reusable HTML communication primitive as a sandboxed `html` node
|
|
905
907
|
- Required: `kind`; run `canvas_render { action: "describe-schema" }` and read `htmlPrimitives` for the current catalog
|
|
906
908
|
- Optional: `title`, `data`, `x`, `y`, `width`, `height`, `strictSize`
|
|
907
909
|
- Use when markdown would be too dense and a structured visual artifact is clearer: tradeoff grids, implementation plans, PR reviews, module maps, design sheets, explainers, reports, and lightweight human-editable boards/editors
|
|
@@ -961,7 +963,7 @@ Use native `json-render` and `graph` nodes when the output should stay fully ins
|
|
|
961
963
|
1. Use `canvas_render { action: "add-json-render" }` for dashboards, forms, summaries, and interactive UI panels
|
|
962
964
|
2. Use `canvas_render { action: "add-graph" }` for charts and trend visualizations
|
|
963
965
|
3. Use the repo-local `json-render-*` skills when you need help authoring or refining the spec itself
|
|
964
|
-
4. Use `
|
|
966
|
+
4. Use `canvas_app { action: "build-artifact" }` instead when the result needs a full custom React app rather than a schema-driven UI
|
|
965
967
|
|
|
966
968
|
Spec elements support an `on` map (`on.press`, `on.change`, …) binding events to actions (`{ action, params }`) — built-in actions (`setState`, `pushState`, …) or, when named after an AX interaction type, a capability-gated AX emit. e.g. a Button with `on: { press: { action: 'ax.work.create', params: { title: '…' } } }` lets a human turn a panel control into a tracked work item; the viewer forwards it to the canvas, which validates and submits it server-side (clamped to the node's own id). See **Node AX Interactions** above.
|
|
967
969
|
|
|
@@ -1107,9 +1109,9 @@ AX interactions are gated per node type. The lists below are each type's **ceili
|
|
|
1107
1109
|
| `group` | `ax.focus.set`, `ax.work.create`, `ax.command.invoke`, `ax.event.record` |
|
|
1108
1110
|
|
|
1109
1111
|
**Opt-in** — set `axCapabilities.enabled = true` (MCP: pass `axCapabilities` to
|
|
1110
|
-
`
|
|
1111
|
-
`html` body are accepted **top-level on both `POST /api/canvas/node`
|
|
1112
|
-
`PATCH /api/canvas/node/<id>`**, or nested under `data` — both work, top-level wins):
|
|
1112
|
+
`canvas_node { action: "add", type: "html" }` / `canvas_node { action: "update" }`. HTTP:
|
|
1113
|
+
`axCapabilities` **and** the `html` body are accepted **top-level on both `POST /api/canvas/node`
|
|
1114
|
+
and `PATCH /api/canvas/node/<id>`**, or nested under `data` — both work, top-level wins):
|
|
1113
1115
|
|
|
1114
1116
|
| Node type | Allowed AX interaction types |
|
|
1115
1117
|
|-----------|------------------------------|
|
|
@@ -1136,7 +1138,7 @@ inbox as a canvas node that BOTH emits AX interactions AND renders the current A
|
|
|
1136
1138
|
state. The read side mirrors the write side:
|
|
1137
1139
|
|
|
1138
1140
|
- **Opt in** (html/mcp-app are off by default): create with
|
|
1139
|
-
`
|
|
1141
|
+
`canvas_node({ action: "add", type: "html", html, axCapabilities: { enabled: true, allowed: ["ax.work.create","ax.work.update"] } })`,
|
|
1140
1142
|
or flip an existing node on with
|
|
1141
1143
|
`canvas_node({ action: "update", id, axCapabilities: { enabled: true, allowed: [...] } })`.
|
|
1142
1144
|
json-render / graph nodes are enabled by default.
|
|
@@ -1163,7 +1165,7 @@ state. The read side mirrors the write side:
|
|
|
1163
1165
|
against `window.PMX_AX`, not direct `fetch()` (the artifact iframe is sandboxed
|
|
1164
1166
|
opaque-origin, so it can't call the API directly).
|
|
1165
1167
|
|
|
1166
|
-
Minimal html work board (drop-in via `
|
|
1168
|
+
Minimal html work board (drop-in via `canvas_node { action: "add", type: "html" }`, `axCapabilities.enabled: true`):
|
|
1167
1169
|
|
|
1168
1170
|
```html
|
|
1169
1171
|
<button id="add">+ Task</button> <span id="ok"></span>
|
|
@@ -1215,10 +1217,10 @@ The `canvas://spatial-context` resource reveals how the human has organized info
|
|
|
1215
1217
|
- **Pinned neighborhoods** — For each pinned node, nearby unpinned nodes are listed. These
|
|
1216
1218
|
are the human's implicit context — things they consider related to what they pinned.
|
|
1217
1219
|
- **Annotations** — Human-drawn markup is summarized by target/bounds only, e.g. an
|
|
1218
|
-
annotation over a node or empty canvas region. Use WebView (`
|
|
1219
|
-
`
|
|
1220
|
+
annotation over a node or empty canvas region. Use WebView (`canvas_webview { action: "start" }` +
|
|
1221
|
+
`canvas_webview { action: "evaluate" }`/`canvas_screenshot`) when you need to see whether the mark is an
|
|
1220
1222
|
arrow, line, circle, or other drawn shape. Remove known annotations with
|
|
1221
|
-
`
|
|
1223
|
+
`canvas_view { action: "remove-annotation" }`; otherwise use WebView to identify the mark first.
|
|
1222
1224
|
- **Board density matters** — On a dense board, spatial context can still read like one large
|
|
1223
1225
|
gallery unless groups and spacing separate the major regions clearly.
|
|
1224
1226
|
|
|
@@ -1367,7 +1369,7 @@ Understand a codebase by visualizing file relationships:
|
|
|
1367
1369
|
When the user wants a real browser app instead of static notes:
|
|
1368
1370
|
|
|
1369
1371
|
1. Use the `web-artifacts-builder` skill if the UI needs React state, routing, or shadcn-style components
|
|
1370
|
-
2. Build with `
|
|
1372
|
+
2. Build with `canvas_app { action: "build-artifact" }`
|
|
1371
1373
|
3. Keep `openInCanvas` enabled unless the user explicitly wants only the output file
|
|
1372
1374
|
4. Use the returned `projectPath` as the reusable source workspace for iterations
|
|
1373
1375
|
5. Use the returned `path` for sharing or for opening the generated artifact outside the canvas
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# HTML Primitive Authoring
|
|
2
2
|
|
|
3
3
|
Use this guide when creating reusable sandboxed HTML communication primitives through
|
|
4
|
-
`
|
|
4
|
+
`canvas_node { action: "add", type: "html", primitive, data }` or `pmx-canvas html primitive add`.
|
|
5
5
|
|
|
6
6
|
## What They Are
|
|
7
7
|
|
|
@@ -11,8 +11,8 @@ sandboxed iframe node, plus metadata describing the primitive kind and source da
|
|
|
11
11
|
- Use them when markdown becomes too dense but a full React web artifact would be too heavy.
|
|
12
12
|
- Prefer them for communication artifacts: choices, plans, reviews, maps, explainers, reports,
|
|
13
13
|
lightweight editors, and handoff boards.
|
|
14
|
-
- Keep using `
|
|
15
|
-
- Keep using `
|
|
14
|
+
- Keep using `canvas_node { action: "add", type: "html", html }` for bespoke one-off HTML and JS.
|
|
15
|
+
- Keep using `canvas_app { action: "build-artifact" }` for multi-component apps, routing, React state, or shadcn UI.
|
|
16
16
|
|
|
17
17
|
The design language is inspired by high-density HTML communication patterns: strong hierarchy,
|
|
18
18
|
metric cards, sticky context panels, annotated snippets, inline SVG figures, and copy/export actions.
|
|
@@ -83,7 +83,8 @@ realize them with PMX Canvas `graph` / `json-render` nodes. Color must encode da
|
|
|
83
83
|
|
|
84
84
|
## Mapping to the PMX Canvas chart catalog
|
|
85
85
|
|
|
86
|
-
Realize these designs with `
|
|
86
|
+
Realize these designs with `canvas_render { action: "add-graph" }` (graph nodes) and
|
|
87
|
+
`canvas_render { action: "add-json-render" }`.
|
|
87
88
|
The chart catalog: `LineChart`, `BarChart`, `PieChart`, `AreaChart`, `ScatterChart`, `RadarChart`,
|
|
88
89
|
`StackedBarChart`, `ComposedChart`, plus the Tufte primitives `Sparkline`, `DotPlot`, `BulletChart`,
|
|
89
90
|
and `Slopegraph`.
|
|
@@ -128,9 +129,9 @@ are directly identifiable; reserve legends for genuinely many overlapping series
|
|
|
128
129
|
|
|
129
130
|
When more than ~4 series would overlap in one chart, do **not** cram them into a single multi-color
|
|
130
131
|
`LineChart`. Create several small `graph` nodes with an **identical shared scale** and consistent
|
|
131
|
-
encoding, arranged in a grid (`
|
|
132
|
-
every panel; the sequence tells the macro story while each panel
|
|
133
|
-
almost always better than color-coding 6+ lines.
|
|
132
|
+
encoding, arranged in a grid (`canvas_view { action: "arrange", layout: "grid" }`, or a `group`).
|
|
133
|
+
Position means the same thing in every panel; the sequence tells the macro story while each panel
|
|
134
|
+
carries the micro detail. This is almost always better than color-coding 6+ lines.
|
|
134
135
|
|
|
135
136
|
## Key Principles Reference
|
|
136
137
|
|
|
@@ -21,10 +21,10 @@ VERY IMPORTANT: To avoid what is often referred to as "AI slop", avoid using exc
|
|
|
21
21
|
|
|
22
22
|
## Quick Start
|
|
23
23
|
|
|
24
|
-
In `pmx-canvas`, prefer the `
|
|
25
|
-
bundled runtime scripts, writes reusable source under
|
|
26
|
-
emits a bundled HTML file under `.pmx-canvas/artifacts/`,
|
|
27
|
-
canvas as an embedded node.
|
|
24
|
+
In `pmx-canvas`, prefer the `canvas_app { action: "build-artifact" }` MCP tool when available. It
|
|
25
|
+
uses the same bundled runtime scripts, writes reusable source under
|
|
26
|
+
`.pmx-canvas/artifacts/.web-artifacts/`, emits a bundled HTML file under `.pmx-canvas/artifacts/`,
|
|
27
|
+
and can open the result directly on the canvas as an embedded node.
|
|
28
28
|
For browser verification after the build, pair this skill with the local `playwright-cli` skill.
|
|
29
29
|
|
|
30
30
|
### Step 1: Initialize Project
|