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.
Files changed (204) hide show
  1. package/.github/extensions/pmx-canvas/extension.mjs +67 -3
  2. package/CHANGELOG.md +73 -0
  3. package/Readme.md +35 -5
  4. package/dist/canvas/global.css +498 -28
  5. package/dist/canvas/index.js +110 -95
  6. package/dist/canvas/mermaid-entry.js +258 -258
  7. package/dist/types/cli/agent.d.ts +4 -0
  8. package/dist/types/cli/commands/backup.d.ts +1 -0
  9. package/dist/types/cli/commands/boards.d.ts +1 -0
  10. package/dist/types/cli/commands/export.d.ts +1 -0
  11. package/dist/types/cli/commands/record.d.ts +12 -0
  12. package/dist/types/client/canvas/BoardCopyDialog.d.ts +5 -0
  13. package/dist/types/client/canvas/BoardFolderDialog.d.ts +7 -0
  14. package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -0
  15. package/dist/types/client/canvas/BoardSwitcher.d.ts +8 -0
  16. package/dist/types/client/canvas/ExportDialog.d.ts +7 -0
  17. package/dist/types/client/canvas/HomeView.d.ts +9 -0
  18. package/dist/types/client/canvas/Presentation.d.ts +13 -0
  19. package/dist/types/client/canvas/use-node-drag.d.ts +2 -1
  20. package/dist/types/client/nodes/AttachmentNode.d.ts +6 -0
  21. package/dist/types/client/nodes/BoardNode.d.ts +5 -0
  22. package/dist/types/client/nodes/McpAppNode.d.ts +24 -1
  23. package/dist/types/client/state/boards-store.d.ts +79 -0
  24. package/dist/types/client/state/canvas-store.d.ts +2 -0
  25. package/dist/types/client/state/intent-bridge.d.ts +1 -0
  26. package/dist/types/client/state/presentation.d.ts +3 -0
  27. package/dist/types/client/state/session-store.d.ts +7 -0
  28. package/dist/types/client/types.d.ts +2 -2
  29. package/dist/types/json-render/catalog.d.ts +3 -3
  30. package/dist/types/json-render/charts/definitions.d.ts +1 -1
  31. package/dist/types/json-render/server.d.ts +8 -0
  32. package/dist/types/mcp/canvas-access.d.ts +10 -3
  33. package/dist/types/mcp/context-uri-template.d.ts +6 -0
  34. package/dist/types/server/agent-presence.d.ts +1 -1
  35. package/dist/types/server/attribution.d.ts +11 -0
  36. package/dist/types/server/ax-context.d.ts +3 -1
  37. package/dist/types/server/ax-interaction.d.ts +2 -2
  38. package/dist/types/server/ax-state.d.ts +13 -3
  39. package/dist/types/server/backup.d.ts +36 -0
  40. package/dist/types/server/board-export.d.ts +45 -0
  41. package/dist/types/server/canvas-db.d.ts +65 -9
  42. package/dist/types/server/canvas-operations.d.ts +45 -0
  43. package/dist/types/server/canvas-provenance.d.ts +1 -1
  44. package/dist/types/server/canvas-schema.d.ts +1 -0
  45. package/dist/types/server/canvas-state.d.ts +146 -3
  46. package/dist/types/server/canvas-validation.d.ts +3 -0
  47. package/dist/types/server/context-brief.d.ts +111 -0
  48. package/dist/types/server/context-reads.d.ts +55 -0
  49. package/dist/types/server/document-import.d.ts +66 -0
  50. package/dist/types/server/html-surface.d.ts +1 -1
  51. package/dist/types/server/index.d.ts +107 -4
  52. package/dist/types/server/mutation-history.d.ts +1 -0
  53. package/dist/types/server/operations/invoker.d.ts +2 -0
  54. package/dist/types/server/operations/mcp.d.ts +7 -1
  55. package/dist/types/server/operations/ops/app.d.ts +2 -0
  56. package/dist/types/server/operations/ops/ax-shared.d.ts +2 -2
  57. package/dist/types/server/operations/ops/backup.d.ts +2 -0
  58. package/dist/types/server/operations/ops/boards.d.ts +10 -0
  59. package/dist/types/server/operations/ops/export.d.ts +2 -0
  60. package/dist/types/server/operations/ops/imports.d.ts +2 -0
  61. package/dist/types/server/operations/ops/json-render.d.ts +2 -0
  62. package/dist/types/server/operations/ops/nodes.d.ts +4 -2
  63. package/dist/types/server/operations/ops/query.d.ts +2 -0
  64. package/dist/types/server/operations/registry.d.ts +9 -1
  65. package/dist/types/server/operations/types.d.ts +1 -1
  66. package/dist/types/server/server.d.ts +1 -0
  67. package/dist/types/server/trace-manager.d.ts +7 -0
  68. package/dist/types/server/web-artifacts.d.ts +3 -0
  69. package/dist/types/server/webpage-node.d.ts +22 -1
  70. package/dist/types/server/workbench-auth.d.ts +3 -0
  71. package/dist/types/shared/boards.d.ts +6 -0
  72. package/dist/types/shared/tour.d.ts +72 -0
  73. package/docs/RELEASE.md +5 -0
  74. package/docs/cli.md +157 -0
  75. package/docs/http-api.md +277 -6
  76. package/docs/mcp.md +96 -7
  77. package/docs/node-types.md +106 -0
  78. package/docs/plans/plan-010-attributed-ask-answers.md +39 -0
  79. package/docs/plans/plan-011-context-read-instrumentation.md +54 -0
  80. package/docs/plans/plan-012-many-boards-stage-1.md +98 -0
  81. package/docs/plans/plan-013-static-board-export.md +47 -0
  82. package/docs/plans/plan-014-connected-board-memory.md +140 -0
  83. package/docs/product-vision-2026-09.md +118 -18
  84. package/docs/sdk.md +50 -0
  85. package/package.json +1 -1
  86. package/skills/pmx-canvas/SKILL.md +62 -5
  87. package/skills/pmx-canvas/references/full-reference.md +44 -8
  88. package/skills/pmx-canvas/references/github-copilot-app-adapter.md +3 -0
  89. package/skills/pmx-canvas/references/installing-pmx-canvas.md +4 -4
  90. package/skills/pmx-canvas-orchestration/SKILL.md +5 -0
  91. package/skills/pmx-canvas-testing/SKILL.md +4 -0
  92. package/src/cli/agent.ts +9 -0
  93. package/src/cli/commands/ax.ts +13 -0
  94. package/src/cli/commands/backup.ts +66 -0
  95. package/src/cli/commands/boards.ts +71 -0
  96. package/src/cli/commands/export.ts +30 -0
  97. package/src/cli/commands/nodes.ts +14 -1
  98. package/src/cli/commands/pins.ts +6 -2
  99. package/src/cli/commands/pump.ts +3 -0
  100. package/src/cli/commands/query.ts +33 -7
  101. package/src/cli/commands/record.ts +218 -0
  102. package/src/cli/commands/view.ts +7 -5
  103. package/src/cli/index.ts +21 -9
  104. package/src/client/App.tsx +28 -4
  105. package/src/client/canvas/AgentPresenceLayer.tsx +1 -1
  106. package/src/client/canvas/BoardCopyDialog.tsx +153 -0
  107. package/src/client/canvas/BoardFolderDialog.tsx +120 -0
  108. package/src/client/canvas/BoardLinkDialog.tsx +93 -0
  109. package/src/client/canvas/BoardSwitcher.tsx +149 -0
  110. package/src/client/canvas/CanvasNode.tsx +8 -0
  111. package/src/client/canvas/CanvasViewport.tsx +3 -0
  112. package/src/client/canvas/CommandPalette.tsx +107 -4
  113. package/src/client/canvas/ContextMenu.tsx +4 -0
  114. package/src/client/canvas/ExpandedNodeOverlay.tsx +3 -0
  115. package/src/client/canvas/ExportDialog.tsx +197 -0
  116. package/src/client/canvas/HomeView.tsx +277 -0
  117. package/src/client/canvas/IntentLayer.tsx +9 -2
  118. package/src/client/canvas/Presentation.tsx +108 -0
  119. package/src/client/canvas/SessionPanel.tsx +28 -1
  120. package/src/client/canvas/ToolRail.tsx +38 -3
  121. package/src/client/canvas/TopBar.tsx +49 -7
  122. package/src/client/canvas/import-files.ts +19 -1
  123. package/src/client/canvas/kind-colors.ts +1 -0
  124. package/src/client/canvas/use-node-drag.ts +8 -3
  125. package/src/client/icons.tsx +2 -0
  126. package/src/client/mermaid-entry.ts +39 -0
  127. package/src/client/nodes/AttachmentNode.tsx +148 -0
  128. package/src/client/nodes/BoardNode.tsx +35 -0
  129. package/src/client/nodes/FileNode.tsx +6 -0
  130. package/src/client/nodes/HtmlNode.tsx +12 -13
  131. package/src/client/nodes/MarkdownNode.tsx +47 -19
  132. package/src/client/nodes/McpAppNode.tsx +105 -13
  133. package/src/client/nodes/MermaidNode.tsx +3 -2
  134. package/src/client/nodes/ax-node-actions.ts +2 -5
  135. package/src/client/nodes/use-ax-surface-bridge.ts +1 -1
  136. package/src/client/state/boards-store.ts +167 -0
  137. package/src/client/state/canvas-store.ts +22 -0
  138. package/src/client/state/intent-bridge.ts +30 -2
  139. package/src/client/state/intent-store.ts +5 -1
  140. package/src/client/state/node-factory.ts +1 -0
  141. package/src/client/state/presentation.ts +7 -0
  142. package/src/client/state/session-store.ts +8 -0
  143. package/src/client/state/sse-bridge.ts +52 -5
  144. package/src/client/theme/global.css +498 -28
  145. package/src/client/types.ts +2 -0
  146. package/src/json-render/server.ts +45 -9
  147. package/src/mcp/canvas-access.ts +59 -22
  148. package/src/mcp/context-uri-template.ts +28 -0
  149. package/src/mcp/server.ts +122 -15
  150. package/src/server/agent-context.ts +116 -29
  151. package/src/server/agent-presence.ts +15 -9
  152. package/src/server/attribution.ts +29 -0
  153. package/src/server/ax-context.ts +4 -2
  154. package/src/server/ax-interaction.ts +1 -0
  155. package/src/server/ax-state-manager.ts +72 -3
  156. package/src/server/ax-state.ts +41 -0
  157. package/src/server/backup.ts +178 -0
  158. package/src/server/board-export.ts +686 -0
  159. package/src/server/canvas-db.ts +612 -105
  160. package/src/server/canvas-operations.ts +183 -31
  161. package/src/server/canvas-provenance.ts +1 -0
  162. package/src/server/canvas-schema.ts +22 -0
  163. package/src/server/canvas-state.ts +812 -48
  164. package/src/server/canvas-validation.ts +9 -1
  165. package/src/server/context-brief.ts +372 -0
  166. package/src/server/context-reads.ts +238 -0
  167. package/src/server/demo-state.json +670 -9
  168. package/src/server/document-import.ts +223 -0
  169. package/src/server/html-primitives.ts +199 -91
  170. package/src/server/html-surface.ts +8 -3
  171. package/src/server/index.ts +243 -5
  172. package/src/server/mutation-history.ts +10 -13
  173. package/src/server/operations/composites.ts +29 -5
  174. package/src/server/operations/http.ts +9 -3
  175. package/src/server/operations/index.ts +8 -0
  176. package/src/server/operations/invoker.ts +14 -3
  177. package/src/server/operations/mcp.ts +50 -11
  178. package/src/server/operations/ops/app.ts +15 -0
  179. package/src/server/operations/ops/ax-read.ts +10 -6
  180. package/src/server/operations/ops/ax-timeline.ts +75 -0
  181. package/src/server/operations/ops/backup.ts +134 -0
  182. package/src/server/operations/ops/batch.ts +20 -4
  183. package/src/server/operations/ops/boards.ts +351 -0
  184. package/src/server/operations/ops/export.ts +74 -0
  185. package/src/server/operations/ops/ext-app.ts +4 -0
  186. package/src/server/operations/ops/groups.ts +14 -7
  187. package/src/server/operations/ops/imports.ts +220 -0
  188. package/src/server/operations/ops/json-render.ts +37 -5
  189. package/src/server/operations/ops/nodes.ts +99 -21
  190. package/src/server/operations/ops/query.ts +206 -9
  191. package/src/server/operations/ops/viewport.ts +32 -0
  192. package/src/server/operations/registry.ts +129 -31
  193. package/src/server/operations/types.ts +1 -1
  194. package/src/server/scope-fence.ts +1 -1
  195. package/src/server/server.ts +155 -8
  196. package/src/server/spatial-analysis.ts +9 -17
  197. package/src/server/trace-manager.ts +19 -0
  198. package/src/server/web-artifacts.ts +11 -3
  199. package/src/server/webpage-node.ts +173 -13
  200. package/src/server/workbench-auth.ts +11 -0
  201. package/src/server/workboard.ts +3 -3
  202. package/src/shared/boards.ts +18 -0
  203. package/src/shared/node-sizes.ts +1 -0
  204. package/src/shared/tour.ts +87 -0
