pmx-canvas 0.1.16 → 0.1.18

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 (41) hide show
  1. package/CHANGELOG.md +110 -0
  2. package/Readme.md +14 -7
  3. package/dist/canvas/global.css +25 -0
  4. package/dist/canvas/index.js +72 -72
  5. package/dist/types/client/canvas/AnnotationLayer.d.ts +4 -0
  6. package/dist/types/client/canvas/CanvasViewport.d.ts +4 -1
  7. package/dist/types/client/canvas/use-pan-zoom.d.ts +2 -1
  8. package/dist/types/client/icons.d.ts +4 -0
  9. package/dist/types/client/state/canvas-store.d.ts +16 -1
  10. package/dist/types/client/types.d.ts +20 -0
  11. package/dist/types/mcp/canvas-access.d.ts +1 -0
  12. package/dist/types/server/canvas-serialization.d.ts +25 -1
  13. package/dist/types/server/canvas-state.d.ts +27 -1
  14. package/dist/types/server/index.d.ts +7 -2
  15. package/dist/types/server/mutation-history.d.ts +1 -1
  16. package/dist/types/server/spatial-analysis.d.ts +11 -2
  17. package/package.json +1 -1
  18. package/skills/pmx-canvas/SKILL.md +19 -0
  19. package/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +145 -0
  20. package/src/cli/agent.ts +6 -0
  21. package/src/client/App.tsx +60 -3
  22. package/src/client/canvas/AnnotationLayer.tsx +28 -0
  23. package/src/client/canvas/CanvasViewport.tsx +169 -10
  24. package/src/client/canvas/ContextPinBar.tsx +2 -1
  25. package/src/client/canvas/use-pan-zoom.ts +10 -5
  26. package/src/client/icons.tsx +22 -0
  27. package/src/client/state/canvas-store.ts +52 -2
  28. package/src/client/state/sse-bridge.ts +35 -1
  29. package/src/client/theme/global.css +25 -0
  30. package/src/client/types.ts +17 -0
  31. package/src/mcp/canvas-access.ts +10 -0
  32. package/src/mcp/server.ts +43 -6
  33. package/src/server/canvas-schema.ts +25 -0
  34. package/src/server/canvas-serialization.ts +117 -1
  35. package/src/server/canvas-state.ts +74 -2
  36. package/src/server/diagram-presets.ts +54 -19
  37. package/src/server/index.ts +20 -3
  38. package/src/server/mutation-history.ts +2 -0
  39. package/src/server/server.ts +77 -2
  40. package/src/server/spatial-analysis.ts +46 -1
  41. package/src/shared/semantic-attention.ts +4 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,114 @@
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.18] - 2026-05-05
7
+
8
+ Token-budget polish on top of 0.1.17. Full-mode MCP responses for
9
+ hosted external-MCP-app nodes now elide the rendered shell HTML in
10
+ favor of a compact `{ omitted, resourceUri, bytes, sha256 }` summary,
11
+ so an agent that asks for `full: true` no longer re-receives the same
12
+ ext-app shell HTML on every read. Adds a dedicated
13
+ `excalidraw-diagram-authoring.md` skill reference and folds the
14
+ freehand annotation feature into the README's main feature list.
15
+
16
+ ### Added
17
+
18
+ - **`serializeCanvasNodeForAgent` / `serializeCanvasLayoutForAgent`.**
19
+ New agent-facing serializers wrap the existing
20
+ `serializeCanvasNode` / `serializeCanvasLayout` helpers and replace
21
+ hosted ext-app shell HTML (`mcp-app` nodes in `ext-app` mode that
22
+ carry a `resourceUri`) with a `{ omitted: 'external-mcp-app-html',
23
+ resourceUri, bytes, sha256 }` descriptor. The MCP server uses
24
+ these wrappers for `canvas_get_node` (full), `canvas_get_layout`
25
+ (full), and the full-payload branch of every add-style response.
26
+ Non-external-app HTML — `html` nodes, bundled web-artifact
27
+ output — is preserved exactly as before.
28
+ - **`skills/pmx-canvas/references/excalidraw-diagram-authoring.md`.**
29
+ A 145-line authoring guide for `canvas_add_diagram` covering shape-
30
+ level `label` format, sizing and camera rules, the pastel palette,
31
+ and common pitfalls. The SKILL points to it from the diagram
32
+ guidance section.
33
+
34
+ ### Changed
35
+
36
+ - **README adds an `03 / Annotate` section.** The annotation feature
37
+ shipped in 0.1.17 is now part of the main README feature list
38
+ alongside Curate / Mix / Control / Save / Any agent. Subsequent
39
+ sections were renumbered (Control your context → 04, Save → 05,
40
+ Any agent → 06).
41
+
42
+ ### Internal
43
+
44
+ - Regression coverage for: agent-mode node serialization eliding
45
+ hosted ext-app shell HTML, agent-mode layout serialization not
46
+ repeating the ext-app shell across multiple nodes, non-external-
47
+ app HTML payloads being preserved unchanged, and `canvas_get_node`
48
+ / `canvas_get_layout` full-mode elision through the MCP server.
49
+
50
+ ## [0.1.17] - 2026-05-04
51
+
52
+ Adds a freehand annotation layer so humans can draw directly on the
53
+ canvas and agents read compact spatial annotation context (bounds,
54
+ target nodes, optional label) without seeing the raw ink. Excalidraw
55
+ bound-text → label hoisting now covers the full set of canonical and
56
+ shorthand shapes the hosted app emits, and the `html` node type gets
57
+ its first-class entry in `canvas_describe_schema` plus a CLI
58
+ `--content` alias that maps to `data.html`.
59
+
60
+ ### Added
61
+
62
+ - **Freehand canvas annotations.** A new top-level annotation layer
63
+ lets humans draw freehand strokes on the canvas with pen and
64
+ eraser tools wired into the toolbar. Annotations live alongside
65
+ nodes and edges in `canvasState` (their own `addAnnotation` /
66
+ `removeAnnotation` history operations), persist into snapshots,
67
+ and are rendered as SVG paths whose default `currentColor` stroke
68
+ follows the active theme via a new `--c-annotation` token.
69
+ Surfaces:
70
+ - HTTP: `POST /api/canvas/annotation`, `DELETE
71
+ /api/canvas/annotation/:id`.
72
+ - MCP: `canvas_remove_annotation` (the canvas now exposes 41 MCP
73
+ tools, was 40).
74
+ - Client: pen / eraser toolbar buttons with theme-aware iconography
75
+ and an `AnnotationLayer` that renders the strokes.
76
+ - **Spatial annotation context for agents.** Each pinned-context /
77
+ spatial-context read now includes a compact
78
+ `SpatialAnnotationContext` per annotation: `id`, `label`,
79
+ `bounds`, `targetNodeIds`, `targetNodeTitles`, and `target`
80
+ summary. Agents see what the annotation *circles* (which nodes it
81
+ overlaps), not the freehand path itself, keeping the read budget
82
+ small while still letting the agent act on the human's intent.
83
+ - **HTML node schema entry in `canvas_describe_schema`.** The `html`
84
+ node type added in 0.1.15 now appears in the schema tour with a
85
+ documented `html` field, `--content` / `--stdin` aliases, the
86
+ sandboxed-iframe note, and an example payload.
87
+ - **CLI `--content` alias for HTML nodes.** `pmx-canvas node add
88
+ --type html --content '<main>Hello</main>'` is accepted as a
89
+ shorthand for setting `data.html` (also supported via `--stdin`).
90
+
91
+ ### Changed
92
+
93
+ - **Excalidraw bound-text → container label hoisting now covers
94
+ every canonical shape.** The diagram preset
95
+ (`normalizeExcalidrawElementsForToolInput`) hoists text into a
96
+ `rectangle` / `ellipse` / `diamond` container's `label` for all
97
+ four patterns the hosted app emits: the canonical
98
+ `containerId`-pointing text, the centered-container variant,
99
+ pre-existing shorthand labels (preserved as-is), and the
100
+ `boundElements`-only path where the text lacks a back-reference.
101
+ Text alignment and vertical-alignment hints are forwarded into
102
+ the label when present.
103
+
104
+ ### Internal
105
+
106
+ - Regression coverage for: annotation persistence and removal in
107
+ `canvasState`, annotation undo/redo history operations,
108
+ annotation create/delete over HTTP, html-content CLI alias
109
+ mapping, all four Excalidraw bound-text patterns, html node
110
+ rendering from server state in the browser (e2e), annotation
111
+ theme contrast plus eraser flow (e2e), and annotation toolbar
112
+ actions preserving the active light theme (e2e).
113
+
6
114
  ## [0.1.16] - 2026-05-04
