pmx-canvas 0.2.6 → 0.3.0

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 (59) hide show
  1. package/CHANGELOG.md +156 -1
  2. package/Readme.md +13 -11
  3. package/dist/canvas/index.js +18 -18
  4. package/dist/json-render/index.css +1 -1
  5. package/dist/types/mcp/canvas-access.d.ts +23 -7
  6. package/dist/types/server/ax-state-manager.d.ts +3 -2
  7. package/dist/types/server/bundled-skills.d.ts +3 -3
  8. package/dist/types/server/canvas-state.d.ts +2 -0
  9. package/dist/types/server/ext-app-lookup.d.ts +1 -3
  10. package/dist/types/server/operations/composites.d.ts +29 -23
  11. package/dist/types/server/operations/http.d.ts +2 -1
  12. package/dist/types/shared/ax-intent.d.ts +1 -1
  13. package/docs/RELEASE.md +23 -8
  14. package/docs/ax-host-adapter-contract.md +7 -7
  15. package/docs/ax-state-contract.md +7 -6
  16. package/docs/bun-webview-integration.md +5 -5
  17. package/docs/cli.md +1 -1
  18. package/docs/http-api.md +7 -3
  19. package/docs/mcp.md +121 -100
  20. package/docs/node-types.md +45 -35
  21. package/docs/plans/plan-006-mcp-tool-consolidation.md +3 -1
  22. package/docs/plans/plan-008-registry-finish.md +2 -0
  23. package/docs/plans/plan-009-tech-debt-backlog.md +51 -0
  24. package/docs/screenshot.png +0 -0
  25. package/docs/tech-debt-assessment-2026-06.md +1 -1
  26. package/docs/tech-debt-assessment-2026-07.md +135 -0
  27. package/package.json +1 -1
  28. package/skills/data-analysis/SKILL.md +3 -3
  29. package/skills/frontend-design/SKILL.md +3 -2
  30. package/skills/json-render-mcp/SKILL.md +4 -3
  31. package/skills/playwright-cli/SKILL.md +1 -1
  32. package/skills/pmx-canvas/SKILL.md +20 -15
  33. package/skills/pmx-canvas/evals/evals.json +2 -2
  34. package/skills/pmx-canvas/references/ax-html-control-surface.md +3 -1
  35. package/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +2 -2
  36. package/skills/pmx-canvas/references/full-reference.md +65 -62
  37. package/skills/pmx-canvas/references/html-primitives.md +3 -3
  38. package/skills/tufte-viz/SKILL.md +5 -4
  39. package/skills/web-artifacts-builder/SKILL.md +4 -4
  40. package/src/client/App.tsx +2 -1
  41. package/src/mcp/canvas-access.ts +115 -107
  42. package/src/mcp/server.ts +74 -201
  43. package/src/server/ax-state-manager.ts +3 -2
  44. package/src/server/bundled-skills.ts +3 -3
  45. package/src/server/canvas-schema.ts +46 -29
  46. package/src/server/canvas-state.ts +5 -0
  47. package/src/server/code-graph.ts +1 -1
  48. package/src/server/ext-app-lookup.ts +1 -8
  49. package/src/server/index.ts +1 -1
  50. package/src/server/intent-registry.ts +1 -1
  51. package/src/server/operations/composites.ts +39 -39
  52. package/src/server/operations/http.ts +3 -2
  53. package/src/server/operations/mcp.ts +7 -6
  54. package/src/server/operations/ops/app.ts +4 -4
  55. package/src/server/operations/ops/nodes.ts +5 -5
  56. package/src/server/operations/ops/query.ts +19 -8
  57. package/src/server/operations/ops/snapshots.ts +6 -6
  58. package/src/server/server.ts +40 -4
  59. package/src/shared/ax-intent.ts +1 -1
package/CHANGELOG.md CHANGED
@@ -3,7 +3,160 @@
3
3
  All notable changes to `pmx-canvas` are documented here. This project follows
