pmx-canvas 0.2.1 → 0.2.2

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 (45) hide show
  1. package/CHANGELOG.md +86 -0
  2. package/Readme.md +2 -2
  3. package/dist/canvas/global.css +260 -0
  4. package/dist/canvas/index.js +76 -76
  5. package/dist/json-render/index.js +2 -2
  6. package/dist/types/client/canvas/IntentLayer.d.ts +1 -0
  7. package/dist/types/client/state/intent-bridge.d.ts +10 -0
  8. package/dist/types/client/state/intent-store.d.ts +25 -0
  9. package/dist/types/json-render/server.d.ts +1 -1
  10. package/dist/types/server/index.d.ts +34 -4
  11. package/dist/types/server/intent-registry.d.ts +45 -0
  12. package/dist/types/server/operations/ops/intent.d.ts +2 -0
  13. package/dist/types/shared/ax-intent.d.ts +58 -0
  14. package/docs/mcp.md +21 -2
  15. package/docs/screenshot.png +0 -0
  16. package/package.json +1 -1
  17. package/skills/pmx-canvas/SKILL.md +197 -1305
  18. package/skills/pmx-canvas/evals/evals.json +199 -0
  19. package/skills/pmx-canvas/references/full-reference.md +1441 -0
  20. package/src/cli/index.ts +21 -4
  21. package/src/client/canvas/CanvasNode.tsx +13 -13
  22. package/src/client/canvas/CanvasViewport.tsx +2 -0
  23. package/src/client/canvas/ContextMenu.tsx +25 -19
  24. package/src/client/canvas/IntentLayer.tsx +278 -0
  25. package/src/client/nodes/ExtAppFrame.tsx +31 -22
  26. package/src/client/state/intent-bridge.ts +31 -0
  27. package/src/client/state/intent-store.ts +107 -0
  28. package/src/client/state/sse-bridge.ts +31 -0
  29. package/src/client/theme/global.css +260 -0
  30. package/src/json-render/charts/components.tsx +18 -4
  31. package/src/json-render/renderer/index.tsx +11 -2
  32. package/src/json-render/server.ts +1 -1
  33. package/src/server/index.ts +240 -158
  34. package/src/server/intent-registry.ts +324 -0
  35. package/src/server/operations/composites.ts +11 -0
  36. package/src/server/operations/index.ts +2 -0
  37. package/src/server/operations/ops/edges.ts +1 -0
  38. package/src/server/operations/ops/groups.ts +3 -0
  39. package/src/server/operations/ops/intent.ts +132 -0
  40. package/src/server/operations/ops/json-render.ts +3 -0
  41. package/src/server/operations/ops/nodes.ts +3 -0
  42. package/src/server/operations/registry.ts +68 -3
  43. package/src/server/server.ts +40 -12
  44. package/src/shared/ax-intent.ts +64 -0
  45. package/src/shared/surface.ts +5 -1
@@ -181,6 +181,205 @@
181
181
  "type": "output_check"
182
182
  }
183
183
  ]
