pmx-canvas 0.1.35 → 0.2.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/CHANGELOG.md +461 -0
- package/Readme.md +14 -2
- package/dist/canvas/index.js +82 -41
- package/dist/json-render/index.js +89 -334
- package/dist/types/client/nodes/ExtAppFrame.d.ts +2 -0
- package/dist/types/mcp/canvas-access.d.ts +12 -159
- package/dist/types/server/ax-context.d.ts +1 -1
- package/dist/types/server/ax-state-manager.d.ts +256 -0
- package/dist/types/server/ax-state.d.ts +29 -1
- package/dist/types/server/ax-wait.d.ts +23 -0
- package/dist/types/server/canvas-operations.d.ts +1 -12
- package/dist/types/server/canvas-state.d.ts +46 -14
- package/dist/types/server/html-surface.d.ts +7 -0
- package/dist/types/server/index.d.ts +66 -26
- package/dist/types/server/operations/composites.d.ts +121 -0
- package/dist/types/server/operations/http.d.ts +7 -0
- package/dist/types/server/operations/index.d.ts +8 -0
- package/dist/types/server/operations/invoker.d.ts +13 -0
- package/dist/types/server/operations/mcp.d.ts +15 -0
- package/dist/types/server/operations/ops/annotation.d.ts +2 -0
- package/dist/types/server/operations/ops/app.d.ts +33 -0
- package/dist/types/server/operations/ops/ax-await.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-shared.d.ts +31 -0
- package/dist/types/server/operations/ops/ax-state.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-timeline.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-work.d.ts +2 -0
- package/dist/types/server/operations/ops/batch.d.ts +19 -0
- package/dist/types/server/operations/ops/edges.d.ts +2 -0
- package/dist/types/server/operations/ops/groups.d.ts +2 -0
- package/dist/types/server/operations/ops/json-render.d.ts +31 -0
- package/dist/types/server/operations/ops/nodes.d.ts +62 -0
- package/dist/types/server/operations/ops/query.d.ts +2 -0
- package/dist/types/server/operations/ops/snapshots.d.ts +2 -0
- package/dist/types/server/operations/ops/validate.d.ts +2 -0
- package/dist/types/server/operations/ops/viewport.d.ts +2 -0
- package/dist/types/server/operations/ops/webview.d.ts +2 -0
- package/dist/types/server/operations/registry.d.ts +15 -0
- package/dist/types/server/operations/types.d.ts +116 -0
- package/dist/types/server/operations/webview-runner.d.ts +69 -0
- package/docs/RELEASE.md +5 -0
- package/docs/adr-001-bun-only-runtime.md +46 -0
- package/docs/api-stability.md +57 -0
- package/docs/ax-host-adapter-contract.md +65 -0
- package/docs/ax-state-contract.md +72 -0
- package/docs/http-api.md +34 -2
- package/docs/mcp.md +64 -11
- package/docs/plans/plan-005-operation-registry.md +84 -0
- package/docs/plans/plan-006-mcp-tool-consolidation.md +109 -0
- package/docs/plans/plan-007-ax-domain.md +99 -0
- package/docs/plans/plan-008-registry-finish.md +91 -0
- package/docs/screenshot.png +0 -0
- package/docs/tech-debt-assessment-2026-06.md +90 -0
- package/package.json +3 -3
- package/skills/pmx-canvas/SKILL.md +233 -185
- package/skills/pmx-canvas/evals/evals.json +3 -3
- package/skills/pmx-canvas/references/codex-app-adapter.md +24 -11
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +31 -1
- package/src/cli/agent.ts +52 -31
- package/src/client/nodes/ExtAppFrame.tsx +73 -5
- package/src/client/nodes/HtmlNode.tsx +12 -3
- package/src/client/nodes/McpAppNode.tsx +12 -3
- package/src/json-render/renderer/index.tsx +3 -0
- package/src/mcp/canvas-access.ts +43 -774
- package/src/mcp/server.ts +190 -2001
- package/src/server/ax-context.ts +7 -1
- package/src/server/ax-state-manager.ts +808 -0
- package/src/server/ax-state.ts +89 -2
- package/src/server/ax-wait.ts +56 -0
- package/src/server/canvas-operations.ts +2 -328
- package/src/server/canvas-schema.ts +2 -2
- package/src/server/canvas-state.ts +140 -382
- package/src/server/html-surface.ts +49 -11
- package/src/server/index.ts +136 -192
- package/src/server/operations/composites.ts +355 -0
- package/src/server/operations/http.ts +103 -0
- package/src/server/operations/index.ts +65 -0
- package/src/server/operations/invoker.ts +87 -0
- package/src/server/operations/mcp.ts +221 -0
- package/src/server/operations/ops/annotation.ts +60 -0
- package/src/server/operations/ops/app.ts +447 -0
- package/src/server/operations/ops/ax-await.ts +216 -0
- package/src/server/operations/ops/ax-shared.ts +38 -0
- package/src/server/operations/ops/ax-state.ts +249 -0
- package/src/server/operations/ops/ax-timeline.ts +381 -0
- package/src/server/operations/ops/ax-work.ts +635 -0
- package/src/server/operations/ops/batch.ts +365 -0
- package/src/server/operations/ops/edges.ts +166 -0
- package/src/server/operations/ops/groups.ts +176 -0
- package/src/server/operations/ops/json-render.ts +691 -0
- package/src/server/operations/ops/nodes.ts +1047 -0
- package/src/server/operations/ops/query.ts +281 -0
- package/src/server/operations/ops/snapshots.ts +366 -0
- package/src/server/operations/ops/validate.ts +37 -0
- package/src/server/operations/ops/viewport.ts +219 -0
- package/src/server/operations/ops/webview.ts +339 -0
- package/src/server/operations/registry.ts +79 -0
- package/src/server/operations/types.ts +150 -0
- package/src/server/operations/webview-runner.ts +77 -0
- package/src/server/server.ts +253 -2170
- package/src/server/web-artifacts.ts +6 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Tech Debt Assessment & Direction Proposal — June 2026
|
|
2
|
+
|
|
3
|
+
**Status:** Proposed
|
|
4
|
+
**Date:** 2026-06-10
|
|
5
|
+
**Scope:** Full-repo audit at v0.1.36 (~70k lines TS; src/server 23.2k, src/client 13.9k, src/mcp 4.2k, src/cli 4.0k)
|
|
6
|
+
|
|
7
|
+
## Verdict
|
|
8
|
+
|
|
9
|
+
Code quality is better than the release velocity would suggest: zero `as any` across the codebase, real test suites, disciplined changelogs. Architecture quality is the problem. The debt is not scattered; it is one systemic disease: **n-way duplication with manual sync**. Almost every entry in `.learnings/` traces back to it.
|
|
10
|
+
|
|
11
|
+
## Tech debt, ranked
|
|
12
|
+
|
|
13
|
+
### 1. The 4-layer copy machine (critical)
|
|
14
|
+
|
|
15
|
+
Every operation is hand-written four times — `CanvasStateManager` → `PmxCanvas` → HTTP handler in `server.ts` → MCP tool in `src/mcp/server.ts` — each with its own validation and error shapes. The CLI (`src/cli/agent.ts`, 3,300 lines) duplicates it a fifth time with raw fetch calls instead of using the SDK.
|
|
16
|
+
|
|
17
|
+
Evidence from `.learnings/` that this is actively producing bugs:
|
|
18
|
+
|
|
19
|
+
- [LRN-20260606-006] Fix #32 applied to only one of two duplicated mutation paths (`updateNode()` vs `applyUpdates()`).
|
|
20
|
+
- [LRN-20260607-005] New `json-render` sourceSurface enum member silently took the permissive default because the `scoped` guard in `applyAxInteraction` was not updated. Security near-miss.
|
|
21
|
+
- [LRN-20260608-002] `readJson` hardening silently killed the documented bare-array shape of `POST /api/canvas/batch` (#49).
|
|
22
|
+
|
|
23
|
+
These are not three bugs. They are one architecture failing three times.
|
|
24
|
+
|
|
25
|
+
**Fix:** a single operation registry. One zod schema per canvas operation; derive the MCP tool, HTTP handler, CLI command, and SDK method from it. Collapses `server.ts` (5,934 lines, raw if-else routing, 14 mutable module-level globals) and `src/mcp/server.ts` (2,861 lines, ~70% schema boilerplate) as a side effect.
|
|
26
|
+
|
|
27
|
+
### 2. 69 MCP tools is bad AX (high)
|
|
28
|
+
|
|
29
|
+
A project whose thesis is agent experience ships a tool surface that consumes a large slice of every connected agent's context window. Many tools are near-identical passthroughs (`full`/`verbose` flag pairs copied across 12+ tools). Consolidate to roughly 20 composable tools. This is product debt, not just code debt. Depends on item 1.
|
|
30
|
+
|
|
31
|
+
### 3. CanvasStateManager mixes too many concerns (high)
|
|
32
|
+
|
|
33
|
+
`canvas-state.ts` (2,498 lines) handles node/edge CRUD, AX state, undo/redo, viewport, pins, SQLite persistence, and snapshots in one class. AX state is re-normalized against node IDs on every mutation, so deleting a node silently orphans work items with no event. AX data is split between snapshotted in-memory state and audit-only DB tables with no documented contract.
|
|
34
|
+
|
|
35
|
+
**Fix:** split canvas layout state from AX state; document the snapshotted-vs-audit-only partition explicitly (the CLAUDE.md section is a start, the code does not enforce it).
|
|
36
|
+
|
|
37
|
+
### 4. E2E is not a CI gate (high)
|
|
38
|
+
|
|
39
|
+
The Playwright/Bun ESM loader blocker ([ERR-20260508-001]) has been open for weeks. E2E was removed from the publish workflow after the apt-mirror hang ([LRN-20260603-002]) and does not gate PRs. The bugs that matter (iframe blank flicker, literal `\n` in ledger, SVG calc()) were all caught only by browser tests. Green CI can currently ship a broken canvas.
|
|
40
|
+
|
|
41
|
+
**Fix:** run Playwright via Node's runner in CI permanently, and make headless e2e a hard PR gate.
|
|
42
|
+
|
|
43
|
+
### 5. Triple-mirrored skill trees + duplicate agent docs (medium)
|
|
44
|
+
|
|
45
|
+
`.agents/skills/`, `.claude/skills/`, `.opencode/skills/` must be byte-identical, enforced by `validate-agent-skill-mirrors.sh`. CLAUDE.md and AGENTS.md are near-identical (4 diff lines as of today) and already drifting.
|
|
46
|
+
|
|
47
|
+
**Fix:** one canonical source, generate the mirrors at build time. ~20 lines of script replacing a permanent tax.
|
|
48
|
+
|
|
49
|
+
### 6. Dual rendering stack (medium)
|
|
50
|
+
|
|
51
|
+
Preact + signals for the canvas, plus React 19 + recharts + a separate Tailwind build for the json-render viewer: ~2.1MB of bundle, zero shared code, duplicate theming. Defensible as a deliberate choice, but it is weight carried for one node type. Decide whether json-render earns its stack or should slim down.
|
|
52
|
+
|
|
53
|
+
### 7. No API versioning despite breaking patch releases (medium)
|
|
54
|
+
|
|
55
|
+
0.1.35 and 0.1.36 both changed HTTP contract behavior in patch releases. No version negotiation, no deprecation path. Consumers cannot pin safely.
|
|
56
|
+
|
|
57
|
+
### Smaller items
|
|
58
|
+
|
|
59
|
+
- `readJson` silently returns `{}` on malformed input; handlers cannot distinguish bad requests from empty ones. Prefer loud validation errors (this pattern already caused #49).
|
|
60
|
+
- `listSnapshotsFromDB` interpolates `LIMIT ${limit}` instead of parameterizing. Safe only because of upstream normalization. Fragile.
|
|
61
|
+
- `server-api.test.ts` (4,950 lines) and `cli-node.test.ts` (2,877 lines) are integration tests against a live server posing as unit tests: slow, order-dependent, hard to debug.
|
|
62
|
+
- Client renderers and state bridges (sse-bridge, canvas-store) are e2e-tested only; no coverage visibility.
|
|
63
|
+
- Stale `dist/` bundle trap is documented but not guarded; the dev server should warn when the bundle is older than `src/client/`.
|
|
64
|
+
|
|
65
|
+
## What is actually fine
|
|
66
|
+
|
|
67
|
+
The TypeScript guardrails are working (zero `as any`). The SQLite persistence layer is mostly clean and parameterized. The AX primitive design (capability ceilings, surface scoping, single trust boundary in `applyAxInteraction`) is sound; the bugs were in the duplication around it, not the design. The `.learnings/` loop is genuinely catching and recording real failures.
|
|
68
|
+
|
|
69
|
+
## Direction proposal
|
|
70
|
+
|
|
71
|
+
### Phase 1 (now, 2–3 weeks): stop shipping features, fix the structure
|
|
72
|
+
|
|
73
|
+
1. Build the operation registry (item 1). This is the single highest-leverage change and the prerequisite for everything below.
|
|
74
|
+
2. Fix the Playwright gate (item 4) in the same window.
|
|
75
|
+
3. Kill the skill-mirror triplication (item 5).
|
|
76
|
+
|
|
77
|
+
### Phase 2: v0.2 as the stability release
|
|
78
|
+
|
|
79
|
+
- Versioned HTTP API with a published breaking-change policy.
|
|
80
|
+
- MCP tool surface consolidated to ~20 composable tools.
|
|
81
|
+
- CLI rebuilt on the SDK.
|
|
82
|
+
- Deliberate Bun-only decision: stay Bun-only for the SDK and treat MCP + HTTP as the universal surface. MCP is the real distribution channel; a Node dual-build is effort on the least differentiated path.
|
|
83
|
+
|
|
84
|
+
### Phase 3: double down on AX
|
|
85
|
+
|
|
86
|
+
The moat is not the canvas. Infinite canvases are a commodity. Pinned context, spatial semantics, approval gates, steering, and the human-curates-agent-reads loop are not — nobody else is building "the agent's extended working memory" as a primitive layer. Once the foundation is stable: document and version the AX contract, and consider speccing it so other canvas hosts could implement it. That is the difference between another agent dashboard and owning a category.
|
|
87
|
+
|
|
88
|
+
### The uncomfortable truth
|
|
89
|
+
|
|
90
|
+
16 releases in the last 8 days is agent-velocity outrunning architecture. The agents building this faithfully replicate the duplication because the structure rewards it. Fix the structure and the same velocity becomes safe instead of compounding.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmx-canvas",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
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",
|
|
@@ -44,10 +44,10 @@
|
|
|
44
44
|
"test": "PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bun test tests/unit",
|
|
45
45
|
"test:unit": "PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bun test tests/unit",
|
|
46
46
|
"test:coverage": "bun test tests/unit --coverage --coverage-reporter=text --coverage-reporter=lcov --coverage-dir coverage",
|
|
47
|
-
"test:web-canvas": "PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bun run build && PMX_CANVAS_DISABLE_BROWSER_OPEN=1
|
|
47
|
+
"test:web-canvas": "PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bun run build && PMX_CANVAS_DISABLE_BROWSER_OPEN=1 bash scripts/run-playwright.sh",
|
|
48
48
|
"test:e2e": "bun run test:web-canvas",
|
|
49
49
|
"test:e2e-cli": "bash scripts/e2e-cli-coverage.sh",
|
|
50
|
-
"test:web-canvas:headed": "bun run build &&
|
|
50
|
+
"test:web-canvas:headed": "bun run build && bash scripts/run-playwright.sh --headed",
|
|
51
51
|
"test:e2e:headed": "bun run test:web-canvas:headed",
|
|
52
52
|
"test:all": "bun run test && bun run test:web-canvas",
|
|
53
53
|
"test:install-browsers": "bun x playwright install chromium",
|