pmx-canvas 0.1.11 → 0.1.12
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 +48 -0
- package/dist/types/mcp/canvas-access.d.ts +87 -0
- package/dist/types/server/server.d.ts +1 -0
- package/package.json +1 -1
- package/src/mcp/canvas-access.ts +651 -0
- package/src/mcp/server.ts +160 -95
- package/src/server/index.ts +2 -2
- package/src/server/server.ts +4 -1
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,53 @@
|
|
|
3
3
|
All notable changes to `pmx-canvas` are documented here. This project follows
|
|
4
4
|
[Semantic Versioning](https://semver.org/).
|
|
5
5
|
|
|
6
|
+
## [0.1.12] - 2026-05-02
|
|
7
|
+
|
|
8
|
+
MCP/canvas state-sharing pass on top of 0.1.11. The MCP server now
|
|
9
|
+
attaches to an already-running canvas daemon for the current workspace
|
|
10
|
+
instead of spinning up a parallel in-process state, so HTTP-created
|
|
11
|
+
nodes and browser pins show up immediately in MCP responses and emit
|
|
12
|
+
the matching resource notifications. The SDK's port binding is also
|
|
13
|
+
hardened so explicit `port:` requests no longer silently land on a
|
|
14
|
+
fallback port.
|
|
15
|
+
|
|
16
|
+
### Added
|
|
17
|
+
|
|
18
|
+
- **`startCanvasServer({ allowPortFallback: false })` and SDK port
|
|
19
|
+
determinism.** The HTTP server option lets callers opt out of the
|
|
20
|
+
fallback-port walk. The Bun SDK's `PmxCanvas.start()` and
|
|
21
|
+
`PmxCanvas.startAutomationWebView()` now pass this flag, so when an
|
|
22
|
+
SDK consumer says `createCanvas({ port: 4313 })` they either bind to
|
|
23
|
+
4313 or fail loudly — preventing two SDK instances or an SDK + a
|
|
24
|
+
daemon from racing onto silently different ports.
|
|
25
|
+
- **`CanvasAccess` abstraction with local + remote backends.** A new
|
|
26
|
+
`src/mcp/canvas-access.ts` module defines the interface the MCP
|
|
27
|
+
server uses to talk to canvas state. `LocalCanvasAccess` wraps an
|
|
28
|
+
in-process `PmxCanvas` (legacy behavior); `RemoteCanvasAccess` talks
|
|
29
|
+
to an existing daemon over HTTP and consumes its SSE stream. The
|
|
30
|
+
factory probes for an existing canvas server in the workspace before
|
|
31
|
+
starting a new one.
|
|
32
|
+
|
|
33
|
+
### Changed
|
|
34
|
+
|
|
35
|
+
- **MCP server defers to an existing canvas daemon as the state
|
|
36
|
+
authority.** When `pmx-canvas --mcp` boots in a workspace that
|
|
37
|
+
already has a canvas server running on the agreed port, the MCP
|
|
38
|
+
process now reads and writes through that daemon's HTTP API instead
|
|
39
|
+
of starting its own canvas. Nodes created via the daemon's HTTP API
|
|
40
|
+
(or by a human in the browser) are visible to MCP queries
|
|
41
|
+
immediately, and SSE events from the daemon are translated into
|
|
42
|
+
MCP `notifications/resources/updated` calls for `canvas://layout`,
|
|
43
|
+
`canvas://summary`, `canvas://spatial-context`, `canvas://history`,
|
|
44
|
+
`canvas://code-graph`, and `canvas://pinned-context`.
|
|
45
|
+
|
|
46
|
+
### Internal
|
|
47
|
+
|
|
48
|
+
- Regression coverage for: `canvas_add_node` strict-size persistence
|
|
49
|
+
through MCP, an MCP session using an existing daemon as the state
|
|
50
|
+
authority for HTTP-created nodes, and HTTP node creation broadcasting
|
|
51
|
+
a live `canvas-layout-update` SSE event.
|
|
52
|
+
|
|
6
53
|
## [0.1.11] - 2026-05-02
|
|
7
54
|
|
|
8
55
|
Agent ergonomics + chart polish on top of 0.1.10. Adds a `--strict-size`
|
|
@@ -316,6 +363,7 @@ otherwise have to discover by trial and error.
|
|
|
316
363
|
- Regression coverage for snapshot flat-`id` aliases on both MCP and
|
|
317
364
|
HTTP surfaces, plus async / top-level-`await` WebView script bodies.
|
|
318
365
|
|
|
366
|
+
[0.1.12]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.12
|
|
319
367
|
[0.1.11]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.11
|
|
320
368
|
[0.1.10]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.10
|
|
321
369
|
[0.1.9]: https://github.com/pskoett/pmx-canvas/releases/tag/v0.1.9
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import { type CanvasLayout, type CanvasNodeState, type CanvasSnapshot, type PmxCanvas } from '../server/index.js';
|
|
2
|
+
type AddNodeInput = Parameters<PmxCanvas['addNode']>[0];
|
|
3
|
+
type AddWebpageNodeInput = Parameters<PmxCanvas['addWebpageNode']>[0];
|
|
4
|
+
type RefreshWebpageNodeResult = Awaited<ReturnType<PmxCanvas['refreshWebpageNode']>>;
|
|
5
|
+
type OpenMcpAppInput = Parameters<PmxCanvas['openMcpApp']>[0];
|
|
6
|
+
type OpenMcpAppResult = Awaited<ReturnType<PmxCanvas['openMcpApp']>>;
|
|
7
|
+
type AddDiagramInput = Parameters<PmxCanvas['addDiagram']>[0];
|
|
8
|
+
type AddJsonRenderNodeInput = Parameters<PmxCanvas['addJsonRenderNode']>[0];
|
|
9
|
+
type AddJsonRenderNodeResult = ReturnType<PmxCanvas['addJsonRenderNode']>;
|
|
10
|
+
type AddGraphNodeInput = Parameters<PmxCanvas['addGraphNode']>[0];
|
|
11
|
+
type AddGraphNodeResult = ReturnType<PmxCanvas['addGraphNode']>;
|
|
12
|
+
type UpdateNodePatch = Parameters<PmxCanvas['updateNode']>[1];
|
|
13
|
+
type AddEdgeInput = Parameters<PmxCanvas['addEdge']>[0];
|
|
14
|
+
type CreateGroupInput = Parameters<PmxCanvas['createGroup']>[0];
|
|
15
|
+
type GroupNodesOptions = Parameters<PmxCanvas['groupNodes']>[2];
|
|
16
|
+
type ArrangeLayout = Parameters<PmxCanvas['arrange']>[0];
|
|
17
|
+
type FocusNodeResult = ReturnType<PmxCanvas['focusNode']>;
|
|
18
|
+
type FitViewOptions = Parameters<PmxCanvas['fitView']>[0];
|
|
19
|
+
type FitViewResult = ReturnType<PmxCanvas['fitView']>;
|
|
20
|
+
type SearchResult = ReturnType<PmxCanvas['search']>;
|
|
21
|
+
type UndoRedoResult = Awaited<ReturnType<PmxCanvas['undo']>>;
|
|
22
|
+
type HistoryResult = ReturnType<PmxCanvas['getHistory']>;
|
|
23
|
+
type SetContextPinsResult = ReturnType<PmxCanvas['setContextPins']>;
|
|
24
|
+
type RunBatchInput = Parameters<PmxCanvas['runBatch']>[0];
|
|
25
|
+
type RunBatchResult = Awaited<ReturnType<PmxCanvas['runBatch']>>;
|
|
26
|
+
type SnapshotList = ReturnType<PmxCanvas['listSnapshots']>;
|
|
27
|
+
type DeleteSnapshotResult = ReturnType<PmxCanvas['deleteSnapshot']>;
|
|
28
|
+
type DiffSnapshotResult = ReturnType<PmxCanvas['diffSnapshot']>;
|
|
29
|
+
type CodeGraphResult = ReturnType<PmxCanvas['getCodeGraph']>;
|
|
30
|
+
type ValidationResult = ReturnType<PmxCanvas['validate']>;
|
|
31
|
+
type WebArtifactInput = Parameters<PmxCanvas['buildWebArtifact']>[0];
|
|
32
|
+
type WebArtifactResult = Awaited<ReturnType<PmxCanvas['buildWebArtifact']>>;
|
|
33
|
+
type AutomationWebViewOptions = Parameters<PmxCanvas['startAutomationWebView']>[0];
|
|
34
|
+
type AutomationWebViewStatus = Awaited<ReturnType<PmxCanvas['startAutomationWebView']>>;
|
|
35
|
+
type AutomationEvaluateResult = Awaited<ReturnType<PmxCanvas['evaluateAutomationWebView']>>;
|
|
36
|
+
type AutomationScreenshotOptions = Parameters<PmxCanvas['screenshotAutomationWebView']>[0];
|
|
37
|
+
export interface CanvasAccess {
|
|
38
|
+
readonly port: number;
|
|
39
|
+
readonly remoteBaseUrl: string | null;
|
|
40
|
+
getLayout(): Promise<CanvasLayout>;
|
|
41
|
+
getNode(id: string): Promise<CanvasNodeState | undefined>;
|
|
42
|
+
addNode(input: AddNodeInput): Promise<string>;
|
|
43
|
+
addWebpageNode(input: AddWebpageNodeInput): Promise<Awaited<ReturnType<PmxCanvas['addWebpageNode']>>>;
|
|
44
|
+
refreshWebpageNode(id: string, url?: string): Promise<RefreshWebpageNodeResult>;
|
|
45
|
+
openMcpApp(input: OpenMcpAppInput): Promise<OpenMcpAppResult>;
|
|
46
|
+
addDiagram(input: AddDiagramInput): Promise<OpenMcpAppResult>;
|
|
47
|
+
addJsonRenderNode(input: AddJsonRenderNodeInput): Promise<AddJsonRenderNodeResult>;
|
|
48
|
+
addGraphNode(input: AddGraphNodeInput): Promise<AddGraphNodeResult>;
|
|
49
|
+
buildWebArtifact(input: WebArtifactInput): Promise<WebArtifactResult>;
|
|
50
|
+
updateNode(id: string, patch: UpdateNodePatch): Promise<void>;
|
|
51
|
+
removeNode(id: string): Promise<void>;
|
|
52
|
+
addEdge(input: AddEdgeInput): Promise<string>;
|
|
53
|
+
removeEdge(id: string): Promise<void>;
|
|
54
|
+
createGroup(input: CreateGroupInput): Promise<string>;
|
|
55
|
+
groupNodes(groupId: string, childIds: string[], options?: GroupNodesOptions): Promise<boolean>;
|
|
56
|
+
ungroupNodes(groupId: string): Promise<boolean>;
|
|
57
|
+
arrange(layout?: ArrangeLayout): Promise<void>;
|
|
58
|
+
focusNode(id: string, options?: {
|
|
59
|
+
noPan?: boolean;
|
|
60
|
+
}): Promise<FocusNodeResult>;
|
|
61
|
+
fitView(options?: FitViewOptions): Promise<FitViewResult>;
|
|
62
|
+
clear(): Promise<void>;
|
|
63
|
+
search(query: string): Promise<SearchResult>;
|
|
64
|
+
undo(): Promise<UndoRedoResult>;
|
|
65
|
+
redo(): Promise<UndoRedoResult>;
|
|
66
|
+
getHistory(): Promise<HistoryResult>;
|
|
67
|
+
setContextPins(nodeIds: string[], mode?: 'set' | 'add' | 'remove'): Promise<SetContextPinsResult>;
|
|
68
|
+
getPinnedNodeIds(): Promise<string[]>;
|
|
69
|
+
runBatch(operations: RunBatchInput): Promise<RunBatchResult>;
|
|
70
|
+
listSnapshots(): Promise<SnapshotList>;
|
|
71
|
+
saveSnapshot(name: string): Promise<CanvasSnapshot | null>;
|
|
72
|
+
restoreSnapshot(id: string): Promise<{
|
|
73
|
+
ok: boolean;
|
|
74
|
+
}>;
|
|
75
|
+
deleteSnapshot(id: string): Promise<DeleteSnapshotResult>;
|
|
76
|
+
diffSnapshot(idOrName: string): Promise<DiffSnapshotResult>;
|
|
77
|
+
getCodeGraph(): Promise<CodeGraphResult>;
|
|
78
|
+
validate(): Promise<ValidationResult>;
|
|
79
|
+
getAutomationWebViewStatus(): Promise<AutomationWebViewStatus>;
|
|
80
|
+
startAutomationWebView(options?: AutomationWebViewOptions): Promise<AutomationWebViewStatus>;
|
|
81
|
+
stopAutomationWebView(): Promise<boolean>;
|
|
82
|
+
evaluateAutomationWebView(expression: string): Promise<AutomationEvaluateResult>;
|
|
83
|
+
resizeAutomationWebView(width: number, height: number): Promise<AutomationWebViewStatus>;
|
|
84
|
+
screenshotAutomationWebView(options?: AutomationScreenshotOptions): Promise<Uint8Array>;
|
|
85
|
+
}
|
|
86
|
+
export declare function createCanvasAccess(): Promise<CanvasAccess>;
|
|
87
|
+
export {};
|
|
@@ -96,6 +96,7 @@ export interface CanvasServerOptions {
|
|
|
96
96
|
port?: number;
|
|
97
97
|
workspaceRoot?: string;
|
|
98
98
|
autoOpenBrowser?: boolean;
|
|
99
|
+
allowPortFallback?: boolean;
|
|
99
100
|
}
|
|
100
101
|
export declare function startCanvasServer(options?: CanvasServerOptions): string | null;
|
|
101
102
|
export declare function stopCanvasServer(): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pmx-canvas",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
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",
|