nudge-ui 0.2.0 → 0.2.2

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 (231) hide show
  1. package/bin/nudge-ui.mjs +3 -1
  2. package/dist/cli/agentCommand.d.ts +8 -0
  3. package/dist/cli/agentCommand.js +59 -0
  4. package/dist/client.mjs +878 -11
  5. package/dist/hosts/astro/astroRuntimeConfig.js +1 -1
  6. package/dist/hosts/astro/clientTransport.js +63 -11
  7. package/dist/hosts/astro/integration.d.ts +2 -2
  8. package/dist/hosts/astro/integration.js +4 -3
  9. package/dist/hosts/environment.d.ts +15 -0
  10. package/dist/hosts/environment.js +16 -0
  11. package/dist/hosts/next/sidecar.d.ts +4 -0
  12. package/dist/hosts/next/sidecar.js +56 -7
  13. package/dist/hosts/next/wrapper.d.ts +2 -0
  14. package/dist/hosts/next/wrapper.js +32 -3
  15. package/dist/hosts/projectBridge.d.ts +21 -0
  16. package/dist/hosts/projectBridge.js +98 -0
  17. package/dist/hosts/static/cli.d.ts +1 -1
  18. package/dist/hosts/static/cli.js +6 -1
  19. package/dist/hosts/static/manifest.d.ts +1 -1
  20. package/dist/hosts/static/manifest.js +3 -1
  21. package/dist/hosts/static/server.js +45 -3
  22. package/dist/hosts/vite/vite.d.ts +6 -1
  23. package/dist/hosts/vite/vite.js +82 -15
  24. package/dist/inspector/agent/McpConnectionDialog.d.ts +5 -4
  25. package/dist/inspector/agent/McpConnectionDialog.js +20 -37
  26. package/dist/inspector/agent/client.d.ts +16 -3
  27. package/dist/inspector/agent/client.js +114 -11
  28. package/dist/inspector/agent/connectionStatus.d.ts +3 -3
  29. package/dist/inspector/agent/connectionStatus.js +11 -4
  30. package/dist/inspector/agent/httpTransport.d.ts +8 -0
  31. package/dist/inspector/agent/httpTransport.js +78 -18
  32. package/dist/inspector/agent/protocol.d.ts +11 -3
  33. package/dist/inspector/agent/protocol.js +1 -1
  34. package/dist/inspector/agent/verification.d.ts +1 -1
  35. package/dist/inspector/agent/verification.js +69 -12
  36. package/dist/inspector/canvas/CanvasCard.d.ts +5 -3
  37. package/dist/inspector/canvas/CanvasCard.js +181 -91
  38. package/dist/inspector/canvas/CanvasElementOverlay.js +288 -52
  39. package/dist/inspector/canvas/CanvasToolbar.d.ts +12 -0
  40. package/dist/inspector/canvas/CanvasToolbar.js +24 -0
  41. package/dist/inspector/canvas/CanvasWorkspace.d.ts +4 -1
  42. package/dist/inspector/canvas/CanvasWorkspace.js +410 -72
  43. package/dist/inspector/canvas/activeCanvasDocument.d.ts +5 -0
  44. package/dist/inspector/canvas/activeCanvasDocument.js +23 -0
  45. package/dist/inspector/canvas/canvasResize.d.ts +30 -0
  46. package/dist/inspector/canvas/canvasResize.js +52 -0
  47. package/dist/inspector/canvas/canvasStore.d.ts +30 -6
  48. package/dist/inspector/canvas/canvasStore.js +128 -61
  49. package/dist/inspector/canvas/frameProtocol.d.ts +82 -5
  50. package/dist/inspector/canvas/frameProtocol.js +63 -2
  51. package/dist/inspector/canvas/keyboardShortcuts.d.ts +4 -0
  52. package/dist/inspector/canvas/keyboardShortcuts.js +16 -0
  53. package/dist/inspector/canvas/linkEligibility.d.ts +0 -5
  54. package/dist/inspector/canvas/linkEligibility.js +0 -29
  55. package/dist/inspector/canvas/projection.d.ts +7 -0
  56. package/dist/inspector/canvas/projection.js +118 -25
  57. package/dist/inspector/canvas/rendererBootstrap.js +42 -29
  58. package/dist/inspector/canvas/rendererElementSelector.d.ts +1 -1
  59. package/dist/inspector/canvas/rendererElementSelector.js +385 -58
  60. package/dist/inspector/canvas/rendererMessageRouter.d.ts +11 -0
  61. package/dist/inspector/canvas/rendererMessageRouter.js +43 -0
  62. package/dist/inspector/canvas/rendererSelectionProxy.js +6 -2
  63. package/dist/inspector/canvas/sessionStore.d.ts +1 -0
  64. package/dist/inspector/canvas/sessionStore.js +12 -4
  65. package/dist/inspector/canvas/staleChangeDetector.js +16 -14
  66. package/dist/inspector/changes/changesLog.js +31 -1
  67. package/dist/inspector/changes/managedStyleProjection.d.ts +1 -1
  68. package/dist/inspector/changes/managedStyleProjection.js +3 -3
  69. package/dist/inspector/changes/structuralTypes.d.ts +4 -0
  70. package/dist/inspector/changes/workspaceChanges.d.ts +4 -0
  71. package/dist/inspector/changes/workspaceChanges.js +29 -3
  72. package/dist/inspector/clientManifest.d.ts +7 -0
  73. package/dist/inspector/clientManifest.js +12 -0
  74. package/dist/inspector/componentSemantics/adapterRegistry.js +4 -3
  75. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +2 -2
  76. package/dist/inspector/componentSemantics/runtimeBridge.js +16 -3
  77. package/dist/inspector/index.d.ts +2 -0
  78. package/dist/inspector/index.js +80 -32
  79. package/dist/inspector/inline-text/inlineTextDiagnostics.d.ts +10 -0
  80. package/dist/inspector/inline-text/inlineTextDiagnostics.js +65 -0
  81. package/dist/inspector/inline-text/inlineTextEditor.d.ts +3 -5
  82. package/dist/inspector/inline-text/inlineTextEditor.js +74 -206
  83. package/dist/inspector/inline-text/inlineTextFeedback.d.ts +5 -0
  84. package/dist/inspector/inline-text/inlineTextFeedback.js +27 -0
  85. package/dist/inspector/inline-text/inlineTextLifecycle.js +2 -0
  86. package/dist/inspector/inline-text/textEditChange.d.ts +14 -0
  87. package/dist/inspector/inline-text/textEditChange.js +165 -0
  88. package/dist/inspector/inspection/selectionProperty.d.ts +1 -0
  89. package/dist/inspector/inspection/selectionProperty.js +1 -0
  90. package/dist/inspector/overlay/DomNavigator.d.ts +10 -0
  91. package/dist/inspector/overlay/DomNavigator.js +40 -0
  92. package/dist/inspector/overlay/InspectorOverlay.js +6 -2
  93. package/dist/inspector/overlay/clickPolicy.d.ts +18 -2
  94. package/dist/inspector/overlay/clickPolicy.js +34 -3
  95. package/dist/inspector/overlay/elementSelector.d.ts +1 -1
  96. package/dist/inspector/overlay/elementSelector.js +18 -7
  97. package/dist/inspector/overlay/selectedGeometry.js +21 -2
  98. package/dist/inspector/overlay/spacingGestures.d.ts +45 -0
  99. package/dist/inspector/overlay/spacingGestures.js +351 -0
  100. package/dist/inspector/overlay/structuralGestures.d.ts +2 -2
  101. package/dist/inspector/overlay/structuralGestures.js +12 -10
  102. package/dist/inspector/projection/managedStylesheet.js +4 -1
  103. package/dist/inspector/projection/renderedInstance.d.ts +2 -0
  104. package/dist/inspector/projection/renderedInstance.js +5 -1
  105. package/dist/inspector/projection/structuralProjection.d.ts +2 -0
  106. package/dist/inspector/projection/structuralProjection.js +85 -1
  107. package/dist/inspector/projection/structuralProjectionBoundary.js +17 -1
  108. package/dist/inspector/projection/textProjection.d.ts +2 -0
  109. package/dist/inspector/projection/textProjection.js +10 -4
  110. package/dist/inspector/prompt/clipboardHandoff.d.ts +1 -1
  111. package/dist/inspector/prompt/clipboardHandoff.js +3 -3
  112. package/dist/inspector/prompt/generatePrompt.d.ts +2 -1
  113. package/dist/inspector/prompt/generatePrompt.js +19 -2
  114. package/dist/inspector/runtime/editorShell.d.ts +2 -0
  115. package/dist/inspector/runtime/editorShell.js +4 -0
  116. package/dist/inspector/runtime/runtimeConfig.d.ts +5 -1
  117. package/dist/inspector/runtime/runtimeConfig.js +4 -0
  118. package/dist/inspector/selection/hierarchy.d.ts +6 -0
  119. package/dist/inspector/selection/hierarchy.js +8 -0
  120. package/dist/inspector/selection/selectionStore.js +2 -0
  121. package/dist/inspector/settings/SettingsDialog.d.ts +1 -1
  122. package/dist/inspector/settings/SettingsDialog.js +12 -2
  123. package/dist/inspector/shell/AppShell.js +5 -1
  124. package/dist/inspector/shell/ChangesLog.js +26 -22
  125. package/dist/inspector/shell/CopyPromptButton.js +102 -19
  126. package/dist/inspector/shell/EmptyState.js +1 -1
  127. package/dist/inspector/shell/InspectorShell.d.ts +0 -1
  128. package/dist/inspector/shell/InspectorShell.js +38 -42
  129. package/dist/inspector/shell/PeekOriginalButton.d.ts +7 -0
  130. package/dist/inspector/shell/PeekOriginalButton.js +57 -0
  131. package/dist/inspector/shell/PeekOriginalIcon.d.ts +7 -0
  132. package/dist/inspector/shell/PeekOriginalIcon.js +9 -0
  133. package/dist/inspector/shell/originalPreview.d.ts +9 -0
  134. package/dist/inspector/shell/originalPreview.js +61 -0
  135. package/dist/inspector/shell/shortcuts.d.ts +3 -0
  136. package/dist/inspector/shell/shortcuts.js +15 -0
  137. package/dist/inspector/sketch/SketchChanges.d.ts +2 -0
  138. package/dist/inspector/sketch/SketchChanges.js +72 -0
  139. package/dist/inspector/sketch/SketchEditor.d.ts +21 -0
  140. package/dist/inspector/sketch/SketchEditor.js +402 -0
  141. package/dist/inspector/sketch/SketchEntryButton.d.ts +4 -0
  142. package/dist/inspector/sketch/SketchEntryButton.js +11 -0
  143. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +11 -0
  144. package/dist/inspector/sketch/SketchFrameOverlay.js +119 -0
  145. package/dist/inspector/sketch/SketchLayersPanel.d.ts +2 -0
  146. package/dist/inspector/sketch/SketchLayersPanel.js +63 -0
  147. package/dist/inspector/sketch/SketchOverlay.d.ts +19 -0
  148. package/dist/inspector/sketch/SketchOverlay.js +420 -0
  149. package/dist/inspector/sketch/SketchPromptPanel.d.ts +15 -0
  150. package/dist/inspector/sketch/SketchPromptPanel.js +18 -0
  151. package/dist/inspector/sketch/SketchWorkspace.d.ts +13 -0
  152. package/dist/inspector/sketch/SketchWorkspace.js +152 -0
  153. package/dist/inspector/sketch/capture.d.ts +55 -0
  154. package/dist/inspector/sketch/capture.js +350 -0
  155. package/dist/inspector/sketch/freehand.d.ts +13 -0
  156. package/dist/inspector/sketch/freehand.js +64 -0
  157. package/dist/inspector/sketch/geometry.d.ts +17 -0
  158. package/dist/inspector/sketch/geometry.js +98 -0
  159. package/dist/inspector/sketch/handoff.d.ts +21 -0
  160. package/dist/inspector/sketch/handoff.js +72 -0
  161. package/dist/inspector/sketch/interaction.d.ts +21 -0
  162. package/dist/inspector/sketch/interaction.js +98 -0
  163. package/dist/inspector/sketch/model.d.ts +104 -0
  164. package/dist/inspector/sketch/model.js +282 -0
  165. package/dist/inspector/sketch/persistence.d.ts +21 -0
  166. package/dist/inspector/sketch/persistence.js +205 -0
  167. package/dist/inspector/sketch/raster.d.ts +22 -0
  168. package/dist/inspector/sketch/raster.js +203 -0
  169. package/dist/inspector/sketch/sketchNote.d.ts +10 -0
  170. package/dist/inspector/sketch/sketchNote.js +30 -0
  171. package/dist/inspector/sketch/store.d.ts +47 -0
  172. package/dist/inspector/sketch/store.js +434 -0
  173. package/dist/inspector/styleEditors/BorderEditor.js +15 -19
  174. package/dist/inspector/styleEditors/BorderRadiusEditor.js +6 -6
  175. package/dist/inspector/styleEditors/BoxShadowEditor.js +12 -1
  176. package/dist/inspector/styleEditors/ColorPicker.js +11 -36
  177. package/dist/inspector/styleEditors/GapField.d.ts +3 -2
  178. package/dist/inspector/styleEditors/GapField.js +2 -2
  179. package/dist/inspector/styleEditors/GridSection.js +1 -1
  180. package/dist/inspector/styleEditors/LayoutSection.js +11 -8
  181. package/dist/inspector/styleEditors/SpacingBox.js +31 -33
  182. package/dist/inspector/styleEditors/layoutPreviewState.d.ts +5 -0
  183. package/dist/inspector/styleEditors/layoutPreviewState.js +19 -0
  184. package/dist/inspector/styleEditors/layoutValue.js +3 -0
  185. package/dist/inspector/styleEditors/nudgeValue.d.ts +11 -0
  186. package/dist/inspector/styleEditors/nudgeValue.js +93 -5
  187. package/dist/inspector/styleEditors/stylePresence.d.ts +7 -0
  188. package/dist/inspector/styleEditors/stylePresence.js +22 -0
  189. package/dist/inspector/styleEditors/textRelevance.d.ts +3 -0
  190. package/dist/inspector/styleEditors/textRelevance.js +35 -0
  191. package/dist/inspector/styleEditors/useFieldVisibility.d.ts +6 -0
  192. package/dist/inspector/styleEditors/useFieldVisibility.js +26 -0
  193. package/dist/inspector/tokens/TokenField.js +130 -7
  194. package/dist/inspector/tokens/TokensPanel.js +2 -1
  195. package/dist/inspector/tokens/dragPointerLock.d.ts +8 -0
  196. package/dist/inspector/tokens/dragPointerLock.js +70 -0
  197. package/dist/inspector/tokens/editActions.d.ts +2 -0
  198. package/dist/inspector/tokens/editActions.js +2 -2
  199. package/dist/inspector/tokens/resolution/cssomCollector.d.ts +1 -1
  200. package/dist/inspector/tokens/resolution/cssomCollector.js +9 -5
  201. package/dist/inspector/tokens/resolution/ruleMatching.d.ts +40 -0
  202. package/dist/inspector/tokens/resolution/ruleMatching.js +423 -0
  203. package/dist/inspector/tokens/resolution/selectorSemantics.d.ts +19 -3
  204. package/dist/inspector/tokens/resolution/selectorSemantics.js +378 -4
  205. package/dist/inspector/tokens/resolution.d.ts +3 -26
  206. package/dist/inspector/tokens/resolution.js +44 -735
  207. package/dist/inspector/tokens/tokenAvailability.d.ts +18 -0
  208. package/dist/inspector/tokens/tokenAvailability.js +204 -0
  209. package/dist/inspector/ui/Button.d.ts +1 -1
  210. package/dist/inspector/ui/Disclosure.d.ts +22 -0
  211. package/dist/inspector/ui/Disclosure.js +13 -0
  212. package/dist/inspector/ui/SideValuesField.js +2 -2
  213. package/dist/inspector/ui/StatusCallout.d.ts +4 -1
  214. package/dist/inspector/ui/StatusCallout.js +2 -2
  215. package/dist/inspector/ui/dragCursor.d.ts +8 -0
  216. package/dist/inspector/ui/dragCursor.js +21 -0
  217. package/dist/inspector/ui/styles.js +21 -17
  218. package/dist/internal/agent-protocol.d.ts +65 -1
  219. package/dist/internal/agent-protocol.js +183 -3
  220. package/dist/nudge-ui.mjs +276 -58
  221. package/dist/transport/editor.d.ts +47 -0
  222. package/dist/transport/editor.js +163 -0
  223. package/dist/transport/index.d.ts +1 -0
  224. package/dist/transport/index.js +1 -0
  225. package/dist/transport/routes.d.ts +10 -0
  226. package/dist/transport/routes.js +10 -0
  227. package/package.json +3 -1
  228. package/dist/inspector/shell/DomNavigation.d.ts +0 -8
  229. package/dist/inspector/shell/DomNavigation.js +0 -30
  230. package/dist/inspector/shell/panelLayout.d.ts +0 -2
  231. package/dist/inspector/shell/panelLayout.js +0 -29
