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
@@ -1,33 +1,56 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { Menu } from "@base-ui/react/menu";
3
+ import { iterationId } from "../canvas/frameContent.js";
2
4
  import { useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
3
- import { IconCheck, IconCopy, IconPlugConnected, IconSend, } from "@tabler/icons-react";
5
+ import { IconArtboard, IconBoltFilled, IconCheck, IconChevronDown, IconCopy, IconPlugConnected, IconSend, } from "@tabler/icons-react";
4
6
  import { useChanges } from "../changes/changesLog.js";
5
- import { generatePrompt } from "../prompt/generatePrompt.js";
6
- import { copyToClipboard } from "../prompt/copyToClipboard.js";
7
+ import { countPromptChanges } from "../prompt/generatePrompt.js";
7
8
  import { loadCustomInstructions, saveCustomInstructions } from "../prompt/promptSettings.js";
8
9
  import { getAgentConnectionStatus } from "../agent/connectionStatus.js";
9
10
  import { SettingsDialog } from "../settings/SettingsDialog.js";
10
11
  import { Button } from "../ui/Button.js";
12
+ import { portalContainer } from "../ui/portalContainer.js";
11
13
  import { StatusCallout } from "../ui/StatusCallout.js";
12
14
  import { getStructuralChanges, subscribeStructuralChanges } from "../projection/structuralProjection.js";
13
15
  import { getNudgeUiRuntimeConfig } from "../runtime/runtimeConfig.js";
14
- import { createPromptRevision, getAgentClient, useAgentClient, } from "../agent/client.js";
16
+ import { getAgentClient, useAgentClient } from "../agent/client.js";
15
17
  import { createAgentPresentationAdapter } from "../canvas/agentPresentation.js";
16
- import { discardAgentDispatch, recordAgentDispatch, verifyAndReconcileAgentDispatch, } from "../agent/verification.js";
17
- import { getClipboardHandoffRevision, getLastClipboardReconciledCount, recordClipboardHandoff, subscribeClipboardHandoff, } from "../prompt/clipboardHandoff.js";
18
- import { useSketches, markSketchesDispatching, markSketchesHandingOff, settleSketchDispatch } from "../sketch/store.js";
19
- import { createSketchAttachments, createSketchHandoffSnapshot, sketchMetadataForHandoff, } from "../sketch/handoff.js";
18
+ import { captureHandoffOwner, getAgentDispatch, verifyAndReconcileAgentDispatch, } from "../agent/verification.js";
19
+ import { clearSentItems, getSentItems, sentItemCount } from "../workspace/sentItems.js";
20
+ import { getClipboardHandoffRevision, getLastClipboardReconciledCount, subscribeClipboardHandoff, } from "../prompt/clipboardHandoff.js";
21
+ import { useSketches, settleSketchDispatch } from "../sketch/store.js";
20
22
  import { SketchLayersPanel } from "../sketch/SketchLayersPanel.js";
21
23
  import { isSendPromptShortcut, SEND_PROMPT_HOTKEY_EVENT } from "./shortcuts.js";
24
+ import { getFocusedCardId, getSelectedCardId, useCanvasCards, useFocusedCardId, useSelectedCardId } from "../canvas/canvasStore.js";
25
+ import { getEditableCardId, sketchBelongsToCard, useDrafts } from "../drafts/store.js";
26
+ import { copyHandoff, deliverHandoff, prepareHandoff, prepareIterationImplementationPrompt } from "../workspace/handoff.js";
27
+ import { copyToClipboard } from "../prompt/copyToClipboard.js";
28
+ import { useFrameComments } from "../comments/store.js";
29
+ import { reconcileComments } from "../comments/verification.js";
30
+ import { getRegisteredFrames } from "../canvas/projection.js";
22
31
  export function CopyPromptButton({ settingsOpen: controlledSettingsOpen, settingsSection: controlledSettingsSection, onOpenSettings, onSettingsOpenChange, } = {}) {
23
32
  const changes = useChanges();
33
+ const comments = useFrameComments();
34
+ useDrafts();
24
35
  const sketches = useSketches();
25
- const pendingSketches = sketches.filter((item) => item.status === "pending");
36
+ const selectedDraftCardId = useSelectedCardId();
37
+ const focusedDraftCardId = useFocusedCardId();
38
+ const activeDraftCardId = getEditableCardId(selectedDraftCardId, focusedDraftCardId);
39
+ const canvasCards = useCanvasCards();
40
+ const activeContent = canvasCards.find((card) => card.id === activeDraftCardId)?.content;
41
+ const activeArtifactId = iterationId(activeContent);
42
+ const visibleSketches = sketches.filter((item) => sketchBelongsToCard(item.document, activeDraftCardId));
43
+ const pendingSketches = visibleSketches.filter((item) => item.status === "pending");
26
44
  const structuralChanges = useSyncExternalStore(subscribeStructuralChanges, getStructuralChanges, getStructuralChanges);
27
45
  useSyncExternalStore(subscribeClipboardHandoff, getClipboardHandoffRevision, getClipboardHandoffRevision);
28
46
  const reconciledCount = getLastClipboardReconciledCount();
29
47
  const [copied, setCopied] = useState(false);
30
- const [agentCompletionStatus, setAgentCompletionStatus] = useState(null);
48
+ const [preparing, setPreparing] = useState(false);
49
+ const handoffBusy = useRef(false);
50
+ const [saveMessage, setSaveMessage] = useState(null);
51
+ const [agentOutcome, setAgentOutcome] = useState(null);
52
+ const [clipboardPhase, setClipboardPhase] = useState("idle");
53
+ const [undoClear, setUndoClear] = useState(null);
31
54
  const [sketchFallback, setSketchFallback] = useState(null);
32
55
  const [localSettingsOpen, setLocalSettingsOpen] = useState(false);
33
56
  const [localSettingsSection, setLocalSettingsSection] = useState("instructions");
@@ -39,8 +62,13 @@ export function CopyPromptButton({ settingsOpen: controlledSettingsOpen, setting
39
62
  const agent = useAgentClient(runtimeConfig.projectId, agentClient);
40
63
  const agentRef = useRef(agent);
41
64
  agentRef.current = agent;
42
- const hasChanges = changes.length + structuralChanges.length + pendingSketches.length > 0;
43
- const changeCount = changes.length + structuralChanges.length + sketches.length;
65
+ const hasChanges = Boolean(activeArtifactId) || countPromptChanges(changes, structuralChanges, pendingSketches.length) + comments.length > 0;
66
+ useEffect(() => {
67
+ if (!copied)
68
+ return;
69
+ const timer = window.setTimeout(() => setCopied(false), 1500);
70
+ return () => window.clearTimeout(timer);
71
+ }, [copied]);
44
72
  useEffect(() => {
45
73
  setCustomInstructions(loadCustomInstructions(runtimeConfig.projectId));
46
74
  }, [runtimeConfig.projectId]);
@@ -60,14 +88,22 @@ export function CopyPromptButton({ settingsOpen: controlledSettingsOpen, setting
60
88
  if (agent.state !== "completed" || revision === undefined)
61
89
  return;
62
90
  let active = true;
91
+ const dispatch = getAgentDispatch(revision);
63
92
  void verifyAndReconcileAgentDispatch(revision)
93
+ .then(async (removed) => {
94
+ for (const [, iframe] of getRegisteredFrames()) {
95
+ if (iframe.contentDocument)
96
+ await reconcileComments(iframe.contentDocument);
97
+ }
98
+ return removed;
99
+ })
64
100
  .then((removed) => {
65
101
  if (!active)
66
102
  return;
67
103
  const latest = agentRef.current;
68
104
  if (latest.request?.changeRevision !== revision || latest.state !== "completed")
69
105
  return;
70
- setAgentCompletionStatus(removed > 0 ? "verified" : null);
106
+ setAgentOutcome({ removed, dispatch });
71
107
  })
72
108
  .catch(() => {
73
109
  if (!active)
@@ -75,7 +111,7 @@ export function CopyPromptButton({ settingsOpen: controlledSettingsOpen, setting
75
111
  const latest = agentRef.current;
76
112
  if (latest.request?.changeRevision !== revision || latest.state !== "completed")
77
113
  return;
78
- setAgentCompletionStatus(null);
114
+ setAgentOutcome({ removed: 0, dispatch });
79
115
  });
80
116
  return () => {
81
117
  active = false;
@@ -95,95 +131,151 @@ export function CopyPromptButton({ settingsOpen: controlledSettingsOpen, setting
95
131
  && !connecting
96
132
  && !working;
97
133
  const canSend = agent.paired && agent.listenerActive && !working;
98
- const disabled = connecting || working || (!canConnect && !hasChanges);
134
+ const changeCount = countPromptChanges(changes, structuralChanges, canSend ? pendingSketches.length : 0) + comments.length;
135
+ const disabled = preparing || connecting || working || (!canConnect && !hasChanges);
99
136
  const agentStatus = getAgentConnectionStatus(agent);
100
137
  const statusAction = agentStatus.action;
101
- const label = copied
102
- ? "Copied!"
103
- : connecting
104
- ? "Connecting…"
105
- : working
106
- ? "Agent working…"
107
- : canConnect
108
- ? "Connect agent"
109
- : canSend
110
- ? "Send prompt"
111
- : "Copy prompt";
138
+ const label = preparing
139
+ ? "Saving iteration…"
140
+ : copied
141
+ ? "Copied!"
142
+ : connecting
143
+ ? "Connecting…"
144
+ : working
145
+ ? "Agent working…"
146
+ : canConnect && !activeArtifactId
147
+ ? "Connect agent"
148
+ : canSend && !activeArtifactId
149
+ ? "Send prompt"
150
+ : "Copy prompt";
112
151
  const icon = copied
113
152
  ? _jsx(IconCheck, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" })
114
- : canConnect || connecting
153
+ : !activeArtifactId && (canConnect || connecting)
115
154
  ? _jsx(IconPlugConnected, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" })
116
- : canSend || working
155
+ : !activeArtifactId && (canSend || working)
117
156
  ? _jsx(IconSend, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" })
118
157
  : _jsx(IconCopy, { size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" });
119
158
  async function onClick() {
120
- if (disabled)
121
- return;
122
- if (canConnect) {
123
- await agentClient.connect();
159
+ if (disabled || handoffBusy.current)
124
160
  return;
161
+ handoffBusy.current = true;
162
+ setPreparing(Boolean(activeArtifactId) && !canConnect);
163
+ try {
164
+ await handoff();
125
165
  }
126
- const hints = {
127
- framework: runtimeConfig.framework,
128
- stylingSystem: runtimeConfig.stylingSystem,
129
- };
130
- const sketchHandoff = createSketchHandoffSnapshot(pendingSketches);
131
- const sketchMetadata = sketchHandoff ? sketchMetadataForHandoff(sketchHandoff) : [];
132
- const text = generatePrompt(changes, hints, structuralChanges, customInstructions, sketchMetadata);
133
- setAgentCompletionStatus(null);
134
- setSketchFallback(null);
135
- if (canSend) {
136
- const revision = createPromptRevision(changes, structuralChanges, sketchMetadata);
137
- recordAgentDispatch(revision, changes, structuralChanges);
138
- const clientDispatchId = sketchHandoff?.localBatchId ?? `dispatch-${Date.now()}-${Math.random().toString(36).slice(2)}`;
139
- let attachments = undefined;
140
- try {
141
- if (sketchHandoff) {
142
- await markSketchesDispatching(sketchHandoff.entries.map((entry) => ({ id: entry.id, revision: entry.revision })), revision, sketchHandoff.localBatchId);
143
- attachments = await createSketchAttachments(sketchHandoff);
144
- }
145
- const response = await agentClient.dispatchPrompt(text, revision, {
146
- clientDispatchId,
147
- ...(attachments === undefined ? {} : { attachments }),
148
- });
149
- if (response) {
150
- if (sketchHandoff) {
151
- await markSketchesHandingOff(sketchHandoff.entries.map((entry) => ({ id: entry.id, revision: entry.revision })), revision, sketchHandoff.localBatchId, response.request.requestId);
152
- }
153
- return;
166
+ finally {
167
+ handoffBusy.current = false;
168
+ setPreparing(false);
169
+ }
170
+ }
171
+ async function copyIterationPrompt(target) {
172
+ if (!activeArtifactId || disabled || handoffBusy.current)
173
+ return;
174
+ handoffBusy.current = true;
175
+ setCopied(false);
176
+ setPreparing(true);
177
+ try {
178
+ const request = {
179
+ cardId: getEditableCardId(getSelectedCardId(), getFocusedCardId()),
180
+ hints: { framework: runtimeConfig.framework, stylingSystem: runtimeConfig.stylingSystem },
181
+ customInstructions,
182
+ pendingSketches,
183
+ };
184
+ if (target === "application") {
185
+ const prompt = await prepareIterationImplementationPrompt(request);
186
+ try {
187
+ await copyToClipboard(prompt);
154
188
  }
155
- if (sketchHandoff) {
156
- await settleSketchDispatch(revision, "failed", undefined, sketchHandoff.localBatchId);
157
- discardAgentDispatch(revision);
158
- const latestAgent = agentClient.getSnapshot();
159
- setSketchFallback({
160
- prompt: text,
161
- error: latestAgent.request?.error
162
- ?? latestAgent.error
163
- ?? "The agent did not accept the sketch attachments.",
164
- });
165
- return;
189
+ catch {
190
+ throw new Error("The iteration was saved, but the prompt could not be copied. Try again.");
166
191
  }
167
192
  }
168
- catch (error) {
169
- discardAgentDispatch(revision);
170
- if (sketchHandoff) {
171
- await settleSketchDispatch(revision, "failed", undefined, sketchHandoff.localBatchId).catch(() => undefined);
172
- setSketchFallback({
173
- prompt: text,
174
- error: error instanceof Error ? error.message : "The sketch could not be sent to the agent.",
175
- });
176
- return;
193
+ else {
194
+ const prepared = await prepareHandoff(request);
195
+ try {
196
+ await copyHandoff(prepared);
197
+ }
198
+ catch {
199
+ throw new Error("The iteration was saved, but the prompt could not be copied. Try again.");
177
200
  }
178
201
  }
179
- discardAgentDispatch(revision);
202
+ setSaveMessage(null);
203
+ setCopied(true);
204
+ }
205
+ catch (error) {
206
+ setSaveMessage(error instanceof Error ? error.message : "The prompt could not be copied. Try again.");
207
+ }
208
+ finally {
209
+ handoffBusy.current = false;
210
+ setPreparing(false);
211
+ }
212
+ }
213
+ async function handoff() {
214
+ if (disabled)
215
+ return;
216
+ if (canConnect) {
217
+ await agentClient.connect();
218
+ return;
219
+ }
220
+ let prepared;
221
+ try {
222
+ prepared = await prepareHandoff({
223
+ cardId: getEditableCardId(getSelectedCardId(), getFocusedCardId()),
224
+ hints: { framework: runtimeConfig.framework, stylingSystem: runtimeConfig.stylingSystem },
225
+ customInstructions,
226
+ pendingSketches,
227
+ });
228
+ setSaveMessage(null);
180
229
  }
181
- await copyToClipboard(text);
182
- if (changes.length > 0 || structuralChanges.length > 0) {
183
- recordClipboardHandoff(changes, structuralChanges);
230
+ catch (error) {
231
+ setSaveMessage(error instanceof Error ? error.message : "The HTML iteration could not be saved.");
232
+ return;
233
+ }
234
+ setAgentOutcome(null);
235
+ setUndoClear(null);
236
+ setClipboardPhase("idle");
237
+ setSketchFallback(null);
238
+ const outcome = await deliverHandoff(prepared, runtimeConfig.projectId, canSend ? agentClient : null);
239
+ if (outcome.kind === "sketch-failed") {
240
+ setSketchFallback({ handoff: outcome.handoff, error: outcome.error });
241
+ return;
184
242
  }
243
+ if (outcome.kind === "sent")
244
+ return;
185
245
  setCopied(true);
186
- window.setTimeout(() => setCopied(false), 1500);
246
+ setClipboardPhase("copied");
247
+ }
248
+ useEffect(() => {
249
+ if (clipboardPhase !== "copied" && clipboardPhase !== "away")
250
+ return;
251
+ // Focus moving into a canvas frame is not a return from the agent.
252
+ const onBlur = () => {
253
+ if (!(document.activeElement instanceof HTMLIFrameElement))
254
+ setClipboardPhase("away");
255
+ };
256
+ const onFocus = () => setClipboardPhase((phase) => phase === "away" ? "returned" : phase);
257
+ window.addEventListener("blur", onBlur);
258
+ window.addEventListener("focus", onFocus);
259
+ return () => {
260
+ window.removeEventListener("blur", onBlur);
261
+ window.removeEventListener("focus", onFocus);
262
+ };
263
+ }, [clipboardPhase]);
264
+ useEffect(() => {
265
+ if (!undoClear)
266
+ return;
267
+ const timer = window.setTimeout(() => setUndoClear(null), 10_000);
268
+ return () => window.clearTimeout(timer);
269
+ }, [undoClear]);
270
+ const handoffOwner = captureHandoffOwner(activeDraftCardId);
271
+ const sentItems = getSentItems(handoffOwner.draftId, handoffOwner.target, agentOutcome?.dispatch ?? null);
272
+ const remainingCount = sentItemCount(sentItems);
273
+ const showImplemented = (agentOutcome?.removed ?? 0) > 0 || reconciledCount > 0
274
+ || (remainingCount > 0 && (agentOutcome !== null || clipboardPhase === "returned"));
275
+ function clearRemaining() {
276
+ const restore = clearSentItems(sentItems);
277
+ if (restore)
278
+ setUndoClear(() => restore);
187
279
  }
188
280
  useEffect(() => {
189
281
  function onKeydown(event) {
@@ -231,12 +323,11 @@ export function CopyPromptButton({ settingsOpen: controlledSettingsOpen, setting
231
323
  }
232
324
  openMcpConnection();
233
325
  }
234
- return (_jsxs("div", { className: "copy-prompt__stack", "data-test": "copy-prompt-control", children: [_jsxs(Button, { variant: "primary", className: "copy-prompt__main", "data-test": "copy-prompt", type: "button", disabled: disabled, "data-copied": copied ? "true" : "false", "data-agent-state": agent.state, "data-agent-listening": agentStatus.kind === "listening" ? "true" : undefined, "aria-busy": working || connecting ? "true" : undefined, title: agent.error, onClick: onClick, children: [icon, label, changeCount > 0 ? (_jsx("span", { className: "copy-prompt__change-count", "data-test": "copy-prompt-change-count", children: changeCount })) : null, agentStatus.kind === "listening" ? (_jsx("span", { className: "copy-prompt__agent-listening", "data-test": "agent-listening-indicator", role: "status", "aria-label": "Agent listening" })) : null] }), _jsx(SketchLayersPanel, {}), statusAction || agentStatus.kind === "connected-not-listening" ? (_jsx(StatusCallout, { className: "copy-prompt__agent-status", tone: agentStatus.tone, "data-test": "agent-connection-status", children: _jsxs("div", { className: "copy-prompt__agent-status-content", children: [_jsx("span", { role: "status", children: agentStatus.label }), statusAction ? (_jsx(Button, { size: "compact", variant: "quiet", "data-test": "agent-status-action", "data-action": statusAction.kind, type: "button", onClick: () => void handleAgentStatusAction(), children: statusAction.label })) : null] }) })) : null, reconciledCount > 0 ? (_jsxs("p", { className: "copy-prompt__hint copy-prompt__hint--centered", "data-test": "clipboard-reconciled-hint", role: "status", children: [reconciledCount, " Implemented changes"] })) : null, agentCompletionStatus === "verified" ? (_jsx("p", { className: "copy-prompt__hint", "data-test": "agent-verified-hint", role: "status", children: "Agent changes verified." })) : null, sketchFallback ? (_jsxs(StatusCallout, { className: "copy-prompt__sketch-fallback", tone: "warning", "data-test": "sketch-dispatch-error", children: [_jsx("span", { children: sketchFallback.error }), _jsx(Button, { size: "compact", variant: "secondary", type: "button", "data-test": "sketch-copy-fallback", onClick: () => {
235
- void copyToClipboard(sketchFallback.prompt).then(() => {
236
- if (changes.length > 0 || structuralChanges.length > 0) {
237
- recordClipboardHandoff(changes, structuralChanges);
238
- }
239
- setSketchFallback(null);
240
- }).catch(() => undefined);
326
+ const promptButton = (_jsxs(Button, { variant: "primary", className: "copy-prompt__main", "data-test": "copy-prompt", type: "button", disabled: disabled, "data-copied": copied ? "true" : "false", "data-agent-state": agent.state, "aria-busy": preparing || working || connecting ? "true" : undefined, onClick: activeArtifactId ? undefined : onClick, children: [icon, label, changeCount > 0 ? (_jsx("span", { className: "copy-prompt__change-count", "data-test": "copy-prompt-change-count", children: changeCount })) : null, activeArtifactId ? _jsx(IconChevronDown, { size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }) : null] }));
327
+ return (_jsxs("div", { className: "copy-prompt__stack", "data-test": "copy-prompt-control", children: [activeArtifactId ? (_jsxs(Menu.Root, { modal: false, children: [_jsx(Menu.Trigger, { render: promptButton }), _jsx(Menu.Portal, { container: portalContainer(), children: _jsx(Menu.Positioner, { className: "inspector-popover__positioner", side: "bottom", align: "start", sideOffset: 6, children: _jsxs(Menu.Popup, { className: "inspector-popover__popup copy-prompt__menu", "data-test": "copy-prompt-menu", children: [_jsxs(Menu.Item, { className: "copy-prompt__menu-item", "data-test": "copy-iteration-prompt", label: "Copy iteration prompt", onClick: () => void copyIterationPrompt("iteration"), children: [_jsx(IconArtboard, { className: "copy-prompt__menu-icon", size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }), _jsxs("span", { className: "copy-prompt__menu-content", children: [_jsx("span", { className: "copy-prompt__menu-title", children: "Copy iteration prompt" }), _jsx("span", { className: "copy-prompt__menu-description", children: "Continue editing this HTML iteration." })] })] }), _jsxs(Menu.Item, { className: "copy-prompt__menu-item", "data-test": "copy-iteration-implementation", label: "Copy prompt for live app", onClick: () => void copyIterationPrompt("application"), children: [_jsx(IconBoltFilled, { className: "copy-prompt__menu-icon copy-prompt__menu-icon--live", size: "var(--icon-size-small)", "aria-hidden": "true" }), _jsxs("span", { className: "copy-prompt__menu-content", children: [_jsx("span", { className: "copy-prompt__menu-title", children: "Copy prompt for live app" }), _jsx("span", { className: "copy-prompt__menu-description", children: "Implement design in real app" })] })] })] }) }) })] }, activeDraftCardId)) : promptButton, _jsx(SketchLayersPanel, {}), statusAction || agentStatus.kind === "connected-not-listening" ? (_jsx(StatusCallout, { className: "copy-prompt__agent-status", tone: agentStatus.tone, "data-test": "agent-connection-status", children: _jsxs("div", { className: "copy-prompt__agent-status-content", children: [_jsx("span", { role: "status", children: agentStatus.label }), statusAction ? (_jsx(Button, { size: "compact", variant: "quiet", "data-test": "agent-status-action", "data-action": statusAction.kind, type: "button", onClick: () => void handleAgentStatusAction(), children: statusAction.label })) : null] }) })) : null, undoClear ? (_jsxs("p", { className: "copy-prompt__hint copy-prompt__hint--centered copy-prompt__hint--implemented", "data-test": "handoff-cleared-hint", role: "status", children: ["Cleared stale edits.", " ", _jsx("button", { type: "button", className: "copy-prompt__hint-action", "data-test": "handoff-undo-clear", onClick: () => {
328
+ undoClear();
329
+ setUndoClear(null);
330
+ }, children: "Undo" })] })) : showImplemented ? (_jsxs("p", { className: "copy-prompt__hint copy-prompt__hint--centered copy-prompt__hint--implemented", "data-test": "handoff-implemented-hint", role: "status", children: ["Changes implemented.", remainingCount > 0 ? (_jsxs(_Fragment, { children: [" ", _jsx("button", { type: "button", className: "copy-prompt__hint-action", "data-test": "handoff-clear-remaining", onClick: clearRemaining, children: "Clear stale edits" })] })) : null] })) : null, saveMessage ? (_jsx("p", { className: "copy-prompt__hint copy-prompt__hint--centered", "data-test": "iteration-save-hint", role: "status", children: saveMessage })) : null, sketchFallback ? (_jsxs(StatusCallout, { className: "copy-prompt__sketch-fallback", tone: "warning", "data-test": "sketch-dispatch-error", children: [_jsx("span", { children: sketchFallback.error }), _jsx(Button, { size: "compact", variant: "secondary", type: "button", "data-test": "sketch-copy-fallback", onClick: () => {
331
+ void copyHandoff(sketchFallback.handoff).then(() => setSketchFallback(null)).catch(() => undefined);
241
332
  }, children: "Copy prompt" })] })) : null, _jsx(SettingsDialog, { open: settingsOpen, initialSection: settingsSection, value: customInstructions, onValueChange: handleCustomInstructionsChange, onOpenChange: setSettingsOpen, projectId: runtimeConfig.projectId, origin: window.location.origin, snapshot: agent, onConnect: () => agentClient.connect(), onTakeOver: () => agentClient.takeOver(), onDisconnect: () => agentClient.disconnect(), onCheckAgain: () => agentClient.checkConnection() })] }));
242
333
  }
@@ -1,15 +1,16 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ import { IconArtboard, IconBoltFilled, IconSparkles } from "@tabler/icons-react";
3
+ import { useCanvasPresentation } from "../canvas/viewStore.js";
4
+ import { Disclosure } from "../ui/Disclosure.js";
2
5
  import gridIllustration from "../ui/assets/grid.svg";
3
- function isMacPlatform() {
4
- if (typeof navigator === "undefined")
5
- return false;
6
- return /Mac|iPhone|iPad|iPod/.test(navigator.platform || navigator.userAgent);
7
- }
6
+ import { getPlatformModifierKey, isMacPlatform } from "./shortcuts.js";
8
7
  export function EmptyState() {
8
+ const presentation = useCanvasPresentation();
9
+ const canvas = presentation === "canvas";
9
10
  const macPlatform = isMacPlatform();
10
- const modifierKey = macPlatform ? "⌘" : "Ctrl";
11
+ const modifierKey = getPlatformModifierKey();
11
12
  const modifierName = macPlatform ? "Command" : "Control";
12
13
  const optionKey = macPlatform ? "⌥" : "Alt";
13
14
  const optionName = macPlatform ? "Option" : "Alt";
14
- return (_jsxs("div", { className: "empty-state", "data-test": "empty-state", children: [_jsx("img", { className: "empty-state__icon", src: gridIllustration, alt: "", "aria-hidden": "true" }), _jsx("h2", { className: "empty-state__title", children: "Select an element to edit" }), _jsx("div", { className: "empty-state__shortcuts", children: _jsxs("ul", { className: "empty-state__shortcut-list", children: [_jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Nudge" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": "Arrow keys", children: [_jsx("kbd", { children: "\u2191" }), _jsx("kbd", { children: "\u2193" }), _jsx("kbd", { children: "\u2190" }), _jsx("kbd", { children: "\u2192" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Big Nudge (8px)" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": "Shift plus arrow keys", children: [_jsx("kbd", { children: "Shift" }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Arrow" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Select deeper" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${modifierName} plus click`, children: [_jsx("kbd", { children: modifierKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Click" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Measure" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${optionName} plus hover`, children: [_jsx("kbd", { children: optionKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Hover" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Hide UI" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${modifierName} plus backslash`, children: [_jsx("kbd", { children: modifierKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "\\" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Hold to view original" }), _jsx("span", { className: "empty-state__shortcut-keys", "aria-label": "Backslash", children: _jsx("kbd", { children: "\\" }) })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Undo" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${modifierName} plus Z`, children: [_jsx("kbd", { children: modifierKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Z" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Deselect" }), _jsx("span", { className: "empty-state__shortcut-keys", children: _jsx("kbd", { children: "Esc" }) })] })] }) })] }));
15
+ return (_jsxs("div", { className: `empty-state${canvas ? " empty-state--canvas" : ""}`, "data-test": "empty-state", children: [canvas ? (_jsxs("div", { className: "empty-state__canvas", "data-test": "canvas-intro", children: [_jsx("h2", { className: "empty-state__title", children: "Using the canvas" }), _jsxs("p", { children: [_jsx("span", { className: "empty-state__live-badge", children: _jsx(IconBoltFilled, { "aria-hidden": "true" }) }), _jsxs("span", { children: [_jsx("strong", { children: "Live app" }), "A view of your real running app"] })] }), _jsxs("p", { children: [_jsx(IconArtboard, { "aria-hidden": "true" }), _jsxs("span", { children: [_jsx("strong", { children: "HTML iterations" }), "Unlinked from live app for isolated changes. Ask your agent to implement in live app once ready."] })] }), _jsxs("p", { children: [_jsx(IconSparkles, { "aria-hidden": "true" }), _jsxs("span", { children: [_jsx("strong", { children: "Agent with MCP" }), "Ask your agent to: lay out flows, show page states and create iterations."] })] })] })) : (_jsxs(_Fragment, { children: [_jsx("img", { className: "empty-state__icon", src: gridIllustration, alt: "", "aria-hidden": "true" }), _jsx("h2", { className: "empty-state__title", children: "Select an element to edit" })] })), _jsx(Disclosure, { className: "empty-state__shortcuts", title: "Keyboard shortcuts", triggerDataTest: "empty-state-shortcuts-toggle", defaultOpen: !canvas, children: _jsxs("ul", { className: "empty-state__shortcut-list", children: [_jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Nudge" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": "Arrow keys", children: [_jsx("kbd", { children: "\u2191" }), _jsx("kbd", { children: "\u2193" }), _jsx("kbd", { children: "\u2190" }), _jsx("kbd", { children: "\u2192" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Big Nudge (8px)" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": "Shift plus arrow keys", children: [_jsx("kbd", { children: "Shift" }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Arrow" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Select deeper" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${modifierName} plus click`, children: [_jsx("kbd", { children: modifierKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Click" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Measure" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${optionName} plus hover`, children: [_jsx("kbd", { children: optionKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Hover" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Hide UI" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${modifierName} plus backslash`, children: [_jsx("kbd", { children: modifierKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "\\" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Hold to view original" }), _jsx("span", { className: "empty-state__shortcut-keys", "aria-label": "Backslash", children: _jsx("kbd", { children: "\\" }) })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Undo" }), _jsxs("span", { className: "empty-state__shortcut-keys", "aria-label": `${modifierName} plus Z`, children: [_jsx("kbd", { children: modifierKey }), _jsx("span", { "aria-hidden": "true", children: "+" }), _jsx("kbd", { children: "Z" })] })] }), _jsxs("li", { className: "empty-state__shortcut", "data-test": "empty-state-shortcut", children: [_jsx("span", { children: "Deselect" }), _jsx("span", { className: "empty-state__shortcut-keys", children: _jsx("kbd", { children: "Esc" }) })] })] }) }, presentation)] }));
15
16
  }
@@ -1,14 +1,16 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import { useEffect, useMemo, useState } from "react";
3
- import { IconLayoutSidebarRight, IconSettings } from "@tabler/icons-react";
3
+ import { IconLayoutSidebarRight } from "@tabler/icons-react";
4
4
  import { useInspectorOpen, toggleInspector, setInspectorOpen } from "./openStore.js";
5
5
  import { useSelectedElement, useSelectedElements, setSelectedElement, removeSelectedElement, } from "../selection/selectionStore.js";
6
6
  import { findTokenRow } from "../styleEditors/rowLookup.js";
7
7
  import { useBrowserCssInspection } from "../inspection/useBrowserCssInspection.js";
8
8
  import { resolveSelectionFromElement } from "../selection/resolveSelection.js";
9
+ import { AgentStatusButton } from "./AgentStatusButton.js";
9
10
  import { SpacingBox } from "../styleEditors/SpacingBox.js";
10
11
  import { Typography } from "../styleEditors/Typography.js";
11
12
  import { isTextRelevant } from "../styleEditors/textRelevance.js";
13
+ import { BackgroundEditor } from "../styleEditors/BackgroundEditor.js";
12
14
  import { ColorPicker } from "../styleEditors/ColorPicker.js";
13
15
  import { BorderEditor } from "../styleEditors/BorderEditor.js";
14
16
  import { AppearanceSection } from "../styleEditors/AppearanceSection.js";
@@ -25,12 +27,11 @@ import { StatusCallout } from "../ui/StatusCallout.js";
25
27
  import { IconButton } from "../ui/IconButton.js";
26
28
  import { UI_STYLES } from "../ui/styles.js";
27
29
  import { getActiveStyleState, setActiveStyleState } from "./styleState.js";
28
- import { isEditableEvent } from "./shortcuts.js";
30
+ import { getInspectorToggleShortcutLabel, isEditableEvent } from "./shortcuts.js";
29
31
  import { formatInspectorLabel } from "../ui/labels.js";
30
32
  import { FieldRow } from "../ui/FieldRow.js";
31
33
  import { Select } from "../ui/Select.js";
32
- import { clearRestoreCount, clearSession } from "../canvas/sessionStore.js";
33
- import { hasWriteLease } from "../canvas/workspaceLease.js";
34
+ import { clearSelectedFrameChanges } from "../canvas/sessionStore.js";
34
35
  import { useFocusedCardId, useSelectedCardId, } from "../canvas/canvasStore.js";
35
36
  import { getActiveCanvasFrame } from "../canvas/activeCanvasDocument.js";
36
37
  import { getElementWindow } from "../runtime/domRealm.js";
@@ -46,10 +47,8 @@ import { intersectTokenEntries } from "../inspection/selectionProperty.js";
46
47
  import { isNudgeUiDev } from "../runtime/devFlag.js";
47
48
  import { isDemoRuntime } from "../runtime/runtimeConfig.js";
48
49
  import { SketchWorkspace } from "../sketch/SketchWorkspace.js";
49
- import { cancelSketchInteraction, useSketchInteractionActive } from "../sketch/interaction.js";
50
- import { clearSketchClipboardHandoff } from "../sketch/handoff.js";
51
- import { clearSketchesForProject } from "../sketch/store.js";
52
- import { closeSketchNote } from "../sketch/sketchNote.js";
50
+ import { useSketchInteractionActive } from "../sketch/interaction.js";
51
+ import { Tooltip } from "../ui/Tooltip.js";
53
52
  function findFirstTokenRow(rows, properties) {
54
53
  for (const property of properties) {
55
54
  const row = findTokenRow(rows, property);
@@ -231,19 +230,12 @@ export function InspectorShell() {
231
230
  setSettingsOpen(true);
232
231
  }
233
232
  function clearInspectorSession() {
234
- clearSession();
235
- clearRestoreCount();
236
- if (!hasWriteLease())
237
- return;
238
- cancelSketchInteraction();
239
- closeSketchNote();
240
- clearSketchClipboardHandoff();
241
- void clearSketchesForProject(runtimeConfig.projectId).catch(() => undefined);
233
+ clearSelectedFrameChanges();
242
234
  }
243
- return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "inspector-styles", children: UI_STYLES }), _jsxs("div", { className: "panel", "data-open": isOpen ? "true" : "false", children: [_jsxs("div", { className: "panel__tabs", "aria-label": "Inspector controls", children: [_jsxs("div", { className: "panel__header-row", "data-test": "inspect-tab", children: [_jsx(IconButton, { variant: "quiet", label: "Collapse inspector", "data-test": "collapse-inspector", disabled: sketchActive, style: { marginLeft: "-8px" }, onClick: () => {
244
- cancelInlineTextEdit();
245
- setInspectorOpen(false);
246
- }, children: _jsx(IconLayoutSidebarRight, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) }), _jsxs("div", { className: "panel__header-actions", children: [_jsx(PeekOriginalButton, {}), _jsx(IconButton, { variant: "quiet", label: "Settings", title: "Settings", "data-test": "settings-button", onClick: () => openSettings("instructions"), children: _jsx(IconSettings, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) })] })] }), _jsx("div", { className: "panel__copy-row", children: _jsx(CopyPromptButton, { settingsOpen: settingsOpen, settingsSection: settingsSection, onOpenSettings: openSettings, onSettingsOpenChange: setSettingsOpen }) })] }), _jsxs("div", { className: "panel__body", children: [inlineTextFeedback ? (_jsx(StatusCallout, { tone: "danger", className: "inline-text-diagnostic", "data-test": "inline-text-diagnostic", role: "status", "aria-live": "polite", "aria-atomic": "true", children: _jsx("span", { children: inlineTextFeedback.message }) })) : null, selected ? (_jsxs(_Fragment, { children: [isMultiSelection || showInteractionState || hasEditScopeCallout ? (_jsxs("div", { className: `selection${hasEditScopeCallout ? "" : " selection--without-scope-callout"}`, "data-test": "selection", "data-selected-cid": selected.cid, "data-selected-src": selected.src, "data-selected-count": selectedElements.length, children: [isMultiSelection ? (_jsx("div", { className: "selection__summary", "data-test": "multi-selection-summary", children: _jsxs("span", { className: "selection__count", children: [selectedElements.length, " elements selected"] }) })) : null, hasEditScopeCallout ? (_jsx(StatusCallout, { tone: editScope === "rendered-instance" ? "neutral" : "accent", "data-test": "edit-scope", "data-lost": "false", children: editScope === "rendered-instance" ? (_jsxs("div", { className: "scope__unlinked", children: [_jsx("span", { children: "Element unlinked" }), _jsx(Button, { size: "compact", className: "scope__action", "data-test": "relink-element", onClick: () => {
235
+ return (_jsxs(_Fragment, { children: [_jsx("style", { "data-test": "inspector-styles", children: UI_STYLES }), _jsxs("div", { className: "panel", "data-open": isOpen ? "true" : "false", children: [_jsxs("div", { className: "panel__tabs", "aria-label": "Inspector controls", children: [_jsxs("div", { className: "panel__header-row", "data-test": "inspect-tab", children: [_jsx(Tooltip, { content: "Hide inspector", shortcut: getInspectorToggleShortcutLabel(), stableTrigger: true, children: _jsx(IconButton, { variant: "quiet", label: "Collapse inspector", "data-test": "collapse-inspector", disabled: sketchActive, style: { marginLeft: "calc(var(--space-8) * -1)" }, onClick: () => {
236
+ cancelInlineTextEdit();
237
+ setInspectorOpen(false);
238
+ }, children: _jsx(IconLayoutSidebarRight, { size: "var(--icon-size-small)", stroke: 1.8, "aria-hidden": "true" }) }) }), _jsxs("div", { className: "panel__header-actions", children: [_jsx(PeekOriginalButton, {}), _jsx(AgentStatusButton, { onOpenSettings: openSettings })] })] }), _jsx("div", { className: "panel__copy-row", children: _jsx(CopyPromptButton, { settingsOpen: settingsOpen, settingsSection: settingsSection, onOpenSettings: openSettings, onSettingsOpenChange: setSettingsOpen }) })] }), _jsxs("div", { className: "panel__body", children: [inlineTextFeedback ? (_jsx(StatusCallout, { tone: "danger", className: "inline-text-diagnostic", "data-test": "inline-text-diagnostic", role: "status", "aria-live": "polite", "aria-atomic": "true", children: _jsx("span", { children: inlineTextFeedback.message }) })) : null, selected ? (_jsxs(_Fragment, { children: [isMultiSelection || showInteractionState || hasEditScopeCallout ? (_jsxs("div", { className: `selection${hasEditScopeCallout ? "" : " selection--without-scope-callout"}`, "data-test": "selection", "data-selected-cid": selected.cid, "data-selected-src": selected.src, "data-selected-count": selectedElements.length, children: [isMultiSelection ? (_jsx("div", { className: "selection__summary", "data-test": "multi-selection-summary", children: _jsxs("span", { className: "selection__count", children: [selectedElements.length, " elements selected"] }) })) : null, hasEditScopeCallout ? (_jsx(StatusCallout, { tone: editScope === "rendered-instance" ? "neutral" : "accent", "data-test": "edit-scope", "data-lost": "false", children: editScope === "rendered-instance" ? (_jsxs("div", { className: "scope__unlinked", children: [_jsx("span", { children: "Element unlinked" }), _jsx(Button, { size: "compact", className: "scope__action", "data-test": "relink-element", onClick: () => {
247
239
  const overrideId = relinkElement(selected.domElement);
248
240
  if (overrideId)
249
241
  discardChangesForInstanceOverride(overrideId);
@@ -260,5 +252,5 @@ export function InspectorShell() {
260
252
  return;
261
253
  setActiveStyleState(nextState);
262
254
  setStyleState(nextState);
263
- } }) })) : null] })) : null, !isMultiSelection ? _jsx(ComponentPropsSection, { selected: selected }) : null, selectionEditable ? (_jsx(AtRuleContextProvider, { rows: tokenRows, children: _jsxs("div", { className: "style-editors", "data-test": "style-editors", children: [_jsx(LayoutSection, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `layout-${styleState}`), _jsx(SpacingBox, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `spacing-${styleState}`), _jsx(AppearanceSection, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `appearance-${styleState}`), showText ? _jsxs(_Fragment, { children: [_jsx(Typography, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `type-${styleState}`), _jsx(ColorPicker, { element: selected, selection: styleSelection, property: "color", entries: tokenEntries, tokenRow: findTokenRow(tokenRows, "color") }, `color-${styleState}`)] }) : null, _jsx(ColorPicker, { element: selected, selection: styleSelection, property: "background-color", entries: tokenEntries, tokenRow: backgroundTokenRow }, `background-${styleState}`), _jsx(BorderEditor, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `border-${styleState}`), _jsx(BoxShadowEditor, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `box-shadow-${styleState}`)] }) })) : (_jsx(StatusCallout, { tone: "neutral", "data-test": "multi-selection-uneditable", children: "These repeated items are indistinguishable, so Nudge UI cannot safely target only part of the group. Select every repeated item to edit them together." }))] })) : (_jsx(EmptyState, {})), _jsx(ChangesLog, { onClearSession: clearInspectorSession })] })] }), sketchEnabled ? (_jsx(SketchWorkspace, { hostElement: sketchHost, projectId: runtimeConfig.projectId })) : null, !isOpen ? (_jsx("div", { className: "panel__restore", children: _jsx(IconButton, { variant: "quiet", label: "Show inspector", className: "panel__restore-button", "data-test": "show-inspector", onClick: () => setInspectorOpen(true), children: _jsx(IconLayoutSidebarRight, { size: 16, stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }) }) })) : null] }));
255
+ } }) })) : null] })) : null, !isMultiSelection ? _jsx(ComponentPropsSection, { selected: selected }) : null, selectionEditable ? (_jsx(AtRuleContextProvider, { rows: tokenRows, children: _jsxs("div", { className: "style-editors", "data-test": "style-editors", children: [_jsx(LayoutSection, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `layout-${styleState}`), _jsx(SpacingBox, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `spacing-${styleState}`), _jsx(AppearanceSection, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `appearance-${styleState}`), showText ? _jsxs(_Fragment, { children: [_jsx(Typography, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `type-${styleState}`), _jsx(ColorPicker, { element: selected, selection: styleSelection, property: "color", entries: tokenEntries, tokenRow: findTokenRow(tokenRows, "color") }, `color-${styleState}`)] }) : null, _jsx(BackgroundEditor, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRow: backgroundTokenRow }, `background-${styleState}`), _jsx(BorderEditor, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `border-${styleState}`), _jsx(BoxShadowEditor, { element: selected, selection: styleSelection, entries: tokenEntries, tokenRows: tokenRows }, `box-shadow-${styleState}`)] }) })) : (_jsx(StatusCallout, { tone: "neutral", "data-test": "multi-selection-uneditable", children: "These repeated items are indistinguishable, so Nudge UI cannot safely target only part of the group. Select every repeated item to edit them together." }))] })) : (_jsx(EmptyState, {})), _jsx(ChangesLog, { onClearSession: clearInspectorSession })] })] }), sketchEnabled ? (_jsx(SketchWorkspace, { hostElement: sketchHost, projectId: runtimeConfig.projectId })) : null, !isOpen ? (_jsx("div", { className: "panel__restore", children: _jsx(Tooltip, { children: _jsx(IconButton, { variant: "quiet", label: "Show inspector", className: "panel__restore-button", "data-test": "show-inspector", onClick: () => setInspectorOpen(true), children: _jsx(IconLayoutSidebarRight, { size: "var(--icon-size-small)", stroke: "var(--icon-stroke-width)", "aria-hidden": "true" }) }) }) })) : null] }));
264
256
  }
@@ -1,12 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import { useEffect, useSyncExternalStore } from "react";
3
3
  import { IconButton } from "../ui/IconButton.js";
4
+ import { Tooltip } from "../ui/Tooltip.js";
4
5
  import { PeekOriginalIcon } from "./PeekOriginalIcon.js";
5
- import { workspaceChangeStore } from "../changes/workspaceChanges.js";
6
+ import { draftChangeStore } from "../changes/draftChanges.js";
6
7
  import { setOriginalPreviewActive, useOriginalPreviewActive, } from "./originalPreview.js";
7
- function useWorkspaceChangeCount() {
8
- return useSyncExternalStore(workspaceChangeStore.subscribe, () => {
9
- const snapshot = workspaceChangeStore.getSnapshot();
8
+ function useDraftChangeCount() {
9
+ return useSyncExternalStore(draftChangeStore.subscribe, () => {
10
+ const snapshot = draftChangeStore.getSnapshot();
10
11
  return snapshot.changes.length + snapshot.structuralChanges.length;
11
12
  }, () => 0);
12
13
  }
@@ -17,7 +18,7 @@ function useWorkspaceChangeCount() {
17
18
  */
18
19
  export function PeekOriginalButton() {
19
20
  const active = useOriginalPreviewActive();
20
- const changeCount = useWorkspaceChangeCount();
21
+ const changeCount = useDraftChangeCount();
21
22
  const disabled = changeCount === 0;
22
23
  useEffect(() => {
23
24
  if (!active)
@@ -35,23 +36,23 @@ export function PeekOriginalButton() {
35
36
  useEffect(() => () => {
36
37
  setOriginalPreviewActive(false);
37
38
  }, []);
38
- return (_jsx(IconButton, { variant: "quiet", "data-test": "peek-original-button", label: "Hold to view original", title: disabled ? "No changes to preview" : "Hold to view original", "aria-pressed": active, "data-active": active ? "true" : "false", disabled: disabled, onPointerDown: (event) => {
39
- if (disabled)
40
- return;
41
- if (event.pointerType === "mouse" && event.button !== 0)
42
- return;
43
- event.currentTarget.setPointerCapture?.(event.pointerId);
44
- setOriginalPreviewActive(true);
45
- }, onPointerUp: () => setOriginalPreviewActive(false), onPointerCancel: () => setOriginalPreviewActive(false), onLostPointerCapture: () => setOriginalPreviewActive(false), onKeyDown: (event) => {
46
- if (disabled || event.repeat)
47
- return;
48
- if (event.key === " " || event.key === "Enter")
39
+ return (_jsx(Tooltip, { content: disabled ? "No changes to preview" : "Hold to view original", shortcut: disabled ? undefined : "\\", stableTrigger: true, children: _jsx(IconButton, { variant: "quiet", "data-test": "peek-original-button", label: "Hold to view original", "aria-pressed": active, "data-active": active ? "true" : "false", disabled: disabled, onPointerDown: (event) => {
40
+ if (disabled)
41
+ return;
42
+ if (event.pointerType === "mouse" && event.button !== 0)
43
+ return;
44
+ event.currentTarget.setPointerCapture?.(event.pointerId);
49
45
  setOriginalPreviewActive(true);
50
- }, onKeyUp: (event) => {
51
- if (event.key === " " || event.key === "Enter")
52
- setOriginalPreviewActive(false);
53
- }, onBlur: () => setOriginalPreviewActive(false), onContextMenu: (event) => {
54
- if (active)
55
- event.preventDefault();
56
- }, children: _jsx(PeekOriginalIcon, {}) }));
46
+ }, onPointerUp: () => setOriginalPreviewActive(false), onPointerCancel: () => setOriginalPreviewActive(false), onLostPointerCapture: () => setOriginalPreviewActive(false), onKeyDown: (event) => {
47
+ if (disabled || event.repeat)
48
+ return;
49
+ if (event.key === " " || event.key === "Enter")
50
+ setOriginalPreviewActive(true);
51
+ }, onKeyUp: (event) => {
52
+ if (event.key === " " || event.key === "Enter")
53
+ setOriginalPreviewActive(false);
54
+ }, onBlur: () => setOriginalPreviewActive(false), onContextMenu: (event) => {
55
+ if (active)
56
+ event.preventDefault();
57
+ }, children: _jsx(PeekOriginalIcon, {}) }) }));
57
58
  }
@@ -1,6 +1,6 @@
1
1
  import { useSyncExternalStore } from "react";
2
- import { workspaceChangeStore } from "../changes/workspaceChanges.js";
3
- import { applyHostWorkspaceProjection, compileWorkspaceProjection, } from "../projection/workspaceProjection.js";
2
+ import { draftChangeStore } from "../changes/draftChanges.js";
3
+ import { applyHostDraftProjection, compileDraftProjection, } from "../projection/draftProjection.js";
4
4
  import { isEditorShellDocument } from "../runtime/editorShell.js";
5
5
  let previewingOriginal = false;
6
6
  const listeners = new Set();
@@ -29,8 +29,8 @@ function notifyOriginalPreviewListeners() {
29
29
  function applyEmptyHostProjection() {
30
30
  if (isEditorShellDocument())
31
31
  return;
32
- const { revision } = workspaceChangeStore.getSnapshot();
33
- applyHostWorkspaceProjection({
32
+ const { revision } = draftChangeStore.getSnapshot();
33
+ applyHostDraftProjection({
34
34
  sourceRevision: revision,
35
35
  managedStyles: { rules: [], css: "" },
36
36
  instanceOverrides: [],
@@ -42,7 +42,7 @@ function applyEmptyHostProjection() {
42
42
  function applyCanonicalHostProjection() {
43
43
  if (isEditorShellDocument())
44
44
  return;
45
- applyHostWorkspaceProjection(compileWorkspaceProjection(workspaceChangeStore.getSnapshot()));
45
+ applyHostDraftProjection(compileDraftProjection(draftChangeStore.getSnapshot()));
46
46
  }
47
47
  /**
48
48
  * Hold-to-view-original (NUD-30). While active the host document shows the