pmx-canvas 0.8.2 → 0.9.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/runtime.json +1 -1
- package/.github/extensions/pmx-canvas/tools.json +601 -22
- package/CHANGELOG.md +49 -0
- package/Readme.md +131 -532
- package/dist/canvas/global.css +2724 -476
- package/dist/canvas/index.js +168 -107
- package/dist/canvas/mcp-app.html +2899 -596
- package/dist/json-render/index.js +20 -20
- package/dist/types/client/canvas/BarHint.d.ts +12 -2
- package/dist/types/client/canvas/BoardLinkDialog.d.ts +3 -1
- package/dist/types/client/canvas/BoardPinButton.d.ts +10 -0
- package/dist/types/client/canvas/BoardSwitcher.d.ts +1 -1
- package/dist/types/client/canvas/CanvasViewport.d.ts +1 -1
- package/dist/types/client/canvas/CommandBar.d.ts +3 -4
- package/dist/types/client/canvas/ConnectionBanner.d.ts +2 -1
- package/dist/types/client/canvas/ContextChip.d.ts +3 -0
- package/dist/types/client/canvas/CrossBoardReferences.d.ts +5 -0
- package/dist/types/client/canvas/EdgeLayer.d.ts +14 -3
- package/dist/types/client/canvas/EmptyState.d.ts +4 -4
- package/dist/types/client/canvas/HomeGraphView.d.ts +2 -0
- package/dist/types/client/canvas/HomeMapView.d.ts +1 -0
- package/dist/types/client/canvas/HomeReviewView.d.ts +6 -0
- package/dist/types/client/canvas/HomeView.d.ts +9 -7
- package/dist/types/client/canvas/KnowledgeDialog.d.ts +4 -0
- package/dist/types/client/canvas/LifecycleChrome.d.ts +5 -0
- package/dist/types/client/canvas/LifecycleFields.d.ts +7 -0
- package/dist/types/client/canvas/LifecyclePanel.d.ts +1 -0
- package/dist/types/client/canvas/MemoryInspector.d.ts +7 -0
- package/dist/types/client/canvas/NearPinLayer.d.ts +14 -0
- package/dist/types/client/canvas/NodeContextMark.d.ts +40 -7
- package/dist/types/client/canvas/RelationPresetsDialog.d.ts +4 -0
- package/dist/types/client/canvas/RelationsPanel.d.ts +4 -0
- package/dist/types/client/canvas/SessionPanel.d.ts +2 -0
- package/dist/types/client/canvas/canvas-area.d.ts +1 -1
- package/dist/types/client/canvas/graph-geometry.d.ts +27 -0
- package/dist/types/client/canvas/graph-model.d.ts +37 -0
- package/dist/types/client/canvas/memory-layout.d.ts +23 -0
- package/dist/types/client/canvas/use-chrome-height.d.ts +2 -0
- package/dist/types/client/canvas/use-focus-trap.d.ts +1 -0
- package/dist/types/client/canvas/use-memory-graph.d.ts +8 -0
- package/dist/types/client/canvas/use-pan-zoom.d.ts +4 -1
- package/dist/types/client/icons.d.ts +0 -10
- package/dist/types/client/nodes/AxStepControls.d.ts +1 -1
- package/dist/types/client/nodes/InlineMarkdownEditor.d.ts +4 -4
- package/dist/types/client/nodes/MarkdownNode.d.ts +5 -1
- package/dist/types/client/nodes/McpAppNode.d.ts +4 -4
- package/dist/types/client/nodes/viewer-runtime-state.d.ts +1 -1
- package/dist/types/client/state/boards-store.d.ts +81 -9
- package/dist/types/client/state/canvas-store.d.ts +14 -1
- package/dist/types/client/state/context-chip-store.d.ts +22 -0
- package/dist/types/client/state/context-status-store.d.ts +35 -0
- package/dist/types/client/state/intent-bridge.d.ts +11 -8
- package/dist/types/client/state/knowledge-store.d.ts +22 -0
- package/dist/types/client/state/near-pin-store.d.ts +44 -1
- package/dist/types/client/state/presence-store.d.ts +4 -4
- package/dist/types/client/state/presentation.d.ts +28 -0
- package/dist/types/client/state/relation-store.d.ts +10 -0
- package/dist/types/client/state/session-store.d.ts +41 -2
- package/dist/types/client/state/workspace-settings.d.ts +7 -0
- package/dist/types/client/types.d.ts +13 -1
- package/dist/types/client/utils/keyboard.d.ts +2 -0
- package/dist/types/client/utils/time-ago.d.ts +4 -0
- package/dist/types/mcp/context-uri-template.d.ts +3 -1
- package/dist/types/server/agent-presence.d.ts +10 -3
- package/dist/types/server/ax-context.d.ts +1 -1
- package/dist/types/server/canvas-db.d.ts +30 -7
- package/dist/types/server/canvas-operations.d.ts +24 -2
- package/dist/types/server/canvas-provenance.d.ts +22 -2
- package/dist/types/server/canvas-serialization.d.ts +2 -0
- package/dist/types/server/canvas-state.d.ts +93 -15
- package/dist/types/server/canvas-validation.d.ts +1 -1
- package/dist/types/server/context-brief.d.ts +94 -6
- package/dist/types/server/context-reads.d.ts +33 -7
- package/dist/types/server/edit-summary.d.ts +20 -0
- package/dist/types/server/index.d.ts +71 -10
- package/dist/types/server/knowledge-lifecycle.d.ts +221 -0
- package/dist/types/server/lifecycle-status.d.ts +10 -0
- package/dist/types/server/memory-graph.d.ts +9 -0
- package/dist/types/server/mutation-history.d.ts +2 -0
- package/dist/types/server/operations/ops/ax-shared.d.ts +1 -1
- package/dist/types/server/operations/ops/boards.d.ts +2 -1
- package/dist/types/server/operations/ops/lifecycle.d.ts +2 -0
- package/dist/types/server/operations/ops/memory-graph.d.ts +2 -0
- package/dist/types/server/operations/ops/nodes.d.ts +5 -0
- package/dist/types/server/operations/ops/query.d.ts +23 -0
- package/dist/types/server/operations/registry.d.ts +1 -0
- package/dist/types/server/placement.d.ts +7 -0
- package/dist/types/server/scope-fence.d.ts +2 -1
- package/dist/types/server/spatial-analysis.d.ts +6 -3
- package/dist/types/server/tour-control.d.ts +32 -0
- package/dist/types/server/wiki-links.d.ts +14 -0
- package/dist/types/server/workbench-auth.d.ts +2 -0
- package/dist/types/shared/agent-context.d.ts +2 -0
- package/dist/types/shared/agent-presence.d.ts +15 -12
- package/dist/types/shared/auto-arrange.d.ts +1 -0
- package/dist/types/shared/boards.d.ts +4 -4
- package/dist/types/shared/knowledge-lifecycle.d.ts +41 -0
- package/dist/types/shared/knowledge-presets.d.ts +6 -0
- package/dist/types/shared/lifecycle-status.d.ts +24 -0
- package/dist/types/shared/memory-graph.d.ts +53 -0
- package/dist/types/shared/relations.d.ts +68 -0
- package/dist/types/shared/semantic-attention.d.ts +2 -0
- package/dist/types/shared/tour.d.ts +38 -0
- package/dist/types/shared/workspace-settings.d.ts +11 -0
- package/docs/RELEASE.md +21 -3
- package/docs/adr-001-bun-only-runtime.md +7 -1
- package/docs/adr-002-shared-product-separate-runtimes.md +93 -0
- package/docs/api-reference.md +109 -0
- package/docs/ax-host-adapter-contract.md +1 -1
- package/docs/ax-state-contract.md +5 -4
- package/docs/cli.md +153 -15
- package/docs/demos/pmx-canvas-demo.mp4 +0 -0
- package/docs/design/AgentContext.dc.html +3 -3
- package/docs/design/BoardPins.dc.html +37 -22
- package/docs/design/Categories.dc.html +208 -0
- package/docs/design/CategoryEditor.dc.html +33 -0
- package/docs/design/Chrome.dc.html +52 -9
- package/docs/design/ContextChip.dc.html +224 -0
- package/docs/design/ContextChip600.dc.html +136 -0
- package/docs/design/EmptyState.dc.html +45 -0
- package/docs/design/Flows.dc.html +23 -1
- package/docs/design/HeaderMarks.dc.html +183 -0
- package/docs/design/Home.dc.html +19 -1
- package/docs/design/HomeGraph.dc.html +86 -202
- package/docs/design/HomeMap.dc.html +23 -1
- package/docs/design/HomeTeam.dc.html +32 -14
- package/docs/design/Lifecycle.dc.html +22 -0
- package/docs/design/Lifecycle600.dc.html +18 -0
- package/docs/design/LifecycleVariants.dc.html +157 -0
- package/docs/design/LinkAuthorship.dc.html +139 -0
- package/docs/design/LinksChanged.dc.html +203 -0
- package/docs/design/LinksOptions.dc.html +137 -0
- package/docs/design/LinksOptions600.dc.html +134 -0
- package/docs/design/NearPin.dc.html +9 -10
- package/docs/design/Pane600.dc.html +4 -3
- package/docs/design/Relations.dc.html +3 -2
- package/docs/design/Restore.dc.html +152 -0
- package/docs/design/SeeChange.dc.html +267 -0
- package/docs/design/Uses.dc.html +12 -6
- package/docs/design/canvas.json +146 -19
- package/docs/design.md +449 -16
- package/docs/environment.md +0 -1
- package/docs/evals/curation-effect.md +128 -0
- package/docs/http-api.md +459 -37
- package/docs/mcp.md +146 -18
- package/docs/node-types.md +58 -3
- package/docs/plans/design-gaps-2026-10-08.md +53 -0
- package/docs/plans/plan-009-tech-debt-backlog.md +379 -0
- package/docs/plans/plan-016-context-made-visible-wave-1.md +150 -5
- package/docs/plans/plan-017-knowledge-categories-and-lifecycle.md +175 -0
- package/docs/plans/plan-018-connected-memory-wave-2.md +594 -0
- package/docs/plans/plan-019-post-0.9-roadmap.md +198 -0
- package/docs/product-context-vision-2026-09.md +17 -1
- package/docs/product-vision-2026-09.md +1082 -43
- package/docs/product-vision-review-2026-09.md +13 -1
- package/docs/screenshots/workbench-live-dark.png +0 -0
- package/docs/screenshots/workbench-live-light.png +0 -0
- package/docs/sdk.md +62 -2
- package/package.json +1 -1
- package/plugins/pmx-canvas/com.github.copilot/extensions/pmx-canvas/runtime.json +1 -1
- package/plugins/pmx-canvas/plugin.json +1 -1
- package/plugins/pmx-canvas/runtime.json +1 -1
- package/plugins/pmx-canvas/tools.json +601 -22
- package/skills/pmx-canvas/SKILL.md +216 -42
- package/skills/pmx-canvas/references/full-reference.md +120 -21
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +2 -2
- package/skills/pmx-canvas/references/importing-context.md +132 -0
- package/skills/pmx-canvas/references/installing-pmx-canvas.md +6 -6
- package/skills/pmx-canvas/references/tours-and-recording.md +16 -1
- package/skills/pmx-canvas-testing/SKILL.md +20 -0
- package/src/cli/agent.ts +2 -0
- package/src/cli/commands/ax.ts +12 -0
- package/src/cli/commands/boards.ts +87 -11
- package/src/cli/commands/edges.ts +28 -0
- package/src/cli/commands/groups.ts +7 -0
- package/src/cli/commands/nodes.ts +1 -0
- package/src/cli/commands/query.ts +34 -2
- package/src/cli/commands/record.ts +199 -48
- package/src/cli/index.ts +6 -1
- package/src/client/App.tsx +177 -70
- package/src/client/canvas/AttentionHistory.tsx +0 -2
- package/src/client/canvas/BarHint.tsx +40 -2
- package/src/client/canvas/BoardCopyDialog.tsx +1 -1
- package/src/client/canvas/BoardFolderDialog.tsx +7 -7
- package/src/client/canvas/BoardLinkDialog.tsx +138 -33
- package/src/client/canvas/BoardPinButton.tsx +33 -0
- package/src/client/canvas/BoardSwitcher.tsx +26 -40
- package/src/client/canvas/CanvasNode.tsx +360 -237
- package/src/client/canvas/CanvasViewport.tsx +45 -7
- package/src/client/canvas/CommandBar.tsx +29 -23
- package/src/client/canvas/CommandPalette.tsx +5 -12
- package/src/client/canvas/ConnectionBanner.tsx +3 -3
- package/src/client/canvas/ContextChip.tsx +296 -0
- package/src/client/canvas/ContextMenu.tsx +63 -5
- package/src/client/canvas/CrossBoardReferences.tsx +60 -0
- package/src/client/canvas/EdgeLayer.tsx +339 -76
- package/src/client/canvas/EmptyState.tsx +33 -18
- package/src/client/canvas/ExpandedNodeOverlay.tsx +72 -40
- package/src/client/canvas/ExternalWriters.tsx +57 -42
- package/src/client/canvas/HomeGraphView.tsx +942 -0
- package/src/client/canvas/HomeMapView.tsx +641 -0
- package/src/client/canvas/HomeReviewView.tsx +167 -0
- package/src/client/canvas/HomeView.tsx +687 -160
- package/src/client/canvas/IntentLayer.tsx +19 -12
- package/src/client/canvas/KnowledgeDialog.tsx +488 -0
- package/src/client/canvas/LifecycleChrome.tsx +133 -0
- package/src/client/canvas/LifecycleFields.tsx +91 -0
- package/src/client/canvas/LifecyclePanel.tsx +533 -0
- package/src/client/canvas/MemoryInspector.tsx +104 -0
- package/src/client/canvas/Minimap.tsx +3 -3
- package/src/client/canvas/NearPinLayer.tsx +187 -0
- package/src/client/canvas/NodeContextMark.tsx +175 -97
- package/src/client/canvas/Presentation.tsx +23 -57
- package/src/client/canvas/RelationPresetsDialog.tsx +413 -0
- package/src/client/canvas/RelationsPanel.tsx +82 -0
- package/src/client/canvas/SelectionBar.tsx +3 -6
- package/src/client/canvas/SessionPanel.tsx +90 -50
- package/src/client/canvas/SessionReceipt.tsx +311 -39
- package/src/client/canvas/ShortcutOverlay.tsx +1 -1
- package/src/client/canvas/SnapshotPanel.tsx +27 -36
- package/src/client/canvas/ToolRail.tsx +367 -192
- package/src/client/canvas/TopBar.tsx +354 -124
- package/src/client/canvas/canvas-area.ts +10 -3
- package/src/client/canvas/graph-geometry.ts +195 -0
- package/src/client/canvas/graph-model.ts +254 -0
- package/src/client/canvas/memory-layout.ts +106 -0
- package/src/client/canvas/use-chrome-height.ts +20 -0
- package/src/client/canvas/use-focus-trap.ts +31 -5
- package/src/client/canvas/use-memory-graph.ts +58 -0
- package/src/client/canvas/use-node-drag.ts +2 -1
- package/src/client/canvas/use-pan-zoom.ts +64 -7
- package/src/client/icons.tsx +0 -63
- package/src/client/mcp-app/style.css +0 -6
- package/src/client/nodes/AxStepControls.tsx +74 -50
- package/src/client/nodes/BoardNode.tsx +5 -1
- package/src/client/nodes/ContextNode.tsx +18 -11
- package/src/client/nodes/ExtAppFrame.tsx +0 -1
- package/src/client/nodes/FileNode.tsx +46 -42
- package/src/client/nodes/HtmlNode.tsx +32 -0
- package/src/client/nodes/ImageNode.tsx +1 -1
- package/src/client/nodes/InlineFormatBar.tsx +6 -9
- package/src/client/nodes/InlineMarkdownEditor.tsx +56 -17
- package/src/client/nodes/MarkdownNode.tsx +377 -109
- package/src/client/nodes/McpAppNode.tsx +50 -20
- package/src/client/nodes/MdFormatBar.tsx +21 -18
- package/src/client/nodes/PromptNode.tsx +1 -1
- package/src/client/nodes/ResponseNode.tsx +1 -1
- package/src/client/nodes/viewer-runtime-state.ts +54 -22
- package/src/client/state/attention-bridge.ts +64 -15
- package/src/client/state/boards-store.ts +193 -39
- package/src/client/state/canvas-store.ts +99 -12
- package/src/client/state/context-chip-store.ts +70 -0
- package/src/client/state/context-status-store.ts +53 -0
- package/src/client/state/intent-bridge.ts +51 -30
- package/src/client/state/knowledge-store.ts +43 -0
- package/src/client/state/near-pin-store.ts +115 -6
- package/src/client/state/presence-store.ts +7 -10
- package/src/client/state/presentation.ts +91 -0
- package/src/client/state/relation-store.ts +81 -0
- package/src/client/state/session-store.ts +144 -18
- package/src/client/state/sse-bridge.ts +206 -29
- package/src/client/state/workspace-settings.ts +11 -0
- package/src/client/theme/global.css +2724 -476
- package/src/client/types.ts +12 -0
- package/src/client/utils/keyboard.ts +10 -0
- package/src/client/utils/time-ago.ts +14 -0
- package/src/json-render/renderer/index.tsx +31 -0
- package/src/mcp/canvas-app.ts +12 -2
- package/src/mcp/context-uri-template.ts +7 -4
- package/src/mcp/server.ts +63 -41
- package/src/mcp/workbench-app.ts +39 -6
- package/src/server/agent-presence.ts +128 -28
- package/src/server/ax-context.ts +27 -13
- package/src/server/board-export.ts +12 -1
- package/src/server/canvas-db.ts +331 -42
- package/src/server/canvas-operations.ts +195 -83
- package/src/server/canvas-provenance.ts +53 -22
- package/src/server/canvas-serialization.ts +2 -0
- package/src/server/canvas-state.ts +950 -122
- package/src/server/canvas-validation.ts +9 -2
- package/src/server/context-brief.ts +345 -38
- package/src/server/context-reads.ts +178 -30
- package/src/server/demo-state.json +355 -24
- package/src/server/edit-summary.ts +74 -0
- package/src/server/html-surface.ts +8 -1
- package/src/server/index.ts +181 -11
- package/src/server/knowledge-lifecycle.ts +304 -0
- package/src/server/lifecycle-status.ts +232 -0
- package/src/server/memory-graph.ts +166 -0
- package/src/server/mutation-history.ts +18 -6
- package/src/server/operations/composites.ts +32 -11
- package/src/server/operations/http.ts +7 -2
- package/src/server/operations/index.ts +4 -0
- package/src/server/operations/mcp.ts +26 -1
- package/src/server/operations/ops/ax-presence.ts +1 -1
- package/src/server/operations/ops/ax-read.ts +57 -6
- package/src/server/operations/ops/ax-timeline.ts +28 -2
- package/src/server/operations/ops/backup.ts +5 -3
- package/src/server/operations/ops/batch.ts +35 -4
- package/src/server/operations/ops/boards.ts +188 -47
- package/src/server/operations/ops/canvas-wire.ts +31 -1
- package/src/server/operations/ops/edges.ts +36 -2
- package/src/server/operations/ops/groups.ts +6 -1
- package/src/server/operations/ops/lifecycle.ts +262 -0
- package/src/server/operations/ops/memory-graph.ts +45 -0
- package/src/server/operations/ops/nodes.ts +107 -24
- package/src/server/operations/ops/query.ts +281 -68
- package/src/server/operations/ops/snapshots.ts +73 -1
- package/src/server/operations/ops/validate.ts +5 -1
- package/src/server/operations/ops/viewport.ts +97 -3
- package/src/server/operations/registry.ts +74 -25
- package/src/server/placement.ts +29 -0
- package/src/server/scope-fence.ts +78 -6
- package/src/server/server.ts +115 -16
- package/src/server/spatial-analysis.ts +48 -23
- package/src/server/tour-control.ts +82 -0
- package/src/server/wiki-links.ts +137 -0
- package/src/server/workbench-auth.ts +11 -0
- package/src/shared/agent-context.ts +3 -0
- package/src/shared/agent-presence.ts +15 -15
- package/src/shared/auto-arrange.ts +2 -0
- package/src/shared/boards.ts +4 -4
- package/src/shared/knowledge-lifecycle.ts +22 -0
- package/src/shared/knowledge-presets.ts +80 -0
- package/src/shared/lifecycle-status.ts +26 -0
- package/src/shared/memory-graph.ts +74 -0
- package/src/shared/relations.ts +98 -0
- package/src/shared/semantic-attention.ts +15 -1
- package/src/shared/tour.ts +23 -5
- package/src/shared/workspace-settings.ts +13 -0
- package/dist/types/client/canvas/ContextPinBar.d.ts +0 -1
- package/dist/types/client/canvas/FocusFieldLayer.d.ts +0 -1
- package/dist/types/client/canvas/kind-colors.d.ts +0 -3
- package/dist/types/server/agent-context.d.ts +0 -22
- package/src/client/canvas/ContextPinBar.tsx +0 -25
|
@@ -68,8 +68,8 @@ export interface SpatialContext {
|
|
|
68
68
|
}[];
|
|
69
69
|
annotations: SpatialAnnotationContext[];
|
|
70
70
|
}
|
|
71
|
-
/**
|
|
72
|
-
export declare function
|
|
71
|
+
/** Gap distance — how far apart two nodes are edge-to-edge (0 if overlapping) */
|
|
72
|
+
export declare function gapDistance(a: CanvasNodeState, b: CanvasNodeState): number;
|
|
73
73
|
/**
|
|
74
74
|
* Detect proximity clusters using single-linkage clustering.
|
|
75
75
|
* Two nodes are "close" if their edge-to-edge gap is within the threshold.
|
|
@@ -78,9 +78,12 @@ export declare function centerDistance(a: CanvasNodeState, b: CanvasNodeState):
|
|
|
78
78
|
*/
|
|
79
79
|
export declare function detectClusters(nodes: CanvasNodeState[], proximityThreshold?: number): SpatialCluster[];
|
|
80
80
|
/**
|
|
81
|
-
* Find the nearest unpinned nodes to each
|
|
81
|
+
* Find the nearest unpinned nodes by their edge-to-edge gap from each pin.
|
|
82
|
+
* The inclusive distance limit is in world pixels, independent of card size.
|
|
82
83
|
*/
|
|
83
84
|
export declare function findNeighborhoods(nodes: CanvasNodeState[], pinnedIds: Set<string>, maxNeighbors?: number, maxDistance?: number): SpatialContext['pinnedNeighborhoods'];
|
|
85
|
+
/** Shared lexical relevance for cards and library metadata. Scores are ranking details. */
|
|
86
|
+
export declare function searchRelevance(title: string, fields: Array<[string, number]>, query: string): number;
|
|
84
87
|
/**
|
|
85
88
|
* Full-text search across node titles and content.
|
|
86
89
|
* Returns matching nodes with relevance score.
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Driving a board tour: the shared stop cursor and eased camera moves.
|
|
3
|
+
*
|
|
4
|
+
* Navigation, not editing: nothing here records undo history, and the cursor
|
|
5
|
+
* is in-memory (like presence) — a restart or board switch starts over at the
|
|
6
|
+
* first stop. The browser animates; the server only decides WHERE to go and
|
|
7
|
+
* broadcasts it, so an agent and every presenting viewer agree on the stop.
|
|
8
|
+
*
|
|
9
|
+
* This module must never import server.ts or index.ts.
|
|
10
|
+
*/
|
|
11
|
+
import { type Camera, type Tour, type TourStop } from '../shared/tour.js';
|
|
12
|
+
export type TourStep = number | 'next' | 'previous';
|
|
13
|
+
export interface TourStepResult {
|
|
14
|
+
index: number;
|
|
15
|
+
total: number;
|
|
16
|
+
stop: TourStop;
|
|
17
|
+
}
|
|
18
|
+
export declare function currentTour(): Tour;
|
|
19
|
+
/** The stop the tour is on for the active board, or null when not touring. */
|
|
20
|
+
export declare function tourPosition(tour?: Tour): number | null;
|
|
21
|
+
/** Move the shared cursor. `next`/`previous` clamp at the ends; an explicit index must exist. */
|
|
22
|
+
export declare function goToTourStop(step: TourStep): TourStepResult;
|
|
23
|
+
export declare function exitTour(): void;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve an eased camera move and store its end camera as the board viewport
|
|
26
|
+
* (unrecorded). The size is the last window a browser reported, so this is the
|
|
27
|
+
* server's best estimate; the browser re-resolves against its real canvas area.
|
|
28
|
+
*/
|
|
29
|
+
export declare function moveCamera(input: unknown): {
|
|
30
|
+
stop: TourStop;
|
|
31
|
+
viewport: Camera;
|
|
32
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { MemoryTarget, WikiLink } from '../shared/memory-graph.js';
|
|
2
|
+
export declare function wikiReferences(content: string): string[];
|
|
3
|
+
export interface WikiBoard {
|
|
4
|
+
id: string;
|
|
5
|
+
name: string;
|
|
6
|
+
cards: Array<{
|
|
7
|
+
id: string;
|
|
8
|
+
title: string;
|
|
9
|
+
}>;
|
|
10
|
+
}
|
|
11
|
+
/** IDs win over names; title matches must be unique. Never retarget an already bound link. */
|
|
12
|
+
export declare function resolveWikiLinks(content: string, previous: WikiLink[], boards: WikiBoard[]): WikiLink[];
|
|
13
|
+
/** Only server-owned bindings may navigate; the client still sanitizes rendered HTML. */
|
|
14
|
+
export declare function renderWikiMarkdown(content: string, links: WikiLink[], exists: (target: MemoryTarget) => boolean): string;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
1
|
/** Per-process capability used only to distinguish workbench clicks from HTTP agents. */
|
|
2
2
|
export declare const workbenchToken: string;
|
|
3
3
|
export declare function isWorkbenchToken(value: string | null): boolean;
|
|
4
|
+
/** Refuse an old tab's writes after a daemon restart, without downgrading its actor. */
|
|
5
|
+
export declare function refuseStaleWorkbenchWrite(req: Request): Response | null;
|
|
@@ -5,6 +5,8 @@ export interface AgentContextNode {
|
|
|
5
5
|
kind: string;
|
|
6
6
|
title: string | null;
|
|
7
7
|
content: string | null;
|
|
8
|
+
/** Context excerpts do not serialize the card's complete incident relations. */
|
|
9
|
+
linksComplete?: false;
|
|
8
10
|
metadata?: Record<string, unknown>;
|
|
9
11
|
position?: {
|
|
10
12
|
x: number;
|
|
@@ -45,20 +45,28 @@ export interface AgentPresence {
|
|
|
45
45
|
opCount: number;
|
|
46
46
|
/**
|
|
47
47
|
* The agent's REAL context window, when its host reports it (tokens used /
|
|
48
|
-
* window size). Null when no adapter reports — the
|
|
49
|
-
* the
|
|
50
|
-
* says so.
|
|
48
|
+
* window size). Null when no adapter reports — the context chip then shows
|
|
49
|
+
* the brief's size against its budget instead.
|
|
51
50
|
*/
|
|
52
51
|
contextUsage: {
|
|
53
52
|
used: number;
|
|
54
53
|
total: number;
|
|
55
54
|
} | null;
|
|
56
55
|
lastSeenAt: string;
|
|
56
|
+
/**
|
|
57
|
+
* What this session has done since it attached (AgentContext.dc.html lens:
|
|
58
|
+
* "Claude · this session"): ids of the cards read, created, edited and
|
|
59
|
+
* pinned on the open board. Only on attached presences; counts every agent
|
|
60
|
+
* on the board, like the receipt.
|
|
61
|
+
*/
|
|
62
|
+
session?: SessionTouches;
|
|
57
63
|
}
|
|
58
|
-
export interface
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
64
|
+
export interface SessionTouches {
|
|
65
|
+
startedAt: string;
|
|
66
|
+
read: string[];
|
|
67
|
+
created: string[];
|
|
68
|
+
edited: string[];
|
|
69
|
+
pinned: string[];
|
|
62
70
|
}
|
|
63
71
|
/**
|
|
64
72
|
* One agent write, as the External Steering activity feed lists it. Derived
|
|
@@ -79,7 +87,6 @@ export interface AgentActivityEntry {
|
|
|
79
87
|
}
|
|
80
88
|
export interface AgentPresenceSnapshot {
|
|
81
89
|
presences: AgentPresence[];
|
|
82
|
-
budget: ContextBudget;
|
|
83
90
|
/** True when any presence is attached — the master gate for agent chrome. */
|
|
84
91
|
sessionActive: boolean;
|
|
85
92
|
/** Most recent agent writes, newest first (bounded by MAX_ACTIVITY_ENTRIES). */
|
|
@@ -98,8 +105,6 @@ export declare const PRESENCE_TOOLING_SETTLE_MS = 4000;
|
|
|
98
105
|
* "Thinking" chips on a silent board. */
|
|
99
106
|
export declare const PRESENCE_THINKING_SETTLE_MS: number;
|
|
100
107
|
export declare const MAX_PRESENCES = 16;
|
|
101
|
-
/** Default `budget.total` when `PMX_CANVAS_CONTEXT_BUDGET_TOKENS` is unset. */
|
|
102
|
-
export declare const CONTEXT_BUDGET_DEFAULT_TOKENS = 32000;
|
|
103
108
|
/**
|
|
104
109
|
* Source labels that name a TRANSPORT, not an agent. A write arriving under
|
|
105
110
|
* one of these while exactly one session is attached is the attached agent's
|
|
@@ -117,7 +122,5 @@ export declare const HUMAN_STARTED_SESSION_LABEL = "Agent session";
|
|
|
117
122
|
export declare function isSessionActive(presences: readonly AgentPresence[]): boolean;
|
|
118
123
|
/** Writers that are live but not attached — the External Steering mode. */
|
|
119
124
|
export declare function externalWriters(presences: readonly AgentPresence[]): AgentPresence[];
|
|
120
|
-
/** Rough token estimate for a JSON payload (chars / 4) — good enough for a meter. */
|
|
121
|
-
export declare function estimateTokens(text: string): number;
|
|
122
125
|
/** Chip label per phase — shared by the top-bar chip and the on-canvas cursor chip. */
|
|
123
126
|
export declare function agentPhaseLabel(presence: Pick<AgentPresence, 'phase' | 'detail'>): string;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
/** The Home
|
|
2
|
-
export declare const
|
|
1
|
+
/** The Home folder migrated 0.6 snapshots land on, so they do not bury the boards in use. */
|
|
2
|
+
export declare const MIGRATED_SNAPSHOT_FOLDER = "From old snapshots";
|
|
3
3
|
/** Slash-separated folder paths shared by the UI, HTTP/MCP and SDK. */
|
|
4
|
-
export declare function
|
|
4
|
+
export declare function normalizeBoardFolder(value: string | null): string | null;
|
|
5
5
|
/** Includes implicit parents, so a board in A/B can also be moved into A. */
|
|
6
|
-
export declare function
|
|
6
|
+
export declare function folderAncestors(path: string): string[];
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/** The same policy contract validates workspace writes and browser drafts. */
|
|
3
|
+
export declare const lifecycleSchema: z.ZodObject<{
|
|
4
|
+
decayType: z.ZodEnum<{
|
|
5
|
+
reality: "reality";
|
|
6
|
+
decision: "decision";
|
|
7
|
+
dependency: "dependency";
|
|
8
|
+
relevance: "relevance";
|
|
9
|
+
}>;
|
|
10
|
+
rate: z.ZodEnum<{
|
|
11
|
+
fast: "fast";
|
|
12
|
+
medium: "medium";
|
|
13
|
+
slow: "slow";
|
|
14
|
+
durable: "durable";
|
|
15
|
+
}>;
|
|
16
|
+
triggers: z.ZodArray<z.ZodString>;
|
|
17
|
+
revalidationMethod: z.ZodString;
|
|
18
|
+
cadenceDays: z.ZodOptional<z.ZodNumber>;
|
|
19
|
+
}, z.core.$strict>;
|
|
20
|
+
export declare const categorySchema: z.ZodObject<{
|
|
21
|
+
decayType: z.ZodEnum<{
|
|
22
|
+
reality: "reality";
|
|
23
|
+
decision: "decision";
|
|
24
|
+
dependency: "dependency";
|
|
25
|
+
relevance: "relevance";
|
|
26
|
+
}>;
|
|
27
|
+
rate: z.ZodEnum<{
|
|
28
|
+
fast: "fast";
|
|
29
|
+
medium: "medium";
|
|
30
|
+
slow: "slow";
|
|
31
|
+
durable: "durable";
|
|
32
|
+
}>;
|
|
33
|
+
triggers: z.ZodArray<z.ZodString>;
|
|
34
|
+
revalidationMethod: z.ZodString;
|
|
35
|
+
cadenceDays: z.ZodOptional<z.ZodNumber>;
|
|
36
|
+
id: z.ZodString;
|
|
37
|
+
name: z.ZodString;
|
|
38
|
+
glyph: z.ZodString;
|
|
39
|
+
}, z.core.$strict>;
|
|
40
|
+
export type Lifecycle = z.infer<typeof lifecycleSchema>;
|
|
41
|
+
export type KnowledgeCategory = z.infer<typeof categorySchema>;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { KnowledgeCategory } from '../server/knowledge-lifecycle.js';
|
|
2
|
+
/** Editable starter data. No runtime behavior depends on these names or ids. */
|
|
3
|
+
export declare const KNOWLEDGE_PRESETS: Record<string, {
|
|
4
|
+
categories: KnowledgeCategory[];
|
|
5
|
+
folders: Record<string, string>;
|
|
6
|
+
}>;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MemoryTarget } from './memory-graph.js';
|
|
2
|
+
export interface SourceQualification extends MemoryTarget {
|
|
3
|
+
title: string;
|
|
4
|
+
reasons: string[];
|
|
5
|
+
unavailable?: true;
|
|
6
|
+
contentRevision?: number;
|
|
7
|
+
observedRevision?: number;
|
|
8
|
+
observedAt?: string;
|
|
9
|
+
}
|
|
10
|
+
export interface LifecycleQualification {
|
|
11
|
+
retired: boolean;
|
|
12
|
+
unknown: boolean;
|
|
13
|
+
due: boolean;
|
|
14
|
+
reasons: string[];
|
|
15
|
+
changedSinceRead: boolean;
|
|
16
|
+
lastReadAt: string | null;
|
|
17
|
+
lastValidatedAt: string | null;
|
|
18
|
+
contentRevision: number;
|
|
19
|
+
contentChangedAt: string | null;
|
|
20
|
+
/** The revisions a validating reviewer must have inspected, qualified by source relation. */
|
|
21
|
+
observations: Record<string, number | null>;
|
|
22
|
+
sources: SourceQualification[];
|
|
23
|
+
relevance: 'card-pinned' | 'board-pinned' | 'not-selected';
|
|
24
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Board-qualified identities: card IDs alone are not unique across a library. */
|
|
2
|
+
export interface MemoryTarget {
|
|
3
|
+
boardId: string;
|
|
4
|
+
cardId?: string;
|
|
5
|
+
}
|
|
6
|
+
export interface WikiLink {
|
|
7
|
+
ref: string;
|
|
8
|
+
target?: MemoryTarget;
|
|
9
|
+
}
|
|
10
|
+
export declare function wikiLinksFromData(data: Record<string, unknown>): WikiLink[];
|
|
11
|
+
export declare const memoryKey: (target: MemoryTarget) => string;
|
|
12
|
+
export interface MemoryGraphNode extends MemoryTarget {
|
|
13
|
+
key: string;
|
|
14
|
+
kind: 'board' | 'card';
|
|
15
|
+
title: string;
|
|
16
|
+
summary: string;
|
|
17
|
+
folder: string | null;
|
|
18
|
+
inContext: boolean;
|
|
19
|
+
summaryOnly: true;
|
|
20
|
+
/** False when the focused view omits incident relations; cannot acknowledge all links. */
|
|
21
|
+
linksComplete?: boolean;
|
|
22
|
+
/** Card link revision captured with this projection. */
|
|
23
|
+
linksRevision?: number;
|
|
24
|
+
type?: string;
|
|
25
|
+
nodeCount?: number;
|
|
26
|
+
position?: {
|
|
27
|
+
x: number;
|
|
28
|
+
y: number;
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
export interface MemoryGraphEdge {
|
|
32
|
+
id: string;
|
|
33
|
+
from: string;
|
|
34
|
+
to: string;
|
|
35
|
+
kind: 'member' | 'portal' | 'wiki' | 'card' | 'previous';
|
|
36
|
+
relationKind?: string;
|
|
37
|
+
reason?: string;
|
|
38
|
+
label?: string;
|
|
39
|
+
type?: string;
|
|
40
|
+
source: MemoryTarget;
|
|
41
|
+
target: MemoryTarget;
|
|
42
|
+
missing: boolean;
|
|
43
|
+
}
|
|
44
|
+
export interface MemoryGraph {
|
|
45
|
+
nodes: MemoryGraphNode[];
|
|
46
|
+
edges: MemoryGraphEdge[];
|
|
47
|
+
unresolvedLinks: Array<{
|
|
48
|
+
source: MemoryTarget;
|
|
49
|
+
ref: string;
|
|
50
|
+
}>;
|
|
51
|
+
focus: string | null;
|
|
52
|
+
depth: number;
|
|
53
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const relationKindSchema: z.ZodString;
|
|
3
|
+
export declare const relationReasonSchema: z.ZodString;
|
|
4
|
+
export declare const relationDefinitionSchema: z.ZodObject<{
|
|
5
|
+
kind: z.ZodString;
|
|
6
|
+
ink: z.ZodEnum<{
|
|
7
|
+
supports: "supports";
|
|
8
|
+
contradicts: "contradicts";
|
|
9
|
+
cites: "cites";
|
|
10
|
+
derived: "derived";
|
|
11
|
+
informs: "informs";
|
|
12
|
+
related: "related";
|
|
13
|
+
}>;
|
|
14
|
+
directed: z.ZodBoolean;
|
|
15
|
+
}, z.core.$strict>;
|
|
16
|
+
export declare const relationVocabularySchema: z.ZodArray<z.ZodObject<{
|
|
17
|
+
kind: z.ZodString;
|
|
18
|
+
ink: z.ZodEnum<{
|
|
19
|
+
supports: "supports";
|
|
20
|
+
contradicts: "contradicts";
|
|
21
|
+
cites: "cites";
|
|
22
|
+
derived: "derived";
|
|
23
|
+
informs: "informs";
|
|
24
|
+
related: "related";
|
|
25
|
+
}>;
|
|
26
|
+
directed: z.ZodBoolean;
|
|
27
|
+
}, z.core.$strict>>;
|
|
28
|
+
export type RelationDefinition = z.infer<typeof relationDefinitionSchema>;
|
|
29
|
+
export declare const relationPresetSchema: z.ZodObject<{
|
|
30
|
+
id: z.ZodString;
|
|
31
|
+
name: z.ZodString;
|
|
32
|
+
vocabulary: z.ZodArray<z.ZodObject<{
|
|
33
|
+
kind: z.ZodString;
|
|
34
|
+
ink: z.ZodEnum<{
|
|
35
|
+
supports: "supports";
|
|
36
|
+
contradicts: "contradicts";
|
|
37
|
+
cites: "cites";
|
|
38
|
+
derived: "derived";
|
|
39
|
+
informs: "informs";
|
|
40
|
+
related: "related";
|
|
41
|
+
}>;
|
|
42
|
+
directed: z.ZodBoolean;
|
|
43
|
+
}, z.core.$strict>>;
|
|
44
|
+
}, z.core.$strict>;
|
|
45
|
+
export type RelationPreset = z.infer<typeof relationPresetSchema>;
|
|
46
|
+
export declare const RELATION_KINDS: RelationDefinition[];
|
|
47
|
+
export declare const RELATION_PRESETS: Record<string, RelationDefinition[]>;
|
|
48
|
+
export declare function relationPreset(vocabulary?: RelationDefinition[]): string | null;
|
|
49
|
+
export declare function relationKind(edge: {
|
|
50
|
+
kind?: string;
|
|
51
|
+
type?: string;
|
|
52
|
+
}): string;
|
|
53
|
+
/** Direction is semantic, not inferred from ink or arrow decoration. */
|
|
54
|
+
export declare function relationSourceEnd(edge: {
|
|
55
|
+
kind?: string;
|
|
56
|
+
type?: string;
|
|
57
|
+
}): 'from' | 'to' | null;
|
|
58
|
+
export declare function relationDefinition(edge: {
|
|
59
|
+
kind?: string;
|
|
60
|
+
type?: string;
|
|
61
|
+
}, vocabulary?: RelationDefinition[]): RelationDefinition;
|
|
62
|
+
/** Keep the authored label and the explanation, rather than treating a label as a kind. */
|
|
63
|
+
export declare function relationText(edge: {
|
|
64
|
+
kind?: string;
|
|
65
|
+
type?: string;
|
|
66
|
+
label?: string | null;
|
|
67
|
+
reason?: string;
|
|
68
|
+
}): string;
|
|
@@ -12,6 +12,7 @@ export interface SemanticWatchEdgeSummary {
|
|
|
12
12
|
edgeType: CanvasEdge['type'];
|
|
13
13
|
fromId: string;
|
|
14
14
|
toId: string;
|
|
15
|
+
toBoardId?: string;
|
|
15
16
|
fromTitle: string | null;
|
|
16
17
|
toTitle: string | null;
|
|
17
18
|
}
|
|
@@ -84,6 +85,7 @@ export interface SemanticAttentionSnapshot {
|
|
|
84
85
|
}
|
|
85
86
|
export declare function formatCompactWatchEvent(event: SemanticWatchEvent): string;
|
|
86
87
|
export declare class SemanticWatchReducer {
|
|
88
|
+
private currentBoardId;
|
|
87
89
|
private currentLayout;
|
|
88
90
|
private currentPins;
|
|
89
91
|
private previousSpatial;
|
|
@@ -4,9 +4,39 @@ export declare const cameraSchema: z.ZodObject<{
|
|
|
4
4
|
y: z.ZodNumber;
|
|
5
5
|
scale: z.ZodNumber;
|
|
6
6
|
}, z.core.$strip>;
|
|
7
|
+
/** A world-space box: `{ x, y }` is its top-left corner. */
|
|
8
|
+
export declare const rectSchema: z.ZodObject<{
|
|
9
|
+
x: z.ZodNumber;
|
|
10
|
+
y: z.ZodNumber;
|
|
11
|
+
width: z.ZodNumber;
|
|
12
|
+
height: z.ZodNumber;
|
|
13
|
+
}, z.core.$strip>;
|
|
14
|
+
export declare const tourTargetSchema: z.ZodUnion<readonly [z.ZodObject<{
|
|
15
|
+
nodeId: z.ZodString;
|
|
16
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
17
|
+
rect: z.ZodObject<{
|
|
18
|
+
x: z.ZodNumber;
|
|
19
|
+
y: z.ZodNumber;
|
|
20
|
+
width: z.ZodNumber;
|
|
21
|
+
height: z.ZodNumber;
|
|
22
|
+
}, z.core.$strip>;
|
|
23
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
24
|
+
viewport: z.ZodObject<{
|
|
25
|
+
x: z.ZodNumber;
|
|
26
|
+
y: z.ZodNumber;
|
|
27
|
+
scale: z.ZodNumber;
|
|
28
|
+
}, z.core.$strip>;
|
|
29
|
+
}, z.core.$strict>]>;
|
|
7
30
|
export declare const tourStopSchema: z.ZodObject<{
|
|
8
31
|
target: z.ZodUnion<readonly [z.ZodObject<{
|
|
9
32
|
nodeId: z.ZodString;
|
|
33
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
34
|
+
rect: z.ZodObject<{
|
|
35
|
+
x: z.ZodNumber;
|
|
36
|
+
y: z.ZodNumber;
|
|
37
|
+
width: z.ZodNumber;
|
|
38
|
+
height: z.ZodNumber;
|
|
39
|
+
}, z.core.$strip>;
|
|
10
40
|
}, z.core.$strict>, z.ZodObject<{
|
|
11
41
|
viewport: z.ZodObject<{
|
|
12
42
|
x: z.ZodNumber;
|
|
@@ -27,6 +57,13 @@ export declare const tourSchema: z.ZodObject<{
|
|
|
27
57
|
stops: z.ZodArray<z.ZodObject<{
|
|
28
58
|
target: z.ZodUnion<readonly [z.ZodObject<{
|
|
29
59
|
nodeId: z.ZodString;
|
|
60
|
+
}, z.core.$strict>, z.ZodObject<{
|
|
61
|
+
rect: z.ZodObject<{
|
|
62
|
+
x: z.ZodNumber;
|
|
63
|
+
y: z.ZodNumber;
|
|
64
|
+
width: z.ZodNumber;
|
|
65
|
+
height: z.ZodNumber;
|
|
66
|
+
}, z.core.$strip>;
|
|
30
67
|
}, z.core.$strict>, z.ZodObject<{
|
|
31
68
|
viewport: z.ZodObject<{
|
|
32
69
|
x: z.ZodNumber;
|
|
@@ -47,6 +84,7 @@ export declare const tourSchema: z.ZodObject<{
|
|
|
47
84
|
export type Tour = z.infer<typeof tourSchema>;
|
|
48
85
|
export type TourStop = z.infer<typeof tourStopSchema>;
|
|
49
86
|
export type Camera = z.infer<typeof cameraSchema>;
|
|
87
|
+
export type Rect = z.infer<typeof rectSchema>;
|
|
50
88
|
export interface TourNode {
|
|
51
89
|
id: string;
|
|
52
90
|
type: string;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export declare const workspaceSettingsSchema: z.ZodObject<{
|
|
3
|
+
agentSessions: z.ZodBoolean;
|
|
4
|
+
knowledgeLifecycle: z.ZodBoolean;
|
|
5
|
+
}, z.core.$strict>;
|
|
6
|
+
export type WorkspaceSettings = z.infer<typeof workspaceSettingsSchema>;
|
|
7
|
+
export declare const workspaceSettingsPatchSchema: z.ZodObject<{
|
|
8
|
+
agentSessions: z.ZodOptional<z.ZodBoolean>;
|
|
9
|
+
knowledgeLifecycle: z.ZodOptional<z.ZodBoolean>;
|
|
10
|
+
}, z.core.$strict>;
|
|
11
|
+
export declare const DEFAULT_WORKSPACE_SETTINGS: WorkspaceSettings;
|
package/docs/RELEASE.md
CHANGED
|
@@ -10,6 +10,8 @@ single source of truth for the release dance — see also
|
|
|
10
10
|
## TL;DR
|
|
11
11
|
|
|
12
12
|
1. Land all the changes you want in the release on `main` with green CI.
|
|
13
|
+
Run the tech-debt sweep (below) on everything since the last tag and fix what it finds
|
|
14
|
+
before bumping the version.
|
|
13
15
|
2. Bump `package.json` `version`.
|
|
14
16
|
Run `bun run build:plugin` to update the Agent Plugins manifest, canonical adapter runtime
|
|
15
17
|
pin, and generated plugin copies. Publish that exact npm runtime version before advertising
|
|
@@ -63,6 +65,20 @@ following it copy-pasted a broken setup.
|
|
|
63
65
|
grep -rn "pmx-canvas@0\." Readme.md docs/ # every hit must be the version you are about to ship
|
|
64
66
|
```
|
|
65
67
|
|
|
68
|
+
**Sweep for tech debt before every release.** Read `git diff <last-tag>..HEAD` for what
|
|
69
|
+
this release leaves behind, not just whether it works, and fix it before tagging rather
|
|
70
|
+
than listing it for later:
|
|
71
|
+
|
|
72
|
+
- **Orphans.** A surface removed but its data path kept: server work, env vars, protocol
|
|
73
|
+
fields, store signals, CSS, tests and docs that only served it.
|
|
74
|
+
- **Duplicates.** A second helper, constant or type doing what an existing one does;
|
|
75
|
+
parallel code paths for the same job.
|
|
76
|
+
- **Redundant work.** The same board, file or query read more than once per request; work
|
|
77
|
+
that runs on every event but whose result nobody uses.
|
|
78
|
+
- **Stand-ins.** A field or revision reused for a meaning it was not built for, where the
|
|
79
|
+
design is still open: record it in the plan with the decision it waits on.
|
|
80
|
+
- **Docs that describe what no longer exists**: `docs/`, skills, CLI help, Readme.
|
|
81
|
+
|
|
66
82
|
**If this release touches CI or the release workflows, review that as
|
|
67
83
|
release content.** A changed gate gets its first real run *on this
|
|
68
84
|
release*: `e2e-cli` once launched Playwright without installing the
|
|
@@ -245,9 +261,11 @@ with `ok: true`, the published tarball is intact end-to-end.
|
|
|
245
261
|
are workspace-local cache and must not be committed; they're gitignored
|
|
246
262
|
but still appear in `git status`. Use `git restore --staged` if they
|
|
247
263
|
sneak into a `git add -A`.
|
|
248
|
-
-
|
|
249
|
-
|
|
250
|
-
|
|
264
|
+
- **Showcase screenshots** go to Playwright's per-test output directory as
|
|
265
|
+
`screenshot.png`, leaving tracked images unchanged. To intentionally refresh
|
|
266
|
+
the README image, copy that capture to `docs/screenshot.png`, run
|
|
267
|
+
`bun run build:plugin`, and commit both the source image and
|
|
268
|
+
`plugins/pmx-canvas/assets/preview.png` together.
|
|
251
269
|
- **CHANGELOG dates**: use the actual publish date in the
|
|
252
270
|
`## [version] - YYYY-MM-DD` header, not the day you wrote the entry.
|
|
253
271
|
- **npm publish is asynchronous now**: a successful publish prints "Your
|
|
@@ -4,6 +4,12 @@
|
|
|
4
4
|
**Date:** 2026-06-12
|
|
5
5
|
**Context for:** v0.2 stability release (docs/tech-debt-assessment-2026-06.md, Phase 2)
|
|
6
6
|
|
|
7
|
+
**Scope clarified, 2026-10-15:** this decision applies to the local distribution and its
|
|
8
|
+
Bun SDK. [ADR-002](adr-002-shared-product-separate-runtimes.md) records this narrowing and the
|
|
9
|
+
[vision's separate-runtime direction](product-vision-2026-09.md#likely-repository-structure-shared-product-separate-runtimes)
|
|
10
|
+
allows runtime-neutral shared product code and distinct Sites/Cloudflare adapters. It does
|
|
11
|
+
not require a Node dual-build, compatibility shims or a cloud dependency for local use.
|
|
12
|
+
|
|
7
13
|
## Context
|
|
8
14
|
|
|
9
15
|
pmx-canvas ships as TypeScript source executed directly by Bun. `package.json` points `main`/`exports` at `src/server/index.ts`, the `bin` entry is `src/cli/index.ts` with a `#!/usr/bin/env bun` shebang, and `engines` requires `bun >= 1.4.2`. There is no compiled JS distribution; `dist/` carries only the client bundle, the json-render viewer, and type declarations.
|
|
@@ -16,7 +22,7 @@ The decisive observation: nobody integrates with pmx-canvas by importing it. Age
|
|
|
16
22
|
|
|
17
23
|
## Decision
|
|
18
24
|
|
|
19
|
-
pmx-canvas stays Bun-only for the SDK and runtime.
|
|
25
|
+
The local pmx-canvas distribution stays Bun-only for the SDK and runtime.
|
|
20
26
|
|
|
21
27
|
1. MCP (stdio) and the HTTP API are the universal integration surfaces. They are runtime-agnostic by construction: any client that can spawn a process or open a socket can use them.
|
|
22
28
|
2. No Node dual-build (ESM + CJS dist of the server/SDK) will be produced. The package continues to ship TypeScript source executed by Bun.
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
# ADR-002: Shared product core, separate runtime editions
|
|
2
|
+
|
|
3
|
+
**Status:** Accepted architectural direction; implementation remains staged
|
|
4
|
+
**Date:** 2026-10-15
|
|
5
|
+
**Context for:** Local PMX Canvas, ChatGPT Sites and the later standalone Cloudflare edition
|
|
6
|
+
**Relationship:** Narrows [ADR-001](adr-001-bun-only-runtime.md) to the local runtime and SDK; does not replace it
|
|
7
|
+
|
|
8
|
+
## Context
|
|
9
|
+
|
|
10
|
+
The [product vision](product-vision-2026-09.md#likely-repository-structure-shared-product-separate-runtimes)
|
|
11
|
+
keeps local PMX usable offline while adding hosted editions in stages. Boards, mutation
|
|
12
|
+
rules, context compilation and renderers should remain one product across those editions.
|
|
13
|
+
Sharing source code must not imply shared live state or a cloud dependency for local users.
|
|
14
|
+
|
|
15
|
+
Today's application couples product behavior to Bun, synchronous SQLite, process-wide state
|
|
16
|
+
and import-time wiring. Moving those modules into packages would not establish runtime
|
|
17
|
+
independence. Conversely, separate product forks would duplicate rules and let editions drift.
|
|
18
|
+
The architecture must separate runtime ownership without introducing distributed transactions
|
|
19
|
+
between closely related board, context and relation operations.
|
|
20
|
+
|
|
21
|
+
## Decision
|
|
22
|
+
|
|
23
|
+
1. **Keep one modular product in one repository.** Reuse product rules and contracts across
|
|
24
|
+
editions. Establish package boundaries from demonstrated reuse, not a speculative folder
|
|
25
|
+
split. Shared contracts and rules must not depend on runtime entrypoints or concrete
|
|
26
|
+
storage; remote clients must not import local execution machinery.
|
|
27
|
+
2. **Give each edition an explicit composition root.** Local, Sites and later standalone
|
|
28
|
+
Cloudflare entrypoints construct their dependencies and own startup, shutdown and recovery.
|
|
29
|
+
Importing shared code must not install global listeners or start local services.
|
|
30
|
+
3. **Keep runtime capabilities behind explicit boundaries.** Authentication supplies a caller
|
|
31
|
+
and grants to shared permission rules. Persistence, temporary session services and external
|
|
32
|
+
effects belong to runtime adapters. Files, network fetches, subprocess MCP, builds and
|
|
33
|
+
browser automation are capabilities, not assumptions of the shared core. Document unsupported
|
|
34
|
+
behavior per edition; preserve distinct iframe sandbox and host-protocol requirements.
|
|
35
|
+
4. **Keep ownership explicit.** Requests target a workspace, board and caller independently
|
|
36
|
+
of a viewer's navigation. Durable board state and audit records have different lifetimes
|
|
37
|
+
from presence, connections, timers and waits. Every supported writer follows the relevant
|
|
38
|
+
mutation policy and commit guarantees defined in the vision.
|
|
39
|
+
5. **Share three contracts:** operation requests/results, the workbench request/event/asset
|
|
40
|
+
protocol, and the editable board archive. MCP adapts product operations to supported host
|
|
41
|
+
capabilities; common registration code does not establish support for every resource,
|
|
42
|
+
subscription or embedded application on every host.
|
|
43
|
+
6. **Separate editions, not every domain into a service.** Keep board, context and relation
|
|
44
|
+
consistency together initially. A separate deployment needs a concrete security,
|
|
45
|
+
execution-lifetime, scaling or failure-isolation reason. Package boundaries alone do not
|
|
46
|
+
justify network boundaries.
|
|
47
|
+
7. **Preserve independent editions.** Local retains Bun, SQLite and offline-capable local
|
|
48
|
+
features without hosted credentials. Sites and standalone hosting own their respective
|
|
49
|
+
storage and operational integrations. Boards move through deliberate export/import copies,
|
|
50
|
+
not automatic synchronization. Local is not a thin client, and Sites is not a disposable fork.
|
|
51
|
+
|
|
52
|
+
## Consequences
|
|
53
|
+
|
|
54
|
+
- Shared fixes can reach all editions, but each runtime needs contract and lifecycle checks.
|
|
55
|
+
Host support and platform limits must be verified on the actual platform, not inferred from
|
|
56
|
+
a portable build or simulated asynchronous storage.
|
|
57
|
+
- ADR-001's rejection of a Node dual-build remains valid for the local distribution. This
|
|
58
|
+
decision permits runtime-neutral product code and hosted adapters, not compatibility shims.
|
|
59
|
+
- Policy parity does not require every local SDK method to become asynchronous. Durable
|
|
60
|
+
completion across asynchronous storage is a separate contract; any SDK API change needs
|
|
61
|
+
its own versioned decision rather than a second permanent command implementation.
|
|
62
|
+
- Exact packages, interfaces, storage mechanisms, journal schema and archive version/upgrade
|
|
63
|
+
policy remain scoped implementation decisions. This ADR does not select services or promise
|
|
64
|
+
indefinite format compatibility.
|
|
65
|
+
|
|
66
|
+
## Alternatives considered
|
|
67
|
+
|
|
68
|
+
- **Separate product forks per edition:** simpler initial porting, but duplicated permission,
|
|
69
|
+
revision and context behavior would drift. Rejected in favor of shared product rules.
|
|
70
|
+
- **Microservices for boards, context and relations:** independent deployment at the cost of
|
|
71
|
+
network failures and cross-service consistency. Rejected without a demonstrated need.
|
|
72
|
+
- **Package migration first:** creates release and import churn without proving isolation.
|
|
73
|
+
Rejected in favor of extracting a complete working slice first.
|
|
74
|
+
- **Hosted backend required by local PMX:** reduces runtime variants by sacrificing offline
|
|
75
|
+
ownership and existing local workflows. Rejected by the product vision.
|
|
76
|
+
|
|
77
|
+
## Delivery and revisit gates
|
|
78
|
+
|
|
79
|
+
Owner acceptance remains first. Curation-effect runs and reruns are deferred to
|
|
80
|
+
[plan 019](plans/plan-019-post-0.9-roadmap.md) step 6 (2026-10-19); preceding work is not
|
|
81
|
+
evaluation-gated. Release and runtime-verification gates remain unchanged. Fix demonstrated
|
|
82
|
+
defects narrowly; this ADR does not authorize a broad refactor, deployment or release.
|
|
83
|
+
|
|
84
|
+
When the second runtime needs extraction, prove one read/edit/commit/reconnect slice with a
|
|
85
|
+
browser and agent conflict, a lost-response retry, persistence failure, restart, independent
|
|
86
|
+
board navigation and an unreadable linked source. Verify isolated runtime instances and the
|
|
87
|
+
installed local offline path. Prove the slice on the target platform before expanding the port;
|
|
88
|
+
package the boundaries once they are established.
|
|
89
|
+
|
|
90
|
+
Revisit deployment boundaries when measured requirements justify separate security, scaling
|
|
91
|
+
or execution lifetimes. Revisit adapter boundaries if a verified platform constraint cannot
|
|
92
|
+
preserve the shared product guarantees. Neither trigger automatically authorizes product forks
|
|
93
|
+
or a cloud dependency for local operation; changes require a new explicit decision.
|