pmx-canvas 0.1.19 → 0.1.21

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 (65) hide show
  1. package/CHANGELOG.md +159 -0
  2. package/Readme.md +19 -6
  3. package/dist/canvas/global.css +123 -2
  4. package/dist/canvas/index.js +103 -68
  5. package/dist/json-render/index.js +109 -109
  6. package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
  7. package/dist/types/client/icons.d.ts +2 -0
  8. package/dist/types/client/nodes/HtmlNode.d.ts +12 -1
  9. package/dist/types/client/state/canvas-store.d.ts +2 -0
  10. package/dist/types/client/types.d.ts +3 -2
  11. package/dist/types/json-render/charts/components.d.ts +5 -1
  12. package/dist/types/json-render/renderer/index.d.ts +1 -0
  13. package/dist/types/json-render/server.d.ts +1 -0
  14. package/dist/types/mcp/canvas-access.d.ts +3 -0
  15. package/dist/types/server/canvas-operations.d.ts +4 -0
  16. package/dist/types/server/canvas-schema.d.ts +19 -3
  17. package/dist/types/server/canvas-serialization.d.ts +1 -0
  18. package/dist/types/server/canvas-state.d.ts +6 -2
  19. package/dist/types/server/html-node-summary.d.ts +2 -0
  20. package/dist/types/server/html-primitives.d.ts +42 -0
  21. package/dist/types/server/index.d.ts +26 -0
  22. package/docs/cli.md +4 -1
  23. package/docs/http-api.md +11 -1
  24. package/docs/mcp.md +10 -4
  25. package/docs/node-types.md +54 -4
  26. package/docs/screenshot.png +0 -0
  27. package/docs/sdk.md +12 -0
  28. package/package.json +1 -1
  29. package/skills/pmx-canvas/SKILL.md +17 -3
  30. package/skills/pmx-canvas/references/html-primitives.md +132 -0
  31. package/src/cli/agent.ts +159 -5
  32. package/src/cli/index.ts +1 -1
  33. package/src/client/App.tsx +21 -2
  34. package/src/client/canvas/AnnotationLayer.tsx +33 -12
  35. package/src/client/canvas/CanvasViewport.tsx +88 -7
  36. package/src/client/canvas/CommandPalette.tsx +2 -2
  37. package/src/client/canvas/ContextMenu.tsx +2 -2
  38. package/src/client/canvas/ExpandedNodeOverlay.tsx +112 -3
  39. package/src/client/canvas/auto-fit.ts +5 -1
  40. package/src/client/icons.tsx +13 -0
  41. package/src/client/nodes/HtmlNode.tsx +125 -13
  42. package/src/client/nodes/McpAppNode.tsx +12 -4
  43. package/src/client/state/canvas-store.ts +15 -5
  44. package/src/client/state/sse-bridge.ts +5 -4
  45. package/src/client/theme/global.css +123 -2
  46. package/src/client/types.ts +2 -1
  47. package/src/json-render/charts/components.tsx +41 -7
  48. package/src/json-render/charts/extra-components.tsx +13 -12
  49. package/src/json-render/renderer/index.tsx +1 -0
  50. package/src/json-render/server.ts +3 -1
  51. package/src/mcp/canvas-access.ts +54 -1
  52. package/src/mcp/server.ts +98 -28
  53. package/src/server/agent-context.ts +39 -0
  54. package/src/server/canvas-operations.ts +99 -38
  55. package/src/server/canvas-provenance.ts +8 -6
  56. package/src/server/canvas-schema.ts +94 -3
  57. package/src/server/canvas-serialization.ts +16 -4
  58. package/src/server/canvas-state.ts +9 -4
  59. package/src/server/demo-state.json +1143 -0
  60. package/src/server/demo.ts +25 -777
  61. package/src/server/html-node-summary.ts +141 -0
  62. package/src/server/html-primitives.ts +1300 -0
  63. package/src/server/index.ts +63 -3
  64. package/src/server/server.ts +154 -17
  65. package/src/server/spatial-analysis.ts +5 -3