7
115
 
8
116
  Live-context-dock and undo-history hygiene pass on top of 0.1.15. The
@@ -663,6 +771,8 @@ otherwise have to discover by trial and error.
663
771
  - Regression coverage for snapshot flat-`id` aliases on both MCP and
664
772
  HTTP surfaces, plus async / top-level-`await` WebView script bodies.
665
773
 
774
+ [0.1.18]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.18
775
+ [0.1.17]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.17
666
776
  [0.1.16]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.16
667
777
  [0.1.15]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.15
668
778
  [0.1.14]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.14
package/Readme.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # pmx-canvas
2
2
 
3
3
  **A moldable canvas for agent-assisted thinking.** An infinite 2D surface
4
- where files, plans, status, charts, fetched web pages, and hand-drawn
5
- diagrams live side by side. Every node carries its own renderer; agents
4
+ where files, plans, status, charts, fetched web pages, annotations, and
5
+ hand-drawn diagrams live side by side. Every node carries its own renderer; agents
6
6
  (and you) build new views in the middle of a session, not as a separate
7
7
  tooling project. Pin what matters and the agent reads your spatial
8
8
  curation as structured context.
@@ -41,14 +41,21 @@ surface. The reach of the canvas is the union of its
41
41
  already has access to** — MCP servers, CLIs, file reads, web fetch, anything
