pmx-canvas 0.7.3 → 0.8.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/.github/extensions/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
- package/.github/extensions/pmx-canvas/extension.mjs +25 -172
- package/.github/extensions/pmx-canvas/mcp-bootstrap.ts +198 -0
- package/.github/extensions/pmx-canvas/runtime.d.mts +41 -0
- package/.github/extensions/pmx-canvas/runtime.json +3 -0
- package/.github/extensions/pmx-canvas/runtime.mjs +194 -0
- package/.github/extensions/pmx-canvas/start-mcp.mjs +51 -0
- package/.github/extensions/pmx-canvas/tools.json +2560 -0
- package/CHANGELOG.md +47 -0
- package/Readme.md +21 -7
- package/dist/canvas/fonts/OFL.txt +93 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-ext-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-mono-latin-ext-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-600-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-400-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-500-normal.woff2 +0 -0
- package/dist/canvas/fonts/ibm-plex-sans-latin-ext-600-normal.woff2 +0 -0
- package/dist/canvas/global.css +723 -672
- package/dist/canvas/index.js +90 -88
- package/dist/canvas/mcp-app.html +7878 -0
- package/dist/canvas/mermaid-entry.js +1 -1
- package/dist/canvas/surface-theme.css +151 -46
- package/dist/json-render/index.css +1 -1
- package/dist/types/cli/commands/record.d.ts +1 -1
- package/dist/types/client/canvas/NodeContextMark.d.ts +24 -0
- package/dist/types/client/canvas/SessionReceipt.d.ts +3 -1
- package/dist/types/client/icons.d.ts +1 -2
- package/dist/types/client/mcp-app/index.d.ts +1 -0
- package/dist/types/client/nodes/ax-node-actions.d.ts +2 -2
- package/dist/types/client/nodes/markdown-sanitize.d.ts +2 -0
- package/dist/types/client/nodes/use-workbench-asset.d.ts +2 -0
- package/dist/types/client/state/attention-store.d.ts +0 -5
- package/dist/types/client/state/context-status-store.d.ts +53 -0
- package/dist/types/client/state/intent-bridge.d.ts +3 -0
- package/dist/types/client/state/near-pin-store.d.ts +16 -0
- package/dist/types/client/state/presence-store.d.ts +5 -0
- package/dist/types/client/state/session-store.d.ts +33 -3
- package/dist/types/client/state/workbench-transport.d.ts +16 -0
- package/dist/types/client/theme/tokens.d.ts +1 -3
- package/dist/types/client/types.d.ts +9 -0
- package/dist/types/json-render/server.d.ts +1 -1
- package/dist/types/mcp/app-server.d.ts +3 -0
- package/dist/types/mcp/canvas-access.d.ts +1 -1
- package/dist/types/mcp/canvas-app.d.ts +4 -0
- package/dist/types/mcp/workbench-app.d.ts +4 -0
- package/dist/types/server/agent-presence.d.ts +1 -1
- package/dist/types/server/ax-state.d.ts +1 -1
- package/dist/types/server/canvas-db.d.ts +8 -0
- package/dist/types/server/canvas-geometry.d.ts +25 -0
- package/dist/types/server/canvas-operations.d.ts +1 -11
- package/dist/types/server/canvas-state.d.ts +25 -3
- package/dist/types/server/context-brief.d.ts +8 -1
- package/dist/types/server/context-reads.d.ts +30 -7
- package/dist/types/server/index.d.ts +6 -1
- package/dist/types/server/mcp-app-runtime.d.ts +1 -0
- package/dist/types/server/operations/http.d.ts +2 -0
- package/dist/types/server/operations/invoker.d.ts +4 -2
- package/dist/types/server/operations/ops/nodes.d.ts +0 -6
- package/dist/types/server/server.d.ts +1 -0
- package/dist/types/server/spatial-analysis.d.ts +2 -0
- package/dist/types/shared/agent-context.d.ts +22 -0
- package/dist/types/shared/agent-presence.d.ts +3 -10
- package/dist/types/shared/canvas-app.d.ts +54 -0
- package/dist/types/shared/themes.d.ts +1 -1
- package/docs/RELEASE.md +7 -3
- package/docs/agent-plugin.md +123 -0
- package/docs/ax-state-contract.md +40 -0
- package/docs/cli.md +7 -2
- package/docs/design/AgentContext.dc.html +186 -0
- package/docs/design/Before.dc.html +208 -0
- package/docs/design/BoardPins.dc.html +151 -0
- package/docs/design/Chrome.dc.html +208 -0
- package/docs/design/Context.dc.html +239 -0
- package/docs/design/Flows.dc.html +181 -0
- package/docs/design/Home.dc.html +209 -0
- package/docs/design/HomeGraph.dc.html +211 -0
- package/docs/design/HomeMap.dc.html +117 -0
- package/docs/design/HomeTeam.dc.html +176 -0
- package/docs/design/Light.dc.html +28 -0
- package/docs/design/Main.dc.html +280 -0
- package/docs/design/NearPin.dc.html +260 -0
- package/docs/design/Pane600.dc.html +120 -0
- package/docs/design/Relations.dc.html +297 -0
- package/docs/design/Themes.dc.html +121 -0
- package/docs/design/TokenSystem.dc.html +136 -0
- package/docs/design/Tokens.dc.html +163 -0
- package/docs/design/Types1.dc.html +177 -0
- package/docs/design/Types2.dc.html +226 -0
- package/docs/design/Types3.dc.html +195 -0
- package/docs/design/Uses.dc.html +152 -0
- package/docs/design/Vision.dc.html +116 -0
- package/docs/design/Zoom.dc.html +82 -0
- package/docs/design/canvas.json +274 -0
- package/docs/design.md +214 -0
- package/docs/environment.md +1 -1
- package/docs/http-api.md +80 -15
- package/docs/mcp.md +198 -3
- package/docs/node-types.md +34 -10
- package/docs/plans/plan-009-tech-debt-backlog.md +1 -1
- package/docs/plans/plan-015-design-foundation-wave-0.md +177 -0
- package/docs/plans/plan-016-context-made-visible-wave-1.md +148 -0
- package/docs/product-vision-2026-09.md +47 -7
- package/docs/screenshot.png +0 -0
- package/docs/sdk.md +1 -0
- package/package.json +10 -4
- package/plugins/pmx-canvas/LICENSE +21 -0
- package/plugins/pmx-canvas/THIRD_PARTY_LICENSES.txt +331 -0
- package/plugins/pmx-canvas/assets/preview.png +0 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/extension.mjs +930 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +3 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.mjs +194 -0
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/steering-delivery.mjs +79 -0
- package/plugins/pmx-canvas/mcp.json +12 -0
- package/plugins/pmx-canvas/plugin.json +24 -0
- package/plugins/pmx-canvas/runtime.json +3 -0
- package/plugins/pmx-canvas/runtime.mjs +194 -0
- package/plugins/pmx-canvas/start-mcp.mjs +51 -0
- package/plugins/pmx-canvas/tools.json +2560 -0
- package/skills/pmx-canvas/SKILL.md +10 -7
- package/skills/pmx-canvas/references/full-reference.md +11 -7
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +20 -8
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
- package/skills/pmx-canvas-testing/SKILL.md +5 -4
- package/src/cli/commands/copilot.ts +5 -0
- package/src/cli/commands/view.ts +1 -1
- package/src/cli/index.ts +8 -3
- package/src/client/App.tsx +6 -1
- package/src/client/canvas/AgentPresenceLayer.tsx +3 -3
- package/src/client/canvas/AnnotationLayer.tsx +1 -1
- package/src/client/canvas/CanvasNode.tsx +32 -49
- package/src/client/canvas/CanvasViewport.tsx +0 -2
- package/src/client/canvas/CommandPalette.tsx +3 -2
- package/src/client/canvas/ContextMenu.tsx +11 -0
- package/src/client/canvas/EdgeLayer.tsx +1 -1
- package/src/client/canvas/ExportDialog.tsx +33 -6
- package/src/client/canvas/IntentLayer.tsx +2 -2
- package/src/client/canvas/Minimap.tsx +12 -7
- package/src/client/canvas/NodeContextMark.tsx +156 -0
- package/src/client/canvas/SessionPanel.tsx +4 -7
- package/src/client/canvas/SessionReceipt.tsx +114 -17
- package/src/client/canvas/ShortcutOverlay.tsx +6 -1
- package/src/client/canvas/SnapshotPanel.tsx +11 -2
- package/src/client/canvas/ToolRail.tsx +12 -9
- package/src/client/canvas/TopBar.tsx +16 -11
- package/src/client/icons.tsx +2 -12
- package/src/client/mcp-app/index.tsx +137 -0
- package/src/client/mcp-app/style.css +10 -0
- package/src/client/nodes/AttachmentNode.tsx +8 -1
- package/src/client/nodes/AxStepControls.tsx +1 -1
- package/src/client/nodes/ContextNode.tsx +9 -9
- package/src/client/nodes/ExtAppFrame.tsx +13 -8
- package/src/client/nodes/FileNode.tsx +8 -5
- package/src/client/nodes/ImageNode.tsx +4 -2
- package/src/client/nodes/InlineMarkdownEditor.tsx +2 -1
- package/src/client/nodes/LedgerNode.tsx +2 -2
- package/src/client/nodes/MarkdownNode.tsx +44 -9
- package/src/client/nodes/McpAppNode.tsx +6 -4
- package/src/client/nodes/PromptNode.tsx +5 -17
- package/src/client/nodes/ResponseNode.tsx +3 -15
- package/src/client/nodes/StatusNode.tsx +2 -2
- package/src/client/nodes/StatusSummary.tsx +3 -1
- package/src/client/nodes/TraceNode.tsx +6 -4
- package/src/client/nodes/WebpageNode.tsx +1 -1
- package/src/client/nodes/ax-node-actions.ts +2 -2
- package/src/client/nodes/iframe-document-url.ts +3 -2
- package/src/client/nodes/markdown-sanitize.ts +10 -0
- package/src/client/nodes/surface-url.ts +10 -0
- package/src/client/nodes/use-surface-frame.ts +3 -1
- package/src/client/nodes/use-workbench-asset.ts +26 -0
- package/src/client/state/attention-bridge.ts +0 -8
- package/src/client/state/attention-store.ts +0 -17
- package/src/client/state/canvas-store.ts +4 -2
- package/src/client/state/context-status-store.ts +66 -0
- package/src/client/state/human-store.ts +2 -0
- package/src/client/state/iframe-mode.ts +5 -0
- package/src/client/state/intent-bridge.ts +10 -4
- package/src/client/state/near-pin-store.ts +53 -0
- package/src/client/state/presence-store.ts +5 -10
- package/src/client/state/session-store.ts +106 -9
- package/src/client/state/sse-bridge.ts +26 -7
- package/src/client/state/theme-override.ts +1 -1
- package/src/client/state/workbench-transport.ts +36 -0
- package/src/client/theme/global.css +723 -672
- package/src/client/theme/surface-theme.css +151 -46
- package/src/client/theme/tokens.ts +7 -11
- package/src/client/types.ts +10 -0
- package/src/json-render/server.ts +71 -14
- package/src/mcp/app-server.ts +64 -0
- package/src/mcp/canvas-access.ts +14 -11
- package/src/mcp/canvas-app.ts +318 -0
- package/src/mcp/server.ts +1 -1
- package/src/mcp/workbench-app.ts +211 -0
- package/src/server/agent-presence.ts +45 -6
- package/src/server/ax-context.ts +1 -1
- package/src/server/ax-state.ts +1 -1
- package/src/server/board-export.ts +5 -2
- package/src/server/canvas-db.ts +46 -12
- package/src/server/canvas-geometry.ts +64 -0
- package/src/server/canvas-operations.ts +6 -24
- package/src/server/canvas-state.ts +105 -15
- package/src/server/canvas-validation.ts +19 -4
- package/src/server/context-brief.ts +39 -2
- package/src/server/context-reads.ts +86 -15
- package/src/server/demo-state.json +31 -31
- package/src/server/html-surface.ts +4 -5
- package/src/server/index.ts +19 -3
- package/src/server/mcp-app-runtime.ts +11 -0
- package/src/server/operations/composites.ts +4 -3
- package/src/server/operations/http.ts +4 -4
- package/src/server/operations/invoker.ts +13 -4
- package/src/server/operations/ops/ax-read.ts +1 -1
- package/src/server/operations/ops/ax-timeline.ts +37 -0
- package/src/server/operations/ops/boards.ts +1 -1
- package/src/server/operations/ops/canvas-wire.ts +3 -6
- package/src/server/operations/ops/intent.ts +31 -2
- package/src/server/operations/ops/json-render.ts +1 -1
- package/src/server/operations/ops/nodes.ts +8 -76
- package/src/server/operations/ops/query.ts +8 -2
- package/src/server/operations/ops/snapshots.ts +4 -1
- package/src/server/operations/ops/viewport.ts +29 -5
- package/src/server/operations/registry.ts +38 -4
- package/src/server/scope-fence.ts +55 -10
- package/src/server/server.ts +83 -5
- package/src/server/spatial-analysis.ts +2 -2
- package/src/server/workboard.ts +6 -1
- package/src/{server → shared}/agent-context.ts +2 -2
- package/src/shared/agent-presence.ts +3 -15
- package/src/shared/canvas-app.ts +62 -0
- package/src/shared/themes.ts +5 -5
- package/src/client/canvas/FocusFieldLayer.tsx +0 -116
- package/src/client/canvas/kind-colors.ts +0 -23
|
@@ -155,12 +155,13 @@ export declare function endSession(session: {
|
|
|
155
155
|
agentId: string | null;
|
|
156
156
|
}): Promise<boolean>;
|
|
157
157
|
export interface SessionReceipt {
|
|
158
|
-
|
|
158
|
+
/** Distinct labels of the sessions on this card (one unless merged). */
|
|
159
|
+
labels: string[];
|
|
160
|
+
/** Endings folded into this card (see applySessionReceipt). */
|
|
161
|
+
sessions: number;
|
|
159
162
|
endedAt: string;
|
|
160
163
|
/** Why it ended — the receipt should answer this, not leave the human asking. */
|
|
161
164
|
endedBy?: 'human' | 'agent' | 'idle-timeout';
|
|
162
|
-
/** The session changed nothing on the board (its pre-session snapshot was dropped). */
|
|
163
|
-
unchanged?: boolean;
|
|
164
165
|
/** Cancelled (withdrawn items), rejected (human's explicit no on a gate), and
|
|
165
166
|
* held (TTL expired unanswered) are three different outcomes — never one
|
|
166
167
|
* "vetoed" pile. */
|
|
@@ -171,13 +172,42 @@ export interface SessionReceipt {
|
|
|
171
172
|
rejected: number;
|
|
172
173
|
held: number;
|
|
173
174
|
};
|
|
175
|
+
/** The pre-session snapshot; null when the board was empty at attach, or on a
|
|
176
|
+
* merged receipt (each session's snapshot is in History). */
|
|
174
177
|
snapshot: {
|
|
175
178
|
id: string;
|
|
176
179
|
name: string;
|
|
177
180
|
} | null;
|
|
181
|
+
/** What the session did with context (docs/design/AgentContext.dc.html receipt). */
|
|
182
|
+
context: SessionContextActivity;
|
|
183
|
+
}
|
|
184
|
+
export interface ReceiptNode {
|
|
185
|
+
id: string;
|
|
186
|
+
title: string;
|
|
187
|
+
reason?: string;
|
|
188
|
+
}
|
|
189
|
+
export interface SessionContextActivity {
|
|
190
|
+
read: ReceiptNode[];
|
|
191
|
+
pinned: ReceiptNode[];
|
|
192
|
+
created: ReceiptNode[];
|
|
193
|
+
edited: ReceiptNode[];
|
|
194
|
+
changedSinceRead: ReceiptNode[];
|
|
178
195
|
}
|
|
196
|
+
/**
|
|
197
|
+
* The agent-activity lens: while on, nodes the last session did not touch
|
|
198
|
+
* (read, pin, create, edit) are dimmed. Null when off.
|
|
199
|
+
*/
|
|
200
|
+
export declare const activityLensNodeIds: import("@preact/signals-core").Signal<Set<string> | null>;
|
|
201
|
+
export declare function setActivityLens(on: boolean): void;
|
|
179
202
|
/** The last ended session's receipt (design item 2); client-side, cleared on dismiss. */
|
|
180
203
|
export declare const sessionReceipt: import("@preact/signals-core").Signal<SessionReceipt | null>;
|
|
204
|
+
/**
|
|
205
|
+
* The receipt rule: a pop-up only for a top-level session that changed the
|
|
206
|
+
* board or read/pinned context. `unchanged` endings and worker endings
|
|
207
|
+
* (`parentAgentId` set — their orchestrator's receipt covers the board since
|
|
208
|
+
* it attached) stay in the timeline and History only, and never replace or
|
|
209
|
+
* extend an open receipt. Qualifying endings while one is up merge into it.
|
|
210
|
+
*/
|
|
181
211
|
export declare function applySessionReceipt(data: Record<string, unknown>): void;
|
|
182
212
|
export declare function dismissSessionReceipt(): void;
|
|
183
213
|
export declare function resetSessionStore(): void;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** The normal workbench uses HTTP; an MCP App installs its host transport before mounting. */
|
|
2
|
+
type WorkbenchFetch = (input: RequestInfo | URL, init?: RequestInit) => Promise<Response>;
|
|
3
|
+
export declare function installWorkbenchTransport(transport: WorkbenchFetch | undefined): void;
|
|
4
|
+
export declare function isHostedWorkbench(): boolean;
|
|
5
|
+
export declare const workbenchFetch: WorkbenchFetch;
|
|
6
|
+
type WorkbenchDownload = (file: {
|
|
7
|
+
name: string;
|
|
8
|
+
mimeType: string;
|
|
9
|
+
text: string;
|
|
10
|
+
}) => Promise<{
|
|
11
|
+
isError?: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function installWorkbenchDownload(download: WorkbenchDownload | undefined): void;
|
|
14
|
+
/** Export files live on PMX, not on the embedded frame's sandbox origin. */
|
|
15
|
+
export declare function downloadWorkbenchExport(path: string): Promise<void>;
|
|
16
|
+
export {};
|
|
@@ -18,8 +18,17 @@ export interface CanvasNodeState {
|
|
|
18
18
|
zIndex: number;
|
|
19
19
|
collapsed: boolean;
|
|
20
20
|
pinned: boolean;
|
|
21
|
+
contentRevision?: number;
|
|
22
|
+
/** Who created / last edited the node's content (server attribution). */
|
|
23
|
+
createdBy?: NodeActor;
|
|
24
|
+
lastEditedBy?: NodeActor;
|
|
21
25
|
data: Record<string, unknown>;
|
|
22
26
|
}
|
|
27
|
+
export interface NodeActor {
|
|
28
|
+
actor: 'human' | 'agent' | 'system' | 'unknown';
|
|
29
|
+
source: string;
|
|
30
|
+
agentId?: string;
|
|
31
|
+
}
|
|
23
32
|
export interface CanvasEdge {
|
|
24
33
|
id: string;
|
|
25
34
|
from: string;
|
|
@@ -66,7 +66,7 @@ export type GraphChartType = 'LineChart' | 'BarChart' | 'PieChart' | 'AreaChart'
|
|
|
66
66
|
export declare function escapeInlineScriptSource(source: string): string;
|
|
67
67
|
export declare function inferJsonRenderNodeTitle(spec: JsonRenderSpec, fallback?: string): string;
|
|
68
68
|
export declare function normalizeAndValidateJsonRenderSpec(spec: unknown): JsonRenderSpec;
|
|
69
|
-
/**
|
|
69
|
+
/** Binding-only form props that normalization could not bind (see bindLiteralFormValues). */
|
|
70
70
|
export declare function jsonRenderFormWarnings(spec: JsonRenderSpec): string[];
|
|
71
71
|
export declare function normalizeGraphType(value: string): GraphChartType;
|
|
72
72
|
export declare function buildGraphSpec(input: GraphNodeInput): JsonRenderSpec;
|
|
@@ -88,5 +88,5 @@ export declare function shouldAttachToExistingDaemon(occupant: {
|
|
|
88
88
|
* FS-safe (defaults to false on any error).
|
|
89
89
|
*/
|
|
90
90
|
export declare function looksLikeIncidentalCwd(cwd: string): boolean;
|
|
91
|
-
export declare function createCanvasAccess(): Promise<CanvasAccess>;
|
|
91
|
+
export declare function createCanvasAccess(allowExternalMcp?: boolean): Promise<CanvasAccess>;
|
|
92
92
|
export {};
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { CanvasAccess } from './canvas-access.js';
|
|
3
|
+
/** Focused app profile; deliberately does not register the general-purpose composites. */
|
|
4
|
+
export declare function registerCanvasApp(server: McpServer, ensureCanvas: () => Promise<CanvasAccess>): void;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
+
import type { CanvasAccess } from './canvas-access.js';
|
|
3
|
+
/** HTTP-shaped replies let the real workbench retain its existing API contracts. */
|
|
4
|
+
export declare function registerWorkbenchApp(server: McpServer, ensureCanvas: () => Promise<CanvasAccess>): void;
|
|
@@ -99,7 +99,7 @@ export declare function estimateContextBudget(): ContextBudget;
|
|
|
99
99
|
/** Returns the id of the pre-session snapshot the server took, if any. */
|
|
100
100
|
type SessionStartListener = (presence: AgentPresence) => string | null;
|
|
101
101
|
export type SessionEndReason = 'human' | 'agent' | 'idle-timeout';
|
|
102
|
-
type SessionEndListener = (presence: AgentPresence, startSnapshotId: string | null, endedBy: SessionEndReason) => void;
|
|
102
|
+
type SessionEndListener = (presence: AgentPresence, startSnapshotId: string | null, endedBy: SessionEndReason, startedAt: string | null) => void;
|
|
103
103
|
export declare class AgentPresenceRegistry {
|
|
104
104
|
private readonly presences;
|
|
105
105
|
/** Newest first; bounded. Survives a writer fading — the feed is history, the writer list is presence. */
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CanvasLayout, CanvasNodeState } from './canvas-state.js';
|
|
2
2
|
import type { AxApprovalStatus, AxEventKind, AxWorkItemStatus } from '../shared/ax-kinds.js';
|
|
3
|
-
import type { AgentContextNode } from '
|
|
3
|
+
import type { AgentContextNode } from '../shared/agent-context.js';
|
|
4
4
|
import type { ActorAttribution } from './attribution.js';
|
|
5
5
|
export type PmxAxSource = 'agent' | 'amp' | 'api' | 'browser' | 'cli' | 'codex' | 'copilot' | 'mcp' | 'sdk' | 'system';
|
|
6
6
|
export interface PmxAxFocusState {
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* WAL-mode persistence. Replaces the previous JSON file-based approach.
|
|
6
6
|
*/
|
|
7
7
|
import { Database } from 'bun:sqlite';
|
|
8
|
+
import type { ActorAttribution } from './attribution.js';
|
|
8
9
|
import { type Tour } from '../shared/tour.js';
|
|
9
10
|
import { type CanvasThemeName } from '../shared/themes.js';
|
|
10
11
|
import type { CanvasAnnotation, CanvasEdge, CanvasNodeState, CanvasSnapshot, CanvasSnapshotListOptions, ViewportState } from './canvas-state.js';
|
|
@@ -20,9 +21,16 @@ export interface PersistedCanvasState {
|
|
|
20
21
|
edges: CanvasEdge[];
|
|
21
22
|
annotations?: CanvasAnnotation[];
|
|
22
23
|
contextPins: string[];
|
|
24
|
+
/** Who pinned each context pin, when and why; pins without an entry have an unknown pinner. */
|
|
25
|
+
contextPinMeta?: Record<string, ContextPinMeta>;
|
|
23
26
|
ax?: PmxAxState;
|
|
24
27
|
revisionState?: PersistedRevisionState;
|
|
25
28
|
}
|
|
29
|
+
export interface ContextPinMeta {
|
|
30
|
+
pinnedBy: ActorAttribution;
|
|
31
|
+
pinnedAt: string;
|
|
32
|
+
reason?: string;
|
|
33
|
+
}
|
|
26
34
|
export interface PersistedRevisionState {
|
|
27
35
|
revision: number;
|
|
28
36
|
floor: number;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CanvasNodeState, CanvasNodeUpdate } from './canvas-state.js';
|
|
2
|
+
/** Flat fields take precedence over nested aliases; absent axes remain absent. */
|
|
3
|
+
export declare function resolveCreateGeometry(body: Record<string, unknown>): {
|
|
4
|
+
x: number | undefined;
|
|
5
|
+
y: number | undefined;
|
|
6
|
+
width: number | undefined;
|
|
7
|
+
height: number | undefined;
|
|
8
|
+
};
|
|
9
|
+
/** Guards and PATCH execution must resolve aliases and single-axis moves identically. */
|
|
10
|
+
export declare function resolvePatchGeometry(body: Record<string, unknown>, existing: CanvasNodeState): {
|
|
11
|
+
size?: {
|
|
12
|
+
width: number;
|
|
13
|
+
height: number;
|
|
14
|
+
} | undefined;
|
|
15
|
+
position?: {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
} | undefined;
|
|
19
|
+
};
|
|
20
|
+
export declare function validateCanvasNodePatch(patch: {
|
|
21
|
+
position?: unknown;
|
|
22
|
+
size?: unknown;
|
|
23
|
+
}): string | null;
|
|
24
|
+
/** Invalid patches cannot count as explicit child-position overrides. */
|
|
25
|
+
export declare function validCanvasNodeUpdates(input: unknown): CanvasNodeUpdate[];
|
|
@@ -130,16 +130,6 @@ export declare function syncCanvasRuntimeBackends(options?: {
|
|
|
130
130
|
rehydrated: number;
|
|
131
131
|
failed: number;
|
|
132
132
|
}>;
|
|
133
|
-
export declare function validateCanvasNodePatch(patch: {
|
|
134
|
-
position?: {
|
|
135
|
-
x: number;
|
|
136
|
-
y: number;
|
|
137
|
-
};
|
|
138
|
-
size?: {
|
|
139
|
-
width: number;
|
|
140
|
-
height: number;
|
|
141
|
-
};
|
|
142
|
-
}): string | null;
|
|
143
133
|
export declare function mergeTraceNodeDataFields(base: Record<string, unknown>, input: Record<string, unknown>): Record<string, unknown>;
|
|
144
134
|
export declare function hasTraceNodeDataFields(input: Record<string, unknown>): boolean;
|
|
145
135
|
export declare function scheduleCodeGraphRecompute(onComplete?: () => void): void;
|
|
@@ -189,7 +179,7 @@ export declare function applyCanvasNodeUpdates(updates: CanvasNodeUpdate[]): {
|
|
|
189
179
|
applied: number;
|
|
190
180
|
skipped: number;
|
|
191
181
|
};
|
|
192
|
-
export declare function setCanvasContextPins(nodeIds: string[], mode?: CanvasPinMode): {
|
|
182
|
+
export declare function setCanvasContextPins(nodeIds: string[], mode?: CanvasPinMode, reason?: string): {
|
|
193
183
|
count: number;
|
|
194
184
|
nodeIds: string[];
|
|
195
185
|
};
|
|
@@ -12,11 +12,11 @@
|
|
|
12
12
|
* the one-shot boot migration into SQLite was retired.
|
|
13
13
|
*/
|
|
14
14
|
import { type Tour } from '../shared/tour.js';
|
|
15
|
-
import { type CanvasBoard, type PersistedCanvasState, type CanvasTheme, type AxTimelineQuery } from './canvas-db.js';
|
|
15
|
+
import { type CanvasBoard, type ContextPinMeta, type PersistedCanvasState, type CanvasTheme, type AxTimelineQuery } from './canvas-db.js';
|
|
16
16
|
import { type DocumentImport, type DocumentImportStatus, type ImportSection, type Attachment } from './document-import.js';
|
|
17
17
|
import { type PmxAxActivityKind, type PmxAxElicitation, type PmxAxModeRequest, type PmxAxMode, type PmxAxCommandDescriptor, type PmxAxPolicy, type PmxAxFocusState, type PmxAxSource, type PmxAxState, type PmxAxWorkItem, type PmxAxWorkItemStatus, type PmxAxApprovalGate, type PmxAxReviewAnnotation, type PmxAxReviewKind, type PmxAxReviewSeverity, type PmxAxReviewStatus, type PmxAxReviewAnchorType, type PmxAxReviewRegion, type PmxAxEvent, type PmxAxEventKind, type PmxAxEvidence, type PmxAxEvidenceKind, type PmxAxSteeringMessage, type PmxAxHostCapability, type PmxAxTimelineSummary } from './ax-state.js';
|
|
18
18
|
import { type ActorAttribution } from './attribution.js';
|
|
19
|
-
import { type ContextRead, type ContextReadConsumerSummary, type ContextReadInput } from './context-reads.js';
|
|
19
|
+
import { type ContextRead, type ContextReadConsumerSummary, type ContextReadInput, type NodeReadStatus } from './context-reads.js';
|
|
20
20
|
export declare const PMX_CANVAS_DIR = ".pmx-canvas";
|
|
21
21
|
export interface PersistedBlobRef {
|
|
22
22
|
__pmxCanvasBlob: 'v1';
|
|
@@ -171,6 +171,8 @@ declare class CanvasStateManager {
|
|
|
171
171
|
private _tour;
|
|
172
172
|
private _theme;
|
|
173
173
|
private _contextPinnedNodeIds;
|
|
174
|
+
/** Who pinned each pin, when and why; kept only for ids in `_contextPinnedNodeIds`. */
|
|
175
|
+
private _contextPinMeta;
|
|
174
176
|
private _workspaceRoot;
|
|
175
177
|
private _contentRevision;
|
|
176
178
|
private _revisionFloor;
|
|
@@ -185,12 +187,15 @@ declare class CanvasStateManager {
|
|
|
185
187
|
*/
|
|
186
188
|
onChange(cb: (type: CanvasChangeType) => void): () => void;
|
|
187
189
|
private _workItemsChangedListener;
|
|
190
|
+
/** Single slot (architecture rule 8): server.ts tells the workbench a read landed. Never MCP. */
|
|
191
|
+
private _contextReadListener;
|
|
188
192
|
/**
|
|
189
193
|
* Register THE work-item change listener (single slot, last-write-wins).
|
|
190
194
|
* Fired after addWorkItem/updateWorkItem completes (including the node
|
|
191
195
|
* status mirror), so live views like the workboard can rebuild from the
|
|
192
196
|
* fresh work-item list.
|
|
193
197
|
*/
|
|
198
|
+
setContextReadListener(listener: ((boardId: string | null) => void) | null): void;
|
|
194
199
|
setWorkItemsChangedListener(listener: (() => void) | null): void;
|
|
195
200
|
private notifyWorkItemsChanged;
|
|
196
201
|
private notifyChange;
|
|
@@ -609,6 +614,12 @@ declare class CanvasStateManager {
|
|
|
609
614
|
getAxTimelineSummary(): PmxAxTimelineSummary;
|
|
610
615
|
/** Records one agent context read (diagnostics; never notifies, so a read cannot trigger reads). */
|
|
611
616
|
recordContextRead(input: ContextReadInput, boardId?: string | null): ContextRead | null;
|
|
617
|
+
/** The delivered ids that are nodes on the read board, each with its content revision now. */
|
|
618
|
+
private readRevisions;
|
|
619
|
+
/** Per node on a board, the latest agent read that delivered its content. */
|
|
620
|
+
getNodeReadStatus(boardId?: string | null): NodeReadStatus[];
|
|
621
|
+
/** Nodes on a board whose content an agent read at or after `since` (ISO). */
|
|
622
|
+
getReadNodeIdsSince(boardId: string | null, since: string): string[];
|
|
612
623
|
getContextReads(limit?: number): {
|
|
613
624
|
reads: ContextRead[];
|
|
614
625
|
summary: ContextReadConsumerSummary[];
|
|
@@ -619,7 +630,18 @@ declare class CanvasStateManager {
|
|
|
619
630
|
steering: PmxAxSteeringMessage[];
|
|
620
631
|
summary: PmxAxTimelineSummary;
|
|
621
632
|
};
|
|
622
|
-
|
|
633
|
+
/**
|
|
634
|
+
* Replace the pin set. Newly pinned nodes are attributed to the current
|
|
635
|
+
* actor (with `reason` when given); pins that stay keep their attribution.
|
|
636
|
+
* `restore` re-applies saved attribution, so undo does not re-attribute.
|
|
637
|
+
*/
|
|
638
|
+
setContextPins(nodeIds: string[], options?: {
|
|
639
|
+
reason?: string;
|
|
640
|
+
restore?: Map<string, ContextPinMeta>;
|
|
641
|
+
}): void;
|
|
642
|
+
/** Who pinned each current pin, when and why (pins with an unknown pinner are absent). */
|
|
643
|
+
getContextPinMeta(): Record<string, ContextPinMeta>;
|
|
644
|
+
private pinMetaRecord;
|
|
623
645
|
clearContextPins(): void;
|
|
624
646
|
/** Move child nodes into a group. Sets data.parentGroup on children and data.children on the group. */
|
|
625
647
|
groupNodes(groupId: string, childIds: string[], options?: GroupNodesOptions): boolean;
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { CanvasNodeState, NodeDeletionTombstone } from './canvas-state.js';
|
|
2
|
-
export type ContextBriefReason = 'pinned' | 'changed' | 'human' | 'ask' | 'steer' | 'linked' | 'category';
|
|
2
|
+
export type ContextBriefReason = 'pinned' | 'near' | 'changed' | 'human' | 'ask' | 'steer' | 'linked' | 'category';
|
|
3
|
+
/** A near entry carries a short summary, never full content: pin the node to send that. */
|
|
4
|
+
export declare const NEAR_SUMMARY_LENGTH = 280;
|
|
3
5
|
export interface ContextBriefSourceEntry {
|
|
4
6
|
sourceBoardId: string;
|
|
5
7
|
nodeId: string;
|
|
@@ -57,6 +59,11 @@ export interface CompiledContextEntry {
|
|
|
57
59
|
text: string;
|
|
58
60
|
/** A linked board's pin title is discovery metadata, not delivery of that pinned card. */
|
|
59
61
|
titleOnly?: true;
|
|
62
|
+
/** reason "near": the pin this node sits next to on the board (docs/design/NearPin.dc.html). */
|
|
63
|
+
near?: {
|
|
64
|
+
pinNodeId: string;
|
|
65
|
+
pinTitle: string;
|
|
66
|
+
};
|
|
60
67
|
/** The body was shortened to fit; the same revision remains eligible on the next pull. */
|
|
61
68
|
truncated?: true;
|
|
62
69
|
provenance?: {
|
|
@@ -22,14 +22,29 @@ export interface ContextRead {
|
|
|
22
22
|
agentId: string | null;
|
|
23
23
|
pinnedNodeIds: string[];
|
|
24
24
|
deliveredNodeIds: string[];
|
|
25
|
+
/** Every node on the read board whose content was delivered, with its content revision at read time. */
|
|
26
|
+
readNodes: Record<string, number>;
|
|
25
27
|
bytes: number;
|
|
26
28
|
/** The board open when the read happened (null on Home). */
|
|
27
29
|
boardId: string | null;
|
|
28
30
|
}
|
|
29
|
-
export type ContextReadInput = Omit<ContextRead, 'seq' | 'id' | 'at' | 'boardId'> & {
|
|
31
|
+
export type ContextReadInput = Omit<ContextRead, 'seq' | 'id' | 'at' | 'boardId' | 'readNodes'> & {
|
|
30
32
|
/** Explicit read target, captured before asynchronous formatting/proxy work. */
|
|
31
33
|
boardId?: string | null;
|
|
34
|
+
/** Ids of every serialized node in what the reader received; the server keeps those on the board. */
|
|
35
|
+
readNodeIds?: string[];
|
|
32
36
|
};
|
|
37
|
+
/** One node's read state on a board: the latest agent read that delivered its content. */
|
|
38
|
+
export interface NodeReadStatus {
|
|
39
|
+
nodeId: string;
|
|
40
|
+
lastReadAt: string;
|
|
41
|
+
/** Who read it: consumer, else agent id, else transport label. */
|
|
42
|
+
lastReadBy: string;
|
|
43
|
+
/** The node's content revision in that read; newer current revision means "changed since read". */
|
|
44
|
+
readRevision: number;
|
|
45
|
+
/** How many retained agent reads delivered its content. */
|
|
46
|
+
readCount: number;
|
|
47
|
+
}
|
|
33
48
|
export interface ContextReadConsumerSummary {
|
|
34
49
|
consumer: string;
|
|
35
50
|
reads: number;
|
|
@@ -39,14 +54,22 @@ export interface ContextReadConsumerSummary {
|
|
|
39
54
|
resources: Record<string, number>;
|
|
40
55
|
}
|
|
41
56
|
/**
|
|
42
|
-
*
|
|
43
|
-
* what the reader received. A bare id list, a
|
|
44
|
-
* not count — the agent got the
|
|
57
|
+
* Ids of every serialized node (an object carrying `"id": "<id>"`, or a
|
|
58
|
+
* `nodeId` with its text) in what the reader received. A bare id list, a
|
|
59
|
+
* title, or a clipped-off node does not count — the agent got the node's
|
|
60
|
+
* name, not its content. Non-node ids (edges, intents) are dropped by the
|
|
61
|
+
* caller against the board's nodes.
|
|
45
62
|
*/
|
|
63
|
+
export declare function deliveredIds(payloadText: string): Set<string>;
|
|
64
|
+
/** Pinned nodes whose content is in what the reader received (see `deliveredIds`). */
|
|
46
65
|
export declare function deliveredPinnedIds(pinnedNodeIds: string[], payloadText: string): string[];
|
|
47
|
-
export declare function contextReadFromPayload(base: Omit<ContextReadInput, 'deliveredNodeIds' | 'bytes'>, payload: unknown): ContextReadInput;
|
|
48
|
-
export declare const CONTEXT_READS_SCHEMA_SQL = "\n CREATE TABLE IF NOT EXISTS context_reads (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n at TEXT NOT NULL,\n channel TEXT NOT NULL,\n resource TEXT NOT NULL,\n source TEXT NOT NULL,\n consumer TEXT,\n agent_id TEXT,\n pinned_node_ids TEXT NOT NULL DEFAULT '[]',\n delivered_node_ids TEXT NOT NULL DEFAULT '[]',\n bytes INTEGER NOT NULL DEFAULT 0,\n board_id TEXT\n );\n";
|
|
49
|
-
export declare function appendContextReadToDB(db: Database, input: ContextReadInput, boardId: string | null): ContextRead;
|
|
66
|
+
export declare function contextReadFromPayload(base: Omit<ContextReadInput, 'deliveredNodeIds' | 'bytes' | 'readNodeIds'>, payload: unknown): ContextReadInput;
|
|
67
|
+
export declare const CONTEXT_READS_SCHEMA_SQL = "\n CREATE TABLE IF NOT EXISTS context_reads (\n seq INTEGER PRIMARY KEY AUTOINCREMENT,\n id TEXT NOT NULL UNIQUE,\n at TEXT NOT NULL,\n channel TEXT NOT NULL,\n resource TEXT NOT NULL,\n source TEXT NOT NULL,\n consumer TEXT,\n agent_id TEXT,\n pinned_node_ids TEXT NOT NULL DEFAULT '[]',\n delivered_node_ids TEXT NOT NULL DEFAULT '[]',\n bytes INTEGER NOT NULL DEFAULT 0,\n board_id TEXT,\n read_nodes TEXT NOT NULL DEFAULT '{}'\n );\n";
|
|
68
|
+
export declare function appendContextReadToDB(db: Database, input: ContextReadInput, boardId: string | null, readNodes?: Record<string, number>): ContextRead;
|
|
69
|
+
/** Per node on a board, the latest agent read that delivered its content (newest row wins). */
|
|
70
|
+
export declare function loadNodeReadStatusFromDB(db: Database, boardId: string): NodeReadStatus[];
|
|
71
|
+
/** Every node on a board whose content an agent read at or after `since` (ISO). */
|
|
72
|
+
export declare function loadReadNodeIdsSince(db: Database, boardId: string, since: string): string[];
|
|
50
73
|
/** Newest first. The summary covers every retained row, not just the returned page. */
|
|
51
74
|
export declare function loadContextReadsFromDB(db: Database, limit?: number): {
|
|
52
75
|
reads: ContextRead[];
|
|
@@ -42,6 +42,8 @@ export declare class PmxCanvas extends EventEmitter {
|
|
|
42
42
|
start(options?: {
|
|
43
43
|
open?: boolean;
|
|
44
44
|
automationWebView?: boolean | CanvasAutomationWebViewOptions;
|
|
45
|
+
/** Embedded startup must not launch external MCP backends from saved nodes. */
|
|
46
|
+
allowExternalMcp?: boolean;
|
|
45
47
|
/**
|
|
46
48
|
* Bind a nearby free port when the preferred one is taken instead of
|
|
47
49
|
* failing. Default false (an explicit SDK port is honored exactly); the
|
|
@@ -293,6 +295,8 @@ export declare class PmxCanvas extends EventEmitter {
|
|
|
293
295
|
restoreBackup(file: string): Promise<void>;
|
|
294
296
|
/** The context read log: which canvas context each agent read and which pinned nodes reached it. */
|
|
295
297
|
getContextReads(limit?: number): ReturnType<typeof canvasState.getContextReads>;
|
|
298
|
+
/** Per node on a board: when an agent last read its content, who, and the content revision it read. */
|
|
299
|
+
getNodeReadStatus(board?: string): ReturnType<typeof canvasState.getNodeReadStatus>;
|
|
296
300
|
listWorkItems(): PmxAxWorkItem[];
|
|
297
301
|
addWorkItem(input: {
|
|
298
302
|
title: string;
|
|
@@ -519,7 +523,8 @@ export declare class PmxCanvas extends EventEmitter {
|
|
|
519
523
|
applied: number;
|
|
520
524
|
skipped: number;
|
|
521
525
|
};
|
|
522
|
-
|
|
526
|
+
/** `reason` is kept with newly pinned nodes and shown to the human on hover. */
|
|
527
|
+
setContextPins(nodeIds: string[], mode?: 'set' | 'add' | 'remove', reason?: string): {
|
|
523
528
|
count: number;
|
|
524
529
|
nodeIds: string[];
|
|
525
530
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { CallToolResult, ListPromptsResult, ListResourcesResult, ListResourceTemplatesResult, ListToolsResult, ReadResourceResult, Tool } from '@modelcontextprotocol/sdk/types.js';
|
|
2
2
|
import type { McpUiResourceMeta } from '@modelcontextprotocol/ext-apps';
|
|
3
|
+
export declare function withoutExternalMcp<T>(run: () => T): T;
|
|
3
4
|
export interface ExternalMcpHttpTransportConfig {
|
|
4
5
|
type: 'http';
|
|
5
6
|
url: string;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export declare function matchOperationPath(template: string, pathname: string): Record<string, string> | null;
|
|
1
2
|
/**
|
|
2
3
|
* Shared body reader: preserves the parsed JSON value as-is (object, array,
|
|
3
4
|
* or primitive) — per-op `readInput` decides what to do with non-object
|
|
@@ -5,4 +6,5 @@
|
|
|
5
6
|
* parse is a 400 (OperationError), never a silent empty input.
|
|
6
7
|
*/
|
|
7
8
|
export declare function readJsonValue(req: Request): Promise<unknown>;
|
|
9
|
+
export declare function readOperationInput(req: Request, params: Record<string, string>, url: URL): Promise<Record<string, unknown>>;
|
|
8
10
|
export declare function dispatchOperationRoute(req: Request, url: URL): Promise<Response | null>;
|
|
@@ -9,18 +9,20 @@ export interface OperationInvoker {
|
|
|
9
9
|
export declare function agentSourceLabel(fallback: string): string;
|
|
10
10
|
/** Runs operations in-process against the shared canvasState singleton. */
|
|
11
11
|
export declare class LocalOperationInvoker implements OperationInvoker {
|
|
12
|
+
private readonly allowExternalMcp;
|
|
12
13
|
private readonly source;
|
|
13
14
|
private readonly proxiedRead;
|
|
14
15
|
/** `source` labels this caller's agent presence ('mcp', 'sdk', …). */
|
|
15
|
-
constructor(source?: string);
|
|
16
|
+
constructor(source?: string, allowExternalMcp?: boolean);
|
|
16
17
|
invoke(name: string, input: Record<string, unknown>): Promise<unknown>;
|
|
17
18
|
}
|
|
18
19
|
/** Builds the HTTP request from the op's route template (`:id` from input, GET flags to query). */
|
|
19
20
|
export declare class HttpOperationInvoker implements OperationInvoker {
|
|
21
|
+
private readonly allowExternalMcp;
|
|
20
22
|
private readonly baseUrl;
|
|
21
23
|
private readonly source;
|
|
22
24
|
private readonly proxiedRead;
|
|
23
25
|
/** `source` labels this caller's agent presence on the server ('cli', 'mcp', …). */
|
|
24
|
-
constructor(baseUrl: string, source?: string);
|
|
26
|
+
constructor(baseUrl: string, source?: string, allowExternalMcp?: boolean);
|
|
25
27
|
invoke(name: string, rawInput: Record<string, unknown>): Promise<unknown>;
|
|
26
28
|
}
|
|
@@ -11,12 +11,6 @@ export declare function isRecord(value: unknown): value is Record<string, unknow
|
|
|
11
11
|
export declare function pickFiniteNumber(record: Record<string, unknown>, key: string): number | undefined;
|
|
12
12
|
export declare function getRecord(value: unknown): Record<string, unknown> | undefined;
|
|
13
13
|
export declare function pickPositiveNumber(record: Record<string, unknown>, key: string): number | undefined;
|
|
14
|
-
export declare function resolveCreateGeometry(body: Record<string, unknown>): {
|
|
15
|
-
x?: number;
|
|
16
|
-
y?: number;
|
|
17
|
-
width?: number;
|
|
18
|
-
height?: number;
|
|
19
|
-
};
|
|
20
14
|
export declare function setGroupChildrenFromApi(groupId: string, childIds: string[]): boolean;
|
|
21
15
|
export declare function nodeAppSessionId(node: CanvasNodeState | undefined): string | null;
|
|
22
16
|
export declare function closeNodeAppSession(node: CanvasNodeState | undefined): void;
|
|
@@ -108,6 +108,7 @@ export interface CanvasServerOptions {
|
|
|
108
108
|
workspaceRoot?: string;
|
|
109
109
|
autoOpenBrowser?: boolean;
|
|
110
110
|
allowPortFallback?: boolean;
|
|
111
|
+
allowExternalMcp?: boolean;
|
|
111
112
|
}
|
|
112
113
|
export declare function startCanvasServer(options?: CanvasServerOptions): string | null;
|
|
113
114
|
export declare function stopCanvasServer(): void;
|
|
@@ -68,6 +68,8 @@ export interface SpatialContext {
|
|
|
68
68
|
}[];
|
|
69
69
|
annotations: SpatialAnnotationContext[];
|
|
70
70
|
}
|
|
71
|
+
/** Euclidean distance between two node centers */
|
|
72
|
+
export declare function centerDistance(a: CanvasNodeState, b: CanvasNodeState): number;
|
|
71
73
|
/**
|
|
72
74
|
* Detect proximity clusters using single-linkage clustering.
|
|
73
75
|
* Two nodes are "close" if their edge-to-edge gap is within the threshold.
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CanvasNodeState } from '../server/canvas-state.js';
|
|
2
|
+
export interface AgentContextNode {
|
|
3
|
+
id: string;
|
|
4
|
+
type: CanvasNodeState['type'];
|
|
5
|
+
kind: string;
|
|
6
|
+
title: string | null;
|
|
7
|
+
content: string | null;
|
|
8
|
+
metadata?: Record<string, unknown>;
|
|
9
|
+
position?: {
|
|
10
|
+
x: number;
|
|
11
|
+
y: number;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
interface AgentContextOptions {
|
|
15
|
+
defaultTextLength?: number;
|
|
16
|
+
webpageTextLength?: number;
|
|
17
|
+
includePosition?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function summarizeNodeForAgentContext(node: CanvasNodeState, options?: AgentContextOptions): string;
|
|
20
|
+
export declare function serializeNodeForAgentContext(node: CanvasNodeState, options?: AgentContextOptions): AgentContextNode;
|
|
21
|
+
export declare function buildAgentContextPreamble(nodes: CanvasNodeState[], options?: AgentContextOptions): string;
|
|
22
|
+
export {};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Agent presence — the contract behind every agent surface in the rail chrome
|
|
3
|
-
*
|
|
4
|
-
*
|
|
2
|
+
* Agent presence — the contract behind every agent surface in the rail chrome.
|
|
3
|
+
* Shared by server and client so the two cannot drift. See
|
|
4
|
+
* docs/ax-state-contract.md, "Agent presence (contract)".
|
|
5
5
|
*
|
|
6
6
|
* Presence is DERIVED from feeds that already exist (AX activity ingest,
|
|
7
7
|
* agent-originated mutations) plus an explicit set for adapters with richer
|
|
@@ -121,10 +121,3 @@ export declare function externalWriters(presences: readonly AgentPresence[]): Ag
|
|
|
121
121
|
export declare function estimateTokens(text: string): number;
|
|
122
122
|
/** Chip label per phase — shared by the top-bar chip and the on-canvas cursor chip. */
|
|
123
123
|
export declare function agentPhaseLabel(presence: Pick<AgentPresence, 'phase' | 'detail'>): string;
|
|
124
|
-
/**
|
|
125
|
-
* Stable per-agent identity hue (0-359) from the writer key. Phase colors
|
|
126
|
-
* kept telling the human WHAT an agent is doing while erasing WHO — two
|
|
127
|
-
* thinking agents rendered identically. Identity rides the glyph/border;
|
|
128
|
-
* phase stays on dots and labels.
|
|
129
|
-
*/
|
|
130
|
-
export declare function agentIdentityHue(key: string): number;
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const CANVAS_APP_URI = "ui://pmx/canvas";
|
|
3
|
+
export declare const CANVAS_APP_WRITE_CONTRACT = "pmx-embedded-workbench-v4";
|
|
4
|
+
export declare const canvasAppSnapshotSchema: z.ZodObject<{
|
|
5
|
+
boardId: z.ZodNullable<z.ZodString>;
|
|
6
|
+
boardName: z.ZodString;
|
|
7
|
+
boards: z.ZodArray<z.ZodObject<{
|
|
8
|
+
id: z.ZodString;
|
|
9
|
+
name: z.ZodString;
|
|
10
|
+
}, z.core.$strip>>;
|
|
11
|
+
revision: z.ZodString;
|
|
12
|
+
nodes: z.ZodArray<z.ZodObject<{
|
|
13
|
+
id: z.ZodString;
|
|
14
|
+
type: z.ZodString;
|
|
15
|
+
title: z.ZodString;
|
|
16
|
+
text: z.ZodString;
|
|
17
|
+
contentRevision: z.ZodNumber;
|
|
18
|
+
editableContent: z.ZodOptional<z.ZodString>;
|
|
19
|
+
position: z.ZodObject<{
|
|
20
|
+
x: z.ZodNumber;
|
|
21
|
+
y: z.ZodNumber;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
size: z.ZodObject<{
|
|
24
|
+
width: z.ZodNumber;
|
|
25
|
+
height: z.ZodNumber;
|
|
26
|
+
}, z.core.$strip>;
|
|
27
|
+
image: z.ZodOptional<z.ZodString>;
|
|
28
|
+
}, z.core.$strip>>;
|
|
29
|
+
edges: z.ZodArray<z.ZodObject<{
|
|
30
|
+
id: z.ZodString;
|
|
31
|
+
from: z.ZodString;
|
|
32
|
+
to: z.ZodString;
|
|
33
|
+
label: z.ZodString;
|
|
34
|
+
}, z.core.$strip>>;
|
|
35
|
+
pinnedNodeIds: z.ZodArray<z.ZodString>;
|
|
36
|
+
}, z.core.$strip>;
|
|
37
|
+
export type CanvasAppSnapshot = z.infer<typeof canvasAppSnapshotSchema>;
|
|
38
|
+
/** Share only curated text, never image bytes or the whole board's contents. */
|
|
39
|
+
export declare function canvasAppContext(snapshot: Pick<CanvasAppSnapshot, 'boardId' | 'boardName' | 'pinnedNodeIds'> & {
|
|
40
|
+
nodes: Pick<CanvasAppSnapshot['nodes'][number], 'id' | 'type' | 'title' | 'text' | 'contentRevision'>[];
|
|
41
|
+
}, selectedIds: string[], focusedIds?: string[]): {
|
|
42
|
+
boardId: string | null;
|
|
43
|
+
boardName: string;
|
|
44
|
+
selectedNodeIds: string[];
|
|
45
|
+
focusedNodeIds: string[];
|
|
46
|
+
pinnedNodeIds: string[];
|
|
47
|
+
nodes: {
|
|
48
|
+
id: string;
|
|
49
|
+
type: string;
|
|
50
|
+
title: string;
|
|
51
|
+
contentRevision: number;
|
|
52
|
+
text: string;
|
|
53
|
+
}[];
|
|
54
|
+
};
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
* theme picker, server validation, and surface documents pick it up from this
|
|
10
10
|
* list.
|
|
11
11
|
*/
|
|
12
|
-
export declare const CANVAS_THEMES: readonly ["
|
|
12
|
+
export declare const CANVAS_THEMES: readonly ["harbor", "daylight", "high-contrast", "midnight", "sepia", "arctic", "ember", "forest", "volt"];
|
|
13
13
|
export type CanvasThemeName = (typeof CANVAS_THEMES)[number];
|
|
14
14
|
export declare function isCanvasTheme(value: unknown): value is CanvasThemeName;
|
|
15
15
|
export declare function normalizeCanvasThemeName(value: unknown, fallback?: CanvasThemeName): CanvasThemeName;
|