pmx-canvas 0.10.0 → 0.12.0

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 (343) hide show
  1. package/.github/extensions/pmx-canvas/extension.mjs +3 -1
  2. package/.github/extensions/pmx-canvas/runtime.json +1 -1
  3. package/.github/extensions/pmx-canvas/tools.json +688 -128
  4. package/CHANGELOG.md +69 -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 +251 -0
  11. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/evals/evals.json +1086 -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 +1785 -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 +251 -0
  26. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/tours-and-recording.md +111 -0
  27. package/dist/amp-plugin/pmx-canvas/skills/pmx-canvas/references/workbench-workflows.md +900 -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-cwtsds5d.js +1 -0
  33. package/dist/canvas/chunks/architecture-TIHT7OUA-x63cwejs.js +1 -0
  34. package/dist/canvas/chunks/architectureDiagram-T3A2C74G-b4xc9tpz.js +36 -0
  35. package/dist/canvas/chunks/blockDiagram-VBNYF7ZC-ahp3yxxs.js +132 -0
  36. package/dist/canvas/chunks/c4Diagram-5PPSVZJV-nappnay7.js +10 -0
  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-a428syda.js +1 -0
  40. package/dist/canvas/chunks/cynefin-VYW2F7L2-8v6jxfz8.js +1 -0
  41. package/dist/canvas/chunks/cynefinDiagram-MW4NZA55-nspsqebj.js +62 -0
  42. package/dist/canvas/chunks/dagre-VZM6K2ZE-8y6177fh.js +4 -0
  43. package/dist/canvas/chunks/diagram-7IWD3JNH-vym028wn.js +30 -0
  44. package/dist/canvas/chunks/diagram-B4RE2ZJO-jddqb8sy.js +3 -0
  45. package/dist/canvas/chunks/diagram-LBJQPF4R-bjwbpkrn.js +24 -0
  46. package/dist/canvas/chunks/diagram-Q27KOJAE-j6ph6hcx.js +24 -0
  47. package/dist/canvas/chunks/diagram-UB23O5K3-p09w8jej.js +41 -0
  48. package/dist/canvas/chunks/ebnfDiagram-BXEA7PRR-j975ycq5.js +1 -0
  49. package/dist/canvas/chunks/erDiagram-JOGREHBK-sxp6hjn8.js +85 -0
  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-4tv230y2.js +292 -0
  53. package/dist/canvas/chunks/gitGraph-TEB2WS4Q-macbhand.js +1 -0
  54. package/dist/canvas/chunks/gitGraphDiagram-DS77QQ5N-mqgmnw9g.js +106 -0
  55. package/dist/canvas/chunks/index-037z5dz2.js +232 -0
  56. package/dist/canvas/chunks/index-081n3har.js +207 -0
  57. package/dist/canvas/chunks/index-5n03dmb9.js +2 -0
  58. package/dist/canvas/chunks/index-5tv8v1hk.js +1 -0
  59. package/dist/canvas/chunks/index-60pgzdqe.js +157 -0
  60. package/dist/canvas/chunks/index-6ceya556.js +332 -0
  61. package/dist/canvas/chunks/index-8g1vb57n.js +2 -0
  62. package/dist/canvas/chunks/index-8rjes9r6.js +2 -0
  63. package/dist/canvas/chunks/index-9022d1n9.js +16 -0
  64. package/dist/canvas/chunks/index-9b02042t.js +2 -0
  65. package/dist/canvas/chunks/index-ap4q4vez.js +2 -0
  66. package/dist/canvas/chunks/index-dyp2nhd3.js +2 -0
  67. package/dist/canvas/chunks/index-frvta4tm.js +2 -0
  68. package/dist/canvas/chunks/index-gf4e0et4.js +2 -0
  69. package/dist/canvas/chunks/index-h9ycj8n2.js +2 -0
  70. package/dist/canvas/chunks/index-hj99nz1f.js +1 -0
  71. package/dist/canvas/chunks/index-mergmj97.js +2 -0
  72. package/dist/canvas/chunks/index-nwsya6dj.js +301 -0
  73. package/dist/canvas/chunks/index-nz8qbd1p.js +2 -0
  74. package/dist/canvas/chunks/index-qhfrazv3.js +2 -0
  75. package/dist/canvas/chunks/index-v119nznk.js +4 -0
  76. package/dist/canvas/chunks/index-vpt37m3d.js +89 -0
  77. package/dist/canvas/chunks/index-y9ma6azy.js +2 -0
  78. package/dist/canvas/chunks/index-zx0j3a2z.js +179 -0
  79. package/dist/canvas/chunks/info-DKCQHKI2-a0ykzs9z.js +1 -0
  80. package/dist/canvas/chunks/infoDiagram-6WML65LV-qv97qq6a.js +2 -0
  81. package/dist/canvas/chunks/ishikawaDiagram-WSZJBQD7-p9306gh0.js +70 -0
  82. package/dist/canvas/chunks/journeyDiagram-NVQOT4AX-sv67zats.js +139 -0
  83. package/dist/canvas/chunks/kanban-definition-27J2QSJJ-k2pfam6p.js +89 -0
  84. package/dist/canvas/chunks/katex-dmg8k4zm.js +257 -0
  85. package/dist/canvas/chunks/mermaid.core-83r0fdce.js +12 -0
  86. package/dist/canvas/chunks/mindmap-definition-FAOFIHXS-vg2newm1.js +96 -0
  87. package/dist/canvas/chunks/packet-7NZHBO7P-tqnabcdv.js +1 -0
  88. package/dist/canvas/chunks/pegDiagram-VL7TDLO6-k2h7zc5n.js +1 -0
  89. package/dist/canvas/chunks/pie-RZYD4A2V-wke6gyhe.js +1 -0
  90. package/dist/canvas/chunks/pieDiagram-7S7Q4E2Y-hg169p1v.js +39 -0
  91. package/dist/canvas/chunks/quadrantDiagram-CIZ2JOQS-bxtvsq0b.js +7 -0
  92. package/dist/canvas/chunks/radar-I7S5WNFK-w7ka0drw.js +1 -0
  93. package/dist/canvas/chunks/railroad-3IZDKUUU-y3vg318x.js +1 -0
  94. package/dist/canvas/chunks/railroad-abnf-AHOZXSZD-6hqvcz3c.js +1 -0
  95. package/dist/canvas/chunks/railroad-ebnf-EBAXGLYW-vcae260m.js +1 -0
  96. package/dist/canvas/chunks/railroad-peg-LSFZ7HO6-0dbyme23.js +1 -0
  97. package/dist/canvas/chunks/railroadDiagram-AXF67PYL-njyhcp4p.js +1 -0
  98. package/dist/canvas/chunks/requirementDiagram-LRYGKXZP-2z6v09gm.js +84 -0
  99. package/dist/canvas/chunks/sankeyDiagram-W5VNT64P-15mzam0e.js +40 -0
  100. package/dist/canvas/chunks/sequenceDiagram-SI44F4Z6-rbshyd2c.js +162 -0
  101. package/dist/canvas/chunks/sizeCapture-X5ZJPWSS-sg26xwts.js +1 -0
  102. package/dist/canvas/chunks/stateDiagram-OKZ733FA-6eahp98e.js +1 -0
  103. package/dist/canvas/chunks/stateDiagram-v2-UEYNNEHI-tty0ggn5.js +1 -0
  104. package/dist/canvas/chunks/swimlanes-SLNWSIFB-ze5db10t.js +1 -0
  105. package/dist/canvas/chunks/swimlanesDiagram-ULZ7WXOC-thze75gq.js +8 -0
  106. package/dist/canvas/chunks/timeline-definition-Z64GVDOM-vnp7jyy8.js +120 -0
  107. package/dist/canvas/chunks/treeView-QDETBFTQ-6ysffnm6.js +1 -0
  108. package/dist/canvas/chunks/treemap-6X3UGDF4-m3h9p066.js +1 -0
  109. package/dist/canvas/chunks/vennDiagram-T6HMQDX7-0qrnb7mj.js +34 -0
  110. package/dist/canvas/chunks/wardley-OPB4EBWU-dp37drwx.js +1 -0
  111. package/dist/canvas/chunks/wardleyDiagram-T6FBY63Y-8nxg8wqt.js +78 -0
  112. package/dist/canvas/chunks/xychartDiagram-ELKLHX3M-nj921e7s.js +7 -0
  113. package/dist/canvas/global.css +483 -230
  114. package/dist/canvas/index.js +158 -219
  115. package/dist/canvas/mcp-app.html +4301 -548
  116. package/dist/canvas/mermaid-entry.js +338 -338
  117. package/dist/canvas/surface-theme.css +6 -6
  118. package/dist/json-render/index.css +1 -1
  119. package/dist/json-render/index.js +49 -49
  120. package/dist/types/client/canvas/BarHint.d.ts +5 -3
  121. package/dist/types/client/canvas/BoardMoveDialog.d.ts +2 -0
  122. package/dist/types/client/canvas/CanvasNode.d.ts +0 -11
  123. package/dist/types/client/canvas/EdgeEditor.d.ts +19 -0
  124. package/dist/types/client/canvas/EdgeLayer.d.ts +1 -2
  125. package/dist/types/client/canvas/GroupNavigation.d.ts +2 -0
  126. package/dist/types/client/canvas/TextPrompt.d.ts +4 -0
  127. package/dist/types/client/canvas/auto-fit.d.ts +4 -5
  128. package/dist/types/client/mermaid-entry.d.ts +1 -2
  129. package/dist/types/client/mermaid-render.d.ts +1 -0
  130. package/dist/types/client/nodes/BoardNode.d.ts +1 -1
  131. package/dist/types/client/nodes/ExtAppFrame.d.ts +7 -90
  132. package/dist/types/client/nodes/McpAppNode.d.ts +1 -25
  133. package/dist/types/client/nodes/MermaidNode.d.ts +1 -8
  134. package/dist/types/client/nodes/PromptNode.d.ts +1 -0
  135. package/dist/types/client/nodes/ViewerFrame.d.ts +29 -0
  136. package/dist/types/client/nodes/ViewerHost.d.ts +6 -0
  137. package/dist/types/client/nodes/WorkCard.d.ts +7 -0
  138. package/dist/types/client/nodes/iframe-document-url.d.ts +3 -9
  139. package/dist/types/client/nodes/primitive-copy.d.ts +5 -0
  140. package/dist/types/client/nodes/use-ax-surface-bridge.d.ts +1 -0
  141. package/dist/types/client/nodes/use-iframe-content-height.d.ts +1 -1
  142. package/dist/types/client/nodes/use-surface-frame.d.ts +4 -6
  143. package/dist/types/client/nodes/viewer-runtime-state.d.ts +2 -1
  144. package/dist/types/client/state/canvas-store.d.ts +18 -1
  145. package/dist/types/client/state/human-store.d.ts +2 -0
  146. package/dist/types/client/state/intent-bridge.d.ts +5 -2
  147. package/dist/types/client/state/presentation.d.ts +17 -6
  148. package/dist/types/client/state/relation-store.d.ts +11 -0
  149. package/dist/types/client/types.d.ts +1 -1
  150. package/dist/types/json-render/catalog.d.ts +2 -2
  151. package/dist/types/json-render/server.d.ts +2 -1
  152. package/dist/types/server/agent-presence.d.ts +1 -0
  153. package/dist/types/server/ax-interaction.d.ts +1 -0
  154. package/dist/types/server/ax-state-manager.d.ts +10 -2
  155. package/dist/types/server/board-local.d.ts +4 -0
  156. package/dist/types/server/board-move.d.ts +38 -0
  157. package/dist/types/server/canvas-db.d.ts +12 -2
  158. package/dist/types/server/canvas-operations.d.ts +5 -6
  159. package/dist/types/server/canvas-provenance.d.ts +1 -1
  160. package/dist/types/server/canvas-serialization.d.ts +1 -0
  161. package/dist/types/server/canvas-state.d.ts +86 -20
  162. package/dist/types/server/card-relocation.d.ts +6 -0
  163. package/dist/types/server/context-reads.d.ts +3 -1
  164. package/dist/types/server/human-presence.d.ts +1 -1
  165. package/dist/types/server/index.d.ts +26 -10
  166. package/dist/types/server/intent-registry.d.ts +8 -4
  167. package/dist/types/server/knowledge-lifecycle.d.ts +4 -2
  168. package/dist/types/server/mutation-history.d.ts +7 -5
  169. package/dist/types/server/operations/ops/boards.d.ts +0 -1
  170. package/dist/types/server/operations/registry.d.ts +2 -0
  171. package/dist/types/server/tour-control.d.ts +13 -3
  172. package/dist/types/server/trace-manager.d.ts +1 -0
  173. package/dist/types/shared/ax-kinds.d.ts +6 -0
  174. package/dist/types/shared/ax-surface-protocol.d.ts +8 -9
  175. package/dist/types/shared/human-presence.d.ts +1 -0
  176. package/dist/types/shared/lifecycle-status.d.ts +2 -0
  177. package/dist/types/shared/tour.d.ts +8 -0
  178. package/docs/RELEASE.md +21 -14
  179. package/docs/agent-plugin.md +16 -2
  180. package/docs/amp-plugin.md +271 -0
  181. package/docs/cli.md +42 -3
  182. package/docs/design/Chrome.dc.html +32 -6
  183. package/docs/design/GuestName.dc.html +50 -0
  184. package/docs/design/PluginLogo.svg +7 -0
  185. package/docs/design/Types1.dc.html +3 -2
  186. package/docs/design/Types2.dc.html +1 -1
  187. package/docs/design/Types3.dc.html +1 -1
  188. package/docs/design/WorkCards.dc.html +39 -0
  189. package/docs/design/Zoom.dc.html +37 -60
  190. package/docs/design/canvas.json +17 -1
  191. package/docs/design/plugin-logo.png +0 -0
  192. package/docs/design.md +280 -12
  193. package/docs/evals/agents-md-sections.md +38 -0
  194. package/docs/http-api.md +179 -11
  195. package/docs/mcp.md +69 -9
  196. package/docs/node-types.md +109 -4
  197. package/docs/plans/plan-009-tech-debt-backlog.md +3 -3
  198. package/docs/plans/plan-019-post-0.9-roadmap.md +327 -31
  199. package/docs/plans/plan-020-wave-5-work-planning.md +553 -0
  200. package/docs/product-vision-2026-09.md +42 -17
  201. package/docs/sdk.md +18 -0
  202. package/package.json +7 -4
  203. package/plugins/pmx-canvas/assets/preview.png +0 -0
  204. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +3 -1
  205. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
  206. package/plugins/pmx-canvas/plugin.json +2 -2
  207. package/plugins/pmx-canvas/runtime.json +1 -1
  208. package/plugins/pmx-canvas/tools.json +688 -128
  209. package/skills/data-analysis/SKILL.md +13 -26
  210. package/skills/frontend-design/LICENSE.txt +177 -0
  211. package/skills/frontend-design/SKILL.md +3 -0
  212. package/skills/pmx-canvas/SKILL.md +232 -849
  213. package/skills/pmx-canvas/evals/evals.json +26 -3
  214. package/skills/pmx-canvas/references/full-reference.md +89 -24
  215. package/skills/pmx-canvas/references/html-primitives.md +7 -0
  216. package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
  217. package/skills/pmx-canvas/references/tours-and-recording.md +29 -2
  218. package/skills/pmx-canvas/references/workbench-workflows.md +900 -0
  219. package/skills/pmx-canvas-testing/SKILL.md +7 -5
  220. package/skills/published-consumer-e2e/SKILL.md +25 -8
  221. package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +51 -77
  222. package/skills/web-artifacts-builder/LICENSE.txt +202 -0
  223. package/skills/web-artifacts-builder/SKILL.md +6 -0
  224. package/skills/web-artifacts-builder/scripts/init-artifact.sh +2 -2
  225. package/src/cli/commands/apps.ts +1 -0
  226. package/src/cli/commands/boards.ts +30 -0
  227. package/src/client/App.tsx +20 -4
  228. package/src/client/canvas/AttentionHistory.tsx +10 -2
  229. package/src/client/canvas/BarHint.tsx +6 -3
  230. package/src/client/canvas/BoardMoveDialog.tsx +225 -0
  231. package/src/client/canvas/CanvasNode.tsx +79 -49
  232. package/src/client/canvas/CanvasViewport.tsx +42 -14
  233. package/src/client/canvas/ContextMenu.tsx +97 -15
  234. package/src/client/canvas/EdgeEditor.tsx +149 -0
  235. package/src/client/canvas/EdgeLayer.tsx +441 -174
  236. package/src/client/canvas/ExpandedNodeOverlay.tsx +5 -2
  237. package/src/client/canvas/GroupNavigation.tsx +85 -0
  238. package/src/client/canvas/Presentation.tsx +53 -3
  239. package/src/client/canvas/RelationsPanel.tsx +9 -0
  240. package/src/client/canvas/SelectionBar.tsx +21 -0
  241. package/src/client/canvas/SessionPanel.tsx +35 -1
  242. package/src/client/canvas/TextPrompt.tsx +18 -1
  243. package/src/client/canvas/TopBar.tsx +54 -9
  244. package/src/client/canvas/auto-fit.ts +9 -11
  245. package/src/client/canvas/canvas-area.ts +2 -2
  246. package/src/client/canvas/use-focus-trap.ts +6 -1
  247. package/src/client/mermaid-entry.ts +6 -20
  248. package/src/client/mermaid-render.ts +39 -0
  249. package/src/client/nodes/AxStepControls.tsx +45 -69
  250. package/src/client/nodes/BoardNode.tsx +65 -9
  251. package/src/client/nodes/ContextNode.tsx +88 -396
  252. package/src/client/nodes/ExtAppFrame.tsx +302 -1465
  253. package/src/client/nodes/FileNode.tsx +92 -81
  254. package/src/client/nodes/HtmlNode.tsx +8 -36
  255. package/src/client/nodes/LedgerNode.tsx +31 -17
  256. package/src/client/nodes/MarkdownNode.tsx +14 -24
  257. package/src/client/nodes/McpAppNode.tsx +48 -154
  258. package/src/client/nodes/MermaidNode.tsx +80 -69
  259. package/src/client/nodes/PromptNode.tsx +44 -17
  260. package/src/client/nodes/ResponseNode.tsx +8 -6
  261. package/src/client/nodes/StatusNode.tsx +34 -7
  262. package/src/client/nodes/StatusSummary.tsx +16 -3
  263. package/src/client/nodes/TraceNode.tsx +8 -8
  264. package/src/client/nodes/ViewerFrame.tsx +273 -0
  265. package/src/client/nodes/ViewerHost.tsx +41 -0
  266. package/src/client/nodes/WebpageNode.tsx +22 -24
  267. package/src/client/nodes/WorkCard.tsx +175 -0
  268. package/src/client/nodes/iframe-document-url.ts +20 -27
  269. package/src/client/nodes/primitive-copy.ts +97 -0
  270. package/src/client/nodes/use-ax-surface-bridge.ts +18 -14
  271. package/src/client/nodes/use-iframe-content-height.ts +34 -10
  272. package/src/client/nodes/use-surface-frame.ts +22 -11
  273. package/src/client/nodes/viewer-runtime-state.ts +41 -35
  274. package/src/client/state/attention-bridge.ts +5 -0
  275. package/src/client/state/attention-store.ts +1 -0
  276. package/src/client/state/canvas-store.ts +202 -26
  277. package/src/client/state/human-store.ts +22 -2
  278. package/src/client/state/intent-bridge.ts +20 -5
  279. package/src/client/state/presentation.ts +135 -15
  280. package/src/client/state/relation-store.ts +127 -1
  281. package/src/client/state/sse-bridge.ts +18 -19
  282. package/src/client/theme/global.css +483 -230
  283. package/src/client/theme/surface-theme.css +6 -6
  284. package/src/client/types.ts +1 -0
  285. package/src/json-render/charts/tufte-components.tsx +44 -2
  286. package/src/json-render/renderer/index.css +62 -2
  287. package/src/json-render/renderer/index.tsx +31 -7
  288. package/src/json-render/server.ts +3 -2
  289. package/src/mcp/server.ts +13 -3
  290. package/src/server/agent-presence.ts +43 -23
  291. package/src/server/ax-flow-loop.ts +6 -0
  292. package/src/server/ax-gate-ttl.ts +8 -1
  293. package/src/server/ax-interaction.ts +16 -10
  294. package/src/server/ax-state-manager.ts +17 -4
  295. package/src/server/ax-wait.ts +20 -6
  296. package/src/server/board-export.ts +54 -30
  297. package/src/server/board-local.ts +20 -0
  298. package/src/server/board-move.ts +297 -0
  299. package/src/server/canvas-db.ts +249 -158
  300. package/src/server/canvas-geometry.ts +1 -0
  301. package/src/server/canvas-operations.ts +139 -109
  302. package/src/server/canvas-schema.ts +21 -0
  303. package/src/server/canvas-serialization.ts +2 -0
  304. package/src/server/canvas-state.ts +797 -159
  305. package/src/server/card-relocation.ts +53 -0
  306. package/src/server/code-graph.ts +4 -3
  307. package/src/server/context-reads.ts +83 -55
  308. package/src/server/demo-state.json +140 -114
  309. package/src/server/file-watcher.ts +30 -10
  310. package/src/server/html-primitives.ts +3 -9
  311. package/src/server/html-surface.ts +8 -0
  312. package/src/server/human-presence.ts +18 -5
  313. package/src/server/index.ts +54 -24
  314. package/src/server/intent-registry.ts +43 -5
  315. package/src/server/knowledge-lifecycle.ts +32 -9
  316. package/src/server/lifecycle-status.ts +29 -1
  317. package/src/server/mcp-app-runtime.ts +26 -7
  318. package/src/server/mutation-history.ts +37 -8
  319. package/src/server/operations/composites.ts +6 -3
  320. package/src/server/operations/mcp-contracts.ts +32 -2
  321. package/src/server/operations/mcp.ts +36 -9
  322. package/src/server/operations/ops/annotation.ts +22 -1
  323. package/src/server/operations/ops/ax-await.ts +1 -0
  324. package/src/server/operations/ops/ax-timeline.ts +28 -2
  325. package/src/server/operations/ops/batch.ts +25 -11
  326. package/src/server/operations/ops/boards.ts +45 -6
  327. package/src/server/operations/ops/nodes.ts +70 -0
  328. package/src/server/operations/ops/query.ts +32 -3
  329. package/src/server/operations/ops/snapshots.ts +1 -0
  330. package/src/server/operations/ops/viewport.ts +11 -9
  331. package/src/server/operations/registry.ts +49 -4
  332. package/src/server/server.ts +69 -75
  333. package/src/server/tour-control.ts +97 -12
  334. package/src/server/trace-manager.ts +4 -0
  335. package/src/server/web-artifacts/scripts/init-artifact.sh +2 -2
  336. package/src/shared/agent-context.ts +7 -1
  337. package/src/shared/auto-arrange.ts +5 -4
  338. package/src/shared/ax-kinds.ts +13 -0
  339. package/src/shared/ax-surface-protocol.ts +20 -9
  340. package/src/shared/content-height-reporter.ts +4 -3
  341. package/src/shared/human-presence.ts +1 -0
  342. package/src/shared/lifecycle-status.ts +2 -0
  343. package/src/shared/tour.ts +8 -0
