nudge-ui 0.2.4 → 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 (250) hide show
  1. package/dist/cli/agentCommand.js +4 -28
  2. package/dist/client.mjs +863 -213
  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 +1 -1
  16. package/dist/inspector/agent/verification.js +7 -4
  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 +21 -12
  22. package/dist/inspector/canvas/CanvasElementOverlay.js +82 -127
  23. package/dist/inspector/canvas/CanvasToolbar.js +2 -1
  24. package/dist/inspector/canvas/CanvasWorkspace.js +74 -97
  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/pageSurface.d.ts +11 -0
  49. package/dist/inspector/canvas/pageSurface.js +34 -0
  50. package/dist/inspector/canvas/projection.d.ts +19 -9
  51. package/dist/inspector/canvas/projection.js +58 -31
  52. package/dist/inspector/canvas/rendererBootstrap.js +4 -1
  53. package/dist/inspector/canvas/rendererElementSelector.js +9 -1
  54. package/dist/inspector/canvas/rendererMessageRouter.d.ts +4 -5
  55. package/dist/inspector/canvas/rendererMessageRouter.js +12 -16
  56. package/dist/inspector/canvas/rendererSelectionProxy.d.ts +7 -1
  57. package/dist/inspector/canvas/rendererSelectionProxy.js +8 -36
  58. package/dist/inspector/canvas/rendererStylesheet.js +15 -0
  59. package/dist/inspector/canvas/sessionStore.d.ts +2 -2
  60. package/dist/inspector/canvas/sessionStore.js +12 -9
  61. package/dist/inspector/canvas/staleChangeDetector.d.ts +1 -1
  62. package/dist/inspector/canvas/staleChangeDetector.js +10 -22
  63. package/dist/inspector/changes/codecs.d.ts +1 -0
  64. package/dist/inspector/changes/codecs.js +20 -5
  65. package/dist/inspector/changes/draftPreview.d.ts +12 -0
  66. package/dist/inspector/changes/draftPreview.js +133 -0
  67. package/dist/inspector/changes/editModel.d.ts +8 -0
  68. package/dist/inspector/changes/editModel.js +8 -2
  69. package/dist/inspector/changes/managedStyleProjection.js +2 -1
  70. package/dist/inspector/changes/previewDiagnostics.js +1 -1
  71. package/dist/inspector/changes/types.d.ts +11 -1
  72. package/dist/inspector/comments/CommentsOverlay.js +18 -16
  73. package/dist/inspector/comments/store.js +3 -2
  74. package/dist/inspector/comments/verification.js +1 -1
  75. package/dist/inspector/componentSemantics/ComponentPropsSection.js +2 -1
  76. package/dist/inspector/componentSemantics/changeAction.js +1 -1
  77. package/dist/inspector/componentSemantics/textBinding.d.ts +1 -2
  78. package/dist/inspector/componentSemantics/textBinding.js +4 -45
  79. package/dist/inspector/drafts/draftStore.d.ts +109 -0
  80. package/dist/inspector/drafts/draftStore.js +451 -0
  81. package/dist/inspector/drafts/model.d.ts +9 -1
  82. package/dist/inspector/drafts/model.js +5 -1
  83. package/dist/inspector/drafts/store.d.ts +53 -15
  84. package/dist/inspector/drafts/store.js +143 -169
  85. package/dist/inspector/index.d.ts +2 -4
  86. package/dist/inspector/index.js +2 -264
  87. package/dist/inspector/inline-text/inlineTextEditor.d.ts +1 -1
  88. package/dist/inspector/inline-text/inlineTextEditor.js +1 -2
  89. package/dist/inspector/inline-text/textEditChange.d.ts +1 -1
  90. package/dist/inspector/inspection/bridge.d.ts +1 -1
  91. package/dist/inspector/inspection/bridge.js +2 -1
  92. package/dist/inspector/inspection/browserCssInspection.d.ts +8 -0
  93. package/dist/inspector/inspection/browserCssInspection.js +28 -6
  94. package/dist/inspector/inspection/inspectionSnapshot.d.ts +6 -0
  95. package/dist/inspector/inspection/inspectionSnapshot.js +10 -0
  96. package/dist/inspector/inspection/performanceDiagnostics.d.ts +18 -0
  97. package/dist/inspector/inspection/performanceDiagnostics.js +31 -0
  98. package/dist/inspector/inspection/useBrowserCssInspection.js +17 -38
  99. package/dist/inspector/iterations/capture.d.ts +2 -1
  100. package/dist/inspector/iterations/client.d.ts +2 -1
  101. package/dist/inspector/iterations/coordinator.d.ts +4 -3
  102. package/dist/inspector/iterations/coordinator.js +5 -3
  103. package/dist/inspector/iterations/prompt.js +9 -8
  104. package/dist/inspector/overlay/interactionStyles.js +17 -0
  105. package/dist/inspector/pageInspector.d.ts +42 -0
  106. package/dist/inspector/pageInspector.js +342 -0
  107. package/dist/inspector/projection/draftProjection.d.ts +10 -2
  108. package/dist/inspector/projection/draftProjection.js +9 -1
  109. package/dist/inspector/projection/managedStylesheet.js +24 -4
  110. package/dist/inspector/projection/renderedInstance.js +7 -1
  111. package/dist/inspector/projection/structuralProjection.d.ts +0 -9
  112. package/dist/inspector/projection/structuralProjection.js +14 -44
  113. package/dist/inspector/projection/textProjection.d.ts +8 -2
  114. package/dist/inspector/projection/textProjection.js +21 -13
  115. package/dist/inspector/prompt/clipboardHandoff.d.ts +9 -0
  116. package/dist/inspector/prompt/clipboardHandoff.js +42 -16
  117. package/dist/inspector/prompt/generatePrompt.d.ts +1 -1
  118. package/dist/inspector/prompt/generatePrompt.js +243 -147
  119. package/dist/inspector/prompt/promptDocument.d.ts +3 -0
  120. package/dist/inspector/prompt/promptDocument.js +8 -0
  121. package/dist/inspector/prompt/promptSettings.js +7 -5
  122. package/dist/inspector/runtime/inspectorStorage.d.ts +17 -0
  123. package/dist/inspector/runtime/inspectorStorage.js +42 -0
  124. package/dist/inspector/runtime/ownedStylesheets.d.ts +20 -0
  125. package/dist/inspector/runtime/ownedStylesheets.js +72 -0
  126. package/dist/inspector/runtime/runtimeConfig.d.ts +4 -0
  127. package/dist/inspector/runtime/runtimeConfig.js +10 -1
  128. package/dist/inspector/runtime/runtimeIdentityClaims.d.ts +29 -0
  129. package/dist/inspector/runtime/runtimeIdentityClaims.js +188 -0
  130. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.d.ts +15 -0
  131. package/dist/inspector/runtime/staticHtmlRuntimeIdentity.js +113 -29
  132. package/dist/inspector/selection/editScope.d.ts +1 -0
  133. package/dist/inspector/selection/editScope.js +13 -2
  134. package/dist/inspector/shell/AgentStatusButton.js +2 -2
  135. package/dist/inspector/shell/AppShell.js +6 -2
  136. package/dist/inspector/shell/ChangesLog.js +27 -9
  137. package/dist/inspector/shell/CopyPromptButton.js +60 -54
  138. package/dist/inspector/shell/EmptyState.js +3 -3
  139. package/dist/inspector/shell/InspectorShell.d.ts +0 -3
  140. package/dist/inspector/shell/InspectorShell.js +21 -13
  141. package/dist/inspector/shell/PeekOriginalButton.js +3 -3
  142. package/dist/inspector/shell/interactionStatePreview.d.ts +9 -0
  143. package/dist/inspector/shell/interactionStatePreview.js +112 -0
  144. package/dist/inspector/shell/originalPreview.d.ts +3 -2
  145. package/dist/inspector/shell/originalPreview.js +10 -37
  146. package/dist/inspector/shell/stateValue.js +2 -3
  147. package/dist/inspector/sketch/SketchEditor.js +5 -4
  148. package/dist/inspector/sketch/SketchFrameOverlay.d.ts +2 -1
  149. package/dist/inspector/sketch/SketchFrameOverlay.js +5 -4
  150. package/dist/inspector/sketch/SketchOverlay.d.ts +3 -5
  151. package/dist/inspector/sketch/SketchOverlay.js +139 -263
  152. package/dist/inspector/sketch/SketchPromptPanel.d.ts +1 -1
  153. package/dist/inspector/sketch/SketchPromptPanel.js +8 -1
  154. package/dist/inspector/sketch/SketchThumbnail.d.ts +5 -0
  155. package/dist/inspector/sketch/SketchThumbnail.js +18 -0
  156. package/dist/inspector/sketch/SketchWorkspace.d.ts +1 -2
  157. package/dist/inspector/sketch/SketchWorkspace.js +69 -34
  158. package/dist/inspector/sketch/capture.js +19 -3
  159. package/dist/inspector/sketch/copySketch.d.ts +10 -0
  160. package/dist/inspector/sketch/copySketch.js +52 -0
  161. package/dist/inspector/sketch/drawingTools.d.ts +17 -0
  162. package/dist/inspector/sketch/drawingTools.js +47 -0
  163. package/dist/inspector/sketch/frameHeading.d.ts +9 -0
  164. package/dist/inspector/sketch/frameHeading.js +30 -0
  165. package/dist/inspector/sketch/freehand.js +3 -3
  166. package/dist/inspector/sketch/geometry.d.ts +6 -0
  167. package/dist/inspector/sketch/geometry.js +19 -0
  168. package/dist/inspector/sketch/history.d.ts +30 -0
  169. package/dist/inspector/sketch/history.js +58 -0
  170. package/dist/inspector/sketch/interaction.d.ts +1 -3
  171. package/dist/inspector/sketch/interaction.js +6 -9
  172. package/dist/inspector/sketch/model.d.ts +35 -1
  173. package/dist/inspector/sketch/model.js +116 -61
  174. package/dist/inspector/sketch/persistence.d.ts +14 -0
  175. package/dist/inspector/sketch/persistence.js +63 -7
  176. package/dist/inspector/sketch/raster.d.ts +6 -2
  177. package/dist/inspector/sketch/raster.js +43 -17
  178. package/dist/inspector/sketch/store.d.ts +1 -1
  179. package/dist/inspector/sketch/store.js +1 -1
  180. package/dist/inspector/sketch/videoFrames.d.ts +6 -0
  181. package/dist/inspector/sketch/videoFrames.js +81 -0
  182. package/dist/inspector/styleEditors/BackgroundEditor.js +2 -1
  183. package/dist/inspector/styleEditors/BorderEditor.js +30 -130
  184. package/dist/inspector/styleEditors/BorderRadiusEditor.js +8 -3
  185. package/dist/inspector/styleEditors/ImageBackgroundEditor.js +1 -1
  186. package/dist/inspector/styleEditors/LayoutSection.js +2 -2
  187. package/dist/inspector/styleEditors/borderModel.d.ts +42 -0
  188. package/dist/inspector/styleEditors/borderModel.js +114 -0
  189. package/dist/inspector/styleEditors/layoutValue.js +2 -3
  190. package/dist/inspector/tokens/TokenField.js +34 -3
  191. package/dist/inspector/tokens/TokensPanel.js +2 -1
  192. package/dist/inspector/tokens/editActions.d.ts +3 -3
  193. package/dist/inspector/tokens/editActions.js +9 -3
  194. package/dist/inspector/tokens/resolution/containerQueryEvaluator.d.ts +15 -0
  195. package/dist/inspector/tokens/resolution/containerQueryEvaluator.js +86 -0
  196. package/dist/inspector/tokens/resolution/cssomCollector.js +44 -9
  197. package/dist/inspector/tokens/resolution/nestedSelectors.d.ts +6 -0
  198. package/dist/inspector/tokens/resolution/nestedSelectors.js +67 -0
  199. package/dist/inspector/tokens/resolution/ruleMatching.js +23 -4
  200. package/dist/inspector/tokens/resolution.d.ts +6 -3
  201. package/dist/inspector/tokens/resolution.js +91 -112
  202. package/dist/inspector/tokens/tokenEdits.d.ts +1 -1
  203. package/dist/inspector/tokens/tokenEdits.js +1 -1
  204. package/dist/inspector/ui/InlineStyleWarning.js +2 -2
  205. package/dist/inspector/ui/InspectorStyle.d.ts +8 -0
  206. package/dist/inspector/ui/InspectorStyle.js +26 -0
  207. package/dist/inspector/ui/PopoverListbox.d.ts +2 -1
  208. package/dist/inspector/ui/PopoverListbox.js +3 -3
  209. package/dist/inspector/ui/Toast.d.ts +14 -0
  210. package/dist/inspector/ui/Toast.js +30 -0
  211. package/dist/inspector/ui/assets/canvasIllustration.d.ts +2 -0
  212. package/dist/inspector/ui/assets/canvasIllustration.js +21 -0
  213. package/dist/inspector/ui/assets/gridIllustration.d.ts +2 -0
  214. package/dist/inspector/ui/assets/{grid.svg → gridIllustration.js} +3 -2
  215. package/dist/inspector/ui/customCursors.d.ts +5 -0
  216. package/dist/inspector/ui/customCursors.js +32 -6
  217. package/dist/inspector/ui/styles.js +12 -10
  218. package/dist/inspector/workspace/commands.js +1 -2
  219. package/dist/inspector/workspace/controller.js +1 -2
  220. package/dist/inspector/workspace/handoff.js +3 -2
  221. package/dist/inspector/workspace/sentItems.d.ts +3 -6
  222. package/dist/inspector/workspace/sentItems.js +6 -24
  223. package/dist/inspector/workspace/timeline.d.ts +24 -10
  224. package/dist/inspector/workspace/timeline.js +118 -96
  225. package/dist/internal/agent-protocol.d.ts +50 -13
  226. package/dist/internal/agent-protocol.js +145 -19
  227. package/dist/nudge-ui.mjs +81 -65
  228. package/dist/project/mcpPackage.d.ts +8 -0
  229. package/dist/project/mcpPackage.js +60 -0
  230. package/package.json +12 -2
  231. package/dist/inspector/canvas/measurementProjection.d.ts +0 -8
  232. package/dist/inspector/canvas/measurementProjection.js +0 -16
  233. package/dist/inspector/changes/changesLog.d.ts +0 -49
  234. package/dist/inspector/changes/changesLog.js +0 -255
  235. package/dist/inspector/changes/draftChanges.d.ts +0 -58
  236. package/dist/inspector/changes/draftChanges.js +0 -304
  237. package/dist/inspector/conformance/projection.d.ts +0 -2
  238. package/dist/inspector/conformance/projection.js +0 -3
  239. package/dist/inspector/inline-text/textChangeBoundary.d.ts +0 -6
  240. package/dist/inspector/inline-text/textChangeBoundary.js +0 -1
  241. package/dist/inspector/overlay/InspectorOverlay.d.ts +0 -5
  242. package/dist/inspector/overlay/InspectorOverlay.js +0 -332
  243. package/dist/inspector/overlay/elementSelector.d.ts +0 -1
  244. package/dist/inspector/overlay/elementSelector.js +0 -111
  245. package/dist/inspector/sketch/SketchChanges.d.ts +0 -2
  246. package/dist/inspector/sketch/SketchChanges.js +0 -72
  247. package/dist/inspector/sketch/SketchEntryButton.d.ts +0 -4
  248. package/dist/inspector/sketch/SketchEntryButton.js +0 -11
  249. package/dist/inspector/sketch/SketchLayersPanel.d.ts +0 -2
  250. package/dist/inspector/sketch/SketchLayersPanel.js +0 -71