@@ -1,11 +1,12 @@
1
1
  import { createElement } from "react";
2
2
  import { createRoot } from "react-dom/client";
3
- import { InspectorShell, toggleInspector, setInspectorOpen, setInspectorHost } from "./shell/InspectorShell.js";
3
+ import { InspectorShell, toggleInspector, setInspectorOpen } from "./shell/InspectorShell.js";
4
4
  import { setSelectedElement } from "./selection/selectionStore.js";
5
5
  import { removeManagedSheet } from "./projection/managedStylesheet.js";
6
- import { isInspectorToggleShortcut } from "./shell/shortcuts.js";
7
- import { clearInspectorLayout } from "./shell/panelLayout.js";
6
+ import { isInspectorToggleShortcut, isOriginalPreviewShortcut, SEND_PROMPT_HOTKEY_EVENT, } from "./shell/shortcuts.js";
8
7
  import { isCanvasRenderer } from "./canvas/roleDetection.js";
8
+ import { isKeyboardShortcutMessage } from "./canvas/frameProtocol.js";
9
+ import { subscribeCanvasRendererMessages } from "./canvas/rendererMessageRouter.js";
9
10
  import { bootstrapRenderer } from "./canvas/rendererBootstrap.js";
10
11
  import { hydrateSession, enableAutoSave, scheduleAutoSave, scheduleCanvasSave, setRestoreCount, } from "./canvas/sessionStore.js";
