pmx-canvas 0.1.3 → 0.1.5

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 CHANGED
@@ -3,6 +3,144 @@
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.5] - 2026-04-26
7
+
8
+ Image-validation hardening + CLI ergonomics. The boundary where untrusted
9
+ file paths become canvas state now validates magic bytes, and common CLI
10
+ typos produce one-line suggestions instead of help-block dumps.
11
+
12
+ ### Added
13
+
14
+ - **Magic-byte validation for local image nodes.** PNG / JPEG / GIF / SVG /
15
+ WebP / BMP / ICO / AVIF headers are sniffed before a file becomes an
16
+ `image` node. A file renamed `screenshot.png` containing PowerPoint XML
17
+ is now rejected with a clear error before it reaches the renderer.
18
+ - **macOS cloud-on-demand placeholder detection.** Files in iCloud Drive,
19
+ OneDrive, etc. that are not yet downloaded locally are detected via
20
+ `stat -f %Xf` flags and rejected with a hint to download them first —
21
+ no more silent freezes when an iCloud-only file is dropped on the canvas.
22
+ - **`/bin/dd` escape hatch with a 5s timeout** for macOS-only paths where
23
+ the direct fs read could hang on an unresponsive volume (e.g. an
24
+ unmounted SMB share that still satisfies `existsSync`). Distinguishes
25
+ timeout (`SIGTERM` / `ETIMEDOUT`) from generic spawn failures so the
26
+ cloud-storage hint isn't shown for unrelated errors.
27
+ - **CLI typo hints for resource subcommands.**
28
+ - `pmx-canvas node delete <id>` and `pmx-canvas node rm <id>` exit 1 with
29
+ `Did you mean: pmx-canvas node remove?`.
30
+ - `pmx-canvas edge delete <id>` and `pmx-canvas edge rm <id>` get the
31
+ same treatment.
32
+ - `pmx-canvas node pin <id>` redirects to the top-level
33
+ `pmx-canvas pin <id>` command.
34
+
35
+ ### Changed
36
+
37
+ - **`GET /api/canvas/image/:id` is now async** (`fs/promises.readFile`) and
38
+ validates content before serving — returns **400** on invalid image bytes
39
+ instead of 200 with `application/octet-stream`.
40
+ - **Bare `pmx-canvas node` (no subcommand)** now exits 1 with structured
41
+ JSON instead of printing the resource help block. Use
42
+ `pmx-canvas node --help` for the listing.
43
+
44
+ ### Internal
45
+
46
+ - New module `src/server/image-source.ts` extracts and extends image
47
+ validation from `canvas-operations.ts`. Same error contract; richer
48
+ checks. The MCP and HTTP layers both flow through `addCanvasNode`, so
49
+ CLAUDE.md rule #5 (four-layer parity) is preserved without touching
50
+ the SDK or MCP server.
51
+ - Direct fs read is the fast path on every platform (no fork, no shell);
52
+ `dd` is only consulted on macOS as a fallback when direct read fails on
53
+ a path that wasn't flagged as a placeholder.
54
+ - Real magic-byte fixtures in `tests/unit/canvas-operations.test.ts` (was:
55
+ `*.png` extension smoke tests). New HTTP coverage in
56
+ `tests/unit/server-api.test.ts` for valid / invalid / missing image
57
+ paths. New CLI coverage for `node delete`, `node pin`, `edge delete`,
58
+ `edge rm` typo hints.
59
+
60
+ [0.1.5]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.5
61
+
62
+ ## [0.1.4] - 2026-04-26
63
+
64
+ Graph/CLI ergonomics + canvas-node taxonomy hardening. Three threads:
65
+ (1) full graph payload surface (`zKey`, `axisKey`, `metrics`, `series`,
66
+ `barKey`/`lineKey`, `barColor`/`lineColor`) reaches CLI/MCP/HTTP/batch with
67
+ both kebab-case and camelCase flag aliases, (2) `mcp-app` nodes serialize a
68
+ `kind` discriminator so agents can target `web-artifact` / `external-app` /
69
+ `mcp-app` subtypes without inspecting `data`, (3) the long-standing
70
+ `ext-app-ext-app-…` double-prefix bug on node IDs is fixed with explicit
71
+ `nodeId` propagation through SSE.
72
+
73
+ ### Added
74
+
75
+ - Serialized `kind` discriminator on every canvas node. `mcp-app` nodes now
76
+ surface as `web-artifact`, `external-app`, or `mcp-app` so agents can
77
+ filter via `node list --type web-artifact` or
78
+ `--type external-app` directly.
79
+ - Full graph payload surface on MCP, HTTP `validate-spec`, and `batch`:
80
+ `zKey`, `axisKey`, `metrics`, `series`, `barKey`, `lineKey`, `barColor`,
81
+ `lineColor`. Radar (`metrics`), stacked-bar (`series`), and composed
82
+ (`barKey`/`lineKey`) configs are now uniformly addressable.
83
+ - CLI camelCase aliases for graph flags: `--graphType`, `--xKey`, `--yKey`,
84
+ `--zKey`, `--axisKey`, `--barKey`, `--lineKey`, `--barColor`,
85
+ `--lineColor`, alongside existing kebab-case forms. Same fields land in
86
+ `canvas_validate_spec` and `canvas_batch`.
87
+ - `id` field on `external-app add` / `canvas_open_mcp_app` /
88
+ `canvas_add_diagram` responses (alias for the canvas node ID, matches
89
+ HTTP).
90
+ - `viewerType: 'web-artifact'` persisted on web-artifact mcp-app nodes for
91
+ authoritative `kind` classification.
92
+
93
+ ### Changed
94
+
95
+ - `SerializedCanvasNode` now includes `kind: string` (additive; consumers
96
+ grouping by `type === 'mcp-app'` should switch to `kind`).
97
+ - `canvas://summary` `typeCounts` keys are derived from `kind`, not `type` —
98
+ `mcp-app` totals split into `web-artifact` / `external-app` / `mcp-app`.
99
+ - Charts wrap with type-specific CSS modifier classes
100
+ (`pmx-chart--line/--bar/--pie/--area/--scatter/--radar/--stacked-bar/--composed`)
101
+ and per-type minimum widths, so axes don't clip in narrow nodes.
102
+ - `canvas-schema.ts` cleanup based on the v0.1.4 review:
103
+ - `nodeHeight` no longer aliases `height` (collision with the chart-content
104
+ `height` field). Use `--node-height` going forward; `--height` always
105
+ means chart content height.
106
+ - `stdin` removed from the `data` and `appTsx` aliases — `--stdin` is an
107
+ input-mode (read from pipe), not a flag synonym. Behavior unchanged;
108
+ schema is now accurate.
109
+
110
+ ### Fixed
111
+
112
+ - Excalidraw / external-app node IDs no longer double-prefix to
113
+ `ext-app-ext-app-…`. The canvas node ID retains the `ext-app-` prefix; the
114
+ `toolCallId` is the random suffix only.
115
+ - SSE `ext-app-open` / `ext-app-update` / `ext-app-result` events now carry
116
+ an explicit `nodeId` so the client and server agree on node identity even
117
+ after the ID-format change.
118
+ - `getCanvasNodeKind` precedence reordered so a future URL-only web-artifact
119
+ (no `data.path`) still classifies correctly via `viewerType`. The legacy
120
+ `hostMode + path` heuristic is now an explicitly-documented backwards-compat
121
+ fallback for canvas state.json files persisted before v0.1.4.
122
+
123
+ ### Internal
124
+
125
+ - `findCanvasExtAppNodeId` extracted into `src/server/ext-app-lookup.ts` and
126
+ shared between `src/server/index.ts` and `src/server/server.ts` (was
127
+ duplicated; drift risk eliminated).
128
+ - `shouldReplayAppToolResult` documented with explicit intent: only `isError`
129
+ or `structuredContent` results overwrite the bootstrap-replay
130
+ `toolResult`, so a plain-text `read_checkpoint`-style return doesn't
131
+ clobber widget state on reload.
132
+ - E2E coverage now exercises camelCase graph flags and asserts the
133
+ single-prefix node-ID fix.
134
+ - New unit coverage:
135
+ - `kind` discriminator across fresh, URL-only, legacy, ext-app, and
136
+ plain-mcp-app paths (6 tests).
137
+ - Camel-case graph flags in CLI.
138
+ - Full-surface graph validation in MCP `canvas_validate_spec`.
139
+ - Single-prefix node-ID round-trip in `external-app add`.
140
+ - Post-restart text-tool replay semantics.
141
+
142
+ [0.1.4]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.4
143
+
6
144
  ## [0.1.3] - 2026-04-25
7
145
 
8
146
  CLI hardening release with full MCP parity for the new affordances. Closes