@agent-native/core 0.182.1 → 0.182.2-nightly-20260917225811

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 (119) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/clips/app/root.tsx +59 -10
  3. package/corpus/templates/clips/changelog/2026-09-17-desktop-popover-closes-when-clicking-away.md +6 -0
  4. package/corpus/templates/clips/changelog/2026-09-17-self-hosted-extension-sign-in.md +6 -0
  5. package/corpus/templates/clips/chrome-extension/src/background.ts +45 -25
  6. package/corpus/templates/clips/chrome-extension/src/content-script.ts +43 -0
  7. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +55 -6
  8. package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +107 -19
  9. package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +1 -0
  10. package/corpus/templates/design/actions/add-localhost-screens.ts +54 -22
  11. package/corpus/templates/design/actions/apply-component-prop-edit.ts +174 -14
  12. package/corpus/templates/design/actions/apply-visual-edit.ts +3 -1
  13. package/corpus/templates/design/actions/create-component.ts +173 -12
  14. package/corpus/templates/design/actions/create-design-from-template.ts +50 -35
  15. package/corpus/templates/design/actions/create-design-version.ts +21 -0
  16. package/corpus/templates/design/actions/create-file.ts +35 -33
  17. package/corpus/templates/design/actions/delete-design.ts +29 -28
  18. package/corpus/templates/design/actions/delete-file.ts +154 -23
  19. package/corpus/templates/design/actions/generate-design.ts +28 -16
  20. package/corpus/templates/design/actions/get-component-details.ts +272 -33
  21. package/corpus/templates/design/actions/get-design-version.ts +9 -1
  22. package/corpus/templates/design/actions/go-to-main-component.ts +37 -35
  23. package/corpus/templates/design/actions/index-components.ts +241 -126
  24. package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +12 -9
  25. package/corpus/templates/design/actions/present-design-variants.ts +68 -72
  26. package/corpus/templates/design/actions/rename-component.ts +294 -0
  27. package/corpus/templates/design/actions/rename-screen.ts +10 -10
  28. package/corpus/templates/design/actions/update-file.ts +327 -330
  29. package/corpus/templates/design/actions/update-screen-source.ts +2 -43
  30. package/corpus/templates/design/app/components/design/EditPanel.tsx +17 -1
  31. package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +228 -24
  32. package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +17 -1
  33. package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +151 -32
  34. package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +4 -0
  35. package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +1 -1
  36. package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +8 -1
  37. package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +55 -33
  38. package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
  39. package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +4 -2
  40. package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +273 -60
  41. package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +9 -2
  42. package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +57 -9
  43. package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +13 -0
  44. package/corpus/templates/design/app/components/design/multi-screen/types.ts +14 -0
  45. package/corpus/templates/design/app/components/design/types.ts +9 -1
  46. package/corpus/templates/design/app/hooks/use-design-versions.ts +3 -2
  47. package/corpus/templates/design/app/i18n-breakpoints.ts +0 -110
  48. package/corpus/templates/design/app/i18n-data.ts +0 -10
  49. package/corpus/templates/design/app/pages/DesignEditor.tsx +669 -161
  50. package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +20 -0
  51. package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +2 -0
  52. package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +21 -3
  53. package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +2 -0
  54. package/corpus/templates/design/app/pages/design-editor/commands/create-component.ts +44 -3
  55. package/corpus/templates/design/app/pages/design-editor/commands/delete-files.ts +69 -47
  56. package/corpus/templates/design/app/pages/design-editor/commands/duplicate-screen.ts +157 -52
  57. package/corpus/templates/design/app/pages/design-editor/commands/duplicate-selection.ts +76 -1
  58. package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +152 -44
  59. package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +131 -2
  60. package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +5 -1
  61. package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +26 -1
  62. package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +1 -0
  63. package/corpus/templates/design/app/pages/design-editor/editor-helpers.ts +58 -8
  64. package/corpus/templates/design/app/pages/design-editor/editor-state.ts +63 -2
  65. package/corpus/templates/design/app/pages/design-editor/history.ts +3 -0
  66. package/corpus/templates/design/app/pages/design-editor/nudge-intent.ts +74 -22
  67. package/corpus/templates/design/app/pages/design-editor/source-publication.ts +14 -2
  68. package/corpus/templates/design/changelog/2026-09-16-design-components-retain-linked-identities-when-edited-and-d.md +6 -0
  69. package/corpus/templates/design/changelog/2026-09-16-fix-design-nested-layer-dragging-and-screen-duplication-pari.md +6 -0
  70. package/corpus/templates/design/changelog/2026-09-17-design-drag-and-drop-keeps-duplicates-cross-screen-moves-and.md +6 -0
  71. package/corpus/templates/design/changelog/2026-09-17-design-preserves-reusable-component-identity-and-props-acros.md +6 -0
  72. package/corpus/templates/design/changelog/2026-09-17-open-vector-paths-no-longer-show-fills-and-interact-dimensio.md +6 -0
  73. package/corpus/templates/design/changelog/2026-09-17-screen-deletion-is-immediate-and-undoable-with-history-that-.md +6 -0
  74. package/corpus/templates/design/e2e/fixtures/design-component-react/index.html +98 -0
  75. package/corpus/templates/design/e2e/fixtures/design-component-react/inline-component.html +65 -0
  76. package/corpus/templates/design/e2e/helpers.ts +6 -1
  77. package/corpus/templates/design/server/lib/design-data-mutation.ts +9 -5
  78. package/corpus/templates/design/server/lib/design-snapshot.ts +28 -16
  79. package/corpus/templates/design/server/lib/design-versions.ts +208 -130
  80. package/corpus/templates/design/server/lib/fusion-screens.ts +46 -20
  81. package/corpus/templates/design/server/lib/import-design-files.ts +5 -1
  82. package/corpus/templates/design/server/lib/localhost-connection.ts +54 -0
  83. package/corpus/templates/design/server/source-workspace.ts +412 -356
  84. package/corpus/templates/design/shared/component-library.ts +36 -6
  85. package/corpus/templates/design/shared/component-model.ts +12 -2
  86. package/corpus/templates/design/shared/local-jsx-visual-edit.ts +231 -5
  87. package/corpus/templates/design/shared/source-mode.ts +22 -0
  88. package/dist/automation/index.d.ts +1 -1
  89. package/dist/client/AssistantChat.d.ts +4 -1
  90. package/dist/client/AssistantChat.js +26 -3
  91. package/dist/client/chat/agentkit-protocol.js +148 -34
  92. package/dist/client/chat/message-components.js +7 -5
  93. package/dist/client/chat/tool-call-display.js +4 -3
  94. package/dist/client/conversation/AgentConversation.js +4 -2
  95. package/dist/client/tool-display.d.ts +9 -0
  96. package/dist/client/tool-display.js +15 -0
  97. package/dist/collab/awareness.d.ts +2 -2
  98. package/dist/collab/routes.d.ts +1 -1
  99. package/dist/localization/core-messages/ar-SA.js +2 -0
  100. package/dist/localization/core-messages/de-DE.js +2 -0
  101. package/dist/localization/core-messages/en-US.d.ts +2 -0
  102. package/dist/localization/core-messages/en-US.js +2 -0
  103. package/dist/localization/core-messages/es-ES.js +2 -0
  104. package/dist/localization/core-messages/fr-FR.js +2 -0
  105. package/dist/localization/core-messages/hi-IN.js +2 -0
  106. package/dist/localization/core-messages/ja-JP.js +2 -0
  107. package/dist/localization/core-messages/ko-KR.js +2 -0
  108. package/dist/localization/core-messages/pt-BR.js +2 -0
  109. package/dist/localization/core-messages/zh-CN.js +2 -0
  110. package/dist/localization/core-messages/zh-TW.js +2 -0
  111. package/dist/localization/core-messages.d.ts +2 -0
  112. package/dist/notifications/routes.d.ts +3 -3
  113. package/dist/observability/routes.d.ts +3 -3
  114. package/dist/resources/handlers.d.ts +1 -1
  115. package/dist/secrets/routes.d.ts +3 -3
  116. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  117. package/dist/server/core-routes-plugin.d.ts +1 -1
  118. package/package.json +3 -3
  119. package/corpus/templates/design/app/components/design/editor/PendingScreenDeletionDialog.tsx +0 -66