11
12
  import { subscribeChanges, getChangesList } from "./changes/changesLog.js";
@@ -15,14 +16,18 @@ import { cancelStaleDetection, startStaleDetection } from "./canvas/staleChangeD
15
16
  import { LockedWorkspaceNotice } from "./canvas/LockedWorkspaceNotice.js";
16
17
  import { AppShell } from "./shell/AppShell.js";
17
18
  import { installInspectionBridge } from "./inspection/bridge.js";
18
- import { disposeBrowserCssInspection } from "./inspection/browserCssInspectionRegistry.js";
19
- import { releaseDocumentProjection } from "./projection/structuralProjection.js";
19
+ import { releaseDocumentProjection, subscribeStructuralChanges } from "./projection/structuralProjection.js";
20
20
  import { cancelInlineTextEdit } from "./inline-text/inlineTextEditor.js";
21
21
  import { configureNudgeUiRuntime, getNudgeUiRuntimeConfig, isDemoRuntime } from "./runtime/runtimeConfig.js";
22
22
  import { setCanvasMode } from "./canvas/canvasStore.js";
23
23
  import { isNudgeUiDev, setNudgeUiHostDevFlag } from "./runtime/devFlag.js";
24
- import { clearClipboardHandoff, startClipboardHandoffController, subscribeClipboardHandoff, } from "./prompt/clipboardHandoff.js";
24
+ import { clearClipboardHandoff, subscribeClipboardHandoff, } from "./prompt/clipboardHandoff.js";
25
25
  import { createWorkspace, InspectorSessionProvider, } from "./session/index.js";
