pmx-canvas 0.4.8 → 0.5.1
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 +154 -5
- package/.github/extensions/pmx-canvas/steering-delivery.mjs +79 -0
- package/CHANGELOG.md +156 -0
- package/Readme.md +72 -23
- package/dist/canvas/global.css +3071 -796
- package/dist/canvas/index.js +122 -104
- package/dist/json-render/index.css +1 -1
- package/dist/types/cli/agent.d.ts +1 -0
- package/dist/types/cli/commands/pump.d.ts +9 -0
- package/dist/types/client/App.d.ts +1 -1
- package/dist/types/client/canvas/AgentPresenceLayer.d.ts +11 -0
- package/dist/types/client/canvas/BarHint.d.ts +22 -0
- package/dist/types/client/canvas/CanvasNode.d.ts +5 -0
- package/dist/types/client/canvas/CanvasViewport.d.ts +4 -4
- package/dist/types/client/canvas/CommandBar.d.ts +10 -0
- package/dist/types/client/canvas/ConnectionBanner.d.ts +13 -0
- package/dist/types/client/canvas/ContextMenu.d.ts +6 -0
- package/dist/types/client/canvas/EdgeLayer.d.ts +2 -1
- package/dist/types/client/canvas/EmptyState.d.ts +11 -0
- package/dist/types/client/canvas/ExternalWriters.d.ts +5 -0
- package/dist/types/client/canvas/HumanPresenceLayer.d.ts +8 -0
- package/dist/types/client/canvas/Minimap.d.ts +12 -1
- package/dist/types/client/canvas/ScopeFenceLayer.d.ts +8 -0
- package/dist/types/client/canvas/SelectionBar.d.ts +6 -0
- package/dist/types/client/canvas/SessionPanel.d.ts +1 -0
- package/dist/types/client/canvas/SessionReceipt.d.ts +17 -0
- package/dist/types/client/canvas/TextPrompt.d.ts +25 -0
- package/dist/types/client/canvas/ToolRail.d.ts +21 -0
- package/dist/types/client/canvas/TopBar.d.ts +7 -0
- package/dist/types/client/canvas/canvas-area.d.ts +39 -0
- package/dist/types/client/canvas/create-in-view.d.ts +18 -0
- package/dist/types/client/canvas/import-files.d.ts +8 -0
- package/dist/types/client/canvas/kind-colors.d.ts +3 -0
- package/dist/types/client/canvas/use-focus-trap.d.ts +14 -0
- package/dist/types/client/canvas/use-now.d.ts +6 -0
- package/dist/types/client/icons.d.ts +11 -4
- package/dist/types/client/nodes/ExtAppFrame.d.ts +2 -0
- package/dist/types/client/nodes/GroupNode.d.ts +6 -1
- package/dist/types/client/nodes/MarkdownNode.d.ts +2 -0
- package/dist/types/client/nodes/inline-editor-commands.d.ts +3 -4
- package/dist/types/client/state/canvas-store.d.ts +49 -5
- package/dist/types/client/state/human-store.d.ts +26 -0
- package/dist/types/client/state/iframe-mode.d.ts +1 -0
- package/dist/types/client/state/intent-bridge.d.ts +37 -5
- package/dist/types/client/state/node-factory.d.ts +0 -1
- package/dist/types/client/state/presence-store.d.ts +78 -0
- package/dist/types/client/state/session-store.d.ts +176 -0
- package/dist/types/client/types.d.ts +2 -1
- package/dist/types/client/utils/platform.d.ts +2 -0
- package/dist/types/server/agent-presence.d.ts +192 -0
- package/dist/types/server/ax-gate-ttl.d.ts +6 -0
- package/dist/types/server/ax-interaction.d.ts +4 -10
- package/dist/types/server/ax-state-manager.d.ts +21 -2
- package/dist/types/server/ax-state.d.ts +49 -3
- package/dist/types/server/ax-wait.d.ts +13 -0
- package/dist/types/server/canvas-db.d.ts +9 -1
- package/dist/types/server/canvas-operations.d.ts +11 -0
- package/dist/types/server/canvas-state.d.ts +27 -13
- package/dist/types/server/canvas-validation.d.ts +0 -14
- package/dist/types/server/html-surface.d.ts +1 -1
- package/dist/types/server/human-presence.d.ts +40 -0
- package/dist/types/server/index.d.ts +29 -3
- package/dist/types/server/intent-registry.d.ts +7 -0
- package/dist/types/server/mutation-history.d.ts +15 -2
- package/dist/types/server/operations/invoker.d.ts +13 -2
- package/dist/types/server/operations/ops/ax-presence.d.ts +2 -0
- package/dist/types/server/operations/ops/human-presence.d.ts +3 -0
- package/dist/types/server/operations/registry.d.ts +11 -0
- package/dist/types/server/operations/types.d.ts +1 -1
- package/dist/types/server/scope-fence.d.ts +62 -0
- package/dist/types/server/server.d.ts +0 -12
- package/dist/types/shared/agent-presence.d.ts +130 -0
- package/dist/types/shared/approval-gates.d.ts +19 -0
- package/dist/types/shared/auto-arrange.d.ts +0 -1
- package/dist/types/shared/ax-kinds.d.ts +11 -0
- package/dist/types/shared/human-presence.d.ts +31 -0
- package/dist/types/shared/iframe-probe.d.ts +8 -0
- package/dist/types/shared/scope-fence.d.ts +21 -0
- package/docs/RELEASE.md +20 -0
- package/docs/ax-host-adapter-contract.md +30 -14
- package/docs/cli.md +37 -1
- package/docs/environment.md +3 -0
- package/docs/http-api.md +222 -5
- package/docs/mcp.md +6 -5
- package/docs/node-types.md +3 -1
- package/docs/plans/plan-009-tech-debt-backlog.md +13 -0
- package/docs/screenshot.png +0 -0
- package/docs/screenshots/multi-agent-live.png +0 -0
- package/docs/screenshots/workbench-live-dark.png +0 -0
- package/docs/screenshots/workbench-live-light.png +0 -0
- package/docs/sdk.md +1 -1
- package/package.json +4 -4
- package/skills/pmx-canvas/SKILL.md +112 -17
- package/skills/pmx-canvas/references/codex-app-adapter.md +28 -0
- package/skills/pmx-canvas/references/full-reference.md +55 -16
- package/skills/pmx-canvas/references/github-copilot-app-adapter.md +41 -24
- package/skills/pmx-canvas-orchestration/SKILL.md +56 -2
- package/skills/pmx-canvas-testing/SKILL.md +17 -0
- package/src/cli/agent.ts +1 -0
- package/src/cli/commands/copilot.ts +15 -8
- package/src/cli/commands/nodes.ts +1 -19
- package/src/cli/commands/pump.ts +263 -0
- package/src/cli/index.ts +2 -5
- package/src/cli/shared.ts +1 -1
- package/src/client/App.tsx +209 -585
- package/src/client/canvas/AgentPresenceLayer.tsx +74 -0
- package/src/client/canvas/AttentionHistory.tsx +0 -10
- package/src/client/canvas/BarHint.tsx +49 -0
- package/src/client/canvas/CanvasNode.tsx +488 -136
- package/src/client/canvas/CanvasViewport.tsx +190 -94
- package/src/client/canvas/CommandBar.tsx +140 -0
- package/src/client/canvas/CommandPalette.tsx +133 -58
- package/src/client/canvas/ConnectionBanner.tsx +65 -0
- package/src/client/canvas/ContextMenu.tsx +88 -27
- package/src/client/canvas/ContextPinBar.tsx +2 -2
- package/src/client/canvas/EdgeLayer.tsx +121 -38
- package/src/client/canvas/EmptyState.tsx +93 -0
- package/src/client/canvas/ExpandedNodeOverlay.tsx +64 -118
- package/src/client/canvas/ExternalWriters.tsx +308 -0
- package/src/client/canvas/FocusFieldLayer.tsx +12 -1
- package/src/client/canvas/HumanPresenceLayer.tsx +45 -0
- package/src/client/canvas/IntentLayer.tsx +1 -1
- package/src/client/canvas/Minimap.tsx +117 -190
- package/src/client/canvas/ScopeFenceLayer.tsx +38 -0
- package/src/client/canvas/SelectionBar.tsx +175 -23
- package/src/client/canvas/SessionPanel.tsx +481 -0
- package/src/client/canvas/SessionReceipt.tsx +141 -0
- package/src/client/canvas/ShortcutOverlay.tsx +21 -6
- package/src/client/canvas/SnapshotPanel.tsx +166 -80
- package/src/client/canvas/TextPrompt.tsx +128 -0
- package/src/client/canvas/ToolRail.tsx +447 -0
- package/src/client/canvas/TopBar.tsx +308 -0
- package/src/client/canvas/auto-fit.ts +1 -5
- package/src/client/canvas/canvas-area.ts +74 -0
- package/src/client/canvas/create-in-view.ts +48 -0
- package/src/client/canvas/import-files.ts +64 -0
- package/src/client/canvas/kind-colors.ts +22 -0
- package/src/client/canvas/snap-guides.ts +1 -1
- package/src/client/canvas/use-focus-trap.ts +54 -0
- package/src/client/canvas/use-now.ts +17 -0
- package/src/client/canvas/use-pan-zoom.ts +13 -2
- package/src/client/icons.tsx +57 -18
- package/src/client/nodes/ExtAppFrame.tsx +86 -20
- package/src/client/nodes/GroupNode.tsx +9 -28
- package/src/client/nodes/InlineFormatBar.tsx +4 -3
- package/src/client/nodes/InlineMarkdownEditor.tsx +27 -0
- package/src/client/nodes/MarkdownNode.tsx +59 -24
- package/src/client/nodes/MdFormatBar.tsx +2 -4
- package/src/client/nodes/inline-editor-commands.ts +17 -6
- package/src/client/nodes/use-surface-frame.ts +3 -1
- package/src/client/state/attention-bridge.ts +3 -0
- package/src/client/state/canvas-store.ts +285 -90
- package/src/client/state/human-store.ts +175 -0
- package/src/client/state/iframe-mode.ts +33 -9
- package/src/client/state/intent-bridge.ts +75 -13
- package/src/client/state/node-factory.ts +2 -8
- package/src/client/state/presence-store.ts +168 -0
- package/src/client/state/session-store.ts +419 -0
- package/src/client/state/sse-bridge.ts +93 -30
- package/src/client/theme/global.css +3071 -796
- package/src/client/types.ts +3 -1
- package/src/client/utils/platform.ts +6 -1
- package/src/mcp/canvas-access.ts +2 -2
- package/src/server/agent-presence.ts +755 -0
- package/src/server/ax-context.ts +45 -0
- package/src/server/ax-gate-ttl.ts +61 -0
- package/src/server/ax-interaction.ts +29 -1
- package/src/server/ax-state-manager.ts +78 -6
- package/src/server/ax-state.ts +82 -15
- package/src/server/ax-wait.ts +33 -0
- package/src/server/canvas-db.ts +103 -33
- package/src/server/canvas-operations.ts +58 -14
- package/src/server/canvas-state.ts +131 -58
- package/src/server/canvas-validation.ts +3 -53
- package/src/server/demo-state.json +2 -70
- package/src/server/html-surface.ts +11 -2
- package/src/server/human-presence.ts +160 -0
- package/src/server/index.ts +111 -6
- package/src/server/intent-registry.ts +13 -0
- package/src/server/mutation-history.ts +47 -2
- package/src/server/operations/composites.ts +6 -3
- package/src/server/operations/http.ts +10 -1
- package/src/server/operations/index.ts +4 -0
- package/src/server/operations/invoker.ts +33 -6
- package/src/server/operations/ops/ax-presence.ts +62 -0
- package/src/server/operations/ops/ax-read.ts +8 -0
- package/src/server/operations/ops/ax-state.ts +106 -1
- package/src/server/operations/ops/ax-timeline.ts +54 -5
- package/src/server/operations/ops/ax-work.ts +46 -0
- package/src/server/operations/ops/batch.ts +3 -1
- package/src/server/operations/ops/edges.ts +88 -2
- package/src/server/operations/ops/groups.ts +4 -3
- package/src/server/operations/ops/human-presence.ts +35 -0
- package/src/server/operations/ops/json-render.ts +11 -1
- package/src/server/operations/ops/nodes.ts +77 -16
- package/src/server/operations/ops/query.ts +1 -0
- package/src/server/operations/ops/snapshots.ts +7 -4
- package/src/server/operations/registry.ts +196 -1
- package/src/server/operations/types.ts +1 -1
- package/src/server/scope-fence.ts +207 -0
- package/src/server/server.ts +177 -79
- package/src/server/trace-manager.ts +0 -2
- package/src/server/web-artifacts.ts +0 -1
- package/src/shared/agent-presence.ts +162 -0
- package/src/shared/approval-gates.ts +35 -0
- package/src/shared/auto-arrange.ts +121 -13
- package/src/shared/ax-kinds.ts +23 -0
- package/src/shared/human-presence.ts +30 -0
- package/src/shared/iframe-probe.ts +8 -0
- package/src/shared/scope-fence.ts +31 -0
- package/dist/types/client/canvas/DockedNode.d.ts +0 -4
- package/src/client/canvas/DockedNode.tsx +0 -165
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Session receipt (rail-chrome-v2 phase 5, design item 2): a dismissible card
|
|
3
|
+
* at the canvas region's top-right after a session ends — what the session did
|
|
4
|
+
* (items / done / vetoed), the pre-session snapshot (taken at attach, so View
|
|
5
|
+
* diff shows the session's changes and a restore undoes them), and History
|
|
6
|
+
* (the snapshots panel). Client-side state, cleared on dismiss.
|
|
7
|
+
*/
|
|
8
|
+
export interface DiffSummary {
|
|
9
|
+
added: number;
|
|
10
|
+
removed: number;
|
|
11
|
+
modified: number;
|
|
12
|
+
}
|
|
13
|
+
/** The wire shape is SnapshotDiffResult (addedNodes/removedNodes/modifiedNodes/addedEdges/removedEdges). */
|
|
14
|
+
export declare function summarizeDiff(diff: unknown): DiffSummary | null;
|
|
15
|
+
export declare function SessionReceipt({ onOpenSnapshots }: {
|
|
16
|
+
onOpenSnapshots: () => void;
|
|
17
|
+
}): import("preact/src").JSX.Element | null;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-canvas replacement for `window.prompt`, which embedded browser panes
|
|
3
|
+
* silently no-op (a Shift+F that "does nothing") and no test can drive. One
|
|
4
|
+
* request at a time; a new ask cancels the previous one.
|
|
5
|
+
*/
|
|
6
|
+
interface TextPromptRequest {
|
|
7
|
+
title: string;
|
|
8
|
+
placeholder: string;
|
|
9
|
+
/** Prefilled (and pre-selected) value — edit flows start from the current text. */
|
|
10
|
+
initial: string;
|
|
11
|
+
/** Submitting an empty field resolves '' instead of null — "clear the value" flows. */
|
|
12
|
+
allowEmpty: boolean;
|
|
13
|
+
confirm: string;
|
|
14
|
+
/** Bumped per ask so consecutive requests get a FRESH input element. */
|
|
15
|
+
seq: number;
|
|
16
|
+
resolve: (value: string | null) => void;
|
|
17
|
+
}
|
|
18
|
+
export declare const textPromptRequest: import("@preact/signals-core").Signal<TextPromptRequest | null>;
|
|
19
|
+
export declare function askText(title: string, placeholder: string, opts?: {
|
|
20
|
+
initial?: string;
|
|
21
|
+
allowEmpty?: boolean;
|
|
22
|
+
confirm?: string;
|
|
23
|
+
}): Promise<string | null>;
|
|
24
|
+
export declare function TextPrompt(): import("preact/src").JSX.Element | null;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AnnotationTool } from '../types';
|
|
2
|
+
/** Prompt-driven creates for node kinds that need a source (url / path). */
|
|
3
|
+
export declare function promptedCreate(kind: 'image' | 'file' | 'webpage'): void;
|
|
4
|
+
/**
|
|
5
|
+
* The persistent 52px left tool rail (rail-chrome-v2 phase 1): brand → tools →
|
|
6
|
+
* node palette → utilities. Every button shows a hover/focus tooltip with its
|
|
7
|
+
* shortcut (`RailButton`) — the rail is the shortcut discovery surface.
|
|
8
|
+
*/
|
|
9
|
+
export declare function ToolRail({ minimapVisible, onToggleMinimap, snapshotOpen, onToggleSnapshot, snapshotBtnRef, onOpenPalette, onOpenShortcuts, annotationTool, onSetAnnotationTool, }: {
|
|
10
|
+
minimapVisible: boolean;
|
|
11
|
+
onToggleMinimap: () => void;
|
|
12
|
+
snapshotOpen: boolean;
|
|
13
|
+
onToggleSnapshot: () => void;
|
|
14
|
+
snapshotBtnRef: {
|
|
15
|
+
current: HTMLButtonElement | null;
|
|
16
|
+
};
|
|
17
|
+
onOpenPalette: () => void;
|
|
18
|
+
onOpenShortcuts: () => void;
|
|
19
|
+
annotationTool: AnnotationTool;
|
|
20
|
+
onSetAnnotationTool: (tool: AnnotationTool) => void;
|
|
21
|
+
}): import("preact/src").JSX.Element;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The slim 44px top bar (rail-chrome-v2 phase 1): connection state, board
|
|
3
|
+
* identity on the left, view controls on the right. `overflow:hidden` +
|
|
4
|
+
* `min-width:0` discipline throughout — the title ellipsizes, meta collapses
|
|
5
|
+
* below 1180px, and nothing ever wraps to a second row.
|
|
6
|
+
*/
|
|
7
|
+
export declare function TopBar(): import("preact").JSX.Element;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The canvas region's box in screen coordinates. With the rail + top-bar shell
|
|
3
|
+
* the canvas no longer spans the window, so every "centre of the view" and
|
|
4
|
+
* "how big is the view" computation must use this region — anchoring zoom at
|
|
5
|
+
* `window.innerWidth / 2` would drift the board toward the rail on every step,
|
|
6
|
+
* and reporting the window to the server makes an agent `fit` compute a scale
|
|
7
|
+
* that hides nodes under the chrome.
|
|
8
|
+
*
|
|
9
|
+
* The shell registers its canvas-region element on mount; everything else asks
|
|
10
|
+
* for the rect. The window fallback keeps unit tests and any chromeless embed
|
|
11
|
+
* working unchanged.
|
|
12
|
+
*/
|
|
13
|
+
export interface CanvasAreaRect {
|
|
14
|
+
left: number;
|
|
15
|
+
top: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function registerCanvasArea(el: HTMLElement | null): void;
|
|
20
|
+
export declare function canvasArea(): CanvasAreaRect;
|
|
21
|
+
/** Screen-space centre of the canvas region — the anchor for centred zoom/focus. */
|
|
22
|
+
export declare function canvasAreaCenter(): {
|
|
23
|
+
x: number;
|
|
24
|
+
y: number;
|
|
25
|
+
};
|
|
26
|
+
export interface CanvasFitInsets {
|
|
27
|
+
top: number;
|
|
28
|
+
right: number;
|
|
29
|
+
bottom: number;
|
|
30
|
+
left: number;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Screen-space insets Fit must reserve for the floating chrome that overlays
|
|
34
|
+
* the canvas region: the bottom command bar (whose pinned-chip row grows it)
|
|
35
|
+
* and the bottom-right minimap. Measured from the live elements — fit's old
|
|
36
|
+
* world-space padding shrank with the fit zoom and parked nodes underneath
|
|
37
|
+
* both (0.5.0 Amp report, finding A; architecture rule 9's trap).
|
|
38
|
+
*/
|
|
39
|
+
export declare function canvasFitInsets(): CanvasFitInsets;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A human create from the rail, keyboard, palette, or empty state lands
|
|
3
|
+
* centred in the CURRENT viewport — where the human is looking — instead of
|
|
4
|
+
* at the server's board-relative auto-placement, which on a busy board can
|
|
5
|
+
* be far off-screen (the rail's Group landed out of view). Explicit x/y win.
|
|
6
|
+
*/
|
|
7
|
+
export declare function createNodeInView(opts: {
|
|
8
|
+
type: string;
|
|
9
|
+
title?: string;
|
|
10
|
+
content?: string;
|
|
11
|
+
x?: number;
|
|
12
|
+
y?: number;
|
|
13
|
+
width?: number;
|
|
14
|
+
height?: number;
|
|
15
|
+
}): Promise<{
|
|
16
|
+
ok: boolean;
|
|
17
|
+
id?: string;
|
|
18
|
+
}>;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export declare function nodeTypeFromFilename(name: string): 'image' | 'markdown' | 'file';
|
|
2
|
+
/**
|
|
3
|
+
* Turn local files into nodes laid out in a grid around a world point — the
|
|
4
|
+
* one implementation behind the viewport's drop zone and the empty state's
|
|
5
|
+
* file picker. Images become image nodes (data URI), markdown becomes
|
|
6
|
+
* markdown, everything else a file node with the text inlined.
|
|
7
|
+
*/
|
|
8
|
+
export declare function importFiles(files: File[], baseWx: number, baseWy: number): Promise<void>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Focus trap for modal overlays (rail-chrome-v2 item 18): while `active`, Tab
|
|
3
|
+
* cycles inside `ref`, the first focusable takes focus on open unless
|
|
4
|
+
* `initial` names one, and the element focused before the overlay opened gets
|
|
5
|
+
* focus back on close.
|
|
6
|
+
*/
|
|
7
|
+
export declare function useFocusTrap(ref: {
|
|
8
|
+
current: HTMLElement | null;
|
|
9
|
+
}, active: boolean, options?: {
|
|
10
|
+
initial?: {
|
|
11
|
+
current: HTMLElement | null;
|
|
12
|
+
};
|
|
13
|
+
restoreTo?: () => HTMLElement | null;
|
|
14
|
+
}): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A ticking "now" for countdowns and relative ages. `intervalMs` 0 stops the
|
|
3
|
+
* ticker (the value still reads as the mount time) — pass 0 while the surface
|
|
4
|
+
* that needs it is hidden so an idle page runs no timers.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useNow(intervalMs?: number): number;
|
|
@@ -5,8 +5,6 @@ interface IconProps {
|
|
|
5
5
|
}
|
|
6
6
|
/** Expand-arrows — fit all nodes */
|
|
7
7
|
export declare function IconFitAll(p: IconProps): JSX.Element;
|
|
8
|
-
/** Framed crosshair — reset view 1:1 */
|
|
9
|
-
export declare function IconResetView(p: IconProps): JSX.Element;
|
|
10
8
|
/** Magnifier with + */
|
|
11
9
|
export declare function IconZoomIn(p: IconProps): JSX.Element;
|
|
12
10
|
/** Magnifier with - */
|
|
@@ -35,13 +33,22 @@ export declare function IconClearTrace(p: IconProps): JSX.Element;
|
|
|
35
33
|
export declare function IconSearch(p: IconProps): JSX.Element;
|
|
36
34
|
/** Keyboard — shortcuts */
|
|
37
35
|
export declare function IconShortcuts(p: IconProps): JSX.Element;
|
|
38
|
-
/**
|
|
39
|
-
export declare function
|
|
36
|
+
/** Speech bubble — steer the agent (command bar composer). */
|
|
37
|
+
export declare function IconSteer(p: IconProps): JSX.Element;
|
|
40
38
|
/** Framed pin — context pinning. */
|
|
41
39
|
export declare function IconPin(p: IconProps): JSX.Element;
|
|
42
40
|
/** Focus Field — PMX Canvas brand mark (concentric rounded squares → lit core). */
|
|
43
41
|
export declare function IconLogo({ size, class: className }: IconProps): JSX.Element;
|
|
44
42
|
/** Framed document with lines — markdown */
|
|
43
|
+
export declare function IconCursorTool({ size }: {
|
|
44
|
+
size?: number;
|
|
45
|
+
}): JSX.Element;
|
|
46
|
+
export declare function IconHandTool({ size }: {
|
|
47
|
+
size?: number;
|
|
48
|
+
}): JSX.Element;
|
|
49
|
+
export declare function IconNodeHtml({ size }: {
|
|
50
|
+
size?: number;
|
|
51
|
+
}): JSX.Element;
|
|
45
52
|
export declare function IconNodeMarkdown(p: IconProps): JSX.Element;
|
|
46
53
|
/** Framed prompt with chevron and reply tail — prompt */
|
|
47
54
|
export declare function IconNodePrompt(p: IconProps): JSX.Element;
|
|
@@ -3,6 +3,8 @@ import { AppBridge } from '@modelcontextprotocol/ext-apps/app-bridge';
|
|
|
3
3
|
import type { CanvasNodeState } from '../types';
|
|
4
4
|
type ExtAppBridgeNotifications = Pick<AppBridge, 'sendToolInput' | 'sendToolResult'>;
|
|
5
5
|
type DisplayMode = 'inline' | 'fullscreen' | 'pip';
|
|
6
|
+
/** Paint probe outcome: only a content-carrying tick counts as painted. */
|
|
7
|
+
export type PaintProbeVerdict = 'content-verified' | 'tick-no-content' | 'timeout';
|
|
6
8
|
interface ExtAppHostDimensionsTarget {
|
|
7
9
|
clientWidth?: number;
|
|
8
10
|
clientHeight?: number;
|
|
@@ -2,5 +2,10 @@ import type { CanvasNodeState } from '../types';
|
|
|
2
2
|
interface GroupNodeProps {
|
|
3
3
|
node: CanvasNodeState;
|
|
4
4
|
}
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Group frame body (rail-chrome-v2 groups v2): the children live in the world
|
|
7
|
+
* layer and the name/count/actions sit on the frame edge, so the body is just
|
|
8
|
+
* the wash — plus a hint while the group is empty.
|
|
9
|
+
*/
|
|
10
|
+
export declare function GroupNode({ node }: GroupNodeProps): import("preact/src").JSX.Element | null;
|
|
6
11
|
export {};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import type { JSX } from 'preact';
|
|
2
2
|
import type { CanvasNodeState } from '../types';
|
|
3
|
+
/** Flip the index-th GFM task marker in the source (document order matches the rendered boxes). */
|
|
4
|
+
export declare function toggleTaskMarker(markdown: string, index: number): string;
|
|
3
5
|
export declare function MarkdownNode({ node, expanded }: {
|
|
4
6
|
node: CanvasNodeState;
|
|
5
7
|
expanded?: boolean;
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
/** Shared contentEditable command helpers used by both the inline editor
|
|
2
|
-
* and its floating toolbar. Kept in a module that neither component
|
|
3
|
-
* depends on transitively so we don't get a circular import. */
|
|
4
1
|
/** Prompt for a URL and insert it as a link on the current selection.
|
|
5
2
|
* Rejects `javascript:` and `data:` schemes so a link can't execute script
|
|
6
|
-
* when clicked.
|
|
3
|
+
* when clicked. Uses the in-canvas prompt (`window.prompt` is a silent no-op
|
|
4
|
+
* in embedded panes); the selection is saved before the dialog takes focus
|
|
5
|
+
* and restored before inserting. */
|
|
7
6
|
export declare function promptAndInsertLink(): void;
|
|
8
7
|
/** Wrap the current non-empty selection in an inline `<code>` element and
|
|
9
8
|
* place the caret immediately after the new element. No-op on collapsed
|
|
@@ -4,8 +4,17 @@ export declare const nodes: import("@preact/signals-core").Signal<Map<string, Ca
|
|
|
4
4
|
export declare const edges: import("@preact/signals-core").Signal<Map<string, CanvasEdge>>;
|
|
5
5
|
export declare const annotations: import("@preact/signals-core").Signal<Map<string, CanvasAnnotation>>;
|
|
6
6
|
export declare const activeNodeId: import("@preact/signals-core").Signal<string | null>;
|
|
7
|
+
/** Click-selected edge — Delete removes it, Escape/background click clears it. */
|
|
8
|
+
export declare const selectedEdgeId: import("@preact/signals-core").Signal<string | null>;
|
|
7
9
|
export declare const connectionStatus: import("@preact/signals-core").Signal<ConnectionStatus>;
|
|
8
10
|
export declare const workbenchConnectionEpoch: import("@preact/signals-core").Signal<number>;
|
|
11
|
+
/**
|
|
12
|
+
* Degraded-connection detail (rail-chrome-v2 phase 7, design item 14):
|
|
13
|
+
* the reconnect attempt and the delay before the next try while the stream is
|
|
14
|
+
* down. Both reset to 0 when a transport is back.
|
|
15
|
+
*/
|
|
16
|
+
export declare const reconnectAttempt: import("@preact/signals-core").Signal<number>;
|
|
17
|
+
export declare const reconnectDelay: import("@preact/signals-core").Signal<number>;
|
|
9
18
|
export declare const sessionId: import("@preact/signals-core").Signal<string>;
|
|
10
19
|
export declare const traceEnabled: import("@preact/signals-core").Signal<boolean>;
|
|
11
20
|
export declare const canvasTheme: import("@preact/signals-core").Signal<string>;
|
|
@@ -22,21 +31,60 @@ export declare const draggingEdge: import("@preact/signals-core").Signal<{
|
|
|
22
31
|
fromY: number;
|
|
23
32
|
cursorX: number;
|
|
24
33
|
cursorY: number;
|
|
34
|
+
/** Node under the cursor that would receive the edge on release (item 15). */
|
|
35
|
+
targetId?: string | null;
|
|
36
|
+
/** L was pressed during the drag: ask for a label on release. */
|
|
37
|
+
withLabel?: boolean;
|
|
25
38
|
} | null>;
|
|
26
39
|
export declare const searchHighlightIds: import("@preact/signals-core").Signal<Set<string> | null>;
|
|
27
40
|
export declare const selectedNodeIds: import("@preact/signals-core").Signal<Set<string>>;
|
|
28
41
|
export declare const contextPinnedNodeIds: import("@preact/signals-core").Signal<Set<string>>;
|
|
42
|
+
/** `connect` (rail-chrome-v2 item 15): drag from anywhere on a node to draw an edge. */
|
|
43
|
+
export type CanvasTool = 'select' | 'pan' | 'connect';
|
|
44
|
+
export declare const canvasTool: import("@preact/signals-core").Signal<CanvasTool>;
|
|
45
|
+
/** Held-Space temporary pan — same semantics as the pan tool while held. */
|
|
46
|
+
export declare const spacePanHeld: import("@preact/signals-core").Signal<boolean>;
|
|
47
|
+
export declare function isPanModeActive(): boolean;
|
|
29
48
|
export declare function getNeighborNodeIds(nodeId: string | null, edgeMap: Map<string, CanvasEdge>): Set<string>;
|
|
30
49
|
export declare const activeNeighborNodeIds: import("@preact/signals-core").ReadonlySignal<Set<string>>;
|
|
31
50
|
export declare function toggleSelected(id: string): void;
|
|
32
51
|
export declare function selectNodes(ids: string[]): void;
|
|
33
52
|
export declare function clearSelection(): void;
|
|
53
|
+
/**
|
|
54
|
+
* Membership feedback while a node is being dragged: the group it would join
|
|
55
|
+
* on release (`add`), or the parent it would leave (`remove`). Membership
|
|
56
|
+
* changes ONLY on release while this is set — never silently by geometry.
|
|
57
|
+
* Esc during the drag clears it and keeps it cleared for that drag.
|
|
58
|
+
*/
|
|
59
|
+
export declare const dragDropTarget: import("@preact/signals-core").Signal<{
|
|
60
|
+
nodeId: string;
|
|
61
|
+
groupId: string;
|
|
62
|
+
mode: "add" | "remove";
|
|
63
|
+
} | null>;
|
|
64
|
+
export declare function suppressDropForDrag(): void;
|
|
65
|
+
export declare function endDropTracking(): void;
|
|
66
|
+
/**
|
|
67
|
+
* Called on every drag move of `nodeId`: updates the drop target and grows a
|
|
68
|
+
* fit-mode parent frame live so a child dragged against it never clips
|
|
69
|
+
* (the server re-fits on persist; shrinking happens there).
|
|
70
|
+
*/
|
|
71
|
+
export declare function trackDragMembership(nodeId: string): void;
|
|
72
|
+
/** Children of collapsed groups are hidden; edges to them point at the chip. */
|
|
73
|
+
export declare const hiddenByCollapsedGroup: import("@preact/signals-core").ReadonlySignal<Map<string, string>>;
|
|
74
|
+
/** The node that stands in for `id` on the canvas: itself, or its collapsed group's chip. */
|
|
75
|
+
export declare function visibleNodeFor(id: string): CanvasNodeState | undefined;
|
|
76
|
+
/** Collapsed groups render as a chip; children keep their positions for restore. */
|
|
77
|
+
export declare function groupsOfSelection(): string[];
|
|
78
|
+
export declare function alignSelection(edge: 'left' | 'top'): void;
|
|
79
|
+
/** Even horizontal gaps between the selected nodes, first and last staying put. */
|
|
80
|
+
export declare function distributeSelection(): void;
|
|
81
|
+
/** Grid the selection in reading order from its own top-left corner. */
|
|
82
|
+
export declare function arrangeSelection(gap?: number): void;
|
|
34
83
|
export declare function getSelectedNodes(): CanvasNodeState[];
|
|
35
84
|
export declare function toggleContextPin(id: string): void;
|
|
36
85
|
export declare function addContextPins(ids: string[]): void;
|
|
37
86
|
export declare function clearContextPins(): void;
|
|
38
87
|
export declare function replaceContextPinsFromServer(ids: string[]): void;
|
|
39
|
-
export declare function getContextPinnedNodes(): CanvasNodeState[];
|
|
40
88
|
export declare function addNode(node: CanvasNodeState): void;
|
|
41
89
|
export declare function updateNode(id: string, patch: Partial<CanvasNodeState>): void;
|
|
42
90
|
export declare function updateNodeData(id: string, dataPatch: Record<string, unknown>): void;
|
|
@@ -65,10 +113,6 @@ export declare function resizeNode(id: string, size: {
|
|
|
65
113
|
}): void;
|
|
66
114
|
export declare function bringToFront(id: string): void;
|
|
67
115
|
export declare function toggleCollapsed(id: string): void;
|
|
68
|
-
export declare function collapseDockedContextNodes(): void;
|
|
69
|
-
export declare const hasOpenDockedContextPanel: import("@preact/signals-core").ReadonlySignal<boolean>;
|
|
70
|
-
export declare function dockNode(id: string, position: 'left' | 'right'): void;
|
|
71
|
-
export declare function undockNode(id: string): void;
|
|
72
116
|
export declare function setViewport(v: Partial<ViewportState>): void;
|
|
73
117
|
export declare function replaceViewport(next: ViewportState): void;
|
|
74
118
|
export declare function commitViewport(next: ViewportState): void;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { type HumanPresence, type HumanPresenceSnapshot } from '../../shared/human-presence.js';
|
|
2
|
+
export declare const humanClientId: string;
|
|
3
|
+
export declare const humanName: import("@preact/signals-core").Signal<string>;
|
|
4
|
+
export declare const humans: import("@preact/signals-core").Signal<HumanPresence[]>;
|
|
5
|
+
export declare const otherHumans: import("@preact/signals-core").ReadonlySignal<HumanPresence[]>;
|
|
6
|
+
/** Nodes a human took over mid-edit → that human's name, shown as the yield pill for a moment. */
|
|
7
|
+
export declare const yieldedNodes: import("@preact/signals-core").Signal<Map<string, string>>;
|
|
8
|
+
export declare function applyHumanSnapshot(snapshot: Partial<HumanPresenceSnapshot> | null | undefined): void;
|
|
9
|
+
/** Report the pointer in world coordinates (throttled); null when it leaves the canvas. */
|
|
10
|
+
export declare function reportHumanCursor(cursor: {
|
|
11
|
+
x: number;
|
|
12
|
+
y: number;
|
|
13
|
+
} | null): void;
|
|
14
|
+
/** Hold / release a node (drag, rename): the edit lock agents must respect. */
|
|
15
|
+
export declare function reportHumanGrab(nodeId: string | null): void;
|
|
16
|
+
export declare function markYielded(nodeId: string, name: string): void;
|
|
17
|
+
/**
|
|
18
|
+
* User wins (item 6): the human grabbed a node the agent is mid-edit on. Every
|
|
19
|
+
* explicit intent targeting it is vetoed through the normal veto path (the
|
|
20
|
+
* agent hears it as steering), a Yield entry lands in the timeline, and the
|
|
21
|
+
* node wears a "took over — agent yielded" pill for a moment.
|
|
22
|
+
*/
|
|
23
|
+
export declare function takeOverNode(nodeId: string, title: string): void;
|
|
24
|
+
/** Announce this tab and keep it alive; renews a held grab. Call once per connection. */
|
|
25
|
+
export declare function startHumanPresence(): () => void;
|
|
26
|
+
export declare function resetHumanPresence(): void;
|
|
@@ -21,6 +21,7 @@ export declare function probeSrcIframes(timeoutMs?: number): Promise<boolean>;
|
|
|
21
21
|
export declare function resolveIframeMode(opts?: {
|
|
22
22
|
embedded?: boolean;
|
|
23
23
|
ampOrb?: boolean;
|
|
24
|
+
probeTimeoutMs?: number;
|
|
24
25
|
}): Promise<IframeMode>;
|
|
25
26
|
/** Test hook: clear the memoized probe so each test starts unresolved. */
|
|
26
27
|
export declare function resetIframeModeForTests(): void;
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
import type { AgentPresenceSnapshot } from '../../shared/agent-presence.js';
|
|
2
|
+
/**
|
|
3
|
+
* Per-tab identity: an AGENT driving the workbench UI from its own pane opens
|
|
4
|
+
* `/workbench?agent=<key>` and every write from that tab is booked as that
|
|
5
|
+
* agent — before this, UI-driven agent tests carried the human marker and the
|
|
6
|
+
* human was told "you rejected a gate" they never saw (0.5.0 readiness).
|
|
7
|
+
*/
|
|
8
|
+
export declare const tabAgentKey: string | null;
|
|
9
|
+
export declare function requestJson<T>(action: string, url: string, fallback: T, init?: RequestInit): Promise<T>;
|
|
10
|
+
export declare function requestOk(action: string, url: string, init?: RequestInit): Promise<{
|
|
11
|
+
ok: boolean;
|
|
12
|
+
}>;
|
|
13
|
+
export declare function requestBestEffort(action: string, url: string, init?: RequestInit): Promise<void>;
|
|
1
14
|
/** Dispatch user intents from the canvas to the server (for TUI consumption). */
|
|
2
15
|
export declare function sendIntent(type: string, payload?: Record<string, unknown>): Promise<{
|
|
3
16
|
ok: boolean;
|
|
@@ -68,7 +81,6 @@ export declare function pushCanvasUpdate(updates: Array<{
|
|
|
68
81
|
height: number;
|
|
69
82
|
};
|
|
70
83
|
collapsed?: boolean;
|
|
71
|
-
dockPosition?: 'left' | 'right' | null;
|
|
72
84
|
}>, options?: {
|
|
73
85
|
recordHistory?: boolean;
|
|
74
86
|
}): Promise<void>;
|
|
@@ -102,10 +114,11 @@ export declare function updateNodeFromClient(id: string, patch: {
|
|
|
102
114
|
};
|
|
103
115
|
collapsed?: boolean;
|
|
104
116
|
pinned?: boolean;
|
|
105
|
-
dockPosition?: 'left' | 'right' | null;
|
|
106
117
|
title?: string;
|
|
107
118
|
content?: string;
|
|
108
119
|
data?: Record<string, unknown>;
|
|
120
|
+
/** Groups: replace the membership list (positions preserved). */
|
|
121
|
+
children?: string[];
|
|
109
122
|
}): Promise<{
|
|
110
123
|
ok: boolean;
|
|
111
124
|
id?: string;
|
|
@@ -138,6 +151,8 @@ export interface AxInteractionResponse {
|
|
|
138
151
|
}
|
|
139
152
|
/** Fetch the compact AX state snapshot pushed into AX-enabled surfaces. */
|
|
140
153
|
export declare function fetchAxSurfaceState(): Promise<unknown>;
|
|
154
|
+
/** Connect-time agent-presence read; live updates arrive as `agent-presence` SSE frames. */
|
|
155
|
+
export declare function fetchAgentPresence(): Promise<Partial<AgentPresenceSnapshot> | null>;
|
|
141
156
|
/** Ask the server to open a node's surface in the system browser. */
|
|
142
157
|
export declare function openNodeInSystemBrowserRequest(nodeId: string, url?: string): Promise<{
|
|
143
158
|
ok: boolean;
|
|
@@ -177,11 +192,19 @@ export declare function createGroupFromClient(opts: {
|
|
|
177
192
|
ok: boolean;
|
|
178
193
|
id?: string;
|
|
179
194
|
}>;
|
|
180
|
-
/** Add nodes to an existing group. */
|
|
181
|
-
export declare function addToGroupFromClient(groupId: string, childIds: string[]): Promise<{
|
|
195
|
+
/** Add nodes to an existing group; `childLayout` packs the children (the header's auto-arrange). */
|
|
196
|
+
export declare function addToGroupFromClient(groupId: string, childIds: string[], childLayout?: 'grid' | 'column' | 'flow'): Promise<{
|
|
182
197
|
ok: boolean;
|
|
183
198
|
}>;
|
|
184
|
-
/**
|
|
199
|
+
/** Replace a group's membership (positions preserved) — how a single child leaves. */
|
|
200
|
+
export declare function setGroupChildrenFromClient(groupId: string, children: string[]): Promise<{
|
|
201
|
+
ok: boolean;
|
|
202
|
+
}>;
|
|
203
|
+
/**
|
|
204
|
+
* Ungroup = dissolve (children released, frame removed). The SAME server op
|
|
205
|
+
* an agent's `canvas_group { action: "ungroup" }` runs, so both sides get the
|
|
206
|
+
* identical board and one undo step.
|
|
207
|
+
*/
|
|
185
208
|
export declare function ungroupFromClient(groupId: string): Promise<{
|
|
186
209
|
ok: boolean;
|
|
187
210
|
}>;
|
|
@@ -203,6 +226,15 @@ export declare function restoreSnapshot(id: string): Promise<{
|
|
|
203
226
|
export declare function deleteSnapshot(id: string): Promise<{
|
|
204
227
|
ok: boolean;
|
|
205
228
|
}>;
|
|
229
|
+
/** Patch an edge in place (label/type/style/animated) via the server. */
|
|
230
|
+
export declare function updateEdgeFromClient(edgeId: string, patch: {
|
|
231
|
+
label?: string;
|
|
232
|
+
type?: string;
|
|
233
|
+
style?: string;
|
|
234
|
+
animated?: boolean;
|
|
235
|
+
}): Promise<{
|
|
236
|
+
ok: boolean;
|
|
237
|
+
}>;
|
|
206
238
|
/** Remove a canvas edge via the server. */
|
|
207
239
|
export declare function removeEdgeFromClient(edgeId: string): Promise<{
|
|
208
240
|
ok: boolean;
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { PmxAxIntent } from '../../shared/ax-intent.js';
|
|
2
|
+
import { type AgentActivityEntry, type AgentPresence, type AgentPresenceSnapshot, type ContextBudget } from '../../shared/agent-presence.js';
|
|
3
|
+
/**
|
|
4
|
+
* Agent presence (rail-chrome-v2 phase 2). Fed by the server's `agent-presence`
|
|
5
|
+
* SSE snapshot (every change, including TTL expiry) and the connect-time read,
|
|
6
|
+
* so this store never runs its own expiry ticker.
|
|
7
|
+
*
|
|
8
|
+
* `sessionActive` is the ONE selector every agent surface reads — the session
|
|
9
|
+
* panel, command bar, presence layer, and top-bar chip all mount on it.
|
|
10
|
+
*/
|
|
11
|
+
export declare const agentPresences: import("@preact/signals-core").Signal<AgentPresence[]>;
|
|
12
|
+
export declare const contextBudget: import("@preact/signals-core").Signal<ContextBudget>;
|
|
13
|
+
/** Recent agent writes, newest first — the External Steering activity feed. */
|
|
14
|
+
export declare const agentActivity: import("@preact/signals-core").Signal<AgentActivityEntry[]>;
|
|
15
|
+
/** External Steering chrome (phase 6): the feed popover and the writers sheet. */
|
|
16
|
+
export declare const activityFeedOpen: import("@preact/signals-core").Signal<boolean>;
|
|
17
|
+
export declare const writersSheetOpen: import("@preact/signals-core").Signal<boolean>;
|
|
18
|
+
/** Feed filter: a writer's sessionId, or null for all. */
|
|
19
|
+
export declare const activityFilter: import("@preact/signals-core").Signal<string | null>;
|
|
20
|
+
export declare function writerColor(sessionId: string): string;
|
|
21
|
+
/** Avatar initial: first letter of the label, upper-cased. */
|
|
22
|
+
export declare function writerInitial(label: string): string;
|
|
23
|
+
/** Compact relative age for feed rows and the writers sheet: now · 12s · 4m · 2h. */
|
|
24
|
+
export declare function relativeAge(iso: string, now?: number): string;
|
|
25
|
+
/** Master gate for every agent surface: an attached session exists. */
|
|
26
|
+
export declare const sessionActive: import("@preact/signals-core").ReadonlySignal<boolean>;
|
|
27
|
+
/** Live writers with no attached session — the External Steering mode. */
|
|
28
|
+
export declare const externalWriterPresences: import("@preact/signals-core").ReadonlySignal<AgentPresence[]>;
|
|
29
|
+
/**
|
|
30
|
+
* Connected agents the human can ADDRESS from the composer: every live
|
|
31
|
+
* presence (attached sessions first). `label` is the display name; `value` is
|
|
32
|
+
* the CONSUMER key the steer must be targeted at — the identity the agent
|
|
33
|
+
* claims deliveries with. For an adapter session that is its source key
|
|
34
|
+
* (Copilot attaches as source "copilot" labelled "GitHub Copilot"); for an
|
|
35
|
+
* adopted human-started session the sessionId is "browser", so the writer's
|
|
36
|
+
* label IS its consumer key. Addressing the display label instead would
|
|
37
|
+
* produce steering nobody can ever claim. The un-adopted placeholder is
|
|
38
|
+
* excluded: no consumer will ever claim as "Agent session".
|
|
39
|
+
*/
|
|
40
|
+
export declare const steerableAgents: import("@preact/signals-core").ReadonlySignal<{
|
|
41
|
+
value: string;
|
|
42
|
+
label: string;
|
|
43
|
+
attached: boolean;
|
|
44
|
+
steerable: boolean;
|
|
45
|
+
pendingSteers: number;
|
|
46
|
+
polling: boolean;
|
|
47
|
+
}[]>;
|
|
48
|
+
/** The attached session's presence (first if several hosts attached). */
|
|
49
|
+
/** Every attached session, in presence order — the top bar shows one chip each. */
|
|
50
|
+
export declare const attachedSessions: import("@preact/signals-core").ReadonlySignal<AgentPresence[]>;
|
|
51
|
+
export declare const activeSession: import("@preact/signals-core").ReadonlySignal<AgentPresence | null>;
|
|
52
|
+
/**
|
|
53
|
+
* Nodes an agent is mutating RIGHT NOW — drives the shimmer. Derived from the
|
|
54
|
+
* intent store's in-flight ghosts (move / edit / remove target an existing
|
|
55
|
+
* node) rather than a parallel source; gated on `sessionActive` at the use
|
|
56
|
+
* site so the quiet board never shimmers.
|
|
57
|
+
*/
|
|
58
|
+
export declare function mutatingNodeIdsFrom(intentList: Iterable<Pick<PmxAxIntent, 'kind' | 'nodeId'>>): Set<string>;
|
|
59
|
+
export declare const mutatingNodeIds: import("@preact/signals-core").ReadonlySignal<Set<string>>;
|
|
60
|
+
/**
|
|
61
|
+
* Where a presence's cursor sits in WORLD coordinates: an explicit cursor
|
|
62
|
+
* wins; otherwise the node the agent last touched (anchored near its title
|
|
63
|
+
* bar's right end, like a collaborator hovering the node); otherwise null.
|
|
64
|
+
*/
|
|
65
|
+
export declare function presenceWorldPosition(presence: Pick<AgentPresence, 'cursor' | 'focusNodeId'>, nodeById: (id: string) => {
|
|
66
|
+
position: {
|
|
67
|
+
x: number;
|
|
68
|
+
y: number;
|
|
69
|
+
};
|
|
70
|
+
size: {
|
|
71
|
+
width: number;
|
|
72
|
+
};
|
|
73
|
+
} | undefined): {
|
|
74
|
+
x: number;
|
|
75
|
+
y: number;
|
|
76
|
+
} | null;
|
|
77
|
+
export declare function applyPresenceSnapshot(snapshot: Partial<AgentPresenceSnapshot> | null | undefined): void;
|
|
78
|
+
export declare function resetPresence(): void;
|