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
@@ -16,12 +16,11 @@ export declare const AX_SURFACE_ACK_SOURCE = "pmx-canvas-ax-ack";
16
16
  export declare const HTML_SURFACE_PUSH_SOURCE = "pmx-canvas-html-node";
17
17
  /** Tab-local JSON viewer state handoff, independent of AX capabilities. */
18
18
  export declare const JSON_VIEWER_STATE_SOURCE = "pmx-canvas-json-state";
19
- /** Ext-app boot beacon: the iframe's scripts executed (WebKit watchdog liveness). */
20
- export declare const EXT_APP_BOOT_BEACON_SOURCE = "pmx-canvas-ext-app-alive";
21
- /**
22
- * Parent→ext-app paint probe (Finding N): the parent asks the app document to
23
- * answer with a double-rAF `paint-tick` beacon. A frame whose rendering
24
- * pipeline is live answers within a frame or two; silence past the timeout is
25
- * the paint-fail signal that drives the recovery ladder.
26
- */
27
- export declare const EXT_APP_PAINT_PROBE_SOURCE = "pmx-canvas-ext-app-paint-probe";
19
+ /** MCP apps share their window channel with an SDK JSON-RPC transport. */
20
+ export declare const MCP_SURFACE_METHOD = "notifications/pmx/surface";
21
+ export declare function surfaceNotification(params: Record<string, unknown>): {
22
+ jsonrpc: "2.0";
23
+ method: string;
24
+ params: Record<string, unknown>;
25
+ };
26
+ export declare function readSurfaceNotification(message: unknown): unknown;
@@ -22,6 +22,7 @@ export interface HumanPresence {
22
22
  export interface HumanPresenceSnapshot {
23
23
  humans: HumanPresence[];
24
24
  }
25
+ export declare const HUMAN_NAME_MAX_LENGTH = 40;
25
26
  /** A tab that stops reporting is gone after this. */
26
27
  export declare const HUMAN_PRESENCE_TTL_MS = 30000;
27
28
  /** A grab the tab stops renewing (crash, tab closed mid-drag) releases after this. */
@@ -19,6 +19,8 @@ export interface LifecycleQualification {
19
19
  contentChangedAt: string | null;
20
20
  /** The revisions a validating reviewer must have inspected, qualified by source relation. */
21
21
  observations: Record<string, number | null>;
22
+ /** Warnings keyed by the same qualified source identity as observations. */
23
+ sourceWarnings?: Record<string, string[]>;
22
24
  sources: SourceQualification[];
23
25
  relevance: 'card-pinned' | 'board-pinned' | 'not-selected';
24
26
  }
@@ -81,6 +81,14 @@ export declare const tourSchema: z.ZodObject<{
81
81
  pullback: z.ZodOptional<z.ZodNumber>;
82
82
  }, z.core.$strip>>;
83
83
  }, z.core.$strip>;
84
+ /** Latest intent from one document, scoped to the server's board activation. */
85
+ export declare const tourPresenterSchema: z.ZodObject<{
86
+ clientId: z.ZodString;
87
+ intent: z.ZodNumber;
88
+ catalogEpoch: z.ZodString;
89
+ boardGeneration: z.ZodNumber;
90
+ }, z.core.$strip>;
91
+ export type TourPresenter = z.infer<typeof tourPresenterSchema>;
84
92
  export type Tour = z.infer<typeof tourSchema>;
85
93
  export type TourStop = z.infer<typeof tourStopSchema>;
86
94
  export type Camera = z.infer<typeof cameraSchema>;
package/docs/RELEASE.md CHANGED
@@ -25,8 +25,11 @@ single source of truth for the release dance — see also
25
25
 
26
26
  ## Pre-flight gates
27
27
 
28
- Run these locally before tagging. They mirror what `publish.yml`
29
- re-runs in CI; a failure here means the publish workflow will also fail.
28
+ Run these locally before tagging. `test.yml` runs the client and browser suites.
29
+ For tag releases, `publish.yml` requires a successful Test run for the exact
30
+ tagged commit, then reruns build, typecheck, unit tests and release smoke.
31
+ Publish does not rerun the client or browser suites. A green remote run does
32
+ not clear an unresolved local failure.
30
33
 
31
34
  ```bash
32
35
  bun install --frozen-lockfile
@@ -35,7 +38,7 @@ bun run build
35
38
  bun test tests/unit # 200+ tests, all green
36
39
  bun run test:web-canvas # Playwright E2E, all green
37
40
  bun run test:e2e-cli # fresh-workspace CLI eval
38
- bun run release:check # bundles + lints
41
+ bun run release:check # build + typecheck + lint + unit + client + browser tests
39
42
  bun run release:smoke # packs + boots from a clean dir
40
43
  bun run pack:dry-run # confirms the tarball shape
41
44
  ```
@@ -179,8 +182,10 @@ git push origin v0.1.6
179
182
  It will:
180
183
 
181
184
  1. Verify the tag matches `package.json` version.
182
- 2. Re-run typecheck / build / unit / E2E / pack.
183
- 3. `npm publish --access public --provenance` using the `NPM_TOKEN`
185
+ 2. Require a successful Test workflow run for the exact tagged commit.
186
+ 3. Re-run build, typecheck, unit tests and release smoke (pack and clean-consumer checks).
187
+ Browser E2E is covered by Test, not rerun by Publish.
188
+ 4. `npm publish --access public --provenance` using the `NPM_TOKEN`
184
189
  secret. Provenance attestations are signed via sigstore and visible
185
190
  on the npm package page.
186
191
 
