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.
- package/CHANGELOG.md +110 -0
- package/Readme.md +14 -7
- package/dist/canvas/global.css +25 -0
- package/dist/canvas/index.js +72 -72
- package/dist/types/client/canvas/AnnotationLayer.d.ts +4 -0
- package/dist/types/client/canvas/CanvasViewport.d.ts +4 -1
- package/dist/types/client/canvas/use-pan-zoom.d.ts +2 -1
- package/dist/types/client/icons.d.ts +4 -0
- package/dist/types/client/state/canvas-store.d.ts +16 -1
- package/dist/types/client/types.d.ts +20 -0
- package/dist/types/mcp/canvas-access.d.ts +1 -0
- package/dist/types/server/canvas-serialization.d.ts +25 -1
- package/dist/types/server/canvas-state.d.ts +27 -1
- package/dist/types/server/index.d.ts +7 -2
- package/dist/types/server/mutation-history.d.ts +1 -1
- package/dist/types/server/spatial-analysis.d.ts +11 -2
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +19 -0
- package/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +145 -0
- package/src/cli/agent.ts +6 -0
- package/src/client/App.tsx +60 -3
- package/src/client/canvas/AnnotationLayer.tsx +28 -0
- package/src/client/canvas/CanvasViewport.tsx +169 -10
- package/src/client/canvas/ContextPinBar.tsx +2 -1
- package/src/client/canvas/use-pan-zoom.ts +10 -5
- package/src/client/icons.tsx +22 -0
- package/src/client/state/canvas-store.ts +52 -2
- package/src/client/state/sse-bridge.ts +35 -1
- package/src/client/theme/global.css +25 -0
- package/src/client/types.ts +17 -0
- package/src/mcp/canvas-access.ts +10 -0
- package/src/mcp/server.ts +43 -6
- package/src/server/canvas-schema.ts +25 -0
- package/src/server/canvas-serialization.ts +117 -1
- package/src/server/canvas-state.ts +74 -2
- package/src/server/diagram-presets.ts +54 -19
- package/src/server/index.ts +20 -3
- package/src/server/mutation-history.ts +2 -0
- package/src/server/server.ts +77 -2
- package/src/server/spatial-analysis.ts +46 -1
- 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
|
|
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 /
|
|
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
|
-
###
|
|
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
|
-
###
|
|
66
|
+
### 06 / Any agent
|
|
60
67
|
|
|
61
|
-
Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (
|
|
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)** —
|
|
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
|
package/dist/canvas/global.css
CHANGED
|
@@ -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;
|