nudge-ui 0.2.3 → 0.2.5

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 (264) hide show
  1. package/dist/cli/agentCommand.js +4 -28
  2. package/dist/client.mjs +870 -212
  3. package/dist/hosts/next/wrapper.js +1 -7
  4. package/dist/hosts/projectBridge.js +3 -17
  5. package/dist/inspector/agent/McpConnectionDialog.js +7 -3
  6. package/dist/inspector/agent/activity.d.ts +1 -1
  7. package/dist/inspector/agent/activity.js +3 -2
  8. package/dist/inspector/agent/client.d.ts +2 -2
  9. package/dist/inspector/agent/client.js +28 -29
  10. package/dist/inspector/agent/connectionStatus.d.ts +3 -1
  11. package/dist/inspector/agent/connectionStatus.js +25 -0
  12. package/dist/inspector/agent/httpTransport.js +31 -147
  13. package/dist/inspector/agent/protocol.d.ts +1 -1
  14. package/dist/inspector/agent/protocol.js +1 -1
  15. package/dist/inspector/agent/verification.d.ts +5 -7
  16. package/dist/inspector/agent/verification.js +67 -20
  17. package/dist/inspector/boot.d.ts +3 -0
  18. package/dist/inspector/boot.js +297 -0
  19. package/dist/inspector/canvas/AgentActivityOverlay.d.ts +2 -1
  20. package/dist/inspector/canvas/AgentActivityOverlay.js +6 -3
  21. package/dist/inspector/canvas/CanvasCard.js +23 -12
  22. package/dist/inspector/canvas/CanvasElementOverlay.js +97 -128
  23. package/dist/inspector/canvas/CanvasToolbar.js +2 -1
  24. package/dist/inspector/canvas/CanvasWorkspace.js +119 -162
  25. package/dist/inspector/canvas/LockedWorkspaceNotice.d.ts +3 -2
  26. package/dist/inspector/canvas/LockedWorkspaceNotice.js +10 -6
  27. package/dist/inspector/canvas/PageCard.d.ts +10 -0
  28. package/dist/inspector/canvas/PageCard.js +51 -0
  29. package/dist/inspector/canvas/SketchToolOptions.d.ts +5 -0
  30. package/dist/inspector/canvas/SketchToolOptions.js +86 -0
  31. package/dist/inspector/canvas/StaleChangeIndicator.d.ts +1 -1
  32. package/dist/inspector/canvas/StaleChangeIndicator.js +1 -1
  33. package/dist/inspector/canvas/ToolOptionsDrawer.d.ts +21 -0
  34. package/dist/inspector/canvas/ToolOptionsDrawer.js +77 -0
  35. package/dist/inspector/canvas/activeCanvasDocument.d.ts +3 -2
  36. package/dist/inspector/canvas/assets/eraser.svg +28 -0
  37. package/dist/inspector/canvas/assets/pen.svg +25 -0
  38. package/dist/inspector/canvas/canvasFrame.d.ts +16 -0
  39. package/dist/inspector/canvas/canvasFrame.js +10 -0
  40. package/dist/inspector/canvas/canvasGestures.d.ts +0 -1
  41. package/dist/inspector/canvas/canvasGestures.js +0 -6
  42. package/dist/inspector/canvas/canvasStore.d.ts +6 -0
  43. package/dist/inspector/canvas/canvasStore.js +36 -1
  44. package/dist/inspector/canvas/frameConnection.d.ts +48 -0
  45. package/dist/inspector/canvas/frameConnection.js +73 -0
  46. package/dist/inspector/canvas/frameProtocol.d.ts +18 -1
  47. package/dist/inspector/canvas/frameProtocol.js +36 -0
  48. package/dist/inspector/canvas/frameScrollbarStyles.d.ts +3 -0
  49. package/dist/inspector/canvas/frameScrollbarStyles.js +21 -0
  50. package/dist/inspector/canvas/pageSurface.d.ts +11 -0
  51. package/dist/inspector/canvas/pageSurface.js +34 -0
  52. package/dist/inspector/canvas/projection.d.ts +19 -9
  53. package/dist/inspector/canvas/projection.js +58 -31
  54. package/dist/inspector/canvas/rendererBootstrap.js +4 -1
  55. package/dist/inspector/canvas/rendererElementSelector.js +9 -1
  56. package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
  57. package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
  58. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
  59. package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
  60. package/dist/inspector/canvas/rendererStylesheet.js +15 -0
  61. package/dist/inspector/canvas/sessionStore.d.ts +2 -2
  62. package/dist/inspector/canvas/sessionStore.js +12 -9
  63. package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
  64. package/dist/inspector/canvas/staleChangeDetector.js +10 -22
  65. package/dist/inspector/changes/codecs.d.ts +2 -0
  66. package/dist/inspector/changes/codecs.js +27 -3
  67. package/dist/inspector/changes/draftPreview.d.ts +12 -0
  68. package/dist/inspector/changes/draftPreview.js +133 -0
  69. package/dist/inspector/changes/editModel.d.ts +18 -0
  70. package/dist/inspector/changes/editModel.js +16 -3
  71. package/dist/inspector/changes/managedStyleProjection.js +2 -1
  72. package/dist/inspector/changes/previewDiagnostics.js +1 -1
  73. package/dist/inspector/changes/types.d.ts +18 -1
  74. package/dist/inspector/comments/CommentsOverlay.js +18 -16
  75. package/dist/inspector/comments/element.js +10 -3
  76. package/dist/inspector/comments/store.js +3 -2
  77. package/dist/inspector/comments/verification.js +1 -1
  78. package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
  79. package/dist/inspector/componentSemantics/adapterRegistry.d.ts +6 -1
  80. package/dist/inspector/componentSemantics/adapterRegistry.js +23 -1
  81. package/dist/inspector/componentSemantics/changeAction.js +1 -1
  82. package/dist/inspector/componentSemantics/reactRuntime.d.ts +2 -1
  83. package/dist/inspector/componentSemantics/reactRuntime.js +38 -0
  84. package/dist/inspector/componentSemantics/runtimeBridge.d.ts +4 -2
  85. package/dist/inspector/componentSemantics/runtimeBridge.js +17 -0
  86. package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
  87. package/dist/inspector/componentSemantics/textBinding.js +4 -45
  88. package/dist/inspector/componentSemantics/types.d.ts +11 -0
  89. package/dist/inspector/drafts/draftStore.d.ts +109 -0
  90. package/dist/inspector/drafts/draftStore.js +451 -0
  91. package/dist/inspector/drafts/model.d.ts +9 -1
  92. package/dist/inspector/drafts/model.js +5 -1
  93. package/dist/inspector/drafts/store.d.ts +53 -15
  94. package/dist/inspector/drafts/store.js +143 -169
  95. package/dist/inspector/index.d.ts +2 -4
  96. package/dist/inspector/index.js +2 -264
  97. package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
  98. package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
  99. package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
  100. package/dist/inspector/inspection/bridge.d.ts +1 -1
  101. package/dist/inspector/inspection/bridge.js +2 -1
  102. package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
  103. package/dist/inspector/inspection/browserCssInspection.js +28 -6
  104. package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
  105. package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
  106. package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
  107. package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
  108. package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
  109. package/dist/inspector/iterations/capture.d.ts +2 -1
  110. package/dist/inspector/iterations/capture.js +2 -1
  111. package/dist/inspector/iterations/client.d.ts +2 -1
  112. package/dist/inspector/iterations/coordinator.d.ts +4 -3
  113. package/dist/inspector/iterations/coordinator.js +5 -3
  114. package/dist/inspector/iterations/prompt.js +9 -8
  115. package/dist/inspector/overlay/interactionStyles.js +17 -0
  116. package/dist/inspector/pageInspector.d.ts +42 -0
  117. package/dist/inspector/pageInspector.js +342 -0
  118. package/dist/inspector/projection/draftProjection.d.ts +10 -2
  119. package/dist/inspector/projection/draftProjection.js +9 -1
  120. package/dist/inspector/projection/managedStylesheet.js +24 -4
  121. package/dist/inspector/projection/renderedInstance.d.ts +15 -2
  122. package/dist/inspector/projection/renderedInstance.js +60 -7
  123. package/dist/inspector/projection/structuralProjection.d.ts +0 -9
  124. package/dist/inspector/projection/structuralProjection.js +16 -46
  125. package/dist/inspector/projection/textProjection.d.ts +8 -2
  126. package/dist/inspector/projection/textProjection.js +77 -24
  127. package/dist/inspector/prompt/clipboardHandoff.d.ts +14 -0
  128. package/dist/inspector/prompt/clipboardHandoff.js +47 -16
  129. package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
  130. package/dist/inspector/prompt/generatePrompt.js +248 -148
  131. package/dist/inspector/prompt/promptDocument.d.ts +3 -0
  132. package/dist/inspector/prompt/promptDocument.js +8 -0
  133. package/dist/inspector/prompt/promptSettings.js +7 -5
  134. package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
  135. package/dist/inspector/runtime/inspectorStorage.js +42 -0
  136. package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
  137. package/dist/inspector/runtime/ownedStylesheets.js +72 -0
  138. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  139. package/dist/inspector/runtime/runtimeConfig.js +10 -1
  140. package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
  141. package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
  142. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
  143. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
  144. package/dist/inspector/selection/editScope.d.ts +1 -0
  145. package/dist/inspector/selection/editScope.js +13 -2
  146. package/dist/inspector/selection/sourceSite.d.ts +12 -0
  147. package/dist/inspector/selection/sourceSite.js +28 -0
  148. package/dist/inspector/shell/AgentStatusButton.js +2 -2
  149. package/dist/inspector/shell/AppShell.js +6 -2
  150. package/dist/inspector/shell/ChangesLog.js +27 -9
  151. package/dist/inspector/shell/CopyPromptButton.js +74 -26
  152. package/dist/inspector/shell/EmptyState.js +3 -3
  153. package/dist/inspector/shell/InspectorShell.d.ts +0 -3
  154. package/dist/inspector/shell/InspectorShell.js +21 -13
  155. package/dist/inspector/shell/PeekOriginalButton.js +3 -3
  156. package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
  157. package/dist/inspector/shell/interactionStatePreview.js +112 -0
  158. package/dist/inspector/shell/originalPreview.d.ts +3 -2
  159. package/dist/inspector/shell/originalPreview.js +10 -37
  160. package/dist/inspector/shell/stateValue.js +2 -3
  161. package/dist/inspector/sketch/SketchEditor.js +5 -4
  162. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
  163. package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
  164. package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
  165. package/dist/inspector/sketch/SketchOverlay.js +139 -263
  166. package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
  167. package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
  168. package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
  169. package/dist/inspector/sketch/SketchThumbnail.js +18 -0
  170. package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
  171. package/dist/inspector/sketch/SketchWorkspace.js +69 -34
  172. package/dist/inspector/sketch/capture.js +19 -3
  173. package/dist/inspector/sketch/copySketch.d.ts +10 -0
  174. package/dist/inspector/sketch/copySketch.js +52 -0
  175. package/dist/inspector/sketch/drawingTools.d.ts +17 -0
  176. package/dist/inspector/sketch/drawingTools.js +47 -0
  177. package/dist/inspector/sketch/frameHeading.d.ts +9 -0
  178. package/dist/inspector/sketch/frameHeading.js +30 -0
  179. package/dist/inspector/sketch/freehand.js +3 -3
  180. package/dist/inspector/sketch/geometry.d.ts +6 -0
  181. package/dist/inspector/sketch/geometry.js +19 -0
  182. package/dist/inspector/sketch/history.d.ts +30 -0
  183. package/dist/inspector/sketch/history.js +58 -0
  184. package/dist/inspector/sketch/interaction.d.ts +1 -3
  185. package/dist/inspector/sketch/interaction.js +6 -9
  186. package/dist/inspector/sketch/model.d.ts +35 -1
  187. package/dist/inspector/sketch/model.js +116 -61
  188. package/dist/inspector/sketch/persistence.d.ts +14 -0
  189. package/dist/inspector/sketch/persistence.js +63 -7
  190. package/dist/inspector/sketch/raster.d.ts +6 -2
  191. package/dist/inspector/sketch/raster.js +43 -17
  192. package/dist/inspector/sketch/store.d.ts +1 -1
  193. package/dist/inspector/sketch/store.js +1 -1
  194. package/dist/inspector/sketch/videoFrames.d.ts +6 -0
  195. package/dist/inspector/sketch/videoFrames.js +81 -0
  196. package/dist/inspector/styleEditors/BackgroundEditor.js +3 -2
  197. package/dist/inspector/styleEditors/BorderEditor.js +30 -130
  198. package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
  199. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
  200. package/dist/inspector/styleEditors/LayoutSection.js +2 -2
  201. package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
  202. package/dist/inspector/styleEditors/borderModel.js +114 -0
  203. package/dist/inspector/styleEditors/layoutValue.js +2 -3
  204. package/dist/inspector/tokens/TokenField.js +40 -7
  205. package/dist/inspector/tokens/TokensPanel.js +2 -1
  206. package/dist/inspector/tokens/editActions.d.ts +3 -3
  207. package/dist/inspector/tokens/editActions.js +15 -3
  208. package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
  209. package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
  210. package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
  211. package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
  212. package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
  213. package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
  214. package/dist/inspector/tokens/resolution.d.ts +6 -3
  215. package/dist/inspector/tokens/resolution.js +91 -112
  216. package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
  217. package/dist/inspector/tokens/tokenEdits.js +1 -1
  218. package/dist/inspector/ui/InlineStyleWarning.js +2 -2
  219. package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
  220. package/dist/inspector/ui/InspectorStyle.js +26 -0
  221. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  222. package/dist/inspector/ui/PopoverListbox.js +3 -3
  223. package/dist/inspector/ui/Toast.d.ts +14 -0
  224. package/dist/inspector/ui/Toast.js +30 -0
  225. package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
  226. package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
  227. package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
  228. package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
  229. package/dist/inspector/ui/customCursors.d.ts +5 -0
  230. package/dist/inspector/ui/customCursors.js +32 -6
  231. package/dist/inspector/ui/styles.js +12 -10
  232. package/dist/inspector/workspace/commands.js +1 -2
  233. package/dist/inspector/workspace/controller.js +1 -2
  234. package/dist/inspector/workspace/handoff.js +3 -2
  235. package/dist/inspector/workspace/sentItems.d.ts +16 -0
  236. package/dist/inspector/workspace/sentItems.js +33 -0
  237. package/dist/inspector/workspace/timeline.d.ts +24 -10
  238. package/dist/inspector/workspace/timeline.js +118 -96
  239. package/dist/internal/agent-protocol.d.ts +50 -13
  240. package/dist/internal/agent-protocol.js +145 -19
  241. package/dist/nudge-ui.mjs +81 -65
  242. package/dist/project/mcpPackage.d.ts +8 -0
  243. package/dist/project/mcpPackage.js +60 -0
  244. package/package.json +13 -3
  245. package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
  246. package/dist/inspector/canvas/measurementProjection.js +0 -16
  247. package/dist/inspector/changes/changesLog.d.ts +0 -47
  248. package/dist/inspector/changes/changesLog.js +0 -247
  249. package/dist/inspector/changes/draftChanges.d.ts +0 -56
  250. package/dist/inspector/changes/draftChanges.js +0 -300
  251. package/dist/inspector/conformance/projection.d.ts +0 -2
  252. package/dist/inspector/conformance/projection.js +0 -3
  253. package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
  254. package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
  255. package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
  256. package/dist/inspector/overlay/InspectorOverlay.js +0 -332
  257. package/dist/inspector/overlay/elementSelector.d.ts +0 -1
  258. package/dist/inspector/overlay/elementSelector.js +0 -111
  259. package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
  260. package/dist/inspector/sketch/SketchChanges.js +0 -72
  261. package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
  262. package/dist/inspector/sketch/SketchEntryButton.js +0 -11
  263. package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
  264. package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
