nudge-ui 0.2.2 → 0.2.3
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/README.md +164 -46
- package/dist/client.mjs +252 -61
- package/dist/css/value-semantics/colorSemantics.d.ts +4 -0
- package/dist/css/value-semantics/colorSemantics.js +17 -0
- package/dist/hosts/astro/astroRuntimeConfig.js +1 -0
- package/dist/hosts/astro/clientTransport.js +38 -32
- package/dist/hosts/astro/integration.js +5 -1
- package/dist/hosts/astro/markdownIdentity.d.ts +28 -0
- package/dist/hosts/astro/markdownIdentity.js +81 -0
- package/dist/hosts/next/manifest.js +1 -1
- package/dist/hosts/next/sidecar.js +5 -1
- package/dist/hosts/static/manifest.js +1 -1
- package/dist/hosts/static/server.js +3 -0
- package/dist/hosts/vite/vite.d.ts +3 -0
- package/dist/hosts/vite/vite.js +24 -4
- package/dist/inspector/agent/McpConnectionDialog.js +13 -19
- package/dist/inspector/agent/activity.d.ts +18 -0
- package/dist/inspector/agent/activity.js +70 -0
- package/dist/inspector/agent/client.d.ts +2 -0
- package/dist/inspector/agent/client.js +29 -1
- package/dist/inspector/agent/connectionStatus.js +1 -1
- package/dist/inspector/agent/httpTransport.js +9 -2
- package/dist/inspector/agent/protocol.d.ts +6 -3
- package/dist/inspector/agent/protocol.js +1 -1
- package/dist/inspector/agent/verification.d.ts +11 -1
- package/dist/inspector/agent/verification.js +53 -25
- package/dist/inspector/canvas/AgentActivityOverlay.d.ts +13 -0
- package/dist/inspector/canvas/AgentActivityOverlay.js +111 -0
- package/dist/inspector/canvas/CanvasCard.d.ts +9 -2
- package/dist/inspector/canvas/CanvasCard.js +133 -38
- package/dist/inspector/canvas/CanvasElementOverlay.js +152 -16
- package/dist/inspector/canvas/CanvasToolIcons.d.ts +10 -0
- package/dist/inspector/canvas/CanvasToolIcons.js +20 -0
- package/dist/inspector/canvas/CanvasToolbar.js +8 -4
- package/dist/inspector/canvas/CanvasWorkspace.js +225 -57
- package/dist/inspector/canvas/StaleChangeIndicator.js +3 -13
- package/dist/inspector/canvas/agentPresentation.d.ts +8 -8
- package/dist/inspector/canvas/agentPresentation.js +64 -52
- package/dist/inspector/canvas/canvasGestures.d.ts +1 -1
- package/dist/inspector/canvas/canvasGestures.js +1 -1
- package/dist/inspector/canvas/canvasStore.d.ts +46 -82
- package/dist/inspector/canvas/canvasStore.js +251 -284
- package/dist/inspector/canvas/frameContent.d.ts +21 -0
- package/dist/inspector/canvas/frameContent.js +44 -0
- package/dist/inspector/canvas/frameProtocol.d.ts +21 -4
- package/dist/inspector/canvas/frameProtocol.js +3 -3
- package/dist/inspector/canvas/keyboardShortcuts.d.ts +3 -1
- package/dist/inspector/canvas/keyboardShortcuts.js +4 -4
- package/dist/inspector/canvas/layout.d.ts +52 -0
- package/dist/inspector/canvas/layout.js +106 -0
- package/dist/inspector/canvas/projection.d.ts +15 -5
- package/dist/inspector/canvas/projection.js +69 -13
- package/dist/inspector/canvas/rendererBootstrap.js +32 -4
- package/dist/inspector/canvas/rendererElementSelector.js +47 -6
- package/dist/inspector/canvas/rendererStylesheet.js +2 -2
- package/dist/inspector/canvas/resizeHandleScale.js +1 -1
- package/dist/inspector/canvas/sessionStore.d.ts +11 -26
- package/dist/inspector/canvas/sessionStore.js +43 -183
- package/dist/inspector/canvas/staleChangeDetector.js +9 -3
- package/dist/inspector/canvas/useCanvasLayoutAnimation.d.ts +5 -0
- package/dist/inspector/canvas/useCanvasLayoutAnimation.js +107 -0
- package/dist/inspector/canvas/viewStore.d.ts +38 -0
- package/dist/inspector/canvas/viewStore.js +104 -0
- package/dist/inspector/canvas/wheelPan.d.ts +8 -0
- package/dist/inspector/canvas/wheelPan.js +8 -0
- package/dist/inspector/changes/changesLog.d.ts +6 -5
- package/dist/inspector/changes/changesLog.js +40 -32
- package/dist/inspector/changes/draftChanges.d.ts +56 -0
- package/dist/inspector/changes/draftChanges.js +300 -0
- package/dist/inspector/changes/previewDiagnostics.d.ts +4 -2
- package/dist/inspector/changes/previewDiagnostics.js +11 -25
- package/dist/inspector/clientManifest.d.ts +1 -1
- package/dist/inspector/comments/CommentsOverlay.d.ts +2 -0
- package/dist/inspector/comments/CommentsOverlay.js +250 -0
- package/dist/inspector/comments/element.d.ts +6 -0
- package/dist/inspector/comments/element.js +47 -0
- package/dist/inspector/comments/store.d.ts +29 -0
- package/dist/inspector/comments/store.js +121 -0
- package/dist/inspector/comments/verification.d.ts +5 -0
- package/dist/inspector/comments/verification.js +52 -0
- package/dist/inspector/drafts/model.d.ts +35 -0
- package/dist/inspector/drafts/model.js +45 -0
- package/dist/inspector/drafts/store.d.ts +28 -0
- package/dist/inspector/drafts/store.js +231 -0
- package/dist/inspector/index.js +20 -27
- package/dist/inspector/inline-text/inlineTextEditor.js +7 -0
- package/dist/inspector/inspection/useBrowserCssInspection.js +15 -1
- package/dist/inspector/iterations/capture.d.ts +2 -0
- package/dist/inspector/iterations/capture.js +173 -0
- package/dist/inspector/iterations/client.d.ts +7 -0
- package/dist/inspector/iterations/client.js +52 -0
- package/dist/inspector/iterations/coordinator.d.ts +15 -0
- package/dist/inspector/iterations/coordinator.js +130 -0
- package/dist/inspector/iterations/prompt.d.ts +3 -0
- package/dist/inspector/iterations/prompt.js +26 -0
- package/dist/inspector/overlay/DomNavigator.js +21 -15
- package/dist/inspector/overlay/interactionStyles.js +3 -1
- package/dist/inspector/overlay/spacingGestures.d.ts +13 -1
- package/dist/inspector/overlay/spacingGestures.js +82 -5
- package/dist/inspector/projection/{workspaceProjection.d.ts → draftProjection.d.ts} +6 -6
- package/dist/inspector/projection/{workspaceProjection.js → draftProjection.js} +4 -4
- package/dist/inspector/projection/renderedInstance.d.ts +2 -1
- package/dist/inspector/projection/renderedInstance.js +9 -5
- package/dist/inspector/projection/structuralProjection.d.ts +2 -1
- package/dist/inspector/projection/structuralProjection.js +19 -15
- package/dist/inspector/projection/textProjection.d.ts +2 -1
- package/dist/inspector/projection/textProjection.js +8 -4
- package/dist/inspector/prompt/PromptSettingsDialog.js +1 -5
- package/dist/inspector/prompt/clipboardHandoff.d.ts +10 -18
- package/dist/inspector/prompt/clipboardHandoff.js +92 -143
- package/dist/inspector/prompt/generatePrompt.d.ts +4 -1
- package/dist/inspector/prompt/generatePrompt.js +17 -16
- package/dist/inspector/runtime/runtimeConfig.d.ts +9 -0
- package/dist/inspector/runtime/runtimeConfig.js +24 -0
- package/dist/inspector/settings/SettingsDialog.js +21 -8
- package/dist/inspector/shell/AgentStatusButton.d.ts +11 -0
- package/dist/inspector/shell/AgentStatusButton.js +36 -0
- package/dist/inspector/shell/AppShell.js +4 -2
- package/dist/inspector/shell/ChangesLog.js +46 -26
- package/dist/inspector/shell/CopyPromptButton.js +138 -89
- package/dist/inspector/shell/EmptyState.js +9 -8
- package/dist/inspector/shell/InspectorShell.js +13 -21
- package/dist/inspector/shell/PeekOriginalButton.js +24 -23
- package/dist/inspector/shell/originalPreview.js +5 -5
- package/dist/inspector/shell/shortcuts.d.ts +3 -0
- package/dist/inspector/shell/shortcuts.js +11 -0
- package/dist/inspector/sketch/SketchEditor.js +14 -14
- package/dist/inspector/sketch/SketchEntryButton.js +1 -1
- package/dist/inspector/sketch/SketchFrameOverlay.d.ts +3 -1
- package/dist/inspector/sketch/SketchFrameOverlay.js +11 -8
- package/dist/inspector/sketch/SketchLayersPanel.js +13 -5
- package/dist/inspector/sketch/SketchOverlay.js +7 -7
- package/dist/inspector/sketch/SketchWorkspace.js +18 -12
- package/dist/inspector/sketch/interaction.d.ts +1 -0
- package/dist/inspector/sketch/interaction.js +8 -4
- package/dist/inspector/sketch/model.d.ts +5 -0
- package/dist/inspector/sketch/model.js +6 -2
- package/dist/inspector/sketch/raster.d.ts +1 -2
- package/dist/inspector/sketch/raster.js +68 -4
- package/dist/inspector/styleEditors/BackgroundEditor.d.ts +4 -0
- package/dist/inspector/styleEditors/BackgroundEditor.js +195 -0
- package/dist/inspector/styleEditors/BorderEditor.js +49 -78
- package/dist/inspector/styleEditors/BorderRadiusEditor.js +6 -1
- package/dist/inspector/styleEditors/BoxShadowEditor.d.ts +1 -2
- package/dist/inspector/styleEditors/BoxShadowEditor.js +132 -4
- package/dist/inspector/styleEditors/ColorPicker.d.ts +5 -1
- package/dist/inspector/styleEditors/ColorPicker.js +10 -4
- package/dist/inspector/styleEditors/GapField.js +3 -5
- package/dist/inspector/styleEditors/GridChildSection.d.ts +1 -1
- package/dist/inspector/styleEditors/GridChildSection.js +18 -9
- package/dist/inspector/styleEditors/GridPicker.d.ts +1 -1
- package/dist/inspector/styleEditors/GridPicker.js +8 -2
- package/dist/inspector/styleEditors/GridSection.js +1 -1
- package/dist/inspector/styleEditors/GridValueField.js +19 -14
- package/dist/inspector/styleEditors/ImageBackgroundEditor.d.ts +18 -0
- package/dist/inspector/styleEditors/ImageBackgroundEditor.js +118 -0
- package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +2 -2
- package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +3 -3
- package/dist/inspector/styleEditors/LayoutComboField.js +6 -4
- package/dist/inspector/styleEditors/LayoutDropdown.js +6 -3
- package/dist/inspector/styleEditors/LayoutSection.js +32 -11
- package/dist/inspector/styleEditors/SpacingBox.js +7 -5
- package/dist/inspector/styleEditors/Typography.js +11 -3
- package/dist/inspector/styleEditors/backgroundLayers.d.ts +24 -0
- package/dist/inspector/styleEditors/backgroundLayers.js +51 -0
- package/dist/inspector/styleEditors/gradientValue.d.ts +17 -0
- package/dist/inspector/styleEditors/gradientValue.js +114 -0
- package/dist/inspector/styleEditors/inlineAuthored.d.ts +10 -0
- package/dist/inspector/styleEditors/inlineAuthored.js +114 -0
- package/dist/inspector/styleEditors/layoutValue.d.ts +0 -8
- package/dist/inspector/styleEditors/layoutValue.js +0 -42
- package/dist/inspector/styleEditors/nudgeValue.d.ts +2 -2
- package/dist/inspector/styleEditors/nudgeValue.js +36 -8
- package/dist/inspector/tokens/TokenField.d.ts +7 -0
- package/dist/inspector/tokens/TokenField.js +29 -21
- package/dist/inspector/tokens/TokenLabel.js +5 -14
- package/dist/inspector/tokens/editActions.d.ts +1 -1
- package/dist/inspector/tokens/editActions.js +1 -1
- package/dist/inspector/ui/AtRuleContext.js +4 -6
- package/dist/inspector/ui/Button.d.ts +6 -2
- package/dist/inspector/ui/Button.js +4 -3
- package/dist/inspector/ui/ControlSurface.d.ts +2 -2
- package/dist/inspector/ui/ControlSurface.js +4 -3
- package/dist/inspector/ui/InlineStyleWarning.d.ts +11 -0
- package/dist/inspector/ui/InlineStyleWarning.js +13 -0
- package/dist/inspector/ui/InspectorPopover.d.ts +2 -1
- package/dist/inspector/ui/InspectorPopover.js +4 -5
- package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
- package/dist/inspector/ui/PopoverListbox.js +8 -7
- package/dist/inspector/ui/SegmentedControl.d.ts +2 -1
- package/dist/inspector/ui/SegmentedControl.js +2 -2
- package/dist/inspector/ui/Select.d.ts +6 -1
- package/dist/inspector/ui/Select.js +7 -11
- package/dist/inspector/ui/SideValuesField.js +1 -1
- package/dist/inspector/ui/Tooltip.d.ts +26 -0
- package/dist/inspector/ui/Tooltip.js +32 -0
- package/dist/inspector/ui/classNames.d.ts +2 -0
- package/dist/inspector/ui/classNames.js +4 -0
- package/dist/inspector/ui/customCursors.d.ts +23 -0
- package/dist/inspector/ui/customCursors.js +122 -0
- package/dist/inspector/ui/dragCursor.d.ts +0 -2
- package/dist/inspector/ui/dragCursor.js +2 -10
- package/dist/inspector/ui/portalContainer.d.ts +2 -0
- package/dist/inspector/ui/portalContainer.js +6 -0
- package/dist/inspector/ui/styles.js +29 -21
- package/dist/inspector/workspace/commands.d.ts +9 -0
- package/dist/inspector/workspace/commands.js +82 -0
- package/dist/inspector/workspace/controller.d.ts +4 -0
- package/dist/inspector/workspace/controller.js +66 -0
- package/dist/inspector/workspace/handoff.d.ts +42 -0
- package/dist/inspector/workspace/handoff.js +115 -0
- package/dist/inspector/workspace/timeline.d.ts +30 -0
- package/dist/inspector/workspace/timeline.js +108 -0
- package/dist/internal/agent-protocol.d.ts +19 -2
- package/dist/internal/agent-protocol.js +13 -0
- package/dist/nudge-ui.mjs +558 -311
- package/dist/project/artifacts.d.ts +13 -0
- package/dist/project/artifacts.js +253 -0
- package/dist/transport/artifacts.d.ts +8 -0
- package/dist/transport/artifacts.js +9 -0
- package/dist/transport/editor.js +3 -1
- package/dist/transport/routes.d.ts +2 -0
- package/dist/transport/routes.js +2 -0
- package/package.json +6 -2
- package/dist/inspector/changes/workspaceChanges.d.ts +0 -47
- package/dist/inspector/changes/workspaceChanges.js +0 -265
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type CanvasCommand, type CanvasCommandResult, type CanvasState } from "../../internal/agent-protocol.js";
|
|
2
|
-
import { type CanvasCard
|
|
1
|
+
import { type CanvasCommand, type CanvasCommandResult, type CanvasGroup, type CanvasState } from "../../internal/agent-protocol.js";
|
|
2
|
+
import { type CanvasCard } from "./canvasStore.js";
|
|
3
3
|
/**
|
|
4
4
|
* Renderer acknowledgements are deliberately shorter than the companion's
|
|
5
5
|
* request timeout. A controller can therefore receive a useful partial-failure
|
|
@@ -24,7 +24,7 @@ export interface AgentPresentationRoute {
|
|
|
24
24
|
label?: string;
|
|
25
25
|
}
|
|
26
26
|
export type AgentPresentationRouteInput = string | AgentPresentationRoute;
|
|
27
|
-
export interface
|
|
27
|
+
export interface PresentAgentRoutesInput {
|
|
28
28
|
label: string;
|
|
29
29
|
routes?: readonly AgentPresentationRouteInput[];
|
|
30
30
|
/** Convenience spelling for direct browser callers. */
|
|
@@ -35,8 +35,8 @@ export interface PresentAgentComparisonGroupInput {
|
|
|
35
35
|
agentId?: string;
|
|
36
36
|
readyTimeoutMs?: number;
|
|
37
37
|
}
|
|
38
|
-
export interface
|
|
39
|
-
group:
|
|
38
|
+
export interface AgentRoutesPresentation {
|
|
39
|
+
group: CanvasGroup;
|
|
40
40
|
cards: CanvasCard[];
|
|
41
41
|
readiness: AgentRendererReadiness;
|
|
42
42
|
}
|
|
@@ -54,8 +54,8 @@ export declare function forgetAgentRendererReadiness(cardIds: readonly string[])
|
|
|
54
54
|
export declare function waitForAgentRendererReadiness(cardIds: readonly string[], timeoutMs?: number): Promise<AgentRendererReadiness>;
|
|
55
55
|
/** Returns the compact state shape shared with the companion bridge. */
|
|
56
56
|
export declare function readCanvasState(): CanvasState;
|
|
57
|
-
export declare function
|
|
58
|
-
export declare function
|
|
57
|
+
export declare function presentAgentRoutes(input: PresentAgentRoutesInput): Promise<AgentRoutesPresentation>;
|
|
58
|
+
export declare function focusAgentGroup(groupId: string, viewport?: {
|
|
59
59
|
width: number;
|
|
60
60
|
height: number;
|
|
61
61
|
}): AgentPresentationState;
|
|
@@ -63,7 +63,7 @@ export declare function fitAgentCanvas(viewport?: {
|
|
|
63
63
|
width: number;
|
|
64
64
|
height: number;
|
|
65
65
|
}): AgentPresentationState;
|
|
66
|
-
export declare function
|
|
66
|
+
export declare function removeOwnAgentGroup(groupId: string, agentId?: string): AgentPresentationState;
|
|
67
67
|
/** The only command vocabulary accepted by the browser presentation adapter. */
|
|
68
68
|
export type AgentPresentationCommand = CanvasCommand;
|
|
69
69
|
export type AgentPresentationCommandResponse = CanvasCommandResult;
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
import { contentSourceUrl } from "./frameContent.js";
|
|
1
2
|
import { AGENT_PROTOCOL_LIMITS, isCanvasCommand, validateRoutes, } from "../../internal/agent-protocol.js";
|
|
2
3
|
import { isNudgeUiDev } from "../runtime/devFlag.js";
|
|
3
4
|
import { getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
|
|
4
5
|
import { canWriteWorkspace } from "./workspaceLease.js";
|
|
5
|
-
import {
|
|
6
|
+
import { removeFrame } from "../workspace/commands.js";
|
|
7
|
+
import { appendAgentRouteCards, getFrameGroup, getFrameGroups, setFrameGroup, removeFrameGroup, batchCanvasChanges, fitAllCards, focusCard, focusCanvasCards, getCanvasCards, getFocusedCardId, } from "./canvasStore.js";
|
|
8
|
+
import { getCanvasMode, setCanvasMode } from "./viewStore.js";
|
|
6
9
|
/**
|
|
7
10
|
* Renderer acknowledgements are deliberately shorter than the companion's
|
|
8
11
|
* request timeout. A controller can therefore receive a useful partial-failure
|
|
@@ -45,11 +48,11 @@ function createGroupId() {
|
|
|
45
48
|
}
|
|
46
49
|
function validateLabel(value) {
|
|
47
50
|
if (!isNonEmptyString(value)) {
|
|
48
|
-
throw new AgentPresentationError("invalid-label", "A
|
|
51
|
+
throw new AgentPresentationError("invalid-label", "A route group label is required.");
|
|
49
52
|
}
|
|
50
53
|
const label = value.trim();
|
|
51
54
|
if (label.length > MAX_GROUP_LABEL_LENGTH || /[\u0000-\u001f\u007f]/.test(label)) {
|
|
52
|
-
throw new AgentPresentationError("invalid-label", `
|
|
55
|
+
throw new AgentPresentationError("invalid-label", `Route group labels must be between 1 and ${MAX_GROUP_LABEL_LENGTH} printable characters.`);
|
|
53
56
|
}
|
|
54
57
|
return label;
|
|
55
58
|
}
|
|
@@ -57,17 +60,17 @@ function routeForValidation(value) {
|
|
|
57
60
|
if (typeof value === "string")
|
|
58
61
|
return { url: value };
|
|
59
62
|
if (!isRecord(value)) {
|
|
60
|
-
throw new AgentPresentationError("invalid-route", "Each
|
|
63
|
+
throw new AgentPresentationError("invalid-route", "Each presented route must be a URL object.");
|
|
61
64
|
}
|
|
62
65
|
return value;
|
|
63
66
|
}
|
|
64
67
|
function normalizeRoutes(input) {
|
|
65
68
|
const rawRoutes = input.routes ?? input.urls;
|
|
66
69
|
if (!rawRoutes || rawRoutes.length === 0) {
|
|
67
|
-
throw new AgentPresentationError("invalid-route", "At least one
|
|
70
|
+
throw new AgentPresentationError("invalid-route", "At least one presented route is required.");
|
|
68
71
|
}
|
|
69
72
|
if (rawRoutes.length > MAX_PRESENTATION_ROUTES) {
|
|
70
|
-
throw new AgentPresentationError("too-many-routes", `A
|
|
73
|
+
throw new AgentPresentationError("too-many-routes", `A route group may contain at most ${MAX_PRESENTATION_ROUTES} routes.`);
|
|
71
74
|
}
|
|
72
75
|
try {
|
|
73
76
|
return validateRoutes(rawRoutes.map((route) => {
|
|
@@ -80,7 +83,7 @@ function normalizeRoutes(input) {
|
|
|
80
83
|
}), window.location.origin);
|
|
81
84
|
}
|
|
82
85
|
catch (error) {
|
|
83
|
-
throw new AgentPresentationError("invalid-route", error instanceof Error ? error.message : "
|
|
86
|
+
throw new AgentPresentationError("invalid-route", error instanceof Error ? error.message : "Presented routes must be same-origin URLs.");
|
|
84
87
|
}
|
|
85
88
|
}
|
|
86
89
|
function ensureDevelopment() {
|
|
@@ -187,18 +190,24 @@ export function waitForAgentRendererReadiness(cardIds, timeoutMs = DEFAULT_RENDE
|
|
|
187
190
|
settleReadinessWaiters();
|
|
188
191
|
});
|
|
189
192
|
}
|
|
190
|
-
function toProtocolGroup(
|
|
193
|
+
function toProtocolGroup(groupId) {
|
|
194
|
+
const group = getFrameGroup(groupId);
|
|
191
195
|
return {
|
|
192
|
-
id:
|
|
193
|
-
label: group
|
|
196
|
+
id: groupId,
|
|
197
|
+
label: group?.label ?? "",
|
|
194
198
|
owner: "agent",
|
|
195
|
-
routes: group
|
|
199
|
+
routes: (group?.routes ?? []).map((route) => ({
|
|
196
200
|
url: route.url,
|
|
197
201
|
...(route.title === undefined || route.title === null ? {} : { title: route.title }),
|
|
198
202
|
...(route.label === undefined ? {} : { label: route.label }),
|
|
199
203
|
})),
|
|
200
204
|
};
|
|
201
205
|
}
|
|
206
|
+
function groupCardIds(groupId) {
|
|
207
|
+
return getCanvasCards()
|
|
208
|
+
.filter((card) => card.groupId === groupId)
|
|
209
|
+
.map((card) => card.id);
|
|
210
|
+
}
|
|
202
211
|
/** Returns the compact state shape shared with the companion bridge. */
|
|
203
212
|
export function readCanvasState() {
|
|
204
213
|
const focusedCardId = getFocusedCardId();
|
|
@@ -207,12 +216,16 @@ export function readCanvasState() {
|
|
|
207
216
|
: undefined;
|
|
208
217
|
return {
|
|
209
218
|
mode: getCanvasMode(),
|
|
210
|
-
groups:
|
|
211
|
-
|
|
212
|
-
|
|
219
|
+
groups: getFrameGroups().map((group) => group.id)
|
|
220
|
+
.filter((groupId) => groupCardIds(groupId).length > 0)
|
|
221
|
+
.map(toProtocolGroup),
|
|
222
|
+
focusedGroupId: focusedCard?.groupId && getFrameGroup(focusedCard.groupId)?.kind === "agent"
|
|
223
|
+
? focusedCard.groupId
|
|
224
|
+
: null,
|
|
225
|
+
focusedRouteUrl: focusedCard ? contentSourceUrl(focusedCard.content) : null,
|
|
213
226
|
};
|
|
214
227
|
}
|
|
215
|
-
export async function
|
|
228
|
+
export async function presentAgentRoutes(input) {
|
|
216
229
|
ensureDevelopment();
|
|
217
230
|
ensureWritable();
|
|
218
231
|
if (activePresentation) {
|
|
@@ -228,53 +241,50 @@ export async function presentAgentComparisonGroup(input) {
|
|
|
228
241
|
}
|
|
229
242
|
const groupId = input.groupId ?? createGroupId();
|
|
230
243
|
if (!isNonEmptyString(groupId) || groupId.length > AGENT_PROTOCOL_LIMITS.groupId) {
|
|
231
|
-
throw new AgentPresentationError("invalid-command", "A
|
|
244
|
+
throw new AgentPresentationError("invalid-command", "A route group ID is required.");
|
|
232
245
|
}
|
|
233
|
-
|
|
234
|
-
|
|
246
|
+
const collides = getFrameGroup(groupId) !== undefined
|
|
247
|
+
|| getCanvasCards().some((card) => card.groupId === groupId);
|
|
248
|
+
if (collides) {
|
|
249
|
+
throw new AgentPresentationError("group-id-conflict", `Route group ${groupId} already exists.`);
|
|
235
250
|
}
|
|
236
251
|
const readyTimeoutMs = clampReadyTimeout(input.readyTimeoutMs);
|
|
237
252
|
// Opening Canvas for an agent group appends only the requested routes. It
|
|
238
253
|
// never creates or repositions the current Inspect route.
|
|
239
254
|
setCanvasMode("canvas");
|
|
240
|
-
const
|
|
241
|
-
id: groupId,
|
|
242
|
-
|
|
243
|
-
owner: "agent",
|
|
244
|
-
agentId,
|
|
245
|
-
routes: routes.map((route) => ({
|
|
255
|
+
const cards = batchCanvasChanges(() => {
|
|
256
|
+
setFrameGroup({ id: groupId, kind: "agent", label, agentId, routes: routes.map((route) => ({ ...route })) });
|
|
257
|
+
return appendAgentRouteCards(groupId, routes.map((route) => ({
|
|
246
258
|
url: route.url,
|
|
247
259
|
...(route.title === undefined ? {} : { title: route.title }),
|
|
248
|
-
|
|
249
|
-
})),
|
|
260
|
+
})));
|
|
250
261
|
});
|
|
251
|
-
if (!
|
|
252
|
-
throw new AgentPresentationError("group-id-conflict", `
|
|
262
|
+
if (!cards) {
|
|
263
|
+
throw new AgentPresentationError("group-id-conflict", `Route group ${groupId} already exists.`);
|
|
253
264
|
}
|
|
254
|
-
const cardIds =
|
|
265
|
+
const cardIds = cards.map((card) => card.id);
|
|
255
266
|
beginRendererReadiness(cardIds);
|
|
256
267
|
const readiness = await waitForAgentRendererReadiness(cardIds, readyTimeoutMs);
|
|
257
|
-
return {
|
|
268
|
+
return { group: toProtocolGroup(groupId), cards, readiness };
|
|
258
269
|
}
|
|
259
270
|
finally {
|
|
260
271
|
activePresentation = false;
|
|
261
272
|
}
|
|
262
273
|
}
|
|
263
274
|
function groupCards(groupId) {
|
|
264
|
-
const group =
|
|
265
|
-
if (
|
|
266
|
-
throw new AgentPresentationError("group-not-found", `
|
|
267
|
-
const
|
|
268
|
-
const cards = getCanvasCards().filter((card) => cardIds.has(card.id));
|
|
275
|
+
const group = getFrameGroup(groupId);
|
|
276
|
+
if (group?.kind !== "agent")
|
|
277
|
+
throw new AgentPresentationError("group-not-found", `Route group ${groupId} was not found.`);
|
|
278
|
+
const cards = getCanvasCards().filter((card) => card.groupId === groupId);
|
|
269
279
|
if (cards.length === 0) {
|
|
270
|
-
throw new AgentPresentationError("group-not-found", `
|
|
280
|
+
throw new AgentPresentationError("group-not-found", `Route group ${groupId} has no cards.`);
|
|
271
281
|
}
|
|
272
|
-
return
|
|
282
|
+
return cards;
|
|
273
283
|
}
|
|
274
|
-
export function
|
|
284
|
+
export function focusAgentGroup(groupId, viewport) {
|
|
275
285
|
ensureDevelopment();
|
|
276
286
|
ensureWritable();
|
|
277
|
-
const
|
|
287
|
+
const cards = groupCards(groupId);
|
|
278
288
|
focusCard(cards[0].id);
|
|
279
289
|
focusCanvasCards(cards.map((card) => card.id), viewport);
|
|
280
290
|
return readCanvasState();
|
|
@@ -285,17 +295,19 @@ export function fitAgentCanvas(viewport) {
|
|
|
285
295
|
fitAllCards(viewport);
|
|
286
296
|
return readCanvasState();
|
|
287
297
|
}
|
|
288
|
-
export function
|
|
298
|
+
export function removeOwnAgentGroup(groupId, agentId = DEFAULT_AGENT_ID) {
|
|
289
299
|
ensureDevelopment();
|
|
290
300
|
ensureWritable();
|
|
291
|
-
const group =
|
|
292
|
-
if (
|
|
293
|
-
throw new AgentPresentationError("group-not-found", `
|
|
294
|
-
if (group.
|
|
295
|
-
throw new AgentPresentationError("not-group-owner", `Agent ${agentId} cannot remove
|
|
301
|
+
const group = getFrameGroup(groupId);
|
|
302
|
+
if (group?.kind !== "agent")
|
|
303
|
+
throw new AgentPresentationError("group-not-found", `Route group ${groupId} was not found.`);
|
|
304
|
+
if (group.agentId !== agentId) {
|
|
305
|
+
throw new AgentPresentationError("not-group-owner", `Agent ${agentId} cannot remove route group ${groupId}.`);
|
|
296
306
|
}
|
|
297
|
-
const cardIds =
|
|
298
|
-
|
|
307
|
+
const cardIds = groupCardIds(groupId);
|
|
308
|
+
for (const cardId of cardIds)
|
|
309
|
+
removeFrame(cardId);
|
|
310
|
+
removeFrameGroup(groupId);
|
|
299
311
|
forgetAgentRendererReadiness(cardIds);
|
|
300
312
|
return readCanvasState();
|
|
301
313
|
}
|
|
@@ -329,7 +341,7 @@ async function executeCanvasCommand(command, agentId) {
|
|
|
329
341
|
ensureDevelopment();
|
|
330
342
|
return { commandId: command.commandId, ok: true, state: readCanvasState() };
|
|
331
343
|
case "present-routes": {
|
|
332
|
-
const presentation = await
|
|
344
|
+
const presentation = await presentAgentRoutes({
|
|
333
345
|
groupId: command.groupId,
|
|
334
346
|
label: command.label,
|
|
335
347
|
routes: command.routes,
|
|
@@ -341,7 +353,7 @@ async function executeCanvasCommand(command, agentId) {
|
|
|
341
353
|
commandId: command.commandId,
|
|
342
354
|
ok: true,
|
|
343
355
|
state,
|
|
344
|
-
group:
|
|
356
|
+
group: presentation.group,
|
|
345
357
|
};
|
|
346
358
|
}
|
|
347
359
|
const failed = presentation.readiness.failedCardIds.length > 0;
|
|
@@ -349,7 +361,7 @@ async function executeCanvasCommand(command, agentId) {
|
|
|
349
361
|
commandId: command.commandId,
|
|
350
362
|
ok: false,
|
|
351
363
|
state,
|
|
352
|
-
group:
|
|
364
|
+
group: presentation.group,
|
|
353
365
|
error: {
|
|
354
366
|
code: failed ? "renderer-error" : "renderer-timeout",
|
|
355
367
|
message: failed
|
|
@@ -362,7 +374,7 @@ async function executeCanvasCommand(command, agentId) {
|
|
|
362
374
|
return {
|
|
363
375
|
commandId: command.commandId,
|
|
364
376
|
ok: true,
|
|
365
|
-
state:
|
|
377
|
+
state: focusAgentGroup(command.groupId),
|
|
366
378
|
};
|
|
367
379
|
case "fit-all":
|
|
368
380
|
return {
|
|
@@ -374,7 +386,7 @@ async function executeCanvasCommand(command, agentId) {
|
|
|
374
386
|
return {
|
|
375
387
|
commandId: command.commandId,
|
|
376
388
|
ok: true,
|
|
377
|
-
state:
|
|
389
|
+
state: removeOwnAgentGroup(command.groupId, agentId),
|
|
378
390
|
};
|
|
379
391
|
}
|
|
380
392
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { MAX_CAMERA_ZOOM, MIN_CAMERA_ZOOM
|
|
1
|
+
import { MAX_CAMERA_ZOOM, MIN_CAMERA_ZOOM } from "./viewStore.js";
|
|
2
2
|
export const ZOOM_WHEEL_FACTOR = 1.02;
|
|
3
3
|
export function zoomCameraAtPointer(camera, pointer, boardRect, deltaY) {
|
|
4
4
|
const pointerX = pointer.x - boardRect.left;
|
|
@@ -1,84 +1,54 @@
|
|
|
1
|
+
import type { FrameContent } from "./frameContent.js";
|
|
2
|
+
import { type CanvasCamera, type CanvasMode, type CanvasPresentation } from "./viewStore.js";
|
|
1
3
|
import { type NormalizedUrl } from "./normalizeUrl.js";
|
|
2
|
-
export
|
|
3
|
-
export type CanvasPresentation = "focus" | "canvas";
|
|
4
|
-
export interface CanvasCard {
|
|
5
|
-
id: string;
|
|
6
|
-
url: string;
|
|
7
|
-
/** A controller-requested document load. Renderer metadata must not set this. */
|
|
8
|
-
navigationUrl?: string;
|
|
9
|
-
title: string | null;
|
|
4
|
+
export interface FrameGeometry {
|
|
10
5
|
x: number;
|
|
11
6
|
y: number;
|
|
12
7
|
width: number;
|
|
13
8
|
height: number;
|
|
14
|
-
/** The agent-created comparison group that owns this card, when present. */
|
|
15
|
-
comparisonGroupId?: string;
|
|
16
9
|
}
|
|
17
|
-
|
|
18
|
-
export interface CanvasComparisonGroup {
|
|
10
|
+
export interface CanvasCard extends FrameGeometry {
|
|
19
11
|
id: string;
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
routes: CanvasComparisonGroupRoute[];
|
|
12
|
+
content: FrameContent;
|
|
13
|
+
entrance?: "linked" | "iteration";
|
|
14
|
+
/** Directly placed iterations skip entrance animation, including on redo. */
|
|
15
|
+
animateEntrance?: boolean;
|
|
16
|
+
groupId?: string;
|
|
17
|
+
title: string | null;
|
|
27
18
|
}
|
|
28
|
-
export interface
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
label
|
|
19
|
+
export interface FrameGroup {
|
|
20
|
+
readonly id: string;
|
|
21
|
+
readonly kind: "agent";
|
|
22
|
+
readonly label: string;
|
|
23
|
+
readonly agentId: string;
|
|
24
|
+
readonly routes: readonly {
|
|
25
|
+
url: string;
|
|
26
|
+
title?: string;
|
|
27
|
+
label?: string;
|
|
28
|
+
}[];
|
|
32
29
|
}
|
|
33
|
-
export
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
export declare const MIN_CAMERA_ZOOM = 0.25;
|
|
39
|
-
export declare const MAX_CAMERA_ZOOM = 3;
|
|
30
|
+
export declare function setFrameGroup(group: FrameGroup): void;
|
|
31
|
+
export declare function getFrameGroup(id: string): FrameGroup | undefined;
|
|
32
|
+
export declare function removeFrameGroup(id: string): void;
|
|
33
|
+
export declare function getFrameGroups(): readonly FrameGroup[];
|
|
34
|
+
export declare function isFrameGroup(value: unknown): value is FrameGroup;
|
|
40
35
|
export declare const CARD_GAP = 40;
|
|
41
36
|
export declare const FIT_ALL_PADDING = 80;
|
|
42
37
|
export declare const PRIMARY_CARD_INSET = 40;
|
|
43
38
|
declare function subscribe(cb: () => void): () => void;
|
|
44
|
-
declare function getMode(): CanvasMode;
|
|
45
39
|
declare function getCards(): CanvasCard[];
|
|
46
|
-
declare function
|
|
47
|
-
export declare function setCanvasMode(newMode: CanvasMode): void;
|
|
48
|
-
/**
|
|
49
|
-
* Changes how the mounted iframe workspace is presented.
|
|
50
|
-
*
|
|
51
|
-
* Canvas starts from the active card centered in the supplied viewport. Card
|
|
52
|
-
* geometry remains durable, but the camera does not carry over from a prior
|
|
53
|
-
* Canvas session.
|
|
54
|
-
*/
|
|
55
|
-
export declare function setCanvasPresentation(next: CanvasPresentation, viewport?: {
|
|
56
|
-
width: number;
|
|
57
|
-
height: number;
|
|
58
|
-
}): void;
|
|
40
|
+
export declare function batchCanvasChanges<T>(operation: () => T): T;
|
|
59
41
|
/** Adds one card while retaining the existing placement policy. */
|
|
60
42
|
export declare function addCanvasCard(url: string, title?: string): CanvasCard;
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*/
|
|
66
|
-
export declare function
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
owner?: "agent";
|
|
71
|
-
routes: readonly CanvasComparisonGroupRoute[];
|
|
72
|
-
}): {
|
|
73
|
-
group: CanvasComparisonGroup;
|
|
74
|
-
cards: CanvasCard[];
|
|
75
|
-
} | null;
|
|
76
|
-
export declare function getCanvasComparisonGroup(id: string): CanvasComparisonGroup | undefined;
|
|
77
|
-
/** Removes a group and exactly the cards owned by that group. */
|
|
78
|
-
export declare function removeCanvasComparisonGroup(id: string): CanvasComparisonGroup | null;
|
|
79
|
-
/** Clears group metadata while leaving ordinary cards intact. */
|
|
80
|
-
export declare function clearCanvasComparisonGroups(): void;
|
|
81
|
-
export declare function removeCanvasCard(id: string): void;
|
|
43
|
+
export declare function appendAgentRouteCards(groupId: string, routes: readonly {
|
|
44
|
+
url: string;
|
|
45
|
+
title?: string | null;
|
|
46
|
+
}[]): CanvasCard[] | null;
|
|
47
|
+
/** Connects canvas replay to the draft controller without coupling the stores. */
|
|
48
|
+
export declare function setCanvasHistoryActivator(activate: (cardId: string) => void): void;
|
|
49
|
+
export declare function removeCanvasCard(id: string, { undoable }?: {
|
|
50
|
+
undoable?: boolean;
|
|
51
|
+
}): void;
|
|
82
52
|
/**
|
|
83
53
|
* Opens one editor target in the iframe workspace without replacing restored
|
|
84
54
|
* cards or their dimensions.
|
|
@@ -86,33 +56,30 @@ export declare function removeCanvasCard(id: string): void;
|
|
|
86
56
|
export declare function activateIframeWorkspace(url: string, viewport: {
|
|
87
57
|
width: number;
|
|
88
58
|
height: number;
|
|
59
|
+
}, options?: {
|
|
60
|
+
replaceActiveCard?: boolean;
|
|
61
|
+
preserveIterationFocus?: boolean;
|
|
89
62
|
}): CanvasCard | null;
|
|
90
63
|
export declare function updateCardTitle(id: string, title: string): void;
|
|
91
64
|
export declare function updateCardUrl(id: string, url: string): void;
|
|
92
65
|
export declare function duplicateCard(sourceId: string): CanvasCard | null;
|
|
66
|
+
export declare function addCanvasIteration(sourceId: string, artifactId: string, position?: {
|
|
67
|
+
x: number;
|
|
68
|
+
y: number;
|
|
69
|
+
}, animateEntrance?: boolean): CanvasCard | null;
|
|
93
70
|
export declare function resizeCard(id: string, width: number, height: number, position?: {
|
|
94
71
|
readonly x: number;
|
|
95
72
|
readonly y: number;
|
|
96
73
|
}): void;
|
|
97
|
-
export declare function getBoardCamera(): CanvasCamera;
|
|
98
|
-
export declare function setBoardCamera(camera: CanvasCamera): void;
|
|
99
|
-
export declare function updateBoardCamera(partial: Partial<CanvasCamera>): void;
|
|
100
74
|
export declare function fitAllCards(viewport?: {
|
|
101
75
|
width: number;
|
|
102
76
|
height: number;
|
|
103
77
|
}): void;
|
|
104
|
-
/** Fits a selected set of cards while preserving cards outside that set. */
|
|
105
|
-
export declare function fitCanvasCards(cardIds: readonly string[], viewport?: {
|
|
106
|
-
width: number;
|
|
107
|
-
height: number;
|
|
108
|
-
}): boolean;
|
|
109
78
|
/** Centers a selected set of cards without changing the current zoom. */
|
|
110
79
|
export declare function focusCanvasCards(cardIds: readonly string[], viewport?: {
|
|
111
80
|
width: number;
|
|
112
81
|
height: number;
|
|
113
82
|
}): boolean;
|
|
114
|
-
export declare function hasFitAllRan(): boolean;
|
|
115
|
-
export declare function resetFitAllFlag(): void;
|
|
116
83
|
export declare function findCardByNormalizedUrl(normalized: NormalizedUrl): CanvasCard | undefined;
|
|
117
84
|
export declare function focusCard(id: string): void;
|
|
118
85
|
export declare function getFocusedCardId(): string | null;
|
|
@@ -122,11 +89,8 @@ export declare function getSelectedCardId(): string | null;
|
|
|
122
89
|
export declare function useSelectedCardId(): string | null;
|
|
123
90
|
export declare function useFocusedCardId(): string | null;
|
|
124
91
|
export declare function setCardPosition(id: string, x: number, y: number): void;
|
|
125
|
-
export declare function hydrateCanvasStore(newMode: CanvasMode, newCards: CanvasCard[], newCamera: CanvasCamera,
|
|
126
|
-
export { subscribe,
|
|
127
|
-
export declare function useCanvasMode(): CanvasMode;
|
|
128
|
-
export declare function useCanvasPresentation(): CanvasPresentation;
|
|
129
|
-
export declare function useCanvasPresentationTransitioning(): boolean;
|
|
92
|
+
export declare function hydrateCanvasStore(newMode: CanvasMode, newCards: CanvasCard[], newCamera: CanvasCamera, restoredFocusedCardId?: string | null, restoredPresentation?: CanvasPresentation, restoredGroups?: readonly FrameGroup[]): void;
|
|
93
|
+
export { subscribe, getCards, getCards as getCanvasCards, };
|
|
130
94
|
export declare function useCanvasCards(): CanvasCard[];
|
|
131
|
-
|
|
132
|
-
export declare function
|
|
95
|
+
/** Returns a route-based label that distinguishes copies and HTML iterations. */
|
|
96
|
+
export declare function getCanvasCardLabel(card: CanvasCard, frameCards?: readonly CanvasCard[]): string;
|