@agent-native/core 0.0.0-beta-20260820190051 → 0.0.0-beta-20260820194548
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/assets/actions/navigate.ts +2 -2
- package/corpus/templates/brain/actions/navigate.ts +2 -2
- package/corpus/templates/chat/actions/navigate.ts +2 -2
- package/corpus/templates/clips/CHANGELOG.md +1 -0
- package/corpus/templates/clips/actions/import-loom-recording.ts +16 -4
- package/corpus/templates/clips/actions/navigate.ts +2 -2
- package/corpus/templates/clips/app/components/player/clips-share-trigger.tsx +17 -0
- package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +3 -3
- package/corpus/templates/clips/app/global.css +4 -0
- package/corpus/templates/clips/app/lib/download-release-channel.ts +10 -0
- package/corpus/templates/clips/app/routes/download.tsx +67 -44
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +6 -11
- package/corpus/templates/clips/app/routes/record.tsx +5 -5
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +22 -25
- package/corpus/templates/clips/changelog/2026-08-20-clip-viewer-share-actions.md +6 -0
- package/corpus/templates/clips/changelog/2026-08-20-preparing-recording-countdown-overlay.md +1 -0
- package/corpus/templates/content/actions/navigate.ts +2 -2
- package/corpus/templates/design/AGENTS.md +2 -1
- package/corpus/templates/design/actions/generate-screens.ts +5 -2
- package/corpus/templates/design/actions/go-to-main-component.ts +2 -2
- package/corpus/templates/design/actions/navigate.ts +2 -2
- package/corpus/templates/design/actions/open-component-source.ts +4 -4
- package/corpus/templates/design/actions/present-design-variants.ts +1 -2
- package/corpus/templates/design/actions/show-design-questions.ts +5 -2
- package/corpus/templates/design/app/i18n-data.ts +122 -0
- package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +163 -6
- package/corpus/templates/factory/actions/navigate.ts +2 -2
- package/dist/agent/engine/registry.js +27 -14
- package/dist/collab/routes.d.ts +1 -1
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +3 -3
- package/dist/observability/routes.d.ts +6 -6
- package/dist/resources/handlers.d.ts +2 -2
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/dist/server/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +1 -1
- package/dist/templates/chat/actions/navigate.ts +2 -2
- package/package.json +1 -1
- package/src/templates/chat/actions/navigate.ts +2 -2
package/corpus/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
2
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
export default defineAction({
|
|
@@ -43,7 +43,7 @@ export default defineAction({
|
|
|
43
43
|
if (!args.view && !args.path) {
|
|
44
44
|
throw new Error("view or path is required.");
|
|
45
45
|
}
|
|
46
|
-
await
|
|
46
|
+
await writeAppStateForCurrentTab("navigate", args);
|
|
47
47
|
return { navigating: true, ...args };
|
|
48
48
|
},
|
|
49
49
|
});
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
2
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
|
|
5
5
|
export default defineAction({
|
|
@@ -37,7 +37,7 @@ export default defineAction({
|
|
|
37
37
|
}),
|
|
38
38
|
http: false,
|
|
39
39
|
run: async (args) => {
|
|
40
|
-
await
|
|
40
|
+
await writeAppStateForCurrentTab("navigate", { ...args, ts: Date.now() });
|
|
41
41
|
return { navigate: args };
|
|
42
42
|
},
|
|
43
43
|
});
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
import { defineAction } from "@agent-native/core/action";
|
|
17
|
-
import {
|
|
17
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
18
18
|
import { z } from "zod";
|
|
19
19
|
|
|
20
20
|
export default defineAction({
|
|
@@ -35,7 +35,7 @@ export default defineAction({
|
|
|
35
35
|
if (args.path) nav.path = args.path;
|
|
36
36
|
if (args.threadId) nav.threadId = args.threadId;
|
|
37
37
|
nav._writeId = `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
38
|
-
await
|
|
38
|
+
await writeAppStateForCurrentTab("navigate", nav);
|
|
39
39
|
return `Navigating to ${args.view || args.path}`;
|
|
40
40
|
},
|
|
41
41
|
});
|
|
@@ -7,6 +7,7 @@ from the command menu (Cmd+K → "What's new") or from Settings.
|
|
|
7
7
|
|
|
8
8
|
### Improved
|
|
9
9
|
|
|
10
|
+
- Clip viewers now make Share the primary action and keep the overflow control compact and vertical.
|
|
10
11
|
- Recording controls now follow you across browser tabs and page navigations.
|
|
11
12
|
|
|
12
13
|
### Fixed
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
writeAppState,
|
|
4
|
+
writeAppStateForCurrentTab,
|
|
5
|
+
} from "@agent-native/core/application-state";
|
|
3
6
|
import { ssrfSafeFetch } from "@agent-native/core/extensions/url-safety";
|
|
4
7
|
import { uploadFile } from "@agent-native/core/file-upload";
|
|
5
8
|
import { buildDeepLink } from "@agent-native/core/server";
|
|
@@ -315,7 +318,10 @@ export default defineAction({
|
|
|
315
318
|
updatedAt: now,
|
|
316
319
|
});
|
|
317
320
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
318
|
-
await
|
|
321
|
+
await writeAppStateForCurrentTab("navigate", {
|
|
322
|
+
view: "recording",
|
|
323
|
+
recordingId: id,
|
|
324
|
+
});
|
|
319
325
|
|
|
320
326
|
return {
|
|
321
327
|
recordingId: id,
|
|
@@ -386,7 +392,10 @@ export default defineAction({
|
|
|
386
392
|
updatedAt: now,
|
|
387
393
|
});
|
|
388
394
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
389
|
-
await
|
|
395
|
+
await writeAppStateForCurrentTab("navigate", {
|
|
396
|
+
view: "recording",
|
|
397
|
+
recordingId: id,
|
|
398
|
+
});
|
|
390
399
|
|
|
391
400
|
try {
|
|
392
401
|
console.log("[import-loom-recording] dispatching loom-import job", {
|
|
@@ -540,7 +549,10 @@ export default defineAction({
|
|
|
540
549
|
updatedAt: now,
|
|
541
550
|
});
|
|
542
551
|
await writeAppState("refresh-signal", { ts: Date.now() });
|
|
543
|
-
await
|
|
552
|
+
await writeAppStateForCurrentTab("navigate", {
|
|
553
|
+
view: "recording",
|
|
554
|
+
recordingId: id,
|
|
555
|
+
});
|
|
544
556
|
|
|
545
557
|
return {
|
|
546
558
|
recordingId: id,
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
18
|
import { defineAction } from "@agent-native/core";
|
|
19
|
-
import {
|
|
19
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
20
20
|
import { z } from "zod";
|
|
21
21
|
|
|
22
22
|
const Views = [
|
|
@@ -91,7 +91,7 @@ export default defineAction({
|
|
|
91
91
|
if (args.shareId) nav.shareId = args.shareId;
|
|
92
92
|
if (args.search) nav.search = args.search;
|
|
93
93
|
if (args.path) nav.path = args.path;
|
|
94
|
-
await
|
|
94
|
+
await writeAppStateForCurrentTab("navigate", nav);
|
|
95
95
|
const target =
|
|
96
96
|
args.path ||
|
|
97
97
|
[
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ShareTrigger,
|
|
3
|
+
type ShareTriggerProps,
|
|
4
|
+
} from "@agent-native/toolkit/sharing";
|
|
5
|
+
|
|
6
|
+
import { cn } from "@/lib/utils";
|
|
7
|
+
|
|
8
|
+
export function ClipsShareTrigger({ className, ...props }: ShareTriggerProps) {
|
|
9
|
+
return (
|
|
10
|
+
<ShareTrigger
|
|
11
|
+
{...props}
|
|
12
|
+
intent="primary"
|
|
13
|
+
emphasis="solid"
|
|
14
|
+
className={cn("clips-share-trigger shrink-0", className)}
|
|
15
|
+
/>
|
|
16
|
+
);
|
|
17
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { useActionMutation } from "@agent-native/core/client/hooks";
|
|
2
2
|
import { useT } from "@agent-native/core/client/i18n";
|
|
3
|
-
import {
|
|
3
|
+
import { IconDotsVertical, IconDownload, IconTrash } from "@tabler/icons-react";
|
|
4
4
|
import { useCallback, useRef, useState } from "react";
|
|
5
5
|
import { toast } from "sonner";
|
|
6
6
|
|
|
@@ -93,10 +93,10 @@ export function RecordingOptionsMenu({
|
|
|
93
93
|
<Button
|
|
94
94
|
variant="ghost"
|
|
95
95
|
size="icon"
|
|
96
|
-
className="shrink-0"
|
|
96
|
+
className="-mx-1.5 h-auto w-auto shrink-0 px-0.5 py-1.5"
|
|
97
97
|
aria-label={t("deleteRecordingMenu.clipOptions")}
|
|
98
98
|
>
|
|
99
|
-
<
|
|
99
|
+
<IconDotsVertical className="h-4 w-4" />
|
|
100
100
|
</Button>
|
|
101
101
|
</DropdownMenuTrigger>
|
|
102
102
|
<DropdownMenuContent align="end" className="w-44">
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type DownloadReleaseChannel = "production" | "nightly";
|
|
2
|
+
|
|
3
|
+
export const BETA_CLIPS_HOSTNAME = "beta.clips.agent-native.com";
|
|
4
|
+
|
|
5
|
+
export function getDefaultDownloadChannel(
|
|
6
|
+
hostname: string | undefined,
|
|
7
|
+
): DownloadReleaseChannel {
|
|
8
|
+
const normalized = hostname?.trim().toLowerCase().replace(/\.$/, "");
|
|
9
|
+
return normalized === BETA_CLIPS_HOSTNAME ? "nightly" : "production";
|
|
10
|
+
}
|
|
@@ -4,12 +4,20 @@ import {
|
|
|
4
4
|
IconBrandChrome,
|
|
5
5
|
IconBrandApple,
|
|
6
6
|
IconBrandWindows,
|
|
7
|
+
IconChevronDown,
|
|
7
8
|
IconDeviceDesktop,
|
|
8
9
|
IconExternalLink,
|
|
9
10
|
} from "@tabler/icons-react";
|
|
10
11
|
import { useEffect, useState } from "react";
|
|
11
12
|
|
|
12
13
|
import { Button } from "@/components/ui/button";
|
|
14
|
+
import {
|
|
15
|
+
DropdownMenu,
|
|
16
|
+
DropdownMenuContent,
|
|
17
|
+
DropdownMenuRadioGroup,
|
|
18
|
+
DropdownMenuRadioItem,
|
|
19
|
+
DropdownMenuTrigger,
|
|
20
|
+
} from "@/components/ui/dropdown-menu";
|
|
13
21
|
import { Skeleton } from "@/components/ui/skeleton";
|
|
14
22
|
import enMessages from "@/i18n/en-US";
|
|
15
23
|
import {
|
|
@@ -17,6 +25,10 @@ import {
|
|
|
17
25
|
markDesktopAppDownloaded,
|
|
18
26
|
useClipsChromeExtensionEnabled,
|
|
19
27
|
} from "@/lib/capture-install-options";
|
|
28
|
+
import {
|
|
29
|
+
getDefaultDownloadChannel,
|
|
30
|
+
type DownloadReleaseChannel,
|
|
31
|
+
} from "@/lib/download-release-channel";
|
|
20
32
|
|
|
21
33
|
export function meta() {
|
|
22
34
|
return [
|
|
@@ -29,7 +41,6 @@ export function meta() {
|
|
|
29
41
|
}
|
|
30
42
|
|
|
31
43
|
type PlatformId = "mac" | "windows" | "linux";
|
|
32
|
-
type ReleaseChannel = "production" | "nightly";
|
|
33
44
|
|
|
34
45
|
interface PlatformVariant {
|
|
35
46
|
id: PlatformId;
|
|
@@ -204,7 +215,8 @@ function secondaryDownloadButton(
|
|
|
204
215
|
export default function DownloadPage() {
|
|
205
216
|
const chromeExtensionEnabled = useClipsChromeExtensionEnabled();
|
|
206
217
|
const t = useT();
|
|
207
|
-
const [channel, setChannel] = useState<
|
|
218
|
+
const [channel, setChannel] = useState<DownloadReleaseChannel>("production");
|
|
219
|
+
const [hostResolved, setHostResolved] = useState(false);
|
|
208
220
|
const [manifest, setManifest] = useState<Manifest | null>(null);
|
|
209
221
|
const [manifestError, setManifestError] = useState(false);
|
|
210
222
|
const [detected, setDetected] = useState<PlatformId | null>(null);
|
|
@@ -215,6 +227,13 @@ export default function DownloadPage() {
|
|
|
215
227
|
}, []);
|
|
216
228
|
|
|
217
229
|
useEffect(() => {
|
|
230
|
+
setChannel(getDefaultDownloadChannel(window.location.hostname));
|
|
231
|
+
setHostResolved(true);
|
|
232
|
+
}, []);
|
|
233
|
+
|
|
234
|
+
useEffect(() => {
|
|
235
|
+
if (!hostResolved) return;
|
|
236
|
+
|
|
218
237
|
let cancelled = false;
|
|
219
238
|
setManifest(null);
|
|
220
239
|
setManifestError(false);
|
|
@@ -233,13 +252,15 @@ export default function DownloadPage() {
|
|
|
233
252
|
return () => {
|
|
234
253
|
cancelled = true;
|
|
235
254
|
};
|
|
236
|
-
}, [channel, manifestRequest]);
|
|
255
|
+
}, [channel, hostResolved, manifestRequest]);
|
|
237
256
|
|
|
238
257
|
const retryManifest = () => {
|
|
239
258
|
setManifestRequest((request) => request + 1);
|
|
240
259
|
};
|
|
241
260
|
|
|
242
|
-
const handleChannelChange = (nextChannel:
|
|
261
|
+
const handleChannelChange = (nextChannel: DownloadReleaseChannel) => {
|
|
262
|
+
if (nextChannel === channel) return;
|
|
263
|
+
|
|
243
264
|
setManifest(null);
|
|
244
265
|
setManifestError(false);
|
|
245
266
|
setChannel(nextChannel);
|
|
@@ -335,46 +356,48 @@ export default function DownloadPage() {
|
|
|
335
356
|
<>{t("downloadRoute.loadingRelease")}</>
|
|
336
357
|
)}
|
|
337
358
|
</div>
|
|
338
|
-
<div className="mt-2 flex items-center
|
|
339
|
-
<
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
359
|
+
<div className="mt-2 flex items-center justify-center text-xs text-muted-foreground">
|
|
360
|
+
<DropdownMenu>
|
|
361
|
+
<DropdownMenuTrigger asChild>
|
|
362
|
+
<Button
|
|
363
|
+
type="button"
|
|
364
|
+
variant="ghost"
|
|
365
|
+
size="sm"
|
|
366
|
+
className="h-7 gap-1.5 px-2 font-normal text-muted-foreground hover:bg-muted/50 hover:text-foreground"
|
|
367
|
+
data-release-channel={channel}
|
|
368
|
+
>
|
|
369
|
+
<span
|
|
370
|
+
className={
|
|
371
|
+
channel === "nightly"
|
|
372
|
+
? "font-medium text-foreground"
|
|
373
|
+
: undefined
|
|
374
|
+
}
|
|
375
|
+
>
|
|
376
|
+
{channel === "nightly"
|
|
377
|
+
? t("downloadRoute.nightly")
|
|
378
|
+
: t("downloadRoute.stable")}
|
|
379
|
+
</span>
|
|
380
|
+
<IconChevronDown className="size-3.5" aria-hidden="true" />
|
|
381
|
+
</Button>
|
|
382
|
+
</DropdownMenuTrigger>
|
|
383
|
+
<DropdownMenuContent align="center" className="w-44">
|
|
384
|
+
<DropdownMenuRadioGroup
|
|
385
|
+
value={channel}
|
|
386
|
+
onValueChange={(value) => {
|
|
387
|
+
if (value === "production" || value === "nightly") {
|
|
388
|
+
handleChannelChange(value);
|
|
389
|
+
}
|
|
390
|
+
}}
|
|
391
|
+
>
|
|
392
|
+
<DropdownMenuRadioItem value="production">
|
|
393
|
+
{t("downloadRoute.stable")}
|
|
394
|
+
</DropdownMenuRadioItem>
|
|
395
|
+
<DropdownMenuRadioItem value="nightly">
|
|
396
|
+
{t("downloadRoute.nightly")}
|
|
397
|
+
</DropdownMenuRadioItem>
|
|
398
|
+
</DropdownMenuRadioGroup>
|
|
399
|
+
</DropdownMenuContent>
|
|
400
|
+
</DropdownMenu>
|
|
378
401
|
</div>
|
|
379
402
|
</div>
|
|
380
403
|
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
isHumanReadableDocumentTitle,
|
|
17
17
|
normalizeDocumentTitle,
|
|
18
18
|
} from "@agent-native/core/shared";
|
|
19
|
-
import { ShareCopyRow
|
|
19
|
+
import { ShareCopyRow } from "@agent-native/toolkit/sharing";
|
|
20
20
|
import {
|
|
21
21
|
BUILDER_CREDITS_UPGRADE_URL,
|
|
22
22
|
type BuilderCreditsStatus,
|
|
@@ -59,6 +59,7 @@ import { toast } from "sonner";
|
|
|
59
59
|
|
|
60
60
|
import { EditableRecordingTitle } from "@/components/editable-recording-title";
|
|
61
61
|
import { EditorLayout } from "@/components/editor/editor-layout";
|
|
62
|
+
import { ClipsShareTrigger } from "@/components/player/clips-share-trigger";
|
|
62
63
|
import { CommentsPanel } from "@/components/player/comments-panel";
|
|
63
64
|
import { RecordingOptionsMenu } from "@/components/player/delete-recording-menu";
|
|
64
65
|
import { InsightsPanel } from "@/components/player/insights-panel";
|
|
@@ -1051,7 +1052,7 @@ export default function RecordingPage() {
|
|
|
1051
1052
|
if (!showRecoveryState) {
|
|
1052
1053
|
return (
|
|
1053
1054
|
<div className="flex min-h-screen w-full flex-col bg-background">
|
|
1054
|
-
<header className="flex min-w-0 shrink-0 items-center gap-
|
|
1055
|
+
<header className="flex min-w-0 shrink-0 items-center gap-2 border-b border-border px-3 py-2 sm:px-4 sm:py-3">
|
|
1055
1056
|
<BackToLibraryButton />
|
|
1056
1057
|
<div className="min-w-0 flex-1">
|
|
1057
1058
|
<p className="truncate text-sm font-medium">{visibleTitle}</p>
|
|
@@ -1070,10 +1071,7 @@ export default function RecordingPage() {
|
|
|
1070
1071
|
hasPassword={Boolean(recording.hasPassword)}
|
|
1071
1072
|
viewerReshareOnly={viewerReshareOnly}
|
|
1072
1073
|
>
|
|
1073
|
-
<
|
|
1074
|
-
label={t("recordingPage.share")}
|
|
1075
|
-
className="shrink-0"
|
|
1076
|
-
/>
|
|
1074
|
+
<ClipsShareTrigger label={t("recordingPage.share")} />
|
|
1077
1075
|
</ShareRecordingPopover>
|
|
1078
1076
|
</header>
|
|
1079
1077
|
|
|
@@ -1370,7 +1368,7 @@ export default function RecordingPage() {
|
|
|
1370
1368
|
<div className="flex min-h-screen w-full max-w-full flex-col overflow-x-hidden bg-background xl:h-screen xl:flex-row xl:overflow-hidden">
|
|
1371
1369
|
{/* Main video column */}
|
|
1372
1370
|
<div className="flex w-full min-w-0 flex-col xl:flex-1">
|
|
1373
|
-
<header className="flex min-w-0 shrink-0 items-center gap-2 border-b border-border px-3 py-2 sm:
|
|
1371
|
+
<header className="flex min-w-0 shrink-0 items-center gap-2 border-b border-border px-3 py-2 sm:px-4 sm:py-3">
|
|
1374
1372
|
<BackToLibraryButton />
|
|
1375
1373
|
<div className="flex-1 min-w-0">
|
|
1376
1374
|
<EditableRecordingTitle
|
|
@@ -1609,10 +1607,7 @@ export default function RecordingPage() {
|
|
|
1609
1607
|
hasPassword={Boolean(recording.hasPassword)}
|
|
1610
1608
|
viewerReshareOnly={viewerReshareOnly}
|
|
1611
1609
|
>
|
|
1612
|
-
<
|
|
1613
|
-
label={t("recordingPage.share")}
|
|
1614
|
-
className="shrink-0"
|
|
1615
|
-
/>
|
|
1610
|
+
<ClipsShareTrigger label={t("recordingPage.share")} />
|
|
1616
1611
|
</ShareRecordingPopover>
|
|
1617
1612
|
) : null}
|
|
1618
1613
|
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
agentNativePath,
|
|
4
4
|
appBasePath,
|
|
5
5
|
} from "@agent-native/core/client/api-path";
|
|
6
|
-
import { callAction } from "@agent-native/core/client/hooks";
|
|
6
|
+
import { callAction, getBrowserTabId } from "@agent-native/core/client/hooks";
|
|
7
7
|
import { useT } from "@agent-native/core/client/i18n";
|
|
8
8
|
import { useLiveTranscription } from "@agent-native/core/client/transcription/use-live-transcription";
|
|
9
9
|
import type { BrowserDiagnosticsData } from "@shared/browser-diagnostics";
|
|
@@ -1783,7 +1783,7 @@ export default function RecordRoute() {
|
|
|
1783
1783
|
}
|
|
1784
1784
|
if (reportContext && createdId) {
|
|
1785
1785
|
const path = bugReportDonePath(createdId, reportContext);
|
|
1786
|
-
await writeAppState(
|
|
1786
|
+
await writeAppState(`navigate:${getBrowserTabId()}`, {
|
|
1787
1787
|
view: "bug-report-done",
|
|
1788
1788
|
recordingId: createdId,
|
|
1789
1789
|
path,
|
|
@@ -1792,7 +1792,7 @@ export default function RecordRoute() {
|
|
|
1792
1792
|
navigate(path);
|
|
1793
1793
|
}, 50);
|
|
1794
1794
|
} else {
|
|
1795
|
-
await writeAppState(
|
|
1795
|
+
await writeAppState(`navigate:${getBrowserTabId()}`, {
|
|
1796
1796
|
view: "recording",
|
|
1797
1797
|
recordingId: createdId,
|
|
1798
1798
|
});
|
|
@@ -1980,7 +1980,7 @@ export default function RecordRoute() {
|
|
|
1980
1980
|
|
|
1981
1981
|
if (reportContext) {
|
|
1982
1982
|
const path = bugReportDonePath(recordingId, reportContext);
|
|
1983
|
-
await writeAppState(
|
|
1983
|
+
await writeAppState(`navigate:${getBrowserTabId()}`, {
|
|
1984
1984
|
view: "bug-report-done",
|
|
1985
1985
|
recordingId,
|
|
1986
1986
|
path,
|
|
@@ -1991,7 +1991,7 @@ export default function RecordRoute() {
|
|
|
1991
1991
|
return;
|
|
1992
1992
|
}
|
|
1993
1993
|
|
|
1994
|
-
await writeAppState(
|
|
1994
|
+
await writeAppState(`navigate:${getBrowserTabId()}`, {
|
|
1995
1995
|
view: "recording",
|
|
1996
1996
|
recordingId,
|
|
1997
1997
|
}).catch(() => {});
|
|
@@ -13,13 +13,12 @@ import {
|
|
|
13
13
|
import { useT } from "@agent-native/core/client/i18n";
|
|
14
14
|
import { buildSignInReturnHref } from "@agent-native/core/client/ui";
|
|
15
15
|
import { docsUrl } from "@agent-native/core/shared";
|
|
16
|
-
import { ShareTrigger } from "@agent-native/toolkit/sharing";
|
|
17
16
|
import {
|
|
18
17
|
IconAlertTriangle,
|
|
19
18
|
IconArrowLeft,
|
|
20
19
|
IconDeviceDesktop,
|
|
21
20
|
IconDownload,
|
|
22
|
-
|
|
21
|
+
IconDotsVertical,
|
|
23
22
|
IconLock,
|
|
24
23
|
IconLogin2,
|
|
25
24
|
} from "@tabler/icons-react";
|
|
@@ -51,6 +50,7 @@ import { toast } from "sonner";
|
|
|
51
50
|
|
|
52
51
|
import { CaptureInstallButton } from "@/components/capture-install-options";
|
|
53
52
|
import { AccessPasswordPrompt } from "@/components/player/access-password-prompt";
|
|
53
|
+
import { ClipsShareTrigger } from "@/components/player/clips-share-trigger";
|
|
54
54
|
import { CommentsPanel } from "@/components/player/comments-panel";
|
|
55
55
|
import { RecordingOptionsMenu } from "@/components/player/delete-recording-menu";
|
|
56
56
|
import { InsightsPanel } from "@/components/player/insights-panel";
|
|
@@ -1111,7 +1111,7 @@ export default function ShareRoute() {
|
|
|
1111
1111
|
<div className="flex min-h-screen max-w-full flex-col overflow-x-hidden bg-background text-foreground lg:h-screen lg:flex-row lg:overflow-hidden">
|
|
1112
1112
|
{agentDiscovery}
|
|
1113
1113
|
<div className="flex w-full min-w-0 flex-col lg:flex-1">
|
|
1114
|
-
<header className="flex min-w-0 shrink-0 flex-wrap items-center gap-2 border-b border-border px-3 py-2 sm:
|
|
1114
|
+
<header className="flex min-w-0 shrink-0 flex-wrap items-center gap-2 border-b border-border px-3 py-2 sm:px-4 sm:py-3 lg:flex-nowrap">
|
|
1115
1115
|
{session ? (
|
|
1116
1116
|
<Button
|
|
1117
1117
|
asChild
|
|
@@ -1147,7 +1147,7 @@ export default function ShareRoute() {
|
|
|
1147
1147
|
)}
|
|
1148
1148
|
</div>
|
|
1149
1149
|
|
|
1150
|
-
<div className="flex w-full min-w-0 flex-wrap items-center justify-between gap-
|
|
1150
|
+
<div className="flex w-full min-w-0 flex-wrap items-center justify-between gap-1 sm:w-auto sm:justify-end">
|
|
1151
1151
|
<RecordingViewsBadge
|
|
1152
1152
|
recordingId={recording.id}
|
|
1153
1153
|
viewCount={viewCount}
|
|
@@ -1161,6 +1161,22 @@ export default function ShareRoute() {
|
|
|
1161
1161
|
onCtaClick={fireShareCtaClick}
|
|
1162
1162
|
/>
|
|
1163
1163
|
)}
|
|
1164
|
+
{viewerCanEdit || canReshareLink ? (
|
|
1165
|
+
<ShareRecordingPopover
|
|
1166
|
+
recordingId={recording.id}
|
|
1167
|
+
recordingTitle={recording.title}
|
|
1168
|
+
initialVisibility={recording.visibility}
|
|
1169
|
+
initialRole={viewerIsOwner ? "owner" : undefined}
|
|
1170
|
+
videoUrl={shareVideoUrl}
|
|
1171
|
+
thumbnailUrl={recording.thumbnailUrl}
|
|
1172
|
+
animatedThumbnailUrl={recording.animatedThumbnailUrl}
|
|
1173
|
+
isLoomRecording={isLoomEmbedBacked}
|
|
1174
|
+
hasPassword={Boolean(recording.hasPassword)}
|
|
1175
|
+
viewerReshareOnly={viewerReshareOnly}
|
|
1176
|
+
>
|
|
1177
|
+
<ClipsShareTrigger label={t("sharePage.share")} />
|
|
1178
|
+
</ShareRecordingPopover>
|
|
1179
|
+
) : null}
|
|
1164
1180
|
{!viewerCanEdit && canDownloadRecording ? (
|
|
1165
1181
|
<DropdownMenu
|
|
1166
1182
|
open={downloadMenuOpen}
|
|
@@ -1170,10 +1186,10 @@ export default function ShareRoute() {
|
|
|
1170
1186
|
<Button
|
|
1171
1187
|
variant="ghost"
|
|
1172
1188
|
size="sm"
|
|
1173
|
-
className="h-
|
|
1189
|
+
className="-mx-1.5 h-auto w-auto shrink-0 px-0.5 py-1.5"
|
|
1174
1190
|
aria-label={t("sharePage.clipOptions")}
|
|
1175
1191
|
>
|
|
1176
|
-
<
|
|
1192
|
+
<IconDotsVertical className="h-4 w-4" />
|
|
1177
1193
|
</Button>
|
|
1178
1194
|
</DropdownMenuTrigger>
|
|
1179
1195
|
<DropdownMenuContent align="end" className="w-44">
|
|
@@ -1206,25 +1222,6 @@ export default function ShareRoute() {
|
|
|
1206
1222
|
onDeleted={() => navigate("/library", { replace: true })}
|
|
1207
1223
|
/>
|
|
1208
1224
|
) : null}
|
|
1209
|
-
{viewerCanEdit || canReshareLink ? (
|
|
1210
|
-
<ShareRecordingPopover
|
|
1211
|
-
recordingId={recording.id}
|
|
1212
|
-
recordingTitle={recording.title}
|
|
1213
|
-
initialVisibility={recording.visibility}
|
|
1214
|
-
initialRole={viewerIsOwner ? "owner" : undefined}
|
|
1215
|
-
videoUrl={shareVideoUrl}
|
|
1216
|
-
thumbnailUrl={recording.thumbnailUrl}
|
|
1217
|
-
animatedThumbnailUrl={recording.animatedThumbnailUrl}
|
|
1218
|
-
isLoomRecording={isLoomEmbedBacked}
|
|
1219
|
-
hasPassword={Boolean(recording.hasPassword)}
|
|
1220
|
-
viewerReshareOnly={viewerReshareOnly}
|
|
1221
|
-
>
|
|
1222
|
-
<ShareTrigger
|
|
1223
|
-
label={t("sharePage.share")}
|
|
1224
|
-
className="shrink-0"
|
|
1225
|
-
/>
|
|
1226
|
-
</ShareRecordingPopover>
|
|
1227
|
-
) : null}
|
|
1228
1225
|
</div>
|
|
1229
1226
|
</header>
|
|
1230
1227
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineAction } from "@agent-native/core";
|
|
2
|
-
import {
|
|
2
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
3
3
|
import { eq } from "drizzle-orm";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
|
|
@@ -57,7 +57,7 @@ export default defineAction({
|
|
|
57
57
|
run: async (args) => {
|
|
58
58
|
const path = await resolveNavigatePath(args);
|
|
59
59
|
|
|
60
|
-
await
|
|
60
|
+
await writeAppStateForCurrentTab("navigate", { path, ts: Date.now() });
|
|
61
61
|
return `Navigating to ${path}`;
|
|
62
62
|
},
|
|
63
63
|
});
|
|
@@ -85,7 +85,8 @@ Read the relevant skill before deeper work in that area.
|
|
|
85
85
|
## Application State
|
|
86
86
|
|
|
87
87
|
- `navigation` — current view, design id, file id, and related UI state.
|
|
88
|
-
- `navigate` — moves the UI; auto-deleted after the
|
|
88
|
+
- `navigate` — moves the UI in the tab that asked; auto-deleted after the
|
|
89
|
+
client consumes it.
|
|
89
90
|
- `design-selection` — active screen, selected element, overview mode,
|
|
90
91
|
inspector tab, zoom, and screen list for the current tab.
|
|
91
92
|
- `design-generation-session:<designId>`, `show-questions`, `guided-questions` —
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { defineAction, embedApp } from "@agent-native/core";
|
|
2
|
-
import {
|
|
2
|
+
import {
|
|
3
|
+
writeAppState,
|
|
4
|
+
writeAppStateForCurrentTab,
|
|
5
|
+
} from "@agent-native/core/application-state";
|
|
3
6
|
import { buildDeepLink } from "@agent-native/core/server";
|
|
4
7
|
import { assertAccess } from "@agent-native/core/sharing";
|
|
5
8
|
import {
|
|
@@ -430,7 +433,7 @@ export default defineAction({
|
|
|
430
433
|
designGenerationSessionKey(designId),
|
|
431
434
|
session as unknown as Record<string, unknown>,
|
|
432
435
|
);
|
|
433
|
-
await
|
|
436
|
+
await writeAppStateForCurrentTab("navigate", {
|
|
434
437
|
view: "editor",
|
|
435
438
|
designId,
|
|
436
439
|
editorView: "overview",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
*/
|
|
29
29
|
|
|
30
30
|
import { defineAction } from "@agent-native/core/action";
|
|
31
|
-
import {
|
|
31
|
+
import { writeAppStateForCurrentTab } from "@agent-native/core/application-state";
|
|
32
32
|
import { getText, hasCollabState } from "@agent-native/core/collab";
|
|
33
33
|
import { accessFilter, resolveAccess } from "@agent-native/core/sharing";
|
|
34
34
|
import { and, eq } from "drizzle-orm";
|
|
@@ -223,7 +223,7 @@ export default defineAction({
|
|
|
223
223
|
};
|
|
224
224
|
}
|
|
225
225
|
|
|
226
|
-
await
|
|
226
|
+
await writeAppStateForCurrentTab("navigate", {
|
|
227
227
|
view: "editor",
|
|
228
228
|
designId,
|
|
229
229
|
editorView: "single",
|