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
@@ -0,0 +1,53 @@
1
+ import type { Database } from 'bun:sqlite';
2
+
3
+ /** JSON target list parameter; event ranges prevent a reused old ID inheriting the moved card's history. */
4
+ export const CARD_HISTORY_CTE = `WITH RECURSIVE
5
+ targets AS (SELECT json_extract(value, '$.boardId') AS current_board,
6
+ json_extract(value, '$.cardId') AS node_id FROM json_each(?)),
7
+ history(current_board, node_id, board_id, review_after, review_through, read_after, read_through, move_before) AS (
8
+ SELECT current_board, node_id, current_board,
9
+ COALESCE((SELECT MAX(review_through) FROM card_relocations r WHERE (r.from_board = t.current_board OR r.to_board = t.current_board) AND r.node_id = t.node_id), 0),
10
+ 9223372036854775807,
11
+ COALESCE((SELECT MAX(read_through) FROM card_relocations r WHERE (r.from_board = t.current_board OR r.to_board = t.current_board) AND r.node_id = t.node_id), 0),
12
+ 9223372036854775807, 9223372036854775807 FROM targets t
13
+ UNION ALL
14
+ SELECT h.current_board, h.node_id, r.from_board, r.review_after, r.review_through,
15
+ r.read_after, r.read_through, r.sequence
16
+ FROM history h JOIN card_relocations r ON r.to_board = h.board_id AND r.node_id = h.node_id
17
+ AND r.sequence = (SELECT MAX(sequence) FROM card_relocations prior
18
+ WHERE (prior.to_board = h.board_id OR prior.from_board = h.board_id)
19
+ AND prior.node_id = h.node_id AND prior.sequence < h.move_before)
20
+ )`;
21
+
22
+ /** Record locations, not new reads or validations. Called inside the move transaction. */
23
+ export function recordCardRelocation(
24
+ db: Database,
25
+ requestId: string,
26
+ from: string,
27
+ to: string,
28
+ nodeIds: string[],
29
+ ): void {
30
+ const reviewThrough = db
31
+ .query<{ value: number }, []>('SELECT COALESCE(MAX(sequence), 0) AS value FROM review_records')
32
+ .get()!.value;
33
+ const readThrough = db
34
+ .query<{ value: number }, []>('SELECT COALESCE(MAX(seq), 0) AS value FROM context_reads')
35
+ .get()!.value;
36
+ for (const id of nodeIds)
37
+ db.run(
38
+ `
39
+ INSERT INTO card_relocations(request_id, node_id, from_board, to_board, review_after, review_through, read_after, read_through)
40
+ VALUES (?, ?, ?, ?,
41
+ COALESCE((SELECT MAX(review_through) FROM card_relocations WHERE (from_board = ? OR to_board = ?) AND node_id = ?), 0), ?,
42
+ COALESCE((SELECT MAX(read_through) FROM card_relocations WHERE (from_board = ? OR to_board = ?) AND node_id = ?), 0), ?)`,
43
+ [requestId, id, from, to, from, from, id, reviewThrough, from, from, id, readThrough],
44
+ );
45
+ }
46
+
47
+ export function boardMoveBoundary(db: Database, boardId: string): string | null {
48
+ return (
49
+ db
50
+ .query<{ request_id: string }, [string]>('SELECT request_id FROM board_move_boundaries WHERE board_id = ?')
51
+ .get(boardId)?.request_id ?? null
52
+ );
53
+ }
@@ -18,6 +18,7 @@ import { resolve, dirname, basename, extname, relative } from 'node:path';
18
18
  import { existsSync } from 'node:fs';
19
19
  import { canvasState } from './canvas-state.js';
20
20
  import type { CanvasNodeState, CanvasEdge } from './canvas-state.js';
21
+ import { createBoardLocal } from './board-local.js';
21
22
 
22
23
  // ── Types ────────────────────────────────────────────────────────────
23
24
 
