pmx-canvas 0.11.0 → 0.12.1

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 (300) hide show
  1. package/.github/extensions/pmx-canvas/extension.mjs +4 -1
  2. package/.github/extensions/pmx-canvas/runtime.json +1 -1
  3. package/.github/extensions/pmx-canvas/tools.json +440 -18
  4. package/CHANGELOG.md +51 -0
  5. package/dist/amp-plugin/pmx-canvas/LICENSE +21 -0
  6. package/dist/amp-plugin/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
  7. package/dist/amp-plugin/pmx-canvas/index.js +5445 -0
  8. package/dist/amp-plugin/pmx-canvas/runtime.json +3 -0
  9. package/dist/amp-plugin/pmx-canvas/shared-runtime.mjs +194 -0
  10. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/SKILL.md +267 -0
  11. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/evals.json +1168 -0
  12. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/auth/jwt.ts +17 -0
  13. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/auth/login.ts +12 -0
  14. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/auth/middleware.ts +13 -0
  15. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/code-exploration/src/routes/auth.ts +13 -0
  16. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/fixtures/investigation-board/src/handlers/users.ts +27 -0
  17. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/mcp.json +36 -0
  18. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/ax-html-control-surface.md +101 -0
  19. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/codex-app-adapter.md +151 -0
  20. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +150 -0
  21. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/full-reference.md +1839 -0
  22. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/github-copilot-app-adapter.md +223 -0
  23. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/html-primitives.md +139 -0
  24. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/importing-context.md +132 -0
  25. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/installing-pmx-canvas.md +301 -0
  26. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/tours-and-recording.md +117 -0
  27. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/workbench-workflows.md +908 -0
  28. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas-orchestration/SKILL.md +141 -0
  29. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas-testing/SKILL.md +266 -0
  30. package/dist/amp-plugin/pmx-canvas/start-mcp.mjs +14857 -0
  31. package/dist/amp-plugin/pmx-canvas/tools.json +10963 -0
  32. package/dist/canvas/chunks/{abnfDiagram-N423BO3Z-p8dtp6va.js → abnfDiagram-N423BO3Z-cwtsds5d.js} +1 -1
  33. package/dist/canvas/chunks/architecture-TIHT7OUA-x63cwejs.js +1 -0
  34. package/dist/canvas/chunks/{architectureDiagram-T3A2C74G-5jhmxrzf.js → architectureDiagram-T3A2C74G-b4xc9tpz.js} +3 -3
  35. package/dist/canvas/chunks/{blockDiagram-VBNYF7ZC-pw1fa9yb.js → blockDiagram-VBNYF7ZC-ahp3yxxs.js} +7 -7
  36. package/dist/canvas/chunks/{c4Diagram-5PPSVZJV-x07nq0tt.js → c4Diagram-5PPSVZJV-nappnay7.js} +4 -4
  37. package/dist/canvas/chunks/classDiagram-JCYQIIEL-k1j2xc1t.js +1 -0
  38. package/dist/canvas/chunks/classDiagram-v2-OCEON4UE-33x08xf2.js +1 -0
  39. package/dist/canvas/chunks/{cose-bilkent-JH36ORCC-nm39npq0.js → cose-bilkent-JH36ORCC-a428syda.js} +1 -1
  40. package/dist/canvas/chunks/cynefin-VYW2F7L2-8v6jxfz8.js +1 -0
  41. package/dist/canvas/chunks/{cynefinDiagram-MW4NZA55-vdxrwahz.js → cynefinDiagram-MW4NZA55-nspsqebj.js} +1 -1
  42. package/dist/canvas/chunks/{dagre-VZM6K2ZE-bqdm7wpd.js → dagre-VZM6K2ZE-8y6177fh.js} +2 -2
  43. package/dist/canvas/chunks/{diagram-7IWD3JNH-gs5gpr93.js → diagram-7IWD3JNH-vym028wn.js} +4 -4
  44. package/dist/canvas/chunks/{diagram-B4RE2ZJO-cgwjg47s.js → diagram-B4RE2ZJO-jddqb8sy.js} +1 -1
  45. package/dist/canvas/chunks/{diagram-LBJQPF4R-w3vahpav.js → diagram-LBJQPF4R-bjwbpkrn.js} +1 -1
  46. package/dist/canvas/chunks/{diagram-Q27KOJAE-42837z6h.js → diagram-Q27KOJAE-j6ph6hcx.js} +2 -2
  47. package/dist/canvas/chunks/{diagram-UB23O5K3-4fz83q59.js → diagram-UB23O5K3-p09w8jej.js} +1 -1
  48. package/dist/canvas/chunks/{ebnfDiagram-BXEA7PRR-zphtgegj.js → ebnfDiagram-BXEA7PRR-j975ycq5.js} +1 -1
  49. package/dist/canvas/chunks/{erDiagram-JOGREHBK-zvbbdxp4.js → erDiagram-JOGREHBK-sxp6hjn8.js} +5 -5
  50. package/dist/canvas/chunks/eventmodeling-45OFAUF4-xzfgn6xg.js +1 -0
  51. package/dist/canvas/chunks/flowDiagram-UKHOOZJN-2nsmkskb.js +1 -0
  52. package/dist/canvas/chunks/{ganttDiagram-PKOTCBZU-282jzycm.js → ganttDiagram-PKOTCBZU-4tv230y2.js} +2 -2
  53. package/dist/canvas/chunks/gitGraph-TEB2WS4Q-macbhand.js +1 -0
  54. package/dist/canvas/chunks/{gitGraphDiagram-DS77QQ5N-vqqy6p1b.js → gitGraphDiagram-DS77QQ5N-mqgmnw9g.js} +1 -1
  55. package/dist/canvas/chunks/{index-wgv7en21.js → index-037z5dz2.js} +2 -2
  56. package/dist/canvas/chunks/{index-w2mra17t.js → index-081n3har.js} +1 -1
  57. package/dist/canvas/chunks/{index-353m7b0p.js → index-5n03dmb9.js} +1 -1
  58. package/dist/canvas/chunks/{index-yw8h9vha.js → index-60pgzdqe.js} +1 -1
  59. package/dist/canvas/chunks/index-8g1vb57n.js +2 -0
  60. package/dist/canvas/chunks/{index-vv56h019.js → index-8rjes9r6.js} +1 -1
  61. package/dist/canvas/chunks/{index-nprm96xp.js → index-9022d1n9.js} +1 -1
  62. package/dist/canvas/chunks/{index-194m3hc3.js → index-9b02042t.js} +1 -1
  63. package/dist/canvas/chunks/{index-0rk4gp1g.js → index-ap4q4vez.js} +1 -1
  64. package/dist/canvas/chunks/{index-rh7nv68n.js → index-dyp2nhd3.js} +1 -1
  65. package/dist/canvas/chunks/index-frvta4tm.js +2 -0
  66. package/dist/canvas/chunks/{index-s4j678gj.js → index-h9ycj8n2.js} +1 -1
  67. package/dist/canvas/chunks/{index-fjtdggjn.js → index-mergmj97.js} +2 -2
  68. package/dist/canvas/chunks/index-nwsya6dj.js +301 -0
  69. package/dist/canvas/chunks/{index-3cy1bzwh.js → index-nz8qbd1p.js} +1 -1
  70. package/dist/canvas/chunks/{index-d3b3gqe9.js → index-qhfrazv3.js} +1 -1
  71. package/dist/canvas/chunks/{index-6qmsnxwy.js → index-v119nznk.js} +4 -4
  72. package/dist/canvas/chunks/{index-r2fyc9w1.js → index-vpt37m3d.js} +6 -6
  73. package/dist/canvas/chunks/{index-qj8fxwsf.js → index-y9ma6azy.js} +1 -1
  74. package/dist/canvas/chunks/{index-tb1wf525.js → index-zx0j3a2z.js} +26 -26
  75. package/dist/canvas/chunks/info-DKCQHKI2-a0ykzs9z.js +1 -0
  76. package/dist/canvas/chunks/{infoDiagram-6WML65LV-v1yvggqj.js → infoDiagram-6WML65LV-qv97qq6a.js} +2 -2
  77. package/dist/canvas/chunks/ishikawaDiagram-WSZJBQD7-p9306gh0.js +70 -0
  78. package/dist/canvas/chunks/{journeyDiagram-NVQOT4AX-zjcffveh.js → journeyDiagram-NVQOT4AX-sv67zats.js} +5 -5
  79. package/dist/canvas/chunks/{kanban-definition-27J2QSJJ-dakqtfp1.js → kanban-definition-27J2QSJJ-k2pfam6p.js} +1 -1
  80. package/dist/canvas/chunks/{mermaid.core-j2geswrd.js → mermaid.core-83r0fdce.js} +4 -4
  81. package/dist/canvas/chunks/{mindmap-definition-FAOFIHXS-142xhr3k.js → mindmap-definition-FAOFIHXS-vg2newm1.js} +1 -1
  82. package/dist/canvas/chunks/packet-7NZHBO7P-tqnabcdv.js +1 -0
  83. package/dist/canvas/chunks/{pegDiagram-VL7TDLO6-5wvk7vsd.js → pegDiagram-VL7TDLO6-k2h7zc5n.js} +1 -1
  84. package/dist/canvas/chunks/pie-RZYD4A2V-wke6gyhe.js +1 -0
  85. package/dist/canvas/chunks/{pieDiagram-7S7Q4E2Y-ztdhwycc.js → pieDiagram-7S7Q4E2Y-hg169p1v.js} +2 -2
  86. package/dist/canvas/chunks/{quadrantDiagram-CIZ2JOQS-c5p9gmg6.js → quadrantDiagram-CIZ2JOQS-bxtvsq0b.js} +5 -5
  87. package/dist/canvas/chunks/radar-I7S5WNFK-w7ka0drw.js +1 -0
  88. package/dist/canvas/chunks/railroad-3IZDKUUU-y3vg318x.js +1 -0
  89. package/dist/canvas/chunks/railroad-abnf-AHOZXSZD-6hqvcz3c.js +1 -0
  90. package/dist/canvas/chunks/railroad-ebnf-EBAXGLYW-vcae260m.js +1 -0
  91. package/dist/canvas/chunks/railroad-peg-LSFZ7HO6-0dbyme23.js +1 -0
  92. package/dist/canvas/chunks/{railroadDiagram-AXF67PYL-xkmqkjwf.js → railroadDiagram-AXF67PYL-njyhcp4p.js} +1 -1
  93. package/dist/canvas/chunks/{requirementDiagram-LRYGKXZP-9wm2dyaw.js → requirementDiagram-LRYGKXZP-2z6v09gm.js} +4 -4
  94. package/dist/canvas/chunks/{sankeyDiagram-W5VNT64P-2w19etgb.js → sankeyDiagram-W5VNT64P-15mzam0e.js} +1 -1
  95. package/dist/canvas/chunks/{sequenceDiagram-SI44F4Z6-0jn0vwmz.js → sequenceDiagram-SI44F4Z6-rbshyd2c.js} +12 -12
  96. package/dist/canvas/chunks/{sizeCapture-X5ZJPWSS-x75epwdq.js → sizeCapture-X5ZJPWSS-sg26xwts.js} +1 -1
  97. package/dist/canvas/chunks/{stateDiagram-OKZ733FA-schjpy6d.js → stateDiagram-OKZ733FA-6eahp98e.js} +1 -1
  98. package/dist/canvas/chunks/stateDiagram-v2-UEYNNEHI-tty0ggn5.js +1 -0
  99. package/dist/canvas/chunks/{swimlanes-SLNWSIFB-gkw4xce3.js → swimlanes-SLNWSIFB-ze5db10t.js} +1 -1
  100. package/dist/canvas/chunks/swimlanesDiagram-ULZ7WXOC-thze75gq.js +8 -0
  101. package/dist/canvas/chunks/{timeline-definition-Z64GVDOM-x7nkcy01.js → timeline-definition-Z64GVDOM-vnp7jyy8.js} +3 -3
  102. package/dist/canvas/chunks/treeView-QDETBFTQ-6ysffnm6.js +1 -0
  103. package/dist/canvas/chunks/treemap-6X3UGDF4-m3h9p066.js +1 -0
  104. package/dist/canvas/chunks/vennDiagram-T6HMQDX7-0qrnb7mj.js +34 -0
  105. package/dist/canvas/chunks/wardley-OPB4EBWU-dp37drwx.js +1 -0
  106. package/dist/canvas/chunks/{wardleyDiagram-T6FBY63Y-t1j52t9r.js → wardleyDiagram-T6FBY63Y-8nxg8wqt.js} +4 -4
  107. package/dist/canvas/chunks/{xychartDiagram-ELKLHX3M-38t16pme.js → xychartDiagram-ELKLHX3M-nj921e7s.js} +5 -5
  108. package/dist/canvas/global.css +94 -1
  109. package/dist/canvas/index.js +154 -145
  110. package/dist/canvas/mcp-app.html +600 -498
  111. package/dist/json-render/index.css +1 -1
  112. package/dist/types/client/canvas/BoardMoveDialog.d.ts +2 -0
  113. package/dist/types/client/canvas/EdgeEditor.d.ts +19 -0
  114. package/dist/types/client/canvas/GroupNavigation.d.ts +2 -0
  115. package/dist/types/client/canvas/TextPrompt.d.ts +4 -0
  116. package/dist/types/client/nodes/PromptNode.d.ts +1 -0
  117. package/dist/types/client/nodes/ViewerFrame.d.ts +1 -1
  118. package/dist/types/client/nodes/WorkCard.d.ts +7 -0
  119. package/dist/types/client/nodes/use-ax-surface-bridge.d.ts +1 -0
  120. package/dist/types/client/state/canvas-store.d.ts +15 -0
  121. package/dist/types/client/state/human-store.d.ts +2 -0
  122. package/dist/types/client/state/intent-bridge.d.ts +4 -2
  123. package/dist/types/client/state/relation-store.d.ts +11 -0
  124. package/dist/types/client/types.d.ts +1 -1
  125. package/dist/types/json-render/catalog.d.ts +2 -2
  126. package/dist/types/server/agent-presence.d.ts +1 -0
  127. package/dist/types/server/ax-interaction.d.ts +1 -0
  128. package/dist/types/server/ax-state-manager.d.ts +10 -2
  129. package/dist/types/server/board-local.d.ts +4 -0
  130. package/dist/types/server/board-move.d.ts +38 -0
  131. package/dist/types/server/canvas-db.d.ts +12 -2
  132. package/dist/types/server/canvas-operations.d.ts +5 -6
  133. package/dist/types/server/canvas-provenance.d.ts +1 -1
  134. package/dist/types/server/canvas-serialization.d.ts +1 -0
  135. package/dist/types/server/canvas-state.d.ts +84 -20
  136. package/dist/types/server/card-relocation.d.ts +6 -0
  137. package/dist/types/server/context-reads.d.ts +3 -1
  138. package/dist/types/server/human-presence.d.ts +1 -1
  139. package/dist/types/server/index.d.ts +16 -5
  140. package/dist/types/server/intent-registry.d.ts +8 -4
  141. package/dist/types/server/knowledge-lifecycle.d.ts +4 -2
  142. package/dist/types/server/mutation-history.d.ts +7 -5
  143. package/dist/types/server/operations/registry.d.ts +2 -0
  144. package/dist/types/server/trace-manager.d.ts +1 -0
  145. package/dist/types/shared/ax-kinds.d.ts +6 -0
  146. package/dist/types/shared/ax-surface-protocol.d.ts +8 -0
  147. package/dist/types/shared/human-presence.d.ts +1 -0
  148. package/dist/types/shared/lifecycle-status.d.ts +2 -0
  149. package/docs/RELEASE.md +21 -14
  150. package/docs/agent-plugin.md +22 -2
  151. package/docs/amp-plugin.md +270 -0
  152. package/docs/cli.md +42 -3
  153. package/docs/design/GuestName.dc.html +50 -0
  154. package/docs/design/PluginLogo.svg +7 -0
  155. package/docs/design/WorkCards.dc.html +39 -0
  156. package/docs/design/canvas.json +16 -0
  157. package/docs/design/plugin-logo.png +0 -0
  158. package/docs/design.md +111 -8
  159. package/docs/evals/agents-md-sections.md +38 -0
  160. package/docs/http-api.md +128 -10
  161. package/docs/mcp.md +61 -9
  162. package/docs/node-types.md +71 -1
  163. package/docs/plans/plan-009-tech-debt-backlog.md +1 -1
  164. package/docs/plans/plan-019-post-0.9-roadmap.md +44 -20
  165. package/docs/plans/plan-020-wave-5-work-planning.md +553 -0
  166. package/docs/product-vision-2026-09.md +33 -17
  167. package/docs/sdk.md +18 -0
  168. package/package.json +6 -3
  169. package/plugins/pmx-canvas/assets/preview.png +0 -0
  170. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +4 -1
  171. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
  172. package/plugins/pmx-canvas/plugin.json +2 -2
  173. package/plugins/pmx-canvas/runtime.json +1 -1
  174. package/plugins/pmx-canvas/tools.json +440 -18
  175. package/skills/data-analysis/SKILL.md +13 -26
  176. package/skills/frontend-design/LICENSE.txt +177 -0
  177. package/skills/frontend-design/SKILL.md +3 -0
  178. package/skills/pmx-canvas/SKILL.md +248 -842
  179. package/skills/pmx-canvas/evals/evals.json +110 -5
  180. package/skills/pmx-canvas/references/full-reference.md +142 -28
  181. package/skills/pmx-canvas/references/html-primitives.md +7 -0
  182. package/skills/pmx-canvas/references/installing-pmx-canvas.md +61 -11
  183. package/skills/pmx-canvas/references/tours-and-recording.md +39 -6
  184. package/skills/pmx-canvas/references/workbench-workflows.md +908 -0
  185. package/skills/pmx-canvas-testing/SKILL.md +7 -5
  186. package/skills/published-consumer-e2e/SKILL.md +25 -8
  187. package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +51 -75
  188. package/skills/web-artifacts-builder/LICENSE.txt +202 -0
  189. package/skills/web-artifacts-builder/SKILL.md +6 -0
  190. package/skills/web-artifacts-builder/scripts/bundle-artifact.sh +2 -2
  191. package/skills/web-artifacts-builder/scripts/init-artifact.sh +8 -8
  192. package/src/cli/commands/apps.ts +1 -0
  193. package/src/cli/commands/boards.ts +30 -0
  194. package/src/client/App.tsx +20 -4
  195. package/src/client/canvas/AttentionHistory.tsx +10 -2
  196. package/src/client/canvas/BoardMoveDialog.tsx +225 -0
  197. package/src/client/canvas/CanvasNode.tsx +45 -2
  198. package/src/client/canvas/CanvasViewport.tsx +38 -9
  199. package/src/client/canvas/ContextMenu.tsx +34 -12
  200. package/src/client/canvas/EdgeEditor.tsx +149 -0
  201. package/src/client/canvas/EdgeLayer.tsx +87 -16
  202. package/src/client/canvas/ExpandedNodeOverlay.tsx +4 -0
  203. package/src/client/canvas/GroupNavigation.tsx +85 -0
  204. package/src/client/canvas/RelationsPanel.tsx +9 -0
  205. package/src/client/canvas/SelectionBar.tsx +21 -0
  206. package/src/client/canvas/SessionPanel.tsx +35 -1
  207. package/src/client/canvas/TextPrompt.tsx +18 -1
  208. package/src/client/canvas/TopBar.tsx +30 -0
  209. package/src/client/canvas/canvas-area.ts +1 -1
  210. package/src/client/nodes/ExtAppFrame.tsx +26 -10
  211. package/src/client/nodes/MarkdownNode.tsx +6 -7
  212. package/src/client/nodes/PromptNode.tsx +32 -3
  213. package/src/client/nodes/StatusNode.tsx +12 -0
  214. package/src/client/nodes/StatusSummary.tsx +11 -0
  215. package/src/client/nodes/ViewerFrame.tsx +21 -10
  216. package/src/client/nodes/WorkCard.tsx +175 -0
  217. package/src/client/nodes/use-ax-surface-bridge.ts +18 -14
  218. package/src/client/state/attention-bridge.ts +5 -0
  219. package/src/client/state/attention-store.ts +1 -0
  220. package/src/client/state/canvas-store.ts +185 -15
  221. package/src/client/state/human-store.ts +22 -2
  222. package/src/client/state/intent-bridge.ts +19 -5
  223. package/src/client/state/relation-store.ts +127 -1
  224. package/src/client/theme/global.css +94 -1
  225. package/src/client/types.ts +1 -0
  226. package/src/mcp/server.ts +13 -3
  227. package/src/server/agent-presence.ts +43 -23
  228. package/src/server/ax-flow-loop.ts +6 -0
  229. package/src/server/ax-gate-ttl.ts +8 -1
  230. package/src/server/ax-interaction.ts +16 -10
  231. package/src/server/ax-state-manager.ts +17 -4
  232. package/src/server/ax-wait.ts +20 -6
  233. package/src/server/board-export.ts +19 -6
  234. package/src/server/board-local.ts +20 -0
  235. package/src/server/board-move.ts +297 -0
  236. package/src/server/canvas-db.ts +262 -160
  237. package/src/server/canvas-operations.ts +139 -109
  238. package/src/server/canvas-schema.ts +21 -0
  239. package/src/server/canvas-serialization.ts +2 -0
  240. package/src/server/canvas-state.ts +792 -159
  241. package/src/server/card-relocation.ts +53 -0
  242. package/src/server/code-graph.ts +4 -3
  243. package/src/server/context-reads.ts +83 -55
  244. package/src/server/demo-state.json +35 -15
  245. package/src/server/file-watcher.ts +30 -10
  246. package/src/server/human-presence.ts +18 -5
  247. package/src/server/index.ts +35 -15
  248. package/src/server/intent-registry.ts +43 -5
  249. package/src/server/knowledge-lifecycle.ts +32 -9
  250. package/src/server/lifecycle-status.ts +29 -1
  251. package/src/server/mcp-app-runtime.ts +26 -7
  252. package/src/server/mutation-history.ts +37 -8
  253. package/src/server/operations/composites.ts +6 -3
  254. package/src/server/operations/mcp-contracts.ts +15 -0
  255. package/src/server/operations/mcp.ts +36 -9
  256. package/src/server/operations/ops/annotation.ts +22 -1
  257. package/src/server/operations/ops/ax-await.ts +1 -0
  258. package/src/server/operations/ops/ax-timeline.ts +28 -2
  259. package/src/server/operations/ops/batch.ts +25 -11
  260. package/src/server/operations/ops/boards.ts +44 -3
  261. package/src/server/operations/ops/nodes.ts +70 -0
  262. package/src/server/operations/ops/query.ts +32 -3
  263. package/src/server/operations/ops/snapshots.ts +1 -0
  264. package/src/server/operations/registry.ts +49 -4
  265. package/src/server/server.ts +62 -16
  266. package/src/server/tour-control.ts +37 -12
  267. package/src/server/trace-manager.ts +4 -0
  268. package/src/server/web-artifacts/scripts/bundle-artifact.sh +2 -2
  269. package/src/server/web-artifacts/scripts/init-artifact.sh +8 -8
  270. package/src/shared/agent-context.ts +7 -1
  271. package/src/shared/auto-arrange.ts +5 -4
  272. package/src/shared/ax-kinds.ts +13 -0
  273. package/src/shared/ax-surface-protocol.ts +22 -0
  274. package/src/shared/human-presence.ts +1 -0
  275. package/src/shared/lifecycle-status.ts +2 -0
  276. package/dist/canvas/chunks/architecture-TIHT7OUA-9tffvpsv.js +0 -1
  277. package/dist/canvas/chunks/classDiagram-JCYQIIEL-nc6g5x1r.js +0 -1
  278. package/dist/canvas/chunks/classDiagram-v2-OCEON4UE-0qnbpwvh.js +0 -1
  279. package/dist/canvas/chunks/cynefin-VYW2F7L2-ys8p46ts.js +0 -1
  280. package/dist/canvas/chunks/eventmodeling-45OFAUF4-v9q6dn4c.js +0 -1
  281. package/dist/canvas/chunks/flowDiagram-UKHOOZJN-yrr5z8tc.js +0 -1
  282. package/dist/canvas/chunks/gitGraph-TEB2WS4Q-kdwb8m0a.js +0 -1
  283. package/dist/canvas/chunks/index-1r72hdzb.js +0 -301
  284. package/dist/canvas/chunks/index-g3pwnqeb.js +0 -2
  285. package/dist/canvas/chunks/index-rft2hcz5.js +0 -2
  286. package/dist/canvas/chunks/info-DKCQHKI2-wpzs6sz3.js +0 -1
  287. package/dist/canvas/chunks/ishikawaDiagram-WSZJBQD7-5hnq1a9p.js +0 -70
  288. package/dist/canvas/chunks/packet-7NZHBO7P-xn439f0s.js +0 -1
  289. package/dist/canvas/chunks/pie-RZYD4A2V-0kf16rwh.js +0 -1
  290. package/dist/canvas/chunks/radar-I7S5WNFK-0g2pz36t.js +0 -1
  291. package/dist/canvas/chunks/railroad-3IZDKUUU-fcaran6j.js +0 -1
  292. package/dist/canvas/chunks/railroad-abnf-AHOZXSZD-wgdya41q.js +0 -1
  293. package/dist/canvas/chunks/railroad-ebnf-EBAXGLYW-gy07a4ka.js +0 -1
  294. package/dist/canvas/chunks/railroad-peg-LSFZ7HO6-ewk6wtkh.js +0 -1
  295. package/dist/canvas/chunks/stateDiagram-v2-UEYNNEHI-k8sfp2e7.js +0 -1
  296. package/dist/canvas/chunks/swimlanesDiagram-ULZ7WXOC-nqysw67j.js +0 -8
  297. package/dist/canvas/chunks/treeView-QDETBFTQ-cesw6gp0.js +0 -1
  298. package/dist/canvas/chunks/treemap-6X3UGDF4-zdv4knp9.js +0 -1
  299. package/dist/canvas/chunks/vennDiagram-T6HMQDX7-x8dqn9yf.js +0 -34
  300. package/dist/canvas/chunks/wardley-OPB4EBWU-44pdddez.js +0 -1