@@ -0,0 +1,66 @@
1
+ import type { Database } from 'bun:sqlite';
2
+ export declare const MAX_ATTACHMENT_BYTES: number;
3
+ export declare const MAX_INLINE_ATTACHMENT_BYTES: number;
4
+ export declare const MAX_ATTACHMENT_NAME_LENGTH = 255;
5
+ export declare const MAX_IMPORT_SECTIONS = 32;
6
+ export declare const MAX_IMPORT_WARNINGS = 20;
7
+ export declare const MAX_IMPORT_TEXT = 200000;
8
+ export declare const MAX_IMPORT_TITLE_LENGTH = 500;
9
+ export declare const MAX_IMPORT_REFERENCE_LENGTH = 2000;
10
+ export declare const MAX_IMPORT_WARNING_LENGTH = 2000;
11
+ export declare const MAX_IMPORT_AGENT_DESCRIPTION_LENGTH = 4000;
12
+ export declare const MAX_IMPORT_REASON_LENGTH = 4000;
13
+ export interface Attachment {
14
+ id: string;
15
+ boardId: string;
16
+ sha256: string;
17
+ name: string;
18
+ mime: string;
19
+ size: number;
20
+ createdAt: string;
21
+ }
22
+ export interface ImportSection {
23
+ title: string;
24
+ markdown: string;
25
+ reference?: string;
26
+ }
27
+ export type DocumentImportStatus = 'attached' | 'requested' | 'drafted' | 'unavailable' | 'cancelled' | 'committed';
28
+ export interface DocumentImport {
29
+ id: string;
30
+ boardId: string;
31
+ attachmentId: string;
32
+ status: DocumentImportStatus;
33
+ position: {
34
+ x: number;
35
+ y: number;
36
+ };
37
+ sections: ImportSection[];
38
+ warnings: string[];
39
+ agentDescription: string | null;
40
+ reason: string | null;
41
+ committedNodeIds: string[];
42
+ createdAt: string;
43
+ updatedAt: string;
44
+ }
45
+ export declare function storeAttachment(db: Database, input: {
46
+ boardId: string;
47
+ name: string;
48
+ mime: string;
49
+ bytes: Uint8Array;
50
+ }): Attachment;
51
+ export declare function getAttachment(db: Database, id: string): Attachment | null;
52
+ export declare function readAttachmentBytes(db: Database, id: string): Uint8Array | null;
53
+ export declare function copyBoardAttachments(db: Database, sourceBoardId: string, targetBoardId: string, referencedIds: Set<string>): Map<string, string>;
54
+ export declare function createImport(db: Database, attachmentId: string, position: {
55
+ x: number;
56
+ y: number;
57
+ }): DocumentImport;
58
+ export declare function getImport(db: Database, id: string): DocumentImport | null;
59
+ export declare function listImports(db: Database, boardId?: string): DocumentImport[];
60
+ export declare function updateImport(db: Database, id: string, status: DocumentImportStatus, fields?: {
61
+ sections?: ImportSection[];
62
+ warnings?: string[];
63
+ agentDescription?: string;
64
+ reason?: string;
65
+ committedNodeIds?: string[];
66
+ }): DocumentImport;
@@ -60,7 +60,7 @@ export declare function buildContentHeightReporter(frameToken: string): string;
60
60
  * of the main SPA bundle). Escaping is mandatory: the source is arbitrary node
