pmx-canvas 0.2.7 → 0.3.1
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 +148 -1
- package/Readme.md +13 -11
- package/dist/canvas/index.js +2 -2
- package/dist/json-render/index.css +1 -1
- package/dist/types/cli/daemon.d.ts +74 -0
- package/dist/types/cli/watch.d.ts +2 -2
- package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
- package/dist/types/client/canvas/CommandPalette.d.ts +1 -1
- package/dist/types/client/canvas/Minimap.d.ts +1 -1
- package/dist/types/client/nodes/FileNode.d.ts +1 -1
- package/dist/types/client/nodes/ImageNode.d.ts +1 -1
- package/dist/types/client/nodes/InlineFormatBar.d.ts +1 -1
- package/dist/types/client/nodes/MarkdownNode.d.ts +1 -1
- package/dist/types/client/nodes/PromptNode.d.ts +1 -1
- package/dist/types/client/nodes/ResponseNode.d.ts +1 -1
- package/dist/types/mcp/canvas-access.d.ts +0 -7
- package/dist/types/server/ax-state-manager.d.ts +3 -2
- package/dist/types/server/bundled-skills.d.ts +3 -3
- package/dist/types/server/canvas-schema.d.ts +1 -1
- package/dist/types/server/canvas-state.d.ts +2 -0
- package/dist/types/server/ext-app-lookup.d.ts +1 -3
- package/dist/types/server/html-primitives.d.ts +1 -1
- package/dist/types/server/index.d.ts +4 -4
- package/dist/types/server/operations/composites.d.ts +29 -23
- package/dist/types/server/operations/http.d.ts +2 -1
- package/dist/types/server/operations/index.d.ts +1 -1
- package/dist/types/server/operations/ops/ax-read.d.ts +2 -0
- package/dist/types/server/operations/ops/canvas-wire.d.ts +2 -0
- package/dist/types/server/operations/ops/ext-app.d.ts +2 -0
- package/dist/types/shared/ax-intent.d.ts +1 -1
- package/docs/RELEASE.md +23 -8
- package/docs/ax-host-adapter-contract.md +7 -7
- package/docs/ax-state-contract.md +7 -6
- package/docs/bun-webview-integration.md +5 -5
- package/docs/cli.md +1 -1
- package/docs/http-api.md +35 -3
- package/docs/mcp.md +121 -100
- package/docs/node-types.md +45 -35
- package/docs/plans/plan-006-mcp-tool-consolidation.md +3 -1
- package/docs/plans/plan-008-registry-finish.md +2 -0
- package/docs/plans/plan-009-tech-debt-backlog.md +51 -0
- package/docs/screenshot.png +0 -0
- package/docs/tech-debt-assessment-2026-06.md +1 -1
- package/docs/tech-debt-assessment-2026-07.md +135 -0
- package/package.json +5 -2
- package/skills/data-analysis/SKILL.md +3 -3
- package/skills/frontend-design/SKILL.md +3 -2
- package/skills/json-render-mcp/SKILL.md +4 -3
- package/skills/playwright-cli/SKILL.md +1 -1
- package/skills/pmx-canvas/SKILL.md +12 -7
- package/skills/pmx-canvas/evals/evals.json +2 -2
- package/skills/pmx-canvas/references/ax-html-control-surface.md +3 -1
- package/skills/pmx-canvas/references/excalidraw-diagram-authoring.md +2 -2
- package/skills/pmx-canvas/references/full-reference.md +58 -56
- package/skills/pmx-canvas/references/html-primitives.md +3 -3
- package/skills/tufte-viz/SKILL.md +5 -4
- package/skills/web-artifacts-builder/SKILL.md +4 -4
- package/src/cli/agent.ts +1861 -1548
- package/src/cli/daemon.ts +460 -0
- package/src/cli/index.ts +63 -326
- package/src/cli/watch.ts +2 -10
- package/src/client/App.tsx +48 -46
- package/src/client/canvas/AttentionHistory.tsx +11 -1
- package/src/client/canvas/CanvasNode.tsx +41 -29
- package/src/client/canvas/CanvasViewport.tsx +101 -66
- package/src/client/canvas/CommandPalette.tsx +61 -27
- package/src/client/canvas/ContextMenu.tsx +13 -20
- package/src/client/canvas/ContextPinBar.tsx +1 -5
- package/src/client/canvas/ContextPinHud.tsx +1 -6
- package/src/client/canvas/DockedNode.tsx +4 -4
- package/src/client/canvas/EdgeLayer.tsx +37 -36
- package/src/client/canvas/ExpandedNodeOverlay.tsx +69 -45
- package/src/client/canvas/FocusFieldLayer.tsx +20 -22
- package/src/client/canvas/IntentLayer.tsx +31 -14
- package/src/client/canvas/Minimap.tsx +11 -16
- package/src/client/canvas/SelectionBar.tsx +4 -11
- package/src/client/canvas/ShortcutOverlay.tsx +3 -1
- package/src/client/canvas/SnapshotPanel.tsx +77 -95
- package/src/client/canvas/auto-fit.ts +15 -14
- package/src/client/canvas/snap-guides.ts +12 -12
- package/src/client/canvas/use-node-resize.ts +1 -5
- package/src/client/canvas/use-pan-zoom.ts +25 -26
- package/src/client/ext-app/bridge.ts +3 -12
- package/src/client/icons.tsx +63 -20
- package/src/client/nodes/ContextNode.tsx +14 -25
- package/src/client/nodes/ExtAppFrame.tsx +60 -39
- package/src/client/nodes/FileNode.tsx +74 -62
- package/src/client/nodes/GroupNode.tsx +4 -6
- package/src/client/nodes/HtmlNode.tsx +76 -46
- package/src/client/nodes/ImageNode.tsx +18 -27
- package/src/client/nodes/InlineFormatBar.tsx +4 -21
- package/src/client/nodes/InlineMarkdownEditor.tsx +0 -1
- package/src/client/nodes/LedgerNode.tsx +10 -4
- package/src/client/nodes/MarkdownNode.tsx +3 -10
- package/src/client/nodes/McpAppNode.tsx +26 -22
- package/src/client/nodes/MdFormatBar.tsx +10 -7
- package/src/client/nodes/PromptNode.tsx +23 -51
- package/src/client/nodes/ResponseNode.tsx +3 -13
- package/src/client/nodes/StatusNode.tsx +5 -9
- package/src/client/nodes/StatusSummary.tsx +2 -8
- package/src/client/nodes/WebpageNode.tsx +20 -14
- package/src/client/nodes/iframe-document-url.ts +25 -16
- package/src/client/nodes/image-warnings.ts +1 -7
- package/src/client/nodes/md-format.ts +20 -5
- package/src/client/state/attention-bridge.ts +4 -9
- package/src/client/state/attention-store.ts +1 -7
- package/src/client/state/canvas-store.ts +52 -36
- package/src/client/state/intent-bridge.ts +176 -112
- package/src/client/state/intent-store.ts +4 -1
- package/src/client/state/sse-bridge.ts +53 -70
- package/src/json-render/catalog.ts +12 -16
- package/src/json-render/charts/components.tsx +16 -20
- package/src/json-render/charts/extra-components.tsx +8 -16
- package/src/json-render/charts/extra-definitions.ts +1 -2
- package/src/json-render/charts/tufte-components.tsx +37 -20
- package/src/json-render/charts/tufte-definitions.ts +8 -2
- package/src/json-render/renderer/index.tsx +42 -22
- package/src/json-render/schema.ts +6 -3
- package/src/json-render/server.ts +33 -39
- package/src/mcp/canvas-access.ts +40 -121
- package/src/mcp/server.ts +206 -271
- package/src/server/agent-context.ts +63 -36
- package/src/server/ax-context.ts +7 -5
- package/src/server/ax-interaction.ts +176 -43
- package/src/server/ax-state-manager.ts +185 -41
- package/src/server/ax-state.ts +142 -47
- package/src/server/bundled-skills.ts +3 -3
- package/src/server/canvas-db.ts +213 -95
- package/src/server/canvas-operations.ts +177 -120
- package/src/server/canvas-provenance.ts +1 -4
- package/src/server/canvas-schema.ts +500 -102
- package/src/server/canvas-serialization.ts +27 -35
- package/src/server/canvas-state.ts +155 -58
- package/src/server/chart-template.ts +4 -5
- package/src/server/code-graph.ts +20 -7
- package/src/server/diagram-presets.ts +28 -29
- package/src/server/ext-app-lookup.ts +4 -20
- package/src/server/html-node-summary.ts +19 -10
- package/src/server/html-primitives.ts +326 -97
- package/src/server/html-surface.ts +6 -9
- package/src/server/image-source.ts +6 -4
- package/src/server/index.ts +321 -218
- package/src/server/intent-registry.ts +3 -6
- package/src/server/mcp-app-candidate.ts +5 -10
- package/src/server/mcp-app-host.ts +14 -38
- package/src/server/mcp-app-runtime.ts +12 -20
- package/src/server/mutation-history.ts +15 -5
- package/src/server/operations/composites.ts +38 -40
- package/src/server/operations/http.ts +5 -5
- package/src/server/operations/index.ts +7 -1
- package/src/server/operations/invoker.ts +4 -3
- package/src/server/operations/mcp.ts +29 -36
- package/src/server/operations/ops/annotation.ts +122 -10
- package/src/server/operations/ops/app.ts +102 -77
- package/src/server/operations/ops/ax-await.ts +17 -10
- package/src/server/operations/ops/ax-read.ts +347 -0
- package/src/server/operations/ops/ax-shared.ts +2 -7
- package/src/server/operations/ops/ax-state.ts +32 -14
- package/src/server/operations/ops/ax-timeline.ts +32 -19
- package/src/server/operations/ops/ax-work.ts +54 -37
- package/src/server/operations/ops/batch.ts +39 -14
- package/src/server/operations/ops/canvas-wire.ts +91 -0
- package/src/server/operations/ops/edges.ts +37 -25
- package/src/server/operations/ops/ext-app.ts +346 -0
- package/src/server/operations/ops/groups.ts +49 -20
- package/src/server/operations/ops/intent.ts +18 -12
- package/src/server/operations/ops/json-render.ts +239 -98
- package/src/server/operations/ops/nodes.ts +300 -111
- package/src/server/operations/ops/query.ts +62 -33
- package/src/server/operations/ops/snapshots.ts +35 -26
- package/src/server/operations/ops/validate.ts +2 -1
- package/src/server/operations/ops/viewport.ts +60 -16
- package/src/server/operations/ops/webview.ts +44 -18
- package/src/server/operations/registry.ts +2 -3
- package/src/server/operations/types.ts +7 -5
- package/src/server/operations/webview-runner.ts +1 -3
- package/src/server/placement.ts +8 -18
- package/src/server/server.ts +121 -1012
- package/src/server/spatial-analysis.ts +39 -25
- package/src/server/trace-manager.ts +3 -8
- package/src/server/web-artifacts.ts +23 -27
- package/src/server/webpage-node.ts +5 -13
- package/src/shared/auto-arrange.ts +12 -5
- package/src/shared/ax-intent.ts +1 -1
- package/src/shared/content-height-reporter.ts +8 -6
- package/src/shared/ext-app-tool-result.ts +2 -6
- package/src/shared/placement.ts +1 -4
- package/src/shared/semantic-attention.ts +39 -37
- package/src/shared/surface.ts +8 -4
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
# Tech Debt Assessment — July 2026
|
|
2
|
+
|
|
3
|
+
**Status:** Proposed
|
|
4
|
+
**Date:** 2026-07-05, revised 2026-07-06
|
|
5
|
+
**Scope:** Full-repo audit at v0.2.7 (`289b7d6`, ~53.4k lines TS in `src/`, ~23.8k in `tests/`) **plus the uncommitted v0.3.0 working tree** (51 files, +1,085/−1,120 — the 57-legacy-MCP-tool removal, plan-006/plan-008 closure, and the matching docs/skills/test updates)
|
|
6
|
+
**Supersedes:** [`tech-debt-assessment-2026-06.md`](tech-debt-assessment-2026-06.md) (v0.1.36)
|
|
7
|
+
**Method:** Six parallel subsystem audits (server core, client, MCP layer, CLI/SDK/json-render, tests/tooling, docs/config), then a revision pass re-verifying every affected anchor against the dev machine's working tree. Verification on the v0.3.0 tree: `tsc --noEmit` clean; `bun test tests/unit` **567 pass / 0 fail** (the port-collision flake from the first run passed here; its root cause is H4 and still stands).
|
|
8
|
+
|
|
9
|
+
> **Revision note (2026-07-06):** the first revision of this document audited committed v0.2.7 only and missed the uncommitted v0.3.0 change already sitting in the working tree. That change resolves H1, most of H2, and parts of M11/L7 as originally written. This revision corrects those findings, adds M12, and confirms the delta touches nothing in C1–C3, H3–H7, M1–M5, M7–M10, or L1–L6 — those anchors were re-verified and stand.
|
|
10
|
+
>
|
|
11
|
+
> **Fix pass (2026-07-06, same day):** a follow-up pass slated for the v0.3.0 release then closed the small/safe findings: the H2 residual, M7, M12, the malformed-JSON half of M4, most of C3, the C2 doc drift, and the M9/L7 residuals. Each affected finding below carries a "Fix pass" status line. Regression tests live in `tests/unit/http-request-hygiene.test.ts`.
|
|
12
|
+
|
|
13
|
+
## Verdict
|
|
14
|
+
|
|
15
|
+
June's central diagnosis — one systemic disease of n-way duplication with manual sync — was correct, and the cure is further along than first reported. The operation registry (`src/server/operations/`) exists and is genuinely well-factored: one `defineOperation` record drives HTTP routing, MCP tools, and composites from a single zod schema. E2E Playwright is a hard CI gate. And June's #2 — MCP tool consolidation — is **fully implemented in the uncommitted v0.3.0 working tree**: 84 tools → 27, every one of the 57 removals mapped to its composite replacement in the changelog, the surface pinned by a freeze test, docs and skills updated in the same change. It is disciplined work — and it currently exists on one machine, in zero commits. The cheapest critical action in this report is committing and releasing it.
|
|
16
|
+
|
|
17
|
+
The debt that remains concentrates in two places. First, the **unfinished registry migration**: `server.ts` still interleaves ~50 hand-written route branches with 44 "migrated to the operation registry" tombstone comments, `PmxCanvas` remains a fourth hand-maintained surface of 76 delegating methods, and the CLI bypasses everything with 60 raw `fetch` calls beside 26 registry calls. Second, **governance drift**: CLAUDE.md/AGENTS.md mandate skill-mirror infrastructure that is gitignored and absent from a clean checkout, guarded by a validator that exits green having checked nothing — while 72 generated runtime files and an orphaned 435 KB bundle sit committed.
|
|
18
|
+
|
|
19
|
+
Code hygiene remains excellent for the velocity: zero `as any`, zero dynamic imports, strict TypeScript, clean typecheck, disciplined changelog. The problem is structural, not stylistic — and it is concentrated in exactly the files with the highest churn (`server.ts` was touched in 27 of the last 50 commits).
|
|
20
|
+
|
|
21
|
+
## Scorecard: June → July
|
|
22
|
+
|
|
23
|
+
| June finding | Status at v0.2.7 + v0.3.0 working tree |
|
|
24
|
+
|---|---|
|
|
25
|
+
| #1 4-layer copy machine → build operation registry | **~60% done.** Registry exists (88 ops); `server.ts` shrank 5,934 → 3,873 lines; `src/mcp/server.ts` 2,861 → 868. Remaining: ~50 legacy routes, `PmxCanvas` (76 methods), CLI (60 raw calls). |
|
|
26
|
+
| #2 69 MCP tools → consolidate to ~20 | **Done in the uncommitted v0.3.0 tree.** 15 composites + 12 standalones = 27 tools; the 57 legacy tools are removed with a per-tool changelog migration map; `mcp-tool-freeze.test.ts` pins the exact 27-name list. Residual: 6 deprecated snapshot standalones fold into a `canvas_snapshot` composite in v0.4. **Not yet committed or released.** |
|
|
27
|
+
| #3 CanvasStateManager mixes concerns | **Partially improved.** AX state largely moved to `ax-state.ts`/`ax-state-manager.ts`; `canvas-state.ts` still 2,136 lines / 87 methods with CRUD + undo + persistence + snapshots. |
|
|
28
|
+
| #4 E2E not a CI gate | **Fixed.** `test.yml` runs Playwright as a hard gate. `publish.yml` still skips e2e (relies on the tag being green on main). |
|
|
29
|
+
| #5 Triple-mirrored skill trees + CLAUDE/AGENTS duplication | **Unresolved** — the mirror trees are gitignored, so docs + CI check reference infrastructure absent from the repo. Re-verified 2026-07-06: CLAUDE.md/AGENTS.md are still 357-line near-identical twins, still differing by the same single demo-board line. |
|
|
30
|
+
| #6 Dual rendering stack | **Unresolved.** Preact + React 19 + recharts + 7 exact-pinned `@json-render` packages all in runtime deps; json-render bundle is 1.37 MB unminified. |
|
|
31
|
+
| #7 No API versioning | **Improved and now exercised.** `docs/api-stability.md` documented the 0.3.0 removal intent; the v0.3.0 working tree consumes that mechanism exactly as designed. |
|
|
32
|
+
| Smaller: `readJson` swallows malformed input | **Unresolved** (`server.ts:923`; registry reader `operations/http.ts:43` inherits the same behavior). |
|
|
33
|
+
| Smaller: giant integration tests posing as unit tests | **Grew.** `server-api.test.ts` 4,950 → 5,213 lines; `cli-node.test.ts` 2,877 → 2,903. |
|
|
34
|
+
| Smaller: client covered by e2e only | **Unresolved.** Still zero component render tests; only pure-helper imports are unit-tested. |
|
|
35
|
+
|
|
36
|
+
## Findings, ranked
|
|
37
|
+
|
|
38
|
+
### Critical
|
|
39
|
+
|
|
40
|
+
#### C1. The registry migration is stalled at the halfway point
|
|
41
|
+
The target architecture exists and works; the old one hasn't been deleted. Evidence:
|
|
42
|
+
|
|
43
|
+
- `server.ts` (3,873 lines) interleaves `dispatchOperationRoute` with ~50 hand-written `if (url.pathname === …)` branches and 44 tombstone comments of the form `// POST /api/canvas/ax/mode … migrated to the operation registry (plan-007 Slice B wave 2)` (e.g. `server.ts:3700-3778`).
|
|
44
|
+
- `PmxCanvas` (`src/server/index.ts`, 76 public methods) bypasses the registry and calls `canvas-operations.ts` directly — a fourth hand-maintained surface. `node.add` alone exists as `canvasState.addNode`, `addCanvasNode`, the `node.add` operation, the `canvas_node` MCP action, and `PmxCanvas.addNode`.
|
|
45
|
+
- The CLI (`src/cli/agent.ts`) is a fifth surface: 60 raw `api('POST', '/api/canvas/…')` calls with literal path strings coexist with 26 `invokeOperation(...)` calls that use the registry (`agent.ts:117` vs `:167`) — two dispatch mechanisms with independently implemented error semantics inside one binary.
|
|
46
|
+
|
|
47
|
+
Half-migrated is the most expensive state: every change currently needs to check *both* systems. **Remediation:** finish it — move remaining routes into operations, make `PmxCanvas` a thin wrapper over `executeOperation`, migrate the CLI's raw calls onto the operation invoker. This deletes code in four files at once.
|
|
48
|
+
|
|
49
|
+
#### C2. Governance docs and a CI gate describe infrastructure that doesn't exist in the repo
|
|
50
|
+
CLAUDE.md/AGENTS.md (lines ~317-332) mandate: *"Agent-facing pipeline skills live in `.agents/skills/` and must be mirrored identically in `.claude/skills/` and `.opencode/skills/` … byte-for-byte identical; verify with `bun run validate:agent-skills`."* All three directories are gitignored/absent from a clean checkout. `scripts/validate-agent-skill-mirrors.sh` detects this and exits 0: *"No skills roots present in this checkout; nothing to validate (skipping)."* The 17 skill names it guards have zero overlap with the committed `skills/` tree. Every agent onboarded via CLAUDE.md is instructed to maintain phantom infrastructure, and the check wired into `package.json` guarantees nothing. Re-verified 2026-07-06 — untouched by the v0.3.0 delta. *Fix pass 2026-07-06:* both files now state that the mirror trees are local-only, gitignored dev tooling absent from clean checkouts and that the validator skips (exits 0) when they are absent — the docs no longer misrepresent the repo. Whether to repoint or delete the validator remains a maintainer decision.
|
|
51
|
+
|
|
52
|
+
#### C3. Generated artifacts are committed; runtime output pollutes the tree
|
|
53
|
+
- **72 tracked files under `.pmx-canvas/`** — a full generated web-artifact scaffold (`artifacts/.web-artifacts/sdlc-control-room/` with `pnpm-lock.yaml`, shadcn `ui/*.tsx`, `bundle.html`). The `.gitignore` patterns `artifacts/.web-artifacts/` are root-anchored and don't match the `.pmx-canvas/` copies (`git check-ignore` confirms).
|
|
54
|
+
- **160 tracked files under `dist/`**, including `dist/client/index.js` (435 KB) — an orphaned bundle untouched since the repo's first commit (current builds output to `dist/canvas/`) — and 154 generated `.d.ts` files under `dist/types/`. The v0.3.0 delta illustrates the tax directly: 10 `dist/types/*.d.ts` diffs are hand-carried inside an otherwise source-level change.
|
|
55
|
+
- Running `bun test tests/unit` can drop an untracked `.pmx-canvas/canvas.db` outside the workspace being tested: at least one code path resolves the workspace to `process.cwd()`. Related bug: `code-graph.ts:116` resolves workspace-relative imports against `process.cwd()` instead of the configured `workspaceRoot`, so the code graph silently mis-resolves whenever the server is started for another directory.
|
|
56
|
+
|
|
57
|
+
*Fix pass 2026-07-06:* `.gitignore` now covers `.pmx-canvas/artifacts/.web-artifacts/` and daemon `*.log`/`*.pid` files; the 72 tracked scaffold files are untracked and the orphaned `dist/client` bundle is deleted; `code-graph.ts` resolves against `canvasState.workspaceRoot`. **Remaining:** the deliberate decision whether `dist/canvas`/`dist/types` stay committed (if yes, add a staleness CI check).
|
|
58
|
+
|
|
59
|
+
### High
|
|
60
|
+
|
|
61
|
+
#### H1. ~~MCP legacy-tool overlap window is overdue~~ — RESOLVED in the v0.3.0 working tree (pending commit/release)
|
|
62
|
+
The 57 legacy tools are removed; 27 remain: 15 composites + `canvas_batch`, `canvas_pin_nodes`, `canvas_invoke_command`, `canvas_ax_interaction`, `canvas_ingest_activity`, `canvas_screenshot`, and the 6 snapshot standalones (deprecated, folding into a `canvas_snapshot` composite in v0.4 — a dated, pinned residual rather than an open-ended window). The surface is now governed instead of accreted: `registerOperationTools` skips composite-folded ops (`operations/mcp.ts:26-31`) and `mcp-tool-freeze.test.ts:157-176` asserts the exact 27-name list plus 14 resources, so a new op can't silently ship a standalone tool. The remaining risk is that all of this is uncommitted, single-machine state — see Direction item 1.
|
|
63
|
+
|
|
64
|
+
#### H2. ~~Six hand-written MCP tools duplicate the registry~~ — mostly RESOLVED in the v0.3.0 working tree
|
|
65
|
+
The 3 fully parallel implementations (`canvas_add_html_node`, `canvas_add_html_primitive`, `canvas_refresh_webpage_node`) and their drift-prone Local/Remote `CanvasAccess` method pairs are deleted (`canvas-access.ts:19` documents the removal; `src/mcp/server.ts` 1,009 → 868 lines, `canvas-access.ts` → 562). Residual (low): `canvas_ax_interaction`, `canvas_ingest_activity`, `canvas_screenshot` remain hand-written — legitimately MCP-specific (image payloads, interaction envelopes). *Fix pass 2026-07-06:* the first two now carry the same try/catch → `{isError:true}` handling as `canvas_screenshot` and the registry tools; nothing of H2 remains open.
|
|
66
|
+
|
|
67
|
+
#### H3. `src/cli/agent.ts` is a 3,337-line monolith with 83 hand-registered commands
|
|
68
|
+
83 `cmd(...)` registrations in one file, routed by a manual three-then-two-then-one word lookup (`agent.ts:3287-3301`); 81 copy-pasted `if (flags.help || flags.h) return showCommandHelp(...)` preambles; a hand-rolled flag parser with a ~40-entry `BOOL_FLAGS` allowlist (`agent.ts:184-193`) that must be updated for every new boolean flag — while `src/cli/index.ts:43-87` independently implements a *second* parser with different rules. **Remediation:** per-domain command modules + a `defineCommand` wrapper + one shared arg parser (and see C1 for the transport).
|
|
69
|
+
|
|
70
|
+
#### H4. Daemon lifecycle: races, orphans, and a dishonest pre-check — FIXED post-0.3.0 (finding partly corrected)
|
|
71
|
+
*Correction (2026-07-07):* the original claim that a fallen-back child leaves the parent polling the wrong port was wrong — the daemon child was already strict-port (`PmxCanvas.start` pins `allowPortFallback: false`, `index.ts:176`; only the MCP auto-start path opts into fallback). The real defects were: the pre-check treated **any** responsive `/health` on the port as "already running" (including a different workspace's daemon — the same wrong-workspace class as v0.2.7 Finding I); a TOCTOU window between health check and spawn; the pid file written only after health passed, so a slow-starting daemon outlived its `--wait-ms` budget as an unkillable orphan; and `isProcessRunning` treating `EPERM` as alive with no PID-recycling guard. *Fix (post-0.3.0):* daemon lifecycle extracted to `src/cli/daemon.ts` — the pid file is created exclusively as the spawn lock and records the pid immediately, failed startups kill the child, the pre-check is workspace-aware, and liveness is cross-checked against the process command line (`tests/unit/cli-daemon.test.ts`, 19 tests, plus a live start/double-start/foreign-workspace/status/stop smoke). The intermittent `pmx-canvas-sdk.test.ts` port flake is unrelated — it is M8's copy-pasted `getAvailablePort()` racing.
|
|
72
|
+
|
|
73
|
+
#### H5. sse-bridge maintains a second, divergent copy of node construction and thread state
|
|
74
|
+
`src/client/state/sse-bridge.ts` (1,066 lines, 34 handlers) has its own `DEFAULT_POSITIONS`/`makeNode` node factory (`:75-114`) fully separate from `canvas-store`'s `addNode`/`parseCanvasNode` — two factories with divergent defaults. Thread/turn reconciliation hand-mutates a `turns[]` array plus a module-level `responseToThreadMap` whose own comment admits it is *"Not cleaned on SSE reconnect"* (`:43`), with heuristic dedup (`:650-654`). Server-side, `syncEventToCanvasState` (`server.ts:3046`, ~330 lines) mirrors this as a giant if/else chain, with node geometry defaults duplicated against `ensureDefaultDockedNodes` under a comment saying *"keep geometry/dock defaults in sync if you change them"* (`:3006`). This is the exact drift class that Canvas Architecture Rule 2 exists to prevent. **Remediation:** one shared node factory; treat `canvas-layout-update` as the single source of truth for thread nodes; table-drive the event sync.
|
|
75
|
+
|
|
76
|
+
#### H6. No lint or format tooling exists — and RELEASE.md claims it does
|
|
77
|
+
No ESLint/Biome/Prettier config anywhere; no lint script. `docs/RELEASE.md:35` states `release:check` "bundles + lints" — it runs build + typecheck + tests only. 53k lines across two UI frameworks with zero automated consistency enforcement. **Remediation:** add Biome, wire into CI and `release:check`.
|
|
78
|
+
|
|
79
|
+
#### H7. Client rendering has zero unit-level coverage; big server modules untested; coverage is decorative
|
|
80
|
+
The 12 `client-*.test.ts` files import only pure exported helpers; no DOM testing library exists in the repo, so every component (`CanvasNode`, `PromptNode`, `ContextNode`, `ContextMenu`, …) plus `sse-bridge.ts` and `canvas-store.ts` are e2e-only. Server modules with no dedicated tests include `ax-state-manager.ts` (826 lines), `mcp-app-host.ts` (814), `canvas-schema.ts` (644), and `shared/semantic-attention.ts` (600 — appears in zero test files). CI collects coverage but nothing fails on a drop. Tests are also not typechecked (`tsconfig.json` includes only `src/**`). **Remediation:** add `happy-dom` + `@testing-library/preact`; unit-test the two pure-logic modules first; set a coverage threshold; add a tests tsconfig.
|
|
81
|
+
|
|
82
|
+
### Medium
|
|
83
|
+
|
|
84
|
+
- **M1. Dual rendering stack, unminified, dev tooling in prod.** Preact app + React 19 + react-dom + recharts as runtime deps; 7 `@json-render/*` packages exact-pinned at 0.19.0, three of them devtools (`@json-render/devtools*` imported at `renderer/index.tsx:20`, gated behind a window flag but shipped). Bundles: `dist/json-render/index.js` 1.37 MB, `dist/canvas/index.js` 599 KB — both readable/unminified (the `--minify` in `build:client` isn't reflected in the committed bundle). `scripts/build-json-render.sh` shells to `python3` for an mtime cache and has a timeout-then-use-stale-bundle fallback, making builds non-deterministic. **Remediation:** minify; move devtools to devDependencies; lazy-load the viewer; replace the Python mtime gate.
|
|
85
|
+
- **M2. Copy-pasted iframe AX bridge across three renderers.** An identical ~33-line `onAxMessage` listener appears in `HtmlNode.tsx:55-89`, `McpAppNode.tsx:89-121`, `ExtAppFrame.tsx:272-303`; the `pmx-canvas-ax` protocol string is spread across 9 sites; the `ax-update` push is likewise duplicated. This is the trust boundary for sandboxed surfaces — the one place copy-paste drift has already caused a security near-miss (June's LRN-20260607-005). **Remediation:** one `useAxSurfaceBridge` hook + a protocol-constants module.
|
|
86
|
+
- **M3. `ExtAppFrame.tsx` (915 lines) is a timing-hack concentration.** 12 refs, 7 `setTimeout`s, 5 rAFs, a WebKit black-tile remount driven by a global serialized slot counter with a 3000 ms reset (`:69-78`), a 1200 ms fallback bootstrap timer (`:619-640`), and two near-duplicate `buildHostContext` blocks (`:426-442` vs `:737-747`). Highest-churn client file (11 of last 50 commits). **Remediation:** extract a `useExtAppBridge` hook; single `buildHostContext`.
|
|
87
|
+
- **M4. Inconsistent HTTP envelopes and swallowed errors.** Registry ops return bare bodies, legacy ext-app handlers return `{ok:true,result}`, 404s are plaintext — three shapes on one API. `canvas-state.ts` has 63 catch→warn→continue sites, so a full-disk/corrupt-DB save failure is invisible to clients. *Fix pass 2026-07-06:* malformed non-empty JSON bodies now return 400 on every route (`readJson` returns null → guarded at all 23 call sites; the registry reader throws `OperationError`) — regression-tested. **Remaining:** one envelope; surface persistence failure via a `/health` degraded flag.
|
|
88
|
+
- **M5. Five byte-identical ext-app list handlers** (`server.ts:1894-1949`) differing only in the runtime function called; the ~30 `readJson → validate → responseJson` skeletons across legacy handlers are the same pattern the registry already solves declaratively. Folds into C1.
|
|
89
|
+
- **M6. Composite MCP schemas advertise every field optional — and are now the only schema surface.** `buildCompositeShape` (`operations/mcp.ts:88`) flattens per-action requirements away (`shape[publicKey] = schema.optional()`), so `canvas_node {action:"add"}` without `type` passes schema validation and fails only in the handler. With the strict-schema legacy tools removed in v0.3.0, this flattened shape is the *only* contract agents see. `resolveCompositeOp` rejects unknown actions loudly (`operations/mcp.ts:141-158`) — good — but per-action required fields still fail only at runtime. **Remediation:** per-action `oneOf` schemas or explicit per-action requirement docs.
|
|
90
|
+
- **M7. Confirmed cross-transport drift (small but real).** *Fix pass 2026-07-06:* the HTTP search route now honors `?limit=` (regression-tested) and the SDK's `setContextPins` emits the same `context-pins-changed` event as HTTP/MCP. **Remaining:** resource notifications over-fan-out — five `canvas://` URIs fire on *every* mutation regardless of type (`mcp/server.ts:95-99`).
|
|
91
|
+
- **M8. Test-suite structural debt.** The two integration monoliths (5,213 + 2,903 lines) under `tests/unit/`; `getAvailablePort()` copy-pasted verbatim in 5 files; `waitForPersistence(ms = 650)` fixed-sleep used across 9 files plus ~19 magic `Bun.sleep` literals; Playwright config lacks `retries` and `forbidOnly`; two hard `waitForTimeout` sleeps (`canvas.pw.ts:1929`, `showcase.pw.ts:985`). `test:e2e-cli` (517-line script) runs in no workflow — it's a manual-only gate. **Remediation:** `tests/integration/` tier, shared port/MCP-client helpers, poll instead of sleep, add retries/forbidOnly, wire `e2e-cli` into CI.
|
|
92
|
+
- **M9. CLAUDE.md/AGENTS.md are 357-line hand-maintained twins.** *Fix pass 2026-07-06:* the demo-board drift line is resolved (the fixture is a saved OKR/DX dashboard, so AGENTS.md was right), the files are byte-identical again, and the executable bit is cleared. **Remaining:** they are still two hand-maintained copies — generate one from the other (or symlink) to prevent the next drift.
|
|
93
|
+
- **M10. Packaging inconsistencies.** `bin` points at a raw `.ts` (Bun-only — consistent with ADR-001 but undocumented in the README install path); `files` ships both `src/` and `dist/`, roughly doubling the tarball with two import paths; `@types/turndown` sits in runtime `dependencies`. **Remediation:** pick one distribution; move `@types/*` to dev.
|
|
94
|
+
- **M11. Doc gaps (node-types staleness fixed in the delta).** ~~`docs/node-types.md` omits ext-app/webview~~ — fixed: webpage nodes get a dedicated section and `mcp-app` is documented. Still open: two live port env vars (`PMX_CANVAS_PORT` vs `PMX_WEB_CANVAS_PORT`) applied inconsistently across entry points (`canvas-access.ts:464` reads both, `cli/index.ts` only one, `cli/agent.ts` only the other); `PMX_DATA` (used 15×) and the `PMX_CANVAS_JSON_RENDER_*` / `PMX_MCP_APP_HOST_*` families undocumented (re-verified 2026-07-06); `publish.yml` intentionally skips e2e with no verification that the tagged SHA passed `test.yml`.
|
|
95
|
+
- **M12 (new). The v0.3.0 removal left stale references to deleted tools inside live registry metadata.** The `node.add` op description (`ops/nodes.ts:711`) still routes agents to six removed tools (*"json-render -> canvas_add_json_render_node, graph -> canvas_add_graph_node, web-artifact -> canvas_build_web_artifact, external apps -> canvas_open_mcp_app, html (preferred) -> canvas_add_html_node, groups -> canvas_create_group"*) and ends *"Call canvas_describe_schema…"* — also removed. Field descriptions at `ops/nodes.ts:657,668,714,716` still say "prefer canvas_create_group". Because `node.add` is composite-folded, none of this text registers anywhere today (`registerOperationTools` skips folded ops), and the agent-facing routing table was correctly updated to composite syntax (`canvas-schema.ts:83-336`) — so the impact is maintainer misdirection plus the risk of stale strings resurfacing if an op is ever unfolded. The now registration-dead `toolName:` fields on folded ops (`ops/app.ts:247,377`, `ops/groups.ts:51`, `ops/json-render.ts:117,224,353,472,543`, …) likewise read as live wiring. *Fix pass 2026-07-06:* the `node.add` description and field hints now route to composite syntax — **fixed**. The `toolName:`/`description` metadata on folded ops stays deliberately: it documents the historical mapping and the folded-op filter plus freeze test keep it inert.
|
|
96
|
+
|
|
97
|
+
### Low
|
|
98
|
+
|
|
99
|
+
- **L1.** Dead client code: `ContextPinHud.tsx` has zero references. Three pure re-export shims (`client/utils/placement.ts`, `client/utils/ext-app-tool-result.ts`, `server/ext-app-tool-result.ts`) add indirection without value.
|
|
100
|
+
- **L2.** Two parallel markdown-formatting stacks (`MdFormatBar`/`md-format.ts` vs `InlineFormatBar`/`inline-editor-commands.ts`) implementing overlapping bold/italic/code/link commands.
|
|
101
|
+
- **L3.** CSS: `global.css` is 3,746 lines/528 rule blocks with 11 `!important`, competing with 227 inline `style={{}}` objects (38 in `ContextNode.tsx` alone) and hard-coded `zIndex: 9998/10000/10001` outside any token scale.
|
|
102
|
+
- **L4.** Legacy JSON→SQLite migration code runs unconditionally on every boot (`canvas-state.ts:758,785`) with perpetual fallback branches; gate behind a one-shot marker and retire.
|
|
103
|
+
- **L5.** Two parallel suppression depth-counters (`_suppressRecordingDepth` in canvas-state, `suppressEmitDepth` in the registry — the latter's comment admits it "mirrors" the former); `onMutation` is a single-slot setter masquerading as a subscribe API and is wired twice (`server.ts:3500` and `index.ts:184`), currently harmless only because last-write-wins.
|
|
104
|
+
- **L6.** ~20 module-level mutable `let` bindings in `server.ts` plus module-global timers (the code-graph debounce timer survives `stopCanvasServer`, leaking across start/stop cycles); the remote SSE watcher in `mcp/server.ts:120-145` is a `while(true)` loop with no cancellation when the target changes.
|
|
105
|
+
- **L7.** ~~`mcp-tool-freeze.test.ts` title says "83-tool list" while asserting 84~~ — fixed in the v0.3.0 delta (asserts the frozen 27-name list with an accurate history comment). *Fix pass 2026-07-06:* `seed-and-screenshot.sh` now sets `-euo pipefail`. Still: `tsconfig` lacks `noUncheckedIndexedAccess`; the June assessment doc cites gitignored `.learnings/` entries unreadable by future maintainers.
|
|
106
|
+
|
|
107
|
+
## What is actually fine
|
|
108
|
+
|
|
109
|
+
- **The operation registry is good architecture, correctly executed** — single zod schema driving HTTP + MCP + composites with uniform validation and error mapping. The debt is that migration onto it stopped, not the design.
|
|
110
|
+
- **The v0.3.0 removal was executed with discipline**: every one of the 57 removals has a changelog mapping to its composite replacement; plans 006/008 closed with status lines; skills, `docs/mcp.md`, CLAUDE.md/AGENTS.md, and the schema routing table updated in the same change; and the folded-op filter + freeze test convert the tool surface from something that accretes into something that is governed.
|
|
111
|
+
- Zero `as any`, zero dynamic imports, `strict: true`, clean `tsc --noEmit` at 53k lines — including on the v0.3.0 tree.
|
|
112
|
+
- Node chrome (titlebar/pin/resize/ports) is properly centralized in `CanvasNode.tsx` — renderers do not duplicate it.
|
|
113
|
+
- `src/shared/` is genuinely shared (9 client + 10 server importers), not a dumping ground; `server/placement.ts` extends rather than copies it.
|
|
114
|
+
- `examples/` compile against the current SDK; `skills/pmx-canvas/SKILL.md` and its references are current at the v0.3.0 surface; tool/resource counts in docs match the code exactly (27/14).
|
|
115
|
+
- CI runs typecheck + build + unit + coverage + a real e2e gate; e2e predominantly uses `expect.poll`; 5 of 6 scripts are disciplined bash.
|
|
116
|
+
- CHANGELOG discipline is genuinely good — the v0.3.0 Breaking section is a model migration map.
|
|
117
|
+
|
|
118
|
+
## Direction
|
|
119
|
+
|
|
120
|
+
Everything still open below is tracked as an actionable backlog in [`docs/plans/plan-009-tech-debt-backlog.md`](plans/plan-009-tech-debt-backlog.md).
|
|
121
|
+
|
|
122
|
+
### Phase 1 — finish what was started (highest leverage, mostly deletion)
|
|
123
|
+
1. **Commit and release v0.3.0.** The consolidation the first revision of this report asked for already exists in the working tree — until it lands it is one `git checkout .` away from vanishing, and every downstream doc/test already assumes it. (M12's stale metadata is already swept in the same tree.)
|
|
124
|
+
2. **Complete the registry migration** (C1): fold the ~50 legacy routes into operations, collapse `PmxCanvas` onto `executeOperation`, migrate the CLI's 60 raw calls. Deletes the M5 handler clones and most envelope inconsistency (M4) as side effects.
|
|
125
|
+
3. **Fix the governance/CI lie** (C2) and **untrack generated artifacts** (C3) — a day of work, permanent credibility win.
|
|
126
|
+
|
|
127
|
+
### Phase 2 — make the safety net real
|
|
128
|
+
4. Add Biome (H6); typecheck tests; coverage threshold; Playwright retries + `forbidOnly`; wire `e2e-cli` into CI; split the integration monoliths (M8, H7).
|
|
129
|
+
5. Fix the daemon port/lock lifecycle (H4) — it is the root of both user-facing "dead daemon" confusion and the suite's one intermittent test.
|
|
130
|
+
|
|
131
|
+
### Phase 3 — client consolidation
|
|
132
|
+
6. One node factory shared by sse-bridge and canvas-store; single AX-bridge hook; `useExtAppBridge` (H5, M2, M3).
|
|
133
|
+
7. Decide the json-render stack's future deliberately (M1): minify + lazy-load at minimum; a separate optional package if the React stack stays.
|
|
134
|
+
|
|
135
|
+
The pattern from June holds: agent velocity faithfully replicates whatever structure exists. The registry proved that fixing the structure works — `src/mcp/server.ts` is down 70% from June (2,861 → 868 lines) while *adding* capability, and the v0.3.0 tree shows the same discipline scaling to a breaking release. The remaining risk is stopping halfway: two routing systems, two node factories, two arg parsers, and two governance stories are each more expensive than either one alone.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmx-canvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"description": "Spatial canvas workbench for coding agents — infinite 2D canvas with agent-native CLI, MCP integration, nodes, edges, file watching, and snapshots",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/server/index.ts",
|
|
@@ -38,9 +38,11 @@
|
|
|
38
38
|
"build": "bun run build:client && bun run build:json-render && bun run build:types",
|
|
39
39
|
"start": "bun run src/cli/index.ts --no-open",
|
|
40
40
|
"pack:dry-run": "bun pm pack --dry-run",
|
|
41
|
-
"release:check": "bun run build && bun run typecheck && bun run test:all",
|
|
41
|
+
"release:check": "bun run build && bun run typecheck && bun run lint && bun run test:all",
|
|
42
42
|
"release:smoke": "bash scripts/release-smoke.sh",
|
|
43
43
|
"typecheck": "tsc --noEmit",
|
|
44
|
+
"lint": "biome check .",
|
|
45
|
+
"lint:fix": "biome check --write .",
|
|
44
46
|
"test": "PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bun test tests/unit",
|
|
45
47
|
"test:unit": "PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bun test tests/unit",
|
|
46
48
|
"test:coverage": "bun test tests/unit --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir coverage",
|
|
@@ -76,6 +78,7 @@
|
|
|
76
78
|
"zod": "^4.3.6"
|
|
77
79
|
},
|
|
78
80
|
"devDependencies": {
|
|
81
|
+
"@biomejs/biome": "^2.5.2",
|
|
79
82
|
"@playwright/test": "^1.58.2",
|
|
80
83
|
"@tailwindcss/cli": "^4.1.18",
|
|
81
84
|
"@types/bun": "latest",
|
|
@@ -31,9 +31,9 @@ outputs:
|
|
|
31
31
|
|
|
32
32
|
Perform analytics synthesis across engineering and product data sources. Answer questions about trends, correlations, comparisons, and distributions by querying MCP servers, analyzing the data, and presenting findings with visualizations.
|
|
33
33
|
|
|
34
|
-
In `pmx-canvas`, prefer `
|
|
35
|
-
`
|
|
36
|
-
the canvas.
|
|
34
|
+
In `pmx-canvas`, prefer `canvas_render { action: "add-graph" }` for charts and trend lines and
|
|
35
|
+
`canvas_render { action: "add-json-render" }` when the analysis should land as a richer dashboard
|
|
36
|
+
or table inside the canvas.
|
|
37
37
|
|
|
38
38
|
For chart design and color choices, apply the `tufte-viz` skill (`skills/tufte-viz/SKILL.md`): color
|
|
39
39
|
must encode data, not decorate. Single-series bar charts default to one accent with the key bar
|
|
@@ -6,8 +6,9 @@ license: Complete terms in LICENSE.txt
|
|
|
6
6
|
|
|
7
7
|
This skill guides creation of distinctive, production-grade frontend interfaces that avoid generic "AI slop" aesthetics. Implement real working code with exceptional attention to aesthetic details and creative choices.
|
|
8
8
|
|
|
9
|
-
In `pmx-canvas`, use `
|
|
10
|
-
and use `
|
|
9
|
+
In `pmx-canvas`, use `canvas_app { action: "build-artifact" }` when the result should be a full
|
|
10
|
+
custom React app, and use `canvas_render { action: "add-json-render" }` when a schema-driven UI
|
|
11
|
+
panel is enough.
|
|
11
12
|
|
|
12
13
|
The user provides frontend requirements: a component, page, application, or interface to build. They may include context about the purpose, audience, or technical constraints.
|
|
13
14
|
|
|
@@ -7,9 +7,10 @@ description: MCP Apps integration for json-render. Use when building MCP servers
|
|
|
7
7
|
|
|
8
8
|
MCP Apps integration that serves json-render UIs as interactive MCP Apps inside Claude, ChatGPT, Cursor, VS Code, and other MCP-capable clients.
|
|
9
9
|
|
|
10
|
-
In `pmx-canvas`, prefer the native `
|
|
11
|
-
|
|
12
|
-
local `pmx-canvas` viewer route without
|
|
10
|
+
In `pmx-canvas`, prefer the native `canvas_render { action: "add-json-render" }` and
|
|
11
|
+
`canvas_render { action: "add-graph" }` composite actions first. They store validated specs
|
|
12
|
+
directly in canvas node state and render them through the local `pmx-canvas` viewer route without
|
|
13
|
+
needing a separate sidecar server.
|
|
13
14
|
|
|
14
15
|
## Quick Start
|
|
15
16
|
|
|
@@ -56,7 +56,7 @@ playwright-cli -s=canvas close
|
|
|
56
56
|
## PMX Canvas Guidance
|
|
57
57
|
|
|
58
58
|
- Start the canvas first: `bun run src/cli/index.ts --no-open`
|
|
59
|
-
- Use this skill after `
|
|
59
|
+
- Use this skill after `canvas_app { action: "build-artifact" }` when you need browser validation
|
|
60
60
|
- Prefer visible browser automation for UI investigation so the human can follow along
|
|
61
61
|
- Store screenshots and snapshots on disk, then only read back the specific files you need
|
|
62
62
|
|
|
@@ -25,7 +25,8 @@ Humans curate agent context by pinning nodes; agents read that curation through
|
|
|
25
25
|
may belong to another project.
|
|
26
26
|
3. **Read before write.** Search with `canvas_query { action: "search", query }` before creating
|
|
27
27
|
nodes. Read the full layout only when necessary.
|
|
28
|
-
4. **Snapshot before destructive changes.** Use `canvas_snapshot`
|
|
28
|
+
4. **Snapshot before destructive changes.** Use `canvas_snapshot` (deprecated standalone; folds into
|
|
29
|
+
the `canvas_snapshot` composite's `save` action in v0.4) before clear, restore, or a major
|
|
29
30
|
reorganization.
|
|
30
31
|
5. **Show intent with the Ghost Cursor — by default.** Signal with
|
|
31
32
|
`canvas_intent { action: "signal", ... }` before every meaningful create, move, connect, remove,
|
|
@@ -54,7 +55,9 @@ Both surfaces report `workspace`. It must match the intended workspace root.
|
|
|
54
55
|
|
|
55
56
|
- If `responsive: true` but `pidRunning: false`, treat the listener as potentially stale.
|
|
56
57
|
- On mismatch, do not mutate. Start the intended workspace on an explicit free port:
|
|
57
|
-
`pmx-canvas serve --daemon --no-open --port=<free-port>`.
|
|
58
|
+
`pmx-canvas serve --daemon --no-open --port=<free-port>`. (`serve --daemon` enforces this
|
|
59
|
+
itself: pointed at a port owned by another workspace, it refuses with the owner named instead
|
|
60
|
+
of reporting "already running".)
|
|
58
61
|
- Target that port and re-check `/health`.
|
|
59
62
|
- `PMX_CANVAS_PORT` is the agent CLI target; the server's startup port is controlled by `--port`
|
|
60
63
|
or `PMX_WEB_CANVAS_PORT`.
|
|
@@ -123,10 +126,12 @@ Important routing:
|
|
|
123
126
|
- Excalidraw: `canvas_app { action: "diagram", ... }`
|
|
124
127
|
- Web artifact: `canvas_app { action: "build-artifact", ... }`
|
|
125
128
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
`canvas_pin_nodes`, `canvas_screenshot`,
|
|
129
|
-
`
|
|
129
|
+
As of v0.3.0, the 57 legacy single-purpose tools from the v0.2 compatibility window are removed.
|
|
130
|
+
The composites above plus the retained standalones are now the whole MCP surface: `canvas_batch`,
|
|
131
|
+
`canvas_pin_nodes`, `canvas_screenshot`, `canvas_ax_interaction`, `canvas_ingest_activity`, and
|
|
132
|
+
`canvas_invoke_command`. The 6 snapshot tools (`canvas_snapshot`, `canvas_list_snapshots`,
|
|
133
|
+
`canvas_restore`, `canvas_delete_snapshot`, `canvas_gc_snapshots`, `canvas_diff`) are also retained
|
|
134
|
+
but deprecated, pending a `canvas_snapshot` composite in v0.4.
|
|
130
135
|
|
|
131
136
|
## Spatial Rules
|
|
132
137
|
|
|
@@ -235,7 +240,7 @@ annotations, pins, snapshots, AX canvas state, and large-node blobs.
|
|
|
235
240
|
- Stop the server or close/flush the SDK before committing `canvas.db`.
|
|
236
241
|
- History is session-scoped and is not persisted.
|
|
237
242
|
- Timeline AX data persists independently from canvas snapshots.
|
|
238
|
-
- `
|
|
243
|
+
- `canvas_view { action: "clear" }` clears canvas-bound state but not host/session diagnostics.
|
|
239
244
|
|
|
240
245
|
## Detailed References
|
|
241
246
|
|
|
@@ -218,7 +218,7 @@
|
|
|
218
218
|
"id": 9,
|
|
219
219
|
"name": "current-composite-routing",
|
|
220
220
|
"prompt": "Create a markdown note, a bar chart, and an Excalidraw diagram on the canvas.",
|
|
221
|
-
"expected_output": "Uses current composites: canvas_node {action:add} for markdown, canvas_render {action:add-graph} for the chart, canvas_app {action:diagram} for Excalidraw. Avoids
|
|
221
|
+
"expected_output": "Uses current composites: canvas_node {action:add} for markdown, canvas_render {action:add-graph} for the chart, canvas_app {action:diagram} for Excalidraw. Avoids removed single-purpose tools (canvas_add_node/canvas_add_diagram/canvas_build_web_artifact/canvas_open_mcp_app).",
|
|
222
222
|
"assertions": [
|
|
223
223
|
{
|
|
224
224
|
"name": "uses-canvas-node",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
},
|
|
238
238
|
{
|
|
239
239
|
"name": "avoids-deprecated",
|
|
240
|
-
"description": "Does not call
|
|
240
|
+
"description": "Does not call removed standalones (canvas_add_node/canvas_add_diagram/etc.)",
|
|
241
241
|
"type": "output_check"
|
|
242
242
|
}
|
|
243
243
|
]
|
|
@@ -10,7 +10,9 @@ messages. Just opt the node in and use `window.PMX_AX`.
|
|
|
10
10
|
|
|
11
11
|
```js
|
|
12
12
|
// MCP / SDK
|
|
13
|
-
|
|
13
|
+
canvas_node({
|
|
14
|
+
action: "add",
|
|
15
|
+
type: "html",
|
|
14
16
|
title: "AX Control Room",
|
|
15
17
|
html: "<!-- see below -->",
|
|
16
18
|
axCapabilities: { enabled: true, allowed: ["ax.work.create", "ax.steer"] },
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Excalidraw Diagram Authoring
|
|
2
2
|
|
|
3
|
-
Use this guide when creating diagrams through PMX Canvas with `
|
|
3
|
+
Use this guide when creating diagrams through PMX Canvas with `canvas_app { action: "diagram" }` or
|
|
4
4
|
`pmx-canvas external-app add --kind excalidraw`.
|
|
5
5
|
|
|
6
6
|
## Why Text Can Still Drift
|
|
@@ -142,4 +142,4 @@ If a title, footer, or rightmost label is clipped, the camera is wrong even if t
|
|
|
142
142
|
- Camera has at least `80px` padding around all visible content.
|
|
143
143
|
- Titles and footers are not near the camera edge.
|
|
144
144
|
- Arrows have explicit `points` and enough space for labels.
|
|
145
|
-
- Calls go through PMX (`
|
|
145
|
+
- Calls go through PMX (`canvas_app { action: "diagram" }` or `external-app add --kind excalidraw`) unless you manually apply these rules to raw Excalidraw MCP input.
|