package/CHANGELOG.md CHANGED
@@ -3,6 +3,163 @@
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.21] - 2026-05-09
7
+
8
+ HTML communication maturity pass on top of 0.1.20. Adds a
9
+ `presentation` primitive kind (PowerPoint-style decks with themes),
10
+ turns every html node into a first-class agent context surface with
11
+ semantic sidecars (summary, agent summary, description, slide
12
+ titles, embedded refs), wires a real Present-mode overlay with
13
+ iframe-focused keyboard navigation and a live theme bridge, and
14
+ routes the `pmx-canvas html` subcommand correctly through the agent
15
+ CLI.
16
+
17
+ ### Added
18
+
19
+ - **New `presentation` HTML primitive kind.** `canvas_add_html_primitive
20
+ --kind presentation` generates a PowerPoint-style fullscreen deck
21
+ inside the standard sandboxed `html` node and persists the deck
22
+ metadata (`presentation: true`, `slideCount`, `slideTitles`,
23
+ optional `presentationTheme`). Themes: `canvas`, `midnight`,
24
+ `paper`, `aurora`, or a custom color object with `bg`, `panel`,
25
+ `surface`, `border`, `text`, `textSecondary`, `textMuted`,
26
+ `accent`, and `colorScheme`. The MCP canvas now exposes 19 HTML
27
+ primitives (was 18).
28
+ - **HTML node semantic sidecars.** Every html node can now carry
29
+ agent-readable metadata that agents see without parsing the
30
+ iframe payload: `summary`, `agentSummary`, `description`,
31
+ `presentation`, `slideTitles`, `embeddedNodeIds`, `embeddedUrls`.
32
+ Same surface lands on CLI (`pmx-canvas node add --type html
33
+ --summary "..." --agent-summary "..." --description "..."
34
+ --presentation true --slide-title "..." --embedded-node-id ...`),
35
+ HTTP `POST /api/canvas/node`, MCP `canvas_add_html_node`, SDK
36
+ `PmxCanvas.addHtmlNode()`, and `canvas_describe_schema`.
37
+ `agent-context` and `canvas://pinned-context` now expose this
38
+ metadata for HTML nodes.
39
+ - **Auto-derived `contentSummary` for html nodes.** When the agent
40
+ doesn't supply an explicit summary, PMX runs the rendered HTML
41
+ through a new `summarizeHtmlText()` (in
42
+ `src/server/html-node-summary.ts`) to extract a bounded plain-
43
+ text summary that drives search, pinned context, and spatial
44
+ context. `normalizeHtmlNodeSemanticData()` keeps existing
45
+ provenance and semantic fields stable across edits.
46
+ - **Browser-side Present mode.** Presentation-marked html nodes
47
+ surface a Present button in `ExpandedNodeOverlay` that opens a
48
+ fullscreen overlay with the deck iframe focused. Arrow keys,
49
+ Page Up/Down, Space, Home, and End are forwarded into the iframe
50
+ via a token-scoped postMessage bridge, and pressing Escape inside
51
+ the iframe exits via the same bridge. A live theme bridge
52
+ re-injects the canvas theme tokens into the iframe whenever the
53
+ theme changes, so present mode reflects light/dark toggles
54
+ instantly.
55
+ - **`html-primitives.md` skill reference.** New 132-line authoring
56
+ guide under `skills/pmx-canvas/references/` covers when to use
57
+ primitives versus `canvas_add_html_node` versus
58
+ `canvas_build_web_artifact`, the catalog, and shared design
59
+ language.
60
+
61
+ ### Changed
62
+
63
+ - **`canvas_add_html_node` clarifies presentation is opt-in.** The
64
+ MCP tool description now states explicitly that presentation
65
+ mode is opt-in (pass `presentation: true` or use the
66
+ `presentation` primitive) — normal html nodes remain the default
67
+ for reports, widgets, and bespoke visualizations.
68
+ - **Auto-fit no longer shrinks presentation html nodes.** Like
69
+ graph and json-render frames, presentation-marked html nodes
70
+ keep their explicit width and height so decks aren't squeezed
71
+ by the content-fit pass.
72
+ - **`pmx-canvas html` subcommand routes through the agent CLI.**
73
+ Same fix as the earlier `fit` and `screenshot` routing issues —
74
+ `html` is now in the `AGENT_COMMANDS` set in `src/cli/index.ts`
75
+ so it doesn't get treated as a server-startup invocation.
76
+
77
+ ### Internal
78
+
79
+ - Regression coverage for: HTML node semantic sidecars persisting
80
+ through CLI/HTTP/MCP, presentation primitives storing slide
81
+ metadata and theme metadata (named + custom), agent context
82
+ exposing html sidecars and presentation metadata, auto-fit
83
+ excluding presentation html frames, the `html` CLI routing,
84
+ client-side present-mode behavior (only explicit presentation
85
+ html nodes can present; theme bridge injected; srcdoc marker
86
+ distinguishes review vs present mode), live theme update on
87
+ present-mode iframe (e2e), and present mode focusing iframe
88
+ keyboard navigation while hiding review hints (e2e).
89
+
90
+ ## [0.1.20] - 2026-05-06
91
+
92
+ A bigger feature release. Adds 18 reusable HTML communication
93
+ primitives (choice grids, plans, review sheets, system maps, design
94
+ sheets, decks, explainers, status reports, throwaway editors…) so
95
+ agents can stop reaching for long markdown for structured artifacts,
96
+ introduces text annotations alongside the existing pen/eraser, makes
97
+ expanded mcp-app/webpage/json-render/graph viewers stretch to fill
98
+ the overlay, fixes grid arrange to respect grouped children, and
99
+ extracts the project-tour demo to a declarative JSON seed.
100
+
101
+ ### Added
102
+
103
+ - **`canvas_add_html_primitive` and 18 communication primitives.**
104
+ A new MCP tool plus CLI `html primitive add` / `html primitive
105
+ schema` and HTTP `POST /api/canvas/node` with `{type:
106
+ "html-primitive", kind, data}` (or the alternative `{type:
107
+ "html", primitive: kind, data}`) generate sandboxed `html` nodes
108
+ from named primitives: `choice-grid`, `plan-timeline`,
109
+ `review-sheet`, `pr-writeup`, `system-map`, `code-walkthrough`,
110
+ `design-sheet`, `component-gallery`, `interaction-prototype`,
111
+ `flowchart`, `deck`, `illustration-set`, `explainer`,
112
+ `status-report`, `incident-report`, `triage-board`,
113
+ `config-editor`, `prompt-tuner`. The MCP canvas now exposes 42
114
+ tools (was 41). `canvas_describe_schema` adds an `htmlPrimitives`
115
+ array describing each primitive's data shape.
116
+ - **Text annotations.** The annotation toolbar gains a third tool
117
+ alongside pen and eraser. Text annotations render as SVG `<text>`
118
+ using the `--c-annotation` token, persist alongside freehand
119
+ strokes (`type: 'text'` on `CanvasAnnotation`), and route through
120
+ the same HTTP create/delete + canvas-state undo/redo paths as the
121
+ freehand layer.
122
+ - **Declarative demo seed (`src/server/demo-state.json`).** The
123
+ project-tour demo is now a 28KB JSON snapshot loaded by a small
124
+ `demo.ts` shim, replacing the 800-line imperative seed. Editing
125
+ the tour is now a JSON edit, and the unit tests exercise the
126
+ loader and verify a stable grouped layout.
127
+ - **Install section in the README.** Documents `bunx pmx-canvas`,
128
+ `bun add -g pmx-canvas`, `bun add pmx-canvas` (for the SDK), and
129
+ `npm install -g pmx-canvas`, plus the Bun-on-PATH caveat (the
130
+ CLI uses a `#!/usr/bin/env bun` shebang). (Released as commits
131
+ `f9449e5`, `fe0843c`.)
132
+
133
+ ### Changed
134
+
135
+ - **Expanded mcp-app / webpage / json-render / graph viewers
136
+ stretch to fill the overlay.** `ExpandedNodeOverlay` now wraps
137
+ embedded viewers in a flex container, json-render and graph
138
+ viewers receive `?display=expanded` in the URL plus a
139
+ `window.__PMX_CANVAS_JSON_RENDER_DISPLAY__` global, and a new
140
+ `useChartFrameHeight()` hook computes available content height
141
+ dynamically. Expanded charts no longer leave a white band at the
142
+ bottom of the overlay.
143
+ - **Grid arrange preserves grouped child offsets.** The arrange
144
+ algorithm in the new shared `auto-arrange.ts` excludes grouped
145
+ children from translation. Previously the parent group was moved
146
+ *and* the child was moved relative to it, double-translating the
147
+ child off-screen. Undo restores the original positions exactly.
148
+ - **CommandPalette gains a "New note" markdown shortcut.** Quick-
149
+ add a `markdown` node from the palette with the standard
150
+ 520×360 default size.
151
+
152
+ ### Internal
153
+
154
+ - Regression coverage for: HTML primitive CLI/MCP creation
155
+ producing searchable html nodes with primitive metadata, text
156
+ annotation persistence and HTTP create/delete, grid arrange
157
+ preserving grouped child offsets through the operation and its
158
+ undo, declarative demo seed loading into a stable grouped layout,
159
+ graph chart-height absent unless explicitly provided, and
160
+ expanded graph nodes stretching content to the overlay frame
161
+ (e2e), plus pen and text annotations starting over nodes (e2e).
162
+
6
163
  ## [0.1.19] - 2026-05-05