@@ -176,7 +177,7 @@ function tryResolveWithExtensions(basePath: string): string | null {
176
177
  const AUTO_EDGE_PREFIX = 'codegraph-';
177
178
 
178
179
  /** Cache of last recomputed edges for buildCodeGraphSummary() to reuse. */
179
- let _lastDiscoveredEdges: CodeGraphEdge[] = [];
180
+ const discovered = createBoardLocal(() => ({ edges: [] as CodeGraphEdge[] }));
180
181
 
181
182
  /**
182
183
  * Get all file nodes currently on the canvas.
@@ -263,7 +264,7 @@ export function recomputeCodeGraph(): CodeGraphEdge[] {
263
264
  }
264
265
  });
265
266
 
266
- _lastDiscoveredEdges = discoveredEdges;
267
+ discovered.current.edges = discoveredEdges;
267
268
  return discoveredEdges;
268
269
  }
269
270
 
@@ -295,7 +296,7 @@ export function buildCodeGraphSummary(): CodeGraphSummary {
295
296
  for (const node of fileNodes) idToPath.set(node.id, node.data.path as string);
296
297
 
297
298
  // Group import specifiers by source node from cached edges
298
- for (const edge of _lastDiscoveredEdges) {
299
+ for (const edge of discovered.current.edges) {
299
300
  const specs = importSpecs.get(edge.fromNodeId);
300
301
  if (specs && !specs.includes(edge.importSpecifier)) {
301
302
  specs.push(edge.importSpecifier);
@@ -6,9 +6,11 @@
6
6
  * recording never notifies (a read must not trigger more reads).
7
7
  */
8
8
  import type { Database } from 'bun:sqlite';
9
- import { randomUUID } from 'node:crypto';
9
+ import { createHash, randomUUID } from 'node:crypto';
10
+ import { CARD_HISTORY_CTE } from './card-relocation.js';
10
11
  import type { MemoryGraph } from '../shared/memory-graph.js';
11
12
  import type { CompiledContextEntry } from './context-brief.js';
13
+ import { OperationError } from './operations/types.js';
12
14
 
13
15
  export const CONTEXT_READ_RETENTION = 5000;
14
16
  const CONTEXT_READ_DEFAULT_LIMIT = 50;
@@ -51,6 +53,8 @@ export interface ContextRead {
51
53
  }
52
54
 
53
55
  export type ContextReadInput = Omit<ContextRead, 'seq' | 'id' | 'at' | 'boardId' | 'readNodes' | 'seenLinks'> & {
56
+ /** Stable adapter receipt identity. Retries record this delivery once per consumer and board. */
57
+ deliveryId?: string;
54
58
  /** Explicit read target, captured before asynchronous formatting/proxy work. */
55
59
  boardId?: string | null;
56
60
  /** Ids of every serialized node in what the reader received; the server keeps those on the board. */
@@ -264,6 +268,7 @@ export function graphReads(
264
268
  }
265
269
 
266
270
  export const CONTEXT_READS_SCHEMA_SQL = `
271
+ CREATE TABLE IF NOT EXISTS context_read_receipts (id TEXT PRIMARY KEY);
267
272
  CREATE TABLE IF NOT EXISTS context_reads (
268
273
  seq INTEGER PRIMARY KEY AUTOINCREMENT,
269
274
  id TEXT NOT NULL UNIQUE,
@@ -289,30 +294,47 @@ export function appendContextReadToDB(
289
294
  readNodes: Record<string, number> = {},
290
295
  seenLinks: Record<string, number> = {},
291
296
  ): ContextRead {
292
- const id = `read-${randomUUID()}`;
293
- const at = new Date().toISOString();
294
- db.run(
295
- 'INSERT INTO context_reads (id, at, channel, resource, source, consumer, agent_id, pinned_node_ids, delivered_node_ids, bytes, board_id, read_nodes, seen_links) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)',
296
- [
297
- id,
298
- at,
299
- input.channel,
300
- input.resource,
301
- input.source,
302
- input.consumer,
303
- input.agentId,
304
- JSON.stringify(input.pinnedNodeIds),
305
- JSON.stringify(input.deliveredNodeIds),
306
- input.bytes,
307
- boardId,
308
- JSON.stringify(readNodes),
309
- JSON.stringify(seenLinks),
310
- ],
311
- );
312
- const seq = Number(db.query<{ seq: number }, []>('SELECT last_insert_rowid() AS seq').get()?.seq ?? 0);
313
- db.run('DELETE FROM context_reads WHERE seq <= ?', [seq - CONTEXT_READ_RETENTION]);
314
- const { readNodeIds: _readNodeIds, seenNodeIds: _seenNodeIds, ...record } = input;
315
- return { ...record, seq, id, at, boardId, readNodes, seenLinks };
297
+ return db.transaction(() => {
298
+ const id = input.deliveryId
299
+ ? `read-${createHash('sha256')
300
+ .update(JSON.stringify([input.source, input.consumer, boardId, input.deliveryId]))
301
+ .digest('hex')}`
302
+ : `read-${randomUUID()}`;
303
+ if (input.deliveryId) {
304
+ const existing = db.query<ContextReadRow, [string]>('SELECT * FROM context_reads WHERE id = ?').get(id);
305
+ if (existing) {
306
+ db.run('INSERT OR IGNORE INTO context_read_receipts VALUES (?)', [id]);
307
+ return rowToContextRead(existing);
308
+ }
309
+ if (db.query('SELECT id FROM context_read_receipts WHERE id = ?').get(id))
310
+ throw new OperationError('Context receipt expired. Obtain fresh context instead of retrying this token.', 409, {
311
+ code: 'context_receipt_expired',
312
+ });
313
+ }
314
+ const at = new Date().toISOString();
315
+ db.run(
316
+ 'INSERT INTO context_reads (id, at, channel, resource, source, consumer, agent_id, pinned_node_ids, delivered_node_ids, bytes, board_id, read_nodes, seen_links) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?) ON CONFLICT(id) DO NOTHING',
317
+ [
318
+ id,
319
+ at,
320
+ input.channel,
321
+ input.resource,
322
+ input.source,
323
+ input.consumer,
324
+ input.agentId,
325
+ JSON.stringify(input.pinnedNodeIds),
326
+ JSON.stringify(input.deliveredNodeIds),
327
+ input.bytes,
328
+ boardId,
329
+ JSON.stringify(readNodes),
330
+ JSON.stringify(seenLinks),
331
+ ],
332
+ );
333
+ const row = db.query<ContextReadRow, [string]>('SELECT * FROM context_reads WHERE id = ?').get(id)!;
334
+ if (input.deliveryId) db.run('INSERT INTO context_read_receipts VALUES (?)', [id]);
335
+ db.run('DELETE FROM context_reads WHERE seq <= ?', [row.seq - CONTEXT_READ_RETENTION]);
336
+ return rowToContextRead(row);
337
+ })();
316
338
  }
317
339
 
318
340
  interface ContextReadRow {
@@ -351,27 +373,43 @@ function rowToContextRead(row: ContextReadRow): ContextRead {
351
373
  };
352
374
  }
353
375
 
376
+ /** Read only the matching card's observation, not a copy of the whole receipt for every card. */
377
+ function loadCardReads(db: Database, boardId: string, field: 'read_nodes' | 'seen_links') {
378
+ const ids = db
379
+ .query<{ id: string }, [string, string, string]>(`
380
+ SELECT id FROM nodes WHERE board_id = ?
381
+ UNION SELECT j.key AS id FROM context_reads r, json_each(r.read_nodes) j WHERE r.board_id = ?
382
+ UNION SELECT j.key AS id FROM context_reads r, json_each(r.seen_links) j WHERE r.board_id = ?
383
+ `)
384
+ .all(boardId, boardId, boardId);
385
+ return db
386
+ .query<{ nodeId: string; revision: number; at: string; who: string }, [string]>(`
387
+ ${CARD_HISTORY_CTE} SELECT h.node_id AS nodeId, j.value AS revision, r.at,
388
+ COALESCE(r.consumer, r.agent_id, r.source) AS who FROM history h JOIN context_reads r
389
+ ON r.board_id = h.board_id AND r.seq > h.read_after AND r.seq <= h.read_through
390
+ JOIN json_each(r.${field}) j ON j.key = h.node_id
391
+ ORDER BY r.seq DESC
392
+ `)
393
+ .all(JSON.stringify(ids.map(({ id }) => ({ boardId, cardId: id }))));
394
+ }
395
+
354
396
  /** Per node on a board, the latest agent read that delivered its content (newest row wins). */
355
397
  export function loadNodeReadStatusFromDB(db: Database, boardId: string): NodeReadStatus[] {
356
- const rows = db
357
- .query<ContextReadRow, [string]>('SELECT * FROM context_reads WHERE board_id = ? ORDER BY seq DESC')
358
- .all(boardId);
359
398
  const status = new Map<string, NodeReadStatus>();
360
- for (const read of rows.map(rowToContextRead)) {
361
- for (const [nodeId, readRevision] of Object.entries(read.readNodes)) {
362
- const known = status.get(nodeId);
363
- if (known) {
364
- known.readCount += 1;
365
- continue;
366
- }
367
- status.set(nodeId, {
368
- nodeId,
369
- lastReadAt: read.at,
370
- lastReadBy: read.consumer ?? read.agentId ?? read.source,
371
- readRevision,
372
- readCount: 1,
373
- });
399
+ for (const read of loadCardReads(db, boardId, 'read_nodes')) {
400
+ const nodeId = read.nodeId;
401
+ const known = status.get(nodeId);
402
+ if (known) {
403
+ known.readCount += 1;
404
+ continue;
374
405
  }
406
+ status.set(nodeId, {
407
+ nodeId,
408
+ lastReadAt: read.at,
409
+ lastReadBy: read.who,
410
+ readRevision: read.revision,
411
+ readCount: 1,
412
+ });
375
413
  }
376
414
  return [...status.values()];
377
415
  }
@@ -391,27 +429,17 @@ export function loadBoardLastReadFromDB(
391
429
 
392
430
  /** Per node on a board, the newest links revision any agent read has carried (connection marks). */
393
431
  export function loadSeenLinksFromDB(db: Database, boardId: string): Record<string, number> {
394
- const rows = db
395
- .query<{ seen_links: string }, [string]>('SELECT seen_links FROM context_reads WHERE board_id = ?')
396
- .all(boardId);
397
432
  const seen: Record<string, number> = {};
398
- for (const row of rows) {
399
- for (const [nodeId, revision] of Object.entries(JSON.parse(row.seen_links) as Record<string, number>)) {
400
- if (revision > (seen[nodeId] ?? -1)) seen[nodeId] = revision;
401
- }
433
+ for (const { nodeId, revision } of loadCardReads(db, boardId, 'seen_links')) {
434
+ if (revision > (seen[nodeId] ?? -1)) seen[nodeId] = revision;
402
435
  }
403
436
  return seen;
404
437
  }
405
438
 
406
439
  /** Every node on a board whose content an agent read at or after `since` (ISO). */
407
440
  export function loadReadNodeIdsSince(db: Database, boardId: string, since: string): string[] {
408
- const rows = db
409
- .query<{ read_nodes: string }, [string, string]>(
410
- 'SELECT read_nodes FROM context_reads WHERE board_id = ? AND at >= ? ORDER BY seq',
411
- )
412
- .all(boardId, since);
413
441
  const ids = new Set<string>();
414
- for (const row of rows) for (const id of Object.keys(JSON.parse(row.read_nodes) as object)) ids.add(id);
442
+ for (const row of loadCardReads(db, boardId, 'read_nodes')) if (row.at >= since) ids.add(row.nodeId);
415
443
  return [...ids];
416
444
  }
417
445