@@ -536,8 +536,8 @@
536
536
  {
537
537
  "id": 22,
538
538
  "name": "tour-authoring-and-capture",
539
- "prompt": "Turn the Overview group and the Results card into a presentation tour, then tell me how to capture it deterministically at 1920x1080. I want a one-second overview move, a zero-duration jump to Results, and no changes to another viewer's camera.",
540
- "expected_output": "Targets the intended board, resolves the real group/card IDs, persists one tour with canvas_view set-tour, and uses valid node targets with durations 1 and 0. Explains that presentation is viewer-local and does not auto-advance. Gives deterministic record guidance using the same saved tour, --resolution 1920x1080, --present, and a new output path after verifying the matching daemon/workspace and Chrome/Bun WebView prerequisites. Does not invent a separate recording timeline or use realtime --duration.",
539
+ "prompt": "On the current board, turn the Overview group and the Results card into a presentation tour, then tell me how to capture it deterministically at 1920x1080. I want a one-second overview move, a zero-duration jump to Results, and no changes to another viewer's camera. That viewer is already presenting.",
540
+ "expected_output": "Verifies the current board, resolves the real group/card IDs, persists one tour with canvas_view set-tour, and uses valid node targets with durations 1 and 0. Distinguishes viewer-local rendering/free pan and isolated recording from shared tour navigation and exit. Does not call tour-go, tour-exit or move, switch boards, or use human Next/Back controls. Explains that present:false still advances viewers already presenting. Gives deterministic record guidance using the same saved tour, --resolution 1920x1080, --present, and a new output path after verifying the matching daemon/workspace and Chrome/Bun WebView prerequisites. Does not invent a separate recording timeline or use realtime --duration.",
541
541
  "assertions": [
542
542
  {
543
543
  "name": "persists-valid-shared-tour-model",
@@ -556,7 +556,30 @@
556
556
  },
557
557
  {
558
558
  "name": "preserves-viewer-camera",
559
- "description": "States that the presentation/capture camera is local and stops advance manually, rather than moving another viewer's camera",
559
+ "description": "Keeps the already-presenting viewer unchanged by avoiding shared tour-go/tour-exit/move, board switching and human navigation; distinguishes isolated capture from the shared cursor and does not treat present:false as isolation",
560
+ "type": "output_check"
561
+ }
562
+ ]
563
+ },
564
+ {
565
+ "id": 44,
566
+ "name": "presenter-superseded-is-not-applied-navigation",
567
+ "prompt": "In disposable boards A and B, verify optional presenter ordering. On visible A send a valid go with intent 2, then an exit with intent 1 for the same document and activation. Repeat with a stale activation. Include an independent-document control and an ordinary unfenced call. Then target background B with a presenter-bearing call and an unfenced control. Can ok:true or the SDK exit return prove the stale command ran?",
568
+ "expected_output": "Reads the actual activation stamps and uses positive safe-integer intents with independent document IDs. Checks applied delivery stamps and cursor/event behavior. Older intent, stale activation and presenter-bearing background calls return ok:true,superseded:true without navigation or cursor change. Independent and unfenced controls still apply on their target board; B's tour does not replace A's cursor or navigate its viewers. Explains that the fence orders requests, does not grant authority or isolate same-board viewers, and that SDK exit returns void while fenced go may return superseded:true. Does not count eval definitions as executed evidence.",
569
+ "assertions": [
570
+ {
571
+ "name": "checks-superseded-side-effects",
572
+ "description": "Observes no navigation event or cursor change for stale intent, stale activation and presenter-bearing background calls, rather than treating ok:true as applied navigation",
573
+ "type": "output_check"
574
+ },
575
+ {
576
+ "name": "positive-controls-and-stamps",
577
+ "description": "Verifies applied epoch/generation/sequence for the newer request and independent-document/unfenced controls; B's unfenced call changes only B's cursor while A remains visible with its own cursor",
578
+ "type": "output_check"
579
+ },
580
+ {
581
+ "name": "sdk-return-boundary",
582
+ "description": "Distinguishes fenced go's superseded result from exit's void return and avoids claiming viewer isolation or authority from the fence",
560
583
  "type": "output_check"
561
584
  }
562
585
  ]
@@ -564,7 +587,7 @@
564
587
  {
565
588
  "id": 23,
566
589
  "name": "multi-board-targeting",
567
- "prompt": "I have Roadmap and Incident Review boards. Add a decision note only to Incident Review and set its tour to the Summary group. Do not disturb Roadmap.",
590
+ "prompt": "Using raw MCP without an Amp plugin binding, I have Roadmap and Incident Review boards. Add a decision note only to Incident Review and set its tour to the Summary group. Preserve Roadmap content; switching the shared view is allowed.",
568
591
  "expected_output": "Lists/gets boards, resolves the exact Incident Review board and calls canvas_board action open or CLI board open with its ID, verifies the returned activeBoardId, searches for the Summary group there, then adds the note and sets that board's tour. It explains that opening switches the shared view but preserves Roadmap content. It does not infer IDs from titles, mutate Roadmap, invent inactive-board write targeting, or assume that a board switch succeeded. It validates Incident Review and reports board/node IDs.",
569
592
  "assertions": [
570
593
  {
@@ -730,7 +753,7 @@
730
753
  {
731
754
  "id": 30,
732
755
  "name": "amp-native-steering-evidence-boundary",
733
- "prompt": "On this disposable board, native Amp MCP is connected and your source/consumer is amp-review. The browser pinned the Review card and sent amp-review a fresh instruction to append receipt CHECK-30. Prove the round trip, then confirm that an idle Amp thread will now wake automatically and that native Skills discovery works.",
756
+ "prompt": "On this disposable board, raw native Amp MCP is connected without the directory plugin and your source/consumer is amp-review. The browser pinned the Review card and sent amp-review a fresh instruction to append receipt CHECK-30. Prove the round trip, then confirm that an idle Amp thread will now wake automatically and that native Skills discovery works.",
734
757
  "expected_output": "Uses actual Amp Canvas tools to read the pinned card, claims only as amp-review, signals intent and appends the requested receipt without losing existing content. Verifies the rendered receipt before marking that delivery for amp-review and confirms it is no longer pending. Uses a different recipient as a negative control and detaches only self-owned test sessions. Reports active-agent polling as verified but declines to infer idle-thread wake-up, persistent pumping or native MCP Skills discovery from this evidence.",
735
758
  "assertions": [
736
759
  {
@@ -1058,6 +1081,88 @@
1058
1081
  "type": "output_check"
1059
1082
  }
1060
1083
  ]
1084
+ },
1085
+ {
1086
+ "id": 45,
1087
+ "name": "quiet-expiry-versus-veto-and-leaf-linkage",
1088
+ "prompt": "In a disposable canvas, signal separate create intents for three Markdown cards. Let the harness quietly expire one, human-veto another, and leave the third live. Create each through a separate batch leaf using the returned intent ID. Explain whether putting one intentId on the batch envelope would protect every sibling. Do not bypass the veto or treat expiry as approval.",
1089
+ "expected_output": "Uses operations[].args.intentId on supported node.add leaves, never the batch envelope. Verifies the expired case proceeds unlinked, the vetoed case creates no card, and the live case settles once. Explains the standalone-MCP versus attached-HTTP top-level mismatch without relying on either behavior. Ordinary scope/revision rules still apply; no new ID is minted to evade the veto.",
1090
+ "assertions": [
1091
+ {
1092
+ "name": "distinguishes-expiry-from-human-refusal",
1093
+ "description": "Readback finds the expired control's card but no vetoed card; the agent neither labels quiet expiry a veto nor retries the vetoed plan under another ID",
1094
+ "type": "output_check"
1095
+ },
1096
+ {
1097
+ "name": "links-only-the-supported-leaf",
1098
+ "description": "Trace puts intentId in node.add args, verifies live settlement, and does not claim one settled intent protects later siblings or a top-level batch intent is portable",
1099
+ "type": "output_check"
1100
+ }
1101
+ ]
1102
+ },
1103
+ {
1104
+ "id": 46,
1105
+ "name": "amp-bound-delivery-and-separate-jev-consents",
1106
+ "prompt": "The actual Amp plugin binds this thread to A while the human views B. Its context packet contains a receive token and a summary of A/Review. Addressed steering asks you to append CHECK-46 there. Context ranking is enabled but Jev advice is off. Show the edit, acknowledge it, and ask Jev to rank your proposed changes. Can you read canvas://context instead, open A, or wake a sleeping orb? Do not change consent yourself.",
1107
+ "expected_output": "Checks session status, receives each supplied packet token, reads full A/Review through routed MCP, edits without switching B, and verifies the result before acknowledging steering. Does not mistake a context receipt for a full read or completed action. Declines Jev inference without the separate advice consent, using deterministic fallback or requesting human opt-in. Reports awake-executor idle wake separately from sleeping-orb resume.",
1108
+ "assertions": [
1109
+ {
1110
+ "name": "uses-bound-tools-without-navigation",
1111
+ "description": "Trace uses routed MCP rather than CLI or resources/read, preserves B's active view, and never overrides the bound destination",
1112
+ "type": "output_check"
1113
+ },
1114
+ {
1115
+ "name": "receive-is-not-acknowledge",
1116
+ "description": "Packet reception precedes full content reading and action; visible CHECK-46 verification precedes steering acknowledgment, and failed/unverified work is not acknowledged",
1117
+ "type": "output_check"
1118
+ },
1119
+ {
1120
+ "name": "consent-and-wake-boundaries",
1121
+ "description": "Ranking consent is not reused for advice, no consent is enabled by the agent, and native awake-executor wake is not claimed to wake a sleeping orb",
1122
+ "type": "output_check"
1123
+ }
1124
+ ]
1125
+ },
1126
+ {
1127
+ "id": 47,
1128
+ "name": "authored-versus-live-task-card-ownership",
1129
+ "prompt": "In a disposable library, A and B each have a task named Review. Show A's existing task as a live status card and also create an independent authored plan card. Mark A's task in-progress, move its presentation to B, then delete that presentation. Do not transfer or cancel either task. Can you edit the live card's title/progress or rebind it to B's same-named task?",
1130
+ "expected_output": "Resolves task identity on A, creates the live card using workItemId without derived fields, and creates the authored card separately with workState. Updates the task through canvas_ax_work on A. After moving, confirms immutable workItemBoardId A and fresh task-derived display; rejects title/progress edits and rebinding. Deleting the presentation leaves both tasks intact and the authored card independent.",
1131
+ "assertions": [
1132
+ {
1133
+ "name": "separates-task-from-presentation",
1134
+ "description": "Live creation includes the resolved task ID but no derived title/content/workState/detail/progress; authored creation uses workState without a task binding",
1135
+ "type": "output_check"
1136
+ },
1137
+ {
1138
+ "name": "preserves-owner-across-move",
1139
+ "description": "Readback after relocation shows owner A, the original task ID and updated state, never B's same-title task; no rebinding or direct display-field edit is attempted as a solution",
1140
+ "type": "output_check"
1141
+ },
1142
+ {
1143
+ "name": "deletion-is-not-cancellation",
1144
+ "description": "After deleting only the presentation, qualified task reads confirm A's task is still in-progress and B's task unchanged; authored plan data remains independent",
1145
+ "type": "output_check"
1146
+ }
1147
+ ]
1148
+ },
1149
+ {
1150
+ "id": 48,
1151
+ "name": "batch-annotation-partial-result-and-tool-envelopes",
1152
+ "prompt": "In a disposable canvas, read canvas_help for supported batch operations. Add a text annotation with an explicit ID, then submit a deliberate unsupported edge.update as the second batch entry. Inspect the failure before retrying the annotation, then remove it. Compare the raw structured replies from canvas_help, canvas_batch and canvas_ingest_activity. Can you always unwrap result.data or retry the entire failed batch?",
1153
+ "expected_output": "Uses annotation.add/remove, identifies edge.update as unsupported, and checks the failedIndex plus committed results/refs before retrying. Equal normalized annotation content with the same ID reuses the mark; removal is not a durable replay receipt. Distinguishes registry result.operation/outcome/data, help metadata under result and direct activity fields. It preserves isError/partial state instead of discarding it or blindly replaying writes.",
1154
+ "assertions": [
1155
+ {
1156
+ "name": "partial-failure-keeps-earlier-annotation",
1157
+ "description": "Failure at index 1 retains one annotation; identical-ID/content retry does not duplicate it, and removal erases that mark only",
1158
+ "type": "output_check"
1159
+ },
1160
+ {
1161
+ "name": "decodes-per-tool-contract",
1162
+ "description": "Extracts batch results from structuredContent.result.data and checks outcome partial, reads help from result, and reads activity fields directly without blanket unwrapping",
1163
+ "type": "output_check"
1164
+ }
1165
+ ]
1061
1166
  }
1062
1167
  ]
1063
1168
  }
@@ -349,7 +349,7 @@ The CLI targets `http://localhost:4313` by default. Override with `PMX_CANVAS_UR
349
349
  | Type | Purpose | When to use |
350
350
  |------|---------|-------------|
351
351
  | `markdown` | Rich formatted content | Explanations, documentation, notes, findings |
352
- | `status` | Compact color-coded indicator | Progress tracking, build/test results, task state |
352
+ | `status` | Compact status or deliberately authored work card | Work plans with `data.workState`; phase/tool status without it |
353
353
  | `file` | Live file viewer (auto-watches) | Show source code with live updates on file change |
354
354
  | `image` | Image display | Screenshots, diagrams, charts |
355
355
  | `context` | Context card | Key context the human should see |
@@ -419,6 +419,9 @@ contract). Their meaning comes from the node **type** and value instead: a `stat
419
419
  `waiting` — e.g. `review` → green, `running` → accent; an unrecognized phase renders gray), and a
420
420
  `trace` node from its `status` field (`success` → green, `failed` → red, `running` → accent). To
421
421
  color an arbitrary region, group the nodes and set the group's `color`.
422
+ Authored status cards with `data.workState` instead use the work-state glyph and label:
423
+ blocked uses the warning token, done the success token, and cancelled the muted token.
424
+ Do not set arbitrary colors to encode work state.
422
425
 
423
426
  When you do set a color (group/graph), use this palette consistently to convey meaning:
424
427
  - **Green** (`#22c55e`) — success, done, healthy
@@ -455,9 +458,9 @@ enforce conditional requirements. Non-registry tools use `tools/list` instead.
455
458
  | `canvas_edge` | `add` · `update` · `remove` | Connect / edit / disconnect nodes |
456
459
  | `canvas_group` | `create` · `add` · `ungroup` | Manage spatial group containers |
457
460
  | `canvas_history` | `undo` · `redo` | Time travel through the mutation ring buffer |
458
- | `canvas_board` | `list` · `get` · `create` · `create-from` · `open` · `update` · `pin` · `unpin` · `knowledge-list` · `category-set` · `category-remove` · `folder-set` · `relation-preset-set` · `relation-preset-remove` | Boards and workspace categories/folder properties/shared relation templates; knowledge writes never open a board. Template edits/deletion never rewrite boards or connections. `category-remove` takes `id` and refuses explicit folder assignments, including empty folders; reassign or clear them first. |
461
+ | `canvas_board` | `list` · `get` · `create` · `create-from` · `move-selection` · `open` · `update` · `pin` · `unpin` · `knowledge-list` · `category-set` · `category-remove` · `folder-set` · `relation-preset-set` · `relation-preset-remove` | Boards and workspace categories/folder properties/shared relation templates; knowledge writes never open a board. Template edits/deletion never rewrite boards or connections. `category-remove` takes `id` and refuses explicit folder assignments, including empty folders; reassign or clear them first. |
459
462
  | `canvas_snapshot` | `save` · `list` · `restore` · `restore-node` · `delete` · `gc` · `diff` | Named snapshots: save/list/restore/delete, garbage-collect old ones, diff current canvas vs a snapshot (`diff` takes `snapshot`, not `id`); `restore-node` puts one card (`nodeId`) back to its content in snapshot `id` |
460
- | `canvas_view` | `arrange` · `focus` · `fit` · `clear` · `remove-annotation` · `get-tour` · `set-tour` · `tour-go` · `tour-exit` · `move` | Auto-arrange, pan-to-node, fit viewport, clear the board, delete annotations, read/persist ordered presentation stops (`tour: null` derives group order), present a stop / exit, ease the camera to a node, rect or viewport (never an undo step) |
463
+ | `canvas_view` | `arrange` · `focus` · `fit` · `clear` · `add-annotation` · `remove-annotation` · `get-tour` · `set-tour` · `tour-go` · `tour-exit` · `move` | Auto-arrange, pan-to-node, fit viewport, clear the board, draw/write/erase annotations, read/persist ordered presentation stops (`tour: null` derives group order), present a stop / exit, ease the camera to a node, rect or viewport (never an undo step) |
461
464
  | `canvas_query` | `context` · `graph` · `search` · `layout` · `validate` | Read the budgeted brief or summary-only connected memory graph, find nodes, read full layout, or **`validate`** collisions / containment / dangling edges |
462
465
  | `canvas_app` | `open-mcp-app` · `diagram` · `build-artifact` | Hosted MCP apps, the Excalidraw diagram preset, and bundled web artifacts (folds `canvas_open_mcp_app` / `canvas_add_diagram` / `canvas_build_web_artifact`) |
463
466
  | `canvas_webview` | `status` · `start` · `stop` · `resize` · `evaluate` | Headless Bun.WebView automation for the workbench (folds the `canvas_webview_*` / `canvas_resize` / `canvas_evaluate` tools) |
@@ -498,6 +501,18 @@ group structure are optional; fresh IDs are allocated; pins, AX state, and
498
501
  history are not copied; the source remains unchanged and the new board inactive.
499
502
  The new board records `previousBoardId` pointing to its source.
500
503
 
504
+ For an identity-preserving move, use `canvas_board` action `move-selection`, not
505
+ copy/delete. Read the active source board's `contentRevision` with `get`. Preview
506
+ with `sourceBoardId`, `nodeIds`, `name`, `expectedRevision: contentRevision`,
507
+ `requestId` and `preview: true`; inspect blockers and notices before committing
508
+ with the same inputs without `preview`. Retry an uncertain response with the same
509
+ request ID and inputs. Group descendants move together; unsafe bindings refuse
510
+ the entire move. Cards retain identities, pins, relations and review history,
511
+ without new validation or read evidence. The source stays open with a portal to
512
+ the new board. Pre-move Undo/Redo is cleared on affected boards; older snapshots
513
+ remain inspectable but cannot be restored across the move. Open the returned
514
+ `destinationBoardId` only when navigation is wanted.
515
+
501
516
  ### Connected memory (wave 2)
502
517
 
503
518
  Home Folders, Map and Graph, wiki links/backlinks, and brief discovery share one
@@ -609,8 +624,11 @@ persisted, auto-expiring (~8s), never in `canvas_query layout`.
609
624
  Narrate → linked mutation → automatic settle:
610
625
  1. `canvas_intent { action: "signal", kind: "create", nodeType: "markdown", label: "Add evidence", reason: "capturing the failing test", confidence: 0.8 }` → returns `intent.id` and the `position` the canvas chose.
611
626
  2. Make the real move and pass that id: `canvas_node { action: "add", intentId: <intent.id>, ... }`.
612
- 3. PMX rejects the mutation if the intent was vetoed or expired; otherwise the
613
- successful mutation settles the ghost into the resulting node automatically.
627
+ 3. A human-vetoed intent rejects its linked mutation. A quietly expired ghost does not:
628
+ the write proceeds unlinked, subject to the ordinary permissions and revision checks.
629
+ A successful write linked to a still-live intent settles the ghost automatically.
630
+ Expiry is neither approval nor a human veto. Never retry a vetoed plan under a new ID
631
+ just to bypass the human's decision.
614
632
 
615
633
  Use `canvas_intent { action: "clear", id }` only when abandoning a plan without
616
634
  performing the linked mutation.
@@ -635,9 +653,18 @@ edits; destructive actions (clear/restore/remove); and creating
635
653
  artifact/report/dashboard nodes. Skip for tiny metadata fixes, API-only pin/unpin
636
654
  verification, deterministic report-node refreshes the human just asked for,
637
655
  post-restore cleanup, and bulk fixture churn. **For batch work, signal one ghost
638
- per human-meaningful move, not one per low-level op** — e.g. one "lay out the
639
- investigation board" intent, then run the batch with that linked `intentId` (use
640
- `seq` to order staged previews) so the human watches the wireframe before it fills.
656
+ per human-meaningful move, not one per low-level op.** Put its `intentId` inside the
657
+ supported leaf operation's `args`, never on the `canvas_batch` envelope. Each live
658
+ intent settles once; it is not a veto gate for every sibling in a batch. For example,
659
+ after signalling a create intent, use its actual returned ID in this leaf:
660
+
661
+ ```json
662
+ {"operations":[{"op":"node.add","args":{"type":"markdown","title":"Evidence","content":"Observed failure","intentId":"<returned-intent-id>"}}]}
663
+ ```
664
+
665
+ Do not rely on a top-level batch `intentId`: standalone MCP can refuse it, while the
666
+ attached HTTP batch reader does not forward it. Unsupported operations cannot be made
667
+ veto-linked by wrapping them in a batch. Use `seq` to order separate staged previews.
641
668
 