@@ -1,7 +1,8 @@
1
- import { getActiveDraftChanges, getDraftChanges } from "../changes/draftChanges.js";
1
+ import { boundRuntimeEvidence, normalizeRuntimeTag, runtimeDomPath } from "../runtime/staticHtmlRuntimeIdentity.js";
2
+ import { getActiveDraftChanges, getDraftChanges } from "../drafts/store.js";
2
3
  import { sourceSiteSelector } from "../selection/sourceSite.js";
3
4
  import { isNudgeUiDev } from "../runtime/devFlag.js";
4
- import { isTextContentChangeValue, isTextProjectionTargetValue, } from "../inline-text/textChangeBoundary.js";
5
+ import { isTextContentChangeValue, isTextProjectionTargetValue, } from "../changes/editModel.js";
5
6
  import { isInteractionStylesInstalled } from "../overlay/interactionStyles.js";
6
7
  /** Strict JSON boundary guard for a text projection target. */
7
8
  export const isTextProjectionTarget = isTextProjectionTargetValue;
@@ -190,28 +191,32 @@ export function resolveTextProjectionTextNode(element, target, expectedText = ta
190
191
  }
191
192
  return matches.length === 1 ? matches[0] : null;
192
193
  }
193
- function hasSafeMixedDescendants(element) {
194
+ /** Whether an element's text is code, form state, or other non-prose content. */
195
+ export function isUnsafeTextHost(element) {
196
+ return UNSAFE_TEXT_TAGS.has(element.tagName);
197
+ }
198
+ /** Whether an application-owned editing region contains the element. */
199
+ export function isInApplicationEditingHost(element) {
200
+ const editingHost = element.closest("[contenteditable]");
201
+ return Boolean(editingHost
202
+ && editingHost.getAttribute("data-inline-editor") !== "true"
203
+ && editingHost.getAttribute("contenteditable") !== "false");
204
+ }
205
+ /** Whether replacing one text node inside the element keeps its authored markup. */
206
+ export function hasSafeMixedDescendants(element) {
194
207
  // <br> only controls line layout. The projection targets one exact text
195
208
  // node, so keeping the break while changing that node is safe; formatting
196
209
  // descendants below still reject a flattening text projection.
197
210
  for (const descendant of Array.from(element.querySelectorAll("*"))) {
198
211
  if (UNSAFE_MIXED_DESCENDANT_TAGS.has(descendant.tagName))
199
212
  return false;
200
- const editingHost = descendant.closest("[contenteditable]");
201
- if (editingHost
202
- && editingHost.getAttribute("data-inline-editor") !== "true"
203
- && editingHost.getAttribute("contenteditable") !== "false")
213
+ if (isInApplicationEditingHost(descendant))
204
214
  return false;
205
215
  }
206
216
  return true;
207
217
  }
208
218
  function textHostIsSafe(element, allowEmpty = false, target) {
209
- if (UNSAFE_TEXT_TAGS.has(element.tagName))
210
- return false;
211
- const editingHost = element.closest("[contenteditable]");
212
- if (editingHost
213
- && editingHost.getAttribute("data-inline-editor") !== "true"
214
- && editingHost.getAttribute("contenteditable") !== "false")
219
+ if (isUnsafeTextHost(element) || isInApplicationEditingHost(element))
215
220
  return false;
216
221
  if (allowEmpty && element.childNodes.length === 0)
217
222
  return true;
@@ -295,6 +300,9 @@ export function captureTextProjectionTarget(element, beforeText = element.textCo
295
300
  props: element.getAttribute("data-cprops"),
296
301
  ariaLabel: element.getAttribute("aria-label"),
297
302
  beforeText,
303
+ tagName: normalizeRuntimeTag(element.tagName),
304
+ elementId: boundRuntimeEvidence(element.id || null),
305
+ domPath: runtimeDomPath(element),
298
306
  ...pathTarget,
299
307
  };
300
308
  }
@@ -27,5 +27,14 @@ export declare function getClipboardHandoffRecords(draftId: string): {
27
27
  structuralChanges: StructuralChange[];
28
28
  };
29
29
  export declare function reconcileClipboardHandoff(doc?: Document): Promise<number>;
30
+ /**
31
+ * Verifies copied edits after the document changes. Each check briefly removes
32
+ * the copied preview, so a check that reconciles nothing doubles the minimum
33
+ * interval before the next one: a page that mutates continuously (clocks,
34
+ * carousels) would otherwise flash the preview every few hundred milliseconds.
35
+ * Later changes never postpone a pending check, so a busy page is still
36
+ * checked once per interval. Returning to the page or copying a new prompt
37
+ * resets the interval.
38
+ */
30
39
  export declare function startClipboardHandoffController(doc?: Document): () => void;
31
40
  export {};
@@ -1,5 +1,5 @@
1
1
  import { changeKey } from "../changes/model.js";
2
- import { getDraftChanges, getActiveDraftChanges, subscribeActiveDraftChanges } from "../changes/draftChanges.js";
2
+ import { getDraftChanges, getActiveDraftChanges, subscribeActiveDraftChanges } from "../drafts/store.js";
3
3
  import { documentRevisions, subscribeDocumentRevision } from "../tokens/resolution/cssomCollector.js";
4
4
  import { captureHandoffOwner, handoffChangeFingerprint, handoffStructuralFingerprint, verifyAndReconcileHandoff, } from "../agent/verification.js";
5
5
  import { isDraftTarget } from "../drafts/model.js";
@@ -124,33 +124,58 @@ export async function reconcileClipboardHandoff(doc = document) {
124
124
  }
125
125
  return removed;
126
126
  }
