@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.
- package/corpus/README.md +1 -1
- package/corpus/templates/clips/app/root.tsx +59 -10
- package/corpus/templates/clips/changelog/2026-09-17-desktop-popover-closes-when-clicking-away.md +6 -0
- package/corpus/templates/clips/changelog/2026-09-17-self-hosted-extension-sign-in.md +6 -0
- package/corpus/templates/clips/chrome-extension/src/background.ts +45 -25
- package/corpus/templates/clips/chrome-extension/src/content-script.ts +43 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +55 -6
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +107 -19
- package/corpus/templates/design/.generated/bridge/hit-test.generated.ts +1 -0
- package/corpus/templates/design/actions/add-localhost-screens.ts +54 -22
- package/corpus/templates/design/actions/apply-component-prop-edit.ts +174 -14
- package/corpus/templates/design/actions/apply-visual-edit.ts +3 -1
- package/corpus/templates/design/actions/create-component.ts +173 -12
- package/corpus/templates/design/actions/create-design-from-template.ts +50 -35
- package/corpus/templates/design/actions/create-design-version.ts +21 -0
- package/corpus/templates/design/actions/create-file.ts +35 -33
- package/corpus/templates/design/actions/delete-design.ts +29 -28
- package/corpus/templates/design/actions/delete-file.ts +154 -23
- package/corpus/templates/design/actions/generate-design.ts +28 -16
- package/corpus/templates/design/actions/get-component-details.ts +272 -33
- package/corpus/templates/design/actions/get-design-version.ts +9 -1
- package/corpus/templates/design/actions/go-to-main-component.ts +37 -35
- package/corpus/templates/design/actions/index-components.ts +241 -126
- package/corpus/templates/design/actions/migrate-board-objects-to-file.ts +12 -9
- package/corpus/templates/design/actions/present-design-variants.ts +68 -72
- package/corpus/templates/design/actions/rename-component.ts +294 -0
- package/corpus/templates/design/actions/rename-screen.ts +10 -10
- package/corpus/templates/design/actions/update-file.ts +327 -330
- package/corpus/templates/design/actions/update-screen-source.ts +2 -43
- package/corpus/templates/design/app/components/design/EditPanel.tsx +17 -1
- package/corpus/templates/design/app/components/design/MultiScreenCanvas.tsx +228 -24
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +17 -1
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +151 -32
- package/corpus/templates/design/app/components/design/bridge/hit-test.bridge.ts +4 -0
- package/corpus/templates/design/app/components/design/canvas-primitive-style.ts +1 -1
- package/corpus/templates/design/app/components/design/code-workbench/CodeWorkbench.tsx +8 -1
- package/corpus/templates/design/app/components/design/code-workbench/explorer/FileTree.tsx +55 -33
- package/corpus/templates/design/app/components/design/code-workbench/workspace/create-providers.ts +2 -0
- package/corpus/templates/design/app/components/design/code-workbench/workspace/inline-provider.ts +4 -2
- package/corpus/templates/design/app/components/design/edit-panel/component-section.tsx +273 -60
- package/corpus/templates/design/app/components/design/edit-panel/element-classification.ts +9 -2
- package/corpus/templates/design/app/components/design/inspector/AutoLayoutMatrix.tsx +57 -9
- package/corpus/templates/design/app/components/design/multi-screen/primitive-drop-target.ts +13 -0
- package/corpus/templates/design/app/components/design/multi-screen/types.ts +14 -0
- package/corpus/templates/design/app/components/design/types.ts +9 -1
- package/corpus/templates/design/app/hooks/use-design-versions.ts +3 -2
- package/corpus/templates/design/app/i18n-breakpoints.ts +0 -110
- package/corpus/templates/design/app/i18n-data.ts +0 -10
- package/corpus/templates/design/app/pages/DesignEditor.tsx +669 -161
- package/corpus/templates/design/app/pages/design-editor/clone-and-pen-edit.ts +20 -0
- package/corpus/templates/design/app/pages/design-editor/code-layer-state.ts +2 -0
- package/corpus/templates/design/app/pages/design-editor/commands/apply-design-editor-command.ts +21 -3
- package/corpus/templates/design/app/pages/design-editor/commands/apply-file-content-update.ts +2 -0
- package/corpus/templates/design/app/pages/design-editor/commands/create-component.ts +44 -3
- package/corpus/templates/design/app/pages/design-editor/commands/delete-files.ts +69 -47
- package/corpus/templates/design/app/pages/design-editor/commands/duplicate-screen.ts +157 -52
- package/corpus/templates/design/app/pages/design-editor/commands/duplicate-selection.ts +76 -1
- package/corpus/templates/design/app/pages/design-editor/commands/redo.ts +152 -44
- package/corpus/templates/design/app/pages/design-editor/commands/save-file-content.ts +131 -2
- package/corpus/templates/design/app/pages/design-editor/commands/screen-visual-duplicate-change.ts +5 -1
- package/corpus/templates/design/app/pages/design-editor/commands/undo.ts +26 -1
- package/corpus/templates/design/app/pages/design-editor/commands/visual-duplicate-change.ts +1 -0
- package/corpus/templates/design/app/pages/design-editor/editor-helpers.ts +58 -8
- package/corpus/templates/design/app/pages/design-editor/editor-state.ts +63 -2
- package/corpus/templates/design/app/pages/design-editor/history.ts +3 -0
- package/corpus/templates/design/app/pages/design-editor/nudge-intent.ts +74 -22
- package/corpus/templates/design/app/pages/design-editor/source-publication.ts +14 -2
- package/corpus/templates/design/changelog/2026-09-16-design-components-retain-linked-identities-when-edited-and-d.md +6 -0
- package/corpus/templates/design/changelog/2026-09-16-fix-design-nested-layer-dragging-and-screen-duplication-pari.md +6 -0
- package/corpus/templates/design/changelog/2026-09-17-design-drag-and-drop-keeps-duplicates-cross-screen-moves-and.md +6 -0
- package/corpus/templates/design/changelog/2026-09-17-design-preserves-reusable-component-identity-and-props-acros.md +6 -0
- package/corpus/templates/design/changelog/2026-09-17-open-vector-paths-no-longer-show-fills-and-interact-dimensio.md +6 -0
- package/corpus/templates/design/changelog/2026-09-17-screen-deletion-is-immediate-and-undoable-with-history-that-.md +6 -0
- package/corpus/templates/design/e2e/fixtures/design-component-react/index.html +98 -0
- package/corpus/templates/design/e2e/fixtures/design-component-react/inline-component.html +65 -0
- package/corpus/templates/design/e2e/helpers.ts +6 -1
- package/corpus/templates/design/server/lib/design-data-mutation.ts +9 -5
- package/corpus/templates/design/server/lib/design-snapshot.ts +28 -16
- package/corpus/templates/design/server/lib/design-versions.ts +208 -130
- package/corpus/templates/design/server/lib/fusion-screens.ts +46 -20
- package/corpus/templates/design/server/lib/import-design-files.ts +5 -1
- package/corpus/templates/design/server/lib/localhost-connection.ts +54 -0
- package/corpus/templates/design/server/source-workspace.ts +412 -356
- package/corpus/templates/design/shared/component-library.ts +36 -6
- package/corpus/templates/design/shared/component-model.ts +12 -2
- package/corpus/templates/design/shared/local-jsx-visual-edit.ts +231 -5
- package/corpus/templates/design/shared/source-mode.ts +22 -0
- package/dist/automation/index.d.ts +1 -1
- package/dist/client/AssistantChat.d.ts +4 -1
- package/dist/client/AssistantChat.js +26 -3
- package/dist/client/chat/agentkit-protocol.js +148 -34
- package/dist/client/chat/message-components.js +7 -5
- package/dist/client/chat/tool-call-display.js +4 -3
- package/dist/client/conversation/AgentConversation.js +4 -2
- package/dist/client/tool-display.d.ts +9 -0
- package/dist/client/tool-display.js +15 -0
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/localization/core-messages/ar-SA.js +2 -0
- package/dist/localization/core-messages/de-DE.js +2 -0
- package/dist/localization/core-messages/en-US.d.ts +2 -0
- package/dist/localization/core-messages/en-US.js +2 -0
- package/dist/localization/core-messages/es-ES.js +2 -0
- package/dist/localization/core-messages/fr-FR.js +2 -0
- package/dist/localization/core-messages/hi-IN.js +2 -0
- package/dist/localization/core-messages/ja-JP.js +2 -0
- package/dist/localization/core-messages/ko-KR.js +2 -0
- package/dist/localization/core-messages/pt-BR.js +2 -0
- package/dist/localization/core-messages/zh-CN.js +2 -0
- package/dist/localization/core-messages/zh-TW.js +2 -0
- package/dist/localization/core-messages.d.ts +2 -0
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +3 -3
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +3 -3
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/core-routes-plugin.d.ts +1 -1
- package/package.json +3 -3
- package/corpus/templates/design/app/components/design/editor/PendingScreenDeletionDialog.tsx +0 -66
package/corpus/README.md
CHANGED
|
@@ -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:
|
|
241
|
-
email:
|
|
242
|
-
clipsBaseUrl:
|
|
288
|
+
token: message.token,
|
|
289
|
+
email: message.email,
|
|
290
|
+
clipsBaseUrl: message.clipsBaseUrl,
|
|
243
291
|
},
|
|
244
292
|
(extensionResponse) => {
|
|
245
|
-
if (cancelled
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
|
|
@@ -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
|
-
|
|
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
|
|
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
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
|
1461
|
+
return fallback;
|
|
1459
1462
|
}
|
|
1460
1463
|
function reactDebugProvenance(el) {
|
|
1461
1464
|
var cached = reactDebugProvenanceCache?.get(el);
|
|
1462
|
-
if (cached !== void 0
|
|
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
|
-
|
|
1939
|
-
|
|
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
|
-
//
|
|
11370
|
-
//
|
|
11371
|
-
//
|
|
11372
|
-
//
|
|
11373
|
-
pointer: bridgeGesturePointer(
|
|
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 = !
|
|
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 && !
|
|
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
|
-
|
|
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;
|