pmx-canvas 0.7.2 → 0.7.3
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/CHANGELOG.md +13 -0
- package/Readme.md +25 -11
- package/dist/canvas/global.css +123 -40
- package/dist/canvas/index.js +84 -84
- package/dist/json-render/index.js +55 -55
- package/dist/types/client/canvas/ChoiceMenu.d.ts +13 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +2 -1
- package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -0
- package/dist/types/client/state/canvas-store.d.ts +2 -0
- package/dist/types/client/state/intent-bridge.d.ts +1 -1
- package/dist/types/json-render/renderer/index.d.ts +2 -1
- package/dist/types/json-render/server.d.ts +2 -0
- package/dist/types/shared/ax-surface-protocol.d.ts +2 -0
- package/docs/ax-host-adapter-contract.md +13 -2
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +23 -11
- package/skills/pmx-canvas/evals/evals.json +69 -0
- package/skills/pmx-canvas/references/full-reference.md +3 -3
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +76 -4
- package/skills/pmx-canvas-testing/SKILL.md +49 -0
- package/src/client/canvas/CanvasNode.tsx +200 -195
- package/src/client/canvas/CanvasViewport.tsx +6 -0
- package/src/client/canvas/ChoiceMenu.tsx +122 -0
- package/src/client/canvas/CommandBar.tsx +25 -23
- package/src/client/canvas/FeedbackDialog.tsx +10 -8
- package/src/client/canvas/ToolRail.tsx +46 -99
- package/src/client/nodes/McpAppNode.tsx +16 -0
- package/src/client/nodes/use-ax-surface-bridge.ts +4 -2
- package/src/client/nodes/viewer-runtime-state.ts +78 -0
- package/src/client/state/canvas-store.ts +3 -0
- package/src/client/state/intent-bridge.ts +14 -2
- package/src/client/theme/global.css +123 -40
- package/src/json-render/renderer/index.tsx +58 -38
- package/src/json-render/server.ts +8 -1
- package/src/server/server.ts +3 -1
- package/src/shared/ax-surface-protocol.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,19 @@
|
|
|
3
3
|
All notable changes to `pmx-canvas` are documented here. This project follows
|
|
4
4
|
[Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.7.3] - 2026-10-01
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- JSON form values and dynamic lists survive expanding and closing focus mode without silently saving drafts to the server; authored spec updates still reset runtime state.
|
|
11
|
+
- Interactive surfaces register their action bridge before first paint.
|
|
12
|
+
- Bundled skill quick references match live MCP discovery, including board opening and workboards, and distinguish local JSON runtime state from durable data.
|
|
13
|
+
- Amp setup guidance covers workspace trust approval, portal targeting and native steering verification; testing guidance preserves first-failure evidence and distinguishes host coverage gaps.
|
|
14
|
+
- The main toolbar keeps Markdown, Attach files, Webpage and Group; one file picker replaces separate File, Image and HTML buttons, with supported formats explained in its tooltip.
|
|
15
|
+
- Draw, Text note and Eraser are separate toolbar buttons for quick board feedback.
|
|
16
|
+
- Connection handles are easier to grab at any zoom, and saved connections appear without waiting for the next background update.
|
|
17
|
+
- Feedback and agent selectors use themed menus, and Cancel actions have clearer button styling.
|
|
18
|
+
|
|
6
19
|
## [0.7.2] - 2026-09-30
|
|
7
20
|
|
|
8
21
|
### Added
|
package/Readme.md
CHANGED
|
@@ -397,20 +397,33 @@ merge this into the workspace's `.amp/settings.json` (not `.mcp.json`):
|
|
|
397
397
|
"amp.mcpServers": {
|
|
398
398
|
"canvas": {
|
|
399
399
|
"command": "bunx",
|
|
400
|
-
"args": ["pmx-canvas@0.7.
|
|
400
|
+
"args": ["pmx-canvas@0.7.3", "--mcp"],
|
|
401
|
+
"includeTools": ["canvas_*"],
|
|
402
|
+
"env": {
|
|
403
|
+
"PMX_CANVAS_WORKSPACE_ROOT": "/absolute/path/to/project",
|
|
404
|
+
"PMX_CANVAS_PORT": "14313",
|
|
405
|
+
"PMX_CANVAS_URL": "",
|
|
406
|
+
"PMX_CANVAS_AGENT_SOURCE": "amp"
|
|
407
|
+
}
|
|
401
408
|
}
|
|
402
409
|
}
|
|
403
410
|
}
|
|
404
411
|
```
|
|
405
412
|
|
|
413
|
+
Replace the root and example port with the portal service's actual workspace and local
|
|
414
|
+
listening port, including an orb-assigned port. Configure this inside the orb/runner;
|
|
415
|
+
settings on your laptop are not automatically available there.
|
|
406
416
|
In the PMX product checkout, use `"command": "bun"` and
|
|
407
417
|
`"args": ["run", "src/mcp/server.ts"]` to test the checked-out source instead.
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
418
|
+
Run `amp mcp doctor` in that workspace. If it reports `awaiting approval`, the user
|
|
419
|
+
must review the command and run `amp mcp approve canvas` there; the agent must not
|
|
420
|
+
self-approve or bypass workspace trust. Then reload MCP connections and confirm
|
|
421
|
+
`connected`, Canvas tool discovery, and matching `/health.workspace`, version and
|
|
422
|
+
active board before writes. An open portal or standalone MCP handshake does not prove
|
|
423
|
+
native discovery. PMX ships no dedicated Amp lifecycle adapter: an active agent can
|
|
424
|
+
poll steering, but MCP setup alone does not wake an idle thread or activate skills.
|
|
425
|
+
See the bundled [Amp setup and verification guide](skills/pmx-canvas/references/installing-pmx-canvas.md#amp-connect-the-agent-separately-from-the-portal)
|
|
426
|
+
and [Amp MCP configuration](https://ampcode.com/docs/customize/mcp).
|
|
414
427
|
|
|
415
428
|
For the visible workbench, run `pmx-canvas` as an orb service (the orb sets
|
|
416
429
|
`AMP_ORB` in the environment automatically) and open the workbench through the
|
|
@@ -428,7 +441,7 @@ services:
|
|
|
428
441
|
```bash
|
|
429
442
|
# .agents/setup — install the CLI (pin the exact version: a fresh orb running
|
|
430
443
|
# @latest can silently pick up a newer release than the one you validated)
|
|
431
|
-
npm install -g pmx-canvas@0.7.
|
|
444
|
+
npm install -g pmx-canvas@0.7.3
|
|
432
445
|
```
|
|
433
446
|
|
|
434
447
|
The server binds the portal-assigned `$PORT` automatically (gated on the
|
|
@@ -444,9 +457,10 @@ be inlined and stay blocked by the portal embed: cross-origin hosted apps (e.g.
|
|
|
444
457
|
the hosted Excalidraw MCP app), and PDF file nodes — a PDF node offers an
|
|
445
458
|
"Open PDF" link there instead of a preview.
|
|
446
459
|
Debug overrides: `/workbench?transport=poll|sse` and
|
|
447
|
-
`?iframe-mode=srcdoc|src`.
|
|
448
|
-
|
|
449
|
-
|
|
460
|
+
`?iframe-mode=srcdoc|src`. After verifying the workspace, `pmx-canvas smoke --port=<actual-port>`
|
|
461
|
+
checks health, versions, a standalone MCP handshake, node lifecycle and validation.
|
|
462
|
+
Use a disposable board: it performs temporary writes and leaves history. This does
|
|
463
|
+
not verify native Amp discovery or browser rendering.
|
|
450
464
|
|
|
451
465
|
### Install the agent skill (recommended)
|
|
452
466
|
|
package/dist/canvas/global.css
CHANGED
|
@@ -572,9 +572,23 @@ body,
|
|
|
572
572
|
box-shadow: 0 4px 24px var(--c-shadow);
|
|
573
573
|
display: flex;
|
|
574
574
|
flex-direction: column;
|
|
575
|
-
overflow:
|
|
575
|
+
overflow: visible;
|
|
576
576
|
transition: box-shadow 0.15s ease;
|
|
577
|
-
contain: layout style
|
|
577
|
+
contain: layout style;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/* Clip card content, not the connection handles centered on its border. */
|
|
581
|
+
.node-content {
|
|
582
|
+
display: flex;
|
|
583
|
+
flex-direction: column;
|
|
584
|
+
flex: 1;
|
|
585
|
+
min-height: 0;
|
|
586
|
+
border-radius: inherit;
|
|
587
|
+
overflow: hidden;
|
|
588
|
+
contain: paint;
|
|
589
|
+
}
|
|
590
|
+
.group-node > .node-content {
|
|
591
|
+
display: contents;
|
|
578
592
|
}
|
|
579
593
|
|
|
580
594
|
.canvas-node:hover {
|
|
@@ -610,34 +624,42 @@ body,
|
|
|
610
624
|
/* ── Connection port handles (drag-to-connect) ───────────── */
|
|
611
625
|
.node-port {
|
|
612
626
|
position: absolute;
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
627
|
+
/* The visible dot stays compact; its grab area stays usable at every zoom. */
|
|
628
|
+
width: calc(32px * var(--node-port-scale, 1));
|
|
629
|
+
height: calc(32px * var(--node-port-scale, 1));
|
|
630
|
+
display: grid;
|
|
631
|
+
place-items: center;
|
|
618
632
|
opacity: 0;
|
|
619
633
|
cursor: crosshair;
|
|
620
634
|
z-index: 10;
|
|
621
|
-
|
|
622
|
-
|
|
635
|
+
touch-action: none;
|
|
636
|
+
transition: opacity 0.15s;
|
|
623
637
|
pointer-events: auto;
|
|
624
638
|
}
|
|
625
|
-
.
|
|
639
|
+
.node-port::after {
|
|
640
|
+
content: '';
|
|
641
|
+
width: calc(6px * var(--node-port-scale, 1));
|
|
642
|
+
height: calc(6px * var(--node-port-scale, 1));
|
|
643
|
+
border-radius: 50%;
|
|
644
|
+
background: var(--c-accent);
|
|
645
|
+
border: calc(2px * var(--node-port-scale, 1)) solid var(--c-panel);
|
|
646
|
+
box-shadow: 0 0 0 calc(1px * var(--node-port-scale, 1)) var(--c-accent);
|
|
647
|
+
}
|
|
648
|
+
.canvas-node:hover .node-port,
|
|
649
|
+
.canvas-node.selected .node-port,
|
|
650
|
+
.canvas-node:focus-within .node-port {
|
|
626
651
|
opacity: 1;
|
|
627
|
-
transform: translate(-50%, -50%) scale(1);
|
|
628
652
|
}
|
|
629
|
-
.node-port:hover {
|
|
653
|
+
.node-port:hover::after {
|
|
630
654
|
background: var(--c-accent-hover);
|
|
631
|
-
transform: translate(-50%, -50%) scale(1.3);
|
|
632
655
|
}
|
|
633
|
-
|
|
634
|
-
.node-port-
|
|
635
|
-
.node-port-
|
|
636
|
-
.node-port-
|
|
637
|
-
.
|
|
638
|
-
.
|
|
639
|
-
.node-port-
|
|
640
|
-
.node-port-right:hover { transform: translate(50%, -50%) scale(1.3); }
|
|
656
|
+
/* Bias vertical grab areas outward so they do not steal title/footer clicks. */
|
|
657
|
+
.node-port-top { top: 0; left: 50%; transform: translate(-50%, -75%); }
|
|
658
|
+
.node-port-bottom { bottom: 0; left: 50%; transform: translate(-50%, 75%); }
|
|
659
|
+
.node-port-top::after { transform: translateY(calc(8px * var(--node-port-scale, 1))); }
|
|
660
|
+
.node-port-bottom::after { transform: translateY(calc(-8px * var(--node-port-scale, 1))); }
|
|
661
|
+
.node-port-left { left: 0; top: 50%; transform: translate(-50%, -50%); }
|
|
662
|
+
.node-port-right { right: 0; top: 50%; transform: translate(50%, -50%); }
|
|
641
663
|
|
|
642
664
|
.canvas-node .node-titlebar {
|
|
643
665
|
display: flex;
|
|
@@ -2001,6 +2023,7 @@ body,
|
|
|
2001
2023
|
color: var(--c-dim);
|
|
2002
2024
|
}
|
|
2003
2025
|
.command-bar-composer {
|
|
2026
|
+
position: relative;
|
|
2004
2027
|
display: flex;
|
|
2005
2028
|
align-items: center;
|
|
2006
2029
|
gap: 10px;
|
|
@@ -2012,24 +2035,72 @@ body,
|
|
|
2012
2035
|
box-shadow: 0 12px 40px rgba(0, 0, 0, 0.5);
|
|
2013
2036
|
}
|
|
2014
2037
|
.command-bar-target {
|
|
2015
|
-
appearance: none;
|
|
2016
|
-
-webkit-appearance: none;
|
|
2017
2038
|
max-width: 148px;
|
|
2018
|
-
padding: 4px 18px 4px 8px;
|
|
2019
|
-
border: 1px solid var(--c-line);
|
|
2020
|
-
border-radius: 7px;
|
|
2021
|
-
background: color-mix(in srgb, var(--c-panel) 80%, transparent)
|
|
2022
|
-
url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='5'%3E%3Cpath d='M1 1l3 3 3-3' fill='none' stroke='%237a8699' stroke-width='1.4'/%3E%3C/svg%3E")
|
|
2023
|
-
no-repeat right 6px center;
|
|
2024
|
-
color: var(--c-text-soft);
|
|
2025
|
-
font: 12px/1.3 var(--mono);
|
|
2026
|
-
cursor: pointer;
|
|
2027
2039
|
flex-shrink: 0;
|
|
2028
2040
|
}
|
|
2029
|
-
.
|
|
2030
|
-
|
|
2031
|
-
|
|
2041
|
+
.choice-menu {
|
|
2042
|
+
position: relative;
|
|
2043
|
+
min-width: 0;
|
|
2044
|
+
}
|
|
2045
|
+
.choice-menu-trigger {
|
|
2046
|
+
display: flex;
|
|
2047
|
+
align-items: center;
|
|
2048
|
+
justify-content: space-between;
|
|
2049
|
+
gap: 10px;
|
|
2050
|
+
width: 100%;
|
|
2051
|
+
min-height: 36px;
|
|
2052
|
+
padding: 8px 10px;
|
|
2053
|
+
border: 1px solid color-mix(in srgb, var(--c-line) 65%, var(--c-muted));
|
|
2054
|
+
border-radius: 8px;
|
|
2055
|
+
background: var(--c-panel-overlay);
|
|
2032
2056
|
color: var(--c-text);
|
|
2057
|
+
font: 12px/1.35 var(--font);
|
|
2058
|
+
cursor: pointer;
|
|
2059
|
+
}
|
|
2060
|
+
.choice-menu-trigger > span {
|
|
2061
|
+
overflow: hidden;
|
|
2062
|
+
text-overflow: ellipsis;
|
|
2063
|
+
white-space: nowrap;
|
|
2064
|
+
}
|
|
2065
|
+
.choice-menu-trigger svg { flex-shrink: 0; }
|
|
2066
|
+
.choice-menu-trigger:hover,
|
|
2067
|
+
.choice-menu-trigger[aria-expanded='true'] { border-color: var(--c-accent); }
|
|
2068
|
+
.choice-menu-trigger:focus-visible,
|
|
2069
|
+
.choice-menu-options button:focus-visible {
|
|
2070
|
+
outline: 2px solid var(--c-accent);
|
|
2071
|
+
outline-offset: 2px;
|
|
2072
|
+
}
|
|
2073
|
+
.toolbar-menu.choice-menu-options {
|
|
2074
|
+
top: calc(100% + 6px);
|
|
2075
|
+
left: 0;
|
|
2076
|
+
right: auto;
|
|
2077
|
+
min-width: 100%;
|
|
2078
|
+
width: max-content;
|
|
2079
|
+
max-width: min(320px, calc(100vw - 64px));
|
|
2080
|
+
max-height: min(280px, 40vh);
|
|
2081
|
+
overflow-y: auto;
|
|
2082
|
+
z-index: 20;
|
|
2083
|
+
}
|
|
2084
|
+
.toolbar-menu.choice-menu-options.opens-above {
|
|
2085
|
+
top: auto;
|
|
2086
|
+
bottom: calc(100% + 6px);
|
|
2087
|
+
}
|
|
2088
|
+
.command-bar-target.choice-menu {
|
|
2089
|
+
position: static;
|
|
2090
|
+
}
|
|
2091
|
+
.command-bar-target .choice-menu-options {
|
|
2092
|
+
/* Anchor to the composer, not its inset trigger, to clear the session rail. */
|
|
2093
|
+
min-width: min(200px, 100%);
|
|
2094
|
+
max-width: 100%;
|
|
2095
|
+
}
|
|
2096
|
+
.choice-menu-options .toolbar-menu-item {
|
|
2097
|
+
min-height: 36px;
|
|
2098
|
+
white-space: normal;
|
|
2099
|
+
overflow-wrap: anywhere;
|
|
2100
|
+
}
|
|
2101
|
+
.choice-menu-options button:disabled {
|
|
2102
|
+
opacity: 0.5;
|
|
2103
|
+
cursor: not-allowed;
|
|
2033
2104
|
}
|
|
2034
2105
|
|
|
2035
2106
|
.command-bar-icon {
|
|
@@ -4498,13 +4569,24 @@ html.is-node-resizing .ext-app-preview-catcher {
|
|
|
4498
4569
|
}
|
|
4499
4570
|
.text-prompt-cancel,
|
|
4500
4571
|
.text-prompt-confirm {
|
|
4501
|
-
|
|
4572
|
+
min-height: 36px;
|
|
4573
|
+
padding: 8px 14px;
|
|
4502
4574
|
border-radius: 7px;
|
|
4503
|
-
border: 1px solid var(--c-line);
|
|
4504
|
-
background:
|
|
4505
|
-
color: var(--c-text
|
|
4575
|
+
border: 1px solid color-mix(in srgb, var(--c-line) 65%, var(--c-muted));
|
|
4576
|
+
background: var(--c-panel-overlay);
|
|
4577
|
+
color: var(--c-text);
|
|
4506
4578
|
cursor: pointer;
|
|
4507
4579
|
font-size: 12px;
|
|
4580
|
+
font-weight: 600;
|
|
4581
|
+
}
|
|
4582
|
+
.text-prompt-cancel:hover {
|
|
4583
|
+
background: var(--c-accent-10);
|
|
4584
|
+
border-color: var(--c-muted);
|
|
4585
|
+
}
|
|
4586
|
+
.text-prompt-cancel:focus-visible,
|
|
4587
|
+
.text-prompt-confirm:focus-visible {
|
|
4588
|
+
outline: 2px solid var(--c-accent);
|
|
4589
|
+
outline-offset: 2px;
|
|
4508
4590
|
}
|
|
4509
4591
|
.text-prompt-confirm {
|
|
4510
4592
|
background: var(--c-accent);
|
|
@@ -4524,7 +4606,8 @@ html.is-node-resizing .ext-app-preview-catcher {
|
|
|
4524
4606
|
overflow-y: auto;
|
|
4525
4607
|
color: var(--c-text);
|
|
4526
4608
|
}
|
|
4527
|
-
.feedback-dialog label
|
|
4609
|
+
.feedback-dialog label,
|
|
4610
|
+
.feedback-field {
|
|
4528
4611
|
display: flex;
|
|
4529
4612
|
flex-direction: column;
|
|
4530
4613
|
gap: 6px;
|