pmx-canvas 0.10.0 → 0.11.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.
- package/.github/extensions/pmx-canvas/runtime.json +1 -1
- package/.github/extensions/pmx-canvas/tools.json +246 -108
- package/CHANGELOG.md +32 -0
- package/dist/canvas/chunks/abnfDiagram-N423BO3Z-p8dtp6va.js +1 -0
- package/dist/canvas/chunks/architecture-TIHT7OUA-9tffvpsv.js +1 -0
- package/dist/canvas/chunks/architectureDiagram-T3A2C74G-5jhmxrzf.js +36 -0
- package/dist/canvas/chunks/blockDiagram-VBNYF7ZC-pw1fa9yb.js +132 -0
- package/dist/canvas/chunks/c4Diagram-5PPSVZJV-x07nq0tt.js +10 -0
- package/dist/canvas/chunks/classDiagram-JCYQIIEL-nc6g5x1r.js +1 -0
- package/dist/canvas/chunks/classDiagram-v2-OCEON4UE-0qnbpwvh.js +1 -0
- package/dist/canvas/chunks/cose-bilkent-JH36ORCC-nm39npq0.js +1 -0
- package/dist/canvas/chunks/cynefin-VYW2F7L2-ys8p46ts.js +1 -0
- package/dist/canvas/chunks/cynefinDiagram-MW4NZA55-vdxrwahz.js +62 -0
- package/dist/canvas/chunks/dagre-VZM6K2ZE-bqdm7wpd.js +4 -0
- package/dist/canvas/chunks/diagram-7IWD3JNH-gs5gpr93.js +30 -0
- package/dist/canvas/chunks/diagram-B4RE2ZJO-cgwjg47s.js +3 -0
- package/dist/canvas/chunks/diagram-LBJQPF4R-w3vahpav.js +24 -0
- package/dist/canvas/chunks/diagram-Q27KOJAE-42837z6h.js +24 -0
- package/dist/canvas/chunks/diagram-UB23O5K3-4fz83q59.js +41 -0
- package/dist/canvas/chunks/ebnfDiagram-BXEA7PRR-zphtgegj.js +1 -0
- package/dist/canvas/chunks/erDiagram-JOGREHBK-zvbbdxp4.js +85 -0
- package/dist/canvas/chunks/eventmodeling-45OFAUF4-v9q6dn4c.js +1 -0
- package/dist/canvas/chunks/flowDiagram-UKHOOZJN-yrr5z8tc.js +1 -0
- package/dist/canvas/chunks/ganttDiagram-PKOTCBZU-282jzycm.js +292 -0
- package/dist/canvas/chunks/gitGraph-TEB2WS4Q-kdwb8m0a.js +1 -0
- package/dist/canvas/chunks/gitGraphDiagram-DS77QQ5N-vqqy6p1b.js +106 -0
- package/dist/canvas/chunks/index-0rk4gp1g.js +2 -0
- package/dist/canvas/chunks/index-194m3hc3.js +2 -0
- package/dist/canvas/chunks/index-1r72hdzb.js +301 -0
- package/dist/canvas/chunks/index-353m7b0p.js +2 -0
- package/dist/canvas/chunks/index-3cy1bzwh.js +2 -0
- package/dist/canvas/chunks/index-5tv8v1hk.js +1 -0
- package/dist/canvas/chunks/index-6ceya556.js +332 -0
- package/dist/canvas/chunks/index-6qmsnxwy.js +4 -0
- package/dist/canvas/chunks/index-d3b3gqe9.js +2 -0
- package/dist/canvas/chunks/index-fjtdggjn.js +2 -0
- package/dist/canvas/chunks/index-g3pwnqeb.js +2 -0
- package/dist/canvas/chunks/index-gf4e0et4.js +2 -0
- package/dist/canvas/chunks/index-hj99nz1f.js +1 -0
- package/dist/canvas/chunks/index-nprm96xp.js +16 -0
- package/dist/canvas/chunks/index-qj8fxwsf.js +2 -0
- package/dist/canvas/chunks/index-r2fyc9w1.js +89 -0
- package/dist/canvas/chunks/index-rft2hcz5.js +2 -0
- package/dist/canvas/chunks/index-rh7nv68n.js +2 -0
- package/dist/canvas/chunks/index-s4j678gj.js +2 -0
- package/dist/canvas/chunks/index-tb1wf525.js +179 -0
- package/dist/canvas/chunks/index-vv56h019.js +2 -0
- package/dist/canvas/chunks/index-w2mra17t.js +207 -0
- package/dist/canvas/chunks/index-wgv7en21.js +232 -0
- package/dist/canvas/chunks/index-yw8h9vha.js +157 -0
- package/dist/canvas/chunks/info-DKCQHKI2-wpzs6sz3.js +1 -0
- package/dist/canvas/chunks/infoDiagram-6WML65LV-v1yvggqj.js +2 -0
- package/dist/canvas/chunks/ishikawaDiagram-WSZJBQD7-5hnq1a9p.js +70 -0
- package/dist/canvas/chunks/journeyDiagram-NVQOT4AX-zjcffveh.js +139 -0
- package/dist/canvas/chunks/kanban-definition-27J2QSJJ-dakqtfp1.js +89 -0
- package/dist/canvas/chunks/katex-dmg8k4zm.js +257 -0
- package/dist/canvas/chunks/mermaid.core-j2geswrd.js +12 -0
- package/dist/canvas/chunks/mindmap-definition-FAOFIHXS-142xhr3k.js +96 -0
- package/dist/canvas/chunks/packet-7NZHBO7P-xn439f0s.js +1 -0
- package/dist/canvas/chunks/pegDiagram-VL7TDLO6-5wvk7vsd.js +1 -0
- package/dist/canvas/chunks/pie-RZYD4A2V-0kf16rwh.js +1 -0
- package/dist/canvas/chunks/pieDiagram-7S7Q4E2Y-ztdhwycc.js +39 -0
- package/dist/canvas/chunks/quadrantDiagram-CIZ2JOQS-c5p9gmg6.js +7 -0
- package/dist/canvas/chunks/radar-I7S5WNFK-0g2pz36t.js +1 -0
- package/dist/canvas/chunks/railroad-3IZDKUUU-fcaran6j.js +1 -0
- package/dist/canvas/chunks/railroad-abnf-AHOZXSZD-wgdya41q.js +1 -0
- package/dist/canvas/chunks/railroad-ebnf-EBAXGLYW-gy07a4ka.js +1 -0
- package/dist/canvas/chunks/railroad-peg-LSFZ7HO6-ewk6wtkh.js +1 -0
- package/dist/canvas/chunks/railroadDiagram-AXF67PYL-xkmqkjwf.js +1 -0
- package/dist/canvas/chunks/requirementDiagram-LRYGKXZP-9wm2dyaw.js +84 -0
- package/dist/canvas/chunks/sankeyDiagram-W5VNT64P-2w19etgb.js +40 -0
- package/dist/canvas/chunks/sequenceDiagram-SI44F4Z6-0jn0vwmz.js +162 -0
- package/dist/canvas/chunks/sizeCapture-X5ZJPWSS-x75epwdq.js +1 -0
- package/dist/canvas/chunks/stateDiagram-OKZ733FA-schjpy6d.js +1 -0
- package/dist/canvas/chunks/stateDiagram-v2-UEYNNEHI-k8sfp2e7.js +1 -0
- package/dist/canvas/chunks/swimlanes-SLNWSIFB-gkw4xce3.js +1 -0
- package/dist/canvas/chunks/swimlanesDiagram-ULZ7WXOC-nqysw67j.js +8 -0
- package/dist/canvas/chunks/timeline-definition-Z64GVDOM-x7nkcy01.js +120 -0
- package/dist/canvas/chunks/treeView-QDETBFTQ-cesw6gp0.js +1 -0
- package/dist/canvas/chunks/treemap-6X3UGDF4-zdv4knp9.js +1 -0
- package/dist/canvas/chunks/vennDiagram-T6HMQDX7-x8dqn9yf.js +34 -0
- package/dist/canvas/chunks/wardley-OPB4EBWU-44pdddez.js +1 -0
- package/dist/canvas/chunks/wardleyDiagram-T6FBY63Y-t1j52t9r.js +78 -0
- package/dist/canvas/chunks/xychartDiagram-ELKLHX3M-38t16pme.js +7 -0
- package/dist/canvas/global.css +389 -229
- package/dist/canvas/index.js +141 -211
- package/dist/canvas/mcp-app.html +4205 -554
- package/dist/canvas/mermaid-entry.js +338 -338
- package/dist/canvas/surface-theme.css +6 -6
- package/dist/json-render/index.css +1 -1
- package/dist/json-render/index.js +49 -49
- package/dist/types/client/canvas/BarHint.d.ts +5 -3
- package/dist/types/client/canvas/CanvasNode.d.ts +0 -11
- package/dist/types/client/canvas/EdgeLayer.d.ts +1 -2
- package/dist/types/client/canvas/auto-fit.d.ts +4 -5
- package/dist/types/client/mermaid-entry.d.ts +1 -2
- package/dist/types/client/mermaid-render.d.ts +1 -0
- package/dist/types/client/nodes/BoardNode.d.ts +1 -1
- package/dist/types/client/nodes/ExtAppFrame.d.ts +7 -90
- package/dist/types/client/nodes/McpAppNode.d.ts +1 -25
- package/dist/types/client/nodes/MermaidNode.d.ts +1 -8
- package/dist/types/client/nodes/ViewerFrame.d.ts +29 -0
- package/dist/types/client/nodes/ViewerHost.d.ts +6 -0
- package/dist/types/client/nodes/iframe-document-url.d.ts +3 -9
- package/dist/types/client/nodes/primitive-copy.d.ts +5 -0
- package/dist/types/client/nodes/use-iframe-content-height.d.ts +1 -1
- package/dist/types/client/nodes/use-surface-frame.d.ts +4 -6
- package/dist/types/client/nodes/viewer-runtime-state.d.ts +2 -1
- package/dist/types/client/state/canvas-store.d.ts +3 -1
- package/dist/types/client/state/intent-bridge.d.ts +1 -0
- package/dist/types/client/state/presentation.d.ts +17 -6
- package/dist/types/json-render/server.d.ts +2 -1
- package/dist/types/server/canvas-state.d.ts +2 -0
- package/dist/types/server/index.d.ts +10 -5
- package/dist/types/server/operations/ops/boards.d.ts +0 -1
- package/dist/types/server/tour-control.d.ts +13 -3
- package/dist/types/shared/ax-surface-protocol.d.ts +0 -9
- package/dist/types/shared/tour.d.ts +8 -0
- package/docs/design/Chrome.dc.html +32 -6
- package/docs/design/Types1.dc.html +3 -2
- package/docs/design/Types2.dc.html +1 -1
- package/docs/design/Types3.dc.html +1 -1
- package/docs/design/Zoom.dc.html +37 -60
- package/docs/design/canvas.json +1 -1
- package/docs/design.md +169 -4
- package/docs/http-api.md +51 -1
- package/docs/mcp.md +8 -0
- package/docs/node-types.md +38 -3
- package/docs/plans/plan-009-tech-debt-backlog.md +2 -2
- package/docs/plans/plan-019-post-0.9-roadmap.md +283 -11
- package/docs/product-vision-2026-09.md +9 -0
- package/package.json +2 -2
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
- package/plugins/pmx-canvas/plugin.json +1 -1
- package/plugins/pmx-canvas/runtime.json +1 -1
- package/plugins/pmx-canvas/tools.json +246 -108
- package/skills/pmx-canvas/SKILL.md +11 -18
- package/skills/pmx-canvas/references/full-reference.md +9 -4
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
- package/skills/published-consumer-e2e/scripts/run-published-consumer-e2e.sh +3 -5
- package/src/client/canvas/BarHint.tsx +6 -3
- package/src/client/canvas/CanvasNode.tsx +34 -47
- package/src/client/canvas/CanvasViewport.tsx +6 -7
- package/src/client/canvas/ContextMenu.tsx +63 -3
- package/src/client/canvas/EdgeLayer.tsx +365 -169
- package/src/client/canvas/ExpandedNodeOverlay.tsx +1 -2
- package/src/client/canvas/Presentation.tsx +53 -3
- package/src/client/canvas/TopBar.tsx +24 -9
- package/src/client/canvas/auto-fit.ts +9 -11
- package/src/client/canvas/canvas-area.ts +1 -1
- package/src/client/canvas/use-focus-trap.ts +6 -1
- package/src/client/mermaid-entry.ts +6 -20
- package/src/client/mermaid-render.ts +39 -0
- package/src/client/nodes/AxStepControls.tsx +45 -69
- package/src/client/nodes/BoardNode.tsx +65 -9
- package/src/client/nodes/ContextNode.tsx +88 -396
- package/src/client/nodes/ExtAppFrame.tsx +283 -1462
- package/src/client/nodes/FileNode.tsx +92 -81
- package/src/client/nodes/HtmlNode.tsx +8 -36
- package/src/client/nodes/LedgerNode.tsx +31 -17
- package/src/client/nodes/MarkdownNode.tsx +8 -17
- package/src/client/nodes/McpAppNode.tsx +48 -154
- package/src/client/nodes/MermaidNode.tsx +80 -69
- package/src/client/nodes/PromptNode.tsx +12 -14
- package/src/client/nodes/ResponseNode.tsx +8 -6
- package/src/client/nodes/StatusNode.tsx +22 -7
- package/src/client/nodes/StatusSummary.tsx +5 -3
- package/src/client/nodes/TraceNode.tsx +8 -8
- package/src/client/nodes/ViewerFrame.tsx +262 -0
- package/src/client/nodes/ViewerHost.tsx +41 -0
- package/src/client/nodes/WebpageNode.tsx +22 -24
- package/src/client/nodes/iframe-document-url.ts +20 -27
- package/src/client/nodes/primitive-copy.ts +97 -0
- package/src/client/nodes/use-iframe-content-height.ts +34 -10
- package/src/client/nodes/use-surface-frame.ts +22 -11
- package/src/client/nodes/viewer-runtime-state.ts +41 -35
- package/src/client/state/canvas-store.ts +18 -12
- package/src/client/state/intent-bridge.ts +1 -0
- package/src/client/state/presentation.ts +135 -15
- package/src/client/state/sse-bridge.ts +18 -19
- package/src/client/theme/global.css +389 -229
- package/src/client/theme/surface-theme.css +6 -6
- package/src/json-render/charts/tufte-components.tsx +44 -2
- package/src/json-render/renderer/index.css +62 -2
- package/src/json-render/renderer/index.tsx +31 -7
- package/src/json-render/server.ts +3 -2
- package/src/server/board-export.ts +35 -24
- package/src/server/canvas-geometry.ts +1 -0
- package/src/server/canvas-state.ts +5 -0
- package/src/server/demo-state.json +106 -100
- package/src/server/html-primitives.ts +3 -9
- package/src/server/html-surface.ts +8 -0
- package/src/server/index.ts +19 -9
- package/src/server/operations/mcp-contracts.ts +17 -2
- package/src/server/operations/ops/boards.ts +1 -3
- package/src/server/operations/ops/viewport.ts +11 -9
- package/src/server/server.ts +7 -59
- package/src/server/tour-control.ts +66 -6
- package/src/shared/ax-surface-protocol.ts +0 -11
- package/src/shared/content-height-reporter.ts +4 -3
- package/src/shared/tour.ts +8 -0
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
body{margin:0}
|
|
14
14
|
</style>
|
|
15
15
|
</helmet>
|
|
16
|
-
<div style="width: 1440px; height:
|
|
16
|
+
<div style="width: 1440px; height: 1360px; box-sizing: border-box; padding: 40px 48px; background: #081524; color: #e6eef7; font-family: 'IBM Plex Sans', system-ui, sans-serif; font-size: 13px; line-height: 1.5; display: grid; grid-template-columns: 500px repeat(2, minmax(0, 1fr)); gap: 40px">
|
|
17
17
|
|
|
18
18
|
<section style="display: flex; flex-direction: column; gap: 14px">
|
|
19
19
|
<div><h2 style="margin: 0; font-size: 15px; font-weight: 600">7 · Tool rail in a 690px-tall window</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">20 buttons need 850px. Settings-type tools move into one menu.</p></div>
|
|
@@ -62,7 +62,7 @@ body{margin:0}
|
|
|
62
62
|
</section>
|
|
63
63
|
|
|
64
64
|
<section style="display: flex; flex-direction: column; gap: 14px">
|
|
65
|
-
<div><h2 style="margin: 0; font-size: 15px; font-weight: 600">8 · Node header</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">Expand and the context pin always show; ⋯ on hover opens the
|
|
65
|
+
<div><h2 style="margin: 0; font-size: 15px; font-weight: 600">8 · Node header</h2><p style="margin: 2px 0 0; font-size: 12px; color: #8ea3bd">Expand and the context pin always show; ⋯ on hover or keyboard focus opens the node menu. Set as README lives here, becoming Remove as README on the current README. Edit stays visible below Markdown.</p></div>
|
|
66
66
|
|
|
67
67
|
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Today</span>
|
|
68
68
|
<div style="border-radius: 12px 12px 8px 8px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 0 0 1px rgba(244,197,66,0.3), 0 8px 24px rgba(244,197,66,0.1); overflow: hidden">
|
|
@@ -78,7 +78,8 @@ body{margin:0}
|
|
|
78
78
|
<div style="border-radius: 10px; border: 1px solid #1b2c44; background: #0f1d31; box-shadow: 0 1px 2px rgba(0,0,0,0.4), 0 6px 20px rgba(0,0,0,0.24); overflow: hidden">
|
|
79
79
|
<div style="display: flex; align-items: center; gap: 8px; height: 36px; padding: 0 8px 0 12px; border-bottom: 1px solid #1b2c44">
|
|
80
80
|
<svg width="16" height="16" viewBox="0 0 24 24" style="color: #8ea3bd; fill: none; stroke: currentColor; stroke-width: 1.6; stroke-linecap: round; stroke-linejoin: round"><path d="M6 5h12a2 2 0 0 1 2 2v10a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V7a2 2 0 0 1 2-2zM8 10h8M8 14h5"></path></svg>
|
|
81
|
-
<span style="flex: 1; font-size: 12px; font-weight: 600">PMX Canvas — guided tour</span>
|
|
81
|
+
<span style="flex: 1; min-width: 0; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; font-size: 12px; font-weight: 600">PMX Canvas — guided tour</span>
|
|
82
|
+
<span style="flex-shrink: 0; font-size: 11px; color: #8ea3bd">README</span>
|
|
82
83
|
<button aria-label="Expand (Enter)" style="width: 22px; height: 22px; border: 0; border-radius: 6px; padding: 0; background: transparent; color: #b9c6d6; display: flex; align-items: center; justify-content: center; flex-shrink: 0"><svg width="13" height="13" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round"><path d="M14 4h6v6M20 4l-7 7M10 20H4v-6M4 20l7-7"></path></svg></button>
|
|
83
84
|
<button aria-label="Add to context (P)" style="width: 18px; height: 18px; box-sizing: border-box; border: 1.5px solid #6b7d94; border-radius: 999px; padding: 0; background: transparent; color: #b9c6d6; display: flex; align-items: center; justify-content: center; flex-shrink: 0"><svg width="10" height="10" viewBox="0 0 24 24" style="fill: none; stroke: currentColor; stroke-width: 2.4; stroke-linecap: round; stroke-linejoin: round"><path d="M9 4h6l-.8 5.5 2.8 3H7l2.8-3zM12 12.5V20"></path></svg></button>
|
|
84
85
|
<!-- Reserve the hover-action slots: revealing More/Close must not move the pin. -->
|
|
@@ -111,7 +112,8 @@ body{margin:0}
|
|
|
111
112
|
<div style="height: 236px; display: flex; flex-direction: column; border: 1px solid #1b2c44; border-radius: 10px; overflow: hidden; background: #0f1d31">
|
|
112
113
|
<div style="flex-shrink: 0; height: 36px; display: flex; align-items: center; padding: 0 12px; border-bottom: 1px solid #1b2c44; font-size: 12px; font-weight: 600">Research index</div>
|
|
113
114
|
<div style="flex: 1; min-height: 0; display: flex; flex-direction: column">
|
|
114
|
-
<div style="flex: 1; min-height: 0; padding: 10px 12px; overflow: auto; font-size: 13px; color: #b9c6d6">Read the source, then follow <a href="#reference-footer" style="color: #e6eef7">the evidence</a
|
|
115
|
+
<div style="flex: 1; min-height: 0; padding: 10px 12px; overflow: auto; font-size: 13px; color: #b9c6d6">Read the source, then follow <a href="#reference-footer" style="color: #e6eef7">the evidence</a>.</div>
|
|
116
|
+
<div style="flex-shrink: 0; border-top: 1px solid #1b2c44; padding: 6px 36px 6px 8px; text-align: right"><button style="border: 1px solid transparent; border-radius: 6px; padding: 4px 8px; background: transparent; color: #8ea3bd; font: 500 11px 'IBM Plex Sans', sans-serif">Edit</button></div>
|
|
115
117
|
<div id="reference-footer" role="region" aria-label="Cross-board references" tabindex="0" style="flex-shrink: 0; max-height: min(40%, 132px); overflow: auto; overscroll-behavior: contain">
|
|
116
118
|
<div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Interview notes</div>
|
|
117
119
|
<div style="padding: 6px 12px; border-top: 1px solid #1b2c44; font-size: 12px; color: #b9c6d6">↗ references: Research / Findings</div>
|
|
@@ -174,11 +176,35 @@ body{margin:0}
|
|
|
174
176
|
<span style="font-size: 11px; color: #8ea3bd">Fit and focus keep a lane clear for floating chrome.</span>
|
|
175
177
|
</div>
|
|
176
178
|
</div>
|
|
179
|
+
|
|
180
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
181
|
+
<h2 style="margin: 0; font-size: 15px; font-weight: 600">Present · hover / keyboard focus</h2>
|
|
182
|
+
<p style="margin: 0; font-size: 11px; color: #8ea3bd">2026-10-25: the button describes this tooltip with aria-describedby. In the narrow ⋯ menu, the same text appears in flow below Present so the scrolling menu cannot clip it.</p>
|
|
183
|
+
<div role="tooltip" style="max-width: 240px; padding: 10px 12px; border: 1px solid #2a4566; border-radius: 10px; background: #0f1d31; color: #b9c6d6; font-size: 12px; line-height: 1.35">
|
|
184
|
+
<strong style="color: #e6eef7">Present board</strong>
|
|
185
|
+
<p>A presentation follows either a saved tour or the board’s groups.</p>
|
|
186
|
+
<p>Saved tour: ask your agent to define the stops and their order. Each stop can focus on a card, a group, a rectangular area, or a specific camera position.</p>
|
|
187
|
+
<p style="margin-bottom: 0">No saved tour: every group becomes a stop, ordered top-to-bottom, then left-to-right. It doesn’t automatically visit every card.</p>
|
|
188
|
+
</div>
|
|
189
|
+
</div>
|
|
190
|
+
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
191
|
+
<h2 style="margin: 0; font-size: 15px; font-weight: 600">Presentation · navigation</h2>
|
|
192
|
+
<p style="margin: 0; font-size: 11px; color: #8ea3bd">Owner decision, 2026-10-25: Back and Next sit beside Exit at the top-right. Instructions appear only in hover/focus tooltips, never in a corner panel. End buttons stay focusable but unavailable; their descriptions remain accessible.</p>
|
|
193
|
+
<div style="position: relative; height: 180px; border: 1px solid #1b2c44; border-radius: 10px; background: #081524">
|
|
194
|
+
<div style="position: absolute; top: 16px; right: 16px; display: flex; gap: 8px">
|
|
195
|
+
<button style="padding: 8px 14px; min-height: 38px; border: 1px solid #8ea3bd; border-radius: 8px; background: #0f1d31; color: #e6eef7; font: inherit; font-weight: 600; opacity: .5" aria-disabled="true">Back</button>
|
|
196
|
+
<button style="padding: 8px 14px; min-height: 38px; border: 1px solid #8ea3bd; border-radius: 8px; background: #0f1d31; color: #e6eef7; font: inherit; font-weight: 600">Next</button>
|
|
197
|
+
<button style="padding: 8px 14px; min-height: 38px; border: 1px solid #8ea3bd; border-radius: 8px; background: #0f1d31; color: #e6eef7; font: inherit; font-weight: 600">Exit presentation</button>
|
|
198
|
+
</div>
|
|
199
|
+
<div style="position: absolute; top: 66px; right: 16px; width: 168px; padding: 10px 12px; border: 1px solid #2a4566; border-radius: 10px; background: #0f1d31; box-shadow: 0 14px 36px #0006; font-size: 12px"><strong>Next stop</strong><br><span style="color: #8ea3bd">→ / ↓ / Space</span></div>
|
|
200
|
+
</div>
|
|
201
|
+
<p style="margin: 0; font-size: 11px; color: #8ea3bd">Back: Previous stop, ← / ↑. Next: Next stop, → / ↓ / Space. Exit: Exit presentation, Esc. Fit clears the top controls; exact camera targets and recording remain exact.</p>
|
|
202
|
+
</div>
|
|
177
203
|
</section>
|
|
178
204
|
|
|
179
205
|
</div>
|
|
180
206
|
</x-dc>
|
|
181
|
-
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":
|
|
207
|
+
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":1360}}'>
|
|
182
208
|
class Component extends DCLogic {
|
|
183
209
|
renderVals() {
|
|
184
210
|
var P = {
|
|
@@ -245,7 +271,7 @@ class Component extends DCLogic {
|
|
|
245
271
|
optIn('Trace', 'Show execution traces. Turning off keeps existing traces and never starts an agent.', false, false),
|
|
246
272
|
setting('Send feedback', '', 'Share feedback about PMX Canvas.')
|
|
247
273
|
];
|
|
248
|
-
var nodeMenu = [m('Focus', ''), m('Rename…', ''), m('Collapse', ''), m('Open in new tab', '', true), msep, m('Delete', '⌫')];
|
|
274
|
+
var nodeMenu = [m('Focus', ''), m('Rename…', ''), m('Collapse', ''), m('Open in new tab', ''), msep, m('Set as README', '', true), msep, m('Delete', '⌫')];
|
|
249
275
|
var oldIcons = [{ d: P.ctx }, { d: P.ask }, { d: P.open }, { d: P.expand }, { d: P.chevron }, { d: P.close }];
|
|
250
276
|
return { railToday: railToday, railNew: railNew, settings: settings, nodeMenu: nodeMenu, oldIcons: oldIcons };
|
|
251
277
|
}
|
|
@@ -22,7 +22,7 @@ body{margin:0}
|
|
|
22
22
|
</div>
|
|
23
23
|
|
|
24
24
|
<div style="{{s.row}}">
|
|
25
|
-
<div><div style="{{s.type}}">markdown</div><p style="{{s.what}}">Body 11 → 12px.
|
|
25
|
+
<div><div style="{{s.type}}">markdown</div><p style="{{s.what}}">Body 11 → 12px. Set as README moves into ⋯, becoming Remove as README when assigned. A quiet README header word stays visible on the designated card, including heading display (Chrome §8). Edit stays visible; double-click still edits. Heading display has no footer.</p></div>
|
|
26
26
|
<div style="{{o.node}}">
|
|
27
27
|
<div style="{{o.head}}"><svg width="16" height="16" viewBox="0 0 24 24" style="{{o.icon}} color: #4BBCFF"><path d="{{i.note}}"></path></svg><span style="{{o.title}}">PMX Canvas — guided tour</span><span style="{{o.ctl}}">⤢⌄×</span></div>
|
|
28
28
|
<div style="padding: 10px 14px; display: flex; flex-direction: column; gap: 6px">
|
|
@@ -39,6 +39,7 @@ body{margin:0}
|
|
|
39
39
|
<div style="color: #b9c6d6">An infinite spatial canvas that agents drive over MCP, HTTP or the Bun SDK — and that humans steer by pinning nodes.</div>
|
|
40
40
|
<div style="color: #b9c6d6">• Pin a node in the browser<br>• The agent reads it from <code style="{{n.code}}">canvas://pinned-context</code></div>
|
|
41
41
|
</div>
|
|
42
|
+
<div style="border-top: 1px solid #1b2c44; padding: 6px 36px 6px 8px; text-align: right"><button style="border: 1px solid transparent; border-radius: 6px; padding: 4px 8px; background: transparent; color: #8ea3bd; font: 500 11px 'IBM Plex Sans', sans-serif">Edit</button></div>
|
|
42
43
|
</div>
|
|
43
44
|
</div>
|
|
44
45
|
|
|
@@ -120,7 +121,7 @@ body{margin:0}
|
|
|
120
121
|
</div>
|
|
121
122
|
|
|
122
123
|
<div style="{{s.row}}">
|
|
123
|
-
<div><div style="{{s.type}}">file</div><p style="{{s.what}}">The extra toolbar row folds into the header (path · lines). Code 10 → 12px with dim line numbers.</p></div>
|
|
124
|
+
<div><div style="{{s.type}}">file</div><p style="{{s.what}}">The extra toolbar row folds into the header (path · lines). Only metadata clips as space tightens; Reload and AX evidence hints remain visible on hover/focus. Code 10 → 12px with dim line numbers.</p></div>
|
|
124
125
|
<div style="{{o.node}}">
|
|
125
126
|
<div style="{{o.head}}"><svg width="16" height="16" viewBox="0 0 24 24" style="{{o.icon}} color: #4BBCFF"><path d="{{i.file}}"></path></svg><span style="{{o.title}}">node-sizes.ts</span><span style="{{o.ctl}}">⤢⌄×</span></div>
|
|
126
127
|
<div style="display: flex; align-items: center; gap: 6px; padding: 4px 12px; border-bottom: 1px solid #1b2c44; font-family: 'IBM Plex Mono', monospace; font-size: 9px; color: #8ea3bd"><span style="padding: 1px 4px; border-radius: 3px; background: #13243b; color: #4BBCFF">TS</span><span>46 lines</span><span style="color: #5c6b80">src/shared/node-sizes.ts</span></div>
|
|
@@ -90,7 +90,7 @@ body{margin:0}
|
|
|
90
90
|
</div>
|
|
91
91
|
|
|
92
92
|
<div style="{{s.row}}">
|
|
93
|
-
<div><div style="{{s.type}}">html</div><p style="{{s.what}}">The white outline around the frame goes. The page gets the canvas tokens, so it sits on the node surface.</p></div>
|
|
93
|
+
<div><div style="{{s.type}}">html</div><p style="{{s.what}}">The white outline around the frame goes. The page gets the canvas tokens, so it sits on the node surface. Owner decision, 2026-10-25: generated primitives have no shared header copy buttons. Copy JSON lives in the card's ⋯ menu and includes live edits. Copy prompt is removed; primitive-specific copy controls remain.</p></div>
|
|
94
94
|
<div style="{{o.node}}">
|
|
95
95
|
<div style="{{o.head}}"><svg width="16" height="16" viewBox="0 0 24 24" style="{{o.icon}} color: #4BBCFF"><path d="{{i.html}}"></path></svg><span style="{{o.title}}">Release gates</span><span style="{{o.ctl}}">↗⤢⌄×</span></div>
|
|
96
96
|
<div style="flex: 1; margin: 8px; border: 1px solid #f2f2f2; border-radius: 2px; padding: 10px 12px; display: flex; flex-direction: column; gap: 5px">
|
|
@@ -49,7 +49,7 @@ body{margin:0}
|
|
|
49
49
|
</div>
|
|
50
50
|
|
|
51
51
|
<div style="{{s.row}}">
|
|
52
|
-
<div><div style="{{s.type}}">graph</div><p style="{{s.what}}">Chart sits on the node surface. The title isn't repeated inside; the chart type becomes header meta.</p></div>
|
|
52
|
+
<div><div style="{{s.type}}">graph</div><p style="{{s.what}}">Chart sits on the node surface. The title isn't repeated inside; the chart type becomes header meta. Close slopegraph labels separate by 14px when space permits; points stay at their values, with short same-ink leaders.</p><svg width="200" height="60" role="img" aria-label="Close slopegraph labels, values unchanged"><path d="M10 42L70 20M10 52L70 26L75 34" fill="none" stroke="#4BBCFF" stroke-width="1.5"></path><circle cx="70" cy="20" r="2.5" fill="#4BBCFF"></circle><circle cx="70" cy="26" r="2.5" fill="#4BBCFF"></circle><text x="78" y="20" dominant-baseline="central" fill="#e6eef7" font-size="11">59 cli</text><text x="78" y="34" dominant-baseline="central" fill="#e6eef7" font-size="11">58 client</text></svg></div>
|
|
53
53
|
<div style="{{o.node}}">
|
|
54
54
|
<div style="{{o.head}}"><svg width="16" height="16" viewBox="0 0 24 24" style="{{o.icon}} color: #f4c542"><path d="{{i.chart}}"></path></svg><span style="{{o.title}}">bar — merged PRs per week</span><span style="{{o.ctl}}">↗⤢⌄×</span></div>
|
|
55
55
|
<div style="flex: 1; margin: 0 8px 8px; position: relative; background: #000000; border-radius: 8px; padding: 10px 12px; font-family: system-ui, sans-serif">
|
package/docs/design/Zoom.dc.html
CHANGED
|
@@ -2,79 +2,56 @@
|
|
|
2
2
|
<html lang="en">
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="utf-8">
|
|
5
|
-
<title>
|
|
5
|
+
<title>Native spatial zoom</title>
|
|
6
6
|
<script src="./support.js"></script>
|
|
7
7
|
</head>
|
|
8
8
|
<body>
|
|
9
9
|
<x-dc>
|
|
10
10
|
<helmet>
|
|
11
|
-
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+
|
|
12
|
-
<style>
|
|
13
|
-
body{margin:0}
|
|
14
|
-
</style>
|
|
11
|
+
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=IBM+Plex+Sans:wght@400;500;600&display=swap">
|
|
12
|
+
<style>body{margin:0}</style>
|
|
15
13
|
</helmet>
|
|
16
|
-
<div style="width:
|
|
17
|
-
<
|
|
18
|
-
<
|
|
19
|
-
|
|
20
|
-
<
|
|
21
|
-
<
|
|
22
|
-
<
|
|
23
|
-
<
|
|
24
|
-
<
|
|
14
|
+
<div style="width:1440px;height:640px;box-sizing:border-box;padding:40px 48px;background:#081524;color:#e6eef7;font-family:'IBM Plex Sans',system-ui,sans-serif;font-size:13px;line-height:1.5">
|
|
15
|
+
<h2 style="margin:0;font-size:20px;font-weight:600">11 · Keep the native board at every zoom</h2>
|
|
16
|
+
<p style="color:#8ea3bd">Maintainer decision, 2026-10-25. The same positions, sizes, groups, connections and contents scale together. No alternate grid or content enlargement.</p>
|
|
17
|
+
<div style="display:flex;gap:24px;margin-top:28px">
|
|
18
|
+
<sc-for list="{{views}}" as="view" hint-placeholder-count="3">
|
|
19
|
+
<section style="width:432px">
|
|
20
|
+
<h3 style="font-size:14px">{{view.label}}</h3>
|
|
21
|
+
<svg width="432" height="380" viewBox="0 0 432 380" style="border:1px solid #1b2c44;border-radius:10px;background:#081524">
|
|
22
|
+
<g transform="translate(16 44)">
|
|
23
|
+
<g transform="scale({{view.scale}})">
|
|
24
|
+
<rect x="0" y="0" width="396" height="308" rx="8" fill="none" stroke="#536c88"/>
|
|
25
|
+
<text x="12" y="22" fill="#e6eef7" font-size="16">Release evidence</text>
|
|
26
|
+
<path d="M182 128 L218 218" stroke="#6b7d94" stroke-width="2" fill="none"/>
|
|
27
|
+
<path d="M211 213 L218 218 L218 210" stroke="#6b7d94" stroke-width="2" fill="none"/>
|
|
28
|
+
<g transform="translate(12 36)">
|
|
29
|
+
<rect width="170" height="154" rx="8" fill="#0f1d31" stroke="#1b2c44"/>
|
|
30
|
+
<text x="12" y="22" fill="#e6eef7" font-size="{{view.titleSize}}">Build durations</text>
|
|
31
|
+
<path d="M14 126 L45 99 L77 110 L110 72 L153 84" fill="none" stroke="#62c4b8" stroke-width="3"/>
|
|
32
|
+
<path d="M14 44 V138 H156" fill="none" stroke="#536c88"/>
|
|
33
|
+
<text x="16" y="59" fill="#8ea3bd" font-size="11">37 → 19 minutes</text>
|
|
34
|
+
</g>
|
|
35
|
+
<g transform="translate(218 146)">
|
|
36
|
+
<rect width="166" height="146" rx="8" fill="#0f1d31" stroke="#1b2c44"/>
|
|
37
|
+
<text x="12" y="22" fill="#e6eef7" font-size="{{view.titleSize}}">Release gates</text>
|
|
38
|
+
<text x="12" y="56" fill="#e6eef7" font-size="13">✓ Tests passed</text>
|
|
39
|
+
<text x="12" y="82" fill="#e6eef7" font-size="13">✓ Review complete</text>
|
|
40
|
+
<text x="12" y="108" fill="#8ea3bd" font-size="12">Source: build report</text>
|
|
41
|
+
</g>
|
|
42
|
+
</g>
|
|
43
|
+
</g>
|
|
44
|
+
</svg>
|
|
45
|
+
</section>
|
|
25
46
|
</sc-for>
|
|
26
|
-
<sc-for list="{{tiles}}" as="t" hint-placeholder-count="20">
|
|
27
|
-
<div style="position: absolute; left: {{t.x}}px; top: {{t.y}}px; width: 112px; height: 72px; box-sizing: border-box; border-radius: 4px; background: #0f1d31; border: 1px solid #1b2c44; overflow: hidden"><div style="height: 6px; background: #13243b"></div></div>
|
|
28
|
-
</sc-for>
|
|
29
|
-
<span style="position: absolute; right: 12px; bottom: 10px; font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #5c6b80">8%</span>
|
|
30
|
-
</div>
|
|
31
|
-
</div>
|
|
32
|
-
|
|
33
|
-
<div style="display: flex; flex-direction: column; gap: 8px">
|
|
34
|
-
<span style="font-size: 11px; font-weight: 500; letter-spacing: 0.06em; text-transform: uppercase; color: #6b7d94">Proposed</span>
|
|
35
|
-
<div style="position: relative; flex: 1; border-radius: 10px; border: 1px solid #1b2c44; overflow: hidden; background: #081524">
|
|
36
|
-
<sc-for list="{{sections}}" as="sct" hint-placeholder-count="2">
|
|
37
|
-
<div style="position: absolute; left: 24px; top: {{sct.yt}}px; font-size: 15px; font-weight: 600; line-height: 20px">{{sct.title}}</div>
|
|
38
|
-
</sc-for>
|
|
39
|
-
<sc-for list="{{tiles}}" as="t" hint-placeholder-count="20">
|
|
40
|
-
<div style="position: absolute; left: {{t.x}}px; top: {{t.y}}px; width: 112px; height: 72px; box-sizing: border-box; padding: 8px 10px; border-radius: 6px; background: #0f1d31; border: 1px solid #1b2c44; display: flex; flex-direction: column; gap: 4px">
|
|
41
|
-
<div style="display: flex; align-items: center; gap: 6px"><svg width="14" height="14" viewBox="0 0 24 24" style="flex-shrink: 0; color: #8ea3bd; fill: none; stroke: currentColor; stroke-width: 1.8; stroke-linecap: round; stroke-linejoin: round"><path d="{{t.icon}}"></path></svg><span style="font-size: 11px; color: #8ea3bd">{{t.kind}}</span></div>
|
|
42
|
-
<span style="font-size: 12px; font-weight: 600; line-height: 1.3">{{t.title}}</span>
|
|
43
|
-
</div>
|
|
44
|
-
</sc-for>
|
|
45
|
-
<span style="position: absolute; right: 12px; bottom: 10px; font-family: 'IBM Plex Mono', monospace; font-size: 11px; color: #6b7d94">8%</span>
|
|
46
|
-
</div>
|
|
47
|
-
</div>
|
|
48
|
-
|
|
49
47
|
</div>
|
|
48
|
+
<p style="color:#8ea3bd">Automatic previews stay on the board. Zoom or expand to read details. Title text grows at most 1.2×; the header line and content space stay fixed.</p>
|
|
50
49
|
</div>
|
|
51
50
|
</x-dc>
|
|
52
51
|
<script type="text/x-dc" data-dc-script data-props='{"$preview":{"width":1440,"height":640}}'>
|
|
53
52
|
class Component extends DCLogic {
|
|
54
53
|
renderVals() {
|
|
55
|
-
|
|
56
|
-
var html = 'M8 8l-4 4 4 4M16 8l4 4-4 4M13.5 5l-3 14';
|
|
57
|
-
var charts = [
|
|
58
|
-
['line', 'p95 latency'], ['bar', 'Merged PRs'], ['area', 'Nodes created'], ['pie', 'Node types'], ['stacked', 'CI minutes'],
|
|
59
|
-
['composed', 'Throughput'], ['scatter', 'PR size'], ['radar', 'Coverage'], ['sparkline', 'Build time'], ['bullet', 'Release KPIs']
|
|
60
|
-
];
|
|
61
|
-
var prims = [
|
|
62
|
-
['html', 'Choice grid'], ['html', 'Plan timeline'], ['html', 'Review sheet'], ['html', 'PR write-up'], ['html', 'System map'],
|
|
63
|
-
['html', 'Walkthrough'], ['html', 'Design sheet'], ['html', 'Component gallery'], ['html', 'Flowchart'], ['html', 'Triage board']
|
|
64
|
-
];
|
|
65
|
-
var sections = [
|
|
66
|
-
{ y: 22, yt: 18, title: '④ Charts' },
|
|
67
|
-
{ y: 222, yt: 218, title: '⑦ HTML primitives' }
|
|
68
|
-
];
|
|
69
|
-
var tiles = [];
|
|
70
|
-
function place(list, top, icon) {
|
|
71
|
-
list.forEach(function (it, i) {
|
|
72
|
-
tiles.push({ x: 24 + (i % 5) * 122, y: top + Math.floor(i / 5) * 82, kind: it[0], title: it[1], icon: icon });
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
place(charts, 50, chart);
|
|
76
|
-
place(prims, 250, html);
|
|
77
|
-
return { sections: sections, tiles: tiles };
|
|
54
|
+
return { views: [{ label: '100%', scale: 1, titleSize: 12 }, { label: '39%', scale: 0.39, titleSize: 14.4 }, { label: '20%', scale: 0.2, titleSize: 14.4 }] };
|
|
78
55
|
}
|
|
79
56
|
}
|
|
80
57
|
</script>
|
package/docs/design/canvas.json
CHANGED
package/docs/design.md
CHANGED
|
@@ -87,8 +87,8 @@ Components reference tokens only. Raw colour values live only in the theme files
|
|
|
87
87
|
- Tints are derived — `color-mix(in srgb, var(--c-pin) 12%, transparent)` — so the 22 alpha
|
|
88
88
|
copies, `--c-warn-alt` and `--c-glow-accent` go.
|
|
89
89
|
- `--c-thinking` becomes `--c-agent`.
|
|
90
|
-
- **Kinds carry no colour.** Type icons use `--c-muted`; the glyph tells the kind
|
|
91
|
-
|
|
90
|
+
- **Kinds carry no colour.** Type icons use `--c-muted`; the glyph tells the kind.
|
|
91
|
+
Minimap rects and group-chip kind dots are neutral, and
|
|
92
92
|
only meaning colours mark them (pinned, agent at work). `KIND_COLOR`, `--kind-accent` and
|
|
93
93
|
`--c-purple` go. Nine kind hues cannot all stay clear of ten meaning colours in nine themes,
|
|
94
94
|
and every hue a kind borrows is one a meaning loses.
|
|
@@ -141,7 +141,7 @@ the same change.
|
|
|
141
141
|
| [`Flows.dc.html`](design/Flows.dc.html) | Data lineage with staleness, what a finding rests on, opening a group | 3, 5 |
|
|
142
142
|
| [`Uses.dc.html`](design/Uses.dc.html) | One relation layer for research, dependencies, decisions and agent flows | 3 |
|
|
143
143
|
| [`Types1.dc.html`](design/Types1.dc.html)–[`Types3.dc.html`](design/Types3.dc.html) | Every node type, today vs proposed | 0, 4 |
|
|
144
|
-
| [`Zoom.dc.html`](design/Zoom.dc.html) |
|
|
144
|
+
| [`Zoom.dc.html`](design/Zoom.dc.html) | Native spatial scaling at every zoom, maintainer override 2026-10-25 | 4 |
|
|
145
145
|
| [`Pane600.dc.html`](design/Pane600.dc.html) | Home and a board at the narrow end, 600 px | all |
|
|
146
146
|
| [`Vision.dc.html`](design/Vision.dc.html) | How each design area maps to the vision, and the open decisions | — |
|
|
147
147
|
|
|
@@ -377,7 +377,7 @@ workflow. A demo of existing features must not be used to claim full sketch pari
|
|
|
377
377
|
| **1. Context made visible** — its curation evaluation moved to the end of the plan (2026-10-19) | Part 1 bet, moves 0a, 2, 7 | Surface `context_reads` (already recorded since 0.7.0: who read, which nodes were delivered) per node and per board as read / not read / changed since read, using revisions; who pinned; activity lens and session receipt from presence activity and revisions; board pins (`board_pins`, tiered brief, `canvas_board pin/unpin`) and Home's pinned-boards section | What the agent did with context, Nodes in context, Board pins, Home (Folders) | From the board alone, a person can answer "did the agent read what I pinned, and is its copy current?" The evaluation in `docs/evals/` reads the same data |
|
|
378
378
|
| **2. Connected memory views** — implemented, verification gates apply | Moves 0, 14 | One board/card projection for Home, links/backlinks, brief discovery and `canvas://graph{?focus,depth}`; saved wiki ID bindings, direct cross-board card edges, previous-board chains, persisted Map positions | Home Map, Home Graph (deviations below) | Map and Graph are generated from the library; orphans visible; works at 600 px and in a full window |
|
|
379
379
|
| **3. Relations layer** | Moves 0, 1, 13 | Edge `reason` and an open `kind` with a per-board vocabulary; relations carried in the brief's text form; "derived from" with staleness from provenance and recipes; relation queries for the inspector | Relations, Lineage, One relation layer | Hovering a node explains each link; a changed source turns downstream nodes amber; the agent's brief includes relations |
|
|
380
|
-
| **4. Frame host and viewers** | Moves 5, 9 | One frame host passing the full theme tokens; json-render defaults to the canvas theme with an opt-out for design experiments;
|
|
380
|
+
| **4. Frame host and viewers** | Moves 5, 9 | One frame host passing the full theme tokens; json-render defaults to the canvas theme with an opt-out for design experiments; native proportional canvas at every zoom | Node types 1–3, Zoom | Viewers use the canvas palette and fill their authored space; approaching a viewer mounts it automatically and retains its state when panning away; no alternate grid or lifetime preview cap |
|
|
381
381
|
| **5. Agent output and groups as pages** | Moves 3, 0 | Work items, gates and asks as nodes; make board / inline board; opening a group keeps its outside links | One relation layer (agent flow), Lineage (open a group) | Agent output is styled by the same shell and tokens; a group opened as a board shows its outside stubs |
|
|
382
382
|
| **Later: hosted version** | Part 4 (moved from Part 3, 2026-10-19) | Read-only link, comments, second writer, accounts and roles; org → team → personal scopes with configurable categories and per-user pins; built once for the ChatGPT Sites and later Cloudflare editions | HomeTeam is the earlier two-root look ahead; updated scope/category drawings are required before building, retaining explicit publication and locked cards for unreadable boards | Exports and shared views inherit the tokens; a viewer sees the same meaning colours; nothing personal reaches a wider audience without explicit publication |
|
|
383
383
|
|
|
@@ -630,6 +630,171 @@ curation evaluation after its remaining features. Local categories and lifecycle
|
|
|
630
630
|
without a model; Jev-style classification is optional longer-term assistance, not a dependency
|
|
631
631
|
of Wave 3 or the org/team/personal structure.
|
|
632
632
|
|
|
633
|
+
## 0.11 implementation notes
|
|
634
|
+
|
|
635
|
+
Chrome §9–10 and Types1–3 drive the section-heading, header, typography and viewer
|
|
636
|
+
pass. Fit and focus reserve a 44 px screen-space top lane. JSON viewers inherit the
|
|
637
|
+
named canvas palette; only duplicate root titles disappear. Mermaid renders inline.
|
|
638
|
+
File-header metadata may clip within its own text container, but Reload and AX
|
|
639
|
+
evidence actions and their hover/focus hints stay outside that clip (Types1).
|
|
640
|
+
The maintainer's 2026-10-25 decision supersedes the earlier reading-flow footer:
|
|
641
|
+
**Set as README** lives only in the card's ⋯ menu, becoming **Remove as README**
|
|
642
|
+
for the current README. The agent normally assigns it; this menu is the human override.
|
|
643
|
+
The designated card keeps a quiet, always-visible **README** word in its header,
|
|
644
|
+
including heading-display Markdown. It uses neutral metadata ink, not pin blue or
|
|
645
|
+
selection styling; the title yields before this identifier truncates.
|
|
646
|
+
Ordinary Markdown keeps its visible **Edit** action; heading display has no footer.
|
|
647
|
+
Chrome and Types1 reflect this decision. The menu takes keyboard focus, supports
|
|
648
|
+
arrows and Tab, and restores the opener on activation or Escape.
|
|
649
|
+
**Present** explains saved tours versus group-derived stops on hover and keyboard
|
|
650
|
+
focus, with an accessible description. The narrow ⋯ menu shows the same explanation
|
|
651
|
+
in flow below Present rather than clipping a floating tooltip. Chrome records the
|
|
652
|
+
owner's exact copy; no tour behavior changes. Its saved-tour instruction says
|
|
653
|
+
**ask your agent to define the stops**, not that a visual human tour editor exists.
|
|
654
|
+
During presentation, **Back** and **Next** sit beside **Exit presentation** at
|
|
655
|
+
the top-right, following the existing shared server cursor. The owner's final
|
|
656
|
+
placement decision puts instructions only in each button's hover/focus tooltip:
|
|
657
|
+
Previous stop (← / ↑), Next stop (→ / ↓ / Space), Exit presentation (Esc).
|
|
658
|
+
There is no lower-left instruction panel. Unavailable end buttons remain focusable
|
|
659
|
+
for their descriptions. Node/rectangle fitting reserves the controls' measured
|
|
660
|
+
height; explicit camera targets and deterministic recordings remain unchanged.
|
|
661
|
+
HTML primitives put **Copy JSON** in the card's ⋯ menu, not their inner header;
|
|
662
|
+
**Copy prompt** is removed. JSON comes from the current mounted document, including
|
|
663
|
+
unsaved interactive edits, through the nonce-bound sandbox bridge. Unloaded or
|
|
664
|
+
replaced documents and denied clipboard access report failure, not stale data or
|
|
665
|
+
success. Raw HTML and the custom presentation primitive have no JSON-export menu
|
|
666
|
+
action. Primitive-specific Copy diff, Copy SVG and similar controls stay in place.
|
|
667
|
+
The maintainer's 2026-10-25 correction rejects the experimental CSS zoom, content
|
|
668
|
+
enlargement and alternate overview. The original world matrix scales cards,
|
|
669
|
+
embedded contents, groups and connections proportionally at every zoom. Only title
|
|
670
|
+
text grows, up to 1.2× inside a fixed 22 px header line. Header controls, padding and
|
|
671
|
+
body space stay fixed in world pixels; enlarging the whole header would resize the
|
|
672
|
+
iframe viewport and reflow charts while zooming. Card bodies never counter-scale.
|
|
673
|
+
All cards share the same stacking and input boundary. A separate
|
|
674
|
+
ext-app portal was rejected in review because it covered higher cards, bypassed
|
|
675
|
+
pan gestures, and disappeared during presentation. The common world also owns
|
|
676
|
+
clipping when a dock resizes the canvas. Headed Linux WebKit reproduced CSS zoom
|
|
677
|
+
shrinking the iframe's internal layout and retaining stale dimensions through
|
|
678
|
+
zoom transitions. Restoring the matrix keeps inner widths stable in the same probe.
|
|
679
|
+
Native WKWebView compositor health remains unverified, not established by that result.
|
|
680
|
+
Automatic previews mount on first approach at any scale, then retain their
|
|
681
|
+
documents to preserve arbitrary app state. The rejected lifetime cap starved later
|
|
682
|
+
board regions. Memory now grows with visited viewers. Visible viewers start loading
|
|
683
|
+
automatically without a shared bootstrap queue or per-card clicks. A slow document
|
|
684
|
+
does not hold another card's loading slot.
|
|
685
|
+
Each loading replacement temporarily coexists with its painted document.
|
|
686
|
+
|
|
687
|
+
The demo gives ordinary standalone charts the full authored card height instead
|
|
688
|
+
of imposing a smaller plot-height cap. Compact chart types keep compact cards:
|
|
689
|
+
the 36 px sparkline sits in a 120 px card, four dot-plot rows in 240 px, three bullet
|
|
690
|
+
rows in 260 px, and the slopegraph in 300 px. These are demo authoring choices,
|
|
691
|
+
not enforced sizes on user cards. Explicit chart `height` still caps content,
|
|
692
|
+
independently of `nodeHeight`. Dashboard and form stacks explicitly use stretch
|
|
693
|
+
alignment; the catalog's start-aligned default is unchanged, as are compact action
|
|
694
|
+
buttons. Work-item controls must fit their authored cards without accidental
|
|
695
|
+
overflow or truncated status. Enlarging the demo to 440×300 did not meet that
|
|
696
|
+
requirement and is not acceptance evidence. The card body now scrolls only its
|
|
697
|
+
content when needed; step controls and Edit share one fixed footer row. The full
|
|
698
|
+
status word takes priority over the title. Steering input and send button wrap
|
|
699
|
+
together. Expanded documents keep their sticky footer. The demo returns to a
|
|
700
|
+
240 px height, with 360 and 440 px widths exercised in both Chromium and WebKit.
|
|
701
|
+
Bodies still shrink proportionally.
|
|
702
|
+
|
|
703
|
+
Static exports use the same embedded chart layout and named palettes, retain
|
|
704
|
+
heading display, and match the live 37 px card header. Fonts and shared palette
|
|
705
|
+
CSS are embedded for offline use. Saved positions, sizes and specs are unchanged;
|
|
706
|
+
live work controls are intentionally absent. Export is a separate acceptance
|
|
707
|
+
surface, not established by live canvas checks. Close slopegraph labels separate
|
|
708
|
+
without moving data endpoints; short same-ink leaders retain their association
|
|
709
|
+
(Types3). An explicitly overcrowded chart still requires adequate authored height.
|
|
710
|
+
|
|
711
|
+
Relation labels keep their curve midpoint when clear. Otherwise the pill and its
|
|
712
|
+
hit area move together to nearby open space, avoiding cards, group headers,
|
|
713
|
+
connection handles and earlier labels. A dashed leader in the relation's ink
|
|
714
|
+
ties it back to the curve. Card positions, curve routing and stacking do not
|
|
715
|
+
change. Font measurements determine pill width. Dense boards can still require
|
|
716
|
+
panning to a displaced label; labels remain hidden below the existing 35% floor.
|
|
717
|
+
|
|
718
|
+
`ViewerHost` owns preview admission, without a second positioning or recovery path.
|
|
719
|
+
`RefreshingViewerFrame` owns document loading, the painted replacement handoff and
|
|
720
|
+
Retry. HTML readiness and the ext-app protocol use that host; JSON additionally
|
|
721
|
+
restores its viewer-local state before promotion. The ext-app adapter no longer
|
|
722
|
+
has a separate paint/recovery ladder. Document preparation failures do not fall
|
|
723
|
+
back to another transport that the embedding probe already rejected.
|
|
724
|
+
Ext-app protocol bootstrap runs once after initialization, or after the loaded
|
|
725
|
+
document's bounded notification-only bootstrap interval. The host waits for
|
|
726
|
+
input/result delivery and paint before declaring it ready; bootstrap errors use
|
|
727
|
+
the same Retry as other loading failures.
|
|
728
|
+
Webpages show cached text until an explicit live-preview request; Mermaid
|
|
729
|
+
and native board thumbnails render inline. Mermaid's inline
|
|
730
|
+
and standalone/export renderers share their palette, serialization and sanitizer.
|
|
731
|
+
Inline rendering uses Mermaid's strict security mode and DOMPurify, including
|
|
732
|
+
sanitized `foreignObject` labels, instead of the old diagram iframe sandbox.
|
|
733
|
+
Mermaid is the exception to the static-import rule: the SPA loads it on the first
|
|
734
|
+
diagram, using hashed chunks from the same server. A six-Markdown-card cold-boot
|
|
735
|
+
probe requested only the entry and its small shared chunk, not Mermaid's 3.46 MB.
|
|
736
|
+
With Bun 1.4.4, headed Chromium 145, 4× CPU throttling and five alternating fresh
|
|
737
|
+
contexts per variant, the baseline median was 1,423.9 ms and the candidate median
|
|
738
|
+
1,349.1 ms to six populated cards plus two animation frames. Ranges overlap
|
|
739
|
+
(1,277.3–1,484.7 ms versus 1,315.2–1,510.1 ms), so this is not a speedup claim.
|
|
740
|
+
The baseline is 0.10.0 rebuilt with the same compiler; both variants use current
|
|
741
|
+
CSS and local intercepted responses, not a network or native-host benchmark.
|
|
742
|
+
Reproduce with `DISPLAY=:99 node scripts/benchmark-canvas-boot.mjs <disposable-server-url> <baseline-index.js>`.
|
|
743
|
+
The populated-board check uses `scripts/benchmark-populated-canvas.mjs`, the same
|
|
744
|
+
70-card fixture and 18% camera, headed Chromium 145 at 1440×900, and three cold-cache
|
|
745
|
+
loads plus three warm reloads per build, with other browsers and tests stopped.
|
|
746
|
+
All 33 visible viewers rendered. The final comparison found baseline 0.10.0 at
|
|
747
|
+
6.71–7.67 s cold and 7.17–7.32 s warm; the candidate took 7.59–8.19 s cold and
|
|
748
|
+
8.00–8.39 s warm. This remains a loading cost, not an orb-only explanation or a
|
|
749
|
+
speedup. Main-page long tasks totalled 4.43–4.87 s on the candidate versus
|
|
750
|
+
3.46–4.20 s on baseline. Each chart document contains about 1.49 MB decoded
|
|
751
|
+
(baseline 1.47 MB). Parent Resource Timing alone misses baseline iframe bytes
|
|
752
|
+
and can duplicate candidate navigation bytes; do not compare or sum those totals.
|
|
753
|
+
The script records frame resources separately. Removing the provisional four-document queue produced overlapping
|
|
754
|
+
completion ranges and a later first viewer; the simpler independent loading path
|
|
755
|
+
avoids cross-card blocking, not a claimed performance win. Warm-load aborted
|
|
756
|
+
presence requests are recorded separately from viewer failures; no viewer failed.
|
|
757
|
+
At the default 52% camera there are no visible iframe viewers. The candidate's
|
|
758
|
+
board appeared in 0.67–0.70 s cold and 0.52–0.65 s warm versus baseline's
|
|
759
|
+
1.08–1.32 s and 1.06–1.36 s. That measures deferred offscreen work, not faster
|
|
760
|
+
viewer rendering. Local document responses were 2–6 ms. Portal-URL checks use
|
|
761
|
+
Amp's local hairpin forwarding inside this orb, so they do not measure external
|
|
762
|
+
portal transport or the user's connection. These are instrumented local readiness
|
|
763
|
+
timings, not native paint latency. Linux WebKit's full fit-all load exceeded this orb's memory limit
|
|
764
|
+
on both baseline and candidate; narrower populated-row checks are separate evidence.
|
|
765
|
+
The self-contained MCP App cannot fetch those chunks: its document includes
|
|
766
|
+
Mermaid and grows from about 1.32 MB to 4.78 MB uncompressed. This is an introduced delivery
|
|
767
|
+
cost, not eliminated debt or measured native performance. Keeping one renderer
|
|
768
|
+
and an offline-capable MCP document is the tradeoff; native boot remains unmeasured.
|
|
769
|
+
The bundle audit found one Mermaid core, one shared renderer and one DOMPurify,
|
|
770
|
+
not an embedded copy of the standalone viewer. The old standalone Mermaid bundle
|
|
771
|
+
already weighed 3,492,157 bytes; moving its renderer inline brings that dependency
|
|
772
|
+
tree into the self-contained MCP host. The dependency graph contains different
|
|
773
|
+
major versions of `marked`, `layout-base` and `cose-base` required by Mermaid's
|
|
774
|
+
renderers; forcing aliases would not be a safe deduplication. Inspect the graph
|
|
775
|
+
with `bun build src/client/mcp-app/index.tsx --target=browser --format=iife --minify --metafile=/tmp/mcp-meta.json --outfile=/tmp/mcp.js`.
|
|
776
|
+
Removing the payload from MCP startup requires a different script-delivery/CSP
|
|
777
|
+
contract or a reduced diagram catalog, rather than deleting a duplicate host.
|
|
778
|
+
Static export checks separately cover all twelve graph variants, compact plots,
|
|
779
|
+
all nine named themes and 600, 1024 and 1920 px widths in headed Chromium.
|
|
780
|
+
The populated 70-card export matches live saved geometry and renders offline
|
|
781
|
+
without HTTP(S) requests; bounded Linux WebKit checks cover the compact chart
|
|
782
|
+
section and dashboard. Linked boards and live MCP apps retain honest unavailable
|
|
783
|
+
placeholders. Arbitrary user HTML can still contain external requests.
|
|
784
|
+
|
|
785
|
+
There is no threshold-triggered grid or list. Zoom's revised drawing keeps the
|
|
786
|
+
same positions, sizes, groups, connections and native content at every scale.
|
|
787
|
+
Fit-all is for orientation; zoom or expand to read details. The earlier overview's
|
|
788
|
+
scrolling and overlay-clearance fixes are superseded by its complete removal.
|
|
789
|
+
|
|
790
|
+
Visual audit: Harbor headings use the drawing's 20 px semibold `#e6eef7` on
|
|
791
|
+
`#081524` (15.69:1). The initial dim capture had the existing relation-focus
|
|
792
|
+
highlight active, which applies 0.35 opacity to unrelated cards; Escape clears
|
|
793
|
+
that view state. A neighboring card outside a 600 px viewport is spatially
|
|
794
|
+
clipped, not internally truncated: focusing it restores the complete title.
|
|
795
|
+
Expanded pin hints remain while their button has keyboard `:focus-visible`, even
|
|
796
|
+
after pointer movement; Tab away dismisses the hint after its fade transition.
|
|
797
|
+
|
|
633
798
|
## Definition of done for any design work
|
|
634
799
|
|
|
635
800
|
1. It is drawn in the proposal canvas first, at 600 px and at full-window width.
|
package/docs/http-api.md
CHANGED
|
@@ -217,9 +217,15 @@ content auto-height or indirect parent-group reflow after editing a child.
|
|
|
217
217
|
update and are included in snapshots/undo. They are board-wide writes under a scope fence.
|
|
218
218
|
- `POST /api/canvas/tour/go` with `{ "stop": 2 }` or `{ "step": "next" | "previous" }`
|
|
219
219
|
(plus optional `"present": false`) moves the shared tour cursor →
|
|
220
|
-
`{ ok, index, total, stop
|
|
220
|
+
`{ ok, index, total, stop, catalogEpoch, boardGeneration, sequence }`;
|
|
221
|
+
400 when the stop does not exist or the board has no stops.
|
|
221
222
|
Broadcasts `canvas-tour-step`; idle workbenches start presenting unless `present` is false.
|
|
223
|
+
Response and event share the same monotonically increasing `sequence` within the
|
|
224
|
+
server's `catalogEpoch`. Viewers accept only newer steps for their current epoch
|
|
225
|
+
and board generation, so delayed echoes cannot rewind or replay the camera.
|
|
222
226
|
- `POST /api/canvas/tour/exit` leaves presentation in every viewer (`canvas-tour-exit`).
|
|
227
|
+
Returns `{ ok, catalogEpoch, boardGeneration, sequence }`; the event shares that
|
|
228
|
+
identity and the step sequence, so an old exit cannot dismiss a newer presentation.
|
|
223
229
|
- `POST /api/canvas/camera/move` with exactly one of `nodeId`, `rect: { x, y, width, height }`
|
|
224
230
|
or `viewport: { x, y, scale }`, plus optional `duration`, `easing`, `padding`, `pullback`
|
|
225
231
|
→ `{ ok, stop, viewport }`. Broadcasts `canvas-camera-move`; browsers ease to the target in
|
|
@@ -229,6 +235,29 @@ content auto-height or indirect parent-group reflow after editing a child.
|
|
|
229
235
|
Tour steps and camera moves are navigation: no undo entry, no agent-presence write, no
|
|
230
236
|
scope-fence check.
|
|
231
237
|
|
|
238
|
+
`tour/go` and `tour/exit` accept optional `presenter: { clientId, intent,
|
|
239
|
+
catalogEpoch, boardGeneration }`. The workbench assigns each document a random ID
|
|
240
|
+
and each gesture an increasing positive safe-integer intent. The server rejects
|
|
241
|
+
an old activation or an intent no newer than that document's accepted watermark
|
|
242
|
+
with `{ ok: true, superseded: true }`, without moving the cursor or emitting an event.
|
|
243
|
+
A structurally valid newer command supersedes older ones even if its stop is missing.
|
|
244
|
+
This lets Present proceed while an earlier Exit request is stalled, without that
|
|
245
|
+
late Exit stopping the restart. Resume reads cannot outlive their originating intent.
|
|
246
|
+
|
|
247
|
+
This is latest-intent-wins, not FIFO: reversed relative Next requests can coalesce.
|
|
248
|
+
Different documents, including a reload, remain independent; unfenced agent calls
|
|
249
|
+
and other documents still act in server arrival order. Reload is not cancellation
|
|
250
|
+
of an old document's pending request. A board activation retains at most 4096
|
|
251
|
+
document IDs, refusing new IDs with 409 rather than evicting an ordering record.
|
|
252
|
+
Switching boards resets that limit; requests stamped with the old activation still
|
|
253
|
+
cannot apply. The SDK exposes the same fence through `goToTourStop(step,
|
|
254
|
+
{ presenter })` and `exitTour(presenter)`; fenced go may return `{ superseded: true }`.
|
|
255
|
+
|
|
256
|
+
Presentation's Back/Next buttons share this cursor with keyboard and agent navigation.
|
|
257
|
+
They sit beside Exit at the top; hover/focus tooltips show the shortcuts. Node and
|
|
258
|
+
rectangle targets fit below those controls, while explicit viewport targets remain
|
|
259
|
+
exact. Presentation does not change the saved board viewport.
|
|
260
|
+
|
|
232
261
|
The [tour model and recording walkthrough](cli.md#tour-and-presentation) describes
|
|
233
262
|
targets, duration, easing, padding, and pullback. Open `/workbench?present=1` to hide
|
|
234
263
|
chrome; camera movement is local to that viewer. Recording writes local files via
|
|
@@ -388,6 +417,14 @@ stored once per file. Live MCP apps become placeholders; local file contents
|
|
|
388
417
|
are left out unless `includeFiles` is true. Files are written to `exports/`
|
|
389
418
|
beside the database. Built-app files are only embedded when they are regular,
|
|
390
419
|
bounded-size files inside the board's owned `.pmx-canvas/artifacts/` directory.
|
|
420
|
+
Exports retain saved card positions and sizes, heading display, and the board's
|
|
421
|
+
named theme. Charts and dashboards use embedded card layout without repeating
|
|
422
|
+
the shell title; explicit chart heights remain unchanged. Viewer bundles, palette
|
|
423
|
+
CSS and shell fonts are embedded. Read-only exports omit live work controls.
|
|
424
|
+
When running from source, run `bun run build` before exporting. Export requires
|
|
425
|
+
the complete built viewer assets, `surface-theme.css`, and the font files referenced
|
|
426
|
+
by `global.css`; the installed package includes them. A missing asset tree is not
|
|
427
|
+
a supported text-only export mode.
|
|
391
428
|
The preview manifest lists card links, remote images, and statically visible
|
|
392
429
|
network destinations in embedded HTML. Imported source-linked Markdown is also
|
|
393
430
|
excluded unless `includeDerivedText=true`, independently of `includeFiles`;
|
|
@@ -462,6 +499,13 @@ opening that board or changing where writes go. This is supported by
|
|
|
462
499
|
return 404. Omit `board` to read the active board. Live AX session/delivery reads
|
|
463
500
|
and fixed MCP resources continue to describe the open board.
|
|
464
501
|
|
|
502
|
+
The workbench's `POST /api/canvas/update` accepts `{updates: [{id, position?, size?,
|
|
503
|
+
collapsed?, zIndex?}], expectedBoardId?, recordHistory?}`. `zIndex` is finite and
|
|
504
|
+
persists stacking without changing geometry. The workbench raises a group and its
|
|
505
|
+
children together, keeping the frame below its children. Title-bar gestures save
|
|
506
|
+
stacking and geometry together on release. Layout notifications and reloads retain
|
|
507
|
+
that order.
|
|
508
|
+
|
|
465
509
|
```bash
|
|
466
510
|
# Get canvas state
|
|
467
511
|
curl http://localhost:4313/api/canvas/state
|
|
@@ -613,6 +657,10 @@ hosted MCP App still refuses file-linked edits. This is not a crash-recovery dis
|
|
|
613
657
|
Replacing a JSON-render node's `spec` preserves its current title; include `title`
|
|
614
658
|
to rename it explicitly. A new authored spec still resets the viewer's local drafts.
|
|
615
659
|
|
|
660
|
+
Markdown nodes accept `data: { "display": "heading" | "card" }` on creation and
|
|
661
|
+
update. Heading display removes the card frame and uses its title as a section
|
|
662
|
+
label; it does not alter content, position, or pin membership.
|
|
663
|
+
|
|
616
664
|
Mermaid nodes accept `data: { "fit": "contain" | "none" }` on both
|
|
617
665
|
`POST /api/canvas/node` and `PATCH /api/canvas/node/:id`. The default, `contain`,
|
|
618
666
|
shrinks overflowing diagrams without changing aspect ratio; `none` keeps 100%
|
|
@@ -1294,6 +1342,8 @@ all consume this stream. Auto-reconnect with exponential backoff.
|
|
|
1294
1342
|
|
|
1295
1343
|
The direct workbench's `connected` snapshot renews its per-process
|
|
1296
1344
|
`workbenchToken` (also embedded in boot HTML) over both SSE and polling.
|
|
1345
|
+
It is followed by `boards-changed` before the layout, so later tour commands
|
|
1346
|
+
already have a board identity even when the separate catalog HTTP read is delayed.
|
|
1297
1347
|
A same-bundle daemon restart does not reload the page or discard an open draft.
|
|
1298
1348
|
Registered writes and file saves marked as workbench calls with a supplied stale capability
|
|
1299
1349
|
return 409 until reconnect renews it; they are never silently recorded as agent
|
package/docs/mcp.md
CHANGED
|
@@ -146,6 +146,10 @@ tour: { stops: [...] } }` persists an ordered tour; `tour: null` resets it.
|
|
|
146
146
|
presents a stop in the workbench, `"tour-exit"` leaves presentation, and
|
|
147
147
|
`canvas_view { action: "move", nodeId | rect | viewport, duration, easing, padding, pullback }`
|
|
148
148
|
eases the camera. None of these enter undo history.
|
|
149
|
+
`tour-go` and `tour-exit` also accept the optional document `presenter` fence
|
|
150
|
+
described in [HTTP board tours](http-api.md#board-tours). Superseded requests return
|
|
151
|
+
`{ ok: true, superseded: true }` with no delivery or event. Ordinary agent calls
|
|
152
|
+
omit it and retain shared arrival-order navigation.
|
|
149
153
|
See the [tour model and CLI walkthrough](cli.md#tour-and-presentation) for stop
|
|
150
154
|
fields. Recording is a local CLI operation; no remote recording/file-writing
|
|
151
155
|
tool is added.
|
|
@@ -513,6 +517,10 @@ into `persistFile: true` with both preconditions and top-level `content` to save
|
|
|
513
517
|
workspace `.md` file and card together. In this mode, `data` accepts only the `rendered` preview;
|
|
514
518
|
refused saves change neither. See [the file-save contract](http-api.md#nodes).
|
|
515
519
|
|
|
520
|
+
For Markdown nodes, `canvas_node` actions `add` and `update` accept
|
|
521
|
+
`data: { display: "heading" | "card" }`. Heading display uses the existing title
|
|
522
|
+
and content as a frameless section label, without changing pin membership.
|
|
523
|
+
|
|
516
524
|
For Mermaid nodes, `canvas_node` actions `add` and `update` accept
|
|
517
525
|
`data: { fit: "contain" | "none" }`. Contain is the default, shrinking overflow
|
|
518
526
|
uniformly; none keeps 100% with scrolling. Use Open as site for 100% without
|