pmx-canvas 0.1.16 → 0.1.17

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 (40) hide show
  1. package/CHANGELOG.md +65 -0
  2. package/Readme.md +2 -2
  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 +23 -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 +17 -0
  19. package/src/cli/agent.ts +6 -0
  20. package/src/client/App.tsx +60 -3
  21. package/src/client/canvas/AnnotationLayer.tsx +28 -0
  22. package/src/client/canvas/CanvasViewport.tsx +169 -10
  23. package/src/client/canvas/ContextPinBar.tsx +2 -1
  24. package/src/client/canvas/use-pan-zoom.ts +10 -5
  25. package/src/client/icons.tsx +22 -0
  26. package/src/client/state/canvas-store.ts +52 -2
  27. package/src/client/state/sse-bridge.ts +35 -1
  28. package/src/client/theme/global.css +25 -0
  29. package/src/client/types.ts +17 -0
  30. package/src/mcp/canvas-access.ts +10 -0
  31. package/src/mcp/server.ts +35 -4
  32. package/src/server/canvas-schema.ts +25 -0
  33. package/src/server/canvas-serialization.ts +69 -1
  34. package/src/server/canvas-state.ts +74 -2
  35. package/src/server/diagram-presets.ts +54 -19
  36. package/src/server/index.ts +20 -3
  37. package/src/server/mutation-history.ts +2 -0
  38. package/src/server/server.ts +77 -2
  39. package/src/server/spatial-analysis.ts +46 -1
  40. package/src/shared/semantic-attention.ts +4 -2
package/CHANGELOG.md CHANGED
@@ -3,6 +3,70 @@
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.17] - 2026-05-04
7
+
8
+ Adds a freehand annotation layer so humans can draw directly on the
9
+ canvas and agents read compact spatial annotation context (bounds,
10
+ target nodes, optional label) without seeing the raw ink. Excalidraw
11
+ bound-text → label hoisting now covers the full set of canonical and
12
+ shorthand shapes the hosted app emits, and the `html` node type gets
13
+ its first-class entry in `canvas_describe_schema` plus a CLI
14
+ `--content` alias that maps to `data.html`.
15
+
16
+ ### Added
17
+
18
+ - **Freehand canvas annotations.** A new top-level annotation layer
19
+ lets humans draw freehand strokes on the canvas with pen and
20
+ eraser tools wired into the toolbar. Annotations live alongside
21
+ nodes and edges in `canvasState` (their own `addAnnotation` /
22
+ `removeAnnotation` history operations), persist into snapshots,
23
+ and are rendered as SVG paths whose default `currentColor` stroke
24
+ follows the active theme via a new `--c-annotation` token.
25
+ Surfaces:
26
+ - HTTP: `POST /api/canvas/annotation`, `DELETE
27
+ /api/canvas/annotation/:id`.
28
+ - MCP: `canvas_remove_annotation` (the canvas now exposes 41 MCP
29
+ tools, was 40).
30
+ - Client: pen / eraser toolbar buttons with theme-aware iconography
31
+ and an `AnnotationLayer` that renders the strokes.
32
+ - **Spatial annotation context for agents.** Each pinned-context /
33
+ spatial-context read now includes a compact
34
+ `SpatialAnnotationContext` per annotation: `id`, `label`,
35
+ `bounds`, `targetNodeIds`, `targetNodeTitles`, and `target`
36
+ summary. Agents see what the annotation *circles* (which nodes it
37
+ overlaps), not the freehand path itself, keeping the read budget
38
+ small while still letting the agent act on the human's intent.
39
+ - **HTML node schema entry in `canvas_describe_schema`.** The `html`
40
+ node type added in 0.1.15 now appears in the schema tour with a
41
+ documented `html` field, `--content` / `--stdin` aliases, the
42
+ sandboxed-iframe note, and an example payload.
43
+ - **CLI `--content` alias for HTML nodes.** `pmx-canvas node add
44
+ --type html --content '<main>Hello</main>'` is accepted as a
45
+ shorthand for setting `data.html` (also supported via `--stdin`).
46
+
47
+ ### Changed
48
+
49
+ - **Excalidraw bound-text → container label hoisting now covers
50
+ every canonical shape.** The diagram preset
51
+ (`normalizeExcalidrawElementsForToolInput`) hoists text into a
52
+ `rectangle` / `ellipse` / `diamond` container's `label` for all
53
+ four patterns the hosted app emits: the canonical
54
+ `containerId`-pointing text, the centered-container variant,
55
+ pre-existing shorthand labels (preserved as-is), and the
56
+ `boundElements`-only path where the text lacks a back-reference.
57
+ Text alignment and vertical-alignment hints are forwarded into
58
+ the label when present.
59
+
60
+ ### Internal
61
+
62
+ - Regression coverage for: annotation persistence and removal in
63
+ `canvasState`, annotation undo/redo history operations,
64
+ annotation create/delete over HTTP, html-content CLI alias
65
+ mapping, all four Excalidraw bound-text patterns, html node
66
+ rendering from server state in the browser (e2e), annotation
67
+ theme contrast plus eraser flow (e2e), and annotation toolbar
68
+ actions preserving the active light theme (e2e).
69
+
6
70
  ## [0.1.16] - 2026-05-04
7
71
 
8
72
  Live-context-dock and undo-history hygiene pass on top of 0.1.15. The
@@ -663,6 +727,7 @@ otherwise have to discover by trial and error.
663
727
  - Regression coverage for snapshot flat-`id` aliases on both MCP and
664
728
  HTTP surfaces, plus async / top-level-`await` WebView script bodies.
665
729
 
730
+ [0.1.17]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.17
666
731
  [0.1.16]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.16
667
732
  [0.1.15]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.15
668
733
  [0.1.14]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.14
package/Readme.md CHANGED
@@ -58,7 +58,7 @@ the canvas durable rather than throwaway.
58
58
 
59
59
  ### 05 / Any agent
60
60
 
61
- Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (40 tools,
61
+ Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (41 tools,
62
62
  8 resources, change notifications), the [CLI](docs/cli.md), the
63
63
  [HTTP API](docs/http-api.md), or the [Bun SDK](docs/sdk.md). Works with
64
64
  Claude Code, GitHub Copilot CLI, Codex, Cursor, Windsurf, or any agent
@@ -136,7 +136,7 @@ the agent can read `canvas://skills` and pull in companion skills
136
136
  the three-tier visual matrix (json-render → html → web-artifact)
137
137
  - **[CLI reference](docs/cli.md)** — full command surface, daemon mode,
138
138
  watch streams, WebView automation
139
- - **[MCP reference](docs/mcp.md)** — 40 tools, 8 resources, change
139
+ - **[MCP reference](docs/mcp.md)** — 41 tools, 8 resources, change
140
140
  notifications, node-type routing
141
141
  - **[HTTP API](docs/http-api.md)** — REST endpoints, SSE, batch operations
142
142
  - **[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;