127
+ const CHECK_DELAY_MS = 450;
128
+ const MAX_CHECK_DELAY_MS = 8_000;
129
+ /**
130
+ * Verifies copied edits after the document changes. Each check briefly removes
131
+ * the copied preview, so a check that reconciles nothing doubles the minimum
132
+ * interval before the next one: a page that mutates continuously (clocks,
133
+ * carousels) would otherwise flash the preview every few hundred milliseconds.
134
+ * Later changes never postpone a pending check, so a busy page is still
135
+ * checked once per interval. Returning to the page or copying a new prompt
136
+ * resets the interval.
137
+ */
127
138
  export function startClipboardHandoffController(doc = document) {
128
139
  const view = doc.defaultView;
129
140
  let timer = null;
130
141
  let checking = false;
131
142
  let stopped = false;
132
- const schedule = () => {
143
+ let interval = CHECK_DELAY_MS;
144
+ let lastCheckEndedAt = -Infinity;
145
+ const run = () => {
146
+ timer = null;
133
147
  if (stopped || checking || !checkpoints.size)
134
148
  return;
149
+ checking = true;
150
+ void reconcileClipboardHandoff(doc).then((removed) => {
151
+ interval = removed > 0 ? CHECK_DELAY_MS : Math.min(interval * 2, MAX_CHECK_DELAY_MS);
152
+ }, () => undefined).finally(() => {
153
+ lastCheckEndedAt = Date.now();
154
+ setTimeout(() => { checking = false; }, 0);
155
+ });
156
+ };
157
+ const schedule = () => {
158
+ if (stopped || checking || !checkpoints.size || timer !== null)
159
+ return;
160
+ // Let the change that triggered this settle, and keep the backoff interval.
161
+ timer = setTimeout(run, Math.max(CHECK_DELAY_MS, lastCheckEndedAt + interval - Date.now()));
162
+ };
163
+ const returned = () => {
164
+ interval = CHECK_DELAY_MS;
165
+ lastCheckEndedAt = -Infinity;
135
166
  if (timer !== null)
136
167
  clearTimeout(timer);
137
- timer = setTimeout(() => {
138
- timer = null;
139
- if (stopped || checking || !checkpoints.size)
140
- return;
141
- checking = true;
142
- void reconcileClipboardHandoff(doc).catch(() => undefined).finally(() => {
143
- setTimeout(() => { checking = false; }, 0);
144
- });
145
- }, 450);
168
+ timer = null;
169
+ schedule();
146
170
  };
147
171
  const visible = () => { if (doc.visibilityState === "visible")
148
- schedule(); };
172
+ returned(); };
149
173
  documentRevisions(doc);
150
174
  const stopRevision = subscribeDocumentRevision(doc, schedule);
151
175
  const stopChanges = subscribeActiveDraftChanges(pruneCheckpoints);
152
- view?.addEventListener("focus", schedule);
153
- view?.addEventListener("pageshow", schedule);
176
+ const stopHandoff = subscribeClipboardHandoff(() => { interval = CHECK_DELAY_MS; });
177
+ view?.addEventListener("focus", returned);
178
+ view?.addEventListener("pageshow", returned);
154
179
  doc.addEventListener("visibilitychange", visible);
155
180
  schedule();
156
181
  return () => {
@@ -159,8 +184,9 @@ export function startClipboardHandoffController(doc = document) {
159
184
  clearTimeout(timer);
160
185
  stopRevision();
161
186
  stopChanges();
162
- view?.removeEventListener("focus", schedule);
163
- view?.removeEventListener("pageshow", schedule);
187
+ stopHandoff();
188
+ view?.removeEventListener("focus", returned);
189
+ view?.removeEventListener("pageshow", returned);
164
190
  doc.removeEventListener("visibilitychange", visible);
165
191
  };
166
192
  }
@@ -1,4 +1,4 @@
1
- import type { ChangeRecord } from "../changes/changesLog.js";
1
+ import type { ChangeRecord } from "../changes/types.js";
2
2
  import type { StructuralChange } from "../projection/structuralProjection.js";
3
3
  import type { AgentSketchMetadata } from "../agent/protocol.js";
4
4
  import { type ElementComment } from "../comments/store.js";