pmx-canvas 0.7.3 → 0.8.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 (235) hide show
  1. package/.github/extensions/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
  2. package/.github/extensions/pmx-canvas/extension.mjs +25 -172
  3. package/.github/extensions/pmx-canvas/mcp-bootstrap.ts +198 -0
  4. package/.github/extensions/pmx-canvas/runtime.d.mts +41 -0
  5. package/.github/extensions/pmx-canvas/runtime.json +3 -0
  6. package/.github/extensions/pmx-canvas/runtime.mjs +194 -0
  7. package/.github/extensions/pmx-canvas/start-mcp.mjs +51 -0
  8. package/.github/extensions/pmx-canvas/tools.json +2560 -0
  9. package/CHANGELOG.md +47 -0
  10. package/Readme.md +21 -7
  11. package/dist/canvas/fonts/OFL.txt +93 -0
  12. package/dist/canvas/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
  13. package/dist/canvas/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
  14. package/dist/canvas/fonts/ibm-plex-mono-latin-ext-400-normal.woff2 +0 -0
  15. package/dist/canvas/fonts/ibm-plex-mono-latin-ext-500-normal.woff2 +0 -0
  16. package/dist/canvas/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
  17. package/dist/canvas/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
  18. package/dist/canvas/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
  19. package/dist/canvas/fonts/ibm-plex-sans-latin-ext-400-normal.woff2 +0 -0
  20. package/dist/canvas/fonts/ibm-plex-sans-latin-ext-500-normal.woff2 +0 -0
  21. package/dist/canvas/fonts/ibm-plex-sans-latin-ext-600-normal.woff2 +0 -0
  22. package/dist/canvas/global.css +723 -672
  23. package/dist/canvas/index.js +90 -88
  24. package/dist/canvas/mcp-app.html +7878 -0
  25. package/dist/canvas/mermaid-entry.js +1 -1
  26. package/dist/canvas/surface-theme.css +151 -46
  27. package/dist/json-render/index.css +1 -1
  28. package/dist/types/cli/commands/record.d.ts +1 -1
  29. package/dist/types/client/canvas/NodeContextMark.d.ts +24 -0
  30. package/dist/types/client/canvas/SessionReceipt.d.ts +3 -1
  31. package/dist/types/client/icons.d.ts +1 -2
  32. package/dist/types/client/mcp-app/index.d.ts +1 -0
  33. package/dist/types/client/nodes/ax-node-actions.d.ts +2 -2
  34. package/dist/types/client/nodes/markdown-sanitize.d.ts +2 -0
  35. package/dist/types/client/nodes/use-workbench-asset.d.ts +2 -0
  36. package/dist/types/client/state/attention-store.d.ts +0 -5
  37. package/dist/types/client/state/context-status-store.d.ts +53 -0
  38. package/dist/types/client/state/intent-bridge.d.ts +3 -0
  39. package/dist/types/client/state/near-pin-store.d.ts +16 -0
  40. package/dist/types/client/state/presence-store.d.ts +5 -0
  41. package/dist/types/client/state/session-store.d.ts +33 -3
  42. package/dist/types/client/state/workbench-transport.d.ts +16 -0
  43. package/dist/types/client/theme/tokens.d.ts +1 -3
  44. package/dist/types/client/types.d.ts +9 -0
  45. package/dist/types/json-render/server.d.ts +1 -1
  46. package/dist/types/mcp/app-server.d.ts +3 -0
  47. package/dist/types/mcp/canvas-access.d.ts +1 -1
  48. package/dist/types/mcp/canvas-app.d.ts +4 -0
  49. package/dist/types/mcp/workbench-app.d.ts +4 -0
  50. package/dist/types/server/agent-presence.d.ts +1 -1
  51. package/dist/types/server/ax-state.d.ts +1 -1
  52. package/dist/types/server/canvas-db.d.ts +8 -0
  53. package/dist/types/server/canvas-geometry.d.ts +25 -0
  54. package/dist/types/server/canvas-operations.d.ts +1 -11
  55. package/dist/types/server/canvas-state.d.ts +25 -3
  56. package/dist/types/server/context-brief.d.ts +8 -1
  57. package/dist/types/server/context-reads.d.ts +30 -7
  58. package/dist/types/server/index.d.ts +6 -1
  59. package/dist/types/server/mcp-app-runtime.d.ts +1 -0
  60. package/dist/types/server/operations/http.d.ts +2 -0
  61. package/dist/types/server/operations/invoker.d.ts +4 -2
  62. package/dist/types/server/operations/ops/nodes.d.ts +0 -6
  63. package/dist/types/server/server.d.ts +1 -0
  64. package/dist/types/server/spatial-analysis.d.ts +2 -0
  65. package/dist/types/shared/agent-context.d.ts +22 -0
  66. package/dist/types/shared/agent-presence.d.ts +3 -10
  67. package/dist/types/shared/canvas-app.d.ts +54 -0
  68. package/dist/types/shared/themes.d.ts +1 -1
  69. package/docs/RELEASE.md +7 -3
  70. package/docs/agent-plugin.md +123 -0
  71. package/docs/ax-state-contract.md +40 -0
  72. package/docs/cli.md +7 -2
  73. package/docs/design/AgentContext.dc.html +186 -0
  74. package/docs/design/Before.dc.html +208 -0
  75. package/docs/design/BoardPins.dc.html +151 -0
  76. package/docs/design/Chrome.dc.html +208 -0
  77. package/docs/design/Context.dc.html +239 -0
  78. package/docs/design/Flows.dc.html +181 -0
  79. package/docs/design/Home.dc.html +209 -0
  80. package/docs/design/HomeGraph.dc.html +211 -0
  81. package/docs/design/HomeMap.dc.html +117 -0
  82. package/docs/design/HomeTeam.dc.html +176 -0
  83. package/docs/design/Light.dc.html +28 -0
  84. package/docs/design/Main.dc.html +280 -0
  85. package/docs/design/NearPin.dc.html +260 -0
  86. package/docs/design/Pane600.dc.html +120 -0
  87. package/docs/design/Relations.dc.html +297 -0
  88. package/docs/design/Themes.dc.html +121 -0
  89. package/docs/design/TokenSystem.dc.html +136 -0
  90. package/docs/design/Tokens.dc.html +163 -0
  91. package/docs/design/Types1.dc.html +177 -0
  92. package/docs/design/Types2.dc.html +226 -0
  93. package/docs/design/Types3.dc.html +195 -0
  94. package/docs/design/Uses.dc.html +152 -0
  95. package/docs/design/Vision.dc.html +116 -0
  96. package/docs/design/Zoom.dc.html +82 -0
  97. package/docs/design/canvas.json +274 -0
  98. package/docs/design.md +214 -0
  99. package/docs/environment.md +1 -1
  100. package/docs/http-api.md +80 -15
  101. package/docs/mcp.md +198 -3
  102. package/docs/node-types.md +34 -10
  103. package/docs/plans/plan-009-tech-debt-backlog.md +1 -1
  104. package/docs/plans/plan-015-design-foundation-wave-0.md +177 -0
  105. package/docs/plans/plan-016-context-made-visible-wave-1.md +148 -0
  106. package/docs/product-vision-2026-09.md +47 -7
  107. package/docs/screenshot.png +0 -0
  108. package/docs/sdk.md +1 -0
  109. package/package.json +10 -4
  110. package/plugins/pmx-canvas/LICENSE +21 -0
  111. package/plugins/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
  112. package/plugins/pmx-canvas/assets/preview.png +0 -0
  113. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +930 -0
  114. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +3 -0
  115. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.mjs +194 -0
  116. package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/steering-delivery.mjs +79 -0
  117. package/plugins/pmx-canvas/mcp.json +12 -0
  118. package/plugins/pmx-canvas/plugin.json +24 -0
  119. package/plugins/pmx-canvas/runtime.json +3 -0
  120. package/plugins/pmx-canvas/runtime.mjs +194 -0
  121. package/plugins/pmx-canvas/start-mcp.mjs +51 -0
  122. package/plugins/pmx-canvas/tools.json +2560 -0
  123. package/skills/pmx-canvas/SKILL.md +10 -7
  124. package/skills/pmx-canvas/references/full-reference.md +11 -7
  125. package/skills/pmx-canvas/references/github-copilot-app-adapter.md +20 -8
  126. package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
  127. package/skills/pmx-canvas-testing/SKILL.md +5 -4
  128. package/src/cli/commands/copilot.ts +5 -0
  129. package/src/cli/commands/view.ts +1 -1
  130. package/src/cli/index.ts +8 -3
  131. package/src/client/App.tsx +6 -1
  132. package/src/client/canvas/AgentPresenceLayer.tsx +3 -3
  133. package/src/client/canvas/AnnotationLayer.tsx +1 -1
  134. package/src/client/canvas/CanvasNode.tsx +32 -49
  135. package/src/client/canvas/CanvasViewport.tsx +0 -2
  136. package/src/client/canvas/CommandPalette.tsx +3 -2
  137. package/src/client/canvas/ContextMenu.tsx +11 -0
  138. package/src/client/canvas/EdgeLayer.tsx +1 -1
  139. package/src/client/canvas/ExportDialog.tsx +33 -6
  140. package/src/client/canvas/IntentLayer.tsx +2 -2
  141. package/src/client/canvas/Minimap.tsx +12 -7
  142. package/src/client/canvas/NodeContextMark.tsx +156 -0
  143. package/src/client/canvas/SessionPanel.tsx +4 -7
  144. package/src/client/canvas/SessionReceipt.tsx +114 -17
  145. package/src/client/canvas/ShortcutOverlay.tsx +6 -1
  146. package/src/client/canvas/SnapshotPanel.tsx +11 -2
  147. package/src/client/canvas/ToolRail.tsx +12 -9
  148. package/src/client/canvas/TopBar.tsx +16 -11
  149. package/src/client/icons.tsx +2 -12
  150. package/src/client/mcp-app/index.tsx +137 -0
  151. package/src/client/mcp-app/style.css +10 -0
  152. package/src/client/nodes/AttachmentNode.tsx +8 -1
  153. package/src/client/nodes/AxStepControls.tsx +1 -1
  154. package/src/client/nodes/ContextNode.tsx +9 -9
  155. package/src/client/nodes/ExtAppFrame.tsx +13 -8
  156. package/src/client/nodes/FileNode.tsx +8 -5
  157. package/src/client/nodes/ImageNode.tsx +4 -2
  158. package/src/client/nodes/InlineMarkdownEditor.tsx +2 -1
  159. package/src/client/nodes/LedgerNode.tsx +2 -2
  160. package/src/client/nodes/MarkdownNode.tsx +44 -9
  161. package/src/client/nodes/McpAppNode.tsx +6 -4
  162. package/src/client/nodes/PromptNode.tsx +5 -17
  163. package/src/client/nodes/ResponseNode.tsx +3 -15
  164. package/src/client/nodes/StatusNode.tsx +2 -2
  165. package/src/client/nodes/StatusSummary.tsx +3 -1
  166. package/src/client/nodes/TraceNode.tsx +6 -4
  167. package/src/client/nodes/WebpageNode.tsx +1 -1
  168. package/src/client/nodes/ax-node-actions.ts +2 -2
  169. package/src/client/nodes/iframe-document-url.ts +3 -2
  170. package/src/client/nodes/markdown-sanitize.ts +10 -0
  171. package/src/client/nodes/surface-url.ts +10 -0
  172. package/src/client/nodes/use-surface-frame.ts +3 -1
  173. package/src/client/nodes/use-workbench-asset.ts +26 -0
  174. package/src/client/state/attention-bridge.ts +0 -8
  175. package/src/client/state/attention-store.ts +0 -17
  176. package/src/client/state/canvas-store.ts +4 -2
  177. package/src/client/state/context-status-store.ts +66 -0
  178. package/src/client/state/human-store.ts +2 -0
  179. package/src/client/state/iframe-mode.ts +5 -0
  180. package/src/client/state/intent-bridge.ts +10 -4
  181. package/src/client/state/near-pin-store.ts +53 -0
  182. package/src/client/state/presence-store.ts +5 -10
  183. package/src/client/state/session-store.ts +106 -9
  184. package/src/client/state/sse-bridge.ts +26 -7
  185. package/src/client/state/theme-override.ts +1 -1
  186. package/src/client/state/workbench-transport.ts +36 -0
  187. package/src/client/theme/global.css +723 -672
  188. package/src/client/theme/surface-theme.css +151 -46
  189. package/src/client/theme/tokens.ts +7 -11
  190. package/src/client/types.ts +10 -0
  191. package/src/json-render/server.ts +71 -14
  192. package/src/mcp/app-server.ts +64 -0
  193. package/src/mcp/canvas-access.ts +14 -11
  194. package/src/mcp/canvas-app.ts +318 -0
  195. package/src/mcp/server.ts +1 -1
  196. package/src/mcp/workbench-app.ts +211 -0
  197. package/src/server/agent-presence.ts +45 -6
  198. package/src/server/ax-context.ts +1 -1
  199. package/src/server/ax-state.ts +1 -1
  200. package/src/server/board-export.ts +5 -2
  201. package/src/server/canvas-db.ts +46 -12
  202. package/src/server/canvas-geometry.ts +64 -0
  203. package/src/server/canvas-operations.ts +6 -24
  204. package/src/server/canvas-state.ts +105 -15
  205. package/src/server/canvas-validation.ts +19 -4
  206. package/src/server/context-brief.ts +39 -2
  207. package/src/server/context-reads.ts +86 -15
  208. package/src/server/demo-state.json +31 -31
  209. package/src/server/html-surface.ts +4 -5
  210. package/src/server/index.ts +19 -3
  211. package/src/server/mcp-app-runtime.ts +11 -0
  212. package/src/server/operations/composites.ts +4 -3
  213. package/src/server/operations/http.ts +4 -4
  214. package/src/server/operations/invoker.ts +13 -4
  215. package/src/server/operations/ops/ax-read.ts +1 -1
  216. package/src/server/operations/ops/ax-timeline.ts +37 -0
  217. package/src/server/operations/ops/boards.ts +1 -1
  218. package/src/server/operations/ops/canvas-wire.ts +3 -6
  219. package/src/server/operations/ops/intent.ts +31 -2
  220. package/src/server/operations/ops/json-render.ts +1 -1
  221. package/src/server/operations/ops/nodes.ts +8 -76
  222. package/src/server/operations/ops/query.ts +8 -2
  223. package/src/server/operations/ops/snapshots.ts +4 -1
  224. package/src/server/operations/ops/viewport.ts +29 -5
  225. package/src/server/operations/registry.ts +38 -4
  226. package/src/server/scope-fence.ts +55 -10
  227. package/src/server/server.ts +83 -5
  228. package/src/server/spatial-analysis.ts +2 -2
  229. package/src/server/workboard.ts +6 -1
  230. package/src/{server → shared}/agent-context.ts +2 -2
  231. package/src/shared/agent-presence.ts +3 -15
  232. package/src/shared/canvas-app.ts +62 -0
  233. package/src/shared/themes.ts +5 -5
  234. package/src/client/canvas/FocusFieldLayer.tsx +0 -116
  235. package/src/client/canvas/kind-colors.ts +0 -23
