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
@@ -61,15 +61,7 @@ export function normalizeContextCardDisplay(card: ContextCard): ContextCardDispl
61
61
  : card.state === 'invalid'
62
62
  ? 'Invalid'
63
63
  : 'Loaded';
64
- return {
65
- title,
66
- summary,
67
- pathDisplay,
68
- category,
69
- sourceKind,
70
- status,
71
- required: card.required === true,
72
- };
64
+ return { title, summary, pathDisplay, category, sourceKind, status, required: card.required === true };
73
65
  }
74
66
 
75
67
  function asTrimmedString(value: unknown): string {
@@ -85,17 +77,9 @@ function stripHtmlToText(value: string): string {
85
77
 
86
78
  export function normalizeContextNodeFallback(nodeData: Record<string, unknown>): ContextNodeFallbackDisplay | null {
87
79
  const title = asTrimmedString(nodeData.title);
88
- const content = asTrimmedString(nodeData.content);
89
- const rendered = stripHtmlToText(asTrimmedString(nodeData.rendered));
90
- const summary = content || rendered;
80
+ const summary = asTrimmedString(nodeData.content) || stripHtmlToText(asTrimmedString(nodeData.rendered));
91
81
  const path = asTrimmedString(nodeData.path);
92
-
93
- if (!title && !summary && !path) return null;
94
- return {
95
- title: title || 'Context',
96
- summary,
97
- path,
98
- };
82
+ return title || summary || path ? { title: title || 'Context', summary, path } : null;
99
83
  }
100
84
 
101
85
  export function normalizePinnedContextDisplay(node: CanvasNodeState): PinnedContextDisplay {
@@ -106,13 +90,12 @@ export function normalizePinnedContextDisplay(node: CanvasNodeState): PinnedCont
106
90
  asTrimmedString(node.data.description) ||
107
91
  asTrimmedString(node.data.pageTitle) ||
108
92
  '';
109
- const path = asTrimmedString(node.data.path) || asTrimmedString(node.data.url);
110
93
  return {
111
94
  id: node.id,
112
95
  title,
113
96
  summary,
114
97
  kind: TYPE_LABELS[node.type] ?? node.type,
115
- path,
98
+ path: asTrimmedString(node.data.path) || asTrimmedString(node.data.url),
116
99
  };
117
100
  }
118
101
 
@@ -123,13 +106,6 @@ function formatTokens(n: number | null): string {
123
106
  return `${Math.round(n)}`;
124
107
  }
125
108
 
126
- function usageBarColor(utilization: number): string {
127
- if (utilization >= 0.95) return 'var(--c-danger)';
128
- if (utilization >= 0.85) return 'var(--c-warn)';
129
- if (utilization >= 0.7) return 'var(--c-warn)';
130
- return 'var(--c-accent)';
131
- }
132
-
133
109
  export function ContextNode({
134
110
  node,
135
111
  expanded = false,
@@ -141,41 +117,57 @@ export function ContextNode({
141
117
  }) {
142
118
  const cards = (node.data.cards as ContextCard[]) ?? [];
143
119
  const auxTabs = (node.data.auxTabs as Array<{ id: string; url: string; reason?: string }>) ?? [];
144
- const pinnedContext = pinnedNodes.map(normalizePinnedContextDisplay);
145
- const hasPinnedContext = pinnedContext.length > 0;
146
- const currentTokens = typeof node.data.currentTokens === 'number' ? node.data.currentTokens : null;
147
- const tokenLimit = typeof node.data.tokenLimit === 'number' ? node.data.tokenLimit : null;
148
- const utilization = typeof node.data.utilization === 'number' ? node.data.utilization : null;
149
- const messagesLength = typeof node.data.messagesLength === 'number' ? node.data.messagesLength : null;
150
- const percent = utilization !== null ? Math.max(0, Math.min(100, Math.round(utilization * 100))) : null;
151
- const barColor = usageBarColor(utilization ?? 0);
152
- const fallback =
153
- !hasPinnedContext && cards.length === 0 && auxTabs.length === 0 ? normalizeContextNodeFallback(node.data) : null;
154
-
155
- const openCard = async (card: ContextCard): Promise<void> => {
156
- const path = typeof card.path === 'string' ? card.path.trim() : '';
157
- if (!path) return;
158
- await openWorkbenchFile(path);
159
- };
160
-
120
+ const pinned = pinnedNodes.map(normalizePinnedContextDisplay);
121
+ const fallback = !pinned.length && !cards.length && !auxTabs.length ? normalizeContextNodeFallback(node.data) : null;
122
+ const current = typeof node.data.currentTokens === 'number' ? node.data.currentTokens : null;
123
+ const limit = typeof node.data.tokenLimit === 'number' ? node.data.tokenLimit : null;
124
+ const percent =
125
+ typeof node.data.utilization === 'number' ? Math.max(0, Math.min(100, Math.round(node.data.utilization * 100))) : 0;
126
+ const rows = pinned.length
127
+ ? pinned.map((item) => ({
128
+ ...item,
129
+ tags: item.kind,
130
+ state: 'Pinned',
131
+ openPath: item.path.startsWith('/') ? item.path : '',
132
+ }))
133
+ : cards.map((card) => {
134
+ const item = normalizeContextCardDisplay(card);
135
+ return {
136
+ ...item,
137
+ id: card.key ?? item.pathDisplay ?? item.title,
138
+ path: item.pathDisplay,
139
+ openPath: card.path ?? '',
140
+ state: item.status,
141
+ tags: [item.category, item.sourceKind, item.required ? 'Required' : ''].filter(Boolean).join(' · '),
142
+ };
143
+ });
161
144
  return (
162
- <div
163
- style={{
164
- display: 'flex',
165
- flexDirection: 'column',
166
- gap: expanded ? '10px' : '6px',
167
- fontSize: expanded ? '14px' : '12px',
168
- maxWidth: expanded ? '760px' : undefined,
169
- margin: expanded ? '0 auto' : undefined,
170
- width: expanded ? '100%' : undefined,
171
- padding: expanded ? '8px 0' : undefined,
172
- }}
173
- >
174
- {/* AX: focus the agent on this context node */}
175
- <div style={{ display: 'flex', justifyContent: 'flex-end' }}>
145
+ <div class={`context-node${expanded ? ' context-node-expanded' : ''}`}>
146
+ <div class="context-node-toolbar">
147
+ {limit !== null && limit > 0 && (
148
+ <span class="context-usage">
149
+ <span
150
+ class="context-usage-track"
151
+ role="meter"
152
+ aria-label="Token usage"
153
+ aria-valuemin={0}
154
+ aria-valuemax={100}
155
+ aria-valuenow={percent}
156
+ >
157
+ <span
158
+ style={{
159
+ width: `${percent}%`,
160
+ background: percent >= 95 ? 'var(--c-danger)' : percent >= 70 ? 'var(--c-warn)' : 'var(--c-pin)',
161
+ }}
162
+ />
163
+ </span>
164
+ {percent}% · {formatTokens(current)} / {formatTokens(limit)} tokens
165
+ {typeof node.data.messagesLength === 'number' && <> · {node.data.messagesLength} messages</>}
166
+ </span>
167
+ )}
176
168
  <BarHint
177
169
  label="Point the agent at this node"
178
- body="Sets it as the agent's current AX focus, so the agent pulls it into context to work on next — a one-click alternative to pinning."
170
+ body="Sets it as the agent's current AX focus."
179
171
  align="end"
180
172
  fitWithin=".node-content"
181
173
  >
@@ -183,8 +175,8 @@ export function ContextNode({
183
175
  type="button"
184
176
  class="ax-node-action"
185
177
  style={axNodeActionButtonStyle}
186
- onClick={(e) => {
187
- e.stopPropagation();
178
+ onClick={(event) => {
179
+ event.stopPropagation();
188
180
  void runNodeAxInteraction(node, 'ax.focus.set', undefined, 'Focus set');
189
181
  }}
190
182
  >
@@ -192,356 +184,56 @@ export function ContextNode({
192
184
  </button>
193
185
  </BarHint>
194
186
  </div>
195
-
196
- {tokenLimit !== null && tokenLimit > 0 && (
197
- <div style={{ marginBottom: '8px' }}>
198
- <div
199
- style={{
200
- fontSize: '10px',
201
- fontWeight: 600,
202
- color: 'var(--c-muted)',
203
- textTransform: 'uppercase',
204
- letterSpacing: '0.04em',
205
- marginBottom: '6px',
206
- }}
207
- >
208
- Token Usage
209
- </div>
210
- <div
211
- style={{
212
- height: '6px',
213
- background: 'var(--c-surface-hover)',
214
- borderRadius: '3px',
215
- overflow: 'hidden',
216
- marginBottom: '4px',
217
- }}
218
- >
219
- <div
220
- style={{
221
- height: '100%',
222
- width: `${Math.min(100, (utilization ?? 0) * 100)}%`,
223
- background: barColor,
224
- borderRadius: '3px',
225
- transition: 'width 0.3s ease',
226
- }}
227
- />
228
- </div>
229
- <div style={{ fontSize: '11px', color: 'var(--c-muted)' }}>
230
- {percent}% — {formatTokens(currentTokens)} / {formatTokens(tokenLimit)} tokens
231
- {messagesLength !== null && <> · {messagesLength} messages</>}
232
- </div>
187
+ {rows.length > 0 && (
188
+ <div class="context-node-label">
189
+ {pinned.length ? 'Pinned context' : 'Context'} ({rows.length})
233
190
  </div>
234
191
  )}
235
-
236
- {hasPinnedContext && (
237
- <div>
238
- <div
239
- style={{
240
- fontSize: '10px',
241
- fontWeight: 600,
242
- color: 'var(--c-muted)',
243
- textTransform: 'uppercase',
244
- letterSpacing: '0.04em',
245
- marginBottom: '6px',
246
- }}
247
- >
248
- Pinned Context ({pinnedContext.length})
192
+ {rows.map((row) => (
193
+ <div class="context-row" key={row.id}>
194
+ <div class="context-row-title">
195
+ <strong>{row.title}</strong>
196
+ <span class={['Missing', 'Stale', 'Invalid'].includes(row.state) ? 'context-row-warning' : ''}>
197
+ {row.state === 'Loaded' ? '✓ ' : row.state === 'Pinned' ? '⊙ ' : '⚠ '}
198
+ {row.state}
199
+ </span>
249
200
  </div>
250
- {pinnedContext.map((display) => (
251
- <div
252
- key={display.id}
253
- style={{
254
- padding: '6px 8px',
255
- background: 'var(--c-surface-subtle)',
256
- borderRadius: '6px',
257
- marginBottom: '4px',
258
- borderLeft: '2px solid var(--c-accent)',
259
- }}
260
- >
261
- <div style={{ fontWeight: 600, color: 'var(--c-text)', marginBottom: '2px' }}>{display.title}</div>
262
- {display.summary && (
263
- <div
264
- style={{
265
- color: 'var(--c-muted)',
266
- fontSize: '10px',
267
- lineHeight: 1.45,
268
- marginBottom: '4px',
269
- whiteSpace: 'pre-wrap',
270
- }}
271
- >
272
- {display.summary}
273
- </div>
274
- )}
275
- <div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap', marginTop: '4px' }}>
276
- <span
277
- style={{
278
- fontSize: '9px',
279
- padding: '1px 4px',
280
- background: 'var(--c-surface-hover)',
281
- color: 'var(--c-text-soft)',
282
- borderRadius: '3px',
283
- display: 'inline-block',
284
- }}
285
- >
286
- {display.kind}
287
- </span>
288
- </div>
289
- {display.path && (
290
- <div style={{ marginTop: '6px' }}>
291
- <div
292
- style={{
293
- color: 'var(--c-dim)',
294
- fontSize: '10px',
295
- wordBreak: 'break-all',
296
- marginBottom: '6px',
297
- }}
298
- >
299
- {display.path}
300
- </div>
301
- {display.path.startsWith('/') && (
302
- <button
303
- type="button"
304
- onClick={() => void openWorkbenchFile(display.path)}
305
- style={{
306
- padding: '4px 8px',
307
- fontSize: '10px',
308
- background: 'color-mix(in srgb, var(--c-accent) 12%, transparent)',
309
- border: '1px solid color-mix(in srgb, var(--c-accent) 25%, transparent)',
310
- borderRadius: '4px',
311
- color: 'var(--c-text-soft)',
312
- cursor: 'pointer',
313
- }}
314
- >
315
- Open in canvas
316
- </button>
317
- )}
318
- </div>
319
- )}
320
- </div>
321
- ))}
322
- </div>
323
- )}
324
-
325
- {!hasPinnedContext && cards.length > 0 && (
326
- <div>
327
- <div
328
- style={{
329
- fontSize: '10px',
330
- fontWeight: 600,
331
- color: 'var(--c-muted)',
332
- textTransform: 'uppercase',
333
- letterSpacing: '0.04em',
334
- marginBottom: '6px',
335
- }}
336
- >
337
- Context ({cards.length})
338
- </div>
339
- {cards.map((card) => {
340
- const display = normalizeContextCardDisplay(card);
341
- return (
342
- <div
343
- key={card.key ?? display.pathDisplay ?? display.title}
344
- style={{
345
- padding: '6px 8px',
346
- background: 'var(--c-surface-subtle)',
347
- borderRadius: '6px',
348
- marginBottom: '4px',
349
- borderLeft: '2px solid var(--c-accent)',
350
- }}
351
- >
352
- <div style={{ fontWeight: 600, color: 'var(--c-text)', marginBottom: '2px' }}>{display.title}</div>
353
- <div
354
- style={{
355
- color: 'var(--c-muted)',
356
- fontSize: '10px',
357
- lineHeight: 1.45,
358
- marginBottom: '4px',
359
- }}
360
- >
361
- {display.summary}
362
- </div>
363
- {display.pathDisplay && (
364
- <div style={{ color: 'var(--c-dim)', fontSize: '10px', wordBreak: 'break-all' }}>
365
- {display.pathDisplay}
366
- </div>
367
- )}
368
- <div style={{ display: 'flex', gap: '4px', flexWrap: 'wrap', marginTop: '4px' }}>
369
- <span
370
- style={{
371
- fontSize: '9px',
372
- padding: '1px 4px',
373
- background: 'color-mix(in srgb, var(--c-accent) 10%, transparent)',
374
- color: 'var(--c-accent)',
375
- borderRadius: '3px',
376
- display: 'inline-block',
377
- }}
378
- >
379
- {display.status}
380
- </span>
381
- {display.category && (
382
- <span
383
- style={{
384
- fontSize: '9px',
385
- padding: '1px 4px',
386
- background: 'var(--c-surface-hover)',
387
- color: 'var(--c-text-soft)',
388
- borderRadius: '3px',
389
- display: 'inline-block',
390
- }}
391
- >
392
- {display.category}
393
- </span>
394
- )}
395
- <span
396
- style={{
397
- fontSize: '9px',
398
- padding: '1px 4px',
399
- background: 'var(--c-surface-hover)',
400
- color: 'var(--c-text-soft)',
401
- borderRadius: '3px',
402
- display: 'inline-block',
403
- }}
404
- >
405
- {display.sourceKind}
406
- </span>
407
- {display.required && (
408
- <span
409
- style={{
410
- fontSize: '9px',
411
- padding: '1px 4px',
412
- background: 'color-mix(in srgb, var(--c-accent) 12%, transparent)',
413
- color: 'var(--c-accent)',
414
- borderRadius: '3px',
415
- display: 'inline-block',
416
- }}
417
- >
418
- Required
419
- </span>
420
- )}
421
- </div>
422
- {card.path && (
423
- <div style={{ marginTop: '6px' }}>
424
- <button
425
- type="button"
426
- onClick={() => void openCard(card)}
427
- style={{
428
- padding: '4px 8px',
429
- fontSize: '10px',
430
- background: 'color-mix(in srgb, var(--c-accent) 12%, transparent)',
431
- border: '1px solid color-mix(in srgb, var(--c-accent) 25%, transparent)',
432
- borderRadius: '4px',
433
- color: 'var(--c-text-soft)',
434
- cursor: 'pointer',
435
- }}
436
- >
437
- Open in canvas
438
- </button>
439
- </div>
440
- )}
441
- </div>
442
- );
443
- })}
201
+ <div class="context-row-meta">{row.tags}</div>
202
+ {row.summary && <div class="context-row-summary">{row.summary}</div>}
203
+ {row.path && <div class="context-row-meta">{row.path}</div>}
204
+ {row.openPath && (
205
+ <button type="button" class="context-row-open" onClick={() => void openWorkbenchFile(row.openPath)}>
206
+ Open in canvas
207
+ </button>
208
+ )}
444
209
  </div>
445
- )}
446
-
447
- {!hasPinnedContext && auxTabs.length > 0 && (
448
- <div>
449
- <div
450
- style={{
451
- fontSize: '10px',
452
- fontWeight: 600,
453
- color: 'var(--c-muted)',
454
- textTransform: 'uppercase',
455
- letterSpacing: '0.04em',
456
- marginBottom: '6px',
457
- marginTop: cards.length > 0 ? '8px' : 0,
458
- }}
459
- >
460
- References ({auxTabs.length})
461
- </div>
210
+ ))}
211
+ {!pinned.length && auxTabs.length > 0 && (
212
+ <>
213
+ <div class="context-node-label">References ({auxTabs.length})</div>
462
214
  {auxTabs.map((tab) => (
463
- <a
464
- key={tab.id}
465
- href={tab.url}
466
- target="_blank"
467
- rel="noopener noreferrer"
468
- style={{
469
- display: 'block',
470
- padding: '4px 8px',
471
- color: 'var(--c-accent)',
472
- fontSize: '11px',
473
- textDecoration: 'none',
474
- borderRadius: '4px',
475
- marginBottom: '2px',
476
- wordBreak: 'break-all',
477
- }}
478
- >
215
+ <a class="context-row" key={tab.id} href={tab.url} target="_blank" rel="noopener noreferrer">
479
216
  {tab.url}
480
- {tab.reason && (
481
- <span style={{ color: 'var(--c-dim)', fontSize: '10px', marginLeft: '6px' }}>({tab.reason})</span>
482
- )}
217
+ {tab.reason && <span class="context-row-meta"> ({tab.reason})</span>}
483
218
  </a>
484
219
  ))}
485
- </div>
220
+ </>
486
221
  )}
487
-
488
222
  {fallback && (
489
- <div
490
- style={{
491
- padding: '8px 10px',
492
- background: 'var(--c-surface-subtle)',
493
- borderRadius: '6px',
494
- borderLeft: '2px solid var(--c-accent)',
495
- }}
496
- >
497
- <div style={{ fontWeight: 600, color: 'var(--c-text)', marginBottom: '4px' }}>{fallback.title}</div>
498
- {fallback.summary && (
499
- <div
500
- style={{
501
- color: 'var(--c-text-soft)',
502
- fontSize: '11px',
503
- lineHeight: 1.5,
504
- whiteSpace: 'pre-wrap',
505
- }}
506
- >
507
- {fallback.summary}
508
- </div>
509
- )}
223
+ <div class="context-row">
224
+ <strong>{fallback.title}</strong>
225
+ {fallback.summary && <div class="context-row-summary">{fallback.summary}</div>}
510
226
  {fallback.path && (
511
- <div style={{ marginTop: '6px' }}>
512
- <div
513
- style={{
514
- color: 'var(--c-dim)',
515
- fontSize: '10px',
516
- wordBreak: 'break-all',
517
- marginBottom: '6px',
518
- }}
519
- >
520
- {fallback.path}
521
- </div>
522
- <button
523
- type="button"
524
- onClick={() => void openWorkbenchFile(fallback.path)}
525
- style={{
526
- padding: '4px 8px',
527
- fontSize: '10px',
528
- background: 'color-mix(in srgb, var(--c-accent) 12%, transparent)',
529
- border: '1px solid color-mix(in srgb, var(--c-accent) 25%, transparent)',
530
- borderRadius: '4px',
531
- color: 'var(--c-text-soft)',
532
- cursor: 'pointer',
533
- }}
534
- >
227
+ <>
228
+ <div class="context-row-meta">{fallback.path}</div>
229
+ <button type="button" class="context-row-open" onClick={() => void openWorkbenchFile(fallback.path)}>
535
230
  Open in canvas
536
231
  </button>
537
- </div>
232
+ </>
538
233
  )}
539
234
  </div>
540
235
  )}
541
-
542
- {!hasPinnedContext && !fallback && cards.length === 0 && auxTabs.length === 0 && (
543
- <div style={{ color: 'var(--c-dim)', fontStyle: 'italic' }}>No context loaded</div>
544
- )}
236
+ {!rows.length && !auxTabs.length && !fallback && <div class="context-row-meta">No context loaded</div>}
545
237
  </div>
546
238
  );
547
239
  }