642
669
  ### Standalones (first-class — not deprecated)
643
670
 
@@ -648,10 +675,12 @@ composite in v0.4.0 (actions `save | list | restore | delete | gc | diff`); the
648
675
  standalones were removed after their deprecated 0.3.x window.
649
676
 
650
677
  `canvas_batch` supports exactly these ops: `node.add`, `node.update`, `node.remove`, `graph.add`,
651
- `edge.add`, `edge.update`, `edge.remove`, `group.create`, `group.add`, `group.remove`, `pin.set`/`pin.add`/
652
- `pin.remove`, `snapshot.save`, and `arrange`. Anything else fails with "Unsupported canvas_batch
678
+ `edge.add`, `edge.remove`, `group.create`, `group.add`, `group.remove`, `annotation.add`,
679
+ `annotation.remove`, `pin.set`, `pin.add`, `pin.remove`, `snapshot.save`, and `arrange`.
680
+ `edge.update` is not supported. Anything else fails with "Unsupported canvas_batch
653
681
  operation" — batch is non-atomic, so earlier ops stay applied and the response carries
654
- `failedIndex`. `canvas_screenshot` requires an active automation WebView: call
682
+ `failedIndex`, `results` and `refs`. Inspect that committed prefix before retrying; an
683
+ error does not roll it back. `canvas_screenshot` requires an active automation WebView: call
655
684
  `canvas_webview { action: "start" }` first.
