pmx-canvas 0.6.4 → 0.7.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/extension.mjs +67 -3
- package/CHANGELOG.md +73 -0
- package/Readme.md +35 -5
- package/dist/canvas/global.css +498 -28
- package/dist/canvas/index.js +110 -95
- package/dist/canvas/mermaid-entry.js +258 -258
- package/dist/types/cli/agent.d.ts +4 -0
- package/dist/types/cli/commands/backup.d.ts +1 -0
- package/dist/types/cli/commands/boards.d.ts +1 -0
- package/dist/types/cli/commands/export.d.ts +1 -0
- package/dist/types/cli/commands/record.d.ts +12 -0
- package/dist/types/client/canvas/BoardCopyDialog.d.ts +5 -0
- package/dist/types/client/canvas/BoardFolderDialog.d.ts +7 -0
- package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -0
- package/dist/types/client/canvas/BoardSwitcher.d.ts +8 -0
- package/dist/types/client/canvas/ExportDialog.d.ts +7 -0
- package/dist/types/client/canvas/HomeView.d.ts +9 -0
- package/dist/types/client/canvas/Presentation.d.ts +13 -0
- package/dist/types/client/canvas/use-node-drag.d.ts +2 -1
- package/dist/types/client/nodes/AttachmentNode.d.ts +6 -0
- package/dist/types/client/nodes/BoardNode.d.ts +5 -0
- package/dist/types/client/nodes/McpAppNode.d.ts +24 -1
- package/dist/types/client/state/boards-store.d.ts +79 -0
- package/dist/types/client/state/canvas-store.d.ts +2 -0
- package/dist/types/client/state/intent-bridge.d.ts +1 -0
- package/dist/types/client/state/presentation.d.ts +3 -0
- package/dist/types/client/state/session-store.d.ts +7 -0
- package/dist/types/client/types.d.ts +2 -2
- package/dist/types/json-render/catalog.d.ts +3 -3
- package/dist/types/json-render/charts/definitions.d.ts +1 -1
- package/dist/types/json-render/server.d.ts +8 -0
- package/dist/types/mcp/canvas-access.d.ts +10 -3
- package/dist/types/mcp/context-uri-template.d.ts +6 -0
- package/dist/types/server/agent-presence.d.ts +1 -1
- package/dist/types/server/attribution.d.ts +11 -0
- package/dist/types/server/ax-context.d.ts +3 -1
- package/dist/types/server/ax-interaction.d.ts +2 -2
- package/dist/types/server/ax-state.d.ts +13 -3
- package/dist/types/server/backup.d.ts +36 -0
- package/dist/types/server/board-export.d.ts +45 -0
- package/dist/types/server/canvas-db.d.ts +65 -9
- package/dist/types/server/canvas-operations.d.ts +45 -0
- package/dist/types/server/canvas-provenance.d.ts +1 -1
- package/dist/types/server/canvas-schema.d.ts +1 -0
- package/dist/types/server/canvas-state.d.ts +146 -3
- package/dist/types/server/canvas-validation.d.ts +3 -0
- package/dist/types/server/context-brief.d.ts +111 -0
- package/dist/types/server/context-reads.d.ts +55 -0
- package/dist/types/server/document-import.d.ts +66 -0
- package/dist/types/server/html-surface.d.ts +1 -1
- package/dist/types/server/index.d.ts +107 -4
- package/dist/types/server/mutation-history.d.ts +1 -0
- package/dist/types/server/operations/invoker.d.ts +2 -0
- package/dist/types/server/operations/mcp.d.ts +7 -1
- package/dist/types/server/operations/ops/app.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-shared.d.ts +2 -2
- package/dist/types/server/operations/ops/backup.d.ts +2 -0
- package/dist/types/server/operations/ops/boards.d.ts +10 -0
- package/dist/types/server/operations/ops/export.d.ts +2 -0
- package/dist/types/server/operations/ops/imports.d.ts +2 -0
- package/dist/types/server/operations/ops/json-render.d.ts +2 -0
- package/dist/types/server/operations/ops/nodes.d.ts +4 -2
- package/dist/types/server/operations/ops/query.d.ts +2 -0
- package/dist/types/server/operations/registry.d.ts +9 -1
- package/dist/types/server/operations/types.d.ts +1 -1
- package/dist/types/server/server.d.ts +1 -0
- package/dist/types/server/trace-manager.d.ts +7 -0
- package/dist/types/server/web-artifacts.d.ts +3 -0
- package/dist/types/server/webpage-node.d.ts +22 -1
- package/dist/types/server/workbench-auth.d.ts +3 -0
- package/dist/types/shared/boards.d.ts +6 -0
- package/dist/types/shared/tour.d.ts +72 -0
- package/docs/RELEASE.md +5 -0
- package/docs/cli.md +157 -0
- package/docs/http-api.md +277 -6
- package/docs/mcp.md +96 -7
- package/docs/node-types.md +106 -0
- package/docs/plans/plan-010-attributed-ask-answers.md +39 -0
- package/docs/plans/plan-011-context-read-instrumentation.md +54 -0
- package/docs/plans/plan-012-many-boards-stage-1.md +98 -0
- package/docs/plans/plan-013-static-board-export.md +47 -0
- package/docs/plans/plan-014-connected-board-memory.md +140 -0
- package/docs/product-vision-2026-09.md +118 -18
- package/docs/sdk.md +50 -0
- package/package.json +1 -1
- package/skills/pmx-canvas/SKILL.md +62 -5
- package/skills/pmx-canvas/references/full-reference.md +44 -8
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +3 -0
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +4 -4
- package/skills/pmx-canvas-orchestration/SKILL.md +5 -0
- package/skills/pmx-canvas-testing/SKILL.md +4 -0
- package/src/cli/agent.ts +9 -0
- package/src/cli/commands/ax.ts +13 -0
- package/src/cli/commands/backup.ts +66 -0
- package/src/cli/commands/boards.ts +71 -0
- package/src/cli/commands/export.ts +30 -0
- package/src/cli/commands/nodes.ts +14 -1
- package/src/cli/commands/pins.ts +6 -2
- package/src/cli/commands/pump.ts +3 -0
- package/src/cli/commands/query.ts +33 -7
- package/src/cli/commands/record.ts +218 -0
- package/src/cli/commands/view.ts +7 -5
- package/src/cli/index.ts +21 -9
- package/src/client/App.tsx +28 -4
- package/src/client/canvas/AgentPresenceLayer.tsx +1 -1
- package/src/client/canvas/BoardCopyDialog.tsx +153 -0
- package/src/client/canvas/BoardFolderDialog.tsx +120 -0
- package/src/client/canvas/BoardLinkDialog.tsx +93 -0
- package/src/client/canvas/BoardSwitcher.tsx +149 -0
- package/src/client/canvas/CanvasNode.tsx +8 -0
- package/src/client/canvas/CanvasViewport.tsx +3 -0
- package/src/client/canvas/CommandPalette.tsx +107 -4
- package/src/client/canvas/ContextMenu.tsx +4 -0
- package/src/client/canvas/ExpandedNodeOverlay.tsx +3 -0
- package/src/client/canvas/ExportDialog.tsx +197 -0
- package/src/client/canvas/HomeView.tsx +277 -0
- package/src/client/canvas/IntentLayer.tsx +9 -2
- package/src/client/canvas/Presentation.tsx +108 -0
- package/src/client/canvas/SessionPanel.tsx +28 -1
- package/src/client/canvas/ToolRail.tsx +38 -3
- package/src/client/canvas/TopBar.tsx +49 -7
- package/src/client/canvas/import-files.ts +19 -1
- package/src/client/canvas/kind-colors.ts +1 -0
- package/src/client/canvas/use-node-drag.ts +8 -3
- package/src/client/icons.tsx +2 -0
- package/src/client/mermaid-entry.ts +39 -0
- package/src/client/nodes/AttachmentNode.tsx +148 -0
- package/src/client/nodes/BoardNode.tsx +35 -0
- package/src/client/nodes/FileNode.tsx +6 -0
- package/src/client/nodes/HtmlNode.tsx +12 -13
- package/src/client/nodes/MarkdownNode.tsx +47 -19
- package/src/client/nodes/McpAppNode.tsx +105 -13
- package/src/client/nodes/MermaidNode.tsx +3 -2
- package/src/client/nodes/ax-node-actions.ts +2 -5
- package/src/client/nodes/use-ax-surface-bridge.ts +1 -1
- package/src/client/state/boards-store.ts +167 -0
- package/src/client/state/canvas-store.ts +22 -0
- package/src/client/state/intent-bridge.ts +30 -2
- package/src/client/state/intent-store.ts +5 -1
- package/src/client/state/node-factory.ts +1 -0
- package/src/client/state/presentation.ts +7 -0
- package/src/client/state/session-store.ts +8 -0
- package/src/client/state/sse-bridge.ts +52 -5
- package/src/client/theme/global.css +498 -28
- package/src/client/types.ts +2 -0
- package/src/json-render/server.ts +45 -9
- package/src/mcp/canvas-access.ts +59 -22
- package/src/mcp/context-uri-template.ts +28 -0
- package/src/mcp/server.ts +122 -15
- package/src/server/agent-context.ts +116 -29
- package/src/server/agent-presence.ts +15 -9
- package/src/server/attribution.ts +29 -0
- package/src/server/ax-context.ts +4 -2
- package/src/server/ax-interaction.ts +1 -0
- package/src/server/ax-state-manager.ts +72 -3
- package/src/server/ax-state.ts +41 -0
- package/src/server/backup.ts +178 -0
- package/src/server/board-export.ts +686 -0
- package/src/server/canvas-db.ts +612 -105
- package/src/server/canvas-operations.ts +183 -31
- package/src/server/canvas-provenance.ts +1 -0
- package/src/server/canvas-schema.ts +22 -0
- package/src/server/canvas-state.ts +812 -48
- package/src/server/canvas-validation.ts +9 -1
- package/src/server/context-brief.ts +372 -0
- package/src/server/context-reads.ts +238 -0
- package/src/server/demo-state.json +670 -9
- package/src/server/document-import.ts +223 -0
- package/src/server/html-primitives.ts +199 -91
- package/src/server/html-surface.ts +8 -3
- package/src/server/index.ts +243 -5
- package/src/server/mutation-history.ts +10 -13
- package/src/server/operations/composites.ts +29 -5
- package/src/server/operations/http.ts +9 -3
- package/src/server/operations/index.ts +8 -0
- package/src/server/operations/invoker.ts +14 -3
- package/src/server/operations/mcp.ts +50 -11
- package/src/server/operations/ops/app.ts +15 -0
- package/src/server/operations/ops/ax-read.ts +10 -6
- package/src/server/operations/ops/ax-timeline.ts +75 -0
- package/src/server/operations/ops/backup.ts +134 -0
- package/src/server/operations/ops/batch.ts +20 -4
- package/src/server/operations/ops/boards.ts +351 -0
- package/src/server/operations/ops/export.ts +74 -0
- package/src/server/operations/ops/ext-app.ts +4 -0
- package/src/server/operations/ops/groups.ts +14 -7
- package/src/server/operations/ops/imports.ts +220 -0
- package/src/server/operations/ops/json-render.ts +37 -5
- package/src/server/operations/ops/nodes.ts +99 -21
- package/src/server/operations/ops/query.ts +206 -9
- package/src/server/operations/ops/viewport.ts +32 -0
- package/src/server/operations/registry.ts +129 -31
- package/src/server/operations/types.ts +1 -1
- package/src/server/scope-fence.ts +1 -1
- package/src/server/server.ts +155 -8
- package/src/server/spatial-analysis.ts +9 -17
- package/src/server/trace-manager.ts +19 -0
- package/src/server/web-artifacts.ts +11 -3
- package/src/server/webpage-node.ts +173 -13
- package/src/server/workbench-auth.ts +11 -0
- package/src/server/workboard.ts +3 -3
- package/src/shared/boards.ts +18 -0
- package/src/shared/node-sizes.ts +1 -0
- package/src/shared/tour.ts +87 -0
|
@@ -5,12 +5,14 @@
|
|
|
5
5
|
* WAL-mode persistence. Replaces the previous JSON file-based approach.
|
|
6
6
|
*/
|
|
7
7
|
import { Database } from 'bun:sqlite';
|
|
8
|
+
import { type Tour } from '../shared/tour.js';
|
|
8
9
|
import { type CanvasThemeName } from '../shared/themes.js';
|
|
9
10
|
import type { CanvasAnnotation, CanvasEdge, CanvasNodeState, CanvasSnapshot, CanvasSnapshotListOptions, ViewportState } from './canvas-state.js';
|
|
10
11
|
import { type PmxAxState, type PmxAxEvent, type PmxAxEvidence, type PmxAxSteeringMessage, type PmxAxHostCapability, type PmxAxTimelineSummary } from './ax-state.js';
|
|
11
12
|
export type CanvasTheme = CanvasThemeName;
|
|
12
13
|
export declare function normalizeCanvasTheme(value: unknown, fallback?: CanvasTheme): CanvasTheme;
|
|
13
14
|
export interface PersistedCanvasState {
|
|
15
|
+
tour?: Tour;
|
|
14
16
|
version: number;
|
|
15
17
|
theme?: CanvasTheme;
|
|
16
18
|
viewport: ViewportState;
|
|
@@ -19,8 +21,27 @@ export interface PersistedCanvasState {
|
|
|
19
21
|
annotations?: CanvasAnnotation[];
|
|
20
22
|
contextPins: string[];
|
|
21
23
|
ax?: PmxAxState;
|
|
24
|
+
revisionState?: PersistedRevisionState;
|
|
22
25
|
}
|
|
23
|
-
export
|
|
26
|
+
export interface PersistedRevisionState {
|
|
27
|
+
revision: number;
|
|
28
|
+
floor: number;
|
|
29
|
+
tombstones: Array<{
|
|
30
|
+
nodeId: string;
|
|
31
|
+
revision: number;
|
|
32
|
+
deletedBy: import('./attribution.js').ActorAttribution;
|
|
33
|
+
}>;
|
|
34
|
+
}
|
|
35
|
+
/** Durable, delivery-based context cursor. This is separate from the bounded diagnostic read log. */
|
|
36
|
+
export declare function readContextBriefCursor(db: Database, boardId: string, consumer: string): number | null;
|
|
37
|
+
/** Monotonic update prevents a stale concurrent response from regressing a consumer. */
|
|
38
|
+
export declare function advanceContextBriefCursor(db: Database, boardId: string, consumer: string, revision: number): void;
|
|
39
|
+
export interface OpenCanvasDbOptions {
|
|
40
|
+
/** Name for the board a pre-boards (0.6.x) database migrates into. */
|
|
41
|
+
migratedBoardName?: string;
|
|
42
|
+
}
|
|
43
|
+
export declare function openCanvasDb(dbPath: string, options?: OpenCanvasDbOptions): Database;
|
|
44
|
+
export declare function createBoardId(): string;
|
|
24
45
|
export declare function checkpointCanvasDb(db: Database): void;
|
|
25
46
|
/**
|
|
26
47
|
* Delete blob rows nothing references any more. Blobs are content-addressed and
|
|
@@ -37,17 +58,52 @@ export declare function checkpointCanvasDb(db: Database): void;
|
|
|
37
58
|
*/
|
|
38
59
|
export declare function gcBlobsInDB(db: Database): number;
|
|
39
60
|
export declare function finalizeCanvasDbForClose(db: Database): void;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
export declare function
|
|
43
|
-
|
|
44
|
-
export declare function
|
|
45
|
-
|
|
61
|
+
/** The theme is workspace-wide: it is saved even while no board is open. */
|
|
62
|
+
export declare function saveThemeToDB(db: Database, theme: CanvasTheme | undefined): void;
|
|
63
|
+
export declare function readThemeFromDB(db: Database): CanvasTheme | undefined;
|
|
64
|
+
/** Saves one board's state; every other board's rows are untouched. */
|
|
65
|
+
export declare function saveStateToDB(db: Database, boardId: string, state: PersistedCanvasState): void;
|
|
66
|
+
/** Loads one board (the open board when `boardId` is omitted); null when there is no such board. */
|
|
67
|
+
export declare function loadStateFromDB(db: Database, boardId?: string): PersistedCanvasState | null;
|
|
68
|
+
export interface CanvasBoard {
|
|
69
|
+
id: string;
|
|
70
|
+
name: string;
|
|
71
|
+
/** A human-chosen shelf on Home ("Planning", "Research"); null is uncategorized. */
|
|
72
|
+
category: string | null;
|
|
73
|
+
createdAt: string;
|
|
74
|
+
lastOpenedAt: string | null;
|
|
75
|
+
nodeCount: number;
|
|
76
|
+
/** Markdown node used as this board's introduction. */
|
|
77
|
+
readmeNodeId: string | null;
|
|
78
|
+
}
|
|
79
|
+
/** Most recently opened first, then never-opened boards, newest first. */
|
|
80
|
+
export declare function listBoardsFromDB(db: Database): CanvasBoard[];
|
|
81
|
+
export declare function getBoardFromDB(db: Database, id: string): CanvasBoard | null;
|
|
82
|
+
export declare function createBoardInDB(db: Database, name: string, category?: string | null): CanvasBoard;
|
|
83
|
+
/** Rename and/or re-shelve a board; `category: null` removes it from its category. */
|
|
84
|
+
export declare function updateBoardInDB(db: Database, id: string, patch: {
|
|
85
|
+
name?: string;
|
|
86
|
+
category?: string | null;
|
|
87
|
+
readmeNodeId?: string | null;
|
|
88
|
+
}): boolean;
|
|
89
|
+
/** Create and populate an inactive board as one SQLite transaction. */
|
|
90
|
+
export declare function createBoardWithStateInDB(db: Database, name: string, category: string | null, state: PersistedCanvasState, readmeNodeId: string | null): CanvasBoard;
|
|
91
|
+
/** Deletes a board with its rows and its snapshots. */
|
|
92
|
+
export declare function deleteBoardFromDB(db: Database, id: string): boolean;
|
|
93
|
+
export declare function readMetaFromDB(db: Database, key: string): string | null;
|
|
94
|
+
/** Write a workspace-wide meta value; null removes it. */
|
|
95
|
+
export declare function writeMetaToDB(db: Database, key: string, value: string | null): void;
|
|
96
|
+
/** The board that was open last, if it still exists. */
|
|
97
|
+
export declare function getActiveBoardIdFromDB(db: Database): string | null;
|
|
98
|
+
export declare function setActiveBoardIdInDB(db: Database, id: string | null): void;
|
|
99
|
+
export declare function saveSnapshotToDB(db: Database, boardId: string, snapshot: CanvasSnapshot, state: PersistedCanvasState): void;
|
|
100
|
+
/** By id or name (most recent match) on `boardId`. */
|
|
101
|
+
export declare function loadSnapshotFromDB(db: Database, idOrName: string, boardId: string | null): {
|
|
46
102
|
snapshot: CanvasSnapshot;
|
|
47
103
|
state: PersistedCanvasState;
|
|
48
104
|
} | null;
|
|
49
|
-
export declare function listSnapshotsFromDB(db: Database, options?: CanvasSnapshotListOptions): CanvasSnapshot[];
|
|
50
|
-
export declare function renameSnapshotInDB(db: Database, id: string, name: string): boolean;
|
|
105
|
+
export declare function listSnapshotsFromDB(db: Database, boardId: string, options?: CanvasSnapshotListOptions): CanvasSnapshot[];
|
|
106
|
+
export declare function renameSnapshotInDB(db: Database, boardId: string, id: string, name: string): boolean;
|
|
51
107
|
export declare function deleteSnapshotFromDB(db: Database, id: string): boolean;
|
|
52
108
|
export declare function writeBlobToDB(db: Database, sha256: string, jsonValue: string): number;
|
|
53
109
|
export declare function readBlobFromDB(db: Database, sha256: string): string | null;
|
|
@@ -73,6 +73,21 @@ export declare const LEDGER_NODE_DEFAULT_SIZE: {
|
|
|
73
73
|
width: number;
|
|
74
74
|
height: number;
|
|
75
75
|
};
|
|
76
|
+
export interface CanvasSizeAdjustment {
|
|
77
|
+
requested: {
|
|
78
|
+
width: number | null;
|
|
79
|
+
height: number | null;
|
|
80
|
+
};
|
|
81
|
+
applied: {
|
|
82
|
+
width: number;
|
|
83
|
+
height: number;
|
|
84
|
+
};
|
|
85
|
+
reason: 'defaulted' | 'clamped-to-minimum' | 'defaulted-and-clamped-to-minimum' | 'fit-to-children';
|
|
86
|
+
}
|
|
87
|
+
export declare function describeCreateSize(requestedWidth: number | undefined, requestedHeight: number | undefined, resolvedWidth: number, resolvedHeight: number, applied: {
|
|
88
|
+
width: number;
|
|
89
|
+
height: number;
|
|
90
|
+
}): CanvasSizeAdjustment | undefined;
|
|
76
91
|
interface CanvasCreateGroupInput {
|
|
77
92
|
title?: string;
|
|
78
93
|
childIds?: string[];
|
|
@@ -146,6 +161,7 @@ export declare function addCanvasNode(input: CanvasAddNodeInput): {
|
|
|
146
161
|
id: string;
|
|
147
162
|
node: CanvasNodeState;
|
|
148
163
|
needsCodeGraphRecompute: boolean;
|
|
164
|
+
sizeAdjustment?: CanvasSizeAdjustment;
|
|
149
165
|
};
|
|
150
166
|
export declare function resolveCanvasNode(nodeRef: CanvasNodeLookupInput): {
|
|
151
167
|
ok: true;
|
|
@@ -192,6 +208,29 @@ export declare function saveCanvasSnapshot(name: string): CanvasSnapshot | null;
|
|
|
192
208
|
export declare function restoreCanvasSnapshot(idOrName: string): Promise<{
|
|
193
209
|
ok: boolean;
|
|
194
210
|
}>;
|
|
211
|
+
/**
|
|
212
|
+
* Open a board (or Home for null): the state layer saves the current board and
|
|
213
|
+
* loads the next, and everything else that holds the old board in memory is
|
|
214
|
+
* reset — undo closures, pending intents, file watchers, app sessions and the
|
|
215
|
+
* code graph (the trace chain restarts itself when its last node is gone).
|
|
216
|
+
* Agent and human presence are kept: they belong to the people and agents,
|
|
217
|
+
* not to a board.
|
|
218
|
+
*/
|
|
219
|
+
export declare function openCanvasBoard(id: string | null): {
|
|
220
|
+
ok: boolean;
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Restore the whole library from a backup file (the current file is kept as
|
|
224
|
+
* `<db>.before-restore`); the restored library opens on its last open board.
|
|
225
|
+
*/
|
|
226
|
+
export declare function restoreCanvasLibrary(file: string): void;
|
|
227
|
+
/**
|
|
228
|
+
* A write that arrives while no board is open (Home) lands on the most recently
|
|
229
|
+
* opened board, or on a new board when the workspace has none — nothing on
|
|
230
|
+
* Home is displaced, because Home holds nothing. Intents and undo history are
|
|
231
|
+
* kept: whatever was signalled on Home was aimed at the board this opens.
|
|
232
|
+
*/
|
|
233
|
+
export declare function openBoardForWrite(): void;
|
|
195
234
|
export declare function deleteCanvasSnapshot(id: string): {
|
|
196
235
|
ok: boolean;
|
|
197
236
|
};
|
|
@@ -213,11 +252,13 @@ export declare function removeCanvasEdge(id: string): {
|
|
|
213
252
|
export declare function createCanvasGroup(input: CanvasCreateGroupInput): {
|
|
214
253
|
id: string;
|
|
215
254
|
node: CanvasNodeState;
|
|
255
|
+
sizeAdjustment?: CanvasSizeAdjustment;
|
|
216
256
|
};
|
|
217
257
|
export declare function groupCanvasNodes(groupId: string, childIds: string[], options?: {
|
|
218
258
|
childLayout?: CanvasArrangeMode;
|
|
219
259
|
}): {
|
|
220
260
|
ok: boolean;
|
|
261
|
+
sizeAdjustment?: CanvasSizeAdjustment;
|
|
221
262
|
};
|
|
222
263
|
export declare function ungroupCanvasNodes(groupId: string): {
|
|
223
264
|
ok: boolean;
|
|
@@ -230,6 +271,8 @@ export declare function createCanvasJsonRenderNode(input: JsonRenderNodeInput):
|
|
|
230
271
|
url: string;
|
|
231
272
|
spec: JsonRenderSpec;
|
|
232
273
|
node: CanvasNodeState;
|
|
274
|
+
warnings: string[];
|
|
275
|
+
sizeAdjustment?: CanvasSizeAdjustment;
|
|
233
276
|
};
|
|
234
277
|
/**
|
|
235
278
|
* Create an empty streaming json-render node. Unlike createCanvasJsonRenderNode
|
|
@@ -248,6 +291,7 @@ export declare function createCanvasStreamingJsonRenderNode(input: {
|
|
|
248
291
|
url: string;
|
|
249
292
|
spec: JsonRenderSpec;
|
|
250
293
|
node: CanvasNodeState;
|
|
294
|
+
sizeAdjustment?: CanvasSizeAdjustment;
|
|
251
295
|
};
|
|
252
296
|
/**
|
|
253
297
|
* Apply a batch of SpecStream patches to an existing json-render node, bumping
|
|
@@ -269,6 +313,7 @@ export declare function createCanvasGraphNode(input: GraphNodeInput): {
|
|
|
269
313
|
url: string;
|
|
270
314
|
spec: JsonRenderSpec;
|
|
271
315
|
node: CanvasNodeState;
|
|
316
|
+
sizeAdjustment?: CanvasSizeAdjustment;
|
|
272
317
|
};
|
|
273
318
|
export declare function setClientViewportSize(width: unknown, height: unknown): void;
|
|
274
319
|
export declare function getClientViewportSize(): {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export type CanvasNodeType = 'markdown' | 'mcp-app' | 'webpage' | 'json-render' | 'graph' | 'prompt' | 'response' | 'status' | 'context' | 'ledger' | 'trace' | 'file' | 'diff' | 'mermaid' | 'image' | 'html' | 'group';
|
|
1
|
+
export type CanvasNodeType = 'markdown' | 'mcp-app' | 'webpage' | 'json-render' | 'graph' | 'board' | 'prompt' | 'response' | 'status' | 'context' | 'ledger' | 'trace' | 'file' | 'diff' | 'mermaid' | 'image' | 'html' | 'group';
|
|
2
2
|
export type CanvasNodeProvenanceSourceKind = 'workspace-file' | 'webpage-url' | 'mcp-tool' | 'artifact-file' | 'image-url';
|
|
3
3
|
export type CanvasNodeRefreshStrategy = 'file-watch' | 'file-read-write' | 'image-reload' | 'webpage-refresh' | 'mcp-app-rehydrate' | 'artifact-reopen';
|
|
4
4
|
export interface CanvasNodeProvenance {
|
|
@@ -11,8 +11,12 @@
|
|
|
11
11
|
* `.pmx-canvas-snapshots/`, loose blob files) are no longer imported as of 0.4.0 —
|
|
12
12
|
* the one-shot boot migration into SQLite was retired.
|
|
13
13
|
*/
|
|
14
|
-
import { type
|
|
14
|
+
import { type Tour } from '../shared/tour.js';
|
|
15
|
+
import { type CanvasBoard, type PersistedCanvasState, type CanvasTheme, type AxTimelineQuery } from './canvas-db.js';
|
|
16
|
+
import { type DocumentImport, type DocumentImportStatus, type ImportSection, type Attachment } from './document-import.js';
|
|
15
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
|
+
import { type ActorAttribution } from './attribution.js';
|
|
19
|
+
import { type ContextRead, type ContextReadConsumerSummary, type ContextReadInput } from './context-reads.js';
|
|
16
20
|
export declare const PMX_CANVAS_DIR = ".pmx-canvas";
|
|
17
21
|
export interface PersistedBlobRef {
|
|
18
22
|
__pmxCanvasBlob: 'v1';
|
|
@@ -53,7 +57,7 @@ export interface CanvasSnapshotGcResult {
|
|
|
53
57
|
}
|
|
54
58
|
export interface CanvasNodeState {
|
|
55
59
|
id: string;
|
|
56
|
-
type: 'markdown' | 'mcp-app' | 'webpage' | 'json-render' | 'graph' | 'prompt' | 'response' | 'status' | 'context' | 'ledger' | 'trace' | 'file' | 'diff' | 'mermaid' | 'image' | 'html' | 'group';
|
|
60
|
+
type: 'markdown' | 'mcp-app' | 'webpage' | 'json-render' | 'graph' | 'board' | 'prompt' | 'response' | 'status' | 'context' | 'ledger' | 'trace' | 'file' | 'diff' | 'mermaid' | 'image' | 'html' | 'group';
|
|
57
61
|
position: {
|
|
58
62
|
x: number;
|
|
59
63
|
y: number;
|
|
@@ -66,6 +70,27 @@ export interface CanvasNodeState {
|
|
|
66
70
|
collapsed: boolean;
|
|
67
71
|
pinned: boolean;
|
|
68
72
|
data: Record<string, unknown>;
|
|
73
|
+
/** Server-owned provenance. Legacy rows normalize to unknown. */
|
|
74
|
+
createdBy?: ActorAttribution;
|
|
75
|
+
lastEditedBy?: ActorAttribution;
|
|
76
|
+
/** Board-monotonic revision of this node's latest semantic content. */
|
|
77
|
+
contentRevision?: number;
|
|
78
|
+
}
|
|
79
|
+
export interface NodeDeletionTombstone {
|
|
80
|
+
nodeId: string;
|
|
81
|
+
revision: number;
|
|
82
|
+
deletedBy: ActorAttribution;
|
|
83
|
+
}
|
|
84
|
+
export interface BoardContentRevision {
|
|
85
|
+
revision: number;
|
|
86
|
+
/** Cursors below this value are expired and must perform a full reset. */
|
|
87
|
+
retentionFloor: number;
|
|
88
|
+
}
|
|
89
|
+
export interface BoardContentDelta extends BoardContentRevision {
|
|
90
|
+
since: number;
|
|
91
|
+
reset: boolean;
|
|
92
|
+
nodes: CanvasNodeState[];
|
|
93
|
+
deleted: NodeDeletionTombstone[];
|
|
69
94
|
}
|
|
70
95
|
export interface ViewportState {
|
|
71
96
|
x: number;
|
|
@@ -102,6 +127,7 @@ export interface CanvasAnnotation {
|
|
|
102
127
|
createdAt: string;
|
|
103
128
|
}
|
|
104
129
|
export interface CanvasLayout {
|
|
130
|
+
tour?: Tour;
|
|
105
131
|
viewport: ViewportState;
|
|
106
132
|
theme: CanvasTheme;
|
|
107
133
|
nodes: CanvasNodeState[];
|
|
@@ -121,6 +147,8 @@ export interface CanvasNodeUpdate {
|
|
|
121
147
|
collapsed?: boolean;
|
|
122
148
|
}
|
|
123
149
|
export type CanvasChangeType = 'pins' | 'nodes' | 'ax' | 'ax-timeline';
|
|
150
|
+
/** Name for a board nobody named yet: when it was made, to the minute. */
|
|
151
|
+
export declare function defaultBoardName(): string;
|
|
124
152
|
export interface MutationRecordInfo {
|
|
125
153
|
operationType: 'addNode' | 'updateNode' | 'removeNode' | 'addEdge' | 'updateEdge' | 'removeEdge' | 'addAnnotation' | 'removeAnnotation' | 'clear' | 'restoreSnapshot' | 'setPins' | 'setAxFocus' | 'addWorkItem' | 'updateWorkItem' | 'requestApproval' | 'resolveApproval' | 'addReviewAnnotation' | 'updateReviewAnnotation' | 'requestElicitation' | 'respondElicitation' | 'requestMode' | 'resolveModeRequest' | 'setPolicy' | 'arrange' | 'batch' | 'groupNodes' | 'releaseGroupChildren' | 'viewport';
|
|
126
154
|
description: string;
|
|
@@ -140,9 +168,13 @@ declare class CanvasStateManager {
|
|
|
140
168
|
private edges;
|
|
141
169
|
private annotations;
|
|
142
170
|
private _viewport;
|
|
171
|
+
private _tour;
|
|
143
172
|
private _theme;
|
|
144
173
|
private _contextPinnedNodeIds;
|
|
145
174
|
private _workspaceRoot;
|
|
175
|
+
private _contentRevision;
|
|
176
|
+
private _revisionFloor;
|
|
177
|
+
private _deletionTombstones;
|
|
146
178
|
private readonly ax;
|
|
147
179
|
private _changeListeners;
|
|
148
180
|
/**
|
|
@@ -175,12 +207,22 @@ declare class CanvasStateManager {
|
|
|
175
207
|
private applyResolvedGroupBounds;
|
|
176
208
|
private getGroupSnapshot;
|
|
177
209
|
private normalizeNode;
|
|
210
|
+
private nextContentRevision;
|
|
211
|
+
private revisionState;
|
|
212
|
+
/**
|
|
213
|
+
* Stable delta cursor contract: revisions strictly increase per active board;
|
|
214
|
+
* geometry-only writes do not advance them. `reset` means `since` predates
|
|
215
|
+
* retained tombstones, so callers must replace their view with `nodes`.
|
|
216
|
+
*/
|
|
217
|
+
readContentDelta(since?: number): BoardContentDelta;
|
|
218
|
+
getContentRevision(): BoardContentRevision;
|
|
178
219
|
private nodeForRead;
|
|
179
220
|
private reflowAllGroups;
|
|
180
221
|
private translateGroupChildren;
|
|
181
222
|
private recomputeParentGroupBounds;
|
|
182
223
|
private compactGroupChildren;
|
|
183
224
|
private _db;
|
|
225
|
+
private _dbPath;
|
|
184
226
|
private _saveTimer;
|
|
185
227
|
/** Workspace root backing persistence and workspace-relative path resolution. */
|
|
186
228
|
get workspaceRoot(): string;
|
|
@@ -198,8 +240,95 @@ declare class CanvasStateManager {
|
|
|
198
240
|
private externalizePersistedStateBlobs;
|
|
199
241
|
getWorkspaceRoot(): string;
|
|
200
242
|
private emptyPersistedState;
|
|
201
|
-
/**
|
|
243
|
+
/**
|
|
244
|
+
* Load the board that was open last. Call once on server startup. With no
|
|
245
|
+
* such board the workspace starts on Home (no board open).
|
|
246
|
+
*/
|
|
202
247
|
loadFromDisk(options?: LoadFromDiskOptions): boolean;
|
|
248
|
+
/** The SQLite file holding every board, or null without a workspace database. */
|
|
249
|
+
get databasePath(): string | null;
|
|
250
|
+
readWorkspaceMeta(key: string): string | null;
|
|
251
|
+
writeWorkspaceMeta(key: string, value: string | null): void;
|
|
252
|
+
/** A consistent copy of the whole library, safe while the server runs. */
|
|
253
|
+
backupDatabaseTo(path: string): void;
|
|
254
|
+
/**
|
|
255
|
+
* Replace the library with `file`: the current file is kept beside it as
|
|
256
|
+
* `<db>.before-restore`, then the restored file opens (migrating an older
|
|
257
|
+
* layout) on the board it had open last.
|
|
258
|
+
*/
|
|
259
|
+
replaceDatabase(file: string): void;
|
|
260
|
+
private _activeBoardId;
|
|
261
|
+
private _boardGeneration;
|
|
262
|
+
/** Invalidates asynchronous work whenever the loaded board state is replaced. */
|
|
263
|
+
get boardGeneration(): number;
|
|
264
|
+
/** The open board, or null on Home. */
|
|
265
|
+
get activeBoardId(): string | null;
|
|
266
|
+
getActiveBoard(): CanvasBoard | null;
|
|
267
|
+
/**
|
|
268
|
+
* One board's content without opening it: the open board from memory, any
|
|
269
|
+
* other straight from SQLite. Null when there is no such board.
|
|
270
|
+
*/
|
|
271
|
+
readBoard(id: string, includeBlobs?: boolean): {
|
|
272
|
+
board: CanvasBoard;
|
|
273
|
+
state: PersistedCanvasState;
|
|
274
|
+
layout: CanvasLayout;
|
|
275
|
+
} | null;
|
|
276
|
+
/** Every board in the workspace, most recently opened first. */
|
|
277
|
+
listBoards(): CanvasBoard[];
|
|
278
|
+
storeAttachment(input: {
|
|
279
|
+
boardId: string;
|
|
280
|
+
name: string;
|
|
281
|
+
mime: string;
|
|
282
|
+
bytes: Uint8Array;
|
|
283
|
+
}): Attachment | null;
|
|
284
|
+
getAttachment(id: string): Attachment | null;
|
|
285
|
+
readAttachmentBytes(id: string): Uint8Array | null;
|
|
286
|
+
createDocumentImport(attachmentId: string, position: {
|
|
287
|
+
x: number;
|
|
288
|
+
y: number;
|
|
289
|
+
}): DocumentImport | null;
|
|
290
|
+
getDocumentImport(id: string): DocumentImport | null;
|
|
291
|
+
listDocumentImports(boardId?: string): DocumentImport[];
|
|
292
|
+
updateDocumentImport(id: string, status: DocumentImportStatus, fields?: {
|
|
293
|
+
sections?: ImportSection[];
|
|
294
|
+
warnings?: string[];
|
|
295
|
+
agentDescription?: string;
|
|
296
|
+
reason?: string;
|
|
297
|
+
committedNodeIds?: string[];
|
|
298
|
+
}): DocumentImport | null;
|
|
299
|
+
commitDocumentImport(id: string, nodeIds: string[]): DocumentImport | null;
|
|
300
|
+
getContextBriefCursor(boardId: string, consumer: string): number | null;
|
|
301
|
+
advanceContextBriefCursor(boardId: string, consumer: string, revision: number): void;
|
|
302
|
+
/** Creates a board without opening it. */
|
|
303
|
+
createBoard(name: string, category?: string | null): CanvasBoard | null;
|
|
304
|
+
updateBoard(id: string, patch: {
|
|
305
|
+
name?: string;
|
|
306
|
+
category?: string | null;
|
|
307
|
+
}): boolean;
|
|
308
|
+
setBoardReadme(id: string, nodeId: string | null): boolean;
|
|
309
|
+
/** Bounded inactive-board creation; never replaces the state the human has open. */
|
|
310
|
+
createBoardFromBoard(input: {
|
|
311
|
+
sourceBoardId: string;
|
|
312
|
+
name: string;
|
|
313
|
+
category?: string | null;
|
|
314
|
+
nodeIds?: string[];
|
|
315
|
+
includeReadme?: boolean;
|
|
316
|
+
includeStructure?: boolean;
|
|
317
|
+
}): CanvasBoard | null;
|
|
318
|
+
/** Deletes a board and its snapshots; deleting the open board returns to Home first. */
|
|
319
|
+
deleteBoard(id: string): boolean;
|
|
320
|
+
/**
|
|
321
|
+
* Save the open board, then open `id` (or Home for null). The canvas state is
|
|
322
|
+
* replaced wholesale; callers own the runtime side (undo history, app
|
|
323
|
+
* sessions, watchers, SSE) — see `openCanvasBoard` in canvas-operations.
|
|
324
|
+
*/
|
|
325
|
+
switchBoard(id: string | null): boolean;
|
|
326
|
+
/**
|
|
327
|
+
* Content written while no board is open (Home) lands on a new board, which
|
|
328
|
+
* opens: nothing the human was looking at is displaced.
|
|
329
|
+
*/
|
|
330
|
+
private ensureActiveBoard;
|
|
331
|
+
private hasBoardContent;
|
|
203
332
|
/** Debounced save — coalesces rapid mutations into a single write. */
|
|
204
333
|
private scheduleSave;
|
|
205
334
|
flushToDisk(): void;
|
|
@@ -236,12 +365,18 @@ declare class CanvasStateManager {
|
|
|
236
365
|
nodes: CanvasNodeState[];
|
|
237
366
|
edges: CanvasEdge[];
|
|
238
367
|
annotations: CanvasAnnotation[];
|
|
368
|
+
tour?: Tour;
|
|
239
369
|
} | null;
|
|
240
370
|
/** Delete a snapshot. */
|
|
241
371
|
renameSnapshot(id: string, name: string): boolean;
|
|
242
372
|
deleteSnapshot(id: string): boolean;
|
|
243
373
|
/** Remove all snapshots from the DB. Used by test teardown. */
|
|
244
374
|
clearAllSnapshots(): void;
|
|
375
|
+
private restampRestoredContent;
|
|
376
|
+
private semanticData;
|
|
377
|
+
private nodeContentChanged;
|
|
378
|
+
private setSemanticNode;
|
|
379
|
+
private recordDeletion;
|
|
245
380
|
get viewport(): ViewportState;
|
|
246
381
|
addNode(node: CanvasNodeState): void;
|
|
247
382
|
addJsonRenderNode(node: CanvasNodeState): void;
|
|
@@ -261,6 +396,8 @@ declare class CanvasStateManager {
|
|
|
261
396
|
private removeEdgesForNode;
|
|
262
397
|
getLayout(): CanvasLayout;
|
|
263
398
|
getLayoutForPersistence(): CanvasLayout;
|
|
399
|
+
getTour(): Tour | undefined;
|
|
400
|
+
setTour(tour: Tour | null): void;
|
|
264
401
|
applyUpdates(updates: CanvasNodeUpdate[], options?: ApplyUpdatesOptions): {
|
|
265
402
|
applied: number;
|
|
266
403
|
skipped: number;
|
|
@@ -470,6 +607,12 @@ declare class CanvasStateManager {
|
|
|
470
607
|
}): PmxAxSteeringMessage[];
|
|
471
608
|
getPendingSteeringCount(consumer?: string): number;
|
|
472
609
|
getAxTimelineSummary(): PmxAxTimelineSummary;
|
|
610
|
+
/** Records one agent context read (diagnostics; never notifies, so a read cannot trigger reads). */
|
|
611
|
+
recordContextRead(input: ContextReadInput, boardId?: string | null): ContextRead | null;
|
|
612
|
+
getContextReads(limit?: number): {
|
|
613
|
+
reads: ContextRead[];
|
|
614
|
+
summary: ContextReadConsumerSummary[];
|
|
615
|
+
};
|
|
473
616
|
getAxTimeline(q?: AxTimelineQuery): {
|
|
474
617
|
events: PmxAxEvent[];
|
|
475
618
|
evidence: PmxAxEvidence[];
|
|
@@ -26,6 +26,8 @@ export interface CanvasValidationResult {
|
|
|
26
26
|
collisions: CanvasValidationPair[];
|
|
27
27
|
containments: CanvasContainmentIssue[];
|
|
28
28
|
containmentViolations: CanvasContainmentIssue[];
|
|
29
|
+
/** Group frames overlapping nodes that are not members (advisory). */
|
|
30
|
+
groupFrameOverlaps: CanvasValidationPair[];
|
|
29
31
|
missingEdgeEndpoints: Array<{
|
|
30
32
|
edgeId: string;
|
|
31
33
|
from: string;
|
|
@@ -39,6 +41,7 @@ export interface CanvasValidationResult {
|
|
|
39
41
|
collisions: number;
|
|
40
42
|
containments: number;
|
|
41
43
|
containmentViolations: number;
|
|
44
|
+
groupFrameOverlaps: number;
|
|
42
45
|
missingEdgeEndpoints: number;
|
|
43
46
|
sizeWarnings: number;
|
|
44
47
|
};
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import type { CanvasNodeState, NodeDeletionTombstone } from './canvas-state.js';
|
|
2
|
+
export type ContextBriefReason = 'pinned' | 'changed' | 'human' | 'ask' | 'steer' | 'linked' | 'category';
|
|
3
|
+
export interface ContextBriefSourceEntry {
|
|
4
|
+
sourceBoardId: string;
|
|
5
|
+
nodeId: string;
|
|
6
|
+
reason: 'human' | 'ask' | 'steer';
|
|
7
|
+
title: string;
|
|
8
|
+
text: string;
|
|
9
|
+
provenance?: {
|
|
10
|
+
kind: 'imported';
|
|
11
|
+
source: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface ContextBriefLibraryBoard {
|
|
15
|
+
boardId: string;
|
|
16
|
+
name: string;
|
|
17
|
+
category: string | null;
|
|
18
|
+
readme?: {
|
|
19
|
+
nodeId: string;
|
|
20
|
+
title: string;
|
|
21
|
+
summary: string;
|
|
22
|
+
provenance?: {
|
|
23
|
+
kind: 'imported';
|
|
24
|
+
source: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
pinnedTitles: Array<{
|
|
28
|
+
nodeId: string;
|
|
29
|
+
title: string;
|
|
30
|
+
}>;
|
|
31
|
+
/** IDs of link cards on the active board which explicitly target this board. */
|
|
32
|
+
linkIds: string[];
|
|
33
|
+
}
|
|
34
|
+
export interface ContextBriefInput {
|
|
35
|
+
activeBoard: {
|
|
36
|
+
boardId: string;
|
|
37
|
+
name: string;
|
|
38
|
+
category: string | null;
|
|
39
|
+
};
|
|
40
|
+
nodes: readonly CanvasNodeState[];
|
|
41
|
+
pinnedNodeIds: readonly string[];
|
|
42
|
+
contentRevision: number;
|
|
43
|
+
retentionFloor: number;
|
|
44
|
+
tombstones: readonly NodeDeletionTombstone[];
|
|
45
|
+
/** null means a first read. Other values must be non-negative safe integers. */
|
|
46
|
+
since: number | null;
|
|
47
|
+
libraryBoards: readonly ContextBriefLibraryBoard[];
|
|
48
|
+
entries?: readonly ContextBriefSourceEntry[];
|
|
49
|
+
/** Maximum JavaScript string length (UTF-16 code units), including the JSON envelope. */
|
|
50
|
+
budget: number;
|
|
51
|
+
}
|
|
52
|
+
export interface CompiledContextEntry {
|
|
53
|
+
sourceBoardId: string;
|
|
54
|
+
nodeId: string;
|
|
55
|
+
reason: ContextBriefReason;
|
|
56
|
+
title: string;
|
|
57
|
+
text: string;
|
|
58
|
+
/** A linked board's pin title is discovery metadata, not delivery of that pinned card. */
|
|
59
|
+
titleOnly?: true;
|
|
60
|
+
/** The body was shortened to fit; the same revision remains eligible on the next pull. */
|
|
61
|
+
truncated?: true;
|
|
62
|
+
provenance?: {
|
|
63
|
+
kind: 'imported';
|
|
64
|
+
source: string;
|
|
65
|
+
trust: 'source-material-not-instructions';
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
export interface ContextBriefDocument {
|
|
69
|
+
version: 1;
|
|
70
|
+
budgetUnit: 'utf16-code-units';
|
|
71
|
+
board: {
|
|
72
|
+
boardId: string;
|
|
73
|
+
name: string;
|
|
74
|
+
category: string | null;
|
|
75
|
+
};
|
|
76
|
+
cursor: {
|
|
77
|
+
requested: number | null;
|
|
78
|
+
next: number | null;
|
|
79
|
+
current: number;
|
|
80
|
+
retentionFloor: number;
|
|
81
|
+
reset: 'first-read' | 'retention-expired' | null;
|
|
82
|
+
valid: boolean;
|
|
83
|
+
};
|
|
84
|
+
entries: CompiledContextEntry[];
|
|
85
|
+
deletions: Array<{
|
|
86
|
+
sourceBoardId: string;
|
|
87
|
+
nodeId: string;
|
|
88
|
+
revision: number;
|
|
89
|
+
}>;
|
|
90
|
+
delivery: {
|
|
91
|
+
truncated: boolean;
|
|
92
|
+
omittedEntries: number;
|
|
93
|
+
omittedDeletions: number;
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
export interface ContextBriefResult {
|
|
97
|
+
/** Empty only when the budget cannot hold even the bounded JSON envelope. */
|
|
98
|
+
serialized: string;
|
|
99
|
+
document: ContextBriefDocument | null;
|
|
100
|
+
deliveredEntryIds: string[];
|
|
101
|
+
deliveredDeletionIds: string[];
|
|
102
|
+
nextCursor: number | null;
|
|
103
|
+
reset: ContextBriefDocument['cursor']['reset'];
|
|
104
|
+
invalidCursor: boolean;
|
|
105
|
+
truncated: boolean;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Pure, deterministic compiler. It reads only the supplied snapshot and never
|
|
109
|
+
* treats library visibility as authorization to read or mutate another board.
|
|
110
|
+
*/
|
|
111
|
+
export declare function compileContextBrief(input: ContextBriefInput): ContextBriefResult;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Context read instrumentation (vision Part 1 item 4, the delivery half):
|
|
3
|
+
* one row per agent read of canvas context — which surface, by whom, and
|
|
4
|
+
* which pinned nodes were in what came back. Diagnostics only, like the AX
|
|
5
|
+
* timeline: never snapshotted, never cleared with the canvas, bounded, and
|
|
6
|
+
* recording never notifies (a read must not trigger more reads).
|
|
7
|
+
*/
|
|
8
|
+
import type { Database } from 'bun:sqlite';
|
|
9
|
+
export declare const CONTEXT_READ_RETENTION = 5000;
|
|
10
|
+
export declare const CONTEXT_READ_CHANNELS: readonly ["operation", "mcp-resource", "mcp-prompt", "adapter"];
|
|
11
|
+
export type ContextReadChannel = (typeof CONTEXT_READ_CHANNELS)[number];
|
|
12
|
+
/** Registry reads that hand an agent canvas context; recorded in executeOperation. */
|
|
13
|
+
export declare const CONTEXT_READ_OPS: Set<string>;
|
|
14
|
+
export interface ContextRead {
|
|
15
|
+
seq: number;
|
|
16
|
+
id: string;
|
|
17
|
+
at: string;
|
|
18
|
+
channel: ContextReadChannel;
|
|
19
|
+
resource: string;
|
|
20
|
+
source: string;
|
|
21
|
+
consumer: string | null;
|
|
22
|
+
agentId: string | null;
|
|
23
|
+
pinnedNodeIds: string[];
|
|
24
|
+
deliveredNodeIds: string[];
|
|
25
|
+
bytes: number;
|
|
26
|
+
/** The board open when the read happened (null on Home). */
|
|
27
|
+
boardId: string | null;
|
|
28
|
+
}
|
|
29
|
+
export type ContextReadInput = Omit<ContextRead, 'seq' | 'id' | 'at' | 'boardId'> & {
|
|
30
|
+
/** Explicit read target, captured before asynchronous formatting/proxy work. */
|
|
31
|
+
boardId?: string | null;
|
|
32
|
+
};
|
|
33
|
+
export interface ContextReadConsumerSummary {
|
|
34
|
+
consumer: string;
|
|
35
|
+
reads: number;
|
|
36
|
+
readsWithPins: number;
|
|
37
|
+
readsDeliveringAllPins: number;
|
|
38
|
+
lastReadAt: string;
|
|
39
|
+
resources: Record<string, number>;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Pinned nodes whose serialized node (an object carrying `"id": "<id>"`) is in
|
|
43
|
+
* what the reader received. A bare id list, a title, or a clipped-off node does
|
|
44
|
+
* not count — the agent got the pin's name, not its content.
|
|
45
|
+
*/
|
|
46
|
+
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;
|
|
50
|
+
/** Newest first. The summary covers every retained row, not just the returned page. */
|
|
51
|
+
export declare function loadContextReadsFromDB(db: Database, limit?: number): {
|
|
52
|
+
reads: ContextRead[];
|
|
53
|
+
summary: ContextReadConsumerSummary[];
|
|
54
|
+
};
|
|
55
|
+
export declare function summarizeContextReads(reads: ContextRead[]): ContextReadConsumerSummary[];
|