pmx-canvas 0.1.18 → 0.1.20

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 (70) hide show
  1. package/CHANGELOG.md +128 -0
  2. package/Readme.md +19 -6
  3. package/dist/canvas/global.css +35 -2
  4. package/dist/canvas/index.js +70 -69
  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/state/canvas-store.d.ts +2 -0
  9. package/dist/types/client/types.d.ts +2 -1
  10. package/dist/types/json-render/charts/components.d.ts +5 -1
  11. package/dist/types/json-render/renderer/index.d.ts +1 -0
  12. package/dist/types/json-render/server.d.ts +1 -0
  13. package/dist/types/mcp/canvas-access.d.ts +3 -0
  14. package/dist/types/server/canvas-operations.d.ts +4 -0
  15. package/dist/types/server/canvas-schema.d.ts +19 -3
  16. package/dist/types/server/canvas-serialization.d.ts +1 -0
  17. package/dist/types/server/canvas-state.d.ts +8 -2
  18. package/dist/types/server/html-primitives.d.ts +34 -0
  19. package/dist/types/server/index.d.ts +19 -0
  20. package/docs/RELEASE.md +153 -0
  21. package/docs/bun-webview-integration.md +296 -0
  22. package/docs/cli.md +143 -0
  23. package/docs/evals/e2e-cli-coverage.md +61 -0
  24. package/docs/http-api.md +201 -0
  25. package/docs/mcp.md +137 -0
  26. package/docs/node-types.md +272 -0
  27. package/docs/plans/.gitkeep +0 -0
  28. package/docs/plans/plan-001-semantic-watch-mvp.md +335 -0
  29. package/docs/plans/plan-002-human-attention-layer-design-spec.md +679 -0
  30. package/docs/plans/plan-003-human-attention-layer-implementation-plan.md +572 -0
  31. package/docs/reactive-canvas-proposal.md +578 -0
  32. package/docs/release-review-0.1.0.md +38 -0
  33. package/docs/screenshot.png +0 -0
  34. package/docs/screenshots/demo-workbench-dark.png +0 -0
  35. package/docs/screenshots/demo-workbench-light.png +0 -0
  36. package/docs/screenshots/welcome-dark.png +0 -0
  37. package/docs/screenshots/welcome-light.png +0 -0
  38. package/docs/sdk.md +103 -0
  39. package/package.json +2 -1
  40. package/skills/pmx-canvas/SKILL.md +8 -0
  41. package/src/cli/agent.ts +167 -5
  42. package/src/client/App.tsx +20 -1
  43. package/src/client/canvas/AnnotationLayer.tsx +33 -12
  44. package/src/client/canvas/CanvasViewport.tsx +88 -7
  45. package/src/client/canvas/CommandPalette.tsx +1 -1
  46. package/src/client/canvas/ContextMenu.tsx +2 -2
  47. package/src/client/canvas/ExpandedNodeOverlay.tsx +7 -1
  48. package/src/client/icons.tsx +13 -0
  49. package/src/client/nodes/McpAppNode.tsx +12 -4
  50. package/src/client/state/canvas-store.ts +15 -5
  51. package/src/client/state/sse-bridge.ts +4 -3
  52. package/src/client/theme/global.css +35 -2
  53. package/src/client/types.ts +2 -1
  54. package/src/json-render/charts/components.tsx +41 -7
  55. package/src/json-render/charts/extra-components.tsx +13 -12
  56. package/src/json-render/renderer/index.tsx +1 -0
  57. package/src/json-render/server.ts +3 -1
  58. package/src/mcp/canvas-access.ts +25 -0
  59. package/src/mcp/server.ts +85 -27
  60. package/src/server/agent-context.ts +17 -0
  61. package/src/server/canvas-operations.ts +91 -38
  62. package/src/server/canvas-schema.ts +83 -3
  63. package/src/server/canvas-serialization.ts +9 -2
  64. package/src/server/canvas-state.ts +27 -9
  65. package/src/server/demo-state.json +1143 -0
  66. package/src/server/demo.ts +25 -777
  67. package/src/server/html-primitives.ts +990 -0
  68. package/src/server/index.ts +43 -2
  69. package/src/server/server.ts +140 -14
  70. package/src/server/spatial-analysis.ts +3 -3