package/docs/http-api.md CHANGED
@@ -3,6 +3,26 @@
3
3
  REST endpoints for all canvas operations + an SSE event stream. Works from
4
4
  any language. Default base URL: `http://localhost:4313`.
5
5
 
6
+ ## Board-targeted operations
7
+
8
+ Registry-backed routes accept `targetBoardId` in the JSON body, or in query parameters
9
+ for GET/DELETE. It must name an existing board. Board-bound reads, writes, batches and waits
10
+ execute on that board without opening it, including across awaits and concurrent navigation.
11
+ Omitting it retains the visible-board behavior. `agentId` identifies the writer for attribution
12
+ and scope fences; it is not an authentication credential.
13
+
14
+ Nested operations inherit the target and writer and reject conflicting overrides. Explicit
15
+ `board`, `expectedBoardId` and `destinationBoardId` must agree with the target. Board metadata
16
+ updates must name that board; a move-selection source must also agree. Deletion or
17
+ workspace replacement invalidates pending work, never redirects it to another board.
18
+
19
+ Board opening/deletion, backup restore and WebView automation refuse a target because they control the
20
+ shared view/workspace. Catalog operations, board creation/pins, settings and knowledge categories
21
+ retain their workspace scope and existing authority checks. AX timeline, evidence and steering
22
+ are workspace-wide; `delivery/pending` uses the consumer's addressed inbox and the target board's
23
+ `pendingActivity`. This is operation routing, not board-level access control. The SSE/poll stream
24
+ still projects the human's visible board, not an individual caller's target.
25
+
6
26
  ## Operation cancellation and progress (0.10)