@@ -1,3 +1,4 @@
1
+ import { type ContainerQueryEvaluator } from "../tokens/resolution/containerQueryEvaluator.js";
1
2
  import type { TokenDefinition, TokenEntry } from "../../css/model/index.js";
2
3
  import type { ResolvedProperty } from "../../css/model/index.js";
3
4
  import type { InteractionState } from "../shell/styleState.js";
@@ -25,6 +26,8 @@ export type InspectionCascade = "authored" | "live" | "stable";
25
26
  export interface BrowserCssInspectionOptions {
26
27
  state?: InteractionState;
27
28
  cascade?: InspectionCascade;
29
+ /** Shared only within one synchronous refresh. */
30
+ containerQueries?: ContainerQueryEvaluator;
28
31
  }
29
32
  export type InspectionTargetStatus = "attached" | "detached" | "foreign-document" | "unsupported" | "disabled" | "disposed";
30
33
  export type InspectionDiagnosticCode = "target-document-mismatch" | "target-detached" | "target-unsupported" | "state-unavailable" | "inspection-failed" | "production-disabled" | "session-disposed";
@@ -62,6 +65,11 @@ export interface DocumentTokenInspectionSnapshot {
62
65
  }
63
66
  export interface BrowserCssInspection {
64
67
  inspect(element: HTMLElement, options?: BrowserCssInspectionOptions): InspectionSnapshot;
68
+ /** Resolves one selection with a shared, short-lived container evaluator. */
69
+ refresh?(elements: readonly HTMLElement[], state: InteractionState): {
70
+ elements: readonly InspectionSnapshot[];
71
+ stableProperties: readonly ResolvedProperty[];
72
+ };
65
73
  inspectTokens(root?: HTMLElement): DocumentTokenInspectionSnapshot;
66
74
  subscribe(listener: (revision: InspectionRevision) => void): () => void;
67
75
  /** Integration hook for managed CSSOM writes. */
@@ -1,5 +1,7 @@
1
+ import { createContainerQueryEvaluator } from "../tokens/resolution/containerQueryEvaluator.js";
1
2
  import { isNudgeUiDev } from "../runtime/devFlag.js";
2
- import { buildTokenTable, getAvailableInteractionStates, getAvailableTokenCatalog, getAvailableTokenEntriesForElement, getResolvedProperties, getResolvedPropertiesForState, getResolvedPropertiesStable, invalidateStyleResolutionCache, prewarmCssomRuleSnapshot, } from "../tokens/resolution.js";
3
+ import { countInspectionWork } from "./performanceDiagnostics.js";
4
+ import { buildTokenTable, getAvailableInteractionStates, getAvailableTokenCatalog, getAvailableTokenEntriesForElement, getResolvedProperties, getResolvedPropertiesForState, getResolvedPropertiesStable, invalidateStyleResolutionCache, prewarmCssomRuleSnapshot, prefetchContainerQueries, } from "../tokens/resolution.js";
3
5
  import { buildTokenCatalogRows } from "../tokens/catalog.js";
4
6
  import { documentRevisions, registerResolutionElement, retainDocumentResolution, subscribeDocumentRevision, } from "../tokens/resolution/cssomCollector.js";
5
7
  function revisionSnapshot(revisions, tokenGeneration) {
@@ -119,12 +121,12 @@ function disabledInspection(config) {
119
121
  function notifyRevision(listener, revisions, tokenGeneration) {
120
122
  listener(revisionSnapshot(revisions, tokenGeneration));
121
123
  }
122
- function resolveCascadeProperties(element, table, cascade, state) {
124
+ function resolveCascadeProperties(element, table, cascade, state, evaluator) {
123
125
  if (cascade === "live")
124
- return getResolvedProperties(element, table);
126
+ return getResolvedProperties(element, table, evaluator);
125
127
  if (cascade === "stable")
126
- return getResolvedPropertiesStable(element, table);
127
- return getResolvedPropertiesForState(element, table, state);
128
+ return getResolvedPropertiesStable(element, table, evaluator);
129
+ return getResolvedPropertiesForState(element, table, state, evaluator);
128
130
  }
129
131
  export function createBrowserCssInspection(config) {
130
132
  if (!isNudgeUiDev())
@@ -197,6 +199,7 @@ export function createBrowserCssInspection(config) {
197
199
  }
198
200
  const session = {
199
201
  inspect(element, options = {}) {
202
+ countInspectionWork(config.document, "inspections");
200
203
  const state = options.state ?? "base";
201
204
  const cascade = options.cascade ?? "authored";
202
205
  const status = disposed ? "disposed" : targetStatus(element, config.document);
@@ -227,7 +230,7 @@ export function createBrowserCssInspection(config) {
227
230
  message: `The ${state} interaction state has no matching authored rule for this element.`,
228
231
  });
229
232
  }
230
- const properties = resolveCascadeProperties(element, table, cascade, state);
233
+ const properties = resolveCascadeProperties(element, table, cascade, state, options.containerQueries ?? createContainerQueryEvaluator(config.document));
231
234
  return {
232
235
  target: { status },
233
236
  cascade,
@@ -249,6 +252,25 @@ export function createBrowserCssInspection(config) {
249
252
  return emptySnapshot(status, cascade, state, revision, diagnostics);
250
253
  }
251
254
  },
255
+ refresh(elements, state) {
256
+ const containerQueries = createContainerQueryEvaluator(config.document);
257
+ const targets = elements.filter((element) => element.ownerDocument === config.document);
258
+ try {
259
+ if (!disposed)
260
+ prefetchContainerQueries(targets, state, containerQueries);
261
+ }
262
+ catch (error) {
263
+ return {
264
+ elements: elements.map((element) => emptySnapshot(targetStatus(element, config.document), "authored", state, currentRevision(), [{ code: "inspection-failed", message: error instanceof Error ? error.message : "Container query evaluation failed." }])),
265
+ stableProperties: [],
266
+ };
267
+ }
268
+ return {
269
+ elements: elements.map((element) => session.inspect(element, { state, containerQueries })),
270
+ stableProperties: elements[0] && state === "base"
271
+ ? session.inspect(elements[0], { cascade: "stable", containerQueries }).properties : [],
272
+ };
273
+ },
252
274
  inspectTokens(root = config.document.documentElement) {
253
275
  const diagnostics = [];
254
276
  const revision = currentRevision();
@@ -0,0 +1,6 @@
1
+ import type { InteractionState } from "../shell/styleState.js";
2
+ import type { InspectionSnapshot } from "./browserCssInspection.js";
3
+ /** Publishes the hook's completed refresh before its controls render. */
4
+ export declare function publishInspectionSnapshot(element: HTMLElement, snapshot: InspectionSnapshot): void;
5
+ /** Reads the current view without starting another cascade inspection. */
6
+ export declare function readInspectionSnapshot(element: HTMLElement, state: InteractionState): InspectionSnapshot | undefined;
@@ -0,0 +1,10 @@
1
+ const snapshots = new WeakMap();
2
+ /** Publishes the hook's completed refresh before its controls render. */
3
+ export function publishInspectionSnapshot(element, snapshot) {
4
+ snapshots.set(element, snapshot);
5
+ }
6
+ /** Reads the current view without starting another cascade inspection. */
7
+ export function readInspectionSnapshot(element, state) {
8
+ const snapshot = snapshots.get(element);
9
+ return snapshot?.requestedState === state ? snapshot : undefined;
10
+ }
@@ -0,0 +1,18 @@
1
+ type Interaction = "selection" | "hover" | "drag" | "idle";
2
+ type Counter = "inspections" | "refreshes" | "containerChecks" | "probePairs" | "probeBatches";
3
+ type Counts = Record<Counter, number>;
4
+ interface InspectionPerformanceDiagnostics {
5
+ read(): Record<Interaction, Counts>;
6
+ reset(): void;
7
+ dispose(): void;
8
+ }
9
+ declare global {
10
+ interface Window {
11
+ __nudgeUiPerformance?: InspectionPerformanceDiagnostics;
12
+ }
13
+ }
14
+ /** Records work only when diagnostics are explicitly enabled for a document. */
15
+ export declare function countInspectionWork(doc: Document, counter: Counter, count?: number): void;
16
+ /** Groups asynchronous inspection work by the most recent pointer gesture. */
17
+ export declare function enableInspectionPerformanceDiagnostics(doc: Document): void;
18
+ export {};
@@ -0,0 +1,31 @@
1
+ const counters = new WeakMap();
2
+ /** Records work only when diagnostics are explicitly enabled for a document. */
3
+ export function countInspectionWork(doc, counter, count = 1) {
4
+ counters.get(doc)?.(counter, count);
5
+ }
6
+ /** Groups asynchronous inspection work by the most recent pointer gesture. */
7
+ export function enableInspectionPerformanceDiagnostics(doc) {
8
+ const view = doc.defaultView;
9
+ if (!view || view.__nudgeUiPerformance)
10
+ return;
11
+ let interaction = "idle";
12
+ const empty = () => ({ inspections: 0, refreshes: 0, containerChecks: 0, probePairs: 0, probeBatches: 0 });
13
+ let counts = { idle: empty(), selection: empty(), hover: empty(), drag: empty() };
14
+ const move = (event) => { interaction = event.buttons ? "drag" : "hover"; };
15
+ const select = () => { interaction = "selection"; };
16
+ doc.addEventListener("pointermove", move, true);
17
+ doc.addEventListener("pointerdown", select, true);
18
+ doc.addEventListener("click", select, true);
19
+ counters.set(doc, (counter, count) => { counts[interaction][counter] += count; });
20
+ view.__nudgeUiPerformance = {
21
+ read: () => structuredClone(counts),
22
+ reset() { counts = { idle: empty(), selection: empty(), hover: empty(), drag: empty() }; },
23
+ dispose() {
24
+ doc.removeEventListener("pointermove", move, true);
25
+ doc.removeEventListener("pointerdown", select, true);
26
+ doc.removeEventListener("click", select, true);
27
+ counters.delete(doc);
28
+ delete view.__nudgeUiPerformance;
29
+ },
30
+ };
31
+ }
@@ -1,5 +1,7 @@
1
+ import { publishInspectionSnapshot } from "./inspectionSnapshot.js";
1
2
  import { useEffect, useMemo, useRef, useState } from "react";
2
3
  import { getBrowserCssInspection } from "./browserCssInspectionRegistry.js";
4
+ import { countInspectionWork } from "./performanceDiagnostics.js";
3
5
  const SELECTION_DEBOUNCE_MS = 8;
4
6
  const EMPTY_SELECTION = [];
5
7
  function isSelectedElementList(selected) {
@@ -18,23 +20,16 @@ function normalizeSelection(selected) {
18
20
  return selected;
19
21
  return [selected];
20
22
  }
21
- function inspectAuthoredElements(session, selected, state) {
22
- return selected.map((element) => session.inspect(element.domElement, { state, cascade: "authored" }));
23
- }
24
- function inspectStableView(session, selected, state, includeDocumentTokens, elements) {
25
- const primary = elements[0] ?? null;
26
- const stableProperties = selected[0] && state === "base"
27
- ? session.inspect(selected[0].domElement, { cascade: "stable" }).properties
28
- : [];
29
- const documentTokens = includeDocumentTokens ? session.inspectTokens() : null;
23
+ function inspectView(session, selected, state, includeDocumentTokens) {
24
+ const result = session.refresh?.(selected.map((element) => element.domElement), state);
25
+ const elements = result?.elements ?? selected.map((element) => session.inspect(element.domElement, { state, cascade: "authored" }));
26
+ const stableProperties = result?.stableProperties ?? (selected[0] && state === "base"
27
+ ? session.inspect(selected[0].domElement, { cascade: "stable" }).properties : []);
28
+ elements.forEach((snapshot, index) => publishInspectionSnapshot(selected[index].domElement, snapshot));
30
29
  return {
31
- selection: selected,
32
- state,
33
- session,
34
- element: primary,
35
- elements,
36
- stableProperties,
37
- documentTokens,
30
+ selection: selected, state, session,
31
+ element: elements[0] ?? null, elements, stableProperties,
32
+ documentTokens: includeDocumentTokens ? session.inspectTokens() : null,
38
33
  };
39
34
  }
40
35
  /**
@@ -49,14 +44,15 @@ export function useBrowserCssInspection(selected, state = "base", options = {})
49
44
  const includeDocumentTokens = options.includeDocumentTokens ?? false;
50
45
  const latest = useRef({ selected: selectedElements, state, session, includeDocumentTokens });
51
46
  latest.current = { selected: selectedElements, state, session, includeDocumentTokens };
52
- const [view, setView] = useState(() => inspectStableView(session, selectedElements, state, includeDocumentTokens, inspectAuthoredElements(session, selectedElements, state)));
47
+ const [view, setView] = useState(() => ({
48
+ ...EMPTY_VIEW, selection: EMPTY_SELECTION, state, session,
49
+ }));
53
50
  const timerRef = useRef(null);
54
51
  const lastSelectionResolveAtRef = useRef(0);
55
52
  const revisionFrameRef = useRef(null);
56
53
  const revisionSecondFrameRef = useRef(null);
57
54
  const revisionThirdFrameRef = useRef(null);
58
55
  const revisionWarmFrameRef = useRef(null);
59
- const stableFrameRef = useRef(null);
60
56
  const cancelScheduledInspection = () => {
61
57
  if (timerRef.current !== null) {
62
58
  clearTimeout(timerRef.current);
@@ -78,29 +74,12 @@ export function useBrowserCssInspection(selected, state = "base", options = {})
78
74
  cancelAnimationFrame(revisionWarmFrameRef.current);
79
75
  revisionWarmFrameRef.current = null;
80
76
  }
81
- if (stableFrameRef.current !== null) {
82
- cancelAnimationFrame(stableFrameRef.current);
83
- stableFrameRef.current = null;
84
- }
85
77
  };
86
78
  const resolveSync = () => {
87
79
  const current = latest.current;
80
+ countInspectionWork(selectedDocument, "refreshes");
88
81
  lastSelectionResolveAtRef.current = performance.now();
89
- setView(inspectStableView(current.session, current.selected, current.state, current.includeDocumentTokens, inspectAuthoredElements(current.session, current.selected, current.state)));
90
- };
91
- const resolveSplit = () => {
92
- const current = latest.current;
93
- // Post-commit refresh: the authored cascade resolves in this task and the
94
- // secondary stable cascade continues one frame later. Rapid successive
95
- // edits therefore cancel the pending refresh (revision bumps reschedule)
96
- // instead of finding a long blocking task already running, and the two
97
- // resolution sweeps never block one task for their combined duration.
98
- // The view still commits once, with the same data and ordering.
99
- const elements = inspectAuthoredElements(current.session, current.selected, current.state);
100
- stableFrameRef.current = requestAnimationFrame(() => {
101
- stableFrameRef.current = null;
102
- setView(inspectStableView(current.session, current.selected, current.state, current.includeDocumentTokens, elements));
103
- });
82
+ setView(inspectView(current.session, current.selected, current.state, current.includeDocumentTokens));
104
83
  };
105
84
  const scheduleSelectionInspection = () => {
106
85
  cancelScheduledInspection();
@@ -135,7 +114,7 @@ export function useBrowserCssInspection(selected, state = "base", options = {})
135
114
  latest.current.session.prewarmRules?.();
136
115
  revisionWarmFrameRef.current = requestAnimationFrame(() => {
137
116
  revisionWarmFrameRef.current = null;
138
- resolveSplit();
117
+ resolveSync();
139
118
  });
140
119
  });
141
120
  });
@@ -1,2 +1,3 @@
1
+ import type { CanvasFrame } from "../canvas/canvasFrame.js";
1
2
  /** Captures the visible DOM of a same-origin frame as a script-free HTML iteration. */
2
- export declare function captureHtmlIteration(frame: HTMLIFrameElement): Promise<string>;
3
+ export declare function captureHtmlIteration(frame: CanvasFrame): Promise<string>;
@@ -1,4 +1,5 @@
1
1
  import { HTML_ARTIFACT_REVISION_ATTRIBUTE } from "../../transport/artifacts.js";
2
+ import { FRAME_SCROLLBAR_STYLE_ID } from "../canvas/frameScrollbarStyles.js";
2
3
  /** Captures the visible DOM of a same-origin frame as a script-free HTML iteration. */
3
4
  export async function captureHtmlIteration(frame) {
4
5
  const source = frame.contentDocument;
@@ -52,7 +53,7 @@ export async function captureHtmlIteration(frame) {
52
53
  copy.querySelectorAll("base").forEach((element) => element.remove());
53
54
  (copy.querySelector("head") ?? copy).prepend(base);
54
55
  copy.querySelectorAll('script, iframe, object, embed, meta[http-equiv="refresh"], meta[http-equiv="Content-Security-Policy"], link[rel=modulepreload], link[rel=preload]').forEach((element) => element.remove());
55
- copy.querySelectorAll("[data-nudge-ui-mount], #nudge-ui-root").forEach((element) => element.remove());
56
+ copy.querySelectorAll(`[data-nudge-ui-mount], #nudge-ui-root, #${FRAME_SCROLLBAR_STYLE_ID}`).forEach((element) => element.remove());
56
57
  copy.querySelectorAll("a, form").forEach((element) => {
57
58
  element.removeAttribute("href");
58
59
  element.removeAttribute("action");
@@ -1,7 +1,8 @@
1
+ import type { CanvasFrame } from "../canvas/canvasFrame.js";
1
2
  import { type HtmlArtifactRevision } from "../../transport/artifacts.js";
2
3
  export declare function artifactDocumentUrl(id: string): string;
3
4
  export declare function readHtmlArtifactRevision(id: string): Promise<HtmlArtifactRevision>;
4
5
  /** Checks the editing base before saving and promoting a captured document. */
5
6
  export declare function commitHtmlArtifact(id: string, expected: HtmlArtifactRevision, html?: string): Promise<HtmlArtifactRevision>;
6
- export declare function createHtmlArtifact(frame: HTMLIFrameElement, sourceUrl: string, title: string, capturedHtml?: string): Promise<string>;
7
+ export declare function createHtmlArtifact(frame: CanvasFrame, sourceUrl: string, title: string, capturedHtml?: string): Promise<string>;
7
8
  export declare function removeHtmlArtifact(id: string): Promise<void>;
@@ -1,5 +1,6 @@
1
+ import { type CanvasFrame } from "../canvas/canvasFrame.js";
1
2
  import type { HtmlArtifactRevision } from "../../transport/artifacts.js";
2
- import { type DraftContents } from "../changes/draftChanges.js";
3
+ import type { DraftContents } from "../drafts/model.js";
3
4
  /** Owned transport; tests use a working in-memory artifact store. */
4
5
  export interface HtmlIterationStorage {
5
6
  readRevision(id: string): Promise<HtmlArtifactRevision>;
@@ -11,5 +12,5 @@ export declare function createHtmlIterationCoordinator(storage: HtmlIterationSto
11
12
  refresh(cardId: string, artifactId: string, baseRevision: string, available: () => boolean): Promise<boolean>;
12
13
  };
13
14
  /** Materializes pending intent before the agent can start editing document.html. */
14
- export declare function prepareHtmlIterationHandoff(cardId: string, artifactId: string, frame: HTMLIFrameElement): Promise<DraftContents>;
15
- export declare function refreshHtmlIteration(cardId: string, artifactId: string, frame: HTMLIFrameElement): Promise<boolean>;
15
+ export declare function prepareHtmlIterationHandoff(cardId: string, artifactId: string, frame: CanvasFrame): Promise<DraftContents>;
16
+ export declare function refreshHtmlIteration(cardId: string, artifactId: string, frame: CanvasFrame): Promise<boolean>;
@@ -1,6 +1,6 @@
1
+ import { canvasFrameElement } from "../canvas/canvasFrame.js";
1
2
  import { HTML_ARTIFACT_REVISION_ATTRIBUTE } from "../../transport/artifacts.js";
2
- import { getDraftForCard, getDraftContentsForCard, clearSavedIterationDraft } from "../drafts/store.js";
3
- import { lockDraft } from "../changes/draftChanges.js";
3
+ import { getDraftForCard, getDraftContentsForCard, clearSavedIterationDraft, lockDraft } from "../drafts/store.js";
4
4
  import { canWriteWorkspace } from "../canvas/workspaceLease.js";
5
5
  import { projectDraftToDocument, isCanvasProjectionRevisionCurrent, projectToAllReadyCards } from "../canvas/projection.js";
6
6
  import { isInlineTextEditingActive } from "../inline-text/inlineTextEditor.js";
@@ -117,7 +117,9 @@ export async function prepareHtmlIterationHandoff(cardId, artifactId, frame) {
117
117
  }
118
118
  return html;
119
119
  });
120
- frame.src = `${artifactDocumentUrl(artifactId)}?revision=${Date.now()}`;
120
+ const element = canvasFrameElement(frame);
121
+ if (element)
122
+ element.src = `${artifactDocumentUrl(artifactId)}?revision=${Date.now()}`;
121
123
  return workspace;
122
124
  }
123
125
  finally {
@@ -1,26 +1,27 @@
1
+ import { withPromptContext } from "../prompt/promptDocument.js";
1
2
  /** Defines the edit destination for every HTML-iteration handoff, including fallback copies. */
2
3
  export function htmlIterationPrompt(id, changes, noInspectorChanges, hasSketches, customInstructions = "") {
3
4
  const directory = `.nudge/artifacts/${id}`;
4
- return [
5
- "# Edit this HTML iteration",
5
+ return withPromptContext([
6
+ "## Edit this HTML iteration",
6
7
  "",
7
8
  `Edit only \`${directory}/document.html\`. This is the standalone HTML and CSS shown in the selected Nudge iteration frame.`,
8
9
  "Preserve its responsive CSS and existing design edits. Keep application source files unchanged. Any original source locations below identify captured elements; they are not files to edit.",
9
10
  `Keep \`${directory}/baseline.html\`, \`${directory}/preview.html\`, and metadata unchanged. Nudge will reload the iteration from your updated document.`,
10
11
  ...(hasSketches ? ["Implement the attached sketch notes in this iteration's HTML and CSS. Match numbered notes to their marks in the image."] : []),
11
12
  "",
12
- ...(noInspectorChanges ? ["Use the current iteration as the editing base. Existing visual edits are already saved in its markup and styles.", ...(customInstructions.trim() ? ["", "## Custom instructions", "", customInstructions.trim()] : [])] : [changes]),
13
- ].join("\n");
13
+ ], noInspectorChanges
14
+ ? ["Use the current iteration as the editing base. Existing visual edits are already saved in its markup and styles.", ...(customInstructions.trim() ? ["", "## Custom instructions", "", customInstructions.trim()] : [])].join("\n")
15
+ : changes);
14
16
  }
15
17
  export function htmlIterationImplementationPrompt(id, label, page, changes) {
16
18
  const directory = `.nudge/artifacts/${id}`;
17
- return [
18
- `# Implement ${label} in the live app`,
19
+ return withPromptContext([
20
+ `## Implement ${label} in the live app`,
19
21
  "",
20
22
  `Page: ${page}`,
21
23
  `Use \`${directory}/document.html\` as the design reference, including all saved visual edits.`,
22
24
  "Update application source for this page to match it. Reuse existing components and styles, and preserve app behavior and data.",
23
25
  "Keep iteration files unchanged; captured source locations below are hints for finding app code.",
24
- ...(changes.trim() ? ["", changes] : []),
25
- ].join("\n");
26
+ ], changes);
26
27
  }
@@ -1,4 +1,5 @@
1
1
  import { DESIGN_SELECT_CURSOR, INTERACTION_CURSOR_PROPERTY } from "../ui/customCursors.js";
2
+ import { adoptStylesheet, allowsStyleElements, releaseAdoptedStylesheet } from "../runtime/ownedStylesheets.js";
2
3
  const INTERACTION_STYLE_ID = "nudge-ui-interaction-styles";
3
4
  const interactionStyleDocuments = new Set();
4
5
  const INTERACTION_CSS = `
@@ -47,6 +48,8 @@ export function isInteractionStylesInstalled(doc = document) {
47
48
  }
48
49
  /** Installs temporary interaction affordances without mutating tracked nodes. */
49
50
  export function installInteractionStyles(doc = document) {
51
+ if (!allowsStyleElements(doc))
52
+ return installAdoptedInteractionStyles(doc);
50
53
  // SAFETY: getElementById returns an Element; the style element is created as HTMLStyleElement below when missing.
51
54
  let style = doc.getElementById(INTERACTION_STYLE_ID);
52
55
  let created = false;
@@ -70,3 +73,17 @@ export function installInteractionStyles(doc = document) {
70
73
  style?.remove();
71
74
  };
72
75
  }
76
+ function installAdoptedInteractionStyles(doc) {
77
+ adoptStylesheet(doc, INTERACTION_STYLE_ID, INTERACTION_CSS);
78
+ interactionStyleDocuments.add(doc);
79
+ for (const slot of Array.from(doc.querySelectorAll("[data-empty-text]"))) {
80
+ slot.hidden = false;
81
+ }
82
+ return () => {
83
+ interactionStyleDocuments.delete(doc);
84
+ for (const slot of Array.from(doc.querySelectorAll("[data-empty-text]"))) {
85
+ slot.hidden = true;
86
+ }
87
+ releaseAdoptedStylesheet(doc, INTERACTION_STYLE_ID);
88
+ };
89
+ }
@@ -0,0 +1,42 @@
1
+ import { type InspectorStorage } from "./runtime/inspectorStorage.js";
2
+ import { type SketchStorage } from "./sketch/persistence.js";
3
+ export type { InspectorStorage } from "./runtime/inspectorStorage.js";
4
+ export { createMirroredStorage } from "./runtime/inspectorStorage.js";
5
+ export type { SketchPersistenceSnapshot, SketchStorage, SketchStorageChange } from "./sketch/persistence.js";
6
+ export type { SketchDocument, SketchHandoffRecord } from "./sketch/model.js";
7
+ export interface PageInspectorOptions {
8
+ /** Replaces `localStorage` for comments, drafts, and Canvas state. */
9
+ storage?: InspectorStorage;
10
+ /** Replaces the page origin's IndexedDB for sketch documents and handoffs. */
11
+ sketchStorage?: SketchStorage;
12
+ /** Skips the `<style>` policy probe and always uses constructable stylesheets. */
13
+ adoptStylesheets?: boolean;
14
+ /**
15
+ * `"editor"` turns a document whose URL carries the editor marker into the
16
+ * iframe editor; otherwise the page itself is the only Canvas card.
17
+ */
18
+ surface?: "editor" | "page";
19
+ /** Shows a short error instead of enabling inspection on an unsupported page. */
20
+ unavailableReason?: string;
21
+ /** Called whenever an editor renderer frame's document finishes parsing. */
22
+ onRendererFrameLoad?: () => void;
23
+ }
24
+ /** Published on `window` so a second injection toggles the first instance. */
25
+ export interface PageInspectorHandle {
26
+ readonly surface: "editor" | "page" | "renderer";
27
+ /** Toggles the page inspector, or leaves the editor. */
28
+ toggle(): void;
29
+ /** Starts the `window.__nudgeUiPerformance` counters for this document. */
30
+ enablePerformanceDiagnostics(): void;
31
+ }
32
+ /**
33
+ * Starts the inspector on the current page. Running a second bundle copy in
34
+ * the same window toggles the first instance instead, because only the first
35
+ * copy's stores drive the UI.
36
+ */
37
+ export declare function startPageInspector(options?: PageInspectorOptions): Promise<void>;
38
+ /**
39
+ * Starts the renderer in an editor's Canvas frame. Does nothing in any other
40
+ * document, or when the frame already runs one.
41
+ */
42
+ export declare function startCanvasRenderer(options?: Pick<PageInspectorOptions, "adoptStylesheets">): void;