656
685
 
657
686
  > **Removed in v0.3.0 → use the composite instead**: `canvas_open_mcp_app` / `canvas_add_diagram` /
@@ -702,8 +731,33 @@ delete+recreate; preserves edges, pins, position)
702
731
 
703
732
  **`canvas_node { action: "get", id }`** — Get a single node's full data by `id`.
704
733
 
705
- **`canvas_view { action: "remove-annotation", id }`** — Remove a human-drawn annotation by `id`. Use when
706
- context gives you the annotation ID; use WebView first if you need to identify a mark by shape or location.
734
+ **`canvas_view { action: "add-annotation", points, … }`** — Draw freehand ink with at least two
735
+ world-coordinate points, or set `type: "text"`, `text` and one point to write a note.
736
+ `width` is stroke width (default 4, clamped to 1–24) or font size (default 24,
737
+ clamped to 1–96). `color` defaults to `currentColor`, the theme's annotation ink;
738
+ explicit colors must be `#rrggbb`. Text is trimmed to 240 characters, labels to 160.
739
+ Bounds and creation time are server-derived.
740
+
741
+ Freehand points render as straight segments with round caps/joins, without automatic
742
+ smoothing. Sample curves densely for smooth-looking outlines and loops. Cursor updates
743
+ through `canvas_ax_state { action: "set-presence", cursor: { x, y } }` are separate,
744
+ ephemeral presence, not drawing gestures; reuse your writer identity without attaching
745
+ a session. An annotation appears complete on creation, not as a streaming stroke.
746
+ See [Shared ink and questions](workbench-workflows.md#shared-ink-and-questions).
747
+
748
+ Use an explicit `id` for retries: equal normalized content returns the existing mark
749
+ without another Undo entry, while different content conflicts. After erasing or Undo,
750
+ adding the ID creates a mark again; this is not a durable creation receipt.
751
+
752
+ **`canvas_view { action: "remove-annotation", id }`** — Erase a whole human or agent mark,
753
+ not the underlying card. An absent mark returns not-found. Context gives you IDs;
754
+ inspect the canvas first when identifying a mark by shape or location.
755
+ CLI and MCP batches accept `annotation.add` / `annotation.remove` with the same arguments.
756
+
757
+ Humans and agents share this layer. Use marks when helpful, not for every task.
758
+ The human may answer in the external agent host's composer; no PMX session,
759
+ PMX composer or reply card is required. Marks are not approval gates, and drawing
760
+ or erasing does not answer a question or execute a loop. Existing scope fences apply.
707
761
 
708
762
  **`canvas_node { action: "update", id, refresh: true }`** — Re-fetch the URL stored on a `webpage` node
709
763
  - `id` (required): webpage node to refresh
@@ -962,17 +1016,17 @@ below operates on the live canvas state through the `canvas_webview` composite.
962
1016
  Useful workbench selectors:
963
1017
  - Nodes: `.canvas-node`, `.canvas-node.active`, `.canvas-node.context-pinned`, `.canvas-node.group-node`
964
1018
  - Node internals: `.node-title`, `.node-titlebar`, `.node-body`, `.node-type-badge`, `.node-controls`
965
- - Annotations: `.annotation-layer path` renders human-drawn freehand ink. Use WebView
966
- to inspect or screenshot annotation shapes; MCP/context resources only expose compact
967
- annotation target summaries, not the raw visual shape. Humans can remove marks with
968
- the eraser in the rail's Annotate popover; agents can remove a known annotation ID with
969
- `canvas_view { action: "remove-annotation" }`.
1019
+ - Annotations: `.annotation-layer path` renders shared freehand ink; `.annotation-layer text`
1020
+ renders text notes. Use WebView to inspect or screenshot shapes; MCP/context resources
1021
+ expose IDs, text, labels, targets and bounds, not raw stroke geometry. Humans use the
1022
+ rail's Draw / Text note / Eraser tools; agents use `canvas_view` actions
1023
+ `add-annotation` / `remove-annotation` on the same layer.
970
1024
  - Canvas chrome (rail-chrome-v2): `.tool-rail`, `.top-bar` (`.connection-dot`, `.agent-chip`,
971
1025
  `.gate-badge`, `.context-chip`, `.external-indicator`, `.start-session-btn`),
972
1026
  `.connection-banner`, `.canvas-region`, `.session-panel`, `.command-bar`, `.selection-bar`,
973
1027
  `.activity-feed`, `.writers-sheet`, `.session-receipt`, `.snapshot-panel` (the History
974
1028
  drawer), `.minimap`, `.empty-state`, `.command-palette`, `.expanded-overlay-panel`.
975
- - Presence: `.agent-cursor` (attached agent), `.human-cursor` (other tabs), `.scope-fence`,
1029
+ - Presence: `.agent-cursor` (attached or external agent), `.human-cursor` (other tabs), `.scope-fence`,
976
1030
  `.canvas-node.agent-mutating` (shimmer), `.node-yield-pill`.
977
1031
  - Groups: `.canvas-node.group-node` with `.group-name-pill`, `.group-actions`, `.group-chip`
978
1032
  (collapsed); `.drop-pill` while a dragged node would join/leave a group; `.edge-hint-pill`
@@ -1146,6 +1200,22 @@ writes occurred. Interaction, activity-ingestion and screenshot tools instead
1146
1200
  use direct structured objects matching their schemas. Check `isError` and domain
1147
1201
  outcomes. A composite's annotations cover all its actions, not just reads.
1148
1202
 
1203
+ Paired example: `canvas_node { action: "add", type: "markdown", content: "Evidence" }`
1204
+ returns registry data under `structuredContent.result.data` (excerpt; the ID varies):
1205
+
1206
+ ```json
1207
+ {"result":{"operation":"node.add","outcome":"success","data":{"ok":true,"id":"example-node"}}}
1208
+ ```
1209
+
1210
+ By contrast, `canvas_help {}` returns `structuredContent.result.operations`, not
1211
+ `result.data`. `canvas_help { op: "node.add" }` returns metadata with `operation`,
1212
+ `tool`, `description` and `inputSchema` directly under `result`.
1213
+ For direct tools (`canvas_ax_interaction`, `canvas_ingest_activity`, `canvas_screenshot`),
1214
+ read fields directly from `structuredContent` according to their `outputSchema`.
1215
+ These are different contracts, not optional wrappers to strip recursively. Text blocks
1216
+ are a separate representation; an SDK/host may already return `structuredContent`.
1217
+ On a failed call, inspect its error response and partial results before retrying writes.
1218
+
1149
1219
  Cancellation releases supported AX waits, aborts webpage fetches before late
1150
1220
  content writes, and stops subsequent batch operations. Completed writes remain;
1151
1221
  batch partial results retain `results` and `refs`. A created webpage can remain
@@ -1449,7 +1519,7 @@ The `canvas://spatial-context` resource reveals how the human has organized info
1449
1519
  This implies sequence or priority.
1450
1520
  - **Pinned neighborhoods** — For each pinned node, nearby unpinned nodes are listed. These
1451
1521
  are the human's implicit context — things they consider related to what they pinned.
1452
- - **Annotations** — Human-drawn markup is summarized by target/bounds only, e.g. an
1522
+ - **Annotations** — Shared markup is summarized by ID, label, text, target and bounds, e.g. an
1453
1523
  annotation over a node or empty canvas region. Use WebView (`canvas_webview { action: "start" }` +
1454
1524
  `canvas_webview { action: "evaluate" }`/`canvas_screenshot`) when you need to see whether the mark is an
1455
1525
  arrow, line, circle, or other drawn shape. Remove known annotations with
@@ -1575,15 +1645,59 @@ Show system components and how they interact:
1575
1645
 
1576
1646
  ### Task Plan with Dependencies
1577
1647
 
1578
- Track work items and their relationships:
1648
+ Show useful work deliberately, not a card per task or event. Ordinary work cards are authored
1649
+ node data, not AX work items. They require no session and create no approval or execution.
1650
+
1651
+ 1. Create a `status` node with `data.workState`: `todo`, `in-progress`, `blocked`, `done` or
1652
+ `cancelled`. Use string `data.detail` for context and optional `data.progress` from 0 to 100.
1653
+ Progress is independent of state: Done does not imply 100%; `null` clears progress.
1654
+ 2. Update the same card through `canvas_node { action: "update", id, data: { ... } }`.
1655
+ Include `expectedBoardId` and `expectedContentRevision` when an edit depends on a prior read.
1656
+ 3. Connect steps, dependencies, alternatives and intentional loops with existing relations.
1657
+ A drawn loop does not execute. Group distinct phases when useful, then inspect readability.
1658
+ 4. Humans use **New work card** from the background menu and **Edit/Save/Cancel** inside the card.
1659
+ Drafts and pending/refused saves survive focus-mode open/close, but not a page reload.
1660
+ The editor's temporary growth does not resize the saved card.
1661
+
1662
+ MCP creation:
1663
+
1664
+ ```json
1665
+ {"action":"add","type":"status","title":"Verify","data":{"workState":"todo","detail":"Run browser checks"}}
1666
+ ```
1667
+
1668
+ CLI creation uses structured batch data, not `node add --data` (that flag is for graph series):
1669
+
1670
+ ```bash
1671
+ pmx-canvas batch --json '[{"op":"node.add","args":{"type":"status","title":"Verify","data":{"workState":"todo","detail":"Run browser checks"}}}]'
1672
+ ```
1673
+
1674
+ Without `data.workState`, status cards retain their phase/tool display. Session-task linking
1675
+ is not provided by these authored cards. Questions can be drawn or written beside the plan;
1676
+ the human can answer in the external agent host's composer, without a PMX reply card.
1677
+
1678
+ ### Live task cards
1679
+
1680
+ A live card presents an existing AX work item; it is not another task or an authored
1681
+ work plan. Read the task first with `canvas_ax_work { action: "list" }` on its owning
1682
+ board, then create a `status` presentation using that task's actual ID:
1683
+
1684
+ ```json
1685
+ {"action":"add","type":"status","data":{"workItemId":"<existing-task-id>"}}
1686
+ ```
1579
1687
 
1580
- 1. Create `status` nodes for each task
1581
- 2. Color-code: green=done, yellow=in-progress, red=blocked, gray=queued, blue=ready/available
1582
- 3. Connect with `depends-on` edges — use `dashed` style for blocked dependencies, `solid` for
1583
- satisfied ones
1584
- 4. Update status nodes as work progresses using `canvas_node { action: "update" }`
1585
- 5. Arrange with `flow` layout to show the dependency chain left-to-right
1586
- 6. Group related tasks if the plan has distinct phases
1688
+ The owner defaults to the current board. To present a task from another board, supply
1689
+ its explicit `data.workItemBoardId` too. Both task ID and owner are fixed at creation;
1690
+ moving the card does not transfer the task. Create through the current board owner
1691
+ (or the Amp plugin's bound board), not `destinationBoardId` background creation.
1692
+
1693
+ Omit `title`, `content`, `workState`, `detail`, `progress`, `axWorkStatus`,
1694
+ `liveWorkAvailable` and `liveWorkSource` from creation and updates, including nested
1695
+ data fields. The server derives title, detail, status and source from the task; these
1696
+ are read-only display fields. Update the underlying work item on its owning board with
1697
+ `canvas_ax_work { action: "update", id: "<existing-task-id>", status: "in-progress" }`.
1698
+ Position and size still belong to the card. Deleting the presentation does not cancel
1699
+ or delete the task. If the task is unavailable, the card displays that fact rather than
1700
+ becoming an editable authored card. To change the binding, create a new presentation.
1587
1701
 
1588
1702
  ### Code Exploration
1589
1703
 
@@ -110,6 +110,13 @@ agent.
110
110
  - `interaction-prototype` exposes live controls and copyable config for implementation tuning.
111
111
  - Tell the human which copy/export button to use, then ask them to paste the result back if you need to act on edits.
112
112
 
113
+ The card menu also offers **Copy JSON** for non-presentation HTML primitives. Open the viewer
114
+ first: this reads its current interactive state, preferring the expanded frame when present,
115
+ not a stale export of saved node data. The reply is bound to the frame source, document token
116
+ and request ID; the parent workbench requests clipboard access from the human's click.
117
+ Clipboard permission or host limitations can still refuse the copy and show an error.
118
+ This does not persist edits, support arbitrary raw HTML, or replace the per-format buttons above.
119
+
113
120
  ## Sandbox And Persistence
114
121
 
115
122
  - Primitive output runs inside the existing HTML iframe sandbox with scripts allowed but no same-origin access.
@@ -4,7 +4,7 @@ Use this reference when the `pmx-canvas` skill is installed but the `pmx-canvas`
4
4
 
5
5
  ## Prerequisites and version
6
6
 
7
- The examples pin **PMX Canvas 0.11.0**, which requires **Bun >=1.4.4** even when
7
+ The examples pin **PMX Canvas 0.12.1**, which requires **Bun >=1.4.4** even when
8
8
  installed through npm: the CLI runs through Bun, not Node. Check `bun --version`
9
9
  first. If missing or older, follow the [Bun installation instructions](https://bun.sh/docs/installation)
10
10
  with the user's authorization. Ensure Bun is on the MCP host's PATH as well as the
@@ -22,11 +22,11 @@ in `SKILL.md`. Do not pair newer checkout guidance with an older runtime unknowi
22
22
  ## Install from npm
23
23
 
24
24
  ```bash
25
- npm install -g pmx-canvas@0.11.0
25
+ npm install -g pmx-canvas@0.12.1
26
26
  pmx-canvas --version
27
27
  ```
28
28
 
29
- Without a global install, use `bunx pmx-canvas@0.11.0` in place of `pmx-canvas` in
29
+ Without a global install, use `bunx pmx-canvas@0.12.1` in place of `pmx-canvas` in
30
30
  the commands below. Do not use unpinned `bunx pmx-canvas` for a version-specific check.
31
31
 
32
32
  ## Choose the workspace and target
@@ -96,7 +96,7 @@ discards empty env values, remove `PMX_CANVAS_URL` from its launch environment i
96
96
  "mcpServers": {
97
97
  "canvas": {
98
98
  "command": "bunx",
99
- "args": ["pmx-canvas@0.11.0", "--mcp"],
99
+ "args": ["pmx-canvas@0.12.1", "--mcp"],
100
100
  "env": {
101
101
  "PMX_CANVAS_WORKSPACE_ROOT": "/absolute/path/to/project",
102
102
  "PMX_CANVAS_PORT": "14313",
@@ -130,9 +130,59 @@ fallback ports; do not assume the configured port is the one the MCP server boun
130
130
 
131
131
  ## Amp: connect the agent separately from the portal
132
132
 
133
- PMX does not ship a dedicated Amp lifecycle adapter. Amp can use the native MCP tools;
134
- the portal is only the human's browser UI. Configure MCP inside the orb or runner where
135
- Amp executes, not only on the user's laptop. Merge this into that workspace's
133
+ PMX ships an opt-in directory plugin with board binding and receipt-based steering, or
134
+ you can configure raw MCP for active polling. The portal is the human's browser UI;
135
+ neither opening it nor configuring raw MCP installs the plugin. Choose one integration
136
+ for the task rather than creating duplicate writers.
137
+
138
+ ### Amp plugin: bound threads
139
+
140
+ When installation is requested, copy the complete installed package directory
141
+ `node_modules/pmx-canvas/dist/amp-plugin/pmx-canvas` to the project's
142
+ `.amp/plugins/pmx-canvas`. Inspect existing plugin files and preserve local changes;
143
+ replacement needs owner approval. Reload Amp plugins and load the qualified
144
+ `pmx-canvas:pmx-canvas` skill. Approve its workspace MCP command through the normal
145
+ human trust flow, never by bypassing it. No global plugin installation is implied.
146
+
147
+ Use `pmx_canvas_session { action: "open" }` to start/reconnect and verify the service,
148
+ then `bind` with an existing explicit `boardId`. `status` reports the binding and
149
+ shared active board; `unbind` removes only this thread's binding. Binding does not
150
+ open a board, change sharing, or create an access-control boundary.
151
+
152
+ Bound MCP tool calls route to that board with identity `amp:<thread-id>`, even when
153
+ the human views another board or Home. Use `canvas_query` for context and full
154
+ `canvas_node` reads for needed content. CLI calls and MCP resource reads are not
155
+ intercepted. Do not navigate the shared workbench through bound calls, override the
156
+ destination, or open the board to make a write work. A missing board or changed
157
+ binding fails instead of silently targeting the visible board; a binding change
158
+ during a turn requires a new turn.
159
+
160
+ At turn start, return the supplied context token through
161
+ `pmx_canvas_delivery { action: "receive", token }`. Reception records the delivered
162
+ map, not full card reads, understanding or approval. For a steering token, receive it,
163
+ read the relevant content, act, verify the result, and only then call
164
+ `pmx_canvas_delivery { action: "acknowledge", token }`. Do not acknowledge failed or
165
+ unverified work. Uncertain sends require human resolution, not blind retries or
166
+ deleting the transport journal.
167
+
168
+ Addressed steering can start an idle thread or queue into a busy turn only while
169
+ the plugin executor is awake. It does not wake a sleeping orb or hold a keep-alive
170
+ lease. A raw MCP polling test does not prove this native delivery path.
171
+
172
+ **Context ranking** and **Jev advice** are separate opt-ins, both off by default.
173
+ Their Amp commands require separate human confirmation for the current binding and
174
+ disclose data sent to TypeSafe Jev and the invoking thread's inference billing.
175
+ Ranking reorders optional summaries; advice suggests formats or review order without
176
+ creating output or verifying work. One consent never enables the other. Rebinding
177
+ does not carry either consent. Respect deterministic fallback and report it rather
178
+ than retrying with another provider. See the
179
+ [plugin contract](https://github.com/pskoett/pmx-canvas/blob/main/docs/amp-plugin.md)
180
+ for request fields, retry identities and native acceptance limits.
181
+
182
+ ### Raw MCP: active polling
183
+
184
+ Configure MCP inside the orb or runner where Amp executes, not only on the user's
185
+ laptop. Merge this into that workspace's
136
186
  `.amp/settings.json`, preserving other settings (Amp does not use the generic `.mcp.json`):
137
187
 
138
188
  ```json
@@ -140,7 +190,7 @@ Amp executes, not only on the user's laptop. Merge this into that workspace's
140
190
  "amp.mcpServers": {
141
191
  "canvas": {
142
192
  "command": "bunx",
143
- "args": ["pmx-canvas@0.11.0", "--mcp"],
193
+ "args": ["pmx-canvas@0.12.1", "--mcp"],
144
194
  "includeTools": ["canvas_*"],
145
195
  "env": {
146
196
  "PMX_CANVAS_WORKSPACE_ROOT": "/absolute/path/to/project",
@@ -174,7 +224,7 @@ The agent must not run this approval itself or move the command to global settin
174
224
  `--mcp-config` to bypass workspace trust. Approval authorizes execution of this MCP
175
225
  command; it is not a new Canvas import consent or permission to mutate arbitrary boards.
176
226
  After approval, reload MCP connections (`reload_mcp` in Amp) and require `connected`.
177
- Discover `canvas` tools with `tool_search`; the full unfiltered 0.11.0 server has 25 tools,
227
+ Discover `canvas` tools with `tool_search`; the full unfiltered 0.12.1 server has 25 tools,
178
228
  including `canvas_help`. If still absent, inspect the server status, command/PATH and target instead
179
229
  of reinstalling blindly. See [Amp MCP documentation](https://ampcode.com/docs/customize/mcp).
180
230
 
@@ -194,8 +244,8 @@ of reinstalling blindly. See [Amp MCP documentation](https://ampcode.com/docs/cu
194
244
  4. Verify the visible result in the browser before marking the message delivered for
195
245
  that consumer. A subsequent claim should omit it. Detach only test-owned sessions.
196
246
 
197
- This proves an **active agent can poll and act**, not automatic wake-up of an idle Amp
198
- thread, background polling, or automatic agent launch for imports. An MCP connection
247
+ This raw-MCP check proves an **active agent can poll and act**, not automatic wake-up
248
+ of an idle Amp thread, background polling, or automatic agent launch for imports. An MCP connection
199
249
  does not install a steering pump. Only configure a pump/host integration when requested;
200
250
  its startup backlog rules are in the main skill. Tool discovery and resource reads also
201
251
  do not establish Amp support for native MCP Skills-extension discovery or activation.