7
27
 
8
28
  Registry-backed operation routes use the request's abort signal. Disconnecting
@@ -173,6 +193,11 @@ are JSON `[boardId,cardId]`. If the snapshot exceeds a quarter of the budget, `c
173
193
  explicitly requires rechecking cached cards via lifecycle-get before reuse. Empty lists in an
174
194
  incomplete snapshot do not mean healthy or active. Delivered entries still carry qualification.
175
195
 
196
+ `GET /health` includes `bundleStamp`, the `<mtimeMs>-<size>` of `dist/canvas/index.js` that
197
+ tabs compare on (re)connect to decide whether to reload. It is read once per process: when it
198
+ differs from the file on disk, new page loads get the rebuilt files but already-open tabs keep
199
+ their old JavaScript until the server restarts.
200
+
176
201
  `GET /health` includes `contracts: ["pmx-embedded-workbench-v4"]` when the daemon
177
202
  enforces `expectedBoardId` and `expectedContentRevision` preconditions, bulk-write
178
203
  fences/locks using validated geometry and affected automatic parent frames only,
@@ -217,9 +242,15 @@ content auto-height or indirect parent-group reflow after editing a child.
217
242
  update and are included in snapshots/undo. They are board-wide writes under a scope fence.
218
243
  - `POST /api/canvas/tour/go` with `{ "stop": 2 }` or `{ "step": "next" | "previous" }`
219
244
  (plus optional `"present": false`) moves the shared tour cursor →
220
- `{ ok, index, total, stop }`; 400 when the stop does not exist or the board has no stops.
245
+ `{ ok, index, total, stop, catalogEpoch, boardGeneration, sequence }`;
246
+ 400 when the stop does not exist or the board has no stops.
221
247
  Broadcasts `canvas-tour-step`; idle workbenches start presenting unless `present` is false.
248
+ Response and event share the same monotonically increasing `sequence` within the
249
+ server's `catalogEpoch`. Viewers accept only newer steps for their current epoch
250
+ and board generation, so delayed echoes cannot rewind or replay the camera.
222
251
  - `POST /api/canvas/tour/exit` leaves presentation in every viewer (`canvas-tour-exit`).
252
+ Returns `{ ok, catalogEpoch, boardGeneration, sequence }`; the event shares that
253
+ identity and the step sequence, so an old exit cannot dismiss a newer presentation.
223
254
  - `POST /api/canvas/camera/move` with exactly one of `nodeId`, `rect: { x, y, width, height }`
224
255
  or `viewport: { x, y, scale }`, plus optional `duration`, `easing`, `padding`, `pullback`
225
256
  → `{ ok, stop, viewport }`. Broadcasts `canvas-camera-move`; browsers ease to the target in
@@ -229,6 +260,29 @@ content auto-height or indirect parent-group reflow after editing a child.
229
260
  Tour steps and camera moves are navigation: no undo entry, no agent-presence write, no
230
261
  scope-fence check.
231
262
 
263
+ `tour/go` and `tour/exit` accept optional `presenter: { clientId, intent,
264
+ catalogEpoch, boardGeneration }`. The workbench assigns each document a random ID
265
+ and each gesture an increasing positive safe-integer intent. The server rejects
266
+ an old activation or an intent no newer than that document's accepted watermark
267
+ with `{ ok: true, superseded: true }`, without moving the cursor or emitting an event.
268
+ A structurally valid newer command supersedes older ones even if its stop is missing.
269
+ This lets Present proceed while an earlier Exit request is stalled, without that
270
+ late Exit stopping the restart. Resume reads cannot outlive their originating intent.
271
+
272
+ This is latest-intent-wins, not FIFO: reversed relative Next requests can coalesce.
273
+ Different documents, including a reload, remain independent; unfenced agent calls
274
+ and other documents still act in server arrival order. Reload is not cancellation
275
+ of an old document's pending request. A board activation retains at most 4096
276
+ document IDs, refusing new IDs with 409 rather than evicting an ordering record.
277
+ Switching boards resets that limit; requests stamped with the old activation still
278
+ cannot apply. The SDK exposes the same fence through `goToTourStop(step,
279
+ { presenter })` and `exitTour(presenter)`; fenced go may return `{ superseded: true }`.
280
+
281
+ Presentation's Back/Next buttons share this cursor with keyboard and agent navigation.
282
+ They sit beside Exit at the top; hover/focus tooltips show the shortcuts. Node and
283
+ rectangle targets fit below those controls, while explicit viewport targets remain
284
+ exact. Presentation does not change the saved board viewport.
285
+
232
286
  The [tour model and recording walkthrough](cli.md#tour-and-presentation) describes
233
287
  targets, duration, easing, padding, and pullback. Open `/workbench?present=1` to hide
234
288
  chrome; camera movement is local to that viewer. Recording writes local files via
@@ -271,6 +325,43 @@ open either board.
271
325
  Board-list `links` expose qualified `boardId`/`cardId` targets; native card
272
326
  connections include `cardTitle` (null if missing), so footers need not display raw IDs.
273
327
 
328
+ ### Move original cards to a new board
329
+
330
+ `GET /api/canvas/boards/:id` returns `contentRevision` alongside `board` and `open`.
331
+ Use that revision for `POST /api/canvas/boards/move-selection`:
332
+
333
+ ```json
334
+ {"sourceBoardId":"board-source","nodeIds":["card-a","group-b"],"name":"Follow-up","expectedRevision":42,"requestId":"unique-move-request","preview":true}
335
+ ```
336
+
337
+ Preview is read-only and returns `{ok:true, preview}` with expanded `nodeIds`,
338
+ `affectedBoardIds`, `readmeNodeId`, `pinnedNodeIds`, `liveTaskNodeIds`, `attachmentIds`,
339
+ `blockers` and `notices`. Commit with the identical input and `preview:false` (or omitted).
340
+ The source must still be open and at that revision. Commit rechecks permissions and bindings,
341
+ then atomically returns `{ok:true, sourceBoardId, destinationBoardId, portalId, nodeIds,
342
+ affectedBoardIds, replayed}`. It never opens the destination. The SDK exposes the same input
343
+ through `moveSelectionToNewBoard(input)`.
344
+
345
+ Keep the request ID and exact input until success is known. Retrying after an interrupted reply
346
+ or restart returns the original result without another board or portal, even if the source is
347
+ no longer open. Reusing that ID with different input returns 409. A stale revision or unsafe
348
+ binding also returns 409; binding refusals include `blockers`. Resolve the cause and preview
349
+ again before a new attempt.
350
+
351
+ This moves identities, not copies. Groups include descendants; card/edge IDs, relative geometry,
352
+ content revisions, pins, review/read evidence and supported attachments survive. Incoming and
353
+ outgoing relations, wiki bindings and provenance retarget across the library. The destination
354
+ inherits the source folder, theme and relation vocabulary. A selected README moves its designation.
355
+ Live task cards keep their original `workItemBoardId` and `workItemId`; task authority stays put.
356
+ Board-space annotations stay on the source, which receives a portal at the moved selection.
357
+
358
+ The entire move is refused for unsafe runtime producers, external app sessions, task/flow action
359
+ bindings, partial or unfinished imports, source tours targeting moved cards, unresolved local
360
+ viewer references, edit locks or scope fences on affected boards. Nothing is silently dropped.
361
+ Pre-move Undo/Redo is cleared on affected boards. Older snapshots remain readable but neither
362
+ whole-board nor single-card restore may cross the move boundary. Use a post-move snapshot for
363
+ restore; consult older snapshots to recover text manually without recreating the old identities.
364
+
274
365
  ### Markdown previews and saved links
275
366
 
276
367
  `POST /api/render` accepts `{markdown, nodeId?, expectedBoardId?}` and returns `{html}`.
@@ -388,6 +479,14 @@ stored once per file. Live MCP apps become placeholders; local file contents
388
479
  are left out unless `includeFiles` is true. Files are written to `exports/`
389
480
  beside the database. Built-app files are only embedded when they are regular,
390
481
  bounded-size files inside the board's owned `.pmx-canvas/artifacts/` directory.
482
+ Exports retain saved card positions and sizes, heading display, and the board's
483
+ named theme. Charts and dashboards use embedded card layout without repeating
484
+ the shell title; explicit chart heights remain unchanged. Viewer bundles, palette
485
+ CSS and shell fonts are embedded. Read-only exports omit live work controls.
486
+ When running from source, run `bun run build` before exporting. Export requires
487
+ the complete built viewer assets, `surface-theme.css`, and the font files referenced
488
+ by `global.css`; the installed package includes them. A missing asset tree is not
489
+ a supported text-only export mode.
391
490
  The preview manifest lists card links, remote images, and statically visible
392
491
  network destinations in embedded HTML. Imported source-linked Markdown is also
393
492
  excluded unless `includeDerivedText=true`, independently of `includeFiles`;
@@ -462,6 +561,13 @@ opening that board or changing where writes go. This is supported by
462
561
  return 404. Omit `board` to read the active board. Live AX session/delivery reads
463
562
  and fixed MCP resources continue to describe the open board.
464
563
 
564
+ The workbench's `POST /api/canvas/update` accepts `{updates: [{id, position?, size?,
565
+ collapsed?, zIndex?}], expectedBoardId?, recordHistory?}`. `zIndex` is finite and
566
+ persists stacking without changing geometry. The workbench raises a group and its
567
+ children together, keeping the frame below its children. Title-bar gestures save
568
+ stacking and geometry together on release. Layout notifications and reloads retain
569
+ that order.
570
+
465
571
  ```bash
