pmx-canvas 0.1.20 → 0.1.22
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 +150 -0
- package/dist/canvas/global.css +71 -0
- package/dist/canvas/index.js +94 -60
- package/dist/types/client/nodes/HtmlNode.d.ts +12 -1
- package/dist/types/client/types.d.ts +1 -1
- package/dist/types/server/canvas-serialization.d.ts +1 -0
- package/dist/types/server/html-node-summary.d.ts +2 -0
- package/dist/types/server/html-primitives.d.ts +9 -1
- package/dist/types/server/index.d.ts +8 -1
- package/docs/http-api.md +1 -1
- package/docs/mcp.md +4 -0
- package/docs/node-types.md +27 -5
- package/docs/screenshot.png +0 -0
- package/docs/sdk.md +1 -0
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +10 -4
- package/skills/pmx-canvas/references/html-primitives.md +132 -0
- package/src/cli/agent.ts +34 -1
- package/src/cli/index.ts +3 -1
- package/src/client/App.tsx +1 -1
- package/src/client/canvas/CommandPalette.tsx +1 -1
- package/src/client/canvas/ExpandedNodeOverlay.tsx +115 -2
- package/src/client/canvas/auto-fit.ts +5 -1
- package/src/client/nodes/HtmlNode.tsx +125 -13
- package/src/client/state/sse-bridge.ts +1 -1
- package/src/client/theme/global.css +71 -0
- package/src/mcp/canvas-access.ts +31 -1
- package/src/mcp/server.ts +17 -3
- package/src/server/agent-context.ts +23 -1
- package/src/server/canvas-operations.ts +18 -5
- package/src/server/canvas-provenance.ts +8 -6
- package/src/server/canvas-schema.ts +11 -0
- package/src/server/canvas-serialization.ts +36 -5
- package/src/server/html-node-summary.ts +141 -0
- package/src/server/html-primitives.ts +328 -8
- package/src/server/index.ts +22 -3
- package/src/server/server.ts +27 -9
- package/src/server/spatial-analysis.ts +4 -2
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,154 @@
|
|
|
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.22] - 2026-05-12
|
|
7
|
+
|
|
8
|
+
CLI ergonomics and response-size polish on top of 0.1.21. Adds a
|
|
9
|
+
`pmx-canvas diagram add` alias, declares kebab-case aliases for the
|
|
10
|
+
HTML sidecar fields in the schema, advertises those flags in `node
|
|
11
|
+
add --help --type html`, elides full file bodies from compact node
|
|
12
|
+
responses, validates presentation theme names with a clear error,
|
|
13
|
+
and improves keyboard focus inside present mode.
|
|
14
|
+
|
|
15
|
+
### Added
|
|
16
|
+
|
|
17
|
+
- **`pmx-canvas diagram add` CLI alias.** A thin wrapper that
|
|
18
|
+
delegates to `pmx-canvas external-app add --kind excalidraw` so
|
|
19
|
+
diagram creation has a discoverable top-level command. The `diagram`
|
|
20
|
+
subcommand is now registered in `AGENT_COMMANDS` and surfaces in
|
|
21
|
+
`pmx-canvas --help`. The help text for `diagram add` notes the
|
|
22
|
+
equivalence so agents can switch between the two without guessing.
|
|
23
|
+
- **`node add --help --type html` advertises sidecar flags.** The
|
|
24
|
+
help output now includes a dedicated "HTML sidecar flags" section
|
|
25
|
+
listing `--summary`, `--agent-summary`, `--description`,
|
|
26
|
+
`--presentation true`, `--slide-title`, and `--embedded-node-id`,
|
|
27
|
+
matching the sidecars added in 0.1.21.
|
|
28
|
+
- **Kebab-case aliases for HTML sidecar fields in
|
|
29
|
+
`canvas_describe_schema`.** The schema entries for `agentSummary`,
|
|
30
|
+
`embeddedNodeIds`, `embeddedUrls`, and `slideTitles` now declare
|
|
31
|
+
the corresponding kebab-case flag names so agents reading the
|
|
32
|
+
schema discover the CLI shape without trial and error.
|
|
33
|
+
|
|
34
|
+
### Changed
|
|
35
|
+
|
|
36
|
+
- **Compact node responses elide file content.**
|
|
37
|
+
`serializeCanvasNodeCompact` replaces a file node's full
|
|
38
|
+
`data.fileContent` with `{ omitted: 'file-content', bytes,
|
|
39
|
+
lineCount, sha256 }`. Agents that hit `canvas_get_node`,
|
|
40
|
+
`canvas_get_layout`, or batch-style responses without
|
|
41
|
+
`full: true` no longer re-receive the file body on every read;
|
|
42
|
+
the file `path` is still exposed as `content` so the node remains
|
|
43
|
+
fetchable.
|
|
44
|
+
- **Presentation theme names are validated.** Passing an invalid
|
|
45
|
+
`theme` (or `theme.base`) to a `presentation` primitive now
|
|
46
|
+
fails fast with a clear "use canvas, midnight, paper, aurora, or
|
|
47
|
+
a custom theme object" message instead of silently falling
|
|
48
|
+
through to a default. The HTTP `POST /api/canvas/node?type=html-
|
|
49
|
+
primitive` endpoint wraps `buildHtmlPrimitive` in a try/catch and
|
|
50
|
+
returns a 400 with the message.
|
|
51
|
+
- **Present-mode keyboard focus is tighter.** Tabbing inside the
|
|
52
|
+
presentation overlay now jumps to the Exit button instead of
|
|
53
|
+
escaping to the underlying canvas, Space and Enter on the Exit
|
|
54
|
+
button no longer trigger slide navigation, and the overlay
|
|
55
|
+
re-focuses itself when keyboard focus drifts outside. The deck
|
|
56
|
+
iframe loses its 18px corner radius in present mode for an
|
|
57
|
+
edge-to-edge fullscreen frame.
|
|
58
|
+
|
|
59
|
+
### Internal
|
|
60
|
+
|
|
61
|
+
- Regression coverage for: `node add` forwarding HTML sidecar flags
|
|
62
|
+
through to the underlying html node, `node add --help --type
|
|
63
|
+
html` advertising the new flags, `diagram add` always invoking
|
|
64
|
+
the Excalidraw external app alias, `diagram` routing through the
|
|
65
|
+
agent CLI (not the server-startup path), presentation primitives
|
|
66
|
+
rejecting unknown theme names, and batch `file` node add
|
|
67
|
+
responses returning compact `file-content` metadata instead of
|
|
68
|
+
the full body.
|
|
69
|
+
|
|
70
|
+
## [0.1.21] - 2026-05-09
|
|
71
|
+
|
|
72
|
+
HTML communication maturity pass on top of 0.1.20. Adds a
|
|
73
|
+
`presentation` primitive kind (PowerPoint-style decks with themes),
|
|
74
|
+
turns every html node into a first-class agent context surface with
|
|
75
|
+
semantic sidecars (summary, agent summary, description, slide
|
|
76
|
+
titles, embedded refs), wires a real Present-mode overlay with
|
|
77
|
+
iframe-focused keyboard navigation and a live theme bridge, and
|
|
78
|
+
routes the `pmx-canvas html` subcommand correctly through the agent
|
|
79
|
+
CLI.
|
|
80
|
+
|
|
81
|
+
### Added
|
|
82
|
+
|
|
83
|
+
- **New `presentation` HTML primitive kind.** `canvas_add_html_primitive
|
|
84
|
+
--kind presentation` generates a PowerPoint-style fullscreen deck
|
|
85
|
+
inside the standard sandboxed `html` node and persists the deck
|
|
86
|
+
metadata (`presentation: true`, `slideCount`, `slideTitles`,
|
|
87
|
+
optional `presentationTheme`). Themes: `canvas`, `midnight`,
|
|
88
|
+
`paper`, `aurora`, or a custom color object with `bg`, `panel`,
|
|
89
|
+
`surface`, `border`, `text`, `textSecondary`, `textMuted`,
|
|
90
|
+
`accent`, and `colorScheme`. The MCP canvas now exposes 19 HTML
|
|
91
|
+
primitives (was 18).
|
|
92
|
+
- **HTML node semantic sidecars.** Every html node can now carry
|
|
93
|
+
agent-readable metadata that agents see without parsing the
|
|
94
|
+
iframe payload: `summary`, `agentSummary`, `description`,
|
|
95
|
+
`presentation`, `slideTitles`, `embeddedNodeIds`, `embeddedUrls`.
|
|
96
|
+
Same surface lands on CLI (`pmx-canvas node add --type html
|
|
97
|
+
--summary "..." --agent-summary "..." --description "..."
|
|
98
|
+
--presentation true --slide-title "..." --embedded-node-id ...`),
|
|
99
|
+
HTTP `POST /api/canvas/node`, MCP `canvas_add_html_node`, SDK
|
|
100
|
+
`PmxCanvas.addHtmlNode()`, and `canvas_describe_schema`.
|
|
101
|
+
`agent-context` and `canvas://pinned-context` now expose this
|
|
102
|
+
metadata for HTML nodes.
|
|
103
|
+
- **Auto-derived `contentSummary` for html nodes.** When the agent
|
|
104
|
+
doesn't supply an explicit summary, PMX runs the rendered HTML
|
|
105
|
+
through a new `summarizeHtmlText()` (in
|
|
106
|
+
`src/server/html-node-summary.ts`) to extract a bounded plain-
|
|
107
|
+
text summary that drives search, pinned context, and spatial
|
|
108
|
+
context. `normalizeHtmlNodeSemanticData()` keeps existing
|
|
109
|
+
provenance and semantic fields stable across edits.
|
|
110
|
+
- **Browser-side Present mode.** Presentation-marked html nodes
|
|
111
|
+
surface a Present button in `ExpandedNodeOverlay` that opens a
|
|
112
|
+
fullscreen overlay with the deck iframe focused. Arrow keys,
|
|
113
|
+
Page Up/Down, Space, Home, and End are forwarded into the iframe
|
|
114
|
+
via a token-scoped postMessage bridge, and pressing Escape inside
|
|
115
|
+
the iframe exits via the same bridge. A live theme bridge
|
|
116
|
+
re-injects the canvas theme tokens into the iframe whenever the
|
|
117
|
+
theme changes, so present mode reflects light/dark toggles
|
|
118
|
+
instantly.
|
|
119
|
+
- **`html-primitives.md` skill reference.** New 132-line authoring
|
|
120
|
+
guide under `skills/pmx-canvas/references/` covers when to use
|
|
121
|
+
primitives versus `canvas_add_html_node` versus
|
|
122
|
+
`canvas_build_web_artifact`, the catalog, and shared design
|
|
123
|
+
language.
|
|
124
|
+
|
|
125
|
+
### Changed
|
|
126
|
+
|
|
127
|
+
- **`canvas_add_html_node` clarifies presentation is opt-in.** The
|
|
128
|
+
MCP tool description now states explicitly that presentation
|
|
129
|
+
mode is opt-in (pass `presentation: true` or use the
|
|
130
|
+
`presentation` primitive) — normal html nodes remain the default
|
|
131
|
+
for reports, widgets, and bespoke visualizations.
|
|
132
|
+
- **Auto-fit no longer shrinks presentation html nodes.** Like
|
|
133
|
+
graph and json-render frames, presentation-marked html nodes
|
|
134
|
+
keep their explicit width and height so decks aren't squeezed
|
|
135
|
+
by the content-fit pass.
|
|
136
|
+
- **`pmx-canvas html` subcommand routes through the agent CLI.**
|
|
137
|
+
Same fix as the earlier `fit` and `screenshot` routing issues —
|
|
138
|
+
`html` is now in the `AGENT_COMMANDS` set in `src/cli/index.ts`
|
|
139
|
+
so it doesn't get treated as a server-startup invocation.
|
|
140
|
+
|
|
141
|
+
### Internal
|
|
142
|
+
|
|
143
|
+
- Regression coverage for: HTML node semantic sidecars persisting
|
|
144
|
+
through CLI/HTTP/MCP, presentation primitives storing slide
|
|
145
|
+
metadata and theme metadata (named + custom), agent context
|
|
146
|
+
exposing html sidecars and presentation metadata, auto-fit
|
|
147
|
+
excluding presentation html frames, the `html` CLI routing,
|
|
148
|
+
client-side present-mode behavior (only explicit presentation
|
|
149
|
+
html nodes can present; theme bridge injected; srcdoc marker
|
|
150
|
+
distinguishes review vs present mode), live theme update on
|
|
151
|
+
present-mode iframe (e2e), and present mode focusing iframe
|
|
152
|
+
keyboard navigation while hiding review hints (e2e).
|
|
153
|
+
|
|
6
154
|
## [0.1.20] - 2026-05-06
|
|
7
155
|
|
|
8
156
|
A bigger feature release. Adds 18 reusable HTML communication
|
|
@@ -897,6 +1045,8 @@ otherwise have to discover by trial and error.
|
|
|
897
1045
|
- Regression coverage for snapshot flat-`id` aliases on both MCP and
|
|
898
1046
|
HTTP surfaces, plus async / top-level-`await` WebView script bodies.
|
|
899
1047
|
|
|
1048
|
+
[0.1.22]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.22
|
|
1049
|
+
[0.1.21]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.21
|
|
900
1050
|
[0.1.20]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.20
|
|
901
1051
|
[0.1.19]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.19
|
|
902
1052
|
[0.1.18]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.18
|
package/dist/canvas/global.css
CHANGED
|
@@ -2438,6 +2438,18 @@ body,
|
|
|
2438
2438
|
border-color: var(--c-muted);
|
|
2439
2439
|
}
|
|
2440
2440
|
|
|
2441
|
+
.expanded-action-btn.expanded-action-primary {
|
|
2442
|
+
background: var(--c-accent-12);
|
|
2443
|
+
border-color: var(--c-accent-30);
|
|
2444
|
+
color: var(--c-accent);
|
|
2445
|
+
}
|
|
2446
|
+
|
|
2447
|
+
.expanded-action-btn.expanded-action-primary:hover {
|
|
2448
|
+
background: var(--c-accent-25);
|
|
2449
|
+
border-color: var(--c-accent);
|
|
2450
|
+
color: var(--c-text);
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2441
2453
|
.expanded-action-btn.expanded-action-active {
|
|
2442
2454
|
background: var(--c-warn-12);
|
|
2443
2455
|
border-color: var(--c-warn-30);
|
|
@@ -2455,6 +2467,65 @@ body,
|
|
|
2455
2467
|
padding: 0 4px;
|
|
2456
2468
|
}
|
|
2457
2469
|
|
|
2470
|
+
.html-presentation-overlay {
|
|
2471
|
+
position: fixed;
|
|
2472
|
+
inset: 0;
|
|
2473
|
+
z-index: 10050;
|
|
2474
|
+
display: flex;
|
|
2475
|
+
padding: 0;
|
|
2476
|
+
background:
|
|
2477
|
+
radial-gradient(circle at top left, var(--c-accent-25), transparent 36rem),
|
|
2478
|
+
rgba(3, 7, 18, 0.96);
|
|
2479
|
+
color: var(--c-text);
|
|
2480
|
+
}
|
|
2481
|
+
|
|
2482
|
+
.html-presentation-exit {
|
|
2483
|
+
position: fixed;
|
|
2484
|
+
top: 12px;
|
|
2485
|
+
right: 12px;
|
|
2486
|
+
z-index: 1;
|
|
2487
|
+
padding: 10px 14px;
|
|
2488
|
+
border: 1px solid var(--c-line);
|
|
2489
|
+
border-radius: 999px;
|
|
2490
|
+
background: var(--c-panel-glass);
|
|
2491
|
+
box-shadow: 0 18px 50px var(--c-shadow-heavy);
|
|
2492
|
+
color: var(--c-text-soft);
|
|
2493
|
+
cursor: pointer;
|
|
2494
|
+
font: 600 12px/1 var(--font);
|
|
2495
|
+
opacity: 0;
|
|
2496
|
+
pointer-events: none;
|
|
2497
|
+
transform: translateY(-6px);
|
|
2498
|
+
transition: opacity 0.15s ease, transform 0.15s ease, border-color 0.15s ease, color 0.15s ease;
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
.html-presentation-exit:hover,
|
|
2502
|
+
.html-presentation-exit:focus-visible {
|
|
2503
|
+
border-color: var(--c-accent);
|
|
2504
|
+
color: var(--c-text);
|
|
2505
|
+
}
|
|
2506
|
+
|
|
2507
|
+
.html-presentation-exit:focus,
|
|
2508
|
+
.html-presentation-exit:focus-visible {
|
|
2509
|
+
opacity: 1;
|
|
2510
|
+
pointer-events: auto;
|
|
2511
|
+
transform: translateY(0);
|
|
2512
|
+
}
|
|
2513
|
+
|
|
2514
|
+
.html-presentation-stage {
|
|
2515
|
+
flex: 1;
|
|
2516
|
+
min-height: 0;
|
|
2517
|
+
display: flex;
|
|
2518
|
+
border-radius: 0;
|
|
2519
|
+
background: var(--c-bg);
|
|
2520
|
+
overflow: hidden;
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
.html-node-frame-presentation {
|
|
2524
|
+
flex: 1;
|
|
2525
|
+
min-height: 0;
|
|
2526
|
+
border-radius: 0 !important;
|
|
2527
|
+
}
|
|
2528
|
+
|
|
2458
2529
|
/* ── Context pin button on node title bar ────────────────────── */
|
|
2459
2530
|
.node-controls .ctx-pin-btn {
|
|
2460
2531
|
color: var(--c-muted);
|