package/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 9518
34
+ - template files: 9529
@@ -212,6 +212,16 @@ function ClipsExtensionAuthBridge() {
212
212
  const targetExtensionId = extensionId;
213
213
 
214
214
  let cancelled = false;
215
+ let removeBridgeListener: (() => void) | null = null;
216
+
217
+ const completeExtensionSignIn = () => {
218
+ if (cancelled) return;
219
+ const cleaned = new URL(window.location.href);
220
+ cleaned.searchParams.delete("clipsExtensionAuth");
221
+ cleaned.searchParams.delete("clipsExtensionId");
222
+ window.history.replaceState(window.history.state, "", cleaned);
223
+ setShowAuthSuccess(true);
224
+ };
215
225
 
216
226
  async function sendSessionToExtension() {
217
227
  const runtime = (
@@ -219,7 +229,6 @@ function ClipsExtensionAuthBridge() {
219
229
  chrome?: { runtime?: ExternalChromeRuntime };
220
230
  }
221
231
  ).chrome?.runtime;
222
- if (!runtime?.sendMessage) return;
223
232
 
224
233
  const response = await fetch(appPath("/_agent-native/auth/session"), {
225
234
  credentials: "include",
@@ -233,21 +242,60 @@ function ClipsExtensionAuthBridge() {
233
242
  return;
234
243
  }
235
244
 
245
+ const message = {
246
+ source: "clips-auth-bridge",
247
+ kind: "session",
248
+ token: session.token,
249
+ email: session.email,
250
+ clipsBaseUrl: window.location.origin,
251
+ } as const;
252
+ const sendViaPageBridge = () => {
253
+ const onMessage = (event: MessageEvent) => {
254
+ if (
255
+ event.source !== window ||
256
+ event.origin !== window.location.origin
257
+ ) {
258
+ return;
259
+ }
260
+ const data = event.data as
261
+ | { source?: unknown; kind?: unknown; ok?: unknown }
262
+ | undefined;
263
+ if (
264
+ data?.source !== "clips-auth-bridge" ||
265
+ data.kind !== "session-result"
266
+ ) {
267
+ return;
268
+ }
269
+ removeBridgeListener?.();
270
+ removeBridgeListener = null;
271
+ if (data.ok === true) completeExtensionSignIn();
272
+ };
273
+ removeBridgeListener = () =>
274
+ window.removeEventListener("message", onMessage);
275
+ window.addEventListener("message", onMessage);
276
+ window.postMessage(message, window.location.origin);
277
+ };
278
+
279
+ if (!runtime?.sendMessage) {
280
+ sendViaPageBridge();
281
+ return;
282
+ }
283
+
236
284
  runtime.sendMessage(
237
285
  targetExtensionId,
238
286
  {
239
287
  type: "CLIPS_AUTH_SESSION",
240
- token: session.token,
241
- email: session.email,
242
- clipsBaseUrl: window.location.origin,
288
+ token: message.token,
289
+ email: message.email,
290
+ clipsBaseUrl: message.clipsBaseUrl,
243
291
  },
244
292
  (extensionResponse) => {
245
- if (cancelled || runtime.lastError || !extensionResponse?.ok) return;
246
- const cleaned = new URL(window.location.href);
247
- cleaned.searchParams.delete("clipsExtensionAuth");
248
- cleaned.searchParams.delete("clipsExtensionId");
249
- window.history.replaceState(window.history.state, "", cleaned);
250
- setShowAuthSuccess(true);
293
+ if (cancelled) return;
294
+ if (!runtime.lastError && extensionResponse?.ok) {
295
+ completeExtensionSignIn();
296
+ return;
297
+ }
298
+ sendViaPageBridge();
251
299
  },
252
300
  );
253
301
  }
@@ -255,6 +303,7 @@ function ClipsExtensionAuthBridge() {
255
303
  void sendSessionToExtension();
256
304
  return () => {
257
305
  cancelled = true;
306
+ removeBridgeListener?.();
258
307
  };
259
308
  }, [location.search]);
260
309
 
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-17
4
+ ---
5
+
6
+ The desktop popover now closes when you click away from it.
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-09-17
4
+ ---
5
+
6
+ Self-hosted Clips extensions now finish sign-in reliably.
@@ -77,6 +77,13 @@ type PopupStartMessage = {
77
77
  settings?: Partial<ExtensionSettings>;
78
78
  };
79
79
 
80
+ type AuthSessionMessage = {
81
+ type: "CLIPS_AUTH_SESSION";
82
+ token?: string;
83
+ email?: string;
84
+ clipsBaseUrl?: string;
85
+ };
86
+
80
87
  type ExternalMessage =
81
88
  | {
82
89
  type: "CLIPS_CAPTURE_START";
@@ -93,12 +100,7 @@ type ExternalMessage =
93
100
  type: "CLIPS_CAPTURE_CANCEL";
94
101
  sessionId?: string;
95
102
  }
96
- | {
97
- type: "CLIPS_AUTH_SESSION";
98
- token?: string;
99
- email?: string;
100
- clipsBaseUrl?: string;
101
- };
103
+ | AuthSessionMessage;
102
104
 
103
105
  type ChromeTab = {
104
106
  id?: number;
@@ -2237,6 +2239,35 @@ async function handlePopupSignIn(message: {
2237
2239
  return { ok: true };
2238
2240
  }
2239
2241
 
2242
+ async function handleAuthSession(
2243
+ message: AuthSessionMessage,
2244
+ senderUrl?: string,
2245
+ ) {
2246
+ const settings = await readSettings();
2247
+ const clipsBaseUrl = normalizeBaseUrl(
2248
+ message.clipsBaseUrl ?? settings.clipsBaseUrl,
2249
+ );
2250
+ const senderOrigin = originOf(senderUrl);
2251
+ if (
2252
+ !senderOrigin ||
2253
+ senderOrigin !== originOf(clipsBaseUrl) ||
2254
+ senderOrigin !== originOf(settings.clipsBaseUrl)
2255
+ ) {
2256
+ return { ok: false, error: "Auth message came from the wrong origin." };
2257
+ }
2258
+ if (typeof message.token !== "string" || !message.token.trim()) {
2259
+ return { ok: false, error: "Missing auth token." };
2260
+ }
2261
+ await storageSet({ ...settings, clipsBaseUrl });
2262
+ await saveAuthSession({
2263
+ token: message.token,
2264
+ email: typeof message.email === "string" ? message.email : undefined,
2265
+ clipsBaseUrl,
2266
+ savedAt: nowIso(),
2267
+ });
2268
+ return { ok: true };
2269
+ }
2270
+
2240
2271
  function summarize(snapshot: {
2241
2272
  endedAt: string;
2242
2273
  consoleLogs: ConsoleLog[];
@@ -2734,25 +2765,7 @@ async function handleExternalMessage(
2734
2765
  }
2735
2766
 
2736
2767
  if (message.type === "CLIPS_AUTH_SESSION") {
2737
- const settings = await readSettings();
2738
- const clipsBaseUrl = normalizeBaseUrl(
2739
- message.clipsBaseUrl ?? settings.clipsBaseUrl,
2740
- );
2741
- const senderOrigin = originOf(sender?.url);
2742
- if (!senderOrigin || senderOrigin !== originOf(clipsBaseUrl)) {
2743
- return { ok: false, error: "Auth message came from the wrong origin." };
2744
- }
2745
- if (typeof message.token !== "string" || !message.token.trim()) {
2746
- return { ok: false, error: "Missing auth token." };
2747
- }
2748
- await storageSet({ ...settings, clipsBaseUrl });
2749
- await saveAuthSession({
2750
- token: message.token,
2751
- email: typeof message.email === "string" ? message.email : undefined,
2752
- clipsBaseUrl,
2753
- savedAt: nowIso(),
2754
- });
2755
- return { ok: true };
2768
+ return handleAuthSession(message, sender?.url);
2756
2769
  }
2757
2770
 
2758
2771
  if (message.type === "CLIPS_CAPTURE_START") {
@@ -2858,6 +2871,13 @@ async function dispatchRuntimeMessage(
2858
2871
  ): Promise<unknown> {
2859
2872
  const type = (message as { type?: unknown }).type;
2860
2873
 
2874
+ if (type === "CLIPS_AUTH_SESSION") {
2875
+ return handleAuthSession(
2876
+ message as AuthSessionMessage,
2877
+ sender?.tab?.url ?? sender?.url,
2878
+ );
2879
+ }
2880
+
2861
2881
  if (type === "CLIPS_DIAGNOSTIC_INTERACTION") {
2862
2882
  const tabId = sender?.tab?.id;
2863
2883
  const sessionId =
@@ -141,6 +141,49 @@
141
141
  }
142
142
  sendDiagnosticNavigation(data.url);
143
143
  });
144
+
145
+ window.addEventListener("message", (event) => {
146
+ if (event.source !== window || event.origin !== window.location.origin) {
147
+ return;
148
+ }
149
+ const data = event.data as
150
+ | {
151
+ source?: unknown;
152
+ kind?: unknown;
153
+ token?: unknown;
154
+ email?: unknown;
155
+ clipsBaseUrl?: unknown;
156
+ }
157
+ | undefined;
158
+ if (
159
+ data?.source !== "clips-auth-bridge" ||
160
+ data.kind !== "session" ||
161
+ typeof data.token !== "string" ||
162
+ typeof data.clipsBaseUrl !== "string"
163
+ ) {
164
+ return;
165
+ }
166
+ chrome.runtime.sendMessage(
167
+ {
168
+ type: "CLIPS_AUTH_SESSION",
169
+ token: data.token,
170
+ ...(typeof data.email === "string" ? { email: data.email } : {}),
171
+ clipsBaseUrl: data.clipsBaseUrl,
172
+ },
173
+ (response?: { ok?: boolean; error?: string }) => {
174
+ void chrome.runtime.lastError;
175
+ window.postMessage(
176
+ {
177
+ source: "clips-auth-bridge",
178
+ kind: "session-result",
179
+ ok: response?.ok === true,
180
+ ...(response?.error ? { error: response.error } : {}),
181
+ },
182
+ window.location.origin,
183
+ );
184
+ },
185
+ );
186
+ });
144
187
  window.postMessage(
145
188
  { source: "clips-diagnostic-history", kind: "request-token" },
146
189
  "*",
@@ -43,6 +43,8 @@ mod util;
43
43
  mod whisper_model;
44
44
  mod whisper_speech;
45
45
 
46
+ use std::time::Duration;
47
+
46
48
  use tauri::{Emitter, Manager};
47
49
 
48
50
  use clips::{position_popover, toggle_popover};
@@ -62,6 +64,12 @@ use util::{
62
64
  // should replace with their real icon.
63
65
  pub(crate) const TRAY_PNG: &[u8] = include_bytes!("../icons/tray.png");
64
66
 
67
+ const POPOVER_BLUR_GUARD: Duration = Duration::from_millis(1500);
68
+
69
+ fn popover_blur_delay(elapsed: Duration) -> Option<Duration> {
70
+ (elapsed < POPOVER_BLUR_GUARD).then(|| POPOVER_BLUR_GUARD - elapsed)
71
+ }
72
+
65
73
  fn present_popover(app: &tauri::AppHandle) {
66
74
  if let Some(window) = app.get_webview_window("popover") {
67
75
  set_capture_excluded(&window);
@@ -480,7 +488,7 @@ pub fn run() {
480
488
  }
481
489
 
482
490
  // Hide the popover on blur so it feels like a real menu-bar popover.
483
- // The 250ms guard is the important bit — during the tray-click
491
+ // The 1.5s guard is the important bit — during the tray-click
484
492
  // itself macOS briefly steals focus from the popover, which would
485
493
  // fire Focused(false) and hide the window we literally just showed.
486
494
  if let Some(window) = app.get_webview_window("popover") {
@@ -511,11 +519,37 @@ pub fn run() {
511
519
  let shown_at = app_handle
512
520
  .try_state::<PopoverShownAt>()
513
521
  .and_then(|s| s.0.lock().ok().and_then(|g| *g));
514
- let elapsed_ms = shown_at
515
- .map(|t| t.elapsed().as_millis())
516
- .unwrap_or(u128::MAX);
517
- dlog!("[clips-tray] popover blur, elapsed_ms={}", elapsed_ms);
518
- if elapsed_ms >= 1500 {
522
+ let elapsed = shown_at.map(|t| t.elapsed()).unwrap_or(Duration::MAX);
523
+ dlog!(
524
+ "[clips-tray] popover blur, elapsed_ms={}",
525
+ elapsed.as_millis()
526
+ );
527
+ if let Some(delay) = popover_blur_delay(elapsed) {
528
+ let Some(shown_at) = shown_at else {
529
+ return;
530
+ };
531
+ let delayed_handle = handle.clone();
532
+ let delayed_app_handle = app_handle.clone();
533
+ tauri::async_runtime::spawn(async move {
534
+ tokio::time::sleep(delay).await;
535
+ let still_current = delayed_app_handle
536
+ .try_state::<PopoverShownAt>()
537
+ .and_then(|state| {
538
+ state.0.lock().ok().map(|guard| *guard == Some(shown_at))
539
+ })
540
+ .unwrap_or(false);
541
+ if !still_current
542
+ || is_recording_active(&delayed_app_handle)
543
+ || !config::auto_hide_popover_enabled(&delayed_app_handle)
544
+ || delayed_handle.is_focused().unwrap_or(true)
545
+ {
546
+ return;
547
+ }
548
+ let _ = delayed_handle.hide();
549
+ clips::close_bubble_if_idle(&delayed_app_handle);
550
+ let _ = delayed_app_handle.emit("clips:popover-visible", false);
551
+ });
552
+ } else {
519
553
  let _ = handle.hide();
520
554
  clips::close_bubble_if_idle(&app_handle);
521
555
  let _ = app_handle.emit("clips:popover-visible", false);
@@ -623,3 +657,18 @@ pub fn run() {
623
657
  }
624
658
  });
625
659
  }
660
+
661
+ #[cfg(test)]
662
+ mod tests {
663
+ use super::{popover_blur_delay, POPOVER_BLUR_GUARD};
664
+ use std::time::Duration;
665
+
666
+ #[test]
667
+ fn retries_blur_until_guard_expires() {
668
+ assert_eq!(
669
+ popover_blur_delay(Duration::from_millis(400)),
670
+ Some(Duration::from_millis(1100))
671
+ );
672
+ assert_eq!(popover_blur_delay(POPOVER_BLUR_GUARD), None);
673
+ }
674
+ }
@@ -1447,19 +1447,24 @@ export const editorChromeBridgeScript: string = `"use strict";
1447
1447
  "__reactInternalFiber$"
1448
1448
  ];
1449
1449
  function reactFiberOf(el) {
1450
- var keys = Object.keys(el);
1450
+ var keys = Object.getOwnPropertyNames(el);
1451
+ var fallback = null;
1451
1452
  for (var i = 0; i < keys.length; i += 1) {
1452
1453
  for (var j = 0; j < REACT_FIBER_KEY_PREFIXES.length; j += 1) {
1453
1454
  if (keys[i].indexOf(REACT_FIBER_KEY_PREFIXES[j]) === 0) {
1454
- return el[keys[i]];
1455
+ var fiber = el[keys[i]];
1456
+ if (!fallback) fallback = fiber;
1457
+ if (fiber && fiber._debugSource) return fiber;
1455
1458
  }
1456
1459
  }
1457
1460
  }
1458
- return null;
1461
+ return fallback;
1459
1462
  }
1460
1463
  function reactDebugProvenance(el) {
1461
1464
  var cached = reactDebugProvenanceCache?.get(el);
1462
- if (cached !== void 0) return cached;
1465
+ if (cached !== void 0 && (cached.method === "debug-source" || cached.method === "debug-stack-remapped")) {
1466
+ return cached;
1467
+ }
1463
1468
  var leafFiber = reactFiberOf(el);
1464
1469
  if (!leafFiber) return { unavailableReason: "not-framework" };
1465
1470
  var elementLocation = fiberDebugLocation(leafFiber);
@@ -1935,10 +1940,8 @@ export const editorChromeBridgeScript: string = `"use strict";
1935
1940
  cloneNode.setAttribute("data-an-runtime-layer-remove", "true");
1936
1941
  continue;
1937
1942
  }
1938
- cloneNode.setAttribute(
1939
- "data-agent-native-node-id",
1940
- ensureRuntimeLayerNodeId(sourceNode)
1941
- );
1943
+ var runtimeNodeId = ensureRuntimeLayerNodeId(sourceNode);
1944
+ cloneNode.setAttribute("data-agent-native-node-id", runtimeNodeId);
1942
1945
  inlineSnapshotComputedStyle(sourceNode, cloneNode);
1943
1946
  var provenance = elementDebugProvenance(sourceNode);
1944
1947
  if (provenance.sourceFile) {
@@ -1959,6 +1962,25 @@ export const editorChromeBridgeScript: string = `"use strict";
1959
1962
  if (provenance.component) {
1960
1963
  cloneNode.setAttribute("data-component-name", provenance.component);
1961
1964
  }
1965
+ var runtimeComponent = runtimeComponentIdentityForElement(
1966
+ sourceNode,
1967
+ provenance,
1968
+ runtimeNodeId
1969
+ );
1970
+ if (runtimeComponent) {
1971
+ cloneNode.setAttribute(
1972
+ "data-agent-native-runtime-component-id",
1973
+ runtimeComponent.componentId
1974
+ );
1975
+ cloneNode.setAttribute(
1976
+ "data-agent-native-runtime-instance-id",
1977
+ runtimeComponent.instanceId
1978
+ );
1979
+ cloneNode.setAttribute(
1980
+ "data-agent-native-runtime-component-capability",
1981
+ runtimeComponent.writeCapability
1982
+ );
1983
+ }
1962
1984
  if (provenance.ownerSourceFile) {
1963
1985
  cloneNode.setAttribute(
1964
1986
  "data-source-owner-file",
@@ -2505,6 +2527,57 @@ export const editorChromeBridgeScript: string = `"use strict";
2505
2527
  if (!elementLooksLikeComponent(el) || !el || !el.getAttribute) return "";
2506
2528
  return layerNameForElement(el);
2507
2529
  }
2530
+ function runtimeComponentPropsForElement(el) {
2531
+ var props = [];
2532
+ if (!el.attributes) return props;
2533
+ for (var index = 0; index < el.attributes.length; index += 1) {
2534
+ var attribute = el.attributes[index];
2535
+ if (!attribute || attribute.name.indexOf("data-agent-native-prop-") !== 0)
2536
+ continue;
2537
+ var rawName = attribute.name.slice("data-agent-native-prop-".length);
2538
+ if (!rawName) continue;
2539
+ props.push({
2540
+ name: rawName.replace(/-([a-z])/g, function(_match, letter) {
2541
+ return String(letter).toUpperCase();
2542
+ }),
2543
+ value: attribute.value
2544
+ });
2545
+ }
2546
+ return props;
2547
+ }
2548
+ function runtimeComponentIdentityForElement(el, provenance, instanceId) {
2549
+ var name = provenance.component && provenance.component.trim();
2550
+ var definitionSourceFile = provenance.sourceFile && provenance.sourceFile.trim();
2551
+ var invocationSourceFile = provenance.ownerSourceFile && provenance.ownerSourceFile.trim();
2552
+ var invocationLine = provenance.ownerLine;
2553
+ var invocationColumn = provenance.ownerColumn;
2554
+ var invocationMethod = provenance.ownerMethod;
2555
+ if (!name || !definitionSourceFile || !provenance.framework || provenance.framework === "html" || !instanceId) {
2556
+ return void 0;
2557
+ }
2558
+ var boundary = [
2559
+ provenance.framework,
2560
+ definitionSourceFile,
2561
+ provenance.line || "",
2562
+ provenance.column || "",
2563
+ name
2564
+ ].join("|");
2565
+ var writable = provenance.framework === "react" && invocationSourceFile !== void 0 && invocationMethod !== void 0 && invocationMethod !== "debug-stack" && Number.isFinite(invocationLine) && Number.isFinite(invocationColumn);
2566
+ return {
2567
+ componentId: "runtime-component-" + runtimeLayerHash(boundary),
2568
+ instanceId,
2569
+ name,
2570
+ framework: provenance.framework,
2571
+ sourceFile: invocationSourceFile,
2572
+ line: invocationLine,
2573
+ column: invocationColumn,
2574
+ method: invocationMethod,
2575
+ ownerKey: provenance.ownerKey,
2576
+ props: runtimeComponentPropsForElement(el),
2577
+ writeCapability: writable ? "authored-jsx-literal" : "unsupported",
2578
+ reason: writable ? void 0 : "The runtime did not expose a verified authored component invocation location."
2579
+ };
2580
+ }
2508
2581
  function isAutoLayoutDisplay(display) {
2509
2582
  return display === "flex" || display === "inline-flex" || display === "grid" || display === "inline-grid";
2510
2583
  }
@@ -3320,6 +3393,7 @@ export const editorChromeBridgeScript: string = `"use strict";
3320
3393
  alignItems: parentStyles.alignItems,
3321
3394
  justifyContent: parentStyles.justifyContent,
3322
3395
  gap: parentStyles.gap,
3396
+ gridAutoFlow: parentStyles.gridAutoFlow,
3323
3397
  gridTemplateColumns: parentStyles.gridTemplateColumns,
3324
3398
  gridTemplateRows: parentStyles.gridTemplateRows,
3325
3399
  position: parentStyles.position
@@ -3356,10 +3430,17 @@ export const editorChromeBridgeScript: string = `"use strict";
3356
3430
  });
3357
3431
  }
3358
3432
  var provenance = elementDebugProvenance(el);
3433
+ var runtimeComponent = runtimeComponentIdentityForElement(
3434
+ el,
3435
+ provenance,
3436
+ sourceId || runtimeSourceId || pendingNodeId || getSelector(el)
3437
+ );
3359
3438
  var portableStyleSnapshot = collectPortableStyleSnapshot(el);
3360
3439
  return {
3361
3440
  tagName: el.tagName.toLowerCase(),
3362
3441
  componentName: componentName || void 0,
3442
+ componentAnnotation: explicitComponentNameForElement(el) || void 0,
3443
+ runtimeComponent,
3363
3444
  id: el.id || void 0,
3364
3445
  sourceId,
3365
3446
  runtimeSelector: runtimeSelector || void 0,
@@ -11336,8 +11417,8 @@ export const editorChromeBridgeScript: string = `"use strict";
11336
11417
  var gestureState = memberStates[groupEls.indexOf(gestureEl)] || memberStates[0];
11337
11418
  var originLeft = gestureState.originLeft;
11338
11419
  var originTop = gestureState.originTop;
11339
- var startX = e.clientX;
11340
- var startY = e.clientY;
11420
+ var startX = pointerStartParam ? pointerStartParam.clientX : e.clientX;
11421
+ var startY = pointerStartParam ? pointerStartParam.clientY : e.clientY;
11341
11422
  var dragEl = gestureEl;
11342
11423
  var gestureViewport = bridgeGestureViewport();
11343
11424
  var DRAG_THRESHOLD = 3;
@@ -11366,11 +11447,13 @@ export const editorChromeBridgeScript: string = `"use strict";
11366
11447
  bridgeMoveController.pointerDown({
11367
11448
  kind: "move",
11368
11449
  objectIds: [getSelector(gestureEl)],
11369
- // \`e\` is deliberately the event that actually began the legacy move
11370
- // lifecycle, not \`pointerStartParam\`: anchoring the controller at the
11371
- // pointerdown moves the element the extra threshold-crossing distance,
11372
- // which breaks the cross-screen drop's target resolution.
11373
- pointer: bridgeGesturePointer(e),
11450
+ // Shield drags begin here after their threshold-crossing event. For an
11451
+ // alt-drag, the clone must include the movement from the original press;
11452
+ // plain shield drags keep their existing threshold-relative baseline so
11453
+ // cross-screen target resolution is unchanged.
11454
+ pointer: bridgeGesturePointer(
11455
+ duplicatedForDrag && pointerStartParam ? { ...e, ...pointerStartParam } : e
11456
+ ),
11374
11457
  viewport: gestureViewport,
11375
11458
  canvas: { width: gestureViewport.width, height: gestureViewport.height }
11376
11459
  });
@@ -11394,7 +11477,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11394
11477
  var dragElOffsetScaleX = ancestorScale(dragEl, "x");
11395
11478
  var dragElOffsetScaleY = ancestorScale(dragEl, "y");
11396
11479
  if (!isGroupDrag) {
11397
- postCrossScreenDrag("start", dragEl, e, {
11480
+ postCrossScreenDrag("start", dragEl, pointerStartParam || e, {
11398
11481
  duplicate: duplicatedForDrag
11399
11482
  });
11400
11483
  }
@@ -11474,7 +11557,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11474
11557
  currentAutoLayoutTarget = null;
11475
11558
  hideInsertionGuide();
11476
11559
  } else {
11477
- currentAutoLayoutTarget = !duplicatedForDrag && !bridgeSpaceKeyPressed ? autoLayoutInsertionTargetForPoint(
11560
+ currentAutoLayoutTarget = !bridgeSpaceKeyPressed ? autoLayoutInsertionTargetForPoint(
11478
11561
  dragEl,
11479
11562
  ev.clientX,
11480
11563
  ev.clientY,
@@ -11574,6 +11657,8 @@ export const editorChromeBridgeScript: string = `"use strict";
11574
11657
  positionOverlay(selectionOverlay, selectedEl);
11575
11658
  postElementSelect(selectedEl);
11576
11659
  postCrossScreenDrag("cancel");
11660
+ } else if (!isGroupDrag) {
11661
+ postCrossScreenDrag("cancel");
11577
11662
  }
11578
11663
  return;
11579
11664
  }
@@ -11601,7 +11686,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11601
11686
  }
11602
11687
  return;
11603
11688
  }
11604
- if (ev && !duplicatedForDrag && !outsideOnDrop && !bridgeSpaceKeyPressed) {
11689
+ if (ev && !outsideOnDrop && !bridgeSpaceKeyPressed) {
11605
11690
  var finalAutoLayoutTarget = autoLayoutInsertionTargetForPoint(
11606
11691
  dragEl,
11607
11692
  ev.clientX,
@@ -11631,7 +11716,7 @@ export const editorChromeBridgeScript: string = `"use strict";
11631
11716
  postVisualDuplicateChange(
11632
11717
  originalSelectedEl,
11633
11718
  dragEl,
11634
- null,
11719
+ currentAutoLayoutTarget,
11635
11720
  duplicatedSourceNodeIdMap
11636
11721
  );
11637
11722
  postCrossScreenDrag("cancel");
@@ -14968,6 +15053,9 @@ export const editorChromeBridgeScript: string = `"use strict";
14968
15053
  "aria-label",
14969
15054
  "class",
14970
15055
  "data-agent-native-component",
15056
+ "data-agent-native-runtime-component-capability",
15057
+ "data-agent-native-runtime-component-id",
15058
+ "data-agent-native-runtime-instance-id",
14971
15059
  "data-agent-native-layer-name",
14972
15060
  "data-layer-name",
14973
15061
  "layer-name",
@@ -326,6 +326,7 @@ export const hitTestBridgeScript: string = `"use strict";
326
326
  }
327
327
  function getOrMintPendingNodeId(el) {
328
328
  if (!el || !el.getAttribute || !el.setAttribute) return "";
329
+ if (el === document.body || el === document.documentElement) return "";
329
330
  if (isTemplateCloneElement(el)) return "";
330
331
  var existing = el.getAttribute("data-an-pending-node-id");
331
332
  if (existing) return existing;