nudge-ui 0.2.2 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (244) hide show
  1. package/README.md +164 -46
  2. package/dist/client.mjs +260 -61
  3. package/dist/css/value-semantics/colorSemantics.d.ts +4 -0
  4. package/dist/css/value-semantics/colorSemantics.js +17 -0
  5. package/dist/hosts/astro/astroRuntimeConfig.js +1 -0
  6. package/dist/hosts/astro/clientTransport.js +38 -32
  7. package/dist/hosts/astro/integration.js +5 -1
  8. package/dist/hosts/astro/markdownIdentity.d.ts +28 -0
  9. package/dist/hosts/astro/markdownIdentity.js +81 -0
  10. package/dist/hosts/next/manifest.js +1 -1
  11. package/dist/hosts/next/sidecar.js +5 -1
  12. package/dist/hosts/static/manifest.js +1 -1
  13. package/dist/hosts/static/server.js +3 -0
  14. package/dist/hosts/vite/vite.d.ts +3 -0
  15. package/dist/hosts/vite/vite.js +24 -4
  16. package/dist/inspector/agent/McpConnectionDialog.js +13 -19
  17. package/dist/inspector/agent/activity.d.ts +18 -0
  18. package/dist/inspector/agent/activity.js +70 -0
  19. package/dist/inspector/agent/client.d.ts +2 -0
  20. package/dist/inspector/agent/client.js +29 -1
  21. package/dist/inspector/agent/connectionStatus.js +1 -1
  22. package/dist/inspector/agent/httpTransport.js +9 -2
  23. package/dist/inspector/agent/protocol.d.ts +6 -3
  24. package/dist/inspector/agent/protocol.js +1 -1
  25. package/dist/inspector/agent/verification.d.ts +15 -7
  26. package/dist/inspector/agent/verification.js +113 -41
  27. package/dist/inspector/canvas/AgentActivityOverlay.d.ts +13 -0
  28. package/dist/inspector/canvas/AgentActivityOverlay.js +111 -0
  29. package/dist/inspector/canvas/CanvasCard.d.ts +9 -2
  30. package/dist/inspector/canvas/CanvasCard.js +135 -38
  31. package/dist/inspector/canvas/CanvasElementOverlay.js +166 -16
  32. package/dist/inspector/canvas/CanvasToolIcons.d.ts +10 -0
  33. package/dist/inspector/canvas/CanvasToolIcons.js +20 -0
  34. package/dist/inspector/canvas/CanvasToolbar.js +8 -4
  35. package/dist/inspector/canvas/CanvasWorkspace.js +270 -122
  36. package/dist/inspector/canvas/StaleChangeIndicator.js +3 -13
  37. package/dist/inspector/canvas/agentPresentation.d.ts +8 -8
  38. package/dist/inspector/canvas/agentPresentation.js +64 -52
  39. package/dist/inspector/canvas/canvasGestures.d.ts +1 -1
  40. package/dist/inspector/canvas/canvasGestures.js +1 -1
  41. package/dist/inspector/canvas/canvasStore.d.ts +46 -82
  42. package/dist/inspector/canvas/canvasStore.js +251 -284
  43. package/dist/inspector/canvas/frameContent.d.ts +21 -0
  44. package/dist/inspector/canvas/frameContent.js +44 -0
  45. package/dist/inspector/canvas/frameProtocol.d.ts +21 -4
  46. package/dist/inspector/canvas/frameProtocol.js +3 -3
  47. package/dist/inspector/canvas/frameScrollbarStyles.d.ts +3 -0
  48. package/dist/inspector/canvas/frameScrollbarStyles.js +21 -0
  49. package/dist/inspector/canvas/keyboardShortcuts.d.ts +3 -1
  50. package/dist/inspector/canvas/keyboardShortcuts.js +4 -4
  51. package/dist/inspector/canvas/layout.d.ts +52 -0
  52. package/dist/inspector/canvas/layout.js +106 -0
  53. package/dist/inspector/canvas/projection.d.ts +15 -5
  54. package/dist/inspector/canvas/projection.js +69 -13
  55. package/dist/inspector/canvas/rendererBootstrap.js +32 -4
  56. package/dist/inspector/canvas/rendererElementSelector.js +47 -6
  57. package/dist/inspector/canvas/rendererStylesheet.js +2 -2
  58. package/dist/inspector/canvas/resizeHandleScale.js +1 -1
  59. package/dist/inspector/canvas/sessionStore.d.ts +11 -26
  60. package/dist/inspector/canvas/sessionStore.js +43 -183
  61. package/dist/inspector/canvas/staleChangeDetector.js +9 -3
  62. package/dist/inspector/canvas/useCanvasLayoutAnimation.d.ts +5 -0
  63. package/dist/inspector/canvas/useCanvasLayoutAnimation.js +107 -0
  64. package/dist/inspector/canvas/viewStore.d.ts +38 -0
  65. package/dist/inspector/canvas/viewStore.js +104 -0
  66. package/dist/inspector/canvas/wheelPan.d.ts +8 -0
  67. package/dist/inspector/canvas/wheelPan.js +8 -0
  68. package/dist/inspector/changes/changesLog.d.ts +9 -6
  69. package/dist/inspector/changes/changesLog.js +48 -32
  70. package/dist/inspector/changes/codecs.d.ts +1 -0
  71. package/dist/inspector/changes/codecs.js +10 -1
  72. package/dist/inspector/changes/draftChanges.d.ts +58 -0
  73. package/dist/inspector/changes/draftChanges.js +304 -0
  74. package/dist/inspector/changes/editModel.d.ts +10 -0
  75. package/dist/inspector/changes/editModel.js +9 -2
  76. package/dist/inspector/changes/previewDiagnostics.d.ts +4 -2
  77. package/dist/inspector/changes/previewDiagnostics.js +11 -25
  78. package/dist/inspector/changes/types.d.ts +7 -0
  79. package/dist/inspector/clientManifest.d.ts +1 -1
  80. package/dist/inspector/comments/CommentsOverlay.d.ts +2 -0
  81. package/dist/inspector/comments/CommentsOverlay.js +250 -0
  82. package/dist/inspector/comments/element.d.ts +6 -0
  83. package/dist/inspector/comments/element.js +54 -0
  84. package/dist/inspector/comments/store.d.ts +29 -0
  85. package/dist/inspector/comments/store.js +121 -0
  86. package/dist/inspector/comments/verification.d.ts +5 -0
  87. package/dist/inspector/comments/verification.js +52 -0
  88. package/dist/inspector/componentSemantics/adapterRegistry.d.ts +6 -1
  89. package/dist/inspector/componentSemantics/adapterRegistry.js +23 -1
  90. package/dist/inspector/componentSemantics/reactRuntime.d.ts +2 -1
  91. package/dist/inspector/componentSemantics/reactRuntime.js +38 -0
  92. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +4 -2
  93. package/dist/inspector/componentSemantics/runtimeBridge.js +17 -0
  94. package/dist/inspector/componentSemantics/types.d.ts +11 -0
  95. package/dist/inspector/drafts/model.d.ts +35 -0
  96. package/dist/inspector/drafts/model.js +45 -0
  97. package/dist/inspector/drafts/store.d.ts +28 -0
  98. package/dist/inspector/drafts/store.js +231 -0
  99. package/dist/inspector/index.js +20 -27
  100. package/dist/inspector/inline-text/inlineTextEditor.js +7 -0
  101. package/dist/inspector/inspection/useBrowserCssInspection.js +15 -1
  102. package/dist/inspector/iterations/capture.d.ts +2 -0
  103. package/dist/inspector/iterations/capture.js +174 -0
  104. package/dist/inspector/iterations/client.d.ts +7 -0
  105. package/dist/inspector/iterations/client.js +52 -0
  106. package/dist/inspector/iterations/coordinator.d.ts +15 -0
  107. package/dist/inspector/iterations/coordinator.js +130 -0
  108. package/dist/inspector/iterations/prompt.d.ts +3 -0
  109. package/dist/inspector/iterations/prompt.js +26 -0
  110. package/dist/inspector/overlay/DomNavigator.js +21 -15
  111. package/dist/inspector/overlay/interactionStyles.js +3 -1
  112. package/dist/inspector/overlay/spacingGestures.d.ts +13 -1
  113. package/dist/inspector/overlay/spacingGestures.js +82 -5
  114. package/dist/inspector/projection/{workspaceProjection.d.ts → draftProjection.d.ts} +6 -6
  115. package/dist/inspector/projection/{workspaceProjection.js → draftProjection.js} +4 -4
  116. package/dist/inspector/projection/renderedInstance.d.ts +17 -3
  117. package/dist/inspector/projection/renderedInstance.js +62 -11
  118. package/dist/inspector/projection/structuralProjection.d.ts +2 -1
  119. package/dist/inspector/projection/structuralProjection.js +21 -17
  120. package/dist/inspector/projection/textProjection.d.ts +2 -1
  121. package/dist/inspector/projection/textProjection.js +64 -15
  122. package/dist/inspector/prompt/PromptSettingsDialog.js +1 -5
  123. package/dist/inspector/prompt/clipboardHandoff.d.ts +15 -18
  124. package/dist/inspector/prompt/clipboardHandoff.js +97 -143
  125. package/dist/inspector/prompt/generatePrompt.d.ts +4 -1
  126. package/dist/inspector/prompt/generatePrompt.js +22 -17
  127. package/dist/inspector/runtime/runtimeConfig.d.ts +9 -0
  128. package/dist/inspector/runtime/runtimeConfig.js +24 -0
  129. package/dist/inspector/selection/sourceSite.d.ts +12 -0
  130. package/dist/inspector/selection/sourceSite.js +28 -0
  131. package/dist/inspector/settings/SettingsDialog.js +21 -8
  132. package/dist/inspector/shell/AgentStatusButton.d.ts +11 -0
  133. package/dist/inspector/shell/AgentStatusButton.js +36 -0
  134. package/dist/inspector/shell/AppShell.js +4 -2
  135. package/dist/inspector/shell/ChangesLog.js +46 -26
  136. package/dist/inspector/shell/CopyPromptButton.js +184 -93
  137. package/dist/inspector/shell/EmptyState.js +9 -8
  138. package/dist/inspector/shell/InspectorShell.js +13 -21
  139. package/dist/inspector/shell/PeekOriginalButton.js +24 -23
  140. package/dist/inspector/shell/originalPreview.js +5 -5
  141. package/dist/inspector/shell/shortcuts.d.ts +3 -0
  142. package/dist/inspector/shell/shortcuts.js +11 -0
  143. package/dist/inspector/sketch/SketchEditor.js +14 -14
  144. package/dist/inspector/sketch/SketchEntryButton.js +1 -1
  145. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +3 -1
  146. package/dist/inspector/sketch/SketchFrameOverlay.js +11 -8
  147. package/dist/inspector/sketch/SketchLayersPanel.js +13 -5
  148. package/dist/inspector/sketch/SketchOverlay.js +7 -7
  149. package/dist/inspector/sketch/SketchWorkspace.js +18 -12
  150. package/dist/inspector/sketch/interaction.d.ts +1 -0
  151. package/dist/inspector/sketch/interaction.js +8 -4
  152. package/dist/inspector/sketch/model.d.ts +5 -0
  153. package/dist/inspector/sketch/model.js +6 -2
  154. package/dist/inspector/sketch/raster.d.ts +1 -2
  155. package/dist/inspector/sketch/raster.js +68 -4
  156. package/dist/inspector/styleEditors/BackgroundEditor.d.ts +4 -0
  157. package/dist/inspector/styleEditors/BackgroundEditor.js +195 -0
  158. package/dist/inspector/styleEditors/BorderEditor.js +49 -78
  159. package/dist/inspector/styleEditors/BorderRadiusEditor.js +6 -1
  160. package/dist/inspector/styleEditors/BoxShadowEditor.d.ts +1 -2
  161. package/dist/inspector/styleEditors/BoxShadowEditor.js +132 -4
  162. package/dist/inspector/styleEditors/ColorPicker.d.ts +5 -1
  163. package/dist/inspector/styleEditors/ColorPicker.js +10 -4
  164. package/dist/inspector/styleEditors/GapField.js +3 -5
  165. package/dist/inspector/styleEditors/GridChildSection.d.ts +1 -1
  166. package/dist/inspector/styleEditors/GridChildSection.js +18 -9
  167. package/dist/inspector/styleEditors/GridPicker.d.ts +1 -1
  168. package/dist/inspector/styleEditors/GridPicker.js +8 -2
  169. package/dist/inspector/styleEditors/GridSection.js +1 -1
  170. package/dist/inspector/styleEditors/GridValueField.js +19 -14
  171. package/dist/inspector/styleEditors/ImageBackgroundEditor.d.ts +18 -0
  172. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +118 -0
  173. package/dist/inspector/styleEditors/LayoutBlockedIndicator.d.ts +2 -2
  174. package/dist/inspector/styleEditors/LayoutBlockedIndicator.js +3 -3
  175. package/dist/inspector/styleEditors/LayoutComboField.js +6 -4
  176. package/dist/inspector/styleEditors/LayoutDropdown.js +6 -3
  177. package/dist/inspector/styleEditors/LayoutSection.js +32 -11
  178. package/dist/inspector/styleEditors/SpacingBox.js +7 -5
  179. package/dist/inspector/styleEditors/Typography.js +11 -3
  180. package/dist/inspector/styleEditors/backgroundLayers.d.ts +24 -0
  181. package/dist/inspector/styleEditors/backgroundLayers.js +51 -0
  182. package/dist/inspector/styleEditors/gradientValue.d.ts +17 -0
  183. package/dist/inspector/styleEditors/gradientValue.js +114 -0
  184. package/dist/inspector/styleEditors/inlineAuthored.d.ts +10 -0
  185. package/dist/inspector/styleEditors/inlineAuthored.js +114 -0
  186. package/dist/inspector/styleEditors/layoutValue.d.ts +0 -8
  187. package/dist/inspector/styleEditors/layoutValue.js +0 -42
  188. package/dist/inspector/styleEditors/nudgeValue.d.ts +2 -2
  189. package/dist/inspector/styleEditors/nudgeValue.js +36 -8
  190. package/dist/inspector/tokens/TokenField.d.ts +7 -0
  191. package/dist/inspector/tokens/TokenField.js +35 -25
  192. package/dist/inspector/tokens/TokenLabel.js +5 -14
  193. package/dist/inspector/tokens/editActions.d.ts +1 -1
  194. package/dist/inspector/tokens/editActions.js +7 -1
  195. package/dist/inspector/ui/AtRuleContext.js +4 -6
  196. package/dist/inspector/ui/Button.d.ts +6 -2
  197. package/dist/inspector/ui/Button.js +4 -3
  198. package/dist/inspector/ui/ControlSurface.d.ts +2 -2
  199. package/dist/inspector/ui/ControlSurface.js +4 -3
  200. package/dist/inspector/ui/InlineStyleWarning.d.ts +11 -0
  201. package/dist/inspector/ui/InlineStyleWarning.js +13 -0
  202. package/dist/inspector/ui/InspectorPopover.d.ts +2 -1
  203. package/dist/inspector/ui/InspectorPopover.js +4 -5
  204. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  205. package/dist/inspector/ui/PopoverListbox.js +8 -7
  206. package/dist/inspector/ui/SegmentedControl.d.ts +2 -1
  207. package/dist/inspector/ui/SegmentedControl.js +2 -2
  208. package/dist/inspector/ui/Select.d.ts +6 -1
  209. package/dist/inspector/ui/Select.js +7 -11
  210. package/dist/inspector/ui/SideValuesField.js +1 -1
  211. package/dist/inspector/ui/Tooltip.d.ts +26 -0
  212. package/dist/inspector/ui/Tooltip.js +32 -0
  213. package/dist/inspector/ui/classNames.d.ts +2 -0
  214. package/dist/inspector/ui/classNames.js +4 -0
  215. package/dist/inspector/ui/customCursors.d.ts +23 -0
  216. package/dist/inspector/ui/customCursors.js +122 -0
  217. package/dist/inspector/ui/dragCursor.d.ts +0 -2
  218. package/dist/inspector/ui/dragCursor.js +2 -10
  219. package/dist/inspector/ui/portalContainer.d.ts +2 -0
  220. package/dist/inspector/ui/portalContainer.js +6 -0
  221. package/dist/inspector/ui/styles.js +29 -21
  222. package/dist/inspector/workspace/commands.d.ts +9 -0
  223. package/dist/inspector/workspace/commands.js +82 -0
  224. package/dist/inspector/workspace/controller.d.ts +4 -0
  225. package/dist/inspector/workspace/controller.js +66 -0
  226. package/dist/inspector/workspace/handoff.d.ts +42 -0
  227. package/dist/inspector/workspace/handoff.js +115 -0
  228. package/dist/inspector/workspace/sentItems.d.ts +19 -0
  229. package/dist/inspector/workspace/sentItems.js +51 -0
  230. package/dist/inspector/workspace/timeline.d.ts +30 -0
  231. package/dist/inspector/workspace/timeline.js +108 -0
  232. package/dist/internal/agent-protocol.d.ts +19 -2
  233. package/dist/internal/agent-protocol.js +13 -0
  234. package/dist/nudge-ui.mjs +558 -311
  235. package/dist/project/artifacts.d.ts +13 -0
  236. package/dist/project/artifacts.js +253 -0
  237. package/dist/transport/artifacts.d.ts +8 -0
  238. package/dist/transport/artifacts.js +9 -0
  239. package/dist/transport/editor.js +3 -1
  240. package/dist/transport/routes.d.ts +2 -0
  241. package/dist/transport/routes.js +2 -0
  242. package/package.json +7 -3
  243. package/dist/inspector/changes/workspaceChanges.d.ts +0 -47
  244. package/dist/inspector/changes/workspaceChanges.js +0 -265