7
164
 
8
165
  Snapshot ergonomics and reference-doc distribution. Adds `before` /
@@ -824,6 +981,8 @@ otherwise have to discover by trial and error.
824
981
  - Regression coverage for snapshot flat-`id` aliases on both MCP and
825
982
  HTTP surfaces, plus async / top-level-`await` WebView script bodies.
826
983
 
984
+ [0.1.21]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.21
985
+ [0.1.20]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.20
827
986
  [0.1.19]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.19
828
987
  [0.1.18]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.18
829
988
  [0.1.17]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.17
package/Readme.md CHANGED
@@ -65,7 +65,7 @@ the canvas durable rather than throwaway.
65
65
 
66
66
  ### 06 / Any agent
67
67
 
68
- Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (41 tools,
68
+ Harness-agnostic. Drive the canvas from [MCP](docs/mcp.md) (42 tools,
69
69
  8 resources, change notifications), the [CLI](docs/cli.md), the
70
70
  [HTTP API](docs/http-api.md), or the [Bun SDK](docs/sdk.md). Works with
71
71
  Claude Code, GitHub Copilot CLI, Codex, Cursor, Windsurf, or any agent
@@ -78,22 +78,35 @@ that can spawn an MCP stdio server, call a CLI, or hit an HTTP endpoint.
78
78
  The published SDK entrypoint is Bun-first. Node.js consumers should use the
79
79
  CLI, MCP server, or HTTP API.
80
80
 
81
+ ## Install
82
+
83
+ ```bash
84
+ bunx pmx-canvas # Run without installing (recommended for one-off use)
85
+ bun add -g pmx-canvas # Install globally — exposes the `pmx-canvas` command
86
+ bun add pmx-canvas # Install into a project (needed for the Bun SDK)
87
+ npm install -g pmx-canvas # npm works too — still requires Bun on PATH to run
88
+ ```
89
+
90
+ `pmx-canvas` is Bun-first: the CLI is a TypeScript file with a `#!/usr/bin/env bun`
91
+ shebang, so Bun must be installed even when you fetch the package via npm or pnpm.
92
+
93
+ To work on the canvas itself, clone the repo — see [Development](#development).
94
+
81
95
  ## Quick start
82
96
 
83
97
  ### Run the canvas
84
98
 
85
99
  ```bash
86
100
  bunx pmx-canvas # Start canvas, open browser
87
- bunx pmx-canvas --demo # Start with the project-tour demo board
101
+ bunx pmx-canvas --demo # Start with the saved dashboard demo board
88
102
  bunx pmx-canvas --no-open # Headless (good for daemons / CI)
89
103
  bunx pmx-canvas --mcp # Run as MCP server (stdio)
90
104
  bunx pmx-canvas --help # All commands
91
105
  ```
92
106
 
93
107
  The canvas opens at `http://localhost:4313`. Try `--demo` first — it seeds a
94
- project tour with grouped markdown, status, file, image, webpage,
95
- json-render, graph, html, Excalidraw diagram, and MCP App nodes connected by
96
- labeled edges.
108
+ saved dashboard with grouped OKR notes, graph panels, context pins, and labeled
109
+ edges.
97
110
 
98
111
  ### Connect your agent (MCP)
99
112
 
@@ -143,7 +156,7 @@ the agent can read `canvas://skills` and pull in companion skills
143
156
  the three-tier visual matrix (json-render → html → web-artifact)
144
157
  - **[CLI reference](docs/cli.md)** — full command surface, daemon mode,
145
158
  watch streams, WebView automation
146
- - **[MCP reference](docs/mcp.md)** — 41 tools, 8 resources, change
159
+ - **[MCP reference](docs/mcp.md)** — 42 tools, 8 resources, change
147
160
  notifications, node-type routing
148
161
  - **[HTTP API](docs/http-api.md)** — REST endpoints, SSE, batch operations
149
162
  - **[Bun SDK](docs/sdk.md)** — `createCanvas()` for TypeScript on Bun
@@ -392,6 +392,19 @@ body,
392
392
  margin: 0.4em 0;
393
393
  color: var(--c-muted);
394
394
  }
395
+
396
+ .canvas-node .node-body ul,
397
+ .canvas-node .node-body ol {
398
+ margin: 0.4em 0;
399
+ padding-left: 0.25em;
400
+ list-style-position: inside;
401
+ }
402
+
403
+ .canvas-node .node-body li {
404
+ margin: 0.2em 0;
405
+ padding-left: 0.15em;
406
+ }
407
+
395
408
  .canvas-node .node-body a {
396
409
  color: var(--c-accent);
397
410
  text-decoration: none;
@@ -1481,14 +1494,14 @@ body,
1481
1494
  height: 1px;
1482
1495
  overflow: visible;
1483
1496
  pointer-events: none;
1484
- z-index: 45;
1497
+ z-index: 9000;
1485
1498
  }
1486
1499
 
1487
1500
  .annotation-capture-layer {
1488
1501
  position: absolute;
1489
1502
  inset: 0;
1490
1503
  z-index: 9996;
1491
- pointer-events: none;
1504
+ pointer-events: auto;
1492
1505
  background: color-mix(in srgb, var(--c-accent) 5%, transparent);
1493
1506
  }
1494
1507
 
@@ -1496,6 +1509,26 @@ body,
1496
1509
  background: color-mix(in srgb, var(--c-danger) 6%, transparent);
1497
1510
  }