@@ -203,24 +208,26 @@ Every release since 0.3.0 has been retested against **stale** skill mirrors:
203
208
  consumer workspaces (e.g. `personalclaude`) carry copies of the pmx-canvas
204
209
  skills under `.github/`, `.codex/`, `.claude/`, and `.agents/`, and testers
205
210
  repeatedly had to sync them mid-cycle before results were trustworthy. After
206
- publishing, update the installed package in the consumer workspace and re-sync
207
- its four mirrors from `<global npm root>/pmx-canvas/skills/` so the first test
208
- pass runs against the released skills, not the previous version's guidance.
211
+ publishing, update the installed package in the consumer workspace and check
212
+ its installed skill copies against that package before trusting skill-guided results.
209
213
 
210
- This is now one command in the consumer workspace (added post-0.4.3):
214
+ Start with drift detection, which does not overwrite local changes:
211
215
 
212
216
  ```bash
213
- pmx-canvas skills sync --yes # refreshes every INSTALLED skill copy from the package
214
217
  pmx-canvas skills sync --check # drift detection only (exit 1 when stale)
215
218
  ```
216
219
 
217
220
  It discovers the skill copies already installed in the workspace (whatever
218
- agent layout owns them — no host list is assumed) and compares/replaces
221
+ agent layout owns them — no host list is assumed) and compares
219
222
  **whole trees** — `references/`, `evals/`, fixtures — not `SKILL.md` hashes
220
223
  alone (the 0.3.x–0.4.x cycles repeatedly hit drift where the hash matched but
221
- supporting files were stale). Also re-run
222
- `pmx-canvas copilot install-extension --yes` in repos that use the Copilot
223
- adapter so the panel picks up new open-URL behavior.
224
+ supporting files were stale). Review the differences and preserve local edits.
225
+ Only run `pmx-canvas skills sync --yes` after the owner approves replacing the
226
+ affected copies; it replaces all drifted installed copies of `pmx-canvas`,
227
+ `pmx-canvas-testing` and `pmx-canvas-orchestration`. For a clean release-guidance
228
+ check without that approval, use a disposable consumer workspace.
229
+ Updating the Copilot adapter with `pmx-canvas copilot install-extension --yes`
230
+ likewise requires approval to replace its installed files.
224
231
 
225
232
  ## GitHub release
226
233
 
@@ -1,5 +1,9 @@
1
1
  # PMX Canvas agent plugin
2
2
 