@@ -0,0 +1,578 @@
1
+ # Reactive Canvas Proposal
2
+
3
+ > Status: Proposal
4
+ > Date: 2026-03-31
5
+ > Scope: PMX Canvas architecture extension in this repo
6
+
7
+ ## Decision
8
+
9
+ Build **Reactive Canvas: a live operating graph powered by a generalized reaction engine**.
10
+
11
+ This merges the two ideas:
12
+
13
+ - **Live Operating Graph** is the right product surface: live data on the canvas, semantic edges, AI synthesis, and durable outputs.
14
+ - **Canvas Reactions** is the right architectural kernel: it fits the current codebase and turns one-off computed behaviors into a general capability.
15
+
16
+ The single smartest addition is not query nodes alone and not rules alone. It is making the canvas itself **executable**: nodes and edges become a reactive program the human and agent shape together.
17
+
18
+ ## Evaluation of the Two Inputs
19
+
20
+ ### 1. "Live Operating Graph" is stronger on user value
21
+
22
+ It points at the clearest step-change in PMX:
23
+
24
+ - the canvas remembers and updates what matters
25
+ - cross-source synthesis becomes ambient instead of prompt-by-prompt
26
+ - spatial arrangement becomes configuration, not just presentation
27
+
28
+ It is compelling because it changes daily behavior:
29
+
30
+ - fewer repeated prompts
31
+ - less tab-juggling
32
+ - less manual synthesis across Jira, GitHub, Slack, and metrics
33
+ - clearer evidence trails when promoting an insight into durable memory
34
+
35
+ ### 2. "Canvas Reactions" is stronger on implementation leverage
36
+
37
+ It matches this repo unusually well.
38
+
39
+ This codebase already has the core ingredients:
40
+
41
+ - **authoritative server state** in [`src/server/canvas-state.ts`](../src/server/canvas-state.ts)
42
+ - **disk persistence** to `.pmx-canvas.json` plus named snapshots
43
+ - **mutation recording / suppression** for computed changes
44
+ - **SSE fanout** to keep the browser synced
45
+ - **MCP / HTTP / SDK parity** as an explicit architectural rule
46
+ - a real computed special case today: [`src/server/code-graph.ts`](../src/server/code-graph.ts) auto-generates dependency edges from file nodes using `withSuppressedRecording()`
47
+
48
+ That means reactions are not a foreign idea. The repo already contains one hardcoded reaction system; it is just not generalized yet.
49
+
50
+ ### 3. The right merge
51
+
52
+ Treat **reactions as the engine** and **live operating graph primitives as built-in reaction types**.
53
+
54
+ Concretely:
55
+
56
+ - query nodes are reaction-driven data sources
57
+ - formula nodes are reaction-driven synthesis sinks
58
+ - semantic edges define propagation semantics
59
+ - custom reaction rules expose the engine directly when users need it
60
+ - promotion/export is the durable output seam
61
+
62
+ ## Repo Reality
63
+
64
+ The proposal should follow the code that exists, not the platform we wish were already here.
65
+
66
+ ### What exists now
67
+
68
+ - Server-owned singleton canvas state
69
+ - SSE layout reconciliation
70
+ - Full node / edge persistence on disk
71
+ - Snapshot save / restore UX
72
+ - Grouping, selection, pinning, search, spatial analysis, code graph, undo / redo
73
+
74
+ ### What does not exist in this checkout
75
+
76
+ - `product-graph.ts`
77
+ - `work-graph.ts`
78
+ - a durable evidence store
79
+ - a multi-canvas board library
80
+
81
+ That matters. In this repo, "promote to product memory" should be designed as an **export / integration seam**, not as a direct mutation into modules that are not present.
82
+
83
+ ### Important implication
84
+
85
+ The original "saved canvases in localStorage" idea is not the right foundation here.
86
+
87
+ This repo already persists:
88
+
89
+ - server state to `.pmx-canvas.json`
90
+ - snapshots to `.pmx-canvas-snapshots/`
91
+ - client layout overrides to localStorage as a cache
92
+
93
+ So the first implementation should build on **server persistence and snapshots**, not invent a second persistence model.
94
+
95
+ ## Implementation Hazards To Address Early
96
+
97
+ These are not reasons to avoid the feature. They are the specific places where the current architecture needs to be tightened first.
98
+
99
+ ### 1. Change notifications are too coarse
100
+
101
+ `CanvasStateManager` only emits `'nodes' | 'pins'` level change notifications today.
102
+
103
+ Reactive propagation will need more precise events, for example:
104
+
105
+ - node added / updated / removed
106
+ - edge added / removed
107
+ - node pinned / unpinned
108
+ - query refreshed
109
+ - formula computed
110
+
111
+ ### 2. Derived edges need provenance
112
+
113
+ The current code-graph feature identifies computed edges by ID prefix. That works for one built-in behavior, but it will not scale once multiple derived systems coexist.
114
+
115
+ Reactive Canvas should add explicit edge provenance, for example:
116
+
117
+ - `source: 'manual' | 'system'`
118
+ - `sourceKind: 'code-graph' | 'query-runtime' | 'reaction'`
119
+
120
+ Without that, manual and computed edges will collide semantically and operationally.
121
+
122
+ ### 3. Batch updates need to participate in the same event model
123
+
124
+ The runtime already has multiple mutation paths. Before adding reactions, all server-side writes should reliably drive:
125
+
126
+ - persistence
127
+ - SSE updates
128
+ - undo / redo where appropriate
129
+ - resource notifications
130
+
131
+ Reactive behavior built on an incomplete mutation stream will become nondeterministic.
132
+
133
+ ## Proposed Feature
134
+
135
+ ### Core concept
136
+
137
+ Reactive Canvas turns the canvas into a live, typed graph:
138
+
139
+ - **sources** emit change events
140
+ - **history** records what changed and why
141
+ - **edges** define propagation meaning
142
+ - **sinks** recompute when upstream inputs change
143
+ - **rules** automate common canvas behaviors
144
+ - **exports** capture durable evidence when needed
145
+
146
+ ### Primitive 1: Query Nodes
147
+
148
+ Add a new node type: `query`.
149
+
150
+ Query nodes bind to a data-producing tool call and refresh on a schedule or manually.
151
+
152
+ ```ts
153
+ interface QueryNodeData {
154
+ title: string;
155
+ serverName: string;
156
+ toolName: string;
157
+ toolArgs: Record<string, unknown>;
158
+ refreshIntervalMs: number;
159
+ displayMode: 'count' | 'list' | 'table' | 'sparkline';
160
+ lastResult?: unknown;
161
+ lastResultAt?: string;
162
+ lastError?: string;
163
+ status: 'idle' | 'refreshing' | 'error';
164
+ }
165
+ ```
166
+
167
+ The first implementation should not depend on arbitrary external MCP transport inside the browser. Query execution should be **server-side**, then pushed over the existing SSE channel.
168
+
169
+ ### Primitive 2: Causal Change Ledger
170
+
171
+ Add a persisted causal ledger that records reactive changes as first-class events.
172
+
173
+ This is not just mutation history. It captures:
174
+
175
+ - what changed
176
+ - when it changed
177
+ - what caused it
178
+ - which upstream nodes were involved
179
+ - which reaction or runtime path fired
180
+ - what the previous and new outputs were
181
+
182
+ ```ts
183
+ interface ReactiveEventRecord {
184
+ id: string;
185
+ at: string;
186
+ kind:
187
+ | 'query-diff'
188
+ | 'reaction-fired'
189
+ | 'formula-computed'
190
+ | 'promotion-created'
191
+ | 'manual-override';
192
+ nodeId?: string;
193
+ edgeIds?: string[];
194
+ causeNodeIds?: string[];
195
+ reactionId?: string;
196
+ summary: string;
197
+ before?: unknown;
198
+ after?: unknown;
199
+ metadata?: Record<string, unknown>;
200
+ }
201
+ ```
202
+
203
+ User-facing value:
204
+
205
+ - "What changed since yesterday?"
206
+ - "Why did this node turn red?"
207
+ - "What caused this formula result?"
208
+ - "What changed since I last opened this canvas?"
209
+
210
+ The ledger is what makes the reactive system trustworthy. Without it, the canvas updates live but cannot explain itself.
211
+
212
+ ### Primitive 3: Semantic Edges
213
+
214
+ Extend the edge type union with:
215
+
216
+ - `feeds`
217
+ - `compares`
218
+ - `blocks`
219
+ - `measures`
220
+
221
+ Existing edge types stay.
222
+
223
+ Meaning:
224
+
225
+ - `feeds`: upstream data should trigger downstream recomputation
226
+ - `compares`: side-by-side delta or contradiction analysis
227
+ - `blocks`: dependency / blocker propagation and attention signaling
228
+ - `measures`: compare live state against target / policy / goal
229
+
230
+ These edges are not just styling. They become routing hints for the reactive engine.
231
+
232
+ ### Primitive 4: Formula-Capable Nodes
233
+
234
+ Do **not** require a brand-new `formula` node type first.
235
+
236
+ Instead, let existing display nodes become formula-capable via metadata:
237
+
238
+ ```ts
239
+ interface FormulaData {
240
+ formula: string;
241
+ computeStatus: 'idle' | 'computing' | 'stale' | 'error';
242
+ lastComputedAt?: string;
243
+ lastComputedResult?: string;
244
+ }
245
+ ```
246
+
247
+ This keeps the UI surface smaller:
248
+
249
+ - markdown node + formula = narrative synthesis
250
+ - status node + formula = compact health signal
251
+ - json-render / graph node + formula = structured synthesis later
252
+
253
+ ### Primitive 5: Reaction Engine
254
+
255
+ Add a generalized server-side reaction runtime.
256
+
257
+ ```ts
258
+ interface CanvasReaction {
259
+ id: string;
260
+ name: string;
261
+ enabled: boolean;
262
+ trigger:
263
+ | { event: 'node-added' | 'node-updated' | 'node-removed' | 'edge-added' | 'edge-removed' }
264
+ | { event: 'node-pinned' | 'node-unpinned' }
265
+ | { event: 'query-refreshed' }
266
+ | { event: 'formula-computed' }
267
+ | { event: 'manual' };
268
+ match?: Record<string, unknown>;
269
+ action: Record<string, unknown>;
270
+ source: 'system' | 'user' | 'agent';
271
+ }
272
+ ```
273
+
274
+ Key point: **query refresh and formula recompute are just system reactions**.
275
+
276
+ That gives one engine with two layers:
277
+
278
+ - **built-in reactions** for query polling, propagation, code-graph recompute, formula evaluation
279
+ - **user / agent-authored reactions** later for things like auto-pin, auto-expand imports, and group summarization
280
+
281
+ ### Primitive 6: Promote / Export
282
+
283
+ This belongs in the design, but not as a direct write into nonexistent product/work graph modules.
284
+
285
+ In this repo, the correct v1 shape is:
286
+
287
+ - `canvas_promote(...)` creates a structured evidence bundle
288
+ - bundle can be written to markdown / JSON in the workspace
289
+ - bundle can later be consumed by PMX proper or another host system
290
+
291
+ That keeps PMX Canvas standalone while preserving the future bridge to product memory.
292
+
293
+ ## Why This Merge Is Better Than Either Proposal Alone
294
+
295
+ ### Better than Live Operating Graph alone
296
+
297
+ Without reactions, query nodes, formula nodes, semantic edges, causal history, and saved boards risk becoming separate features with duplicated scheduling, propagation, and state logic.
298
+
299
+ ### Better than Reactions alone
300
+
301
+ Without live data and synthesis primitives, reactions are clever but niche. They help debugging boards, but they do not create the broader category-defining surface.
302
+
303
+ ### The merged shape
304
+
305
+ The canvas becomes:
306
+
307
+ - a **live dashboard**
308
+ - a **causal memory**
309
+ - a **spatial synthesis surface**
310
+ - a **reaction graph**
311
+ - an **evidence capture surface**
312
+
313
+ All with one conceptual model.
314
+
315
+ ## Proposed Implementation Strategy
316
+
317
+ ### Phase 1: Generalize the Runtime
318
+
319
+ Goal: create the engine before adding more surface area.
320
+
321
+ New files:
322
+
323
+ - `src/server/reaction-engine.ts`
324
+ - `src/server/query-runtime.ts`
325
+
326
+ Modified files:
327
+
328
+ - `src/server/canvas-state.ts`
329
+ - `src/server/index.ts`
330
+ - `src/server/server.ts`
331
+ - `src/mcp/server.ts`
332
+
333
+ Deliverables:
334
+
335
+ - richer typed canvas events
336
+ - server-side reaction registry
337
+ - typed canvas event stream for reactions
338
+ - reaction-safe computed mutations using existing suppression pattern
339
+ - provenance for derived edges / derived node updates
340
+ - query scheduling as built-in reactions
341
+
342
+ Why first:
343
+
344
+ - it subsumes the current hardcoded code-graph pattern cleanly
345
+ - it prevents query / formula logic from being bolted on separately
346
+
347
+ ### Phase 2: Ship Query Nodes
348
+
349
+ Goal: first visible user value.
350
+
351
+ New files:
352
+
353
+ - `src/client/nodes/QueryNode.tsx`
354
+
355
+ Modified files:
356
+
357
+ - `src/server/canvas-state.ts`
358
+ - `src/client/types.ts`
359
+ - `src/client/canvas/CanvasViewport.tsx`
360
+ - `src/client/canvas/CanvasNode.tsx`
361
+ - `src/client/state/sse-bridge.ts`
362
+ - `src/server/server.ts`
363
+ - `src/server/index.ts`
364
+ - `src/mcp/server.ts`
365
+
366
+ New tools / endpoints:
367
+
368
+ - `canvas_add_query`
369
+ - `canvas_refresh_query`
370
+ - `POST /api/canvas/query`
371
+ - `POST /api/canvas/query/:id/refresh`
372
+
373
+ Validation:
374
+
375
+ - place a live query node on the canvas
376
+ - refreshes server-side
377
+ - result diffs update the node over SSE
378
+ - survives restart because node config lives in the persisted canvas state
379
+
380
+ ### Phase 3: Add the Causal Change Ledger
381
+
382
+ Goal: make the system explainable and durable before adding more reactive complexity.
383
+
384
+ New files:
385
+
386
+ - `src/server/change-ledger.ts`
387
+
388
+ Possible new UI files:
389
+
390
+ - `src/client/canvas/ChangeFeedPanel.tsx`
391
+
392
+ Modified files:
393
+
394
+ - `src/server/canvas-state.ts`
395
+ - `src/server/query-runtime.ts`
396
+ - `src/server/server.ts`
397
+ - `src/mcp/server.ts`
398
+ - `src/client/state/sse-bridge.ts`
399
+
400
+ New tools / endpoints:
401
+
402
+ - `canvas_what_changed`
403
+ - `canvas_why_changed`
404
+ - `GET /api/canvas/changes`
405
+ - `GET /api/canvas/changes/node/:id`
406
+
407
+ Deliverables:
408
+
409
+ - persisted `ReactiveEventRecord` log
410
+ - query diffs recorded as structured events
411
+ - reaction and formula executions recorded with causes
412
+ - node-level "why did this change?" lookup
413
+ - a basic "since last visit" or recent changes feed
414
+
415
+ Validation:
416
+
417
+ - a query refresh that changes result writes a readable ledger event
418
+ - a user can ask why a node changed and see the causal chain
419
+
420
+ ### Phase 4: Add Semantic Propagation + Formula Nodes
421
+
422
+ Goal: make the graph compute.
423
+
424
+ New files:
425
+
426
+ - `src/server/reactive-graph.ts`
427
+ - `src/server/formula-evaluator.ts`
428
+
429
+ Modified files:
430
+
431
+ - `src/server/canvas-state.ts`
432
+ - `src/client/types.ts`
433
+ - `src/client/canvas/EdgeLayer.tsx`
434
+ - `src/server/index.ts`
435
+ - `src/server/server.ts`
436
+ - `src/mcp/server.ts`
437
+
438
+ Deliverables:
439
+
440
+ - semantic edge types
441
+ - propagation walk from changed source nodes
442
+ - debounce / rate-limit formula evaluation
443
+ - formula metadata on markdown / status nodes
444
+
445
+ Validation:
446
+
447
+ - connect three query nodes to one formula-capable markdown node via `feeds`
448
+ - refreshing any upstream node recomputes the formula result once
449
+
450
+ ### Phase 5: Expose Custom Reactions
451
+
452
+ Goal: let humans and agents program the canvas directly.
453
+
454
+ Possible new files:
455
+
456
+ - `src/client/nodes/ReactionNode.tsx`
457
+
458
+ New tools:
459
+
460
+ - `canvas_add_reaction`
461
+ - `canvas_remove_reaction`
462
+ - `canvas_list_reactions`
463
+ - `canvas_toggle_reaction`
464
+
465
+ Starter built-in actions:
466
+
467
+ - pin node
468
+ - focus node
469
+ - refresh query
470
+ - evaluate formula
471
+ - add import neighbors
472
+ - upsert summary node
473
+
474
+ Validation:
475
+
476
+ - debugging board can auto-pin red status nodes
477
+ - pinning a file can expand one-hop imports using the same generalized runtime
478
+
479
+ ### Phase 6: Promote / Export
480
+
481
+ Goal: capture durable evidence without coupling this package to PMX internals that are not here.
482
+
483
+ New files:
484
+
485
+ - `src/server/canvas-promotion.ts`
486
+
487
+ Possible outputs:
488
+
489
+ - `docs/canvas-promotions/*.md`
490
+ - `artifacts/canvas-promotions/*.json`
491
+
492
+ Tool:
493
+
494
+ - `canvas_promote`
495
+
496
+ Validation:
497
+
498
+ - selecting a cluster can produce a timestamped evidence bundle with node refs, snapshots, and structured summary
499
+
500
+ ## Non-Goals for This Repo's First Pass
501
+
502
+ - No direct mutation of `product-graph.ts` or `work-graph.ts` here
503
+ - No fully normalized evidence warehouse beyond the causal change ledger
504
+ - No multi-board storage system before reaction runtime exists
505
+ - No background live refresh for unopened canvases in v1
506
+ - No arbitrary browser-side MCP execution
507
+
508
+ ## Saved Canvases, Re-scoped
509
+
510
+ The original "saved canvases" idea is still good, but it should be built on existing persistence primitives.
511
+
512
+ Recommended path:
513
+
514
+ - keep the existing always-persisted working canvas
515
+ - keep snapshots as named restore points
516
+ - later evolve snapshots into named "boards" if the workflow proves necessary
517
+
518
+ That avoids fighting the current architecture too early.
519
+
520
+ ## Concrete Use Cases
521
+
522
+ ### 1. Sprint Operating Board
523
+
524
+ - Query nodes: Jira bugs, stale PRs, deploy frequency
525
+ - Causal ledger: "bug count spiked after QA import" is visible as a recent change, not inferred from memory
526
+ - Semantic edges: all three `feed` a markdown node with a formula
527
+ - Formula output: a one-line sprint health summary
528
+ - Promote/export: capture the board state as a risk or status record
529
+
530
+ ### 2. Production Investigation Board
531
+
532
+ - File nodes and status nodes already exist
533
+ - Reactions auto-pin red statuses and expand import neighbors on pin
534
+ - Query nodes later add live incident data or failing checks
535
+ - Formula node summarizes root-cause confidence as evidence accumulates
536
+
537
+ This is why the merge works: it serves both PM workflows and engineering investigation without creating two products.
538
+
539
+ ## Success Criteria
540
+
541
+ Phase 1-2 are successful if:
542
+
543
+ - a user can create a live query node in under a minute
544
+ - query refreshes survive restart
545
+ - query updates arrive over SSE without corrupting layout reconciliation
546
+
547
+ Phase 3 is successful if:
548
+
549
+ - a user can answer "what changed?" and "why did this change?" without re-running analysis
550
+ - query, reaction, and formula events are persisted in a form that can later support promotion and summaries
551
+
552
+ Phase 4 is successful if:
553
+
554
+ - a formula-capable node recomputes from connected upstream data without duplicate evaluations
555
+ - semantic edges change behavior, not just visuals
556
+
557
+ Phase 5 is successful if:
558
+
559
+ - at least two current hardcoded behaviors can be expressed as reactions
560
+ - one user-authored debugging rule works end-to-end
561
+
562
+ Phase 6 is successful if:
563
+
564
+ - a promoted bundle provides enough evidence for later human review
565
+ - the export seam is useful before deeper PMX integration exists
566
+
567
+ ## Recommendation
568
+
569
+ Build this as **Reactive Canvas**, with the following framing:
570
+
571
+ - **product promise**: a live operating graph on a spatial canvas
572
+ - **technical kernel**: a generalized reaction engine
573
+ - **first visible wedge**: query nodes
574
+ - **first trust layer**: a causal change ledger
575
+ - **first compounding step**: formula-capable nodes + semantic propagation
576
+ - **future bridge**: evidence export and promotion into external product memory systems
577
+
578
+ That is the most innovative, accretive, and buildable version of the idea in this repo as it exists today.
@@ -0,0 +1,38 @@
1
+ # PMX Canvas 0.1.0 — Release Review
2
+
3
+ **Date:** 2026-04-24
4
+ **Target:** public release of `pmx-canvas` 0.1.0
5
+
6
+ ## TL;DR
7
+
8
+ **Ready to ship on the Bun-first release path.** The current tree passes build, typecheck,
9
+ unit tests, browser smoke, tarball pack/install smoke, and live endpoint checks. The remaining
10
+ work for release hygiene was documentation and workflow alignment, which is now tracked in the
11
+ same repo as code and package metadata.
12
+
13
+ ## Verification Summary
14
+
15
+ | Check | Result | Notes |
16
+ |---|---|---|
17
+ | `bun run test` | ✅ | 159 passing unit/API/MCP/SDK tests |
18
+ | `bun run test:web-canvas` | ✅ | 26 passing Playwright tests, 1 skipped published-consumer scenario |
19
+ | `bun pm pack --dry-run` | ✅ | Tarball now includes `skills/` in addition to `src/`, `dist/`, and docs |
20
+ | `bun run release:smoke` | ✅ | Pack → install → boot → probe consumer flow passed |
21
+ | Live startup probes | ✅ | `/health`, `/api/canvas/state`, `/api/canvas/summary`, `/canvas/index.js`, and SSE stream responded correctly |
22
+ | Bun SDK import | ✅ | `import { createCanvas } from 'pmx-canvas'` works in Bun |
23
+ | Node SDK import | ⚠️ unsupported by design | Published export remains Bun-first; Node consumers should use CLI, MCP, or HTTP |
24
+
25
+ ## Release Notes
26
+
27
+ - Persistence is documented and implemented as `.pmx-canvas/state.json` with automatic migration
28
+ from legacy `.pmx-canvas.json` and `.pmx-canvas-snapshots/`.
29
+ - The Bun package now ships the documented `skills/` directory alongside the CLI, MCP server,
30
+ HTTP surface, and Bun SDK.
31
+ - The publish workflow now validates the same release surfaces used in local release review:
32
+ browser smoke and consumer install/start smoke both run before `npm publish`.
33
+
34
+ ## Known Scope
35
+
36
+ - The package is Bun-first. The SDK import path is intended for Bun runtimes.
37
+ - The Playwright `published-consumer` test remains opt-in because it requires an externally
38
+ provisioned install-style URL via `PMX_CANVAS_URL`.
Binary file