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
|
@@ -1,10 +1,6 @@
|
|
|
1
1
|
import { type CanvasLayout, type CanvasNodeState, type PmxCanvas } from '../server/index.js';
|
|
2
2
|
import type { PmxAxSource } from '../server/ax-state.js';
|
|
3
3
|
import { type OperationInvoker } from '../server/operations/index.js';
|
|
4
|
-
type RefreshWebpageNodeResult = Awaited<ReturnType<PmxCanvas['refreshWebpageNode']>>;
|
|
5
|
-
type AddHtmlNodeInput = Parameters<PmxCanvas['addHtmlNode']>[0];
|
|
6
|
-
type AddHtmlPrimitiveInput = Parameters<PmxCanvas['addHtmlPrimitive']>[0];
|
|
7
|
-
type AddHtmlPrimitiveResult = ReturnType<PmxCanvas['addHtmlPrimitive']>;
|
|
8
4
|
type AxStateResult = ReturnType<PmxCanvas['getAxState']>;
|
|
9
5
|
type AxContextResult = ReturnType<PmxCanvas['getAxContext']>;
|
|
10
6
|
type SubmitAxInteractionInput = Parameters<PmxCanvas['submitAxInteraction']>[0];
|
|
@@ -33,9 +29,6 @@ export interface CanvasAccess {
|
|
|
33
29
|
invoker(): OperationInvoker;
|
|
34
30
|
getLayout(): Promise<CanvasLayout>;
|
|
35
31
|
getNode(id: string): Promise<CanvasNodeState | undefined>;
|
|
36
|
-
refreshWebpageNode(id: string, url?: string): Promise<RefreshWebpageNodeResult>;
|
|
37
|
-
addHtmlNode(input: AddHtmlNodeInput): Promise<string>;
|
|
38
|
-
addHtmlPrimitive(input: AddHtmlPrimitiveInput): Promise<AddHtmlPrimitiveResult>;
|
|
39
32
|
getAxState(): Promise<AxStateResult>;
|
|
40
33
|
getAxContext(options?: {
|
|
41
34
|
consumer?: string;
|
|
@@ -7,8 +7,9 @@
|
|
|
7
7
|
*
|
|
8
8
|
* • Canvas-bound (`_axState`): focus, work items, approval gates, review
|
|
9
9
|
* annotations, elicitations, mode requests, policy. Snapshotted, cleared by
|
|
10
|
-
* `
|
|
11
|
-
* (via the injected `recordMutation` / `suppressed`
|
|
10
|
+
* `canvas_view` (`clear` action), replaced by `restore`. Mutators record
|
|
11
|
+
* undo/redo history (via the injected `recordMutation` / `suppressed`
|
|
12
|
+
* callbacks).
|
|
12
13
|
* • Timeline (audit-only): agent events, evidence, steering. DB-direct, NOT in
|
|
13
14
|
* `_axState`, NOT history-recorded, NOT snapshotted, retention-bounded.
|
|
14
15
|
* • Host/session: a single host-capability row in its own table.
|
|
@@ -3,9 +3,9 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Skill files ship inside the npm package under `skills/<name>/SKILL.md`
|
|
5
5
|
* but until 0.1.2 they were not discoverable to the agent — an agent
|
|
6
|
-
* calling `
|
|
7
|
-
* `skills/web-artifacts-builder/SKILL.md` prompt that documents
|
|
8
|
-
* workflow, stack choices, and gotchas.
|
|
6
|
+
* calling `canvas_app` (`build-artifact` action) had no way to find the
|
|
7
|
+
* companion `skills/web-artifacts-builder/SKILL.md` prompt that documents
|
|
8
|
+
* the workflow, stack choices, and gotchas.
|
|
9
9
|
*
|
|
10
10
|
* This module locates the bundled `skills/` directory relative to the
|
|
11
11
|
* package root (works for both repo-local development and global npm
|
|
@@ -34,7 +34,7 @@ export interface StructuredValidationResult {
|
|
|
34
34
|
summary: Record<string, unknown>;
|
|
35
35
|
}
|
|
36
36
|
declare const CANONICAL_GRAPH_TYPES: readonly ["line", "bar", "pie", "area", "scatter", "radar", "stacked-bar", "composed", "sparkline", "dot-plot", "bullet", "slopegraph"];
|
|
37
|
-
type CanvasGraphType = typeof CANONICAL_GRAPH_TYPES[number];
|
|
37
|
+
type CanvasGraphType = (typeof CANONICAL_GRAPH_TYPES)[number];
|
|
38
38
|
export declare function describeCanvasSchema(): {
|
|
39
39
|
ok: true;
|
|
40
40
|
source: 'running-server';
|
|
@@ -174,6 +174,8 @@ declare class CanvasStateManager {
|
|
|
174
174
|
private _stateFilePath;
|
|
175
175
|
private _db;
|
|
176
176
|
private _saveTimer;
|
|
177
|
+
/** Workspace root backing persistence and workspace-relative path resolution. */
|
|
178
|
+
get workspaceRoot(): string;
|
|
177
179
|
/** Set the workspace root to enable auto-persistence. */
|
|
178
180
|
setWorkspaceRoot(workspaceRoot: string): void;
|
|
179
181
|
private get blobsDir();
|
|
@@ -9,9 +9,7 @@
|
|
|
9
9
|
* Resolution order:
|
|
10
10
|
* 1. The direct prefixed form (`ext-app-<toolCallId>` if not already
|
|
11
11
|
* prefixed, otherwise `toolCallId` as-is).
|
|
12
|
-
* 2.
|
|
13
|
-
* v0.1.4 and still on disk. Remove this fallback in v0.2.x.
|
|
14
|
-
* 3. A scan of the layout for any `mcp-app` ext-app node carrying that
|
|
12
|
+
* 2. A scan of the layout for any `mcp-app` ext-app node carrying that
|
|
15
13
|
* `toolCallId` in its data.
|
|
16
14
|
*/
|
|
17
15
|
import type { CanvasNodeState } from './canvas-state.js';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export declare const HTML_PRIMITIVE_KINDS: readonly ["choice-grid", "plan-timeline", "review-sheet", "pr-writeup", "system-map", "code-walkthrough", "design-sheet", "component-gallery", "interaction-prototype", "flowchart", "deck", "presentation", "illustration-set", "explainer", "status-report", "incident-report", "triage-board", "config-editor", "prompt-tuner"];
|
|
2
|
-
export type HtmlPrimitiveKind = typeof HTML_PRIMITIVE_KINDS[number];
|
|
2
|
+
export type HtmlPrimitiveKind = (typeof HTML_PRIMITIVE_KINDS)[number];
|
|
3
3
|
export interface HtmlPrimitiveDescriptor {
|
|
4
4
|
kind: HtmlPrimitiveKind;
|
|
5
5
|
title: string;
|
|
@@ -13,7 +13,7 @@ import { type SerializedCanvasNode } from './canvas-serialization.js';
|
|
|
13
13
|
import type { HtmlPrimitiveKind } from './html-primitives.js';
|
|
14
14
|
import { type WebArtifactBuildInput, type WebArtifactCanvasBuildResult } from './web-artifacts.js';
|
|
15
15
|
import { type ExternalMcpTransportConfig } from './mcp-app-runtime.js';
|
|
16
|
-
import {
|
|
16
|
+
import type { DiagramPresetOpenInput } from './diagram-presets.js';
|
|
17
17
|
import { type GraphNodeInput, type JsonRenderNodeInput, type JsonRenderSpec } from '../json-render/server.js';
|
|
18
18
|
import type { CanvasAutomationWebViewOptions, CanvasAutomationWebViewStatus } from './server.js';
|
|
19
19
|
/**
|
|
@@ -557,21 +557,21 @@ export type { CanvasNodeState, CanvasEdge, CanvasLayout, ViewportState } from '.
|
|
|
557
557
|
export type { CanvasAutomationWebViewOptions, CanvasAutomationWebViewStatus, PrimaryWorkbenchCanvasPromptRequest, PrimaryWorkbenchIntent, } from './server.js';
|
|
558
558
|
export { emitPrimaryWorkbenchEvent, consumePrimaryWorkbenchIntents, setPrimaryWorkbenchAutoOpenEnabled, setPrimaryWorkbenchCanvasPromptHandler, startCanvasServer, stopCanvasServer, getCanvasServerPort, openUrlInExternalBrowser, getCanvasAutomationWebViewStatus, startCanvasAutomationWebView, stopCanvasAutomationWebView, evaluateCanvasAutomationWebView, resizeCanvasAutomationWebView, screenshotCanvasAutomationWebView, } from './server.js';
|
|
559
559
|
export { canvasState } from './canvas-state.js';
|
|
560
|
-
export type { CanvasAnnotation, CanvasSnapshot, CanvasSnapshotGcResult, CanvasSnapshotListOptions } from './canvas-state.js';
|
|
560
|
+
export type { CanvasAnnotation, CanvasSnapshot, CanvasSnapshotGcResult, CanvasSnapshotListOptions, } from './canvas-state.js';
|
|
561
561
|
export { findOpenCanvasPosition } from './placement.js';
|
|
562
562
|
export { searchNodes, buildSpatialContext, detectClusters, findNeighborhoods } from './spatial-analysis.js';
|
|
563
563
|
export type { SpatialCluster, SpatialContext, SpatialNeighbor, NodeSpatialInfo } from './spatial-analysis.js';
|
|
564
564
|
export { mutationHistory, diffLayouts, formatDiff } from './mutation-history.js';
|
|
565
565
|
export { recomputeCodeGraph, buildCodeGraphSummary, formatCodeGraph } from './code-graph.js';
|
|
566
566
|
export { describeCanvasSchema, validateStructuredCanvasPayload } from './canvas-schema.js';
|
|
567
|
-
export { buildHtmlPrimitive, getHtmlPrimitiveSemanticMetadata, isHtmlPrimitiveKind, listHtmlPrimitiveDescriptors } from './html-primitives.js';
|
|
567
|
+
export { buildHtmlPrimitive, getHtmlPrimitiveSemanticMetadata, isHtmlPrimitiveKind, listHtmlPrimitiveDescriptors, } from './html-primitives.js';
|
|
568
568
|
export { buildWebArtifactOnCanvas, executeWebArtifactBuild, openWebArtifactInCanvas, resolveWebArtifactScriptPath, resolveWorkspacePath, } from './web-artifacts.js';
|
|
569
569
|
export { buildGraphSpec, buildJsonRenderViewerHtml, createJsonRenderNodeData, GRAPH_NODE_SIZE, JSON_RENDER_NODE_SIZE, normalizeAndValidateJsonRenderSpec, } from '../json-render/server.js';
|
|
570
570
|
export type { CodeGraphSummary, CodeGraphEdge } from './code-graph.js';
|
|
571
571
|
export type { MutationEntry, MutationSummary, SnapshotDiffResult } from './mutation-history.js';
|
|
572
572
|
export type { WebArtifactBuildInput, WebArtifactBuildOutput, WebArtifactCanvasBuildResult, WebArtifactCanvasOpenResult, } from './web-artifacts.js';
|
|
573
573
|
export type { GraphNodeInput, JsonRenderNodeInput, JsonRenderSpec } from '../json-render/server.js';
|
|
574
|
-
export type { HtmlPrimitiveKind, HtmlPrimitiveDescriptor, HtmlPrimitiveInput, HtmlPrimitiveBuildResult } from './html-primitives.js';
|
|
574
|
+
export type { HtmlPrimitiveKind, HtmlPrimitiveDescriptor, HtmlPrimitiveInput, HtmlPrimitiveBuildResult, } from './html-primitives.js';
|
|
575
575
|
export { traceManager } from './trace-manager.js';
|
|
576
576
|
export type { PmxAxApprovalGate, PmxAxApprovalStatus, PmxAxCommandDescriptor, PmxAxContext, PmxAxEvent, PmxAxElicitation, PmxAxElicitationStatus, PmxAxEventKind, PmxAxEvidence, PmxAxEvidenceKind, PmxAxFocusState, PmxAxHostCapability, PmxAxMode, PmxAxModeRequest, PmxAxModeRequestStatus, PmxAxPolicy, PmxAxReviewAnchorType, PmxAxReviewAnnotation, PmxAxReviewKind, PmxAxReviewRegion, PmxAxReviewSeverity, PmxAxReviewStatus, PmxAxSource, PmxAxState, PmxAxSteeringMessage, PmxAxTimelineSummary, PmxAxWorkItem, PmxAxWorkItemStatus, } from './ax-state.js';
|
|
577
577
|
export type { AxTimelineQuery } from './canvas-db.js';
|
|
@@ -9,17 +9,22 @@
|
|
|
9
9
|
* to the standalone `canvas_add_edge` — same op, same arg mapping, same result
|
|
10
10
|
* shape — by construction. No handler logic lives here.
|
|
11
11
|
*
|
|
12
|
-
* Migration (docs/api-stability.md + plan-006): composites
|
|
13
|
-
* v0.2 alongside the legacy single-purpose tools
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* Migration (docs/api-stability.md + plan-006): composites landed ADDITIVELY in
|
|
13
|
+
* v0.2 alongside the legacy single-purpose tools. As of v0.3.0 the legacy tools
|
|
14
|
+
* those composites fold are REMOVED (registration-suppressed — see
|
|
15
|
+
* `compositeFoldedOpNames` below); every action here maps to a registry-backed
|
|
16
|
+
* operation (plan-005 slices 1–7 + plan-008 Wave 1) that is now reachable ONLY
|
|
17
|
+
* through its composite (or `canvas_batch`).
|
|
16
18
|
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
19
|
+
* Deferred to v0.4: the `canvas_snapshot` composite (still a name collision —
|
|
20
|
+
* see below). Its 6 legacy snapshot standalones (`canvas_snapshot`,
|
|
21
|
+
* `canvas_list_snapshots`, `canvas_restore`, `canvas_delete_snapshot`,
|
|
22
|
+
* `canvas_gc_snapshots`, `canvas_diff`) stay registered in v0.3.0 but are marked
|
|
23
|
+
* deprecated (description-prefixed) per docs/api-stability.md's
|
|
24
|
+
* deprecate-one-minor-before-removal rule. (`canvas_webview` shipped in plan-008
|
|
25
|
+
* Wave 3 via runner injection; `canvas_app` shipped in Wave 4 — open-mcp-app /
|
|
26
|
+
* diagram / build-artifact. Wave 5 folded the last three legacy tools
|
|
27
|
+
* deprecate-only — NO per-action input-injection mechanism was needed:
|
|
23
28
|
* `canvas_add_html_node` / `canvas_add_html_primitive` → `canvas_node` action
|
|
24
29
|
* "add" (type:"html" [+ primitive]); `canvas_refresh_webpage_node` → `canvas_node`
|
|
25
30
|
* action "update" (refresh:true). `canvas_screenshot` stays standalone — it
|
|
@@ -30,8 +35,8 @@
|
|
|
30
35
|
* name is ALREADY a legacy standalone tool (the save-snapshot tool, op
|
|
31
36
|
* `snapshot.save`), so it cannot be added additively without a name clash, and
|
|
32
37
|
* repurposing `canvas_snapshot` to be action-discriminated now would break
|
|
33
|
-
* existing callers. It lands in v0.
|
|
34
|
-
*
|
|
38
|
+
* existing callers. It lands in v0.4, in the same change that removes the 6
|
|
39
|
+
* kept-but-deprecated legacy snapshot tools and frees the name.
|
|
35
40
|
*
|
|
36
41
|
* This module must never import server.ts or index.ts.
|
|
37
42
|
*/
|
|
@@ -45,7 +50,7 @@ import { type ZodRawShape } from 'zod';
|
|
|
45
50
|
* - Two-discriminator (`canvas_ax_gate`, plan-007 Slice C): a `kind` × `action`
|
|
46
51
|
* matrix folds 9 ops into one tool. Set `extraDiscriminatorShape` (the `kind`
|
|
47
52
|
* enum), `memberOps` (the op names — used to derive the schema union + the
|
|
48
|
-
*
|
|
53
|
+
* folded-op set), `actionEnum` (the action discriminator values), and
|
|
49
54
|
* `resolveOp` (maps `{ kind, action }` → op name, or undefined for an invalid
|
|
50
55
|
* combo → a loud error at dispatch). The flat `actions` map is left empty for
|
|
51
56
|
* these; the matrix path uses `resolveOp` instead.
|
|
@@ -76,8 +81,9 @@ export interface CompositeToolDefinition {
|
|
|
76
81
|
actionEnum?: readonly string[];
|
|
77
82
|
/**
|
|
78
83
|
* Two-discriminator extension: every member op name. Used to build the schema
|
|
79
|
-
* union (all member-op fields, optional) and to
|
|
80
|
-
*
|
|
84
|
+
* union (all member-op fields, optional) and to populate the folded-op set
|
|
85
|
+
* (`compositeFoldedOpNames`) that suppresses each member op's standalone
|
|
86
|
+
* registration.
|
|
81
87
|
*/
|
|
82
88
|
memberOps?: string[];
|
|
83
89
|
/**
|
|
@@ -110,12 +116,12 @@ export interface CompositeToolDefinition {
|
|
|
110
116
|
}
|
|
111
117
|
export declare const compositeToolDefinitions: CompositeToolDefinition[];
|
|
112
118
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
*
|
|
117
|
-
*
|
|
118
|
-
* Deriving it
|
|
119
|
-
* folded action automatically
|
|
119
|
+
* Operation names FOLDED by a composite, DERIVED from the composites: every op
|
|
120
|
+
* a composite folds had its standalone single-purpose tool REMOVED in v0.3.0
|
|
121
|
+
* (see docs/api-stability.md). This set is the do-not-register list —
|
|
122
|
+
* `registerOperationTools` skips any op whose name is in it, since the op is
|
|
123
|
+
* only reachable through its composite (and through `canvas_batch`) now.
|
|
124
|
+
* Deriving it from the composites keeps suppression in lockstep with them — a
|
|
125
|
+
* newly folded action is automatically suppressed from standalone registration.
|
|
120
126
|
*/
|
|
121
|
-
export declare function
|
|
127
|
+
export declare function compositeFoldedOpNames(definitions?: CompositeToolDefinition[]): Set<string>;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Shared body reader: preserves the parsed JSON value as-is (object, array,
|
|
3
3
|
* or primitive) — per-op `readInput` decides what to do with non-object
|
|
4
|
-
* bodies; the shared reader never coerces.
|
|
4
|
+
* bodies; the shared reader never coerces. A non-empty body that fails to
|
|
5
|
+
* parse is a 400 (OperationError), never a silent empty input.
|
|
5
6
|
*/
|
|
6
7
|
export declare function readJsonValue(req: Request): Promise<unknown>;
|
|
7
8
|
export declare function dispatchOperationRoute(req: Request, url: URL): Promise<Response | null>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
export { executeOperation, getOperation, listOperations, registerOperation, setOperationEventEmitter, } from './registry.js';
|
|
2
2
|
export { dispatchOperationRoute } from './http.js';
|
|
3
3
|
export { runCanvasBatchOperation, type BatchEnvelope } from './ops/batch.js';
|
|
4
|
-
export {
|
|
4
|
+
export type { OpenMcpAppCoreResult } from './ops/app.js';
|
|
5
5
|
export { LocalOperationInvoker, HttpOperationInvoker, type OperationInvoker } from './invoker.js';
|
|
6
6
|
export { registerOperationTools, registerCompositeTools, type OperationToolHost } from './mcp.js';
|
|
7
7
|
export { compositeToolDefinitions, type CompositeToolDefinition } from './composites.js';
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* agent is ABOUT to make (create / move / connect / remove / edit) so the canvas
|
|
6
6
|
* can paint a faint placeholder before the real mutation lands. Like a
|
|
7
7
|
* multiplayer cursor, it auto-expires, is count-capped, and never enters
|
|
8
|
-
* `
|
|
8
|
+
* `canvas_query` (`layout` action), `state.json`, or snapshots.
|
|
9
9
|
*
|
|
10
10
|
* This module is import-shared by the server (IntentRegistry + the intent ops)
|
|
11
11
|
* and the client (intent-store + IntentLayer); it must stay free of any
|
package/docs/RELEASE.md
CHANGED
|
@@ -46,14 +46,18 @@ and exercises the CLI flows from
|
|
|
46
46
|
|
|
47
47
|
## Versioning
|
|
48
48
|
|
|
49
|
-
Semantic versioning
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
49
|
+
Semantic versioning, in 0.x semver honestly (see `docs/api-stability.md`).
|
|
50
|
+
We are pre-1.0, so minor versions — not just major — are the breaking-change
|
|
51
|
+
boundary:
|
|
52
|
+
|
|
53
|
+
- Patch (`0.x.y → 0.x.y+1`): bug fixes, hardening, internal cleanups,
|
|
54
|
+
additive CLI flags / MCP fields with backwards-compat fallbacks. Never
|
|
55
|
+
breaks a public surface.
|
|
56
|
+
- Minor (`0.x → 0.x+1`): documented breaking changes are allowed only here
|
|
57
|
+
(e.g. the 0.2 → 0.3 removal of the 57 deprecated legacy single-purpose MCP
|
|
58
|
+
tools in favor of their composite replacements). Every breaking change in
|
|
59
|
+
a minor needs a `### Breaking` CHANGELOG entry naming the replacement —
|
|
60
|
+
see the release-blocker gate below.
|
|
57
61
|
- Major (`0.x → 1.0`): production-stability commitment.
|
|
58
62
|
|
|
59
63
|
CLAUDE.md rule #5 (CanvasStateManager / PmxCanvas SDK / HTTP / MCP
|
|
@@ -70,6 +74,11 @@ Each release section uses these subheadings:
|
|
|
70
74
|
command/flag, SDK export, JSON shape).
|
|
71
75
|
- **Changed** — behavior changes that aren't strictly bug fixes
|
|
72
76
|
(response shape additions, schema cleanups, stricter validation).
|
|
77
|
+
- **Breaking** — removed or incompatibly changed public surface (see
|
|
78
|
+
`docs/api-stability.md`). Required at minor version boundaries whenever a
|
|
79
|
+
public surface breaks; must name the replacement.
|
|
80
|
+
- **Deprecated** — public surface marked for removal in a future minor,
|
|
81
|
+
per the `docs/api-stability.md` deprecation policy.
|
|
73
82
|
- **Fixed** — bug fixes.
|
|
74
83
|
- **Internal** — refactors, test additions, docs that don't affect
|
|
75
84
|
the public surface.
|
|
@@ -78,6 +87,12 @@ Don't ship a release without a CHANGELOG entry. The GitHub release
|
|
|
78
87
|
notes file (`/tmp/pmx-canvas-vX.Y.Z-release-notes.md` by convention)
|
|
79
88
|
expands on the CHANGELOG with examples and migration notes.
|
|
80
89
|
|
|
90
|
+
**Release-blocker gate:** a breaking change without a `### Breaking`
|
|
91
|
+
CHANGELOG entry blocks the release (`docs/api-stability.md`). Check the
|
|
92
|
+
diff against the previous tag for removed/renamed public surface — MCP
|
|
93
|
+
tool names, HTTP routes, SDK exports, CLI flags — before tagging; if
|
|
94
|
+
anything broke and isn't named under `### Breaking`, add the entry first.
|
|
95
|
+
|
|
81
96
|
## Tag → publish
|
|
82
97
|
|
|
83
98
|
The publish workflow ([`/.github/workflows/publish.yml`](../.github/workflows/publish.yml))
|
|
@@ -20,9 +20,9 @@ surface each one binds to.
|
|
|
20
20
|
| Adapter method | PMX surface (owned) | Harness-owned part |
|
|
21
21
|
| --- | --- | --- |
|
|
22
22
|
| `pullContext()` | `GET /api/canvas/ax/context?consumer=<id>` · `canvas://ax-context` — full board **plus** a compact `delivery` lead block | When/where to inject it into the model's turn |
|
|
23
|
-
| `deliverSteer()` | `GET /api/canvas/ax/delivery/pending?consumer=<id>` · `
|
|
23
|
+
| `deliverSteer()` | `GET /api/canvas/ax/delivery/pending?consumer=<id>` · `canvas_ax_delivery { action: "claim" }` → act → `POST …/delivery/<id>/mark` · `canvas_ax_delivery { action: "mark" }` | Calling the host's native send/wake |
|
|
24
24
|
| `ingestActivity(event)` | `POST /api/canvas/ax/activity` · `canvas_ingest_activity` — board auto-reacts | Forwarding the host's tool/session hooks |
|
|
25
|
-
| `awaitGate(id)` | `GET /api/canvas/ax/{approval\|elicitation\|mode}/<id>?waitMs=` · `
|
|
25
|
+
| `awaitGate(id)` | `GET /api/canvas/ax/{approval\|elicitation\|mode}/<id>?waitMs=` · `canvas_ax_gate { kind: "approval"\|"elicitation"\|"mode", action: "await" }` | Optionally surfacing a native modal; the agent must await PMX |
|
|
26
26
|
| `mirrorLog(event)` *(optional)* | `GET /api/canvas/ax/timeline` · `canvas://ax-timeline` | Writing AX events into the host's own chat/session log |
|
|
27
27
|
|
|
28
28
|
## Steering is gated, not pushed (#54)
|
|
@@ -37,8 +37,8 @@ message; it does **not** wake the agent. It reaches the next turn only when:
|
|
|
37
37
|
2. **A human message fires the turn.** A sandbox button click cannot itself create a
|
|
38
38
|
new agent turn (an app-platform constraint). Any human prompt triggers the injection.
|
|
39
39
|
3. **The agent acts, then acks.** Injected `pendingSteering` / `pendingActivity` is
|
|
40
|
-
*to-do*, not narration: act on it, then `
|
|
41
|
-
(or resolve the work item / gate). Until acked, steering re-injects every gated turn.
|
|
40
|
+
*to-do*, not narration: act on it, then `canvas_ax_delivery { action: "mark" }`
|
|
41
|
+
the steering (or resolve the work item / gate). Until acked, steering re-injects every gated turn.
|
|
42
42
|
|
|
43
43
|
The `delivery` lead block (`GET /api/canvas/ax/context?consumer=<id>`) is the
|
|
44
44
|
robustness hedge: it's compact and sits above the full dump, so an adapter can inject
|
|
@@ -69,9 +69,9 @@ turn"), never imply it interrupts the agent now.
|
|
|
69
69
|
tool becomes a blocked work item + a review finding + evidence without the agent
|
|
70
70
|
remembering to push it. Reactions are kind-driven and overridable per call.
|
|
71
71
|
- **Blocking gates (gates that actually gate).** Before, an approval gate was inert
|
|
72
|
-
data the agent had to poll. With `
|
|
73
|
-
long-poll), the agent requests a gate then *blocks* until the
|
|
74
|
-
the browser — real human-in-the-loop control on any harness.
|
|
72
|
+
data the agent had to poll. With `canvas_ax_gate { kind: "approval", action: "await" }`
|
|
73
|
+
(and the `?waitMs` HTTP long-poll), the agent requests a gate then *blocks* until the
|
|
74
|
+
human resolves it in the browser — real human-in-the-loop control on any harness.
|
|
75
75
|
|
|
76
76
|
## What stays harness-owned
|
|
77
77
|
|
|
@@ -6,7 +6,7 @@ snapshot-vs-audit boundary; it is the documented module boundary for
|
|
|
6
6
|
`AxStateManager` (`src/server/ax-state-manager.ts`), which `CanvasStateManager`
|
|
7
7
|
holds and delegates to.
|
|
8
8
|
|
|
9
|
-
| Partition | Members | Storage | Snapshotted | Cleared by `
|
|
9
|
+
| Partition | Members | Storage | Snapshotted | Cleared by `canvas_view { action: "clear" }` | Cleared by `restore` |
|
|
10
10
|
|-----------|---------|---------|:-----------:|:-------------------------:|:--------------------:|
|
|
11
11
|
| **Canvas-bound** | `focus`, `workItems`, `approvalGates`, `reviewAnnotations`, `elicitations`, `modeRequests`, `policy` | in-memory `_axState` + one JSON blob in the `ax_state` table | ✅ | ✅ | ✅ (replaced by the snapshot's AX) |
|
|
12
12
|
| **Timeline (audit-only)** | `agent-event`, `evidence-item`, `steering-message` | `ax_events` / `ax_evidence` / `ax_steering` tables, 500-row retention, sequential ids | ❌ | ❌ | ❌ |
|
|
@@ -15,14 +15,15 @@ holds and delegates to.
|
|
|
15
15
|
**Rules.** Canvas-bound state travels with the canvas (snapshot / restore / clear);
|
|
16
16
|
timeline and host data are diagnostic and survive all three. Timeline rows are
|
|
17
17
|
append-only, retention-bounded (`AX_TIMELINE_RETENTION = 500` per table), and
|
|
18
|
-
read via `
|
|
19
|
-
row is reported by adapters and read via `
|
|
18
|
+
read via `canvas_ax_timeline { action: "read" }` / `canvas://ax-timeline`. The
|
|
19
|
+
host-capability row is reported by adapters and read via `canvas_ax_state {
|
|
20
|
+
action: "get" }`.
|
|
20
21
|
|
|
21
22
|
## Read surfaces
|
|
22
23
|
|
|
23
|
-
- **Canvas-bound:** `
|
|
24
|
-
- **Timeline:** `
|
|
25
|
-
- **Host:** `
|
|
24
|
+
- **Canvas-bound:** `canvas_ax_state { action: "get" }`, `canvas://ax`, `canvas://ax-context`, `canvas://ax-work`
|
|
25
|
+
- **Timeline:** `canvas_ax_timeline { action: "read" }`, `canvas://ax-timeline`, `canvas://ax-pending-steering`, `canvas://ax-delivery`
|
|
26
|
+
- **Host:** `canvas_ax_state { action: "get" }`
|
|
26
27
|
|
|
27
28
|
## Node-deletion semantics (soft-orphan + audit)
|
|
28
29
|
|
|
@@ -144,11 +144,11 @@ These flags are intentionally automation-only. They do **not** imply a visible B
|
|
|
144
144
|
|
|
145
145
|
Implemented in [`src/mcp/server.ts`](../src/mcp/server.ts):
|
|
146
146
|
|
|
147
|
-
- `
|
|
148
|
-
- `
|
|
149
|
-
- `
|
|
150
|
-
- `
|
|
151
|
-
- `
|
|
147
|
+
- `canvas_webview { action: "status" }`
|
|
148
|
+
- `canvas_webview { action: "start" }`
|
|
149
|
+
- `canvas_webview { action: "stop" }`
|
|
150
|
+
- `canvas_webview { action: "evaluate" }`
|
|
151
|
+
- `canvas_webview { action: "resize" }`
|
|
152
152
|
- `canvas_screenshot`
|
|
153
153
|
|
|
154
154
|
Current MCP behavior:
|
package/docs/cli.md
CHANGED
|
@@ -217,7 +217,7 @@ take a screenshot when the drawn form matters.
|
|
|
217
217
|
|
|
218
218
|
Humans draw with the pen toolbar button and remove marks with the eraser button.
|
|
219
219
|
If an agent already knows the annotation ID from context, it can remove it through
|
|
220
|
-
MCP with `
|
|
220
|
+
MCP with `canvas_view { action: "remove-annotation", id }`.
|
|
221
221
|
|
|
222
222
|
## When to reach for the CLI
|
|
223
223
|
|
package/docs/http-api.md
CHANGED
|
@@ -3,14 +3,18 @@
|
|
|
3
3
|
REST endpoints for all canvas operations + an SSE event stream. Works from
|
|
4
4
|
any language. Default base URL: `http://localhost:4313`.
|
|
5
5
|
|
|
6
|
+
A non-empty request body that is not valid JSON returns
|
|
7
|
+
`400 { "ok": false, "error": "Malformed JSON body." }` on every route; empty
|
|
8
|
+
bodies are treated as an empty request.
|
|
9
|
+
|
|
6
10
|
## Canvas state
|
|
7
11
|
|
|
8
12
|
```bash
|
|
9
13
|
# Get canvas state
|
|
10
14
|
curl http://localhost:4313/api/canvas/state
|
|
11
15
|
|
|
12
|
-
# Search nodes
|
|
13
|
-
curl "http://localhost:4313/api/canvas/search?q=auth"
|
|
16
|
+
# Search nodes (optional limit= caps the result count)
|
|
17
|
+
curl "http://localhost:4313/api/canvas/search?q=auth&limit=10"
|
|
14
18
|
|
|
15
19
|
# Validate the current layout
|
|
16
20
|
curl http://localhost:4313/api/canvas/validate
|
|
@@ -133,7 +137,7 @@ Host-agnostic agent-experience primitives across three state partitions.
|
|
|
133
137
|
Canvas-bound state (work items, approval gates, review annotations) rides
|
|
134
138
|
canvas snapshots; timeline state (events, evidence, steering) persists for
|
|
135
139
|
diagnostics but is retention-bounded and not restored by snapshots; the host
|
|
136
|
-
capability is reported by adapters and survives `
|
|
140
|
+
capability is reported by adapters and survives `canvas_view { action: "clear" }`.
|
|
137
141
|
|
|
138
142
|
```bash
|
|
139
143
|
# Timeline — record a normalized agent-event
|
|
@@ -272,6 +276,34 @@ and `/ax/mode/:id/resolve` return 404 for unknown IDs; `/ax/activity` requires a
|
|
|
272
276
|
valid `kind` + `title` (400 otherwise); the single-item gate GETs return 404 for
|
|
273
277
|
unknown IDs and clamp `?waitMs` to ≤120000.
|
|
274
278
|
|
|
279
|
+
## Ghost Cursor intents (ephemeral)
|
|
280
|
+
|
|
281
|
+
Intents are verb-routed over HTTP — there is **no `action` field**. That
|
|
282
|
+
discriminator exists only on the MCP `canvas_intent` composite; `POST` always
|
|
283
|
+
signals a *new* intent, so a body like `{"action":"clear"}` is rejected by the
|
|
284
|
+
registry's kind validation. Pick the operation by method + path:
|
|
285
|
+
|
|
286
|
+
```bash
|
|
287
|
+
# Signal a ghost — returns { ok, intent } with the id. Auto-expires after ttlMs
|
|
288
|
+
# (default 8000, max 60000), so cleanup is optional.
|
|
289
|
+
curl -X POST http://localhost:4313/api/canvas/ax/intent \
|
|
290
|
+
-H "Content-Type: application/json" \
|
|
291
|
+
-d '{"kind":"create","position":{"x":400,"y":300},"nodeType":"markdown","label":"Add evidence","reason":"collecting run logs"}'
|
|
292
|
+
|
|
293
|
+
# Update the ghost (position/label/reason/confidence/ttlMs; vetoed:true dissolves
|
|
294
|
+
# it AND poisons the id so a later linked settle is rejected)
|
|
295
|
+
curl -X PATCH http://localhost:4313/api/canvas/ax/intent/<id> \
|
|
296
|
+
-H "Content-Type: application/json" \
|
|
297
|
+
-d '{"position":{"x":520,"y":300},"reason":"moved next to the trace"}'
|
|
298
|
+
|
|
299
|
+
# Clear the ghost: plain DELETE dissolves it; settle it into the real node it
|
|
300
|
+
# became via settledNodeId, or veto it. Fields are accepted as JSON body or
|
|
301
|
+
# query params (?vetoed=true/false is coerced; other values are rejected 400).
|
|
302
|
+
curl -X DELETE http://localhost:4313/api/canvas/ax/intent/<id>
|
|
303
|
+
curl -X DELETE "http://localhost:4313/api/canvas/ax/intent/<id>?settledNodeId=node-42"
|
|
304
|
+
curl -X DELETE "http://localhost:4313/api/canvas/ax/intent/<id>?vetoed=true"
|
|
305
|
+
```
|
|
306
|
+
|
|
275
307
|
## Diagrams (Excalidraw preset)
|
|
276
308
|
|
|
277
309
|
```bash
|