1498
1511
 
1512
+ .annotation-capture-layer.text {
1513
+ background: color-mix(in srgb, var(--c-annotation) 4%, transparent);
1514
+ }
1515
+
1516
+ .annotation-text-input {
1517
+ position: absolute;
1518
+ z-index: 9997;
1519
+ min-width: 120px;
1520
+ max-width: min(560px, calc(100% - 24px));
1521
+ padding: 2px 4px;
1522
+ border: 1px solid var(--c-annotation);
1523
+ border-radius: 4px;
1524
+ background: color-mix(in srgb, var(--c-bg) 72%, transparent);
1525
+ color: var(--c-annotation);
1526
+ font-family: var(--font);
1527
+ font-weight: 700;
1528
+ line-height: 1.15;
1529
+ outline: none;
1530
+ }
1531
+
1499
1532
  /* ── Drop Zone (file drag-and-drop) ─────────────────────────── */
1500
1533
  .drop-zone-overlay {
1501
1534
  position: absolute;
@@ -2405,6 +2438,18 @@ body,
2405
2438
  border-color: var(--c-muted);
2406
2439
  }
2407
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
+
2408
2453
  .expanded-action-btn.expanded-action-active {
2409
2454
  background: var(--c-warn-12);
2410
2455
  border-color: var(--c-warn-30);
@@ -2422,6 +2467,82 @@ body,
2422
2467
  padding: 0 4px;
2423
2468
  }
