pmx-canvas 0.7.2 → 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.
- package/.github/extensions/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
- package/.github/extensions/pmx-canvas/extension.mjs +25 -172
- package/.github/extensions/pmx-canvas/mcp-bootstrap.ts +198 -0
- package/.github/extensions/pmx-canvas/runtime.d.mts +41 -0
- package/.github/extensions/pmx-canvas/runtime.json +3 -0
- package/.github/extensions/pmx-canvas/runtime.mjs +194 -0
- package/.github/extensions/pmx-canvas/start-mcp.mjs +51 -0
- package/.github/extensions/pmx-canvas/tools.json +2560 -0
- package/CHANGELOG.md +60 -0
- package/Readme.md +44 -16
- package/dist/canvas/fonts/OFL.txt +93 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-ext-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-ext-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-600-normal.woff2 +0 -0
- package/dist/canvas/global.css +844 -710
- package/dist/canvas/index.js +92 -90
- package/dist/canvas/mcp-app.html +7878 -0
- package/dist/canvas/mermaid-entry.js +1 -1
- package/dist/canvas/surface-theme.css +151 -46
- package/dist/json-render/index.css +1 -1
- package/dist/json-render/index.js +55 -55
- package/dist/types/cli/commands/record.d.ts +1 -1
- package/dist/types/client/canvas/ChoiceMenu.d.ts +13 -0
- package/dist/types/client/canvas/NodeContextMark.d.ts +24 -0
- package/dist/types/client/canvas/SessionReceipt.d.ts +3 -1
- package/dist/types/client/icons.d.ts +1 -2
- package/dist/types/client/mcp-app/index.d.ts +1 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +2 -1
- package/dist/types/client/nodes/ax-node-actions.d.ts +2 -2
- package/dist/types/client/nodes/markdown-sanitize.d.ts +2 -0
- package/dist/types/client/nodes/use-workbench-asset.d.ts +2 -0
- package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -0
- package/dist/types/client/state/attention-store.d.ts +0 -5
- package/dist/types/client/state/canvas-store.d.ts +2 -0
- package/dist/types/client/state/context-status-store.d.ts +53 -0
- package/dist/types/client/state/intent-bridge.d.ts +4 -1
- package/dist/types/client/state/near-pin-store.d.ts +16 -0
- package/dist/types/client/state/presence-store.d.ts +5 -0
- package/dist/types/client/state/session-store.d.ts +33 -3
- package/dist/types/client/state/workbench-transport.d.ts +16 -0
- package/dist/types/client/theme/tokens.d.ts +1 -3
- package/dist/types/client/types.d.ts +9 -0
- package/dist/types/json-render/renderer/index.d.ts +2 -1
- package/dist/types/json-render/server.d.ts +3 -1
- package/dist/types/mcp/app-server.d.ts +3 -0
- package/dist/types/mcp/canvas-access.d.ts +1 -1
- package/dist/types/mcp/canvas-app.d.ts +4 -0
- package/dist/types/mcp/workbench-app.d.ts +4 -0
- package/dist/types/server/agent-presence.d.ts +1 -1
- package/dist/types/server/ax-state.d.ts +1 -1
- package/dist/types/server/canvas-db.d.ts +8 -0
- package/dist/types/server/canvas-geometry.d.ts +25 -0
- package/dist/types/server/canvas-operations.d.ts +1 -11
- package/dist/types/server/canvas-state.d.ts +25 -3
- package/dist/types/server/context-brief.d.ts +8 -1
- package/dist/types/server/context-reads.d.ts +30 -7
- package/dist/types/server/index.d.ts +6 -1
- package/dist/types/server/mcp-app-runtime.d.ts +1 -0
- package/dist/types/server/operations/http.d.ts +2 -0
- package/dist/types/server/operations/invoker.d.ts +4 -2
- package/dist/types/server/operations/ops/nodes.d.ts +0 -6
- package/dist/types/server/server.d.ts +1 -0
- package/dist/types/server/spatial-analysis.d.ts +2 -0
- package/dist/types/shared/agent-context.d.ts +22 -0
- package/dist/types/shared/agent-presence.d.ts +3 -10
- package/dist/types/shared/ax-surface-protocol.d.ts +2 -0
- package/dist/types/shared/canvas-app.d.ts +54 -0
- package/dist/types/shared/themes.d.ts +1 -1
- package/docs/RELEASE.md +7 -3
- package/docs/agent-plugin.md +123 -0
- package/docs/ax-host-adapter-contract.md +13 -2
- package/docs/ax-state-contract.md +40 -0
- package/docs/cli.md +7 -2
- package/docs/design/AgentContext.dc.html +186 -0
- package/docs/design/Before.dc.html +208 -0
- package/docs/design/BoardPins.dc.html +151 -0
- package/docs/design/Chrome.dc.html +208 -0
- package/docs/design/Context.dc.html +239 -0
- package/docs/design/Flows.dc.html +181 -0
- package/docs/design/Home.dc.html +209 -0
- package/docs/design/HomeGraph.dc.html +211 -0
- package/docs/design/HomeMap.dc.html +117 -0
- package/docs/design/HomeTeam.dc.html +176 -0
- package/docs/design/Light.dc.html +28 -0
- package/docs/design/Main.dc.html +280 -0
- package/docs/design/NearPin.dc.html +260 -0
- package/docs/design/Pane600.dc.html +120 -0
- package/docs/design/Relations.dc.html +297 -0
- package/docs/design/Themes.dc.html +121 -0
- package/docs/design/TokenSystem.dc.html +136 -0
- package/docs/design/Tokens.dc.html +163 -0
- package/docs/design/Types1.dc.html +177 -0
- package/docs/design/Types2.dc.html +226 -0
- package/docs/design/Types3.dc.html +195 -0
- package/docs/design/Uses.dc.html +152 -0
- package/docs/design/Vision.dc.html +116 -0
- package/docs/design/Zoom.dc.html +82 -0
- package/docs/design/canvas.json +274 -0
- package/docs/design.md +214 -0
- package/docs/environment.md +1 -1
- package/docs/http-api.md +80 -15
- package/docs/mcp.md +198 -3
- package/docs/node-types.md +34 -10
- package/docs/plans/plan-009-tech-debt-backlog.md +1 -1
- package/docs/plans/plan-015-design-foundation-wave-0.md +177 -0
- package/docs/plans/plan-016-context-made-visible-wave-1.md +148 -0
- package/docs/product-vision-2026-09.md +47 -7
- package/docs/screenshot.png +0 -0
- package/docs/sdk.md +1 -0
- package/package.json +10 -4
- package/plugins/pmx-canvas/LICENSE +21 -0
- package/plugins/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
- package/plugins/pmx-canvas/assets/preview.png +0 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +930 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +3 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.mjs +194 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/steering-delivery.mjs +79 -0
- package/plugins/pmx-canvas/mcp.json +12 -0
- package/plugins/pmx-canvas/plugin.json +24 -0
- package/plugins/pmx-canvas/runtime.json +3 -0
- package/plugins/pmx-canvas/runtime.mjs +194 -0
- package/plugins/pmx-canvas/start-mcp.mjs +51 -0
- package/plugins/pmx-canvas/tools.json +2560 -0
- package/skills/pmx-canvas/SKILL.md +31 -16
- package/skills/pmx-canvas/evals/evals.json +69 -0
- package/skills/pmx-canvas/references/full-reference.md +14 -10
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +20 -8
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +76 -4
- package/skills/pmx-canvas-testing/SKILL.md +54 -4
- package/src/cli/commands/copilot.ts +5 -0
- package/src/cli/commands/view.ts +1 -1
- package/src/cli/index.ts +8 -3
- package/src/client/App.tsx +6 -1
- package/src/client/canvas/AgentPresenceLayer.tsx +3 -3
- package/src/client/canvas/AnnotationLayer.tsx +1 -1
- package/src/client/canvas/CanvasNode.tsx +208 -220
- package/src/client/canvas/CanvasViewport.tsx +6 -2
- package/src/client/canvas/ChoiceMenu.tsx +122 -0
- package/src/client/canvas/CommandBar.tsx +25 -23
- package/src/client/canvas/CommandPalette.tsx +3 -2
- package/src/client/canvas/ContextMenu.tsx +11 -0
- package/src/client/canvas/EdgeLayer.tsx +1 -1
- package/src/client/canvas/ExportDialog.tsx +33 -6
- package/src/client/canvas/FeedbackDialog.tsx +10 -8
- package/src/client/canvas/IntentLayer.tsx +2 -2
- package/src/client/canvas/Minimap.tsx +12 -7
- package/src/client/canvas/NodeContextMark.tsx +156 -0
- package/src/client/canvas/SessionPanel.tsx +4 -7
- package/src/client/canvas/SessionReceipt.tsx +114 -17
- package/src/client/canvas/ShortcutOverlay.tsx +6 -1
- package/src/client/canvas/SnapshotPanel.tsx +11 -2
- package/src/client/canvas/ToolRail.tsx +58 -108
- package/src/client/canvas/TopBar.tsx +16 -11
- package/src/client/icons.tsx +2 -12
- package/src/client/mcp-app/index.tsx +137 -0
- package/src/client/mcp-app/style.css +10 -0
- package/src/client/nodes/AttachmentNode.tsx +8 -1
- package/src/client/nodes/AxStepControls.tsx +1 -1
- package/src/client/nodes/ContextNode.tsx +9 -9
- package/src/client/nodes/ExtAppFrame.tsx +13 -8
- package/src/client/nodes/FileNode.tsx +8 -5
- package/src/client/nodes/ImageNode.tsx +4 -2
- package/src/client/nodes/InlineMarkdownEditor.tsx +2 -1
- package/src/client/nodes/LedgerNode.tsx +2 -2
- package/src/client/nodes/MarkdownNode.tsx +44 -9
- package/src/client/nodes/McpAppNode.tsx +22 -4
- package/src/client/nodes/PromptNode.tsx +5 -17
- package/src/client/nodes/ResponseNode.tsx +3 -15
- package/src/client/nodes/StatusNode.tsx +2 -2
- package/src/client/nodes/StatusSummary.tsx +3 -1
- package/src/client/nodes/TraceNode.tsx +6 -4
- package/src/client/nodes/WebpageNode.tsx +1 -1
- package/src/client/nodes/ax-node-actions.ts +2 -2
- package/src/client/nodes/iframe-document-url.ts +3 -2
- package/src/client/nodes/markdown-sanitize.ts +10 -0
- package/src/client/nodes/surface-url.ts +10 -0
- package/src/client/nodes/use-ax-surface-bridge.ts +4 -2
- package/src/client/nodes/use-surface-frame.ts +3 -1
- package/src/client/nodes/use-workbench-asset.ts +26 -0
- package/src/client/nodes/viewer-runtime-state.ts +78 -0
- package/src/client/state/attention-bridge.ts +0 -8
- package/src/client/state/attention-store.ts +0 -17
- package/src/client/state/canvas-store.ts +7 -2
- package/src/client/state/context-status-store.ts +66 -0
- package/src/client/state/human-store.ts +2 -0
- package/src/client/state/iframe-mode.ts +5 -0
- package/src/client/state/intent-bridge.ts +24 -6
- package/src/client/state/near-pin-store.ts +53 -0
- package/src/client/state/presence-store.ts +5 -10
- package/src/client/state/session-store.ts +106 -9
- package/src/client/state/sse-bridge.ts +26 -7
- package/src/client/state/theme-override.ts +1 -1
- package/src/client/state/workbench-transport.ts +36 -0
- package/src/client/theme/global.css +844 -710
- package/src/client/theme/surface-theme.css +151 -46
- package/src/client/theme/tokens.ts +7 -11
- package/src/client/types.ts +10 -0
- package/src/json-render/renderer/index.tsx +58 -38
- package/src/json-render/server.ts +79 -15
- package/src/mcp/app-server.ts +64 -0
- package/src/mcp/canvas-access.ts +14 -11
- package/src/mcp/canvas-app.ts +318 -0
- package/src/mcp/server.ts +1 -1
- package/src/mcp/workbench-app.ts +211 -0
- package/src/server/agent-presence.ts +45 -6
- package/src/server/ax-context.ts +1 -1
- package/src/server/ax-state.ts +1 -1
- package/src/server/board-export.ts +5 -2
- package/src/server/canvas-db.ts +46 -12
- package/src/server/canvas-geometry.ts +64 -0
- package/src/server/canvas-operations.ts +6 -24
- package/src/server/canvas-state.ts +105 -15
- package/src/server/canvas-validation.ts +19 -4
- package/src/server/context-brief.ts +39 -2
- package/src/server/context-reads.ts +86 -15
- package/src/server/demo-state.json +31 -31
- package/src/server/html-surface.ts +4 -5
- package/src/server/index.ts +19 -3
- package/src/server/mcp-app-runtime.ts +11 -0
- package/src/server/operations/composites.ts +4 -3
- package/src/server/operations/http.ts +4 -4
- package/src/server/operations/invoker.ts +13 -4
- package/src/server/operations/ops/ax-read.ts +1 -1
- package/src/server/operations/ops/ax-timeline.ts +37 -0
- package/src/server/operations/ops/boards.ts +1 -1
- package/src/server/operations/ops/canvas-wire.ts +3 -6
- package/src/server/operations/ops/intent.ts +31 -2
- package/src/server/operations/ops/json-render.ts +1 -1
- package/src/server/operations/ops/nodes.ts +8 -76
- package/src/server/operations/ops/query.ts +8 -2
- package/src/server/operations/ops/snapshots.ts +4 -1
- package/src/server/operations/ops/viewport.ts +29 -5
- package/src/server/operations/registry.ts +38 -4
- package/src/server/scope-fence.ts +55 -10
- package/src/server/server.ts +86 -6
- package/src/server/spatial-analysis.ts +2 -2
- package/src/server/workboard.ts +6 -1
- package/src/{server → shared}/agent-context.ts +2 -2
- package/src/shared/agent-presence.ts +3 -15
- package/src/shared/ax-surface-protocol.ts +3 -0
- package/src/shared/canvas-app.ts +62 -0
- package/src/shared/themes.ts +5 -5
- package/src/client/canvas/FocusFieldLayer.tsx +0 -116
- package/src/client/canvas/kind-colors.ts +0 -23
|
@@ -20,7 +20,8 @@ At the start of board work, read `canvas://context?consumer=<stable-unique-id>`
|
|
|
20
20
|
(or `canvas_query { action: "context", consumer: "<stable-unique-id>" }`) before
|
|
21
21
|
falling back to broader resources. The budget is UTF-16 code units, not tokens.
|
|
22
22
|
Use one stable consumer ID per agent/adapter only when durable deltas are wanted;
|
|
23
|
-
omit it for a fresh read. Pins are highest priority
|
|
23
|
+
omit it for a fresh read. Pins are highest priority, then the cards near each pin
|
|
24
|
+
(reason `near`, title + short summary only). If a source card is clipped or near,
|
|
24
25
|
pull that card explicitly by its returned board/card IDs.
|
|
25
26
|
|
|
26
27
|
When authoring a board, establish its README without waiting for the human to
|
|
@@ -43,11 +44,14 @@ for the authoritative stop, viewport, persistence, reset, group-order, and captu
|
|
|
43
44
|
|
|
44
45
|
## Runtime prerequisites
|
|
45
46
|
|
|
46
|
-
PMX Canvas 0.
|
|
47
|
+
PMX Canvas 0.8.0 requires **Bun >=1.4.2**, including when installed through npm.
|
|
47
48
|
Check `bun --version` and ensure Bun is on the MCP host's PATH, not just your shell's;
|
|
48
49
|
use an absolute executable path if needed. Install/configure only when requested.
|
|
49
50
|
For pinned installation, MCP configuration, managed services, and disposable verification,
|
|
50
51
|
read [Installing PMX Canvas](references/installing-pmx-canvas.md).
|
|
52
|
+
In Amp, follow that reference's [Amp setup](references/installing-pmx-canvas.md#amp-connect-the-agent-separately-from-the-portal):
|
|
53
|
+
portal access is separate from native MCP, workspace commands need human trust approval,
|
|
54
|
+
and a connected MCP server does not install an idle-thread wake-up adapter.
|
|
51
55
|
|
|
52
56
|
## Reading bundled skills over MCP
|
|
53
57
|
|
|
@@ -58,7 +62,8 @@ files (for example `skill://pmx-canvas/references/installing-pmx-canvas.md`) thr
|
|
|
58
62
|
`resources/read`, fetching only what is needed. Hosts without extension support can still read
|
|
59
63
|
ordinary resources or use installed filesystem skills; `canvas://skills` remains available.
|
|
60
64
|
Resource reads do not activate skills or authorize executing their scripts. The host must
|
|
61
|
-
preserve MCP origin and apply integrity/approval checks.
|
|
65
|
+
preserve MCP origin and apply integrity/approval checks. Native Canvas tool discovery alone
|
|
66
|
+
does not establish native MCP Skills-extension support. Restart MCP after upgrading the package;
|
|
62
67
|
the served catalog is a startup snapshot. Local mirrors still use `skills sync` below.
|
|
63
68
|
|
|
64
69
|
## Required Operating Sequence
|
|
@@ -104,7 +109,7 @@ the served catalog is a startup snapshot. Local mirrors still use `skills sync`
|
|
|
104
109
|
Do not detach a host-owned session; its adapter manages its lifetime. Everything the session
|
|
105
110
|
gives you and asks of you (cursor + phase chip, the session panel, steering, the scope fence's
|
|
106
111
|
403s, the human edit lock's 409s, unattended approvals) is in **Sessions & the human** below.
|
|
107
|
-
7. **Mutate through current composites.** Prefer the
|
|
112
|
+
7. **Mutate through current composites.** Prefer the 18 composite MCP tools below.
|
|
108
113
|
7. **Arrange and validate.** After batch changes, use `canvas_view { action: "arrange" }` when
|
|
109
114
|
appropriate and always finish with `canvas_query { action: "validate" }`.
|
|
110
115
|
7b. **Show the human.** After creating user-facing output, bring the camera to it: a single node
|
|
@@ -112,7 +117,8 @@ the served catalog is a startup snapshot. Local mirrors still use `skills sync`
|
|
|
112
117
|
`canvas_view { action: "fit", nodeIds: [...] }` with exactly the new ids. See
|
|
113
118
|
**In-View Placement & Sizing** below — auto-placement is board-relative, not camera-relative.
|
|
114
119
|
8. **Verify context pins.** Pin with `canvas_pin_nodes` or the browser's **Pin as context**, then
|
|
115
|
-
read `canvas://pinned-context`.
|
|
120
|
+
read `canvas://pinned-context`. When you pin, pass a short `reason` — the human sees who pinned a
|
|
121
|
+
node and why.
|
|
116
122
|
9. **Clean up temporary nodes.** Remove retry/test fixtures and restore the baseline snapshot when
|
|
117
123
|
the task requires leaving the board unchanged.
|
|
118
124
|
|
|
@@ -204,7 +210,7 @@ always authoritative, independent of the installed release version.
|
|
|
204
210
|
|-----------|---------|
|
|
205
211
|
| `canvas_import` | `list`, `read`, `submit`, `unavailable` |
|
|
206
212
|
| `canvas_node` | `add`, `get`, `update`, `remove` |
|
|
207
|
-
| `canvas_render` | `describe-schema`, `validate`, `add-json-render`, `stream-json-render`, `add-graph` |
|
|
213
|
+
| `canvas_render` | `describe-schema`, `validate`, `add-json-render`, `stream-json-render`, `add-graph`, `workboard` |
|
|
208
214
|
| `canvas_edge` | `add`, `update`, `remove` |
|
|
209
215
|
| `canvas_group` | `create`, `add`, `ungroup` |
|
|
210
216
|
| `canvas_history` | `undo`, `redo` |
|
|
@@ -215,9 +221,9 @@ always authoritative, independent of the installed release version.
|
|
|
215
221
|
| `canvas_ax_state` | `get`, `set-focus`, `set-policy`, `report-capability`, `presence`, `set-presence` |
|
|
216
222
|
| `canvas_ax_work` | `add`, `update`, `annotate` |
|
|
217
223
|
| `canvas_ax_gate` | `request`, `resolve`, `await` with `approval`, `elicitation`, or `mode` |
|
|
218
|
-
| `canvas_ax_timeline` | `read`, `record-event`, `add-evidence`, `send-steering`, `reads` |
|
|
224
|
+
| `canvas_ax_timeline` | `read`, `record-event`, `add-evidence`, `send-steering`, `reads`, `read-status` |
|
|
219
225
|
| `canvas_ax_delivery` | `claim`, `mark` |
|
|
220
|
-
| `canvas_board` | `list`, `get`, `create`, `create-from`, `update` |
|
|
226
|
+
| `canvas_board` | `list`, `get`, `create`, `create-from`, `open`, `update` |
|
|
221
227
|
| `canvas_snapshot` | `save`, `list`, `restore`, `delete`, `gc`, `diff` |
|
|
222
228
|
| `canvas_intent` | `signal`, `update`, `clear` |
|
|
223
229
|
|
|
@@ -299,8 +305,14 @@ reports any node below its floor as an advisory `sizeWarnings` entry — treat a
|
|
|
299
305
|
as layout work left to do.
|
|
300
306
|
Creation responses may include `sizeAdjustment` (`defaulted`, `clamped-to-minimum`, or
|
|
301
307
|
`fit-to-children`); use its `applied` geometry rather than assuming the request won. Json-render
|
|
302
|
-
validation/creation
|
|
303
|
-
|
|
308
|
+
validation/creation binds a literal form-control `value` to `state.form` automatically; it still
|
|
309
|
+
warns for `$state` expressions, controls inside a repeat, or a non-object `state.form`, which render
|
|
310
|
+
but do not update runtime state until bound with `$bindState`/`$bindItem`.
|
|
311
|
+
Bound JSON input and dynamic lists are local UI state, not saved canvas data. Focus-mode
|
|
312
|
+
expand/close preserves that state for the same spec in the current tab; an authored spec update,
|
|
313
|
+
board switch or page reload resets it. Persist important edits explicitly through the app's
|
|
314
|
+
save/AX actions. Published 0.7.2 loses this state on expand/close too (AK): avoid changing views
|
|
315
|
+
with an unsaved JSON form on that release. This contract does not extend to HTML or external apps.
|
|
304
316
|
If the documented receipts or warnings are unexpectedly absent, do not guess around them with raw
|
|
305
317
|
payload reads: verify that the CLI/MCP host and daemon use the same 0.7 installation and workspace,
|
|
306
318
|
restart the matching daemon after upgrade, and re-check `/health`.
|
|
@@ -428,15 +440,18 @@ Use the visible workbench when the human is actively curating layout:
|
|
|
428
440
|
- Other open tabs appear as green cursors with a name tag (`/workbench?name=mia` sets yours);
|
|
429
441
|
a node you drag is locked for agents until you release it.
|
|
430
442
|
- The chrome is a persistent 52px left tool rail plus a slim 44px top bar (0.4.8+). The rail
|
|
431
|
-
carries the tools (Select V, Pan Space, Connect C),
|
|
432
|
-
|
|
443
|
+
carries the tools (Select V, Pan Space, Connect C), Markdown note M, Attach files, webpage W,
|
|
444
|
+
group G, and separate Draw A, Text note and Eraser buttons for board feedback,
|
|
433
445
|
and utilities: search & commands (Cmd+K — actions with shortcuts, then jump-to-node), arrange,
|
|
434
446
|
trace, minimap, history, the theme picker (nine themes: dark, light, high-contrast, midnight,
|
|
435
447
|
sepia, arctic, ember, forest, volt), and shortcuts (?). The top bar holds the connection dot,
|
|
436
448
|
workspace title, the session chip / gate badge / context meter while a session is attached
|
|
437
449
|
(or the external-writers indicator and *Start agent session* otherwise), and the zoom cluster
|
|
438
450
|
(zoom out, % label = reset, zoom in, fit F). Hovering a rail button shows a tooltip with its
|
|
439
|
-
shortcut.
|
|
451
|
+
shortcut or supported file types. Attach files shares the drop workflow: images, Markdown,
|
|
452
|
+
text/code and PDF/Office originals; PDF/Office extraction still requires the import request
|
|
453
|
+
and human review. Workspace file paths (Shift+F) and image URLs (I) remain in the canvas
|
|
454
|
+
menu and shortcuts; HTML surfaces remain available through H and agent tools.
|
|
440
455
|
On viewports ≤1180px the top bar drops its meta text and the session panel becomes a drawer;
|
|
441
456
|
every control stays in the rail at any width — there is no separate mobile menu.
|
|
442
457
|
- Keyboard: nodes are focusable — arrow keys move to the nearest node, Enter opens it in focus
|
|
@@ -444,7 +459,7 @@ Use the visible workbench when the human is actively curating layout:
|
|
|
444
459
|
- Embedding hosts can open `/workbench?theme=<name>` (or `?theme=auto` to follow the host's
|
|
445
460
|
light/dark appearance) for a session-local default theme that never changes the server-global
|
|
446
461
|
theme other clients see; an explicit pick from the theme menu ends the override. The bundled
|
|
447
|
-
Copilot extension opens its panel with `?theme=
|
|
462
|
+
Copilot extension opens its panel with `?theme=daylight`.
|
|
448
463
|
|
|
449
464
|
After changing files under `src/client/`, rebuild with `bun run build` before manual browser
|
|
450
465
|
verification.
|
|
@@ -653,5 +668,5 @@ Load only the reference relevant to the task:
|
|
|
653
668
|
- [GitHub Copilot adapter](references/github-copilot-app-adapter.md)
|
|
654
669
|
- [Codex app adapter](references/codex-app-adapter.md)
|
|
655
670
|
|
|
656
|
-
|
|
657
|
-
[
|
|
671
|
+
Use fresh MCP `tools/list` for the installed runtime's authoritative inventory and action schemas;
|
|
672
|
+
the [bundled full reference](references/full-reference.md) remains available in mirrored skills.
|
|
@@ -703,6 +703,75 @@
|
|
|
703
703
|
"type": "output_check"
|
|
704
704
|
}
|
|
705
705
|
]
|
|
706
|
+
},
|
|
707
|
+
{
|
|
708
|
+
"id": 29,
|
|
709
|
+
"name": "amp-workspace-trust-and-target",
|
|
710
|
+
"prompt": "The Canvas portal is working in this Amp orb, but tool_search finds no Canvas tools. The workspace MCP server is named review-canvas and amp mcp doctor says awaiting approval. The portal service health says workspace /work/review on port 4361; MCP is configured for /work/other on 4313. Fix the setup; can you just approve it or use global config?",
|
|
711
|
+
"expected_output": "Aligns the workspace amp.mcpServers entry with /work/review and port 4361, clearing stale PMX_CANVAS_URL, without altering unrelated settings or stopping the other workspace. Explains that workspace execution trust belongs to the human and gives amp mcp approve review-canvas for the orb workspace terminal after review. Does not execute approval or bypass it through global config/--mcp-config. After human approval, reloads MCP, requires connected and native tool discovery, verifies health identity and active board, and only then permits writes. Does not equate portal access or standalone MCP smoke with native integration.",
|
|
712
|
+
"assertions": [
|
|
713
|
+
{
|
|
714
|
+
"name": "preserves-human-trust-boundary",
|
|
715
|
+
"description": "Requests human review and amp mcp approve review-canvas in the executing workspace; neither self-approves nor changes configuration scope to bypass trust",
|
|
716
|
+
"type": "output_check"
|
|
717
|
+
},
|
|
718
|
+
{
|
|
719
|
+
"name": "aligns-actual-target",
|
|
720
|
+
"description": "Uses the observed /work/review workspace and 4361 local port, clears stale URL targeting and preserves unrelated settings/listeners",
|
|
721
|
+
"type": "output_check"
|
|
722
|
+
},
|
|
723
|
+
{
|
|
724
|
+
"name": "verifies-native-connection-after-approval",
|
|
725
|
+
"description": "Requires reload, connected status, actual Amp Canvas tools and matching health/board before writes; does not treat portal or standalone smoke as native proof",
|
|
726
|
+
"type": "output_check"
|
|
727
|
+
}
|
|
728
|
+
]
|
|
729
|
+
},
|
|
730
|
+
{
|
|
731
|
+
"id": 30,
|
|
732
|
+
"name": "amp-native-steering-evidence-boundary",
|
|
733
|
+
"prompt": "On this disposable board, native Amp MCP is connected and your source/consumer is amp-review. The browser pinned the Review card and sent amp-review a fresh instruction to append receipt CHECK-30. Prove the round trip, then confirm that an idle Amp thread will now wake automatically and that native Skills discovery works.",
|
|
734
|
+
"expected_output": "Uses actual Amp Canvas tools to read the pinned card, claims only as amp-review, signals intent and appends the requested receipt without losing existing content. Verifies the rendered receipt before marking that delivery for amp-review and confirms it is no longer pending. Uses a different recipient as a negative control and detaches only self-owned test sessions. Reports active-agent polling as verified but declines to infer idle-thread wake-up, persistent pumping or native MCP Skills discovery from this evidence.",
|
|
735
|
+
"assertions": [
|
|
736
|
+
{
|
|
737
|
+
"name": "checks-pin-and-addressed-delivery",
|
|
738
|
+
"description": "Reads the browser-pinned card via native Amp tools, claims using amp-review, and verifies a different recipient does not receive the addressed test message",
|
|
739
|
+
"type": "output_check"
|
|
740
|
+
},
|
|
741
|
+
{
|
|
742
|
+
"name": "verifies-edit-before-ack",
|
|
743
|
+
"description": "Signals intent, preserves card content, verifies CHECK-30 in the browser before marking delivery, then confirms no pending test message remains",
|
|
744
|
+
"type": "output_check"
|
|
745
|
+
},
|
|
746
|
+
{
|
|
747
|
+
"name": "does-not-overclaim-host-support",
|
|
748
|
+
"description": "Distinguishes active-agent polling from idle wake-up/background pumps and tools/resources from native Skills discovery; cleans up only test-owned sessions",
|
|
749
|
+
"type": "output_check"
|
|
750
|
+
}
|
|
751
|
+
]
|
|
752
|
+
},
|
|
753
|
+
{
|
|
754
|
+
"id": 31,
|
|
755
|
+
"name": "json-focus-runtime-state-continuity",
|
|
756
|
+
"prompt": "On a disposable board, verify that an unsaved JSON form and dynamic list survive inline-to-focus and focus-to-inline transitions. Seed draft Initial and one item; use the browser to enter DRAFT-MUST-SURVIVE and load 16 items, expand, then enter EXPANDED-MUST-SURVIVE and replace the list with three distinct items, and close. Does this also prove the draft survives a reload or spec replacement?",
|
|
757
|
+
"expected_output": "Runs the browser regression with bound input and echo plus runtime list values in both directions, without saving or updating the spec between transitions. Verifies exact values and counts, not only node size or server spec. Exercises src and srcdoc including AX-disabled JSON. Proves the regression fails with the old behavior before trusting green. Separately confirms an authored spec revision resets to the new seed and the server spec was not silently changed by runtime edits. Reports local focus continuity separately from durable AX state, page reload, other hosts, HTML and external apps; a defined eval is not a completed benchmark.",
|
|
758
|
+
"assertions": [
|
|
759
|
+
{
|
|
760
|
+
"name": "verifies-both-directions-in-browser",
|
|
761
|
+
"description": "Checks exact bound input, echo and asymmetric list contents/counts inline to focus and back without an intervening save or spec edit",
|
|
762
|
+
"type": "output_check"
|
|
763
|
+
},
|
|
764
|
+
{
|
|
765
|
+
"name": "checks-transport-and-revision-boundaries",
|
|
766
|
+
"description": "Runs src and srcdoc including AX-disabled JSON, verifies authored spec replacement resets runtime state and ordinary input edits leave server spec unchanged",
|
|
767
|
+
"type": "output_check"
|
|
768
|
+
},
|
|
769
|
+
{
|
|
770
|
+
"name": "discriminates-and-limits-claims",
|
|
771
|
+
"description": "Records a failure against old behavior and a passing fixed run; does not infer persistence across reloads, native-host support or scored model quality",
|
|
772
|
+
"type": "output_check"
|
|
773
|
+
}
|
|
774
|
+
]
|
|
706
775
|
}
|
|
707
776
|
]
|
|
708
777
|
}
|
|
@@ -128,11 +128,11 @@ pmx-canvas # Start and open browser (port 4313)
|
|
|
128
128
|
pmx-canvas --no-open # Start without opening browser (for agents)
|
|
129
129
|
pmx-canvas --port=8080 # Custom port
|
|
130
130
|
pmx-canvas --demo # Start with sample content
|
|
131
|
-
pmx-canvas --theme=
|
|
131
|
+
pmx-canvas --theme=daylight # Daylight theme
|
|
132
132
|
pmx-canvas --version # Print installed version and exit
|
|
133
133
|
```
|
|
134
134
|
|
|
135
|
-
`--theme` accepts `
|
|
135
|
+
`--theme` accepts `harbor` (default), `daylight`, `high-contrast`, `midnight`, `sepia`, `arctic`, `ember`, `forest`, or `volt` (0.4.x; the rail's theme picker lists the same nine). Same value can be set via
|
|
136
136
|
the `PMX_CANVAS_THEME` environment variable, or picked live from the left tool rail.
|
|
137
137
|
|
|
138
138
|
Start the canvas once per session, then reuse it. Use `--no-open` when running as an agent — the
|
|
@@ -430,8 +430,8 @@ single-purpose tools behind an `action` (and, for `canvas_ax_gate`, a `kind`) di
|
|
|
430
430
|
|
|
431
431
|
> **Legacy single-purpose tools were removed in v0.3.0.** The old names (`canvas_add_node`,
|
|
432
432
|
> `canvas_update_node`, `canvas_request_approval`, `canvas_add_work_item`, …) are no longer
|
|
433
|
-
> registered — use the composites
|
|
434
|
-
>
|
|
433
|
+
> registered — use the composites below and fresh MCP `tools/list` for the installed runtime's
|
|
434
|
+
> authoritative action schemas. This skill does not re-enumerate the removed names.
|
|
435
435
|
|
|
436
436
|
### The 18 composites
|
|
437
437
|
|
|
@@ -439,7 +439,7 @@ single-purpose tools behind an `action` (and, for `canvas_ax_gate`, a `kind`) di
|
|
|
439
439
|
|-----------|-----------------|--------------|
|
|
440
440
|
| `canvas_import` | `list` · `read` · `submit` · `unavailable` | Process human-requested imports: inspect metadata/controlled bytes, submit reviewable Markdown with references/warnings/agent description, or report unavailable. Request/cancel/commit are human-only |
|
|
441
441
|
| `canvas_node` | `add` · `get` · `update` · `remove` | Create / read / mutate / delete a node. **`add` covers html + primitives too**: `{ action:"add", type:"html", html:"…" }` and `{ action:"add", type:"html", primitive:"choice-grid", data:{} }` — no separate add-html tool needed |
|
|
442
|
-
| `canvas_render` | `describe-schema` · `validate` · `add-json-render` · `stream-json-render` · `add-graph` | Schema introspection, spec dry-run validation,
|
|
442
|
+
| `canvas_render` | `describe-schema` · `validate` · `add-json-render` · `stream-json-render` · `add-graph` · `workboard` | Schema introspection, spec dry-run validation, native json-render / graph node creation, and a live AX work-item board |
|
|
443
443
|
| `canvas_edge` | `add` · `update` · `remove` | Connect / edit / disconnect nodes |
|
|
444
444
|
| `canvas_group` | `create` · `add` · `ungroup` | Manage spatial group containers |
|
|
445
445
|
| `canvas_history` | `undo` · `redo` | Time travel through the mutation ring buffer |
|
|
@@ -452,7 +452,7 @@ single-purpose tools behind an `action` (and, for `canvas_ax_gate`, a `kind`) di
|
|
|
452
452
|
| `canvas_ax_state` | `get` · `set-focus` · `set-policy` · `report-capability` · `presence` · `set-presence` | Read AX state; set AX focus; patch tool/prompt policy (the scope fence is human-set, read-only here); report host capability; read / set agent presence (phase, cursor, focus, attached session) |
|
|
453
453
|
| `canvas_ax_work` | `add` · `update` · `annotate` | Canvas-bound work items + review annotations |
|
|
454
454
|
| `canvas_ax_gate` | `request` · `resolve` · `await` × `kind` `approval` \| `elicitation` \| `mode` | Attributed gate lifecycle (request → await → resolve); attribution does not itself grant authority |
|
|
455
|
-
| `canvas_ax_timeline` | `read` · `record-event` · `add-evidence` · `send-steering` · `reads` | The bounded AX diagnostics timeline, and the context read log (`reads`) |
|
|
455
|
+
| `canvas_ax_timeline` | `read` · `record-event` · `add-evidence` · `send-steering` · `reads` · `read-status` | The bounded AX diagnostics timeline, and the context read log (`reads`) |
|
|
456
456
|
| `canvas_ax_delivery` | `claim` · `mark` | Adapterless steering delivery (claim → act → mark) |
|
|
457
457
|
| `canvas_intent` | `signal` · `update` · `clear` | Ghost Cursor of Intent — announce a move before making it |
|
|
458
458
|
|
|
@@ -508,7 +508,7 @@ coming and can veto it mid-thought. Intents are ephemeral presence: never
|
|
|
508
508
|
persisted, auto-expiring (~8s), never in `canvas_query layout`.
|
|
509
509
|
|
|
510
510
|
Narrate → linked mutation → automatic settle:
|
|
511
|
-
1. `canvas_intent { action: "signal", kind: "create",
|
|
511
|
+
1. `canvas_intent { action: "signal", kind: "create", nodeType: "markdown", label: "Add evidence", reason: "capturing the failing test", confidence: 0.8 }` → returns `intent.id` and the `position` the canvas chose.
|
|
512
512
|
2. Make the real move and pass that id: `canvas_node { action: "add", intentId: <intent.id>, ... }`.
|
|
513
513
|
3. PMX rejects the mutation if the intent was vetoed or expired; otherwise the
|
|
514
514
|
successful mutation settles the ghost into the resulting node automatically.
|
|
@@ -522,9 +522,13 @@ mcp-app) and `canvas_webview` do **not** accept an `intentId` and reject it with
|
|
|
522
522
|
400 — to telegraph one of those, signal a ghost, then `clear` it (or let it
|
|
523
523
|
expire) and run the open *without* an `intentId`.
|
|
524
524
|
|
|
525
|
-
Per kind, pass the anchor it renders against: `position` for `
|
|
526
|
-
`nodeId` for `move`/`edit`/`remove`, `edge: { from, to, type }` for
|
|
527
|
-
|
|
525
|
+
Per kind, pass the anchor it renders against: `position` for `move` (optional for
|
|
526
|
+
`create`), `nodeId` for `move`/`edit`/`remove`, `edge: { from, to, type }` for
|
|
527
|
+
`connect`. **Omit `position` on a create unless you know where the node goes:** the
|
|
528
|
+
canvas then forms the ghost where it will auto-place the node, keeps staged ghosts
|
|
529
|
+
from stacking, and lands the linked create on its ghost. Never pass a placeholder
|
|
530
|
+
such as `{ x: 0, y: 0 }`. The payoff is **legibility** — `reason` is shown beneath
|
|
531
|
+
the ghost.
|
|
528
532
|
|
|
529
533
|
**When to use vs skip.** Signal for adds, removes, and moves of visible nodes;
|
|
530
534
|
connecting nodes; creating groups; layout reorganizations; meaningful title/content
|
|
@@ -4,6 +4,10 @@ Use this reference when PMX Canvas is running inside the GitHub Copilot app as a
|
|
|
4
4
|
extension. The adapter is intentionally thin: PMX Canvas remains the state owner, and the extension
|
|
5
5
|
maps Copilot SDK features onto PMX AX primitives.
|
|
6
6
|
|
|
7
|
+
The [standalone agent plugin](../../../docs/agent-plugin.md) bundles this adapter and PMX's
|
|
8
|
+
MCP launcher. Its native canvas is Copilot-only; other Agent Plugins-compatible clients use
|
|
9
|
+
the portable MCP tools and browser workbench.
|
|
10
|
+
|
|
7
11
|
## Adapter Identity
|
|
8
12
|
|
|
9
13
|
- Extension path: `.github/extensions/pmx-canvas/extension.mjs`
|
|
@@ -17,9 +21,9 @@ maps Copilot SDK features onto PMX AX primitives.
|
|
|
17
21
|
packaged extension directory into the repository:
|
|
18
22
|
`mkdir -p .github/extensions && cp -R node_modules/pmx-canvas/.github/extensions/pmx-canvas .github/extensions/`
|
|
19
23
|
2. Reload Copilot app extensions with `extensions_reload` so `project:pmx-canvas` is registered.
|
|
20
|
-
3.
|
|
21
|
-
|
|
22
|
-
|
|
24
|
+
3. The adapter discovers a matching workspace daemon or starts the pinned package version
|
|
25
|
+
in `runtime.json` with Bun. It needs Bun on `PATH`, not a global `pmx-canvas` executable.
|
|
26
|
+
The shared daemon stays running when the extension exits.
|
|
23
27
|
4. Open the canvas with `extensionId: "project:pmx-canvas"`, `canvasId: "pmx-canvas"`, and a stable
|
|
24
28
|
`instanceId`.
|
|
25
29
|
5. If the first `invoke_canvas_action` immediately after `open_canvas` returns
|
|
@@ -66,6 +70,8 @@ end it after each task. Explicit agent IDs are reserved for genuinely independen
|
|
|
66
70
|
The Copilot app webview can leave nested `srcdoc` and `blob:` iframes blank, so PMX should route
|
|
67
71
|
generated frame HTML through `/api/canvas/frame-documents/...` instead.
|
|
68
72
|
- Connects to a matching local PMX server for the current workspace, or starts one when needed.
|
|
73
|
+
- Uses the session's working directory for startup, context, presence, and steering; Copilot's
|
|
74
|
+
`workspacePath` points to session artifacts and is not the project root.
|
|
69
75
|
- Reads `/api/canvas/ax/context` and injects pinned/focused context from
|
|
70
76
|
`onUserPromptSubmitted`.
|
|
71
77
|
- Exposes adapter actions for status, AX context refresh, AX focus, and explicit session steering.
|
|
@@ -137,16 +143,22 @@ All fields are optional:
|
|
|
137
143
|
}
|
|
138
144
|
```
|
|
139
145
|
|
|
140
|
-
Default discovery
|
|
146
|
+
Default discovery:
|
|
141
147
|
|
|
142
|
-
1. `serverUrl` input.
|
|
143
|
-
2. `
|
|
144
|
-
|
|
145
|
-
|
|
148
|
+
1. An explicit `serverUrl` input or `PMX_CANVAS_URL`, without silently choosing another target.
|
|
149
|
+
2. Workspace daemon pid-file ports, the preferred `PMX_CANVAS_PORT` / `PMX_WEB_CANVAS_PORT`,
|
|
150
|
+
and the normal MCP fallback ports, verified against the workspace's real path.
|
|
151
|
+
3. Serialized daemon startup for the session working directory when `autoStart` is not `false`.
|
|
146
152
|
|
|
147
153
|
The adapter rejects an unrelated running PMX server unless `allowWorkspaceMismatch` is true,
|
|
148
154
|
including when `serverUrl` is explicit.
|
|
149
155
|
|
|
156
|
+
To package this adapter in another plugin, copy `extension.mjs`, `steering-delivery.mjs`,
|
|
157
|
+
`runtime.mjs`, and `runtime.json`. For the portable MCP connector, also copy `start-mcp.mjs`,
|
|
158
|
+
`tools.json`, and `THIRD_PARTY_LICENSES.txt`, and invoke `start-mcp.mjs` with Bun. The agent calls
|
|
159
|
+
`canvas_connect_workspace` with its absolute project directory before using board tools;
|
|
160
|
+
plugin initialization must never adopt the installation directory as a project.
|
|
161
|
+
|
|
150
162
|
If discovery fails, the panel shows a connection page, not a partial workbench. It checks the
|
|
151
163
|
original target automatically; **Check connection** retries immediately and **Start server**
|
|
152
164
|
explicitly allows local startup even if `autoStart` was disabled. After recovery it navigates
|
|
@@ -4,7 +4,7 @@ Use this reference when the `pmx-canvas` skill is installed but the `pmx-canvas`
|
|
|
4
4
|
|
|
5
5
|
## Prerequisites and version
|
|
6
6
|
|
|
7
|
-
The examples pin **PMX Canvas 0.
|
|
7
|
+
The examples pin **PMX Canvas 0.8.0**, which requires **Bun >=1.4.2** even when
|
|
8
8
|
installed through npm: the CLI runs through Bun, not Node. Check `bun --version`
|
|
9
9
|
first. If missing or older, follow the [Bun installation instructions](https://bun.sh/docs/installation)
|
|
10
10
|
with the user's authorization. Ensure Bun is on the MCP host's PATH as well as the
|
|
@@ -17,11 +17,11 @@ in `SKILL.md`. Do not pair newer checkout guidance with an older runtime unknowi
|
|
|
17
17
|
## Install from npm
|
|
18
18
|
|
|
19
19
|
```bash
|
|
20
|
-
npm install -g pmx-canvas@0.
|
|
20
|
+
npm install -g pmx-canvas@0.8.0
|
|
21
21
|
pmx-canvas --version
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Without a global install, use `bunx pmx-canvas@0.
|
|
24
|
+
Without a global install, use `bunx pmx-canvas@0.8.0` in place of `pmx-canvas` in
|
|
25
25
|
the commands below. Do not use unpinned `bunx pmx-canvas` for a version-specific check.
|
|
26
26
|
|
|
27
27
|
## Choose the workspace and target
|
|
@@ -91,7 +91,7 @@ discards empty env values, remove `PMX_CANVAS_URL` from its launch environment i
|
|
|
91
91
|
"mcpServers": {
|
|
92
92
|
"canvas": {
|
|
93
93
|
"command": "bunx",
|
|
94
|
-
"args": ["pmx-canvas@0.
|
|
94
|
+
"args": ["pmx-canvas@0.8.0", "--mcp"],
|
|
95
95
|
"env": {
|
|
96
96
|
"PMX_CANVAS_WORKSPACE_ROOT": "/absolute/path/to/project",
|
|
97
97
|
"PMX_CANVAS_PORT": "14313",
|
|
@@ -123,6 +123,78 @@ If you are using a local checkout instead of the published package, point the co
|
|
|
123
123
|
Restart the host's MCP process after changing configuration. Inspect startup output for
|
|
124
124
|
fallback ports; do not assume the configured port is the one the MCP server bound.
|
|
125
125
|
|
|
126
|
+
## Amp: connect the agent separately from the portal
|
|
127
|
+
|
|
128
|
+
PMX does not ship a dedicated Amp lifecycle adapter. Amp can use the native MCP tools;
|
|
129
|
+
the portal is only the human's browser UI. Configure MCP inside the orb or runner where
|
|
130
|
+
Amp executes, not only on the user's laptop. Merge this into that workspace's
|
|
131
|
+
`.amp/settings.json`, preserving other settings (Amp does not use the generic `.mcp.json`):
|
|
132
|
+
|
|
133
|
+
```json
|
|
134
|
+
{
|
|
135
|
+
"amp.mcpServers": {
|
|
136
|
+
"canvas": {
|
|
137
|
+
"command": "bunx",
|
|
138
|
+
"args": ["pmx-canvas@0.8.0", "--mcp"],
|
|
139
|
+
"includeTools": ["canvas_*"],
|
|
140
|
+
"env": {
|
|
141
|
+
"PMX_CANVAS_WORKSPACE_ROOT": "/absolute/path/to/project",
|
|
142
|
+
"PMX_CANVAS_PORT": "14313",
|
|
143
|
+
"PMX_CANVAS_URL": "",
|
|
144
|
+
"PMX_CANVAS_AGENT_SOURCE": "amp"
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Replace root and port with the **existing portal service's actual workspace and local
|
|
152
|
+
listening port**. A supervised service may use an assigned `PORT`, not 4313 or 14313;
|
|
153
|
+
inspect its status/logs and `/health`. Do not put the public portal URL in the stdio
|
|
154
|
+
command or copy another test run's absolute paths. Use an absolute executable path if
|
|
155
|
+
the MCP process cannot find Bun. The `canvas_*` filter exposes the Canvas tool family.
|
|
156
|
+
|
|
157
|
+
### Workspace trust is a human approval
|
|
158
|
+
|
|
159
|
+
Run `amp mcp doctor` from this workspace to distinguish `awaiting approval` from a
|
|
160
|
+
missing executable or connection failure. A new workspace MCP command requires the
|
|
161
|
+
user to review and approve it. Give the user this command to run in that workspace's
|
|
162
|
+
orb Terminal or runner terminal (replace `canvas` if the configured server name differs):
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
amp mcp approve canvas
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The agent must not run this approval itself or move the command to global settings or
|
|
169
|
+
`--mcp-config` to bypass workspace trust. Approval authorizes execution of this MCP
|
|
170
|
+
command; it is not a new Canvas import consent or permission to mutate arbitrary boards.
|
|
171
|
+
After approval, reload MCP connections (`reload_mcp` in Amp) and require `connected`.
|
|
172
|
+
Discover `canvas` tools with `tool_search`; for the full unfiltered 0.8.0 server there
|
|
173
|
+
are 24 tools. If still absent, inspect the server status, command/PATH and target instead
|
|
174
|
+
of reinstalling blindly. See [Amp MCP documentation](https://ampcode.com/docs/customize/mcp).
|
|
175
|
+
|
|
176
|
+
### Verify native tools, then steering
|
|
177
|
+
|
|
178
|
+
1. Check `/health` for the expected package version and canonical workspace. Through
|
|
179
|
+
Amp's discovered tools, read `canvas_board { action: "get" }` and
|
|
180
|
+
`canvas_query { action: "context" }`; verify the board matches the visible portal.
|
|
181
|
+
A CLI smoke check or SDK-spawned MCP client does not establish native Amp discovery.
|
|
182
|
+
2. For a requested end-to-end check, use a disposable board. Pin a known card in the
|
|
183
|
+
portal and require a native context read to return that card as pinned. Use one
|
|
184
|
+
stable presence/steering identity (`amp` above, or a unique source per independent
|
|
185
|
+
agent); reuse any adapter-owned session instead of attaching a duplicate.
|
|
186
|
+
3. Send a fresh browser message addressed to that identity. The running agent claims
|
|
187
|
+
it with `canvas_ax_delivery` using the same `consumer`, reads the relevant card,
|
|
188
|
+
signals intent, and performs the requested edit through native Canvas tools.
|
|
189
|
+
4. Verify the visible result in the browser before marking the message delivered for
|
|
190
|
+
that consumer. A subsequent claim should omit it. Detach only test-owned sessions.
|
|
191
|
+
|
|
192
|
+
This proves an **active agent can poll and act**, not automatic wake-up of an idle Amp
|
|
193
|
+
thread, background polling, or automatic agent launch for imports. An MCP connection
|
|
194
|
+
does not install a steering pump. Only configure a pump/host integration when requested;
|
|
195
|
+
its startup backlog rules are in the main skill. Tool discovery and resource reads also
|
|
196
|
+
do not establish Amp support for native MCP Skills-extension discovery or activation.
|
|
197
|
+
|
|
126
198
|
## Verify the actual target before writes
|
|
127
199
|
|
|
128
200
|
For the local target selected above:
|
|
@@ -68,10 +68,11 @@ and check `$?`, then read the file.
|
|
|
68
68
|
|
|
69
69
|
- In the product source checkout, Bun tests live under `tests/unit/`.
|
|
70
70
|
- In the product source checkout, Playwright browser smoke lives under `tests/e2e/`.
|
|
71
|
-
- Playwright runs
|
|
72
|
-
`tests/e2e/reference-pane.pw.ts
|
|
73
|
-
|
|
74
|
-
|
|
71
|
+
- Playwright runs `desktop` (1440×900, the whole suite except the reference cases) and three
|
|
72
|
+
reference projects for `tests/e2e/reference-pane.pw.ts`: `narrow-600`, `middle-1024` and
|
|
73
|
+
`wide-1920`. The workbench lives anywhere from a narrow side pane to a full window, so every
|
|
74
|
+
node type must paint at all three. A new node type fails its coverage test until it gets a
|
|
75
|
+
reference case. Run one width alone with `bash scripts/run-playwright.sh --project=narrow-600`.
|
|
75
76
|
- Product CI runs those checkout suites: Bun coverage plus the browser smoke flow.
|
|
76
77
|
- An isolated installed consumer instead tests the package's public transports and host behavior;
|
|
77
78
|
it does not run or depend on the product checkout's source suites.
|
|
@@ -139,6 +140,12 @@ Four ways a test silently stops discriminating in this repo:
|
|
|
139
140
|
- For `graph`, `json-render`, `mcp-app`, webpage, and image nodes, API geometry is not enough.
|
|
140
141
|
Verify the rendered browser frame when changing sizing: iframe/body `scrollHeight` and
|
|
141
142
|
`scrollWidth` should fit the available frame unless scrolling is the intended behavior.
|
|
143
|
+
- For JSON focus transitions, edit a bound input and load a multi-item runtime list inline,
|
|
144
|
+
expand and verify both, edit/replace them in focus mode, then close and verify both again.
|
|
145
|
+
Exercise `src` and `srcdoc`, including AX-disabled JSON. No save, spec edit or reload belongs
|
|
146
|
+
between those assertions. Separately verify a real spec revision resets to authored state,
|
|
147
|
+
and that local drafts never entered the server spec. See `tests/e2e/json-render-forms.pw.ts`.
|
|
148
|
+
Eval definitions are not evidence of executing this browser regression or a model benchmark.
|
|
142
149
|
- When checking embedded frame fit manually, start from a clean seeded state, rebuild stale bundles,
|
|
143
150
|
and inspect the actual iframe document in a browser. Server dimensions can look correct while the
|
|
144
151
|
embedded content is still clipped.
|
|
@@ -160,6 +167,49 @@ Four ways a test silently stops discriminating in this repo:
|
|
|
160
167
|
- If browser tests fail after a client change, confirm the bundle was rebuilt and the server
|
|
161
168
|
started from the updated code
|
|
162
169
|
|
|
170
|
+
### Keep first-failure evidence before rerunning
|
|
171
|
+
|
|
172
|
+
Use a separate directory for each attempt, including non-browser probes. Save the exact
|
|
173
|
+
command, target/version, exit status, stdout and stderr; keep credentials out of logs.
|
|
174
|
+
Before rerunning Playwright, copy its failure traces/screenshots and results out of the
|
|
175
|
+
runner's overwritten output directory. Never overwrite an initial failure log with a rerun.
|
|
176
|
+
For a shell gate, capture its status even with `set -e`, for example:
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
attempt_dir=$(mktemp -d /tmp/pmx-check.XXXXXX)
|
|
180
|
+
printf '%s\n' 'bun run test' > "$attempt_dir/command.txt"
|
|
181
|
+
status=0
|
|
182
|
+
bun run test > "$attempt_dir/stdout.log" 2> "$attempt_dir/stderr.log" || status=$?
|
|
183
|
+
printf '%s\n' "$status" > "$attempt_dir/exit-status.txt"
|
|
184
|
+
# Inspect this attempt before rerunning; return the gate's original exit status.
|
|
185
|
+
(exit "$status")
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Record what changed between attempts. Distinguish harness corrections, product fixes,
|
|
189
|
+
unchanged retries and host approval. A corrected pass does not make the original attempt
|
|
190
|
+
green. If logs were lost, say so; never reconstruct them or claim first-run success.
|
|
191
|
+
|
|
192
|
+
## Native-host verification is separate from transport checks
|
|
193
|
+
|
|
194
|
+
Record source, packed-package, registry-package, portal and native-host results separately.
|
|
195
|
+
An SDK subprocess's MCP handshake/catalog is not evidence that Amp discovered tools.
|
|
196
|
+
For Amp setup/trust and the pin → read → addressed steer → edit → visible result → ack
|
|
197
|
+
procedure, follow the bundled [installation reference](../pmx-canvas/references/installing-pmx-canvas.md#amp-connect-the-agent-separately-from-the-portal).
|
|
198
|
+
MCP-only consumers should read `skill://pmx-canvas/references/installing-pmx-canvas.md`
|
|
199
|
+
directly with `resources/read`, not traverse outside the testing skill's resource tree.
|
|
200
|
+
Workspace trust approval belongs to the human; report a blocked native check until approved.
|
|
201
|
+
Include a different-recipient negative control for addressed delivery on a disposable board.
|
|
202
|
+
Verify the rendered edit before acknowledging; detach only test-owned sessions afterward.
|
|
203
|
+
Do not label active-agent polling as idle-thread wake-up, a persistent pump, or automatic
|
|
204
|
+
import-agent launch. Native MCP tools do not prove native Skills-extension discovery.
|
|
205
|
+
|
|
206
|
+
List unexercised surfaces explicitly: native Copilot/WebKit, Windows-native behavior,
|
|
207
|
+
physical mobile, OCR and Office extraction need their own evidence. Source adapter tests
|
|
208
|
+
or a source helper pointed at a published server do not establish installed-adapter execution.
|
|
209
|
+
Sampled resource digests are not a full-catalog audit; eval definitions are not scored model
|
|
210
|
+
results; a skipped mirror check is not validation. Do not change the product merely to
|
|
211
|
+
turn an untested surface into a claimed pass.
|
|
212
|
+
|
|
163
213
|
## Handoff Standard
|
|
164
214
|
|
|
165
215
|
Before marking work done, report:
|
|
@@ -20,6 +20,11 @@ cmd(
|
|
|
20
20
|
const sourcePaths = [
|
|
21
21
|
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/extension.mjs', import.meta.url)),
|
|
22
22
|
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/steering-delivery.mjs', import.meta.url)),
|
|
23
|
+
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/runtime.mjs', import.meta.url)),
|
|
24
|
+
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/runtime.json', import.meta.url)),
|
|
25
|
+
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/start-mcp.mjs', import.meta.url)),
|
|
26
|
+
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/tools.json', import.meta.url)),
|
|
27
|
+
fileURLToPath(new URL('../../../.github/extensions/pmx-canvas/THIRD_PARTY_LICENSES.txt', import.meta.url)),
|
|
23
28
|
];
|
|
24
29
|
const missingSource = sourcePaths.find((sourcePath) => !existsSync(sourcePath));
|
|
25
30
|
if (missingSource) {
|
package/src/cli/commands/view.ts
CHANGED
|
@@ -179,7 +179,7 @@ cmd(
|
|
|
179
179
|
[
|
|
180
180
|
'pmx-canvas serve',
|
|
181
181
|
'pmx-canvas serve --port=8080 --no-open',
|
|
182
|
-
'pmx-canvas serve --demo --theme=
|
|
182
|
+
'pmx-canvas serve --demo --theme=daylight',
|
|
183
183
|
'pmx-canvas --no-open --webview-automation',
|
|
184
184
|
],
|
|
185
185
|
async (_args) => {
|
package/src/cli/index.ts
CHANGED
|
@@ -149,9 +149,10 @@ function commandAfterGlobalTargetFlags(argv: string[]): string {
|
|
|
149
149
|
return '';
|
|
150
150
|
}
|
|
151
151
|
|
|
152
|
-
function runMcpServerProcess(): Promise<void> {
|
|
152
|
+
function runMcpServerProcess(app = false): Promise<void> {
|
|
153
153
|
return new Promise((resolvePromise, rejectPromise) => {
|
|
154
|
-
const
|
|
154
|
+
const entry = app ? resolve(cliDir, '..', 'mcp', 'app-server.ts') : mcpServerEntry;
|
|
155
|
+
const child = spawn(process.execPath, ['run', entry], {
|
|
155
156
|
stdio: 'inherit',
|
|
156
157
|
env: process.env,
|
|
157
158
|
});
|
|
@@ -222,6 +223,9 @@ if (firstArg === 'serve') {
|
|
|
222
223
|
const routedCommand = commandAfterGlobalTargetFlags(args);
|
|
223
224
|
if (AGENT_COMMANDS.has(routedCommand) && routedCommand !== 'serve') {
|
|
224
225
|
await runAgentCli(args);
|
|
226
|
+
} else if (args.includes('--mcp-app')) {
|
|
227
|
+
// Private MCP Apps profile: focused tools and a self-contained UI resource.
|
|
228
|
+
await runMcpServerProcess(true);
|
|
225
229
|
} else if (args.includes('--mcp')) {
|
|
226
230
|
// MCP server mode: stdio transport, auto-starts canvas on first tool call
|
|
227
231
|
await runMcpServerProcess();
|
|
@@ -274,7 +278,7 @@ Server options:
|
|
|
274
278
|
--log-file=PATH Daemon log file (default: ./.pmx-canvas/daemon-${port}.log)
|
|
275
279
|
--pid-file=PATH Optional daemon PID file (default: ./.pmx-canvas/daemon-${port}.pid)
|
|
276
280
|
--wait-ms=MS Health-check wait budget for daemon mode (default: 10000)
|
|
277
|
-
--theme=THEME Theme:
|
|
281
|
+
--theme=THEME Theme: harbor (default), daylight, high-contrast, midnight, sepia, arctic, ember, forest, volt
|
|
278
282
|
--webview-automation Start a headless Bun.WebView automation session for /workbench
|
|
279
283
|
--webview-backend=BACKEND Bun.WebView backend: chrome or webkit
|
|
280
284
|
--webview-width=PX Automation WebView width (default: 1280)
|
|
@@ -283,6 +287,7 @@ Server options:
|
|
|
283
287
|
--webview-chrome-argv=CSV Extra Chrome args for Bun.WebView, comma-separated
|
|
284
288
|
--webview-data-dir=PATH Persist automation browser storage in PATH
|
|
285
289
|
--mcp Run as MCP server (stdio transport)
|
|
290
|
+
--mcp-app Run the private MCP App profile (stdio; shared active board)
|
|
286
291
|
--help, -h Show this help
|
|
287
292
|
|
|
288
293
|
Agent CLI (works against running server):
|
package/src/client/App.tsx
CHANGED
|
@@ -54,6 +54,7 @@ import {
|
|
|
54
54
|
import { connectSSE } from './state/sse-bridge';
|
|
55
55
|
import { intents } from './state/intent-store';
|
|
56
56
|
import { sessionActive } from './state/presence-store';
|
|
57
|
+
import { isHostedWorkbench } from './state/workbench-transport';
|
|
57
58
|
import {
|
|
58
59
|
createGroupFromClient,
|
|
59
60
|
removeEdgeFromClient,
|
|
@@ -376,7 +377,11 @@ export function App() {
|
|
|
376
377
|
intents.value.size === 0 && <EmptyState onOpenPalette={() => setPaletteOpen(true)} />
|
|
377
378
|
)}
|
|
378
379
|
{selectedNodeIds.value.size > 0 && <SelectionBar />}
|
|
379
|
-
{sessionIsActive
|
|
380
|
+
{sessionIsActive && !isHostedWorkbench() ? (
|
|
381
|
+
<CommandBar />
|
|
382
|
+
) : (
|
|
383
|
+
contextPinnedNodeIds.value.size > 0 && <ContextPinBar />
|
|
384
|
+
)}
|
|
380
385
|
<SessionReceipt onOpenSnapshots={() => setSnapshotOpen(true)} />
|
|
381
386
|
<TextPrompt />
|
|
382
387
|
<ExportDialog />
|