4
4
  [Semantic Versioning](https://semver.org/).
5
5
 
6
- ## [Unreleased]
6
+ ## [0.3.0] - 2026-07-07
7
+
8
+ ### Breaking
9
+
10
+ - **MCP tool surface shrinks from 84 to 27.** The 57 deprecated legacy
11
+ single-purpose MCP tools left over from the v0.2 composites migration are
12
+ removed. Each has a direct composite replacement — same operation, new
13
+ entry point:
14
+ - **`canvas_node`**: `canvas_add_node` → `action: "add"`; `canvas_get_node`
15
+ → `action: "get"`; `canvas_update_node` → `action: "update"`;
16
+ `canvas_remove_node` → `action: "remove"`; `canvas_add_html_node` →
17
+ `action: "add"` with `type: "html"`; `canvas_add_html_primitive` →
18
+ `action: "add"` with `type: "html"` + `primitive: "<kind>"`;
19
+ `canvas_refresh_webpage_node` → `action: "update"` with `refresh: true`.
20
+ - **`canvas_render`**: `canvas_describe_schema` → `action:
21
+ "describe-schema"`; `canvas_validate_spec` → `action: "validate"`;
22
+ `canvas_add_json_render_node` → `action: "add-json-render"`;
23
+ `canvas_stream_json_render_node` → `action: "stream-json-render"`;
24
+ `canvas_add_graph_node` → `action: "add-graph"`.
25
+ - **`canvas_edge`**: `canvas_add_edge` → `action: "add"`;
26
+ `canvas_remove_edge` → `action: "remove"`.
27
+ - **`canvas_group`**: `canvas_create_group` → `action: "create"`;
28
+ `canvas_group_nodes` → `action: "add"`; `canvas_ungroup` → `action:
29
+ "ungroup"`.
30
+ - **`canvas_history`**: `canvas_undo` → `action: "undo"`; `canvas_redo` →
31
+ `action: "redo"`.
32
+ - **`canvas_view`**: `canvas_arrange` → `action: "arrange"`;
33
+ `canvas_focus_node` → `action: "focus"`; `canvas_fit_view` → `action:
34
+ "fit"`; `canvas_clear` → `action: "clear"`; `canvas_remove_annotation` →
35
+ `action: "remove-annotation"`.
36
+ - **`canvas_query`**: `canvas_search` → `action: "search"`;
37
+ `canvas_get_layout` → `action: "layout"`; `canvas_validate` → `action:
38
+ "validate"`.
39
+ - **`canvas_app`**: `canvas_open_mcp_app` → `action: "open-mcp-app"`;
40
+ `canvas_add_diagram` → `action: "diagram"`; `canvas_build_web_artifact` →
41
+ `action: "build-artifact"`.
42
+ - **`canvas_webview`**: `canvas_webview_status` → `action: "status"`;
43
+ `canvas_webview_start` → `action: "start"`; `canvas_webview_stop` →
44
+ `action: "stop"`; `canvas_resize` → `action: "resize"`; `canvas_evaluate`
45
+ → `action: "evaluate"`.
46
+ - **`canvas_ax_state`**: `canvas_get_ax` → `action: "get"`;
47
+ `canvas_set_ax_focus` → `action: "set-focus"`; `canvas_set_ax_policy` →
48
+ `action: "set-policy"`; `canvas_report_host_capability` → `action:
49
+ "report-capability"`.
50
+ - **`canvas_ax_work`**: `canvas_add_work_item` → `action: "add"`;
51
+ `canvas_update_work_item` → `action: "update"`;
52
+ `canvas_add_review_annotation` → `action: "annotate"`.
53
+ - **`canvas_ax_gate`**: `canvas_request_approval` → `kind: "approval"`,
54
+ `action: "request"`; `canvas_resolve_approval` → `kind: "approval"`,
55
+ `action: "resolve"`; `canvas_await_approval` → `kind: "approval"`,
56
+ `action: "await"`; `canvas_request_elicitation` → `kind: "elicitation"`,
57
+ `action: "request"`; `canvas_respond_elicitation` → `kind:
58
+ "elicitation"`, `action: "resolve"`; `canvas_await_elicitation` → `kind:
59
+ "elicitation"`, `action: "await"`; `canvas_request_mode` → `kind:
60
+ "mode"`, `action: "request"`; `canvas_resolve_mode` → `kind: "mode"`,
61
+ `action: "resolve"`; `canvas_await_mode` → `kind: "mode"`, `action:
62
+ "await"`.
63
+ - **`canvas_ax_timeline`**: `canvas_get_ax_timeline` → `action: "read"`;
64
+ `canvas_record_ax_event` → `action: "record-event"`; `canvas_add_evidence`
65
+ → `action: "add-evidence"`; `canvas_send_steering` → `action:
66
+ "send-steering"`.
67
+ - **`canvas_ax_delivery`**: `canvas_claim_ax_delivery` → `action: "claim"`;
68
+ `canvas_mark_ax_delivery` → `action: "mark"`.
69
+
70
+ The HTTP API, the SDK, and `canvas_batch` are unaffected — these are the
71
+ same underlying operations, only the standalone MCP tool entry points are
72
+ removed. `docs/mcp.md` retains the full migration table for reference.
73
+
74
+ - **Malformed JSON request bodies now return 400.** Every HTTP API route
75
+ responds `400 { ok: false, error: "Malformed JSON body." }` when a non-empty
76
+ body fails to parse, instead of silently treating it as an empty request.
77
+ Empty bodies are still accepted.
78
+
79
+ ### Deprecated
80
+
81
+ - The 6 snapshot standalone tools (`canvas_snapshot`, `canvas_list_snapshots`,
82
+ `canvas_restore`, `canvas_delete_snapshot`, `canvas_gc_snapshots`,
83
+ `canvas_diff`) now carry deprecation notices in their tool descriptions and
84
+ fold into a `canvas_snapshot` composite (`action: save|list|restore|delete
85
+ |gc|diff`) in v0.4.
86
+
87
+ ### Removed
88
+
89
+ - Legacy `ext-app-ext-app-…` double-prefix blob-lookup fallback in
90
+ `findCanvasExtAppNodeId` (`src/server/ext-app-lookup.ts`), scheduled for
91
+ removal since v0.1.4. All ext-app node IDs have carried the single-prefix
92
+ form since then; the primary lookup and the data-scan fallback are
93
+ unaffected.
94
+ - The orphaned `dist/client` bundle and the generated web-artifact build
95
+ projects under `.pmx-canvas/artifacts/.web-artifacts/` are no longer
96
+ committed to the repo.
97
+
98
+ ### Fixed
99
+
100
+ - HTTP `GET /api/canvas/search` now honors the `limit` query parameter
101
+ (previously only the MCP tool applied it).
102
+ - The SDK's `setContextPins` emits the same `context-pins-changed` event as
103
+ the HTTP API and MCP tool, instead of a full layout update.
104
+ - `canvas_ax_interaction` and `canvas_ingest_activity` return a clean tool
105
+ error instead of an MCP protocol error when they fail.
106
+ - The code graph resolves workspace-relative imports against the configured
107
+ workspace root instead of the server process working directory.
108
+ - The MCP server now reports the real package version in its handshake
109
+ (read from `package.json`) instead of a stale hard-coded `0.1.0`.
110
+
111
+ ### Docs
112
+
113
+ - Operation descriptions and field hints no longer route agents to MCP tools
114
+ removed in v0.3.0.
115
+
116
+ ## [0.2.7] - 2026-06-25
117
+
118
+ ### Fixed
119
+
120
+ - **Ghost Cursor of Intent is no longer hidden behind the welcome card on an empty board (report
121
+ Finding J).** The intent ghost lives inside the zoom/pan world transform (its own stacking
122
+ context), so its high z-index could not lift it above the `.welcome-card`, which is a sibling
123
+ outside the transform. The welcome card is now suppressed while a ghost intent is live
124
+ (`intents.value.size > 0`), so a `canvas_intent` signal on a fresh board is visible immediately;
125
+ the card returns when the intent clears/settles and the board is still empty. Verified by
126
+ screenshot in the WebKit backend.
127
+ - **MCP `--mcp` no longer silently splits to (or silently adopts) a wrong workspace — structural
128
+ fix (report Finding I).** The GitHub Copilot adapter spawns `pmx-canvas --mcp` from an incidental
129
+ cwd (e.g. `~/.copilot`); the old code then either split to a hidden fallback port (when the
130
+ preferred port was held) or adopted that incidental cwd as the workspace (when the port was free),
131
+ so writes landed on a canvas the project panel never renders. Now, in `createCanvasAccess`:
132
+ - **Port held by a different-workspace daemon →** the MCP server **attaches** to it (inherits its
133
+ workspace) so writes are visible where the panel renders, instead of splitting.
134
+ - **Free port + incidental launch cwd (`~/.copilot`-shaped) →** it still binds (the agent always
135
+ gets a working canvas) but emits a loud, actionable stderr warning instead of silently adopting
136
+ the cwd; a race-tolerant re-probe first attaches to any daemon that appeared on the port.
137
+ - **`PMX_CANVAS_WORKSPACE_ROOT=<abs project root>`** (new) pins the workspace for both the lookup
138
+ and the bound daemon (`startCanvasServer` honors it), overriding the launch cwd — the deterministic
139
+ host fix. `PMX_CANVAS_ALLOW_WORKSPACE_SPLIT=1` (or a distinct `PMX_CANVAS_PORT`) forces a separate
140
+ canvas. The incidental detector is **positive-signal only** (home dir / dot-child of home), so the
141
+ `mkdtemp` temp dirs the test suite runs from are never misflagged — startup behavior is
142
+ byte-identical for real projects and tests.
143
+ Verified on the real `--mcp` stdio path: port-held → attach (no fallback); incidental + free →
144
+ bind-but-warn (no split); `PMX_CANVAS_WORKSPACE_ROOT` → binds the project root (no warning); real
145
+ project → binds (no warning). Pure `shouldAttachToExistingDaemon` + `looksLikeIncidentalCwd`
146
+ helpers are unit-tested.
147
+
148
+ ### Docs
149
+
150
+ - **Clarified the `color` contract: renderer color vs persisted metadata (report Finding H).** A
151
+ top-level `color` is a renderer parameter only for `group` (frame accent) and `graph` nodes; on
152
+ `markdown` / `status` / `context` it is dropped, and while an arbitrary `data.color` posted under
153
+ `data` persists like any `data.*` metadata, it is not read as a render color for basic node types.
154
+ The reference now states this renderer-vs-storage distinction so docs/schema/runtime agree.
155
+ - **Made the WebView automation timeout error actionable (report Finding G).** The chrome backend is
156
+ known-flaky on some hosts (Bun.WebView), reproduced in both the Copilot and Codex hosts; the webkit
157
+ backend (the macOS default) works. The timeout error now points to `start --backend webkit` and the
158
+ already-configurable `PMX_CANVAS_WEBVIEW_TIMEOUT_MS` instead of a dead-end "may be unavailable".
159
+ Not a PMX regression — no canvas source touches the WebView/automation path.
7
160
 
8
161
  ## [0.2.6] - 2026-06-25
9
162
 
@@ -2488,6 +2641,8 @@ otherwise have to discover by trial and error.
2488
2641
  - Regression coverage for snapshot flat-`id` aliases on both MCP and
2489
2642
  HTTP surfaces, plus async / top-level-`await` WebView script bodies.
2490
2643
 
2644
+ [0.3.0]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.3.0
2645
+ [0.2.7]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.2.7
2491
2646
  [0.2.6]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.2.6
2492
2647
  [0.2.5]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.2.5
2493
2648
  [0.2.4]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.2.4
package/Readme.md CHANGED
@@ -98,14 +98,14 @@ vendor-specific.
98
98
 
99
99
  Spatial state auto-saves to `.pmx-canvas/canvas.db` (debounced ~500 ms) —
100
100
  git-committable, shareable across machines, and survives both browser
101
- refresh and server restart. Named [snapshots](docs/mcp.md#tools), full
101
+ refresh and server restart. Named [snapshots](docs/mcp.md#standalone-tools), full
102
102
  undo/redo, and an auto-detected code graph (JS/TS, Python, Go, Rust) make
103
103
  the canvas durable rather than throwaway. Stop the server before committing
104
104
  the DB so SQLite WAL data is checkpointed into the file.
105
105
 
106
106
  ### 06 / Any agent
107
107
 
108
- Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (84 tools,
108
+ Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (27 tools,
109
109
  14 resources, change notifications), the [CLI](docs/cli.md), the
110
110
  [HTTP API](docs/http-api.md), or the [Bun SDK](docs/sdk.md). Works with
111
111
  Claude Code, GitHub Copilot CLI, Codex, Cursor, Windsurf, or any agent
@@ -136,9 +136,9 @@ surfaces (the core never imports a host SDK).
136
136
  preview).
137
137
  - **Codex app** — native through the Codex in-app Browser (opened to
138
138
  `/workbench`) plus the PMX MCP server: agents read `canvas://ax-context` /
139
- `canvas_get_ax` and label Codex-originated focus with `source: "codex"`. No
140
- extension API needed — Codex's two native surfaces (MCP + in-app Browser) are
141
- exactly what the canvas requires.
139
+ `canvas_ax_state { action: "get" }` and label Codex-originated focus with
140
+ `source: "codex"`. No extension API needed — Codex's two native surfaces
141
+ (MCP + in-app Browser) are exactly what the canvas requires.
142
142
 
143
143
  The contract is host-agnostic, so a new host plugs in the same way: map its
144
144
  hooks, canvas, and session APIs onto PMX's AX primitives — no core changes.
@@ -219,8 +219,9 @@ Codex needs no extension — its two native surfaces are exactly what the canvas
219
219
  requires. Add the PMX MCP server to the Codex workspace config (same snippet as
220
220
  [Connect your agent](#connect-your-agent-mcp)), then open the returned
221
221
  `/workbench` URL in the **Codex in-app Browser** so you can see mutations live.
222
- Agents read pinned/focused context from `canvas://ax-context` / `canvas_get_ax`
223
- and label Codex-originated focus with `source: "codex"`. See
222
+ Agents read pinned/focused context from `canvas://ax-context` /
223
+ `canvas_ax_state { action: "get" }` and label Codex-originated focus with
224
+ `source: "codex"`. See
224
225
  [`codex-app-adapter.md`](skills/pmx-canvas/references/codex-app-adapter.md) for
225
226
  the full workflow and live-test checklist.
226
227
 
@@ -255,7 +256,7 @@ the agent can read `canvas://skills` and pull in companion skills
255
256
  the three-tier visual matrix (json-render → html → web-artifact)
256
257
  - **[CLI reference](docs/cli.md)** — full command surface, daemon mode,
257
258
  watch streams, WebView automation
258
- - **[MCP reference](docs/mcp.md)** — 84 tools, 14 resources, change
259
+ - **[MCP reference](docs/mcp.md)** — 27 tools, 14 resources, change
259
260
  notifications, node-type routing
260
261
  - **[HTTP API](docs/http-api.md)** — REST endpoints, SSE, batch operations
261
262
  - **[AX host-adapter contract](docs/ax-host-adapter-contract.md)** — how native
@@ -273,9 +274,10 @@ the agent can read `canvas://skills` and pull in companion skills
273
274
  - **What leaves your machine.** The core canvas runs entirely on
274
275
  `localhost`. Network egress only happens for explicit, opt-in flows:
275
276
  `webpage` nodes fetch the URL you give them; `mcp-app` /
276
- `canvas_add_diagram` calls go to whatever MCP server URL you configure
277
- (the Excalidraw preset uses `https://mcp.excalidraw.com/mcp`); `bunx`
278
- itself reads the npm registry on first install. Nothing else phones home.
277
+ `canvas_app { action: "diagram" }` calls go to whatever MCP server URL you
278
+ configure (the Excalidraw preset uses `https://mcp.excalidraw.com/mcp`);
279
+ `bunx` itself reads the npm registry on first install. Nothing else phones
280
+ home.
279
281
 
280
282
  ## Tech stack
281
283