184
+ },
185
+ {
186
+ "id": 8,
187
+ "name": "workspace-identity-preflight",
188
+ "prompt": "Attach to the running PMX canvas and add a status node for our deploy. There's already a daemon on port 4313.",
189
+ "expected_output": "Before mutating, reads GET /health (or serve status) and confirms the returned workspace matches the intended workspace root; refuses to mutate a mismatched/stale listener and starts an isolated server on an explicit --port instead.",
190
+ "assertions": [
191
+ {
192
+ "name": "reads-health",
193
+ "description": "Reads /health or serve status before any mutation",
194
+ "type": "output_check"
195
+ },
196
+ {
197
+ "name": "checks-workspace",
198
+ "description": "Compares the returned workspace to the intended workspace root",
199
+ "type": "output_check"
200
+ },
201
+ {
202
+ "name": "handles-mismatch",
203
+ "description": "On workspace mismatch or responsive+pidRunning:false, does NOT mutate; isolates via explicit --port and re-checks /health",
204
+ "type": "output_check"
205
+ }
206
+ ]
207
+ },
208
+ {
209
+ "id": 9,
210
+ "name": "current-composite-routing",
211
+ "prompt": "Create a markdown note, a bar chart, and an Excalidraw diagram on the canvas.",
212
+ "expected_output": "Uses current composites: canvas_node {action:add} for markdown, canvas_render {action:add-graph} for the chart, canvas_app {action:diagram} for Excalidraw. Avoids deprecated single-purpose tools (canvas_add_node/canvas_add_diagram/canvas_build_web_artifact/canvas_open_mcp_app).",
213
+ "assertions": [
214
+ {
215
+ "name": "uses-canvas-node",
216
+ "description": "Creates the markdown node via canvas_node {action:add}",
217
+ "type": "output_check"
218
+ },
219
+ {
220
+ "name": "uses-canvas-render",
221
+ "description": "Creates the chart via canvas_render {action:add-graph}",
222
+ "type": "output_check"
223
+ },
224
+ {
225
+ "name": "uses-canvas-app",
226
+ "description": "Creates the Excalidraw diagram via canvas_app {action:diagram}",
227
+ "type": "output_check"
228
+ },
229
+ {
230
+ "name": "avoids-deprecated",
231
+ "description": "Does not call deprecated standalones (canvas_add_node/canvas_add_diagram/etc.)",
232
+ "type": "output_check"
233
+ }
234
+ ]
235
+ },
236
+ {
237
+ "id": 10,
238
+ "name": "existing-board-extension",
239
+ "prompt": "Add two more findings to the investigation board that's already on the canvas.",
240
+ "expected_output": "Searches the existing board first, snapshots before extending, adds new nodes without duplicating existing titles, and validates the final layout for collisions.",
241
+ "assertions": [
242
+ {
243
+ "name": "searches-first",
244
+ "description": "Searches existing nodes (canvas_query {action:search}) before adding",
245
+ "type": "output_check"
246
+ },
247
+ {
248
+ "name": "snapshots-before",
249
+ "description": "Snapshots before extending the board",
250
+ "type": "output_check"
251
+ },
252
+ {
253
+ "name": "no-duplicates",
254
+ "description": "Adds new nodes without duplicating existing node titles",
255
+ "type": "output_check"
256
+ },
257
+ {
258
+ "name": "validates-layout",
259
+ "description": "Runs canvas_query {action:validate} (or arrange+validate) on the result",
260
+ "type": "output_check"
261
+ }
262
+ ]
263
+ },
264
+ {
265
+ "id": 11,
266
+ "name": "context-pin-workflow",
267
+ "prompt": "Pin the auth design node so I (the agent) keep it in context, then confirm it's pinned.",
268
+ "expected_output": "Pins via a verified path (canvas_pin_nodes, the CLI pin, or browser/right-click 'Pin as context'), then reads canvas://pinned-context to confirm; does not claim a broken UI action succeeded.",
269
+ "assertions": [
270
+ {
271
+ "name": "pins-via-verified-path",
272
+ "description": "Pins via canvas_pin_nodes / CLI pin / 'Pin as context' — not an unverified action",
273
+ "type": "output_check"
274
+ },
275
+ {
276
+ "name": "reads-pinned-context",
277
+ "description": "Reads canvas://pinned-context (or canvas_ax_state) to confirm the pin",
278
+ "type": "output_check"
279
+ },
280
+ {
281
+ "name": "confirms-count",
282
+ "description": "Confirms the pin is reflected (context count / pinned set) rather than assuming success",
283
+ "type": "output_check"
284
+ }
285
+ ]
286
+ },
287
+ {
288
+ "id": 12,
289
+ "name": "status-node-cleanup",
290
+ "prompt": "Remove the obsolete 'Deploy: pending' status node from the board.",
291
+ "expected_output": "Removes the status node via canvas_node {action:remove} (status nodes are removable like any other type) and verifies removal; undo remains available.",
292
+ "assertions": [
293
+ {
294
+ "name": "removes-status-node",
295
+ "description": "Removes the status node via canvas_node {action:remove}",
296
+ "type": "output_check"
297
+ },
298
+ {
299
+ "name": "verifies-removal",
300
+ "description": "Verifies the node is gone from the layout",
301
+ "type": "output_check"
302
+ },
303
+ {
304
+ "name": "preserves-undo",
305
+ "description": "Notes/relies on undo (canvas_history) remaining available",
306
+ "type": "output_check"
307
+ }
308
+ ]
309
+ },
310
+ {
311
+ "id": 13,
312
+ "name": "ax-html-control-surface",
313
+ "prompt": "Build an AX control surface as an HTML node with a button that creates a work item and a button that steers me.",
314
+ "expected_output": "Creates an opted-in html node (axCapabilities.enabled) using the blessed recipe: awaits window.PMX_AX.emit, reflects live state via pmx-ax-update, avoids sandbox-blocked localStorage, and labels the steer button as queued for the next turn (not immediate wake).",
315
+ "assertions": [
316
+ {
317
+ "name": "opts-in-ax",
318
+ "description": "Creates the html node with axCapabilities.enabled = true",
319
+ "type": "output_check"
320
+ },
321
+ {
322
+ "name": "awaits-emit",
323
+ "description": "Uses window.PMX_AX.emit with await (not fire-and-forget)",
324
+ "type": "output_check"
325
+ },
326
+ {
327
+ "name": "sandbox-safe",
328
+ "description": "Avoids localStorage/sessionStorage/cookies in the sandboxed iframe",
329
+ "type": "output_check"
330
+ },
331
+ {
332
+ "name": "labels-steer-queued",
333
+ "description": "Labels steering as queued for the next turn, not immediate agent wake",
334
+ "type": "output_check"
335
+ }
336
+ ]
337
+ },
338
+ {
339
+ "id": 14,
340
+ "name": "ax-delivery-lifecycle",
341
+ "prompt": "There are pending steering messages from the board. Pick them up and act on them.",
342
+ "expected_output": "Reads compact context (newest-first pendingSteering + totalPending/omittedPending) and/or claims via canvas_ax_delivery {action:claim}; acts, then marks delivered. Understands direct delivery stays FIFO oldest-first.",
343
+ "assertions": [
344
+ {
345
+ "name": "reads-newest-first",
346
+ "description": "Uses compact context (newest-first + counts) or canvas_ax_delivery claim to find fresh steering",
347
+ "type": "output_check"
348
+ },
349
+ {
350
+ "name": "acts-then-marks",
351
+ "description": "Acts on the steering then marks it delivered (canvas_ax_delivery {action:mark})",
352
+ "type": "output_check"
353
+ },
354
+ {
355
+ "name": "understands-fifo",
356
+ "description": "Recognizes the direct delivery queue is FIFO oldest-first, distinct from compact context",
357
+ "type": "output_check"
358
+ }
359
+ ]
360
+ },
361
+ {
362
+ "id": 15,
363
+ "name": "final-cleanup-and-validate",
364
+ "prompt": "We're done with the test board. Clean up the temporary nodes and leave the canvas as we found it.",
365
+ "expected_output": "Removes retry/test fixtures, runs canvas_query {action:validate} to confirm no accidental collisions/dangling edges, and restores the baseline snapshot.",
366
+ "assertions": [
367
+ {
368
+ "name": "removes-fixtures",
369
+ "description": "Removes the temporary/retry fixture nodes",
370
+ "type": "output_check"
371
+ },
372
+ {
373
+ "name": "validates-final",
374
+ "description": "Validates the final layout (canvas_query {action:validate})",
375
+ "type": "output_check"
376
+ },
377
+ {
378
+ "name": "restores-baseline",
379
+ "description": "Restores the baseline snapshot to leave the canvas as found",
380
+ "type": "output_check"
381
+ }
382
+ ]
184
383
  }
185
384
  ]
186
385
  }