2424
2469
 
2470
+ .html-presentation-overlay {
2471
+ position: fixed;
2472
+ inset: 0;
2473
+ z-index: 10050;
2474
+ display: flex;
2475
+ flex-direction: column;
2476
+ gap: 14px;
2477
+ padding: clamp(12px, 2vw, 28px);
2478
+ background:
2479
+ radial-gradient(circle at top left, var(--c-accent-25), transparent 36rem),
2480
+ rgba(3, 7, 18, 0.96);
2481
+ color: var(--c-text);
2482
+ }
2483
+
2484
+ .html-presentation-toolbar {
2485
+ display: flex;
2486
+ align-items: center;
2487
+ justify-content: space-between;
2488
+ gap: 16px;
2489
+ flex-shrink: 0;
2490
+ padding: 10px 12px;
2491
+ border: 1px solid var(--c-line);
2492
+ border-radius: 16px;
2493
+ background: var(--c-panel-glass);
2494
+ box-shadow: 0 18px 50px var(--c-shadow-heavy);
2495
+ }
2496
+
2497
+ .html-presentation-kicker {
2498
+ color: var(--c-accent);
2499
+ font-size: 10px;
2500
+ font-weight: 800;
2501
+ letter-spacing: 0.14em;
2502
+ text-transform: uppercase;
2503
+ }
2504
+
2505
+ .html-presentation-title {
2506
+ max-width: min(72vw, 900px);
2507
+ overflow: hidden;
2508
+ color: var(--c-text);
2509
+ font-size: 14px;
2510
+ font-weight: 700;
2511
+ text-overflow: ellipsis;
2512
+ white-space: nowrap;
2513
+ }
2514
+
2515
+ .html-presentation-exit {
2516
+ flex-shrink: 0;
2517
+ padding: 8px 12px;
2518
+ border: 1px solid var(--c-line);
2519
+ border-radius: 999px;
2520
+ background: var(--c-panel-soft);
2521
+ color: var(--c-text-soft);
2522
+ cursor: pointer;
2523
+ font: 600 12px/1 var(--font);
2524
+ }
2525
+
2526
+ .html-presentation-exit:hover {
2527
+ border-color: var(--c-accent);
2528
+ color: var(--c-text);
2529
+ }
2530
+
2531
+ .html-presentation-stage {
2532
+ flex: 1;
2533
+ min-height: 0;
2534
+ display: flex;
2535
+ border-radius: 22px;
2536
+ background: var(--c-bg);
2537
+ box-shadow: 0 24px 90px rgba(0, 0, 0, 0.55);
2538
+ overflow: hidden;
2539
+ }
2540
+
2541
+ .html-node-frame-presentation {
2542
+ flex: 1;
2543
+ min-height: 0;
2544
+ }
2545
+
2425
2546
  /* ── Context pin button on node title bar ────────────────────── */
2426
2547
  .node-controls .ctx-pin-btn {
2427
2548
  color: var(--c-muted);