466
572
  # Get canvas state
467
573
  curl http://localhost:4313/api/canvas/state
@@ -514,7 +620,8 @@ term-OR discovery and whole-term ranking remain unchanged. Search never navigate
514
620
  `POST /api/canvas/node` accepts `destinationBoardId` to create on a stored board
515
621
  without opening it or changing the human's active board. `expectedBoardId` remains
516
622
  an **active-board** precondition, not a destination selector; stale values return 409.
517
- Unknown destinations return 404. This is creation-only, not background CRUD.
623
+ Unknown destinations return 404. `destinationBoardId` is creation-only. Use
624
+ `targetBoardId` for board-scoped reads and mutations without shared navigation.
518
625
 
519
626
  Optional `requestId` identifies a logical creation within the workspace database.
520
627
  Use the same id, destination and creation input when retrying; a new intentional
@@ -547,8 +654,24 @@ descendants and affected parent frames. Edges resolve `from`/`fromSearch` and
547
654
  target board, not the owner of the edge. Both endpoints' relation clocks update
548
655
  without changing their content/freshness. A retry returns its original group or
549
656
  edge receipt, preserving later edits and not resurrecting removals. A request ID
550
- cannot be reused for a different creation operation. Inactive group membership
551
- updates/removals and other background CRUD remain unsupported.
657
+ cannot be reused for a different creation operation. `destinationBoardId` selects
658
+ the destination for creation only. Use `targetBoardId` for background updates,
659
+ removals and group membership changes (see [board-targeted operations](#board-targeted-operations)).
660
+
661
+ For authored work cards, create `type: "status"` with
662
+ `data: { workState: "todo", detail: "Plan the change", progress: 25 }`.
663
+ `workState` accepts `todo`, `in-progress`, `blocked`, `done`, `cancelled`;
664
+ `detail` must be a string and progress must be 0–100 or `null` to clear it.
665
+ PATCH merges supplied data fields and validates the resulting work card. Use
666
+ `expectedBoardId` and `expectedContentRevision` to refuse stale edits. These cards
667
+ do not create session work or approvals. See [work cards](node-types.md#work-cards).
668
+
669
+ For a read-only live task presentation, POST `{"type":"status","data":{"workItemId":"<task-id>"}}`
670
+ on the task's active board. Unknown tasks, background creation, supplied display fields,
671
+ reference changes and display-field PATCHes return 400. Title, detail, work state and attribution
672
+ are derived from the existing task; progress is absent. Geometry and pins remain writable.
673
+ Use the existing AX work update endpoint to change the task. Deleting a presentation never
674
+ cancels work. See [live task cards](node-types.md#read-only-live-task-cards).
552
675
 
553
676
  ```bash
554
677
  # Add a node
@@ -590,9 +713,10 @@ against the node's top-level `contentRevision`; stale content returns `409`
590
713
  without changing the node. Conditional edits cannot request webpage refresh.
591
714
  The private MCP App uses these guards to reject stale board actions and note drafts.
592
715
 
593
- Native Markdown Save captures the currently observed revision for each attempt. Newer content
594
- arriving during rendering or network delivery refuses that attempt and keeps the draft; a later
595
- deliberate human Save may replace already-observed work. Queued saves advance their precondition
716
+ Markdown Save uses the draft's original content revision in both standalone and hosted workbenches.
717
+ Newer content refuses the save and keeps the draft, even if the peer update arrived before Save
718
+ was clicked. Retrying a stale draft still refuses; copy it before reloading to reconcile with the
719
+ latest saved text. Queued saves advance their precondition
596
720
  only through successful acknowledgements of their own preceding saves, never through an external
597
721
  revision or an automatic retry after conflict. Acknowledgements from before a restart, restore,
598
722
  or board replacement cannot update canonical content, clear an unsaved draft or advance queued
@@ -613,6 +737,10 @@ hosted MCP App still refuses file-linked edits. This is not a crash-recovery dis
613
737
  Replacing a JSON-render node's `spec` preserves its current title; include `title`
614
738
  to rename it explicitly. A new authored spec still resets the viewer's local drafts.
615
739
 
740
+ Markdown nodes accept `data: { "display": "heading" | "card" }` on creation and
741
+ update. Heading display removes the card frame and uses its title as a section
742
+ label; it does not alter content, position, or pin membership.
743
+
616
744
  Mermaid nodes accept `data: { "fit": "contain" | "none" }` on both
617
745
  `POST /api/canvas/node` and `PATCH /api/canvas/node/:id`. The default, `contain`,
618
746
  shrinks overflowing diagrams without changing aspect ratio; `none` keeps 100%
@@ -709,8 +837,23 @@ curl -X POST http://localhost:4313/api/canvas/annotation \
709
837
  curl -X DELETE http://localhost:4313/api/canvas/annotation/ann-123
710
838
  ```
711
839
 
712
- Agent-readable context reports annotation IDs, targets, and bounds. Use WebView
713
- inspection or screenshots when the drawn shape matters.
840
+ Both agents and humans use this layer. Set `type: "text"`, `text` and a point to
841
+ write a note; omit `type` for freehand ink with at least two points. Coordinates
842
+ are canvas world coordinates, independent of pan and zoom. `width` is stroke
843
+ width for ink (default 4, clamped to 1–24), or font size for text (default 24,
844
+ clamped to 1–96). Text is trimmed to 240 characters and labels to 160.
845
+
846
+ An explicit `id` makes creation retryable while that mark exists: the same
847
+ normalized content returns the existing mark without another Undo entry;
848
+ different content returns 409. After removal or Undo, adding that ID creates
849
+ the mark again. This is not a durable creation receipt. Removal erases the whole
850
+ mark, never the underlying cards; missing IDs return 404. Agent writes obey the
851
+ existing scope fence, including annotation points and removal bounds.
852
+
853
+ Agent-readable context reports annotation IDs, labels, text-note content,
854
+ targets and bounds without raw stroke points. Use screenshots when the drawn
855
+ shape matters. Questions can be answered in the external agent host's composer;
856
+ no PMX session or canvas reply is required, and marks are not approval gates.
714
857
 
715
858
  ## Viewport
716
859
 
@@ -782,8 +925,17 @@ a merged receipt has recorded more than 20 IDs across sessions; unrelated pins s
782
925
 
783
926
  `consumer` is optional. Supply a stable unique value only for a durable,
784
927
  board-scoped cursor; without `consumer` or `since`, each request starts from the
785
- beginning. An explicit `since` never advances a cursor. The brief is a map,
786
- not a dump: an `overview` entry for the open board first, then pins, then each
928
+ beginning. An explicit `since` never advances a cursor. `contextDelivery=false`
929
+ prepares the brief without recording a read or advancing the
930
+ consumer cursor. Adapters must record reception separately; preparation is not
931
+ delivery. `includeSteering=false` excludes steering when the host delivers addressed
932
+ instructions separately. Both flags default to true.
933
+
934
+ Before capturing context, live task cards reconcile their displayed content and
935
+ content revisions with their task owner, including after restart or another writer's
936
+ task update. This does not attribute an edit to the reader or reset consumer cursors.
937
+
938
+ The brief is a map, not a dump: an `overview` entry for the open board first, then pins, then each
787
939
  pin's neighbours (reason `near`: up to five unpinned cards within a 600 canvas-pixel
788
940
  edge-to-edge gap, nearest first, with `near: { pinNodeId, pinTitle }`), then relevant
789
941
  current-board changes and asks, then pinned boards (reason `pinned-board`: the board and its pinned
@@ -896,6 +1048,11 @@ curl "http://localhost:4313/api/canvas/ax/context-status?board=<board-id>"
896
1048
  # For a captured graph/brief, also pass seenLinkRevisions: {"node-1": 12} from
897
1049
  # the delivered linksRevision values, not revisions fetched after delivery.
898
1050
  # Only seenNodeIds with captured entries are acknowledged when this map is supplied.
1051
+ # Optional deliveryId deduplicates receipt retries by source, consumer and board
1052
+ # while the original read is retained (the read log retains 5000 rows).
1053
+ # Repeating it returns the original read, never revisions fetched at retry time.
1054
+ # Receipt identities outlive diagnostic pruning. An expired retry returns HTTP 409
1055
+ # with code=context_receipt_expired; obtain fresh context instead of retrying that ID.
899
1056
  curl -X POST http://localhost:4313/api/canvas/ax/context-reads \
900
1057
  -H "Content-Type: application/json" \
901
1058
  -d '{"channel":"adapter","resource":"copilot:prompt-context","consumer":"copilot","pinnedNodeIds":["node-1"],"deliveredNodeIds":["node-1"],"bytes":2048}'
@@ -1152,6 +1309,10 @@ curl -X POST http://localhost:4313/api/canvas/ax/interaction \
1152
1309
  # browser composer offers a target picker fed by live presence — always claim
1153
1310
  # with your own label or addressed steering never reaches you.
1154
1311
  curl "http://localhost:4313/api/canvas/ax/delivery/pending?consumer=copilot&limit=20"
1312
+ # addressedOnly=true requires consumer and excludes broadcasts BEFORE the limit.
1313
+ # offset skips matching pending messages; restart at zero after an empty page.
1314
+ # Used by hosts that can wake one explicitly addressed thread.
1315
+ curl "http://localhost:4313/api/canvas/ax/delivery/pending?consumer=amp:T-example&addressedOnly=true"
1155
1316
 
1156
1317
  # Long-poll: `waitMs` parks the request until steering for this consumer
1157
1318
  # arrives or the timeout elapses (capped at 120000ms) — the reactive loop for
@@ -1294,6 +1455,8 @@ all consume this stream. Auto-reconnect with exponential backoff.
1294
1455
 
1295
1456
  The direct workbench's `connected` snapshot renews its per-process
1296
1457
  `workbenchToken` (also embedded in boot HTML) over both SSE and polling.
1458
+ It is followed by `boards-changed` before the layout, so later tour commands
1459
+ already have a board identity even when the separate catalog HTTP read is delayed.
1297
1460
  A same-bundle daemon restart does not reload the page or discard an open draft.
1298
1461
  Registered writes and file saves marked as workbench calls with a supplied stale capability
1299
1462
  return 409 until reconnect renews it; they are never silently recorded as agent
@@ -1471,6 +1634,10 @@ curl -X POST http://localhost:4313/api/workbench/webview/screenshot \
1471
1634
  Build a canvas in one shot. Earlier results can be referenced from later
1472
1635
  operations via `$assigned-name.field`.
1473
1636
 
1637
+ Entries retain the caller's transport source for per-agent scope checks. An
1638
+ optional top-level `agentId` supplies the default writer identity for entries
1639
+ without their own `args.agentId`. Batches never inherit a human scope bypass.
1640
+
1474
1641
  ```bash
1475
1642
  curl -X POST http://localhost:4313/api/canvas/batch \
1476
1643
  -H "Content-Type: application/json" \
@@ -1483,6 +1650,7 @@ Supported operations:
1483
1650
  - `graph.add`
1484
1651
  - `edge.add`
1485
1652
  - `group.create`, `group.add`, `group.remove`
1653
+ - `annotation.add`, `annotation.remove`
1486
1654
  - `pin.set`, `pin.add`, `pin.remove`
1487
1655
  - `snapshot.save`
1488
1656
  - `arrange`
package/docs/mcp.md CHANGED
@@ -6,6 +6,25 @@ resources**, and two canvas resource templates, plus per-skill resources at
6
6
  `notifications/resources/updated` to subscribed connections when canvas state changes.
7
7
  This uses MCP SDK v1, not SDK v2.
8
8
 
9
+ ## Board-targeted tools
10
+
11
+ Registry-backed tools and AX interaction/activity tools accept `targetBoardId` and `agentId`.
12
+ Board-bound operations retain that target across awaits and nested batches without changing the
13
+ human's view. See the [routing contract](http-api.md#board-targeted-operations) for conflicts,
14
+ workspace-wide operations and permissions. `canvas_screenshot` rejects a target: its image is
15
+ of the shared WebView, not a background board.
16
+
17
+ The [Amp plugin](amp-plugin.md) supplies the target and authenticated thread identity for bound
18
+ MCP tool calls. It does not intercept MCP resource reads or CLI commands. Use routed query tools
19
+ instead of `canvas://` resources when reading a bound background board.
20
+
21
+ The plugin's `pmx_canvas_delivery` tool is an Amp host tool, not part of this MCP catalog.
22
+ It confirms automatic context reception separately from successful steering actions.
23
+ Context preparation uses `contextDelivery: false`; adapters record receipts through the
24
+ [HTTP context-reads endpoint](http-api.md#ax-context-and-focus), not a public MCP write action.
25
+ `canvas_ax_delivery` with `action: "claim"` supports `addressedOnly` and `offset` so a host pump
26
+ can scan beyond already-received instructions without marking them acted on.
27
+
9
28
  ## Operation help (0.10)
10
29
 
11
30
  Call `canvas_help {}` for the sorted registry names exposed through MCP, then
@@ -146,6 +165,10 @@ tour: { stops: [...] } }` persists an ordered tour; `tour: null` resets it.
146
165
  presents a stop in the workbench, `"tour-exit"` leaves presentation, and
147
166
  `canvas_view { action: "move", nodeId | rect | viewport, duration, easing, padding, pullback }`
148
167
  eases the camera. None of these enter undo history.
168
+ `tour-go` and `tour-exit` also accept the optional document `presenter` fence
169
+ described in [HTTP board tours](http-api.md#board-tours). Superseded requests return
170
+ `{ ok: true, superseded: true }` with no delivery or event. Ordinary agent calls
171
+ omit it and retain shared arrival-order navigation.
149
172
  See the [tour model and CLI walkthrough](cli.md#tour-and-presentation) for stop
150
173
  fields. Recording is a local CLI operation; no remote recording/file-writing
151
174
  tool is added.
@@ -374,7 +397,7 @@ its `action` to the same operation the legacy tool used, so results are identica
374
397
  | `canvas_edge` | `add` · `update` · `remove` | `canvas_add_edge`, `canvas_update_edge`, `canvas_remove_edge` |
375
398
  | `canvas_group` | `create` · `add` · `ungroup` | `canvas_create_group`, `canvas_group_nodes`, `canvas_ungroup` |
376
399
  | `canvas_history` | `undo` · `redo` | `canvas_undo`, `canvas_redo` |
377
- | `canvas_view` | `arrange` · `focus` · `fit` · `clear` · `remove-annotation` · `get-tour` · `set-tour` · `tour-go` · `tour-exit` · `move` | `canvas_arrange`, `canvas_focus_node`, `canvas_fit_view`, `canvas_clear`, `canvas_remove_annotation` |
400
+ | `canvas_view` | `arrange` · `focus` · `fit` · `clear` · `add-annotation` · `remove-annotation` · `get-tour` · `set-tour` · `tour-go` · `tour-exit` · `move` | `canvas_arrange`, `canvas_focus_node`, `canvas_fit_view`, `canvas_clear`, `canvas_remove_annotation` |
378
401
  | `canvas_query` | `context` · `graph` · `search` · `layout` · `validate` | Budgeted context and summary-only connected memory; the others replace `canvas_search`, `canvas_get_layout`, `canvas_validate` |
379
402
  | `canvas_webview` | `status` · `start` · `stop` · `resize` · `evaluate` | `canvas_webview_status`, `canvas_webview_start`, `canvas_webview_stop`, `canvas_resize`, `canvas_evaluate` |
380
403
  | `canvas_app` | `open-mcp-app` · `diagram` · `build-artifact` | `canvas_open_mcp_app`, `canvas_add_diagram`, `canvas_build_web_artifact` |
@@ -384,7 +407,7 @@ its `action` to the same operation the legacy tool used, so results are identica
384
407
  | `canvas_ax_timeline` | `read` · `record-event` · `add-evidence` · `send-steering` · `reads` · `read-status` | `canvas_get_ax_timeline`, `canvas_record_ax_event`, `canvas_add_evidence`, `canvas_send_steering` (`reads` is the context read log; `read-status` is per node: last read, by whom, at which content revision) |
385
408
  | `canvas_ax_delivery` | `claim` (long-polls with `timeoutMs`) · `mark` | `canvas_claim_ax_delivery`, `canvas_mark_ax_delivery` |
386
409
  | `canvas_intent` | `signal` · `update` · `clear` | _(new — Ghost Cursor of Intent; no legacy standalone tool)_ |
387
- | `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 explicit workspace category/folder/shared-preset data |
410
+ | `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 explicit workspace category/folder/shared-preset data |
388
411
  | `canvas_snapshot` | `save` · `list` · `restore` · `restore-node` · `delete` · `gc` · `diff` | `canvas_snapshot` (legacy save tool), `canvas_list_snapshots`, `canvas_restore`, `canvas_delete_snapshot`, `canvas_gc_snapshots`, `canvas_diff` — removed in v0.4.0 after one deprecated minor |
389
412
 
390
413
  For receipt-safe single-card Undo, use `canvas_snapshot { action: "restore-node", id,
@@ -412,6 +435,17 @@ first: `prompt`, `response`, `trace`, and `mcp-app` are not reusable. Creation i
412
435
  transactional and inactive, assigns fresh node/edge IDs, and copies no pins, AX
413
436
  state, or history. Groups and the designated README are opt-in.
414
437
 
438
+ `canvas_board { action: "move-selection", sourceBoardId, nodeIds, name,
439
+ expectedRevision, requestId, preview: true }` instead previews relocation of the
440
+ original cards, expanding group descendants. Get `contentRevision` from `get`
441
+ for `expectedRevision`. Commit the same input without `preview`; retain the
442
+ request ID for safe retries, including after restart. A successful result names
443
+ `destinationBoardId`, `portalId`, moved `nodeIds`, affected boards and `replayed`.
444
+ It does not open the destination. Preview exposes unsafe bindings and the history
445
+ boundary: pre-move Undo/Redo clears; older snapshots remain readable but cannot
446
+ restore across the move. Resolve blockers before committing, never omit cards
447
+ silently. See the [move contract](http-api.md#move-original-cards-to-a-new-board).
448
+
415
449
  The copy records `previousBoardId` for its source. Board `update` accepts
416
450
  `mapPosition: { x, y }` or `null` to persist/reset a Home Map position.
417
451
  `canvas_edge { action: "add", from, to, toBoardId, type }` connects the open
@@ -513,6 +547,21 @@ into `persistFile: true` with both preconditions and top-level `content` to save
513
547
  workspace `.md` file and card together. In this mode, `data` accepts only the `rendered` preview;
514
548
  refused saves change neither. See [the file-save contract](http-api.md#nodes).
515
549
 
550
+ For Markdown nodes, `canvas_node` actions `add` and `update` accept
551
+ `data: { display: "heading" | "card" }`. Heading display uses the existing title
552
+ and content as a frameless section label, without changing pin membership.
553
+
554
+ For authored work cards, use `canvas_node { action: "add", type: "status", title:
555
+ "Verify", data: { workState: "todo", detail: "Run browser checks" } }`. Update the
556
+ same fields with `action: "update"`. State is `todo`, `in-progress`, `blocked`,
557
+ `done` or `cancelled`; optional `progress` is 0–100 or `null` to clear it.
558
+ These are ordinary cards, not sessions or approvals. [Work-card behavior](node-types.md#work-cards).
559
+
560
+ To present an existing task read-only, use `canvas_node { action: "add", type: "status",
561
+ data: { workItemId: "<task-id>" } }` on its active board. Omit title, detail, state and progress:
562
+ the task supplies display fields. Remove the card without cancelling work; update the task
563
+ through `canvas_ax_work`, not `canvas_node`. The reference cannot be patched or converted.
564
+
516
565
  For Mermaid nodes, `canvas_node` actions `add` and `update` accept
517
566
  `data: { fit: "contain" | "none" }`. Contain is the default, shrinking overflow
518
567
  uniformly; none keeps 100% with scrolling. Use Open as site for 100% without
@@ -805,14 +854,25 @@ AX state records where the focus came from. The full workflow lives in
805
854
 
806
855
  ## Annotation Visibility
807
856
 
808
- Human-drawn canvas annotations are rendered as browser SVG ink. MCP resources
809
- keep annotation context compact: agents see annotation counts, bounds, and target
810
- summaries such as the node or empty canvas region that was marked, but not the
811
- raw stroke geometry or visual shape.
857
+ Humans and agents share browser SVG ink and text notes. MCP resources keep context
858
+ compact: annotation IDs, labels, text-note content, bounds and target summaries,
859
+ without raw stroke geometry. These are distinct from AX review annotations.
860
+
861
+ ```json
862
+ {"action":"add-annotation","id":"option-question","type":"text","points":[{"x":160,"y":320}],"text":"Use this option?"}
863
+ ```
812
864
 
813
- Annotations are a browser-visible markup layer. Humans draw with the rail's
814
- Annotate popover (pen / text / eraser — the eraser removes a mark); agents can also
815
- remove a known annotation ID with `canvas_view { action: "remove-annotation", id }`.
865
+ Pass that input to `canvas_view`. Omit `type` for freehand drawing with at least
866
+ two points. Coordinates are canvas world coordinates, not screen pixels.
867
+ `color` defaults to the theme's annotation ink; `width` controls stroke width
868
+ or text size. [Defaults and retry rules](http-api.md#annotations) match HTTP.
869
+ Erase a whole mark with `canvas_view { action: "remove-annotation", id }`.
870
+ Both operations also work in `canvas_batch` as `annotation.add` / `annotation.remove`.
871
+
872
+ Use marks when helpful for questions, pointing and emphasis, not for every task.
873
+ The human can answer in the external agent host's composer; the agent then uses
874
+ its canvas tools to act on the answer. No PMX composer or Session is required,
875
+ and drawing or erasing a mark never resolves an approval.
816
876
 
817
877
  Use WebView automation when an agent needs to actually see annotations as drawn.
818
878
  For example, inspect `.annotation-layer path` with `canvas_webview { action: "evaluate" }`
@@ -1,9 +1,9 @@
1
1
  # Node types
2
2
 
3
- `board` is a native text-only link. Set `data.boardId` to the durable target ID. Its header pin pins the
3
+ `board` is a native link with a lightweight board thumbnail. Set `data.boardId` to the durable target ID. Its header pin pins the
4
4
  linked board into the agent's working set (`canvas_board { action: "pin" }`), not the portal card.
5
5
  Titles resolve from that ID, so renames and folder moves are safe; deleted
6
- targets render explicitly as missing. It is not an iframe or a cross-board card
6
+ targets render explicitly as missing, with **Link to board…** to choose a replacement. It is not an iframe or a cross-board card
7
7
  edge. Static exports lock the card and intentionally do not embed the target
8
8
  title or summary, so exporting this board does not disclose another board.
9
9
 
@@ -17,7 +17,7 @@ see [MCP tools](mcp.md), [HTTP API](http-api.md), and [SDK](sdk.md).
17
17
  | Type | Purpose |
18
18
  |------|---------|
19
19
  | `markdown` | Rich markdown with rendered preview |
20
- | `status` | Compact status indicator (phase, message, elapsed time) |
20
+ | `status` | Authored work card, or a compact phase/message status indicator |
21
21
  | `context` | Context cards, token usage, workspace grounding |
22
22
  | `ledger` | Execution ledger summary |
23
23
  | `trace` | Agent trace pills (tool calls, subagent activity) |
@@ -32,7 +32,7 @@ see [MCP tools](mcp.md), [HTTP API](http-api.md), and [SDK](sdk.md).
32
32
  | `html` | Self-contained HTML/JS in a sandboxed iframe |
33
33
  | `web-artifact` | Bundled React/Tailwind artifact (full single-file app) |
34
34
  | `group` | Spatial container/frame around other nodes |
35
- | `board` | Text-only link to another board, with its README summary and navigation |
35
+ | `board` | Lightweight thumbnail link to another board, with its README summary and navigation |
36
36
 
37
37
  Creation applies per-type frame defaults and readability minimums. When a
38
38
  dimension is defaulted or clamped, HTTP and MCP create responses include a
@@ -48,6 +48,53 @@ response warns about the distinction.
48
48
  Thread node types `prompt` and `response` exist internally for agent
49
49
  conversation rendering and are not created through public APIs.
50
50
 
51
+ ## Work cards
52
+
53
+ Choose **New work card** in the canvas background menu, then **Edit** inside the card.
54
+ Title, work state, detail and optional progress save together. Cancel (or Escape inside
55
+ the form) discards the draft. Editing grows the card locally without resizing its saved
56
+ frame. A refused or stale save keeps the draft; Cancel returns to the latest saved state.
57
+ Drafts, refused saves and pending saves survive opening and closing focus mode in the
58
+ same browser tab. Unsaved drafts are not persisted across a page reload.
59
+
60
+ Agents use ordinary status-node creation/update with `data.workState`: `todo`,
61
+ `in-progress`, `blocked`, `done` or `cancelled`. `data.detail` is a string;
62
+ `data.progress` is an optional number from 0 to 100, or `null` to clear it.
63
+ State and progress are independent: Done does not invent 100%.
64
+
65
+ ```json
66
+ {"type":"status","title":"3. Verify","data":{"workState":"in-progress","detail":"Run the browser checks.","progress":60}}
67
+ ```
68
+
69
+ These are deliberately authored plans, not a task feed. They create no session, task,
70
+ approval or execution. Connect them with existing relations, including intentional loops.
71
+ Status nodes without `workState` or `workItemId` keep their existing phase/tool display.
72
+
73
+ ### Read-only live task cards
74
+
75
+ Choose **Show on board** on a session task row to present that existing task. **Show card**
76
+ focuses its existing presentation. No task or session automatically creates a card.
77
+ Agents use ordinary status creation with `data: { workItemId: "<existing-task-id>" }` on
78
+ the active board. The immutable reference includes `workItemBoardId`, defaulting to the
79
+ active board. Moving the presentation to another board preserves that original task owner;
80
+ an ordinary planning card cannot be converted by patching it.
81
+
82
+ Title, detail, work state and attribution are derived from the task record, not independently
83
+ editable card fields. Do not supply those fields or progress when creating a live card.
84
+ The persisted display cache is refreshed on task changes, Undo and reload. Update the task
85
+ through the existing work-item API, not a card PATCH. Geometry, pins and relations remain editable.
86
+ Ending a session preserves its task cards; removing a card does not cancel the task.
87
+ A missing task displays **Task unavailable**, never an actionable control. Static exports
88
+ label live cards as read-only snapshots. No progress percentage or approval controls are added.
89
+ Selective board copies become independent authored work cards, without a task reference or task attribution.
90
+
91
+ ## Shared node behavior
92
+
93
+ The spatial board and its content scale proportionally at every zoom, without
94
+ switching layouts. Iframe previews mount automatically near the viewport and
95
+ remain mounted to preserve arbitrary app state. There is no lifetime preview cap;
96
+ memory use grows with the viewers visited. Board links and Mermaid render inline.
97
+
51
98
  Full node reads expose server-owned `createdBy`, `lastEditedBy`, and
52
99
  `contentRevision`. Authors distinguish human, agent, system, and unknown;
53
100
  legacy nodes remain unknown. The revision advances on semantic content changes,
@@ -73,6 +120,15 @@ that fits the work — each step adds capability and bundle weight.
73
120
 
74
121
  ## Markdown tasks
75
122
 
123
+ Use **Display as heading** in a Markdown card's context menu for a frameless section
124
+ label. Its title becomes the heading and its content remains below it. **Display as card**
125
+ restores the frame; this does not change the content or context pins. Agents can set
126
+ `data.display` to `"heading"` or `"card"` through ordinary node creation or updates.
127
+ **Set as README** in the card's ⋯ menu designates the board's existing README field;
128
+ the current README instead offers **Remove as README** to clear it. A quiet **README**
129
+ word stays visible in the designated card's header, including heading display.
130
+ **Edit** stays visible below ordinary Markdown. Heading display has no footer.
131
+
76
132
  Tick a task directly on its card, including quoted and nested tasks. A card click changes
77
133
  only that task's `[ ]` or `[x]` marker, preserving the rest of the source exactly.
78
134
  Task-shaped text in code examples and raw HTML checkboxes are not Markdown task controls.
@@ -119,6 +175,9 @@ different type by extension:
119
175
 
120
176
  ## Mermaid nodes
121
177
 
178
+ Diagrams render inline with the canvas palette, rather than in an iframe. Invalid
179
+ source shows a visible error and **Retry**. Native WebKit hosts remain best-effort.
180
+
122
181
  Mermaid diagrams default to `data.fit: "contain"`: when the diagram overflows
123
182
  the available body, it shrinks uniformly until the entire diagram fits. Small
124
183
  diagrams stay at 100%; aspect ratio, labels, and edges are preserved, in both
@@ -216,6 +275,12 @@ with the server's transport, tool name, and arguments.
216
275
 
217
276
  ## json-render nodes
218
277
 
278
+ Embedded dashboards and charts inherit all nine named canvas themes. Their root
279
+ card fills the viewer without an extra panel or shadow. A root title identical to
280
+ the canvas card title is hidden; distinct authored titles and descriptions remain.
281
+ Theme changes preserve viewer-local inputs. A failed replacement keeps the last
282
+ painted document and offers **Retry** instead of repeatedly reloading it.
283
+
219
284
  `json-render` nodes turn structured JSON specs into rendered UI panels
220
285
  (dashboards, tables, forms, cards) without writing HTML. PMX Canvas ships the
221
286
  [`@json-render/*`](https://www.npmjs.com/package/@json-render/core) 0.21.0 runtime
@@ -372,6 +437,10 @@ Fitting waits for local or remote human grabs to end. A growing ungrouped,
372
437
  screen-unpinned card moves downward if needed to leave a 24px gap from neighboring
373
438
  cards, without moving those neighbors. A relocation records one undo step for
374
439
  both size and position; height-only adjustments do not add undo entries.
440
+ Repeated measurements from the same document do not reverse Undo or a smaller
441
+ height set by another writer. Changed content dimensions, width or chrome can
442
+ fit again. Replacing or reopening the viewer starts a fresh measurement, so this
443
+ suppression does not survive reload, collapse/reopen or a board switch.
375
444
  Grouped or screen-pinned cards retain their positions. Collapsed cards and cards
376
445
  marked `strictSize` or `userResized` are not automatically resized. Hosted MCP
377
446
  apps and webpage viewers do not use this authored-content fitting behavior.
@@ -380,6 +449,22 @@ Read the settled node geometry after mounting rather than treating requested
380
449
  dimensions as final. Prefer targeted node reads or the CLI's projected layout
381
450
  fields over fetching full content merely to check spacing.
382
451
 
452
+ ### Move original cards between boards
453
+
454
+ Use **Move to new board** from the selection bar or a group's **⋯** menu. Name the
455
+ destination, preview the expanded selection and its pins/README/history effects, then
456
+ choose **Move and open**. Groups include all descendants. The source receives a working
457
+ portal; the destination contains the same card identities, not copies. A late reply never
458
+ overrides a newer board choice. If the reply is interrupted, **Retry move** reuses the same
459
+ request without creating a duplicate destination.
460
+
461
+ Save or cancel local drafts first. Runtime sessions, streams, authority-bearing controls,
462
+ partial imports and unsupported cross-board references can refuse the whole move with a
463
+ reason. Read-only live task cards keep their original owner; moving never starts or cancels
464
+ a task. Board-space annotations stay on the source. Pre-move Undo/Redo clears on affected
465
+ boards; older snapshots remain inspectable, but cannot restore across that boundary.
466
+ See the [move contract](http-api.md#move-original-cards-to-a-new-board) for agent access.
467
+
383
468
  ## HTML nodes
384
469
 
385
470
  `html` nodes render a normal self-contained HTML/JS document in a sandboxed iframe.
@@ -431,6 +516,14 @@ component gallery, interaction prototype, flowchart, SVG illustration set,
431
516
  presentation, explainer, status report, incident report, triage board, config
432
517
  editor, or prompt tuner.
433
518
 
519
+ The card's ⋯ menu offers **Copy JSON** for primitives with JSON export (all except
520
+ the custom `presentation` template). It copies the mounted document's current
521
+ state, including interactive edits, rather than the original server data.
522
+ Open the viewer first; unavailable/reloading content or denied clipboard access
523
+ shows a failure message. Copy prompt and the shared inner-header copy buttons are
524
+ removed. Primitive-specific actions such as Copy diff and Copy SVG remain.
525
+ Ordinary HTML nodes do not receive this menu item.
526
+
434
527
  Omitted fields may use the template's examples. Explicit empty arrays, empty
435
528
  strings, or `null` mean “show nothing”: the field's section, heading, and
436
529
  dependent controls are omitted rather than replaced with sample content.
@@ -535,6 +628,10 @@ as dashed-border frames with a title bar and optional accent color.
535
628
  its children stay as independent nodes (one undo step); `canvas_group { action: "ungroup" }`
536
629
  does exactly the same
537
630
  - Collapsing a group hides children and shows a summary
631
+ - **Open group** in the frame menu, or Enter on the focused frame, drills into its
632
+ original cards. Breadcrumbs and Escape restore the parent camera and selection.
633
+ Outside-link stubs navigate to the actual cards. This view creates no boards or
634
+ copies and does not change context pins or what agents can read.
538
635
  - By default, group creation preserves the children's current positions and
539
636
  expands the frame around them
540
637
  - Pass `childLayout` to auto-pack children (`grid`, `column`, `flow`)
@@ -549,6 +646,14 @@ canvas_group({ action: 'create', title: 'Auth Module', childIds: ['node-1', 'nod
549
646
 
550
647
  All edges support labels, styles (solid/dashed/dotted), and animation.
551
648
 
649
+ Select an edge to edit its kind, label or reason inline, or delete it. Parallel
650
+ links show their pair count. Dependency counts report cyclic clusters and cards
651
+ affected downstream of the selected cards; `loop` and `if-fails` remain inert flow
652
+ illustrations. Qualified dependency/source warnings carry a separate amber mark.
653
+ In a card's Relations panel, **Show lineage** highlights its local dependency and
654
+ derivation component; **Show on canvas** highlights its direct connections. Remote
655
+ targets remain accessible through their named references.
656
+
552
657
  Native edges optionally carry `toBoardId`: `from` belongs to the open source
553
658
  board and `to` identifies a card on that target board. These connections appear
554
659
  in the visible source card footer with readable board/card titles; missing