@@ -0,0 +1,208 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>PMX Canvas — today</title>
6
+ <script src="./support.js"></script>
7
+ </head>
8
+ <body>
9
+ <x-dc>
10
+ <helmet>
11
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&amp;display=swap">
12
+ <style>
13
+ body{margin:0}
14
+ </style>
15
+ </helmet>
16
+ <div style="position: relative; width: 1440px; height: 900px; overflow: hidden; background: #081524; color: #e6eef7; font-family: -apple-system, 'SF Pro Text', system-ui, sans-serif; font-size: 11px; line-height: 1.45">
17
+
18
+ <nav aria-label="Tools" style="position: absolute; left: 0; top: 0; width: 52px; height: 900px; box-sizing: border-box; padding: 8px 0; background: #0b1828; border-right: 1px solid #1b2c44; display: flex; flex-direction: column; align-items: center; gap: 4px; color: #8ea3bd">
19
+ <button aria-label="Home" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #4BBCFF; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="20" height="20" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6"><rect x="4" y="4" width="16" height="16" rx="4"></rect><rect x="9" y="9" width="6" height="6" rx="1.5"></rect></svg></button>
20
+ <button aria-label="Bug and feedback" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><rect x="8" y="7" width="8" height="12" rx="4"></rect><path d="M12 7V4M5 10h3M16 10h3M5 15h3M16 15h3M9 5l1.5 2M15 5l-1.5 2"></path></svg></button>
21
+ <div style="width: 24px; height: 1px; margin: 4px 0; background: #1b2c44"></div>
22
+ <button aria-label="Select (V)" style="width: 36px; height: 36px; border: 1px solid #2a4566; border-radius: 8px; background: #13243b; color: #4BBCFF; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round"><path d="M5 3.5l13 7.5-5.6 1.6L10.8 18z"></path></svg></button>
23
+ <button aria-label="Pan (Space)" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round"><path d="M8 12V6.5a1.5 1.5 0 0 1 3 0V11M11 10.5V5a1.5 1.5 0 0 1 3 0v6M14 10.5V7a1.5 1.5 0 0 1 3 0v6.5a6.5 6.5 0 0 1-6.5 6.5h-.6a6 6 0 0 1-5-2.7l-1.8-3a1.5 1.5 0 0 1 2.5-1.6L8 14"></path></svg></button>
24
+ <button aria-label="Connect (C)" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><circle cx="6" cy="6" r="2.2"></circle><circle cx="18" cy="18" r="2.2"></circle><path d="M7.6 7.6l8.8 8.8"></path></svg></button>
25
+ <div style="width: 24px; height: 1px; margin: 4px 0; background: #1b2c44"></div>
26
+ <button aria-label="Markdown note (M)" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><rect x="4" y="5" width="16" height="14" rx="2"></rect><path d="M8 10h8M8 14h5"></path></svg></button>
27
+ <button aria-label="Attach files" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round"><path d="M12 15V4M7.5 8.5L12 4l4.5 4.5M5 19.5h14"></path></svg></button>
28
+ <button aria-label="Webpage (W)" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6"><rect x="3.5" y="5" width="17" height="14" rx="2"></rect><path d="M3.5 9h17"></path></svg></button>
29
+ <button aria-label="Group (G)" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-dasharray: 3 3"><rect x="4" y="4" width="16" height="16" rx="3"></rect></svg></button>
30
+ <button aria-label="Draw (A)" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round"><path d="M4 20l4.2-1L19 8.2 15.8 5 5 15.8z"></path></svg></button>
31
+ <button aria-label="Text note" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><path d="M5.5 6h13M12 6v13"></path></svg></button>
32
+ <button aria-label="Eraser" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round"><path d="M4 15l9-9 6 6-7 7H8zM9 10l6 6M8 19h12"></path></svg></button>
33
+ <div style="width: 24px; height: 1px; margin: 4px 0; background: #1b2c44"></div>
34
+ <button aria-label="Search and commands" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><circle cx="11" cy="11" r="6"></circle><path d="M20 20l-4.6-4.6"></path></svg></button>
35
+ <button aria-label="Arrange" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6"><rect x="4" y="4" width="6" height="6" rx="1.2"></rect><rect x="14" y="4" width="6" height="6" rx="1.2"></rect><rect x="4" y="14" width="6" height="6" rx="1.2"></rect><rect x="14" y="14" width="6" height="6" rx="1.2"></rect></svg></button>
36
+ <button aria-label="Enable trace" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6"><circle cx="12" cy="12" r="8"></circle><circle cx="12" cy="12" r="3"></circle></svg></button>
37
+ <button aria-label="Clear trace" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><circle cx="12" cy="12" r="8"></circle><path d="M9 9l6 6M15 9l-6 6"></path></svg></button>
38
+ <button aria-label="Hide minimap" style="width: 36px; height: 36px; border: 1px solid #2a4566; border-radius: 8px; background: #13243b; color: #4BBCFF; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6"><rect x="4" y="5" width="16" height="14" rx="2"></rect><rect x="11" y="11" width="6" height="5" rx="1"></rect></svg></button>
39
+ <button aria-label="Snapshots" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linejoin: round"><path d="M4 8h3l1.5-2h7L17 8h3v11H4z"></path><circle cx="12" cy="13" r="3"></circle></svg></button>
40
+ <button aria-label="Choose theme" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><circle cx="12" cy="12" r="4"></circle><path d="M12 3v2M12 19v2M3 12h2M19 12h2M5.6 5.6L7 7M17 17l1.4 1.4M5.6 18.4L7 17M17 7l1.4-1.4"></path></svg></button>
41
+ <button aria-label="Shortcuts" style="width: 36px; height: 36px; border: 0; border-radius: 8px; background: transparent; color: #8ea3bd; padding: 0; display: flex; align-items: center; justify-content: center"><svg width="18" height="18" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round"><rect x="3" y="6" width="18" height="12" rx="2"></rect><path d="M7 10h1M11 10h1M15 10h1M8 14h8"></path></svg></button>
42
+ </nav>
43
+
44
+ <header style="position: absolute; left: 52px; top: 0; right: 0; height: 48px; box-sizing: border-box; padding: 0 12px 0 16px; display: flex; align-items: center; gap: 10px; background: #0b1828; border-bottom: 1px solid #1b2c44">
45
+ <span style="width: 9px; height: 9px; border-radius: 999px; background: #2fd07f"></span>
46
+ <button style="font-family: Arial, sans-serif; font-size: 14px; font-weight: 700; color: #e6eef7; background: transparent; border: 0; padding: 0">Board 2026-10-04 06:27 ⌄</button>
47
+ <span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #5c6b80">pmx-mutfv69j · 70 nodes · 9 edges · 3 traces</span>
48
+ <div style="flex: 1"></div>
49
+ <button style="font-family: Arial, sans-serif; font-size: 12px; font-weight: 700; color: #8ea3bd; background: transparent; border: 1px solid #1b2c44; border-radius: 999px; height: 28px; padding: 0 12px">● Start agent session beta</button>
50
+ <button style="font-family: Arial, sans-serif; font-size: 13px; color: #e6eef7; background: transparent; border: 1px solid #1b2c44; border-radius: 6px; height: 30px; padding: 0 12px">Export</button>
51
+ <button style="font-family: Arial, sans-serif; font-size: 13px; color: #e6eef7; background: transparent; border: 1px solid #1b2c44; border-radius: 6px; height: 30px; padding: 0 12px">Present</button>
52
+ <span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd; padding: 0 10px">⊖ 52% ⊕ ⛶</span>
53
+ </header>
54
+
55
+ <main style="position: absolute; left: 52px; top: 48px; width: 1388px; height: 852px; overflow: hidden; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.10) 1px, transparent 1.2px); background-size: 24px 24px">
56
+
57
+ <div style="position: absolute; left: 32px; top: 6px; width: 1256px; height: 78px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
58
+ <div style="position: absolute; left: 32px; top: 72px; width: 432px; height: 372px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
59
+ <div style="position: absolute; left: 464px; top: 72px; width: 372px; height: 372px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
60
+ <div style="position: absolute; left: 836px; top: 72px; width: 502px; height: 372px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
61
+ <div style="position: absolute; left: 32px; top: 442px; width: 1256px; height: 78px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
62
+ <div style="position: absolute; left: 32px; top: 510px; width: 432px; height: 206px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
63
+ <div style="position: absolute; left: 836px; top: 510px; width: 452px; height: 206px; box-sizing: border-box; border: 1.5px solid rgba(244,197,66,0.45); border-radius: 22px; background: rgba(244,197,66,0.05); box-shadow: 0 0 36px rgba(244,197,66,0.14)"></div>
64
+
65
+ <section style="position: absolute; left: 48px; top: 16px; width: 1224px; height: 58px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
66
+ <div style="display: flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; background: #13243b; border-bottom: 1px solid #1b2c44"><span style="color: #4BBCFF">▤</span><span style="font-size: 11px; font-weight: 600">① Start here</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 8px">⤢⌄×</span></div>
67
+ <div style="padding: 2px 10px; font-size: 9px; color: #b9c6d6">What the agent is doing, what context it holds, what it decided, and the tool calls behind it.</div>
68
+ <div style="display: flex; justify-content: space-between; padding: 0 10px; font-family: Arial, sans-serif; font-size: 9px; color: #5c6b80"><span>Set as README</span><span>Edit</span></div>
69
+ </section>
70
+
71
+ <section style="position: absolute; left: 48px; top: 88px; width: 400px; height: 340px; box-sizing: border-box; background: #0f1d31; border: 1px solid rgba(244,197,66,0.6); border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 2px #f4c542, 0 0 8px rgba(244,197,66,0.3), 0 12px 34px rgba(244,197,66,0.18); overflow: hidden">
72
+ <div style="display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; background: linear-gradient(90deg, rgba(244,197,66,0.12), transparent 68%), #13243b; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; font-weight: 700; padding: 1px 5px; border-radius: 4px; background: rgba(244,197,66,0.15); color: #f4c542">▤</span><span style="font-size: 12px; font-weight: 600">PMX Canvas — guided tour</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 7px">○✧↗⤢⌄×</span></div>
73
+ <div style="padding: 10px 12px; display: flex; flex-direction: column; gap: 6px">
74
+ <div style="font-size: 12px; font-weight: 700">PMX Canvas</div>
75
+ <div style="font-size: 9.5px; color: #b9c6d6">An infinite spatial canvas that agents drive over MCP, HTTP or the Bun SDK — and that humans steer by pinning nodes.</div>
76
+ <div style="display: grid; grid-template-columns: 110px 1fr; font-size: 9px; border: 1px solid #1b2c44">
77
+ <div style="padding: 3px 6px; background: #13243b; color: #8ea3bd">Band</div><div style="padding: 3px 6px; background: #13243b; color: #8ea3bd">Shows</div>
78
+ <div style="padding: 3px 6px; border-top: 1px solid #1b2c44">① Start here</div><div style="padding: 3px 6px; border-top: 1px solid #1b2c44; color: #8ea3bd">status · context · ledger · trace</div>
79
+ <div style="padding: 3px 6px; border-top: 1px solid #1b2c44">② Files &amp; review</div><div style="padding: 3px 6px; border-top: 1px solid #1b2c44; color: #8ea3bd">file · CSV · diff · image · webpage</div>
80
+ <div style="padding: 3px 6px; border-top: 1px solid #1b2c44">③ Diagrams</div><div style="padding: 3px 6px; border-top: 1px solid #1b2c44; color: #8ea3bd">mermaid · raw HTML · MCP app</div>
81
+ <div style="padding: 3px 6px; border-top: 1px solid #1b2c44">④ Charts</div><div style="padding: 3px 6px; border-top: 1px solid #1b2c44; color: #8ea3bd">all 12 graph types</div>
82
+ </div>
83
+ <div style="font-size: 9.5px; color: #b9c6d6">Pin a node in the browser and the agent reads it back from canvas://pinned-context.</div>
84
+ </div>
85
+ <div style="position: absolute; left: 12px; right: 12px; bottom: 6px; display: flex; justify-content: space-between; font-family: Arial, sans-serif; font-size: 9px; color: #5c6b80"><span>Set as README</span><span>Edit</span></div>
86
+ </section>
87
+
88
+ <section style="position: absolute; left: 480px; top: 88px; width: 340px; height: 140px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 1px rgba(244,197,66,0.72), 0 12px 34px rgba(244,197,66,0.18), inset 0 0 0 1px rgba(244,197,66,0.28); overflow: hidden">
89
+ <div style="display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; background: linear-gradient(90deg, rgba(244,197,66,0.12), transparent 68%), #13243b; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(47,208,127,0.15); color: #2fd07f">◉</span><span style="font-size: 11.5px; font-weight: 600">Agent</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 8px">⌄×</span></div>
90
+ <div style="padding: 8px 12px; display: flex; flex-direction: column; gap: 5px; font-size: 10px">
91
+ <div><span style="color: #4BBCFF">● </span><strong style="color: #4BBCFF">TOOLING</strong> <span style="color: #8ea3bd">Rebuilding the release checklist</span></div>
92
+ <div style="font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: #f4c542">● canvas_render</div>
93
+ <div style="font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: #4BBCFF">◦ release-auditor <span style="color: #5c6b80">(running)</span></div>
94
+ <div style="color: #8ea3bd">3 of 5 gates green</div>
95
+ </div>
96
+ </section>
97
+
98
+ <div style="position: absolute; left: 649px; top: 228px; width: 1.5px; height: 44px; background: #2a4566"></div>
99
+ <span style="position: absolute; left: 622px; top: 238px; font-family: Arial, sans-serif; font-size: 11px; line-height: 22px; padding: 0 8px; border-radius: 4px; background: #13243b; border: 1px solid #2a4566; color: #b9c6d6">runs</span>
100
+
101
+ <div style="position: absolute; left: 480px; top: 272px; width: 340px; height: 56px; box-sizing: border-box; display: flex; align-items: center; gap: 8px; padding: 0 18px; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 999px; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1)">
102
+ <span style="color: #2fd07f">✓</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: #4BBCFF">canvas_query · search</span><span style="font-size: 9px; padding: 1px 5px; border-radius: 4px; background: #13243b; color: #5c6b80">38ms</span>
103
+ </div>
104
+
105
+ <div style="position: absolute; left: 649px; top: 328px; width: 1.5px; height: 44px; background: #2a4566"></div>
106
+ <span style="position: absolute; left: 624px; top: 338px; font-family: Arial, sans-serif; font-size: 11px; line-height: 22px; padding: 0 8px; border-radius: 4px; background: #13243b; border: 1px solid #2a4566; color: #b9c6d6">then</span>
107
+
108
+ <div style="position: absolute; left: 480px; top: 372px; width: 340px; height: 56px; box-sizing: border-box; display: flex; align-items: center; gap: 8px; padding: 0 18px; background: #0f1d31; border: 1.5px solid #4BBCFF; border-radius: 999px; box-shadow: 0 0 14px rgba(75,188,255,0.35)">
109
+ <span style="color: #5c6b80">◦</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 10px; color: #f4c542">edit_file · CHANGELOG.md</span><span style="font-size: 9px; padding: 1px 5px; border-radius: 4px; background: #13243b; color: #5c6b80">1.2s</span>
110
+ </div>
111
+
112
+ <section style="position: absolute; left: 852px; top: 88px; width: 470px; height: 340px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
113
+ <div style="display: flex; align-items: center; gap: 6px; height: 32px; padding: 0 10px; background: #13243b; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(244,197,66,0.12); color: #f4c542">▥</span><span style="font-size: 11.5px; font-weight: 600">bar — merged PRs per …</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 7px">↗⤢⌄×</span></div>
114
+ <div style="position: absolute; left: 8px; right: 8px; top: 40px; height: 230px; box-sizing: border-box; padding: 12px 14px; background: #000000; border: 1px solid #1f1f1f; border-radius: 8px">
115
+ <div style="font-size: 10px; font-weight: 700; color: #f2f2f2">bar — merged PRs per week</div>
116
+ <div style="position: absolute; left: 40px; right: 16px; bottom: 30px; height: 150px; display: flex; align-items: flex-end; gap: 14px; border-left: 1px solid #333; border-bottom: 1px solid #333; padding: 0 8px">
117
+ <div style="flex: 1; height: 92px; background: #2b4a6b"></div><div style="flex: 1; height: 84px; background: #2b4a6b"></div><div style="flex: 1; height: 118px; background: #2b4a6b"></div><div style="flex: 1; height: 106px; background: #2b4a6b"></div><div style="flex: 1; height: 128px; background: #2b4a6b"></div><div style="flex: 1; height: 146px; background: #4BBCFF"></div>
118
+ </div>
119
+ <div style="position: absolute; left: 48px; right: 16px; bottom: 12px; display: flex; justify-content: space-around; font-size: 8.5px; color: #8a8a8a"><span>W23</span><span>W24</span><span>W25</span><span>W26</span><span>W27</span><span>W28</span></div>
120
+ </div>
121
+ </section>
122
+
123
+ <button style="position: absolute; right: 16px; top: 96px; display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 8px 0 12px; border-radius: 999px; border: 1px solid #2a4566; background: #0f1d31; color: #e6eef7; font-family: Arial, sans-serif; font-size: 12px; font-weight: 700; letter-spacing: 0.06em; box-shadow: 0 8px 24px rgba(0,0,0,0.5)">▣ UPDATES <span style="width: 18px; height: 18px; border-radius: 999px; background: #f4c542; color: #081524; font-size: 11px; display: flex; align-items: center; justify-content: center">1</span></button>
124
+
125
+ <section style="position: absolute; left: 48px; top: 452px; width: 1224px; height: 58px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
126
+ <div style="display: flex; align-items: center; gap: 6px; height: 24px; padding: 0 10px; background: #13243b; border-bottom: 1px solid #1b2c44"><span style="color: #4BBCFF">▤</span><span style="font-size: 11px; font-weight: 600">② Files &amp; review</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 8px">⤢⌄×</span></div>
127
+ <div style="padding: 2px 10px; font-size: 9px; color: #b9c6d6">Inline file text, unified diffs, images and cached webpages.</div>
128
+ <div style="display: flex; justify-content: space-between; padding: 0 10px; font-family: Arial, sans-serif; font-size: 9px; color: #5c6b80"><span>Set as README</span><span>Edit</span></div>
129
+ </section>
130
+
131
+ <section style="position: absolute; left: 48px; top: 524px; width: 400px; height: 176px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
132
+ <div style="display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; background: #13243b; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(244,197,66,0.12); color: #f4c542">▭</span><span style="font-size: 11.5px; font-weight: 600">Model Context Protocol — Res…</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 7px">○↗⤢⌄×</span></div>
133
+ <div style="padding: 8px 12px; display: flex; flex-direction: column; gap: 6px">
134
+ <div style="font-size: 9.5px; padding: 4px 8px; border-radius: 4px; background: rgba(244,197,66,0.10); color: #f4c542">⚠ Showing cached copy — live fetch failed</div>
135
+ <div style="font-size: 11px; font-weight: 700">Resources</div>
136
+ <div style="font-size: 9.5px; color: #b9c6d6">Servers expose data and content that clients can read and use as context for model interactions.</div>
137
+ </div>
138
+ </section>
139
+
140
+ <section style="position: absolute; left: 480px; top: 524px; width: 340px; height: 176px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; overflow: hidden">
141
+ <div style="display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; background: #13243b; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(75,188,255,0.12); color: #4BBCFF">▯</span><span style="font-size: 11.5px; font-weight: 600">node-sizes.ts</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 7px">○↗⤢⌄×</span></div>
142
+ <div style="padding: 8px 12px; font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; line-height: 1.6; color: #b9c6d6; white-space: pre">export const NODE_MIN = { width: 180, height: 96 };
143
+
144
+ export function clampSize(size) {
145
+ return {
146
+ width: Math.max(size.width, NODE_MIN.width),
147
+ height: Math.max(size.height, NODE_MIN.height),</div>
148
+ </section>
149
+
150
+ <section style="position: absolute; left: 852px; top: 524px; width: 420px; height: 176px; box-sizing: border-box; background: #0f1d31; border: 1px solid #1b2c44; border-radius: 12px 12px 8px 8px; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
151
+ <div style="display: flex; align-items: center; gap: 6px; height: 30px; padding: 0 10px; background: #13243b; border-bottom: 1px solid #1b2c44"><span style="font-size: 10px; padding: 1px 5px; border-radius: 4px; background: rgba(75,188,255,0.12); color: #4BBCFF">±</span><span style="font-size: 11.5px; font-weight: 600">Readability floor — 2 files</span><span style="flex: 1"></span><span style="font-family: Arial, sans-serif; color: #8ea3bd; letter-spacing: 7px">○✧↗⤢⌄×</span></div>
152
+ <div style="padding: 6px 0; font-family: 'IBM Plex Mono', monospace; font-size: 9.5px; line-height: 1.7">
153
+ <div style="padding: 0 12px; color: #5c6b80">@@ src/client/theme/global.css</div>
154
+ <div style="padding: 0 12px; background: rgba(255,106,127,0.10); color: #ff6a7f">- font-size: 10px;</div>
155
+ <div style="padding: 0 12px; background: rgba(47,208,127,0.10); color: #2fd07f">+ font-size: var(--fs-meta);</div>
156
+ <div style="padding: 0 12px; background: rgba(255,106,127,0.10); color: #ff6a7f">- border-radius: 12px 12px 8px 8px;</div>
157
+ <div style="padding: 0 12px; background: rgba(47,208,127,0.10); color: #2fd07f">+ border-radius: var(--r-node);</div>
158
+ </div>
159
+ </section>
160
+
161
+ <button style="position: absolute; left: 574px; bottom: 20px; display: flex; align-items: center; gap: 10px; height: 34px; padding: 0 12px; border-radius: 10px; border: 1px solid rgba(244,197,66,0.55); background: rgba(30,32,30,0.92); color: #f4c542; font-family: Arial, sans-serif; font-size: 13px; font-weight: 700">✦ 4 nodes in context <span style="color: #8ea3bd">×</span></button>
162
+
163
+ <div style="position: absolute; right: 16px; bottom: 16px; width: 200px; height: 130px; box-sizing: border-box; border-radius: 8px; border: 1px solid #2a4566; background: #0b1828; overflow: hidden">
164
+ <div style="position: absolute; left: 10px; top: 10px; width: 16px; height: 8px; background: #4BBCFF"></div>
165
+ <div style="position: absolute; left: 30px; top: 10px; width: 20px; height: 8px; background: #2fd07f"></div>
166
+ <div style="position: absolute; left: 54px; top: 10px; width: 14px; height: 8px; background: #2fd07f"></div>
167
+ <div style="position: absolute; left: 10px; top: 22px; width: 18px; height: 10px; background: #8d6bff"></div>
168
+ <div style="position: absolute; left: 32px; top: 22px; width: 18px; height: 10px; background: #8d6bff"></div>
169
+ <div style="position: absolute; left: 54px; top: 22px; width: 18px; height: 10px; background: #2fd07f"></div>
170
+ <div style="position: absolute; left: 10px; top: 36px; width: 18px; height: 10px; background: #8d6bff"></div>
171
+ <div style="position: absolute; left: 32px; top: 36px; width: 18px; height: 10px; background: #4BBCFF"></div>
172
+ <div style="position: absolute; left: 54px; top: 36px; width: 18px; height: 10px; background: #8d6bff"></div>
173
+ <div style="position: absolute; left: 10px; top: 50px; width: 18px; height: 10px; background: #8d6bff"></div>
174
+ <div style="position: absolute; left: 32px; top: 50px; width: 18px; height: 10px; background: #8d6bff"></div>
175
+ <div style="position: absolute; left: 82px; top: 10px; width: 22px; height: 14px; background: #2fd07f"></div>
176
+ <div style="position: absolute; left: 108px; top: 10px; width: 22px; height: 14px; background: #2fd07f"></div>
177
+ <div style="position: absolute; left: 134px; top: 10px; width: 22px; height: 14px; background: #4BBCFF"></div>
178
+ <div style="position: absolute; left: 82px; top: 28px; width: 22px; height: 18px; background: #c9a227"></div>
179
+ <div style="position: absolute; left: 108px; top: 28px; width: 22px; height: 18px; background: #c9a227"></div>
180
+ <div style="position: absolute; left: 134px; top: 28px; width: 22px; height: 18px; background: #c9a227"></div>
181
+ <div style="position: absolute; left: 160px; top: 28px; width: 22px; height: 18px; background: #c9a227"></div>
182
+ <div style="position: absolute; left: 82px; top: 50px; width: 22px; height: 18px; background: #c9a227"></div>
183
+ <div style="position: absolute; left: 108px; top: 50px; width: 22px; height: 18px; background: #c9a227"></div>
184
+ <div style="position: absolute; left: 134px; top: 50px; width: 22px; height: 18px; background: #c9a227"></div>
185
+ <div style="position: absolute; left: 160px; top: 50px; width: 22px; height: 18px; background: #c9a227"></div>
186
+ <div style="position: absolute; left: 82px; top: 72px; width: 22px; height: 18px; background: #c9a227"></div>
187
+ <div style="position: absolute; left: 108px; top: 72px; width: 22px; height: 18px; background: #c9a227"></div>
188
+ <div style="position: absolute; left: 134px; top: 72px; width: 22px; height: 18px; background: #c9a227"></div>
189
+ <div style="position: absolute; left: 160px; top: 72px; width: 22px; height: 18px; background: #c9a227"></div>
190
+ <div style="position: absolute; left: 10px; top: 72px; width: 18px; height: 10px; background: #8d6bff"></div>
191
+ <div style="position: absolute; left: 32px; top: 72px; width: 18px; height: 10px; background: #8d6bff"></div>
192
+ <div style="position: absolute; left: 82px; top: 94px; width: 22px; height: 18px; background: #c9a227"></div>
193
+ <div style="position: absolute; left: 8px; top: 8px; width: 46px; height: 28px; border: 1.5px solid #4BBCFF"></div>
194
+ <span style="position: absolute; right: 6px; bottom: 4px; font-family: 'IBM Plex Mono', monospace; font-size: 9px; color: #5c6b80">52%</span>
195
+ </div>
196
+
197
+ </main>
198
+ </div>
199
+ </x-dc>
200
+ <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":900}}'>
201
+ class Component extends DCLogic {
202
+ renderVals() {
203
+ return {};
204
+ }
205
+ }
206
+ </script>
207
+ </body>
208
+ </html>
@@ -0,0 +1,151 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Board pins</title>
6
+ <script src="./support.js"></script>
7
+ </head>
8
+ <body>
9
+ <x-dc>
10
+ <helmet>
11
+ <link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Mono:wght@400;500&amp;family=IBM+Plex+Sans:wght@400;500;600&amp;display=swap">
12
+ <style>
13
+ body{margin:0}
14
+ </style>
15
+ </helmet>
16
+ <div style="width: 1440px; height: 1100px; box-sizing: border-box; padding: 44px 56px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: flex; flex-direction: column; gap: 24px">
17
+
18
+ <div>
19
+ <h1 style="margin: 0; font-size: 28px; font-weight: 600; letter-spacing: -0.015em">Board pins — a working set across boards</h1>
20
+ <p style="margin: 4px 0 0; font-size: 13px; color: #8ea3bd">One gesture at two levels. Pin a card and its content goes to the agent. Pin a board and the whole board joins the agent's working set, wherever it sits in the library.</p>
21
+ </div>
22
+
23
+ <div style="display: grid; grid-template-columns: 600px minmax(0, 1fr); gap: 40px">
24
+
25
+ <section style="display: flex; flex-direction: column; gap: 12px">
26
+ <span style="{{s.label}}">Where you pin a board — same pin, same place</span>
27
+
28
+ <div style="{{s.card}}">
29
+ <span style="{{s.cap}}">Home — board cards</span>
30
+ <div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px">
31
+ <div style="border-radius: 10px; border: 1.5px solid #4BBCFF; background: #0f1d31; overflow: hidden"><div style="position: relative; height: 70px; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 10px 10px; border-bottom: 1px solid #1b2c44"><span style="{{s.pinOn}} position: absolute; right: 8px; top: 8px"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div><div style="padding: 8px 10px"><div style="font-size: 12px; font-weight: 600">C4 2026 OKR planning</div><div style="font-size: 11px; color: #8ea3bd">in context · 34 cards</div></div></div>
32
+ <div style="border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; overflow: hidden"><div style="position: relative; height: 70px; background-color: #081524; background-image: radial-gradient(rgba(142,163,189,0.14) 1px, transparent 1.2px); background-size: 10px 10px; border-bottom: 1px solid #1b2c44"><span style="{{s.pinOff}} position: absolute; right: 8px; top: 8px"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div><div style="padding: 8px 10px"><div style="font-size: 12px; font-weight: 600">Platform roadmap 2027</div><div style="font-size: 11px; color: #8ea3bd">click the pin to add · 26 cards</div></div></div>
33
+ </div>
34
+ </div>
35
+
36
+ <div style="display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px">
37
+ <div style="{{s.card}}">
38
+ <span style="{{s.cap}}">Board switcher</span>
39
+ <sc-for list="{{switcher}}" as="b" hint-placeholder-count="4">
40
+ <div style="display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 8px; border-radius: 6px; background: {{b.bg}}"><span style="width: 8px; height: 8px; border-radius: 3px; background: {{b.hue}}"></span><span style="flex: 1; font-size: 12px; font-weight: 500">{{b.name}}</span><span style="{{b.pinStyle}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div>
41
+ </sc-for>
42
+ </div>
43
+ <div style="{{s.card}}">
44
+ <span style="{{s.cap}}">A portal card on a board</span>
45
+ <div style="border-radius: 10px; border: 1.5px solid #4BBCFF; background: #0f1d31; overflow: hidden">
46
+ <div style="display: flex; align-items: center; gap: 8px; height: 34px; padding: 0 8px 0 10px; border-bottom: 1px solid #1b2c44; background: rgba(75,188,255,0.10)"><svg width="14" height="14" viewBox="0 0 24 24" style="color: #4BBCFF; {{s.ic}}"><path d="M5 6h9v12H5zM14 9l5-3v12l-5-3"></path></svg><span style="flex: 1; font-size: 12px; font-weight: 600">Pricing research</span><span style="{{s.pinOn}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span></div>
47
+ <div style="padding: 8px 10px; font-size: 11px; color: #8ea3bd">Board · 27 cards · pinned here, so it travels with you</div>
48
+ </div>
49
+ </div>
50
+ </div>
51
+
52
+ <div style="{{s.card}}">
53
+ <span style="{{s.cap}}">The open board's top bar</span>
54
+ <div style="display: flex; align-items: center; gap: 8px; height: 40px; padding: 0 10px; border-radius: 8px; background: #0f1d31; border: 1px solid #1b2c44">
55
+ <span style="width: 7px; height: 7px; border-radius: 999px; background: #2fd07f"></span>
56
+ <span style="font-size: 13px; font-weight: 600">Pricing research ▾</span>
57
+ <span style="{{s.pinOn}}"><svg width="10" height="10" viewBox="0 0 24 24" style="{{s.ic}}"><path d="{{i.pin}}"></path></svg></span>
58
+ <span style="flex: 1"></span>
59
+ <span style="display: flex; align-items: center; gap: 6px; height: 26px; padding: 0 10px; border-radius: 999px; border: 1px solid rgba(75,188,255,0.3); color: #4BBCFF; font-size: 12px; font-weight: 500">4 cards · 3 boards in context</span>
60
+ </div>
61
+ </div>
62
+
63
+ <div style="display: flex; gap: 10px; padding: 12px 14px; border-radius: 10px; border: 1px solid #1b2c44; background: #0b1828; font-size: 12px; color: #b9c6d6"><span style="color: #4BBCFF; font-weight: 600; flex-shrink: 0">Read, not write.</span><span>A pinned board is context. The agent still writes only to the board that's open; pinning never widens what it may change.</span></div>
64
+ </section>
65
+
66
+ <section style="display: flex; flex-direction: column; gap: 12px">
67
+ <span style="{{s.label}}">What the agent gets — the brief, in order</span>
68
+ <sc-for list="{{tiers}}" as="t" hint-placeholder-count="3">
69
+ <div style="{{s.card}} gap: 8px; border-color: {{t.border}}">
70
+ <div style="display: flex; align-items: baseline; gap: 10px"><span style="width: 22px; height: 22px; border-radius: 999px; background: {{t.numBg}}; color: {{t.numC}}; font-size: 12px; font-weight: 600; text-align: center; line-height: 22px; flex-shrink: 0">{{t.n}}</span><span style="font-size: 15px; font-weight: 600; flex: 1">{{t.title}}</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd">{{t.tokens}}</span></div>
71
+ <span style="font-size: 12px; color: #8ea3bd">{{t.what}}</span>
72
+ <sc-for list="{{t.rows}}" as="r" hint-placeholder-count="2">
73
+ <div style="display: flex; align-items: center; gap: 8px; height: 30px; padding: 0 10px; border-radius: 6px; background: #13243b; font-size: 12px"><span style="{{r.mark}}">{{r.markText}}</span><span style="flex: 1; font-weight: 500">{{r.name}}</span><span style="font-size: 11px; color: #8ea3bd">{{r.detail}}</span></div>
74
+ </sc-for>
75
+ </div>
76
+ </sc-for>
77
+ <div style="display: flex; align-items: center; gap: 12px; font-size: 12px; color: #8ea3bd"><span style="width: 200px; height: 6px; border-radius: 999px; background: #1b2c44; overflow: hidden; display: block"><span style="display: block; width: 77%; height: 6px; background: #f4c542"></span></span><span style="font-family: 'IBM Plex Mono', monospace; color: #e6eef7; white-space: nowrap">24.5k / 32k</span><span>Over budget, a pinned board falls back to discovery — said on the chip, never silent.</span></div>
78
+ </section>
79
+
80
+ </div>
81
+
82
+ <section style="display: flex; flex-direction: column; gap: 12px">
83
+ <span style="{{s.label}}">On any board — the context chip, opened</span>
84
+ <div style="display: flex; gap: 24px; align-items: flex-start">
85
+ <div style="width: 420px; box-sizing: border-box; padding: 12px; border-radius: 12px; border: 1px solid #2a4566; background: #13243b; box-shadow: 0 10px 30px rgba(0,0,0,0.55); display: flex; flex-direction: column; gap: 8px">
86
+ <div style="display: flex; align-items: center; justify-content: space-between"><span style="font-size: 12px; font-weight: 600">In the agent's context</span><span style="font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #8ea3bd">24.5k tokens</span></div>
87
+ <span style="{{s.cap}}">Boards · 3</span>
88
+ <sc-for list="{{chipBoards}}" as="r" hint-placeholder-count="3">
89
+ <div style="display: flex; align-items: center; gap: 8px; height: 28px; font-size: 12px"><span style="width: 8px; height: 8px; border-radius: 3px; background: {{r.hue}}"></span><span style="flex: 1">{{r.name}}</span><span style="{{r.readStyle}}">{{r.read}}</span><span style="color: #6b7d94">×</span></div>
90
+ </sc-for>
91
+ <span style="{{s.cap}}">Cards on this board · 4</span>
92
+ <div style="font-size: 12px; color: #b9c6d6">Raise Pro to $24? · Churn flat after last raise · SMB is price-sensitive · Competitor pricing</div>
93
+ </div>
94
+ <div style="flex: 1; display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 12px">
95
+ <sc-for list="{{rules}}" as="r" hint-placeholder-count="3">
96
+ <div style="{{s.card}} gap: 4px"><span style="font-size: 12px; font-weight: 600">{{r.t}}</span><span style="font-size: 11px; color: #b9c6d6">{{r.d}}</span></div>
97
+ </sc-for>
98
+ </div>
99
+ </div>
100
+ </section>
101
+
102
+ </div>
103
+ </x-dc>
104
+ <script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1100}}'>
105
+ class Component extends DCLogic {
106
+ renderVals() {
107
+ var i = { pin: 'M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20' };
108
+ var pinOn = 'width:18px;height:18px;border-radius:999px;display:flex;align-items:center;justify-content:center;flex-shrink:0;background:#4BBCFF;color:#081524;';
109
+ var pinOff = 'width:18px;height:18px;box-sizing:border-box;border-radius:999px;display:flex;align-items:center;justify-content:center;flex-shrink:0;border:1.5px solid #6b7d94;color:#b9c6d6;';
110
+ var s = {
111
+ label: 'font-size:11px;font-weight:500;letter-spacing:0.06em;text-transform:uppercase;color:#6b7d94;',
112
+ cap: 'font-size:11px;font-weight:500;color:#8ea3bd;',
113
+ card: 'display:flex;flex-direction:column;gap:10px;padding:14px 16px;border-radius:10px;border:1px solid #1b2c44;background:#0b1828;',
114
+ ic: 'fill:none;stroke:currentColor;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;',
115
+ pinOn: pinOn, pinOff: pinOff
116
+ };
117
+ var switcher = [
118
+ { name: 'Pricing research', hue: '#7C9CFF', pinStyle: pinOn, bg: '#13243b' },
119
+ { name: 'C4 2026 OKR planning', hue: '#5FCFC0', pinStyle: pinOn, bg: 'transparent' },
120
+ { name: 'Tech Enabling — overview', hue: '#5FCFC0', pinStyle: pinOn, bg: 'transparent' },
121
+ { name: 'Platform roadmap 2027', hue: '#5FCFC0', pinStyle: pinOff, bg: 'transparent' }
122
+ ];
123
+ var mOn = 'font-size:11px;font-weight:600;padding:0 6px;border-radius:999px;background:rgba(75,188,255,0.14);color:#4BBCFF;';
124
+ var mDisc = 'font-size:11px;font-weight:600;padding:0 6px;border-radius:999px;background:#1b2c44;color:#8ea3bd;';
125
+ var tiers = [
126
+ { n: '1', title: 'This board’s pinned cards', tokens: '9k', what: 'Full content, as today.', border: 'rgba(75,188,255,0.35)', numBg: '#4BBCFF', numC: '#081524',
127
+ rows: [{ name: '4 cards on Pricing research', detail: 'full text', mark: mOn, markText: 'cards' }] },
128
+ { n: '2', title: 'Pinned boards', tokens: '14k', what: 'Each board’s README and its pinned cards, in full. New.', border: 'rgba(75,188,255,0.35)', numBg: '#4BBCFF', numC: '#081524',
129
+ rows: [{ name: 'Tech Enabling — overview', detail: 'README + 2 pinned · 6k', mark: mOn, markText: 'board' },
130
+ { name: 'C4 2026 OKR planning', detail: 'README + 3 pinned · 8k', mark: mOn, markText: 'board' }] },
131
+ { n: '3', title: 'Discovery', tokens: '1.5k', what: 'Linked and same-folder boards: README summary and pinned titles only — today’s behaviour.', border: '#1b2c44', numBg: '#1b2c44', numC: '#b9c6d6',
132
+ rows: [{ name: 'Churn analysis · SMB interviews · Competitor teardown', detail: 'summaries', mark: mDisc, markText: 'linked' }] }
133
+ ];
134
+ var read = 'font-size:11px;font-weight:500;padding:0 6px;border-radius:999px;background:rgba(179,136,255,0.16);color:#B388FF;';
135
+ var notRead = 'font-size:11px;font-weight:500;padding:0 6px;border-radius:999px;background:#1b2c44;color:#8ea3bd;';
136
+ var chipBoards = [
137
+ { name: 'Pricing research (this board)', hue: '#7C9CFF', read: 'read 2m ago', readStyle: read },
138
+ { name: 'Tech Enabling — overview', hue: '#5FCFC0', read: 'read 2m ago', readStyle: read },
139
+ { name: 'C4 2026 OKR planning', hue: '#5FCFC0', read: 'not read yet', readStyle: notRead }
140
+ ];
141
+ var rules = [
142
+ { t: 'Lasts until you unpin', d: 'Board pins belong to the workspace: they survive board switches and restarts. You or the agent can pin; the agent’s pins carry its violet dot.' },
143
+ { t: 'Seen like card pins', d: 'Read and “not read yet” come from the recorded reads, per board — so you know which boards the agent actually loaded.' },
144
+ { t: 'Agents use the same pins', d: 'canvas://pinned-context lists pinned boards; canvas_board pin / unpin sets them, with the HTTP route, SDK and CLI kept in step.' }
145
+ ];
146
+ return { s: s, i: i, switcher: switcher, tiers: tiers, chipBoards: chipBoards, rules: rules };
147
+ }
148
+ }
149
+ </script>
150
+ </body>
151
+ </html>