61
61
  * data and must not be parsed as markup.
62
62
  */
63
- export declare function buildMermaidSurfaceHtml(source: string, inlineEntry?: string | null): string;
63
+ export declare function buildMermaidSurfaceHtml(source: string, inlineEntry?: string | null, fit?: 'contain' | 'none', frameToken?: string): string;
64
64
  export interface HtmlSurfaceOptions {
65
65
  theme: SurfaceTheme;
66
66
  /**
@@ -1,11 +1,16 @@
1
1
  import { EventEmitter } from 'node:events';
2
+ import { type Tour } from '../shared/tour.js';
3
+ export type { Tour, TourStop } from '../shared/tour.js';
2
4
  import type { AgentPhase, AgentPresence, AgentPresenceSnapshot } from '../shared/agent-presence.js';
3
5
  import { canvasState } from './canvas-state.js';
4
6
  import type { CanvasAnnotation, CanvasNodeState, CanvasEdge, CanvasLayout } from './canvas-state.js';
5
7
  import { type AxInteractionInput, type AxInteractionPublicResult } from './ax-interaction.js';
6
8
  import type { PmxAxIntent } from '../shared/ax-intent.js';
7
9
  import type { PmxAxActivityKind, PmxAxApprovalGate, PmxAxCommandDescriptor, PmxAxContext, PmxAxElicitation, PmxAxEvent, PmxAxEvidence, PmxAxEvidenceKind, PmxAxFocusState, PmxAxHostCapability, PmxAxMode, PmxAxModeRequest, PmxAxPolicy, PmxAxReviewAnchorType, PmxAxReviewAnnotation, PmxAxReviewKind, PmxAxReviewRegion, PmxAxReviewSeverity, PmxAxReviewStatus, PmxAxSource, PmxAxState, PmxAxSteeringMessage, PmxAxWorkItem, PmxAxWorkItemStatus } from './ax-state.js';
8
- import type { AxTimelineQuery } from './canvas-db.js';
10
+ import type { AxTimelineQuery, CanvasBoard } from './canvas-db.js';
11
+ import type { Attachment, DocumentImport, ImportSection } from './document-import.js';
12
+ import type { BackupFile, BackupStatus } from './backup.js';
13
+ import type { ExportManifest } from './board-export.js';
9
14
  import { searchNodes } from './spatial-analysis.js';
10
15
  import { diffLayouts } from './mutation-history.js';
11
16
  import { fitCanvasView, gcCanvasSnapshots, listCanvasSnapshots } from './canvas-operations.js';
@@ -140,6 +145,8 @@ export declare class PmxCanvas extends EventEmitter {
140
145
  ungroupNodes(groupId: string, options?: {
141
146
  intentId?: string;
142
147
  }): boolean;
148
+ getTour(): Tour;
149
+ setTour(tour: Tour | null): void;
143
150
  clear(): void;
144
151
  arrange(layout?: 'grid' | 'column' | 'flow'): void;
145
152
  focusNode(id: string, options?: {
@@ -151,7 +158,9 @@ export declare class PmxCanvas extends EventEmitter {
151
158
  getAxState(): PmxAxState;
152
159
  getAxContext(options?: {
153
160
  consumer?: string;
154
- }): PmxAxContext;
161
+ }): PmxAxContext & {
162
+ boardId: string | null;
163
+ };
155
164
  setAxFocus(nodeIds: string[], options?: {
156
165
  source?: PmxAxSource;
157
166
  }): PmxAxFocusState;
@@ -197,6 +206,93 @@ export declare class PmxCanvas extends EventEmitter {
197
206
  source?: PmxAxSource;
198
207
  }): AxInteractionPublicResult;
199
208
  getAxTimeline(query?: AxTimelineQuery): ReturnType<typeof canvasState.getAxTimeline>;
209
+ listBoards(): {
210
+ activeBoardId: string | null;
211
+ boards: CanvasBoard[];
212
+ };
213
+ listImports(boardId?: string): DocumentImport[];
214
+ readImport(id: string): {
215
+ import: DocumentImport;
216
+ attachment: Attachment;
217
+ downloadPath: string;
218
+ bytes?: Uint8Array;
219
+ } | null;
220
+ submitImport(id: string, sections: ImportSection[], agentDescription: string, warnings?: string[]): Promise<DocumentImport>;
221
+ markImportUnavailable(id: string, reason: string): Promise<DocumentImport>;
222
+ attachDocument(input: {
223
+ boardId: string;
224
+ name: string;
225
+ mime?: string;
226
+ bytes: Uint8Array;
227
+ x?: number;
228
+ y?: number;
229
+ }): {
230
+ attachment: Attachment;
231
+ import: DocumentImport;
232
+ nodeId: string;
233
+ };
234
+ requestImport(id: string, consent: true, trustedHumanToken: string): Promise<DocumentImport>;
235
+ cancelImport(id: string, trustedHumanToken: string): Promise<DocumentImport>;
236
+ commitImport(id: string, trustedHumanToken: string): Promise<{
237
+ import: DocumentImport;
238
+ nodeIds: string[];
239
+ }>;
240
+ createBoard(name: string, category?: string): Promise<CanvasBoard>;
241
+ /** Rename a board and/or file it under a category (`category: null` removes it). */
242
+ updateBoard(id: string, patch: {
243
+ name?: string;
244
+ category?: string | null;
245
+ }): Promise<void>;
246
+ setBoardReadme(id: string, readmeNodeId: string | null): Promise<void>;
247
+ createBoardFrom(input: {
248
+ sourceBoardId: string;
249
+ name: string;
250
+ category?: string;
251
+ nodeIds?: string[];
252
+ includeReadme?: boolean;
253
+ includeStructure?: boolean;
254
+ preview?: boolean;
255
+ }): Promise<Record<string, unknown>>;
256
+ searchLibrary(query: string, limit?: number): Promise<Record<string, unknown>>;
257
+ /** Budgeted cross-board brief. Budget is measured in UTF-16 characters. */
258
+ getContextBrief(options?: {
259
+ consumer?: string;
260
+ since?: number;
261
+ budget?: number;
262
+ }): Promise<Record<string, unknown>>;
263
+ /** Open a board, or Home with null. */
264
+ openBoard(id: string | null): Promise<void>;
265
+ deleteBoard(id: string): Promise<void>;
266
+ /** Write a self-contained HTML file of a board (default: the open board). */
267
+ exportBoard(options?: {
268
+ board?: string;
269
+ includeFiles?: boolean;
270
+ includeDerivedText?: boolean;
271
+ }): Promise<{
272
+ path: string;
273
+ url: string;
274
+ bytes: number;
275
+ manifest: ExportManifest;
276
+ }>;
277
+ getBackupStatus(): Promise<BackupStatus>;
278
+ /** Back up every board now; `to` and `keep` default to the configured folder and count. */
279
+ backup(options?: {
280
+ to?: string;
281
+ keep?: number;
282
+ }): Promise<{
283
+ backup: BackupFile;
284
+ removed: string[];
285
+ }>;
286
+ /** Back up on a schedule run by the server; `every: 'off'` stops it. */
287
+ setBackupSchedule(options: {
288
+ every: string;
289
+ to?: string;
290
+ keep?: number;
291
+ }): Promise<BackupStatus>;
292
+ /** Replace every board with a backup file; the current file is kept as `canvas.db.before-restore`. */
293
+ restoreBackup(file: string): Promise<void>;
294
+ /** The context read log: which canvas context each agent read and which pinned nodes reached it. */
295
+ getContextReads(limit?: number): ReturnType<typeof canvasState.getContextReads>;
200
296
  listWorkItems(): PmxAxWorkItem[];
201
297
  addWorkItem(input: {
202
298
  title: string;
@@ -386,8 +482,12 @@ export declare class PmxCanvas extends EventEmitter {
386
482
  maxScale?: number;
387
483
  nodeIds?: string[];
388
484
  }): ReturnType<typeof fitCanvasView>;
389
- getLayout(): CanvasLayout;
390
- getNode(id: string): SdkCanvasNode | undefined;
485
+ getLayout(options?: {
486
+ board?: string;
487
+ }): CanvasLayout;
488
+ getNode(id: string, options?: {
489
+ board?: string;
490
+ }): SdkCanvasNode | undefined;
391
491
  search(query: string): ReturnType<typeof searchNodes>;
392
492
  getSpatialContext(): import("./spatial-analysis.js").SpatialContext;
393
493
  undo(): Promise<{
@@ -588,6 +688,9 @@ export type { CanvasNodeState, CanvasEdge, CanvasLayout, ViewportState } from '.
588
688
  export type { CanvasAutomationWebViewOptions, CanvasAutomationWebViewStatus, PrimaryWorkbenchCanvasPromptRequest, PrimaryWorkbenchIntent, } from './server.js';
589
689
  export { emitPrimaryWorkbenchEvent, consumePrimaryWorkbenchIntents, setPrimaryWorkbenchAutoOpenEnabled, setPrimaryWorkbenchCanvasPromptHandler, startCanvasServer, stopCanvasServer, getCanvasServerPort, openUrlInExternalBrowser, getCanvasAutomationWebViewStatus, startCanvasAutomationWebView, stopCanvasAutomationWebView, evaluateCanvasAutomationWebView, resizeCanvasAutomationWebView, screenshotCanvasAutomationWebView, } from './server.js';
590
690
  export { canvasState } from './canvas-state.js';
691
+ export type { CanvasBoard } from './canvas-db.js';
692
+ export type { BackupFile, BackupStatus } from './backup.js';
693
+ export type { ExportManifest } from './board-export.js';
591
694
  export type { CanvasAnnotation, CanvasSnapshot, CanvasSnapshotGcResult, CanvasSnapshotListOptions, } from './canvas-state.js';
592
695
  export { findOpenCanvasPosition } from './placement.js';
593
696
  export { searchNodes, buildSpatialContext, detectClusters, findNeighborhoods } from './spatial-analysis.js';
@@ -114,5 +114,6 @@ export declare function diffLayouts(snapshotName: string, snapshotLayout: {
114
114
  */
115
115
  export declare function formatDiff(diff: SnapshotDiffResult): string;
116
116
  export declare const mutationHistory: MutationHistory;
117
+ /** Direct callers share the same async-local attribution as node mutations. */
117
118
  export declare function setMutationActor(actor: MutationActor | null, writer?: string | null): void;
118
119
  export {};
@@ -10,6 +10,7 @@ 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
12
  private readonly source;
13
+ private readonly proxiedRead;
13
14
  /** `source` labels this caller's agent presence ('mcp', 'sdk', …). */
14
15
  constructor(source?: string);
15
16
  invoke(name: string, input: Record<string, unknown>): Promise<unknown>;
@@ -18,6 +19,7 @@ export declare class LocalOperationInvoker implements OperationInvoker {
18
19
  export declare class HttpOperationInvoker implements OperationInvoker {
19
20
  private readonly baseUrl;
20
21
  private readonly source;
22
+ private readonly proxiedRead;
21
23
  /** `source` labels this caller's agent presence on the server ('cli', 'mcp', …). */
22
24
  constructor(baseUrl: string, source?: string);
23
25
  invoke(name: string, rawInput: Record<string, unknown>): Promise<unknown>;
@@ -1,9 +1,15 @@
1
1
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- import type { OperationInvoker } from './invoker.js';
2
+ import { type OperationInvoker } from './invoker.js';
3
3
  import { type OperationMcpToolHost } from './types.js';
4
+ import { type ContextReadInput } from '../context-reads.js';
4
5
  import { type CompositeToolDefinition } from './composites.js';
5
6
  export interface OperationToolHost extends OperationMcpToolHost {
6
7
  invoker(): OperationInvoker;
8
+ prepareContextRead(board?: string): Promise<{
9
+ boardId: string | null;
10
+ pinnedNodeIds: string[];
11
+ }>;
12
+ recordContextRead(read: ContextReadInput): Promise<void>;
7
13
  }
8
14
  export declare function registerOperationTools(server: McpServer, getHost: () => Promise<OperationToolHost>): void;
9
15
  /**
@@ -1,3 +1,4 @@
1
+ import { type CanvasSizeAdjustment } from '../../canvas-operations.js';
1
2
  import { type ExternalMcpTransportConfig } from '../../mcp-app-runtime.js';
2
3
  import { type Operation, type OperationContext } from '../types.js';
3
4
  export interface OpenMcpAppCoreInput {
@@ -20,6 +21,7 @@ export interface OpenMcpAppCoreResult {
20
21
  toolCallId: string;
21
22
  sessionId: string;
22
23
  resourceUri: string;
24
+ sizeAdjustment?: CanvasSizeAdjustment;
23
25
  }
24
26
  /**
25
27
  * Open an external MCP app: connect + call + read resource (openExternalMcpApp),
@@ -16,14 +16,14 @@ export declare const AX_SOURCES: readonly ["agent", "amp", "api", "browser", "cl
16
16
  export declare const AX_SOURCE_SHAPE: z.ZodOptional<z.ZodEnum<{
17
17
  amp: "amp";
18
18
  agent: "agent";
19
+ system: "system";
20
+ sdk: "sdk";
19
21
  api: "api";
20
22
  browser: "browser";
21
23
  cli: "cli";
22
24
  codex: "codex";
23
25
  copilot: "copilot";
24
26
  mcp: "mcp";
25
- sdk: "sdk";
26
- system: "system";
27
27
  }>>;
28
28
  /** Zod schema for the optional `agentId` field shared by AX MCP tool shapes. */
29
29
  export declare const AX_AGENT_ID_SHAPE: z.ZodOptional<z.ZodString>;
@@ -0,0 +1,2 @@
1
+ import { type Operation } from '../types.js';
2
+ export declare const backupOperations: Operation[];
@@ -0,0 +1,10 @@
1
+ import { type CanvasLayout } from '../../canvas-state.js';
2
+ import { type Operation } from '../types.js';
3
+ export declare function boardsPayload(): Record<string, unknown>;
4
+ /** Read a board without opening it. Omitted board preserves the active-board contract. */
5
+ export declare function readTargetBoard(boardId?: unknown, includeBlobs?: boolean): {
6
+ boardId: string | null;
7
+ layout: CanvasLayout;
8
+ pinnedNodeIds: Set<string>;
9
+ };
10
+ export declare const boardOperations: Operation[];
@@ -0,0 +1,2 @@
1
+ import { type Operation } from '../types.js';
2
+ export declare const exportOperations: Operation[];
@@ -0,0 +1,2 @@
1
+ import { type Operation } from '../types.js';
2
+ export declare const importOperations: Operation[];
@@ -1,3 +1,4 @@
1
+ import { type CanvasSizeAdjustment } from '../../canvas-operations.js';
1
2
  import { type Operation } from '../types.js';
2
3
  /** Legacy server.ts parseGraphPayloadData: a graph dataset must be an array of records. */
3
4
  export declare function parseGraphPayloadData(value: unknown): Array<Record<string, unknown>> | null;
@@ -21,6 +22,7 @@ export interface StreamJsonRenderResult {
21
22
  specVersion: number;
22
23
  elementCount: number;
23
24
  streamStatus: 'open' | 'closed';
25
+ sizeAdjustment?: CanvasSizeAdjustment;
24
26
  }
25
27
  /**
26
28
  * Create-or-append core for streaming json-render nodes (the SDK's
@@ -1,6 +1,7 @@
1
1
  import { type CanvasLayout, type CanvasNodeState } from '../../canvas-state.js';
2
+ import { type CanvasSizeAdjustment } from '../../canvas-operations.js';
2
3
  import { type Operation } from '../types.js';
3
- export declare const NODE_TYPES: readonly ["markdown", "status", "context", "ledger", "trace", "file", "diff", "mermaid", "image", "mcp-app", "webpage", "html", "group"];
4
+ export declare const NODE_TYPES: readonly ["markdown", "board", "status", "context", "ledger", "trace", "file", "diff", "mermaid", "image", "mcp-app", "webpage", "html", "group"];
4
5
  /** Per-type default node frame size (formerly copy-pasted ladders). */
5
6
  export declare function defaultNodeSize(type: string): {
6
7
  width: number;
@@ -30,7 +31,7 @@ export declare function agentSafeFullLayoutPayload(layout: CanvasLayout): Record
30
31
  * agents using either key (or a cached schema) work — matching the
31
32
  * external-app / web-artifact responses that already return both.
32
33
  */
33
- export declare function createdNodePayloadFromNode(node: CanvasNodeState, options?: Record<string, unknown>): Record<string, unknown>;
34
+ export declare function createdNodePayloadFromNode(node: CanvasNodeState, options?: Record<string, unknown>, extras?: Record<string, unknown>): Record<string, unknown>;
34
35
  /**
35
36
  * Create a basic (non-webpage / non-group / non-primitive) node. Union of the
36
37
  * legacy handleCanvasAddNode generic branch; the SDK passes fileMode 'path',
@@ -41,6 +42,7 @@ export declare function createBasicCanvasNode(body: Record<string, unknown>, opt
41
42
  }): {
42
43
  node: CanvasNodeState;
43
44
  needsCodeGraphRecompute: boolean;
45
+ sizeAdjustment?: CanvasSizeAdjustment;
44
46
  };
45
47
  /**
46
48
  * Build a node patch with the full HTTP superset semantics (webpage
@@ -1,2 +1,4 @@
1
1
  import { type Operation } from '../types.js';
2
+ export declare const DEFAULT_CONTEXT_BRIEF_BUDGET = 16000;
3
+ export declare const MAX_CONTEXT_BRIEF_BUDGET = 100000;
2
4
  export declare const queryOperations: Operation[];
@@ -9,7 +9,7 @@ export declare function setOperationEventEmitter(emitter: OperationEventEmitter
9
9
  * mcpapp.open, whose canvas node is created as a side-effect of `ext-app-open` —
10
10
  * use this to reject loudly instead of silently no-op'ing in a suppressed run. */
11
11
  export declare function isEmitSuppressed(): boolean;
12
- /** Run `fn` with all operation SSE emits suppressed; restores depth on finally. */
12
+ /** Suppress this call chain's per-entry frames; the batch emits its final frame afterward. */
13
13
  export declare function runWithSuppressedEmits<T>(fn: () => Promise<T>): Promise<T>;
14
14
  export interface ExecuteOperationMeta {
15
15
  /**
@@ -29,6 +29,14 @@ export interface ExecuteOperationMeta {
29
29
  * to agents only, and batch inner writes are always agent-originated.
30
30
  */
31
31
  fromWorkbench?: boolean;
32
+ /** Authorship only: true when the per-boot workbench token matched. */
33
+ humanAuthor?: boolean;
34
+ /**
35
+ * An MCP server attached to this daemon, or a host adapter, fetching on an
36
+ * agent's behalf. It records the read the agent actually made itself
37
+ * (POST /api/canvas/ax/context-reads), so this fetch is not recorded.
38
+ */
39
+ proxiedRead?: boolean;
32
40
  }
33
41
  export declare function executeOperation(name: string, rawInput: unknown, meta?: ExecuteOperationMeta): Promise<unknown>;
34
42
  export {};
@@ -45,7 +45,7 @@ export interface OperationHttpRoute {
45
45
  }
46
46
  /** Host capabilities available to MCP result formatters. */
47
47
  export interface OperationMcpToolHost {
48
- getPinnedNodeIds(): Promise<string[]>;
48
+ getPinnedNodeIds(board?: string): Promise<string[]>;
49
49
  /**
50
50
  * Invoke another registered operation over the host's transport (local or
51
51
  * HTTP) — structural subset of OperationInvoker to avoid an import cycle.
@@ -23,6 +23,7 @@
23
23
  * - POST /api/canvas/graph -> create a native graph node
24
24
  * - GET /api/canvas/json-render/view?nodeId=... -> local json-render viewer
25
25
  * - GET /api/canvas/file-bytes?nodeId=... -> raw bytes for a file node
26
+ * - GET /api/canvas/exports/<file> -> a written static board export (sandboxed)
26
27
  * - POST /api/canvas/web-artifact -> build bundled HTML artifact + optional canvas node
27
28
  * - GET /api/workbench/events -> SSE event stream
28
29
  * - GET /api/workbench/poll -> proxy-safe polling transport (same events, JSON)
@@ -37,6 +37,13 @@ declare class TraceManager {
37
37
  durationMs?: number;
38
38
  failed?: boolean;
39
39
  }): void;
40
+ /**
41
+ * The chain's last node is gone (another board was opened, or it was
42
+ * deleted): start a new chain instead of wiring edges to a missing node.
43
+ */
44
+ private dropStaleChain;
45
+ /** Forget the trace chain without touching nodes. */
46
+ resetChain(): void;
40
47
  clearTrace(): void;
41
48
  getTraceNodeCount(): number;
42
49
  private getOrigin;
@@ -1,3 +1,4 @@
1
+ import { type CanvasSizeAdjustment } from './canvas-operations.js';
1
2
  export interface WebArtifactBuildInput {
2
3
  title: string;
3
4
  appTsx: string;
@@ -41,11 +42,13 @@ export interface WebArtifactSourceContext {
41
42
  export interface WebArtifactCanvasOpenResult {
42
43
  nodeId: string;
43
44
  url: string;
45
+ sizeAdjustment: CanvasSizeAdjustment;
44
46
  }
45
47
  export interface WebArtifactCanvasBuildResult extends WebArtifactBuildOutput {
46
48
  openedInCanvas: boolean;
47
49
  nodeId?: string;
48
50
  url?: string;
51
+ sizeAdjustment?: CanvasSizeAdjustment;
49
52
  startedAt: string;
50
53
  completedAt: string;
51
54
  durationMs: number;
@@ -17,9 +17,30 @@ export interface WebpageSnapshot {
17
17
  }
18
18
  export declare function normalizeWebpageUrl(rawUrl: string): string;
19
19
  export declare function summarizeWebpageContent(data: Record<string, unknown>, maxLength?: number): string;
20
- export declare function fetchWebpageSnapshot(inputUrl: string): Promise<WebpageSnapshot>;
20
+ export type AddressScope = 'public' | 'private' | 'link-local';
21
+ /**
22
+ * Where an IP literal points. `private` covers loopback, RFC 1918, CGNAT and
23
+ * IPv6 ULA; `link-local` is kept apart because it holds cloud metadata
24
+ * (169.254.169.254) and is refused on every hop.
25
+ */
26
+ export declare function classifyAddress(address: string): AddressScope;
27
+ type ResolveHost = (hostname: string) => Promise<Array<{
28
+ address: string;
29
+ family: number;
30
+ }>>;
31
+ /**
32
+ * Refuses link-local on every hop, and a redirect that moves a public fetch
33
+ * onto a loopback or private address. A URL the caller points at a local dev
34
+ * server on purpose still loads, and may redirect within the local network.
35
+ */
36
+ export declare function checkWebpageHop(originScope: AddressScope, hopScope: AddressScope, hopUrl: string): void;
37
+ export declare function fetchWebpageSnapshot(inputUrl: string, options?: {
38
+ resolveHost?: ResolveHost;
39
+ timeoutMs?: number;
40
+ }): Promise<WebpageSnapshot>;
21
41
  export declare function getWebpageFetchErrorDetails(error: unknown): {
22
42
  message: string;
23
43
  statusCode: number | null;
24
44
  contentType: string | null;
25
45
  };
46
+ export {};
@@ -0,0 +1,3 @@
1
+ /** Per-process capability used only to distinguish workbench clicks from HTTP agents. */
2
+ export declare const workbenchToken: string;
3
+ export declare function isWorkbenchToken(value: string | null): boolean;
@@ -0,0 +1,6 @@
1
+ /** The Home category migrated 0.6 snapshots land on, so they do not bury the boards in use. */
2
+ export declare const MIGRATED_SNAPSHOT_CATEGORY = "From old snapshots";
3
+ /** Slash-separated folder paths shared by the UI, HTTP/MCP and SDK. */
4
+ export declare function normalizeBoardCategory(value: string | null): string | null;
5
+ /** Includes implicit parents, so a board in A/B can also be moved into A. */
6
+ export declare function categoryAncestors(path: string): string[];
@@ -0,0 +1,72 @@
1
+ import { z } from 'zod';
2
+ export declare const cameraSchema: z.ZodObject<{
3
+ x: z.ZodNumber;
4
+ y: z.ZodNumber;
5
+ scale: z.ZodNumber;
6
+ }, z.core.$strip>;
7
+ export declare const tourStopSchema: z.ZodObject<{
8
+ target: z.ZodUnion<readonly [z.ZodObject<{
9
+ nodeId: z.ZodString;
10
+ }, z.core.$strict>, z.ZodObject<{
11
+ viewport: z.ZodObject<{
12
+ x: z.ZodNumber;
13
+ y: z.ZodNumber;
14
+ scale: z.ZodNumber;
15
+ }, z.core.$strip>;
16
+ }, z.core.$strict>]>;
17
+ duration: z.ZodOptional<z.ZodNumber>;
18
+ easing: z.ZodOptional<z.ZodEnum<{
19
+ linear: "linear";
20
+ "ease-in-out": "ease-in-out";
21
+ "ease-out": "ease-out";
22
+ }>>;
23
+ padding: z.ZodOptional<z.ZodNumber>;
24
+ pullback: z.ZodOptional<z.ZodNumber>;
25
+ }, z.core.$strip>;
26
+ export declare const tourSchema: z.ZodObject<{
27
+ stops: z.ZodArray<z.ZodObject<{
28
+ target: z.ZodUnion<readonly [z.ZodObject<{
29
+ nodeId: z.ZodString;
30
+ }, z.core.$strict>, z.ZodObject<{
31
+ viewport: z.ZodObject<{
32
+ x: z.ZodNumber;
33
+ y: z.ZodNumber;
34
+ scale: z.ZodNumber;
35
+ }, z.core.$strip>;
36
+ }, z.core.$strict>]>;
37
+ duration: z.ZodOptional<z.ZodNumber>;
38
+ easing: z.ZodOptional<z.ZodEnum<{
39
+ linear: "linear";
40
+ "ease-in-out": "ease-in-out";
41
+ "ease-out": "ease-out";
42
+ }>>;
43
+ padding: z.ZodOptional<z.ZodNumber>;
44
+ pullback: z.ZodOptional<z.ZodNumber>;
45
+ }, z.core.$strip>>;
46
+ }, z.core.$strip>;
47
+ export type Tour = z.infer<typeof tourSchema>;
48
+ export type TourStop = z.infer<typeof tourStopSchema>;
49
+ export type Camera = z.infer<typeof cameraSchema>;
50
+ export interface TourNode {
51
+ id: string;
52
+ type: string;
53
+ position: {
54
+ x: number;
55
+ y: number;
56
+ };
57
+ size: {
58
+ width: number;
59
+ height: number;
60
+ };
61
+ }
62
+ export declare function derivedTour(nodes: TourNode[]): Tour;
63
+ export declare function resolveStop(stop: TourStop, nodes: TourNode[], width: number, height: number): Camera;
64
+ /** Interpolate world-space centres and log zoom; translations remain screen-space. */
65
+ export declare function interpolateCamera(from: Camera, to: Camera, progress: number, width: number, height: number, easing?: TourStop['easing'], pullback?: number): Camera;
66
+ /** Each segment includes its endpoint; zero-duration stops take one frame. */
67
+ export declare function segmentFrameCount(duration: number, fps: number): number;
68
+ export declare function tourFrames(tour: Tour, initial: Camera, nodes: TourNode[], width: number, height: number, fps: number): Generator<{
69
+ x: number;
70
+ y: number;
71
+ scale: number;
72
+ }, void, unknown>;
package/docs/RELEASE.md CHANGED
@@ -40,6 +40,11 @@ bun run pack:dry-run # confirms the tarball shape
40
40
  do not call `bun x playwright test` directly; it fails before test
41
41
  discovery with a `.esm.preflight` loader error (ERR-20260508-001).
42
42
 
43
+ The Playwright run includes the `pane-600` project
44
+ (`tests/e2e/reference-pane.pw.ts`): the reference surface, Chromium at
45
+ 600 px. Every node type must paint there or the release does not ship.
46
+ Embedded WebKit panes (the Copilot app) stay best-effort.
47
+
43
48
  `bun run test:e2e-cli` starts a local server in a fresh temp workspace
44
49
  and exercises the CLI flows from
45
50
  [`docs/evals/e2e-cli-coverage.md`](evals/e2e-cli-coverage.md).