42
42
  on its toolbelt.
43
43
 
44
- ### 03 / Control your context
44
+ ### 03 / Annotate
45
+
46
+ Draw freehand marks directly on the canvas to circle, underline, connect, or
47
+ call out what matters without turning the markup into another node. Annotations
48
+ persist with state and snapshots, can be erased in the browser, and appear to
49
+ agents as compact spatial context: target, bounds, and nearby canvas content.
50
+
51
+ ### 04 / Control your context
45
52
 
46
53
  Pinning is an explicit, low-noise control over what the agent sees next. No
47
54
  prompt engineering, no copy-paste — pin a node in the browser and the MCP
48
55
  server fires a `notifications/resources/updated` event the agent's harness
49
56
  picks up immediately.
50
57
 
51
- ### 04 / Save
58
+ ### 05 / Save
52
59
 
53
60
  Spatial state auto-saves to `.pmx-canvas/state.json` (debounced ~500 ms) —
54
61
  git-committable, shareable across machines, and survives both browser
@@ -56,9 +63,9 @@ refresh and server restart. Named [snapshots](docs/mcp.md#tools), full
56
63
  undo/redo, and an auto-detected code graph (JS/TS, Python, Go, Rust) make
57
64
  the canvas durable rather than throwaway.
58
65
 
59
- ### 05 / Any agent
66
+ ### 06 / Any agent
60
67
 
61
- Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (40 tools,
68
+ Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (41 tools,
62
69
  8 resources, change notifications), the [CLI](docs/cli.md), the
63
70
  [HTTP API](docs/http-api.md), or the [Bun SDK](docs/sdk.md). Works with
64
71
  Claude Code, GitHub Copilot CLI, Codex, Cursor, Windsurf, or any agent
@@ -136,7 +143,7 @@ the agent can read `canvas://skills` and pull in companion skills
136
143
  the three-tier visual matrix (json-render → html → web-artifact)
137
144
  - **[CLI reference](docs/cli.md)** — full command surface, daemon mode,
138
145
  watch streams, WebView automation
139
- - **[MCP reference](docs/mcp.md)** — 40 tools, 8 resources, change
146
+ - **[MCP reference](docs/mcp.md)** — 41 tools, 8 resources, change
140
147
  notifications, node-type routing
141
148
  - **[HTTP API](docs/http-api.md)** — REST endpoints, SSE, batch operations
142
149
  - **[Bun SDK](docs/sdk.md)** — `createCanvas()` for TypeScript on Bun
@@ -50,6 +50,7 @@
50
50
  --c-accent-hover: #6ECAFF;
51
51
  --c-warn-hover: #f5d06b;
52
52
  --c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.02), rgba(0, 0, 0, 0));
53
+ --c-annotation: #F4EFE6;
53
54
  /* ── Non-color tokens ────────────────────────────────────── */
54
55
  --font: "IBM Plex Sans", "SF Pro Text", "Avenir Next", system-ui, sans-serif;
55
56
  --mono: "IBM Plex Mono", "SF Mono", "Fira Code", monospace;
@@ -109,6 +110,7 @@
109
110
  --c-accent-hover: #1588CE;
110
111
  --c-warn-hover: #dab040;
111
112
  --c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.12), rgba(8, 21, 36, 0.02));
113
+ --c-annotation: #081524;
112
114
  }
113
115
 
114
116
  :root[data-theme="high-contrast"] {
@@ -162,6 +164,7 @@
162
164
  --c-accent-hover: #33ffff;
163
165
  --c-warn-hover: #ffff33;
164
166
  --c-canvas-wash: linear-gradient(180deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0));
167
+ --c-annotation: #ffff00;
165
168
  }
166
169
 
167
170
  * {
@@ -1471,6 +1474,28 @@ body,
1471
1474
  z-index: 9998;
1472
1475
  }
1473
1476
 
1477
+ .annotation-layer {
1478
+ position: absolute;
1479
+ inset: 0;
1480
+ width: 1px;
1481
+ height: 1px;
1482
+ overflow: visible;
1483
+ pointer-events: none;
1484
+ z-index: 45;
1485
+ }
1486
+
1487
+ .annotation-capture-layer {
1488
+ position: absolute;
1489
+ inset: 0;
1490
+ z-index: 9996;
1491
+ pointer-events: none;
1492
+ background: color-mix(in srgb, var(--c-accent) 5%, transparent);
1493
+ }
1494
+
1495
+ .annotation-capture-layer.erasing {
1496
+ background: color-mix(in srgb, var(--c-danger) 6%, transparent);
1497
+ }
1498
+
1474
1499
  /* ── Drop Zone (file drag-and-drop) ─────────────────────────── */
1475
1500
  .drop-zone-overlay {
1476
1501
  position: absolute;