26
+ import { clearSketchClipboardHandoff } from "./sketch/handoff.js";
27
+ import { cancelSketchInteraction, isSketchInteractionActive } from "./sketch/interaction.js";
28
+ import { setOriginalPreviewActive } from "./shell/originalPreview.js";
29
+ import { initializeSketchStore } from "./sketch/store.js";
30
+ export { resolveNudgeUiClientEntry } from "../transport/editor.js";
26
31
  let hostElement = null;
27
32
  let reactRoot = null;
28
33
  let lockedRoot = null;
@@ -33,11 +38,47 @@ let beforeUnloadAttached = false;
33
38
  let persistenceSubscribed = false;
34
39
  let unsubscribeOwnership = null;
35
40
  let removeInspectionBridge = null;
36
- let stopClipboardHandoffController = null;
41
+ let keyboardPeekHeld = false;
37
42
  function onKeydown(e) {
43
+ if (isSketchInteractionActive())
44
+ return;
38
45
  if (isInspectorToggleShortcut(e)) {
39
46
  toggleInspector();
40
47
  e.preventDefault();
48
+ return;
49
+ }
50
+ if (isOriginalPreviewShortcut(e)) {
51
+ keyboardPeekHeld = true;
52
+ setOriginalPreviewActive(true);
53
+ e.preventDefault();
54
+ }
55
+ }
56
+ function onKeyup(e) {
57
+ // Release only a keyboard-started peek so a button-held preview survives
58
+ // unrelated Backslash keyups (e.g. the panel-toggle shortcuts pressed
59
+ // mid-hold). A guarded keydown never sets the flag, so this stays a no-op
60
+ // for keyups without a matching hold.
61
+ if (e.code === "Backslash" && keyboardPeekHeld) {
62
+ keyboardPeekHeld = false;
63
+ setOriginalPreviewActive(false);
64
+ }
65
+ }
66
+ function onRendererKeyboardShortcut(message, identity) {
67
+ if (!isKeyboardShortcutMessage(message, identity))
68
+ return;
69
+ if (message.code === "KeyS" && message.phase === "keydown") {
70
+ window.dispatchEvent(new Event(SEND_PROMPT_HOTKEY_EVENT));
71
+ return;
72
+ }
73
+ if (message.code !== "Backslash")
74
+ return;
75
+ if (message.phase === "keydown") {
76
+ keyboardPeekHeld = true;
77
+ setOriginalPreviewActive(true);
78
+ }
79
+ else if (keyboardPeekHeld) {
80
+ keyboardPeekHeld = false;
81
+ setOriginalPreviewActive(false);
41
82
  }
42
83
  }