3
+ PMX Canvas is a collaborative canvas where you and your AI agent collect evidence, analyze findings,
4
+ and develop ideas together. Pin material as context for your agent, then ask it to add findings,
5
+ comparisons, or diagrams to the board for you to review, present, and build on.
6
+
3
7
  `plugins/pmx-canvas/` is a self-contained [Agent Plugins 1.0](https://agent-plugins.org/)
4
8
  package. It contains only PMX Canvas: the portable MCP server configuration and a native
5
9
  canvas extension for the GitHub Copilot app. It does not include frame integrations,
@@ -97,6 +101,14 @@ Use the exact version from `runtime.json` and the port from the panel's `status`
97
101
  `PMX_CANVAS_PORT` selects a preferred port; `PMX_CANVAS_URL` targets an existing server.
98
102
  An explicit URL that fails ownership checks is reported rather than silently replaced.
99
103
 
104
+ ## Context and steering delivery
105
+
106
+ The Copilot adapter reads AX context and marks steering delivery with the same `copilot`
107
+ consumer identity. Its next context excludes instructions and pickups already delivered to
108
+ Copilot. A different consumer can still see them pending; that is not a failed Copilot receipt.
109
+ The delivery mark records handoff to the host, not proof that the requested action succeeded.
110
+ This is separate from the Amp plugin's explicit context receipt and action acknowledgment.
111
+
100
112
  ## Package maintenance
101
113
 
102
114
  The plugin's adapter copies are generated from `.github/extensions/pmx-canvas/`:
@@ -116,8 +128,10 @@ The portable root contains `plugin.json`, `mcp.json`, `start-mcp.mjs`, `tools.js
116
128
  `runtime.json`, and license notices for the bundled dependencies. Copilot auto-discovers the native adapter at
117
129
  `com.github.copilot/extensions/pmx-canvas/extension.mjs`.
118
130
 
119
- The marketplace preview is copied from `docs/screenshot.png` to `assets/preview.png` on each
120
- plugin build. The manifest's `extensions.com.github.copilot.logo` points to that packaged PNG.
131
+ The plugin logo is copied from `docs/design/plugin-logo.png` to `assets/preview.png` on each
132
+ plugin build. It is a 512 × 512 export of the PMX Focus Field brand mark, not a canvas screenshot.
133
+ The marketplace requires that image path; the manifest's `extensions.com.github.copilot.logo`
134
+ points to it. The editable source and regeneration command are in [the design guide](design.md#plugin-logo).
121
135
 
122
136
  Publishing a repository package does not register it in a curated marketplace or make it
123
137
  Featured in the Copilot app. Those are separate submission and review steps.
@@ -0,0 +1,271 @@
1
+ # Amp plugin, context and steering
2
+
3
+ The Wave 5 Amp plugin opens the workspace Canvas and binds each Amp thread to an existing board.
4
+ Bound MCP calls read and edit that board while the human views another board or Home. Bound
5
+ threads receive context at turn start and addressed steering can wake an idle thread.
6
+ People can set a self-reported cursor name in Canvas. Optional Jev context ranking and on-demand
7
+ format/review advice are off by default, with separate human consent.
8
+
9
+ ## Install locally
10
+
11
+ Requires Bun >=1.4.4 and Amp with directory-plugin skills. The tested baseline is
12
+ `0.0.1793119929-g574f34` (2026-10-27). Source: `plugins/amp/`; build: `bun run build:plugin`.
13
+ The npm package includes the generated directory at `dist/amp-plugin/pmx-canvas`.
14
+
15
+ Copy that complete directory to your project's `.amp/plugins/pmx-canvas`. For an installed
16
+ package, copy from `node_modules/pmx-canvas/dist/amp-plugin/pmx-canvas`. Do not overwrite an
17
+ existing plugin or locally edited skills: inspect the differences and approve replacement first.
18
+ Reload Amp plugins. Nothing is installed in a personal or workspace-global plugin repository.
19
+
20
+ Amp registers `pmx-canvas:pmx-canvas`, `pmx-canvas:pmx-canvas-testing` and
21
+ `pmx-canvas:pmx-canvas-orchestration`. They are generated copies of the existing PMX skills,
22
+ not separate authoring sources. The main skill bundles MCP and gates its tools until loaded.
23
+ Approve the workspace MCP command through Amp's normal trust flow. A Portal alone does not
24
+ prove native MCP discovery. `canvas_connect_workspace` accepts only this executor's directory.
25
+
26
+ ## Commands and session tool
27
+
28
+ | Command | Effect |
29
+ |---|---|
30
+ | PMX Canvas: Open | Start/reconnect, verify workspace, version and bundle stamp, then open the Amp Portal. |
31
+ | PMX Canvas: Bind | Choose an existing board for this thread, without opening or editing it. |
32
+ | PMX Canvas: Status | Read service identity, binding, whether its board exists, and the shared active board. Does not start a service. |
33
+ | PMX Canvas: Unbind | Remove only this thread's binding. Works while the server is down. |
34
+ | PMX Canvas: Resolve pending steering | Inspect uncertain sends, then explicitly retry or dismiss with human confirmation. |
35
+ | PMX Canvas: Context ranking | Enable Jev after human confirmation for this binding, or turn it off. |
36
+ | PMX Canvas: Jev advice | Separately enable on-demand format/review advice after human confirmation, or turn it off. |
37
+
38
+ Agents use `pmx_canvas_session` with `action: "open" | "bind" | "status" | "unbind"`.
39
+ Bind requires an explicit `boardId`. Invocation thread identity comes from Amp, never model input.
40
+
41
+ Each binding stores workspace, thread, board and stable consumer ID `amp:<thread-id>` in
42
+ `.pmx-canvas/amp-bindings/<thread-id>.json`. Keep this runtime directory out of Git. Separate files
43
+ prevent one thread's update from overwriting another's. Bindings survive plugin reload and
44
+ service restart. Missing boards are reported, never silently rebound. Board navigation and
45
+ moving cards do not change a binding. Unbind is idempotent.
46
+ Each binding also has an incarnation ID. Repeating Bind to the same board keeps it; unbinding
47
+ and binding again invalidates old receipts, even for the same board. Installations created
48
+ before this delivery increment must Unbind, then Bind again.
49
+
50
+ **Bindings route PMX MCP tool calls.** The plugin supplies `targetBoardId` and the authenticated
51
+ `amp:<thread-id>` identity before invocation. Conflicting destinations and nested overrides fail;
52
+ missing/deleted boards never fall back to the visible board. Batches, delayed operations, approval
53
+ waits, undo history and file watchers retain their board ownership across human navigation.
54
+ An active turn retains the binding it started with or first used. If that binding changes or
55
+ disappears, subsequent Canvas calls fail until a new turn starts, including after plugin reload.
56
+
57
+ Open still displays the shared workbench. There is no private per-thread browser. Bound calls
58
+ cannot navigate the shared workbench, restore the workspace backup, or control/capture its shared
59
+ WebView. Board deletion remains an unscoped human library action. Tour/camera commands affect
60
+ only their target board; they reach the browser only when
61
+ that board is visible. CLI calls and MCP resource reads are **not** intercepted by the plugin;
62
+ use routed MCP query tools for bound-board context.
63
+
64
+ A binding is routing, not an access-control or privacy boundary. Board-owned metadata updates
65
+ must name the bound board. Catalog reads, board creation, board pins, workspace settings and
66
+ knowledge categories keep their workspace scope and existing permission checks. AX timeline,
67
+ evidence and addressed steering/delivery are workspace-wide; a steering wait can wake on a message
68
+ sent from another board, while its `pendingActivity` contains only the bound board's work/gates.
69
+ Cross-board relation targets remain explicit.
70
+
71
+ ## Automatic delivery
72
+
73
+ At `agent.start`, the plugin prepares a context map with a 12,000-character JSON budget.
74
+ Preparation records no reads and advances no cursor. The agent returns the supplied token to
75
+ `pmx_canvas_delivery { action: "receive", token }` to confirm reception. This records the
76
+ delivered map and complete links, never full card-content reads. Omitted or clipped changes
77
+ remain beyond the saved cursor. Pull a card with the existing MCP tools to read its full content.
78
+ The plugin keeps its own per-thread, per-board cursor, separate from other readers' cursors.
79
+
80
+ While the plugin executor is awake, it checks persisted bindings every five seconds for steering
81
+ addressed exactly to `amp:<thread-id>`. Broadcasts and messages for other consumers are excluded
82
+ before the queue limit. It appends the instruction through Amp's native thread API: an idle
83
+ thread starts a turn; a busy thread receives queued steering, which Amp can inject into the
84
+ current turn after a tool returns without another `agent.start`. This does not wake a sleeping
85
+ orb, hold a keep-alive lease, or create a scheduler. Scanning resumes when the plugin runs again.
86
+ The pump scans successive pages of 50 messages so unacknowledged instructions cannot hide later
87
+ ones. Instructions over 32,000 characters are not clipped or sent: they appear as `blocked-size`
88
+ in Resolve pending steering, where a human can dismiss them and send a shorter instruction.
89
+
90
+ The agent first receives the steering token, then acts and verifies the result, then calls
91
+ `pmx_canvas_delivery { action: "acknowledge", token }`. Host acceptance, reception and action
92
+ acknowledgment are separate states. An action that failed or was not verified must not be
93
+ acknowledged as successful. The plugin cannot itself certify the agent's work.
94
+
95
+ Each thread has a SQLite transport journal beside its binding. A send is reserved durably before
96
+ calling Amp, preventing duplicate pumps from sending the same instruction. An interrupted or
97
+ timed-out send remains **uncertain**, not automatically retried. Reconciliation checks the last
98
+ 200 transcript messages for the exact user-message payload; finding it confirms acceptance,
99
+ not action completion. Absence does not prove non-delivery. Status exposes pending tokens and
100
+ polling errors; Resolve pending steering requires human confirmation because retrying an
101
+ uncertain send can duplicate an instruction. Dismiss closes delivery without claiming success.
102
+ Journals retain packet identities across reloads; do not delete them to retry a message.
103
+ Receipt identities also survive Canvas's 5,000-row diagnostic retention. A retry whose original
104
+ read has expired is refused rather than counted again; start a new turn for fresh context.
105
+ Stop cancels receipt and acknowledgment requests before a pending discovery can initiate a write.
106
+
107
+ Queued steering with an obsolete binding or completed packet is cancelled at turn start.
108
+ Finish or dismiss pending steering before binding to another board. Unbind stops delivery;
109
+ the human can still dismiss a pending packet after unbinding or deleting its board.
110
+ No exactly-once action-execution guarantee is made.
111
+
112
+ ## Runtime boundaries
113
+
114
+ The plugin reuses exact-version PMX runtime discovery and refuses a foreign workspace. Startup
115
+ prefers the project's installed matching-version package, then the pinned registry runtime if
116
+ the package is absent. An installed version mismatch fails instead of downloading another copy.
117
+ In an orb it probes the actual ports returned by `amp orb services ensure`, including custom
118
+ ports. If those services do not include Canvas, it creates a supervised Canvas service. The
119
+ connection hint in `.pmx-canvas/amp-server.json` is revalidated against workspace health on reuse.
120
+ It never holds an orb keep-alive lease. Outside an orb it uses the existing local PMX daemon
121
+ launcher. `PMX_CANVAS_URL` is an explicit target, not a fallback. An unavailable explicit target
122
+ fails rather than starting a second server. Version mismatch or a missing/unknown bundle stamp
123
+ also fails, including at MCP connection and subsequent requests.
124
+
125
+ **Release limitation:** the published `0.11.0` runtime lacks the required bundle stamp. This
126
+ foundation is verified with the locally packed package, not registry-only startup. A compatible
127
+ release is required before recommending the registry fallback. No publication is part of this
128
+ increment.
129
+
130
+ Amp supplies the Portal URL and access controls. Open does not change sharing or multiplayer.
131
+
132
+ ## Optional context relevance
133
+
134
+ **Context ranking** is off by default. Its human-only confirmation explains that your current
135
+ prompt and optional summaries go to TypeSafe Jev through Amp, using the invoking thread's
136
+ inference billing. Consent applies to the current thread/board binding, survives reload,
137
+ and does not carry to a new binding. Repeating the command disables it. Session Status reports
138
+ `contextRanking: "off" | "jev"`. Enabling cannot opt an already-started preparation into inference.
139
+ Existing prepared packets remain byte-identical on retries. An interrupted ranking attempt is
140
+ durably claimed: another delivery instance or a reload falls back without submitting it again.
141
+
142
+ Context ranking only reorders optional summaries already admitted by the context compiler:
143
+ `near`, `linked` and `folder`. Explicit pins, pinned boards, human instructions, changes,
144
+ title-only discovery entries and lifecycle-qualified pins are not candidates. No new sources
145
+ are fetched. No content is removed, no omission is hidden, and no cursor or receipt is advanced
146
+ by ranking. Existing workspace/binding boundaries still apply; relevance is not authorization.
147
+ The compiler's omitted content cannot be recovered by this ranker. This changes order, not
148
+ content membership or full-content read accounting. It does not reduce the compiled brief's
149
+ size. The ranking report adds delivery metadata, and ranking makes a separate billed inference
150
+ request; no recall, token-saving or cost-saving claim is made.
151
+
152
+ Each fresh preparation uses at most one batch of 20 questions. Inputs are bounded to 2,000
153
+ UTF-16 units of the current prompt, 160 per title and 600 per summary; serialized decision
154
+ state cannot exceed 24,000 units. Later candidates keep their original positions. Scores use
155
+ three levels: unrelated, background, directly useful. Sort descending with stable ties; no
156
+ confidence threshold is treated as proof. The delivery includes the model version, ranked and
157
+ eligible counts, clipping flag, or fallback reason. Missing API, unavailable provider, invalid
158
+ answers, oversized input or a three-second timeout retain deterministic order, with no retry
159
+ or substitute provider. The host API cannot cancel a timed-out inference call; late results
160
+ are ignored and may still be billed. Production enablement is never changed by evaluations.
161
+
162
+ ## On-demand output and review advice
163
+
164
+ `pmx_canvas_advice` operates only on facts the agent supplies. **Jev advice** requires its own
165
+ human confirmation per binding; enabling Context ranking does not enable advice. Status reports
166
+ `jevAdvice: "off" | "jev"`. Consent survives reload, but rebinding disables it. The confirmation
167
+ discloses the supplied text, TypeSafe provider and invoking thread's inference billing.
168
+
169
+ Every request requires `requestId` (1–100 characters), `task` (1–2,000), and `action`:
170
+
171
+ - `representation`: requires `summary` (up to 12,000 characters); optional `explicitFormat`
172
+ (1–80) preserves the user's exact choice without inference, even when advice is off or the
173
+ format is unsupported. Otherwise Jev suggests Markdown, Mermaid, graph, json-render, HTML,
174
+ image or diff. The deterministic fallback is Markdown.
175
+ - `review`: requires 1–20 `changes`, each with a unique `id` (1–160), `title` (up to 160)
176
+ and `summary` (up to 600). Scores order changes by review urgency with stable ties. Every ID
177
+ is retained; the fallback preserves input order. A single change needs no inference.
178
+
179
+ Lengths are UTF-16 units. Serialized decision state is limited to 24,000 units, with one
180
+ three-second inference attempt per logical request. Invalid results, missing providers and
181
+ timeouts return an explicit fallback, never another provider or automatic retry. Reuse the
182
+ same `requestId` and identical input to retry, including across plugin reloads. Reusing an ID
183
+ with different input fails. An interrupted or concurrent retry freezes the durable fallback
184
+ rather than risking another billed call. Completed responses are immutable. Turning advice
185
+ off affects new requests; a retry can still return its previously completed result.
186
+
187
+ Advice creates no output, fetches no source, records no read and verifies no work. The main
188
+ agent must create and verify the actual result. A review priority is not a correctness or
189
+ security verdict. Responses report `mode` (`explicit`, `jev`, or `fallback`), the selected
190
+ format or ordered IDs, and the actual model or fallback reason.
191
+
192
+ ### Reproduce the native decision evaluation
193
+
194
+ In a source checkout, temporarily register `scripts/eval-amp-context.ts` through a root plugin
195
+ file in `.amp/plugins/` that re-exports its default export. Load that file with Amp's plugin
196
+ loader and call its `evaluate_canvas_context` tool. Remove the temporary plugin and reload
197
+ afterward. This development harness is not bundled into the production plugin.
198
+
199
+ The harness sends four fixed fictional pairs in both candidate orders, never workspace data.
200
+ Expected ordering is authored in `tests/fixtures/context-relevance.ts`, independently of model
201
+ scores. It compares against the unchanged compiler order, checks unchanged contents and pins,
202
+ and writes model version, input size and elapsed time to `.amp/in/artifacts/jev-context-*.json`.
203
+ It includes semantic relevance and misleading source instructions. A passing small diagnostic
204
+ set is not evidence of general task improvement or prompt-injection immunity. The decision
205
+ API exposes no billed cost, so the report does not invent one.
206
+
207
+ The same harness exposes `evaluate_canvas_advice`: four fictional representation cases and
208
+ two review pairs in both orders, with expectations in `tests/fixtures/jev-advice.ts`. It compares
209
+ against Markdown and unchanged review order, checks unchanged inputs, and saves
210
+ `.amp/in/artifacts/jev-advice-*.json`. Neither evaluator changes production consent. These
211
+ diagnostics do not establish rendered output quality or replace native human opt-in acceptance.
212
+
213
+ ## Collaboration and names
214
+
215
+ Use Amp's existing thread access, multiplayer and Portal controls to share. Canvas adds no
216
+ account, guest token or permission picker. Amp's [Portal access documentation](https://ampcode.com/docs/orbs/portals#access-and-lifecycle)
217
+ describes the current controls and workspace restrictions. The installed CLI also exposes
218
+ `amp orb portal access`; its presence is not evidence of an external guest completing the flow.
219
+ Sharing a Portal exposes its port, including other boards and APIs available there, not just
220
+ the current board URL. Only share a workspace whose contents are appropriate for the audience.
221
+ Public Portal access does not grant access to the Amp thread or its review tools.
222
+
223
+ Open **Your name** at the end of the Canvas top bar. Enter up to 40 characters and choose
224
+ **Save name**. Other participants see the name on your cursor. Cancel, Escape or blank input
225
+ keeps the existing name. The name is saved in this browser when storage is available and
226
+ survives reload and reconnect. Renaming does not change the visitor's tab ID; two people may
227
+ choose the same name without merging their presence. A name is self-reported, not verified
228
+ identity, attribution to an Amp account, or an access grant. Naming makes no access-control
229
+ request and does not change thread or Portal sharing.
230
+
231
+ This control is available in the HTTP workbench, including an Amp Portal, not an MCP-hosted
232
+ workbench or an agent-view tab. An initial `?name=` still works; saving a name removes that
233
+ parameter so a reload cannot overwrite the saved choice.
234
+
235
+ **Acceptance boundary:** two browsers inside the owning orb can verify Canvas collaboration,
236
+ but Amp routes those Portal requests directly to the service without external authentication.
237
+ That does not verify an outside guest's sign-in, public access, or revocation. Test those
238
+ separately with fictional data and the owner's approved sharing scope.
239
+
240
+ ## Verification
241
+
242
+ `bun test tests/unit/amp-plugin.test.ts` checks bindings and workspace safety through the
243
+ registered session tool. `bun run typecheck` checks against the pinned published Amp types.
244
+ `tests/unit/amp-delivery.test.ts` checks receipt accounting, clipped context, wrong recipients,
245
+ competing pumps, interrupted sends/receipts and restart against real Canvas HTTP and SQLite.
246
+ `tests/unit/boards-api.test.ts` checks concurrent HTTP routing, restart persistence, nested
247
+ identity, waits and refusal paths. `tests/e2e/boards.pw.ts` checks visible-board isolation,
248
+ reconnect and opening the populated target board. These do not substitute for native hooks.
249
+ After `bun run build:plugin`, verify a fresh copied package with `amp plugins list` and
250
+ `amp skill info pmx-canvas:pmx-canvas`, then reload the actual host and test discovery and
251
+ `pmx_canvas_session`. Test native MCP trust separately from an SDK handshake.
252
+
253
+ Native acceptance includes open, bind, reload, status, unbind, a foreign-workspace refusal,
254
+ two independent thread bindings, persisted boards after service restart, and a rendered Portal.
255
+ Actual orb pause/resume and a second live Amp thread must be reported separately from simulated
256
+ thread contexts or process restarts. Do not call the entire Wave 5 integration verified from
257
+ these foundation checks.
258
+ Delivery acceptance also requires an actually idle thread to wake from addressed Canvas steering,
259
+ receive its context, edit the bound board, show the rendered result and acknowledge only afterward.
260
+
261
+ Native acceptance on Amp `0.0.1793405518-gc59f01` verified idle wake, busy delivery into the
262
+ current turn, bound MCP routing through `code_exec`, rendered edits before acknowledgment,
263
+ receipt retries, reload and end-of-turn journal cleanup. Wrong-recipient steering stayed pending.
264
+ Obsolete queued-packet cancellation and sleeping-orb resume were not exercised; startup
265
+ cancellation guards have unit coverage, not native cancellation acceptance.
266
+
267
+ Independent-orb Jev diagnostics on `jev-1.14.0` passed 8/8 context cases against 4/8 unchanged
268
+ order, and two advice runs each passed 8/8 against a 3/8 deterministic baseline. These are small
269
+ fictional diagnostics, not general quality, latency or cost benchmarks. Native disabled advice,
270
+ explicit format, receipt idempotency and reload were exercised. Human-confirmed enablement,
271
+ enabled next-turn ranking and native advice revocation/rebinding remain acceptance checks.
package/docs/cli.md CHANGED
@@ -333,6 +333,24 @@ pmx-canvas batch --file ./canvas-ops.json
333
333
  See [HTTP API → batch](http-api.md#batch-operations) for the operation
334
334
  schema; the same JSON works for the CLI batch file.
335
335
 
336
+ Authored [work cards](node-types.md#work-cards) use structured `data` through batch:
337
+
338
+ ```bash
339
+ pmx-canvas batch --json '[{"op":"node.add","args":{"type":"status","title":"Verify","data":{"workState":"todo","detail":"Run browser checks"}}}]'
340
+ pmx-canvas batch --json '[{"op":"node.update","args":{"id":"<card-id>","data":{"workState":"done","progress":null}}}]'
341
+ ```
342
+
343
+ The ordinary `node add --data` flag is for graph series, not general node data.
344
+
345
+ Present an existing task read-only on its active board:
346
+
347
+ ```bash
348
+ pmx-canvas batch --json '[{"op":"node.add","args":{"type":"status","data":{"workItemId":"<task-id>"}}}]'
349
+ ```
350
+
351
+ Do not send title, detail, work state or progress; these follow the task. Removing the card
352
+ does not cancel work. Update the task through `ax work update`, not a card patch.
353
+
336
354
  ## Web artifacts
337
355
 
338
356
  ```bash
@@ -405,6 +423,8 @@ pmx-canvas board pin <board-id> --reason "Q4 rests on it" # join the agent's wor
405
423
  pmx-canvas board unpin <board-id>
406
424
  pmx-canvas board from <source-id> "Follow-up" --preview
407
425
  pmx-canvas board from <source-id> "Follow-up" --nodes id1,id2 --readme --structure
426
+ pmx-canvas board move-selection <source-id> "Follow-up" --nodes id1,id2 --revision 42 --request move-123 --preview
427
+ pmx-canvas board move-selection <source-id> "Follow-up" --nodes id1,id2 --revision 42 --request move-123
408
428
  ```
409
429
 
410
430
  Commands write to the board open in the workbench. `board open` switches the
@@ -418,6 +438,15 @@ cards are retained automatically. `--readme` carries the designated README. The
418
438
  does not inherit pins, AX state, or mutation history. Its `previousBoardId`
419
439
  records the source board.
420
440
 
441
+ `board move-selection` moves the original cards instead. Read `board get <source-id>`
442
+ for `contentRevision`, pass it as `--revision`, and preview first. Group selections
443
+ include descendants. Keep `--request` and all other inputs unchanged when retrying an
444
+ interrupted commit; a recorded success returns the same destination after restart.
445
+ The operation leaves a portal but does not open the destination. It preserves pins,
446
+ relations and review/read history, and refuses the whole selection if bindings cannot
447
+ move safely. Pre-move Undo/Redo clears; old snapshots remain inspectable but cannot
448
+ restore across the move. See the [move contract](http-api.md#move-original-cards-to-a-new-board).
449
+
421
450
  ## Connected memory
422
451
 
423
452
  ```bash
@@ -643,9 +672,19 @@ reports annotation targets and bounds; it does not describe whether the human
643
672
  drew an arrow, line, circle, or other shape. Inspect `.annotation-layer path` or
644
673
  take a screenshot when the drawn form matters.
645
674
 
646
- Humans draw with the rail's Annotate popover (pen / text) and remove marks with its eraser.
647
- If an agent already knows the annotation ID from context, it can remove it through
648
- MCP with `canvas_view { action: "remove-annotation", id }`.
675
+ Humans and agents share pen, text and whole-mark erasing. CLI agents use the
676
+ existing batch command:
677
+
678
+ ```bash
679
+ pmx-canvas batch --json '[{"op":"annotation.add","args":{"id":"question-b","type":"text","points":[{"x":160,"y":320}],"text":"Use option B?"}}]'
680
+ pmx-canvas batch --json '[{"op":"annotation.remove","args":{"id":"question-b"}}]'
681
+ ```
682
+
683
+ For freehand ink, omit `type` and supply at least two points in canvas world
684
+ coordinates. [Annotation defaults and retry rules](http-api.md#annotations) are
685
+ shared across transports. Layout/context reads include text notes as well as mark
686
+ IDs and bounds. The human can answer in the external agent host's composer;
687
+ neither Sessions nor PMX's composer is required.
649
688
 
650
689
  ## When to reach for the CLI
651
690
 
@@ -13,7 +13,7 @@
13
13
  body{margin:0}
14
14
  </style>
15
15
  </helmet>
16
- <div style="width: 1440px; height: 1000px; box-sizing: border-box; padding: 40px 48px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: grid; grid-template-columns: 500px repeat(2, minmax(0, 1fr)); gap: 40px">
16
+ <div style="width: 1440px; height: 1360px; box-sizing: border-box; padding: 40px 48px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: grid; grid-template-columns: 500px repeat(2, minmax(0, 1fr)); gap: 40px">
17
17
 
18
18
  <section style="display: flex; flex-direction: column; gap: 14px">
19
19
  <div><h2 style="margin: 0; font-size: 15px; font-weight: 600">7 · Tool rail in a 690px-tall window</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">20 buttons need 850px. Settings-type tools move into one menu.</p></div>
@@ -62,7 +62,7 @@ body{margin:0}
62
62
  </section>
63
63
 
64
64
  <section style="display: flex; flex-direction: column; gap: 14px">
65
- <div><h2 style="margin: 0; font-size: 15px; font-weight: 600">8 · Node header</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">Expand and the context pin always show; ⋯ on hover opens the existing node menu (now with Open in new tab), and Set as README stays in the markdown footer.</p></div>
65
+ <div><h2 style="margin: 0; font-size: 15px; font-weight: 600">8 · Node header</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">Expand and the context pin always show; ⋯ on hover or keyboard focus opens the node menu. Set as README lives here, becoming Remove as README on the current README. Edit stays visible below Markdown.</p></div>
66
66
 
67
67
  <span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Today</span>
68
68
  <div style="border-radius: 12px 12px 8px 8px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
@@ -78,7 +78,8 @@ body{margin:0}
78
78
  <div style="border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 1px 2px rgba(0,0,0,0.4), 0 6px 20px rgba(0,0,0,0.24); overflow: hidden">
79
79
  <div style="display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 8px 0 12px; border-bottom: 1px solid #1b2c44">
80
80
  <svg width="16" height="16" viewBox="0 0 24 24" style="color: #8ea3bd; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round"><path d="M6 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zM8 10h8M8 14h5"></path></svg>
81
- <span style="flex: 1; font-size: 12px; font-weight: 600">PMX Canvas — guided tour</span>
81
+ <span style="flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 12px; font-weight: 600">PMX Canvas — guided tour</span>
82
+ <span style="flex-shrink: 0; font-size: 11px; color: #8ea3bd">README</span>
82
83
  <button aria-label="Expand (Enter)" style="width: 22px; height: 22px; border: 0; border-radius: 6px; padding: 0; background: transparent; color: #b9c6d6; display: flex; align-items: center; justify-content: center; flex-shrink: 0"><svg width="13" height="13" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round"><path d="M14 4h6v6M20 4l-7 7M10 20H4v-6M4 20l7-7"></path></svg></button>
83
84
  <button aria-label="Add to context (P)" style="width: 18px; height: 18px; box-sizing: border-box; border: 1.5px solid #6b7d94; border-radius: 999px; padding: 0; background: transparent; color: #b9c6d6; display: flex; align-items: center; justify-content: center; flex-shrink: 0"><svg width="10" height="10" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg></button>
84
85
  <!-- Reserve the hover-action slots: revealing More/Close must not move the pin. -->
@@ -111,7 +112,8 @@ body{margin:0}
111
112
  <div style="height: 236px; display: flex; flex-direction: column; border: 1px solid #1b2c44; border-radius: 10px; overflow: hidden; background: #0f1d31">
112
113
  <div style="flex-shrink: 0; height: 36px; display: flex; align-items: center; padding: 0 12px; border-bottom: 1px solid #1b2c44; font-size: 12px; font-weight: 600">Research index</div>
113
114
  <div style="flex: 1; min-height: 0; display: flex; flex-direction: column">
114
- <div style="flex: 1; min-height: 0; padding: 10px 12px; overflow: auto; font-size: 13px; color: #b9c6d6">Read the source, then follow <a href="#reference-footer" style="color: #e6eef7">the evidence</a>.<div style="margin-top: 20px; font-size: 12px; color: #8ea3bd">Set as README <span style="float: right">Edit</span></div></div>
115
+ <div style="flex: 1; min-height: 0; padding: 10px 12px; overflow: auto; font-size: 13px; color: #b9c6d6">Read the source, then follow <a href="#reference-footer" style="color: #e6eef7">the evidence</a>.</div>
116
+ <div style="flex-shrink: 0; border-top: 1px solid #1b2c44; padding: 6px 36px 6px 8px; text-align: right"><button style="border: 1px solid transparent; border-radius: 6px; padding: 4px 8px; background: transparent; color: #8ea3bd; font: 500 11px 'IBM Plex Sans', sans-serif">Edit</button></div>
115
117
  <div id="reference-footer" role="region" aria-label="Cross-board references" tabindex="0" style="flex-shrink: 0; max-height: min(40%, 132px); overflow: auto; overscroll-behavior: contain">
116
118
  <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Interview notes</div>
117
119
  <div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Findings</div>
@@ -174,11 +176,35 @@ body{margin:0}
174
176
  <span style="font-size: 11px; color: #8ea3bd">Fit and focus keep a lane clear for floating chrome.</span>
175
177
  </div>
176
178
  </div>
179
+
180
+ <div style="display: flex; flex-direction: column; gap: 8px">
181
+ <h2 style="margin: 0; font-size: 15px; font-weight: 600">Present · hover / keyboard focus</h2>
182
+ <p style="margin: 0; font-size: 11px; color: #8ea3bd">2026-10-25: the button describes this tooltip with aria-describedby. In the narrow ⋯ menu, the same text appears in flow below Present so the scrolling menu cannot clip it.</p>
183
+ <div role="tooltip" style="max-width: 240px; padding: 10px 12px; border: 1px solid #2a4566; border-radius: 10px; background: #0f1d31; color: #b9c6d6; font-size: 12px; line-height: 1.35">
184
+ <strong style="color: #e6eef7">Present board</strong>
185
+ <p>A presentation follows either a saved tour or the board’s groups.</p>
186
+ <p>Saved tour: ask your agent to define the stops and their order. Each stop can focus on a card, a group, a rectangular area, or a specific camera position.</p>
187
+ <p style="margin-bottom: 0">No saved tour: every group becomes a stop, ordered top-to-bottom, then left-to-right. It doesn’t automatically visit every card.</p>
188
+ </div>
189
+ </div>
190
+ <div style="display: flex; flex-direction: column; gap: 8px">
191
+ <h2 style="margin: 0; font-size: 15px; font-weight: 600">Presentation · navigation</h2>
192
+ <p style="margin: 0; font-size: 11px; color: #8ea3bd">Owner decision, 2026-10-25: Back and Next sit beside Exit at the top-right. Instructions appear only in hover/focus tooltips, never in a corner panel. End buttons stay focusable but unavailable; their descriptions remain accessible.</p>
193
+ <div style="position: relative; height: 180px; border: 1px solid #1b2c44; border-radius: 10px; background: #081524">
194
+ <div style="position: absolute; top: 16px; right: 16px; display: flex; gap: 8px">
195
+ <button style="padding: 8px 14px; min-height: 38px; border: 1px solid #8ea3bd; border-radius: 8px; background: #0f1d31; color: #e6eef7; font: inherit; font-weight: 600; opacity: .5" aria-disabled="true">Back</button>
196
+ <button style="padding: 8px 14px; min-height: 38px; border: 1px solid #8ea3bd; border-radius: 8px; background: #0f1d31; color: #e6eef7; font: inherit; font-weight: 600">Next</button>
197
+ <button style="padding: 8px 14px; min-height: 38px; border: 1px solid #8ea3bd; border-radius: 8px; background: #0f1d31; color: #e6eef7; font: inherit; font-weight: 600">Exit presentation</button>
198
+ </div>
199
+ <div style="position: absolute; top: 66px; right: 16px; width: 168px; padding: 10px 12px; border: 1px solid #2a4566; border-radius: 10px; background: #0f1d31; box-shadow: 0 14px 36px #0006; font-size: 12px"><strong>Next stop</strong><br><span style="color: #8ea3bd">→ / ↓ / Space</span></div>
200
+ </div>
201
+ <p style="margin: 0; font-size: 11px; color: #8ea3bd">Back: Previous stop, ← / ↑. Next: Next stop, → / ↓ / Space. Exit: Exit presentation, Esc. Fit clears the top controls; exact camera targets and recording remain exact.</p>
202
+ </div>
177
203
  </section>
178
204
 
179
205
  </div>
180
206
  </x-dc>
181
- <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1000}}'>
207
+ <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1360}}'>
182
208
  class Component extends DCLogic {
183
209
  renderVals() {
184
210
  var P = {
@@ -245,7 +271,7 @@ class Component extends DCLogic {
245
271
  optIn('Trace', 'Show execution traces. Turning off keeps existing traces and never starts an agent.', false, false),
246
272
  setting('Send feedback', '', 'Share feedback about PMX Canvas.')
247
273
  ];
248
- var nodeMenu = [m('Focus', ''), m('Rename…', ''), m('Collapse', ''), m('Open in new tab', '', true), msep, m('Delete', '⌫')];
274
+ var nodeMenu = [m('Focus', ''), m('Rename…', ''), m('Collapse', ''), m('Open in new tab', ''), msep, m('Set as README', '', true), msep, m('Delete', '⌫')];
249
275
  var oldIcons = [{ d: P.ctx }, { d: P.ask }, { d: P.open }, { d: P.expand }, { d: P.chevron }, { d: P.close }];
250
276
  return { railToday: railToday, railNew: railNew, settings: settings, nodeMenu: nodeMenu, oldIcons: oldIcons };
251
277
  }