@@ -3,8 +3,6 @@ import { useSyncExternalStore } from "react";
3
3
  import { isPreviewableChange, isTokenChange } from "../changes/changesLog.js";
4
4
  import { changeKey } from "../changes/model.js";
5
5
  import { getAnyPreviewDiagnostic, getPreviewDiagnosticRevision, subscribePreviewDiagnostics, } from "../changes/previewDiagnostics.js";
6
- import { humanizeSelector } from "../tokens/catalog.js";
7
- import { getScopingSelectorPattern } from "../runtime/runtimeConfig.js";
8
6
  import { isVerificationPending } from "./staleChangeDetector.js";
9
7
  export function StaleChangeIndicator({ change }) {
10
8
  useSyncExternalStore(subscribePreviewDiagnostics, getPreviewDiagnosticRevision, getPreviewDiagnosticRevision);
@@ -21,23 +19,15 @@ export function StaleChangeIndicator({ change }) {
21
19
  return (_jsx("span", { className: "changes__diagnostic", "data-test": "preview-applied", "data-status": "applied", children: "Preview active" }));
22
20
  }
23
21
  if (result.reason === "target-missing") {
24
- // ADR-0011: host scoping markers are opaque structure and must not
25
- // surface as human-facing guidance; the raw selector stays in change
26
- // records for managed-rule targeting.
27
- const selectorLabel = humanizeSelector(change.selector, getScopingSelectorPattern())
28
- || change.selector;
29
- return (_jsx("span", { className: "changes__stale", "data-test": "stale-missing", title: `Selector: ${selectorLabel}`, children: "Source missing \u2014 this edit may be stale" }));
22
+ return (_jsx("span", { className: "changes__stale", "data-test": "stale-missing", children: "Source missing \u2014 this edit may be stale" }));
30
23
  }
31
24
  if (result.reason === "token-drift") {
32
- const currentValue = result.computedValue
33
- ? ` (current: ${result.computedValue})`
34
- : "";
35
25
  if (isTokenChange(change)) {
36
- return (_jsx("span", { className: "changes__stale", "data-test": "stale-token-drift", title: `Token ${change.tokenName} baseline has changed since this edit was made${currentValue}`, children: "Token baseline has changed" }));
26
+ return (_jsx("span", { className: "changes__stale", "data-test": "stale-token-drift", children: "Token baseline has changed" }));
37
27
  }
38
28
  return null;
39
29
  }
40
- return (_jsxs("span", { className: "changes__conflict", "data-test": "preview-conflict", title: `Computed: ${result.computedValue}`, children: ["Preview Blocked (", result.reason
30
+ return (_jsxs("span", { className: "changes__conflict", "data-test": "preview-conflict", children: ["Preview Blocked (", result.reason
41
31
  ? result.reason.replace(/-/g, " ")
42
32
  : "Unknown", ")"] }));
43
33
  }
@@ -1,5 +1,5 @@
1
- import { type CanvasCommand, type CanvasCommandResult, type CanvasState } from "../../internal/agent-protocol.js";
2
- import { type CanvasCard, type CanvasComparisonGroup } from "./canvasStore.js";
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 PresentAgentComparisonGroupInput {
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 AgentComparisonGroupPresentation {
39
- group: CanvasComparisonGroup;
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 presentAgentComparisonGroup(input: PresentAgentComparisonGroupInput): Promise<AgentComparisonGroupPresentation>;
58
- export declare function focusAgentComparisonGroup(groupId: string, viewport?: {
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 removeOwnAgentComparisonGroup(groupId: string, agentId?: string): AgentPresentationState;
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 { appendCanvasComparisonGroup, fitAllCards, focusCard, focusCanvasCards, getCanvasCards, getCanvasComparisonGroup, getCanvasComparisonGroups, getCanvasMode, getFocusedCardId, removeCanvasComparisonGroup, setCanvasMode, } from "./canvasStore.js";
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 comparison group label is required.");
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", `Comparison group labels must be between 1 and ${MAX_GROUP_LABEL_LENGTH} printable characters.`);
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 comparison route must be a URL object.");
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 comparison route is required.");
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 comparison group may contain at most ${MAX_PRESENTATION_ROUTES} routes.`);
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 : "Comparison routes must be same-origin URLs.");
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(group) {
193
+ function toProtocolGroup(groupId) {
194
+ const group = getFrameGroup(groupId);
191
195
  return {
192
- id: group.id,
193
- label: group.label,
196
+ id: groupId,
197
+ label: group?.label ?? "",
194
198
  owner: "agent",
195
- routes: group.routes.map((route) => ({
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: getCanvasComparisonGroups().map(toProtocolGroup),
211
- focusedGroupId: focusedCard?.comparisonGroupId ?? null,
212
- focusedRouteUrl: focusedCard?.url ?? null,
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 presentAgentComparisonGroup(input) {
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 comparison group ID is required.");
244
+ throw new AgentPresentationError("invalid-command", "A route group ID is required.");
232
245
  }
233
- if (getCanvasComparisonGroup(groupId)) {
234
- throw new AgentPresentationError("group-id-conflict", `Comparison group ${groupId} already exists.`);
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 appended = appendCanvasComparisonGroup({
241
- id: groupId,
242
- label,
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
- ...(route.label === undefined ? {} : { label: route.label }),
249
- })),
260
+ })));
250
261
  });
251
- if (!appended) {
252
- throw new AgentPresentationError("group-id-conflict", `Comparison group ${groupId} already exists.`);
262
+ if (!cards) {
263
+ throw new AgentPresentationError("group-id-conflict", `Route group ${groupId} already exists.`);
253
264
  }
254
- const cardIds = appended.cards.map((card) => card.id);
265
+ const cardIds = cards.map((card) => card.id);
255
266
  beginRendererReadiness(cardIds);
256
267
  const readiness = await waitForAgentRendererReadiness(cardIds, readyTimeoutMs);
257
- return { ...appended, readiness };
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 = getCanvasComparisonGroup(groupId);
265
- if (!group)
266
- throw new AgentPresentationError("group-not-found", `Comparison group ${groupId} was not found.`);
267
- const cardIds = new Set(group.cardIds);
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", `Comparison group ${groupId} has no cards.`);
280
+ throw new AgentPresentationError("group-not-found", `Route group ${groupId} has no cards.`);
271
281
  }
272
- return { group, cards };
282
+ return cards;
273
283
  }
274
- export function focusAgentComparisonGroup(groupId, viewport) {
284
+ export function focusAgentGroup(groupId, viewport) {
275
285
  ensureDevelopment();
276
286
  ensureWritable();
277
- const { cards } = groupCards(groupId);
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 removeOwnAgentComparisonGroup(groupId, agentId = DEFAULT_AGENT_ID) {
298
+ export function removeOwnAgentGroup(groupId, agentId = DEFAULT_AGENT_ID) {
289
299
  ensureDevelopment();
290
300
  ensureWritable();
291
- const group = getCanvasComparisonGroup(groupId);
292
- if (!group)
293
- throw new AgentPresentationError("group-not-found", `Comparison group ${groupId} was not found.`);
294
- if (group.owner !== "agent" || group.agentId !== agentId) {
295
- throw new AgentPresentationError("not-group-owner", `Agent ${agentId} cannot remove comparison group ${groupId}.`);
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 = [...group.cardIds];
298
- removeCanvasComparisonGroup(groupId);
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 presentAgentComparisonGroup({
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: toProtocolGroup(presentation.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: toProtocolGroup(presentation.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: focusAgentComparisonGroup(command.groupId),
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: removeOwnAgentComparisonGroup(command.groupId, agentId),
389
+ state: removeOwnAgentGroup(command.groupId, agentId),
378
390
  };
379
391
  }
380
392
  }
@@ -1,4 +1,4 @@
1
- import { type CanvasCamera } from "./canvasStore.js";
1
+ import { type CanvasCamera } from "./viewStore.js";
2
2
  export declare const ZOOM_WHEEL_FACTOR = 1.02;
3
3
  export interface ClientPoint {
4
4
  x: number;
@@ -1,4 +1,4 @@
1
- import { MAX_CAMERA_ZOOM, MIN_CAMERA_ZOOM, } from "./canvasStore.js";
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 type CanvasMode = "inspect" | "canvas";
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
- /** A durable, agent-owned collection of Canvas cards. */
18
- export interface CanvasComparisonGroup {
10
+ export interface CanvasCard extends FrameGeometry {
19
11
  id: string;
20
- label: string;
21
- /** Public protocol marker. Canvas currently exposes only agent-created groups. */
22
- owner: "agent";
23
- /** Pairing identity used to authorize removal of this group. */
24
- agentId: string;
25
- cardIds: string[];
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 CanvasComparisonGroupRoute {
29
- url: string;
30
- title?: string | null;
31
- label?: string;
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 interface CanvasCamera {
34
- x: number;
35
- y: number;
36
- zoom: number;
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 getComparisonGroups(): CanvasComparisonGroup[];
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
- * Appends an agent-created comparison group without disturbing existing cards.
63
- * Callers validate route URLs and labels at the command boundary; this store
64
- * function only enforces the durable identity and placement invariants.
65
- */
66
- export declare function appendCanvasComparisonGroup(input: {
67
- id: string;
68
- label: string;
69
- agentId: string;
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, newComparisonGroups?: CanvasComparisonGroup[], restoredFocusedCardId?: string | null): void;
126
- export { subscribe, getMode, getCards, getComparisonGroups, getMode as getCanvasMode, getCards as getCanvasCards, getComparisonGroups as getCanvasComparisonGroups, };
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
- export declare function useCanvasComparisonGroups(): CanvasComparisonGroup[];
132
- export declare function useBoardCamera(): CanvasCamera;
95
+ /** Returns a route-based label that distinguishes copies and HTML iterations. */
96
+ export declare function getCanvasCardLabel(card: CanvasCard, frameCards?: readonly CanvasCard[]): string;