43
84
  function disposeInspectorSession() {
@@ -57,11 +98,15 @@ export function bootstrapNudgeUi(inspectorHost) {
57
98
  // for its own document. The bundle mode name alone must never flip it,
58
99
  // so every build without both opt-ins stays governed by ADR-0002.
59
100
  setNudgeUiHostDevFlag(true);
60
- // Public demo builds intentionally expose only the static inspector. The
61
- // Canvas workspace, write lease, persistence, and agent bridge stay out
62
- // of the embedded frame.
63
- setCanvasMode("inspect");
101
+ if (runtimeConfig.capabilities.canvas && isCanvasRenderer()) {
102
+ rendererBootstrapHandle = bootstrapRenderer() ?? null;
103
+ return;
104
+ }
105
+ // The public demo shares the iframe editor while keeping the write lease,
106
+ // persistence, and agent bridge disabled.
107
+ setCanvasMode("canvas");
64
108
  mountInspector(inspectorHost);
109
+ setInspectorOpen(false);
65
110
  return;
66
111
  }
67
112
  if (!runtimeConfig.capabilities.canvas) {
@@ -94,6 +139,7 @@ function startController(inspectorHost) {
94
139
  lockedRoot.unmount();
95
140
  lockedRoot = null;
96
141
  }
142
+ void initializeSketchStore(getNudgeUiRuntimeConfig().projectId).catch(() => undefined);
97
143
  unsubscribeOwnership?.();
98
144
  unsubscribeOwnership = subscribeOwnership((hasLease) => {
99
145
  if (!hasLease)
@@ -107,9 +153,12 @@ function startController(inspectorHost) {
107
153
  startStaleDetection(restored);
108
154
  }
109
155
  }
156
+ if (getNudgeUiRuntimeConfig().capabilities.canvas) {
157
+ // Normal controllers always host the iframe workspace. Hydration runs
158
+ // first so this mode change cannot discard cards, camera, or edits.
159
+ setCanvasMode("canvas");
160
+ }
110
161
  mountInspector(inspectorHost);
111
- stopClipboardHandoffController?.();
112
- stopClipboardHandoffController = startClipboardHandoffController(document);
113
162
  enableAutoSave();
114
163
  if (!beforeUnloadAttached) {
115
164
  // enableAutoSave registers its flush listener first. Release the lease only
@@ -120,14 +169,13 @@ function startController(inspectorHost) {
120
169
  }
121
170
  if (!persistenceSubscribed) {
122
171
  subscribeChanges(() => scheduleAutoSave());
172
+ subscribeStructuralChanges(() => scheduleAutoSave());
123
173
  subscribeClipboardHandoff(() => scheduleAutoSave());
124
174
  subscribeCanvas(() => scheduleCanvasSave());
125
175
  persistenceSubscribed = true;
126
176
  }
127
177
  }
128
178
  function mountLockedNotice(host) {
129
- stopClipboardHandoffController?.();
130
- stopClipboardHandoffController = null;
131
179
  if (reactRoot) {
132
180
  reactRoot.unmount();
133
181
  reactRoot = null;
@@ -139,8 +187,9 @@ function mountLockedNotice(host) {
139
187
  cancelStaleDetection();
140
188
  setInspectorOpen(false);
141
189
  cancelInlineTextEdit();
190
+ cancelSketchInteraction();
191
+ clearSketchClipboardHandoff();
142
192
  setSelectedElement(null);
143
- clearInspectorLayout();
144
193
  removeManagedSheet();
145
194
  releaseDocumentProjection(document);
146
195
  hostElement = null;
@@ -159,14 +208,12 @@ export function mountInspector(host) {
159
208
  const demo = isDemoRuntime();
160
209
  if (!demo && !hasWriteLease())
161
210
  return;
162
- if (host.dataset.nudgeUiDebug === "true") {
163
- const runtimeConfig = getNudgeUiRuntimeConfig();
164
- if (runtimeConfig.capabilities.domNavigation !== true) {
165
- configureNudgeUiRuntime({
166
- ...runtimeConfig,
167
- capabilities: { ...runtimeConfig.capabilities, domNavigation: true },
168
- });
169
- }
211
+ const runtimeConfig = getNudgeUiRuntimeConfig();
212
+ if (runtimeConfig.capabilities.domNavigation !== true) {
213
+ configureNudgeUiRuntime({
214
+ ...runtimeConfig,
215
+ capabilities: { ...runtimeConfig.capabilities, domNavigation: true },
216
+ });
170
217
  }
171
218
  if (lockedRoot) {
172
219
  lockedRoot.unmount();
@@ -178,21 +225,20 @@ export function mountInspector(host) {
178
225
  if (!reactRoot) {
179
226
  reactRoot = createRoot(shadow);
180
227
  inspectorSession = workspace.createInspectorSession(host);
181
- const documentSession = inspectorSession.createDocumentSession(document);
182
- documentSession.registerCleanup(() => disposeBrowserCssInspection(document));
183
- documentSession.registerCleanup(() => releaseDocumentProjection(document));
184
228
  inspectorSession.registerCleanup(() => window.removeEventListener("keydown", onKeydown));
185
- setInspectorHost(host);
186
- reactRoot.render(createElement(InspectorSessionProvider, { inspector: inspectorSession, documentSession }, createElement(demo ? InspectorShell : AppShell)));
229
+ inspectorSession.registerCleanup(() => window.removeEventListener("keyup", onKeyup));
230
+ inspectorSession.registerCleanup(subscribeCanvasRendererMessages(({ identity, message }) => {
231
+ onRendererKeyboardShortcut(message, identity);
232
+ }));
233
+ reactRoot.render(createElement(InspectorSessionProvider, { inspector: inspectorSession, documentSession: null }, createElement(AppShell)));
187
234
  window.addEventListener("keydown", onKeydown);
235
+ window.addEventListener("keyup", onKeyup);
188
236
  }
189
237
  setInspectorOpen(true);
190
238
  }
191
239
  export function unmountInspector() {
192
240
  rendererBootstrapHandle?.teardown();
193
241
  rendererBootstrapHandle = null;
194
- stopClipboardHandoffController?.();
195
- stopClipboardHandoffController = null;
196
242
  unsubscribeOwnership?.();
197
243
  unsubscribeOwnership = null;
198
244
  if (lockedRoot) {
@@ -201,6 +247,7 @@ export function unmountInspector() {
201
247
  }
202
248
  cancelStaleDetection();
203
249
  cancelInlineTextEdit();
250
+ cancelSketchInteraction();
204
251
  setSelectedElement(null);
205
252
  if (reactRoot) {
206
253
  reactRoot.unmount();
@@ -215,8 +262,8 @@ export function unmountInspector() {
215
262
  // a session (gestures, workspace projection) cannot leak across unmount.
216
263
  releaseDocumentProjection(document);
217
264
  clearClipboardHandoff();
265
+ clearSketchClipboardHandoff();
218
266
  removeManagedSheet();
219
- clearInspectorLayout();
220
267
  removeInspectionBridge?.();
221
268
  removeInspectionBridge = null;
222
269
  hostElement = null;
@@ -227,6 +274,7 @@ export { InspectorShell } from "./shell/InspectorShell.js";
227
274
  export { detectFramework } from "./prompt/detectFramework.js";
228
275
  export { installStaticHtmlRuntimeIdentity, isRuntimeGeneratedSource, RUNTIME_ELEMENT_CID_PREFIX, RUNTIME_UNKNOWN_SOURCE_PREFIX, } from "./runtime/staticHtmlRuntimeIdentity.js";
229
276
  export { isCanvasRenderer } from "./canvas/roleDetection.js";
277
+ export { createNudgeUiEditorUrl, hasNudgeUiDirectTabIntent, isNudgeUiDirectUrl, readNudgeUiEditorTarget, rememberNudgeUiDirectTabIntent, } from "../transport/editor.js";
230
278
  export { NUDGE_UI_INSPECTION_VERSION, inspectElement, installInspectionBridge } from "./inspection/bridge.js";
231
279
  export { beginInlineTextEdit, cancelInlineTextEdit, disposeInlineTextEdit, getInlineTextDiagnostic, getInlineTextDiagnostics, getInlineTextSession, inlineTextEditor, isInlineTextEditingActive, subscribeInlineTextDiagnostics, resolveTextBinding, useInlineTextSession, } from "./inline-text/inlineTextEditor.js";
232
280
  export { projectInspectorValues, projectionSides } from "./spacing/projection.js";
@@ -0,0 +1,10 @@
1
+ import type { InlineTextDiagnostic } from "./inlineTextEditor.js";
2
+ export declare function recordInlineTextDiagnostic(diagnostic: InlineTextDiagnostic, ownerDocument?: Document, target?: Element): void;
3
+ export declare function getInlineTextDiagnostics(): readonly InlineTextDiagnostic[];
4
+ export declare function getInlineTextDiagnostic(): InlineTextDiagnostic | null;
5
+ export declare function subscribeInlineTextDiagnostics(listener: () => void): () => void;
6
+ export declare function useInlineTextDiagnostic(): InlineTextDiagnostic | null;
7
+ /** Clear the current diagnostic, optionally only when it belongs to a frame. */
8
+ export declare function clearInlineTextDiagnostics(ownerDocument?: Document): void;
9
+ /** Keep feedback for the target that was just selected, but clear stale feedback. */
10
+ export declare function clearInlineTextDiagnosticsForSelection(selectedElements: readonly HTMLElement[]): void;
@@ -0,0 +1,65 @@
1
+ import { useSyncExternalStore } from "react";
2
+ const listeners = new Set();
3
+ let diagnostics = [];
4
+ let revision = 0;
5
+ function notify() {
6
+ revision += 1;
7
+ for (const listener of listeners)
8
+ listener();
9
+ }
10
+ function sameDiagnostic(left, right) {
11
+ return left.kind === right.kind
12
+ && left.status === right.status
13
+ && left.reason === right.reason
14
+ && left.before === right.before
15
+ && left.after === right.after;
16
+ }
17
+ export function recordInlineTextDiagnostic(diagnostic, ownerDocument, target) {
18
+ const resolvedDocument = ownerDocument ?? target?.ownerDocument;
19
+ const previous = diagnostics.at(-1);
20
+ if (previous
21
+ && previous.ownerDocument === resolvedDocument
22
+ && previous.target === target
23
+ && sameDiagnostic(previous.diagnostic, diagnostic)) {
24
+ return;
25
+ }
26
+ diagnostics = [
27
+ ...diagnostics.slice(-31),
28
+ { diagnostic, ownerDocument: resolvedDocument, target },
29
+ ];
30
+ notify();
31
+ }
32
+ export function getInlineTextDiagnostics() {
33
+ return diagnostics.map(({ diagnostic }) => diagnostic);
34
+ }
35
+ export function getInlineTextDiagnostic() {
36
+ return diagnostics.at(-1)?.diagnostic ?? null;
37
+ }
38
+ export function subscribeInlineTextDiagnostics(listener) {
39
+ listeners.add(listener);
40
+ return () => listeners.delete(listener);
41
+ }
42
+ export function useInlineTextDiagnostic() {
43
+ useSyncExternalStore(subscribeInlineTextDiagnostics, () => revision, () => revision);
44
+ return getInlineTextDiagnostic();
45
+ }
46
+ /** Clear the current diagnostic, optionally only when it belongs to a frame. */
47
+ export function clearInlineTextDiagnostics(ownerDocument) {
48
+ const current = diagnostics.at(-1);
49
+ if (!current)
50
+ return;
51
+ if (ownerDocument && current.ownerDocument !== ownerDocument)
52
+ return;
53
+ diagnostics = [];
54
+ notify();
55
+ }
56
+ /** Keep feedback for the target that was just selected, but clear stale feedback. */
57
+ export function clearInlineTextDiagnosticsForSelection(selectedElements) {
58
+ const current = diagnostics.at(-1);
59
+ if (!current)
60
+ return;
61
+ const target = current.target;
62
+ if (target && selectedElements.length === 1 && selectedElements[0] === target)
63
+ return;
64
+ clearInlineTextDiagnostics();
65
+ }
@@ -1,4 +1,4 @@
1
- import { type TextBindingChoice, type TextEditBinding, type TextEditRejection } from "../componentSemantics/textBinding.js";
1
+ import { type TextBindingChoice, type TextEditBinding, type TextEditRejection, type TextEditRejectionReason } from "../componentSemantics/textBinding.js";
2
2
  import type { ChangeRecord } from "../changes/types.js";
3
3
  import type { TextProjectionScope } from "./textChangeBoundary.js";
4
4
  export type { TextEditBinding, TextEditRejection } from "../componentSemantics/textBinding.js";
@@ -28,13 +28,11 @@ export type InlineTextInputRejectionReason = "cross-host-range" | "rich-input" |
28
28
  export interface InlineTextDiagnostic {
29
29
  kind: "inline-text";
30
30
  status: "started" | "committed" | "cancelled" | "rejected";
31
- reason: InlineTextSessionEndReason | InlineTextInputRejectionReason;
31
+ reason: InlineTextSessionEndReason | InlineTextInputRejectionReason | TextEditRejectionReason;
32
32
  before: string;
33
33
  after?: string;
34
34
  }
35
- export declare function getInlineTextDiagnostics(): readonly InlineTextDiagnostic[];
36
- export declare function getInlineTextDiagnostic(): InlineTextDiagnostic | null;
37
- export declare function subscribeInlineTextDiagnostics(listener: () => void): () => void;
35
+ export { clearInlineTextDiagnostics, getInlineTextDiagnostic, getInlineTextDiagnostics, subscribeInlineTextDiagnostics, useInlineTextDiagnostic, } from "./inlineTextDiagnostics.js";
38
36
  export declare function getInlineTextSession(): InlineTextSession | null;
39
37
  export declare function useInlineTextSession(): InlineTextSession | null;
40
38
  export declare function isInlineTextEditingActive(): boolean;