@agent-native/core 0.153.1 → 0.153.2
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/templates/analytics/.agents/skills/adhoc-analysis/SKILL.md +21 -19
- package/corpus/templates/clips/app/components/meetings/share-meeting-dialog.tsx +0 -11
- package/corpus/templates/clips/app/components/player/share-dialog.tsx +32 -33
- package/corpus/templates/clips/app/components/sharing/share-ui.tsx +29 -39
- package/corpus/templates/clips/app/routes/_app.meetings.$meetingId.tsx +0 -1
- package/corpus/templates/clips/desktop/src/app.tsx +817 -441
- package/corpus/templates/clips/desktop/src/styles.css +234 -0
- package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
- package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +584 -1
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +25 -0
- package/dist/client/sharing/ShareDialog.js +4 -2
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/routes.d.ts +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
|
@@ -101,25 +101,27 @@ Don't just dump raw data. Synthesize findings:
|
|
|
101
101
|
|
|
102
102
|
### Step 4: Generate Charts (when useful)
|
|
103
103
|
|
|
104
|
-
When the analysis benefits from a visual — trends over time, distributions,
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
generate-chart
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
104
|
+
When the analysis benefits from a visual — trends over time, distributions, or
|
|
105
|
+
comparisons between categories — query the data first, then use the live
|
|
106
|
+
`/chart` embed described in `data-querying` for an in-chat answer. Do not call
|
|
107
|
+
`generate-chart` for a one-off chat result: it produces a static image for
|
|
108
|
+
saved artifacts, requires pre-stringified JSON, and does not count as a real
|
|
109
|
+
data query for the final response guard.
|
|
110
|
+
|
|
111
|
+
For a stacked multi-series bar chart, keep the query in long form and emit a
|
|
112
|
+
panel with `chartType: "bar"`, `config.pivot` containing `xKey`, `seriesKey`,
|
|
113
|
+
and `valueKey`, plus `config.stacked: true`. The live chart route pivots the
|
|
114
|
+
rows and renders one stack per x-axis category. See `data-querying`'s
|
|
115
|
+
"Inline Charts In Chat" section for the exact `embed` fence and encoding.
|
|
116
|
+
|
|
117
|
+
Only use `generate-chart` when a saved analysis artifact explicitly needs a
|
|
118
|
+
static image. If it returns an error while answering in chat, switch to the
|
|
119
|
+
live embed instead of retrying reformatted `labels` or `data` parameters.
|
|
120
|
+
|
|
121
|
+
You can include multiple live charts in one analysis. Reach for a chart when it
|
|
122
|
+
communicates the finding faster than a table - don't force visuals on every
|
|
123
|
+
analysis. Include the query and embed configuration in saved `instructions` so
|
|
124
|
+
re-runs produce fresh charts.
|
|
123
125
|
|
|
124
126
|
### Step 5: Format Results as Markdown
|
|
125
127
|
|
|
@@ -12,7 +12,6 @@ import {
|
|
|
12
12
|
CopyField,
|
|
13
13
|
GeneralAccessSelect,
|
|
14
14
|
MakePublicCard,
|
|
15
|
-
ShareCardHeader,
|
|
16
15
|
SharePeopleTab,
|
|
17
16
|
copyToClipboard,
|
|
18
17
|
useResourceVisibilityMutation,
|
|
@@ -30,7 +29,6 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
|
|
30
29
|
|
|
31
30
|
export interface ShareMeetingPopoverProps {
|
|
32
31
|
meetingId: string;
|
|
33
|
-
meetingTitle?: string;
|
|
34
32
|
shareTranscript: boolean;
|
|
35
33
|
transcriptReady: boolean;
|
|
36
34
|
children: ReactNode;
|
|
@@ -38,7 +36,6 @@ export interface ShareMeetingPopoverProps {
|
|
|
38
36
|
|
|
39
37
|
export function ShareMeetingPopover({
|
|
40
38
|
meetingId,
|
|
41
|
-
meetingTitle,
|
|
42
39
|
shareTranscript,
|
|
43
40
|
transcriptReady,
|
|
44
41
|
children,
|
|
@@ -52,7 +49,6 @@ export function ShareMeetingPopover({
|
|
|
52
49
|
>
|
|
53
50
|
<ShareMeetingContent
|
|
54
51
|
meetingId={meetingId}
|
|
55
|
-
meetingTitle={meetingTitle}
|
|
56
52
|
shareTranscript={shareTranscript}
|
|
57
53
|
transcriptReady={transcriptReady}
|
|
58
54
|
/>
|
|
@@ -63,12 +59,10 @@ export function ShareMeetingPopover({
|
|
|
63
59
|
|
|
64
60
|
function ShareMeetingContent({
|
|
65
61
|
meetingId,
|
|
66
|
-
meetingTitle,
|
|
67
62
|
shareTranscript,
|
|
68
63
|
transcriptReady,
|
|
69
64
|
}: {
|
|
70
65
|
meetingId: string;
|
|
71
|
-
meetingTitle?: string;
|
|
72
66
|
shareTranscript: boolean;
|
|
73
67
|
transcriptReady: boolean;
|
|
74
68
|
}) {
|
|
@@ -85,14 +79,9 @@ function ShareMeetingContent({
|
|
|
85
79
|
|
|
86
80
|
const data = sharesQuery.data;
|
|
87
81
|
const canManage = data?.role === "owner" || data?.role === "admin";
|
|
88
|
-
const titleText = meetingTitle
|
|
89
|
-
? t("clipsFinalRaw.shareNamedMeeting", { title: meetingTitle })
|
|
90
|
-
: t("clipsFinalRaw.shareMeeting");
|
|
91
82
|
|
|
92
83
|
return (
|
|
93
84
|
<>
|
|
94
|
-
<ShareCardHeader title={titleText} ownerEmail={data?.ownerEmail} />
|
|
95
|
-
|
|
96
85
|
<Tabs defaultValue="link" className="min-w-0 px-4 py-3">
|
|
97
86
|
<TabsList className="grid w-full grid-cols-2">
|
|
98
87
|
<TabsTrigger value="link" className="gap-1.5">
|
|
@@ -27,7 +27,6 @@ import {
|
|
|
27
27
|
CopyField,
|
|
28
28
|
GeneralAccessSelect,
|
|
29
29
|
MakePublicCard,
|
|
30
|
-
ShareCardHeader,
|
|
31
30
|
SharePeopleTab,
|
|
32
31
|
copyToClipboard,
|
|
33
32
|
useResourceVisibilityMutation,
|
|
@@ -51,6 +50,7 @@ import {
|
|
|
51
50
|
} from "@/components/ui/popover";
|
|
52
51
|
import { Switch } from "@/components/ui/switch";
|
|
53
52
|
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs";
|
|
53
|
+
import { cn } from "@/lib/utils";
|
|
54
54
|
|
|
55
55
|
import { buildEmailPreviewMarkup } from "../../../shared/email-preview";
|
|
56
56
|
import { isLoomEmbedUrl } from "../../../shared/loom";
|
|
@@ -228,19 +228,12 @@ function ShareRecordingContent({
|
|
|
228
228
|
absoluteAppUrl(`/share/${recordingId}`),
|
|
229
229
|
ownerViaId,
|
|
230
230
|
);
|
|
231
|
-
const titleText = recordingTitle
|
|
232
|
-
? t("shareDialog.shareTitle", { title: recordingTitle })
|
|
233
|
-
: t("shareDialog.shareRecording");
|
|
234
|
-
|
|
235
231
|
return (
|
|
236
232
|
<>
|
|
237
|
-
<
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
/>
|
|
242
|
-
|
|
243
|
-
<Tabs defaultValue="link" className="min-w-0 px-4 py-3">
|
|
233
|
+
<Tabs
|
|
234
|
+
defaultValue="link"
|
|
235
|
+
className={cn("min-w-0 px-4 py-3", reserveCloseButton && "pe-12")}
|
|
236
|
+
>
|
|
244
237
|
<TabsList className="grid w-full grid-cols-3">
|
|
245
238
|
<TabsTrigger value="link" className="gap-1.5">
|
|
246
239
|
<IconLink size={14} />
|
|
@@ -441,6 +434,25 @@ function LinkTab({
|
|
|
441
434
|
? t("shareDialog.agentPrompt", { agentContextUrl: agentLink })
|
|
442
435
|
: "";
|
|
443
436
|
const [agentDetailsOpen, setAgentDetailsOpen] = useState(false);
|
|
437
|
+
const showMakePublic = sharesLoaded && !isPublic && canManage;
|
|
438
|
+
const downloadButton = videoUrl ? (
|
|
439
|
+
<Button
|
|
440
|
+
variant="outline"
|
|
441
|
+
size="sm"
|
|
442
|
+
className={isLoomRecording ? "gap-1.5" : undefined}
|
|
443
|
+
onClick={() => window.open(videoUrl, "_blank", "noopener,noreferrer")}
|
|
444
|
+
>
|
|
445
|
+
{isLoomRecording ? (
|
|
446
|
+
<>
|
|
447
|
+
<IconExternalLink className="h-4 w-4" />
|
|
448
|
+
{t("shareDialog.openPlayer")}
|
|
449
|
+
</>
|
|
450
|
+
) : (
|
|
451
|
+
t("recordRoute.downloadRecording")
|
|
452
|
+
)}
|
|
453
|
+
</Button>
|
|
454
|
+
) : null;
|
|
455
|
+
const moveDownloadIntoMakePublicRow = showMakePublic && Boolean(videoUrl);
|
|
444
456
|
|
|
445
457
|
useEffect(() => {
|
|
446
458
|
if (isPublic) setAgentDetailsOpen(false);
|
|
@@ -540,9 +552,12 @@ function LinkTab({
|
|
|
540
552
|
</Collapsible>
|
|
541
553
|
) : null}
|
|
542
554
|
|
|
543
|
-
{
|
|
555
|
+
{showMakePublic ? (
|
|
544
556
|
<MakePublicCard
|
|
545
557
|
isPending={isPending}
|
|
558
|
+
secondaryAction={
|
|
559
|
+
moveDownloadIntoMakePublicRow ? downloadButton : undefined
|
|
560
|
+
}
|
|
546
561
|
onMakePublic={() =>
|
|
547
562
|
setResourceVisibility("public", {
|
|
548
563
|
onSuccess: () => copyToClipboard(shareUrl),
|
|
@@ -551,7 +566,9 @@ function LinkTab({
|
|
|
551
566
|
/>
|
|
552
567
|
) : null}
|
|
553
568
|
|
|
554
|
-
{emailPreviewThumbnailUrl ||
|
|
569
|
+
{emailPreviewThumbnailUrl ||
|
|
570
|
+
animatedThumbnailUrl ||
|
|
571
|
+
(videoUrl && !moveDownloadIntoMakePublicRow) ? (
|
|
555
572
|
<div className="flex flex-wrap gap-2">
|
|
556
573
|
{emailPreviewThumbnailUrl ? (
|
|
557
574
|
<Button
|
|
@@ -571,25 +588,7 @@ function LinkTab({
|
|
|
571
588
|
{t("shareDialog.gifPreview")}
|
|
572
589
|
</Button>
|
|
573
590
|
) : null}
|
|
574
|
-
{
|
|
575
|
-
<Button
|
|
576
|
-
variant="outline"
|
|
577
|
-
size="sm"
|
|
578
|
-
className={isLoomRecording ? "gap-1.5" : undefined}
|
|
579
|
-
onClick={() =>
|
|
580
|
-
window.open(videoUrl, "_blank", "noopener,noreferrer")
|
|
581
|
-
}
|
|
582
|
-
>
|
|
583
|
-
{isLoomRecording ? (
|
|
584
|
-
<>
|
|
585
|
-
<IconExternalLink className="h-4 w-4" />
|
|
586
|
-
{t("shareDialog.openPlayer")}
|
|
587
|
-
</>
|
|
588
|
-
) : (
|
|
589
|
-
t("recordRoute.downloadRecording")
|
|
590
|
-
)}
|
|
591
|
-
</Button>
|
|
592
|
-
) : null}
|
|
591
|
+
{!moveDownloadIntoMakePublicRow ? downloadButton : null}
|
|
593
592
|
</div>
|
|
594
593
|
) : null}
|
|
595
594
|
</div>
|
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
IconWorld,
|
|
15
15
|
} from "@tabler/icons-react";
|
|
16
16
|
import { useQueryClient } from "@tanstack/react-query";
|
|
17
|
-
import { useMemo, useState } from "react";
|
|
17
|
+
import { useMemo, useState, type ReactNode } from "react";
|
|
18
18
|
|
|
19
19
|
import {
|
|
20
20
|
Avatar as UserAvatar,
|
|
@@ -136,34 +136,19 @@ export function useResourceVisibilityMutation(
|
|
|
136
136
|
}
|
|
137
137
|
|
|
138
138
|
// ---------------------------------------------------------------------------
|
|
139
|
-
//
|
|
139
|
+
// Compact section labels
|
|
140
140
|
// ---------------------------------------------------------------------------
|
|
141
141
|
|
|
142
|
-
export function
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
reserveCloseButton = false,
|
|
142
|
+
export function ShareSectionLabel({
|
|
143
|
+
children,
|
|
144
|
+
className,
|
|
146
145
|
}: {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
reserveCloseButton?: boolean;
|
|
146
|
+
children: ReactNode;
|
|
147
|
+
className?: string;
|
|
150
148
|
}) {
|
|
151
|
-
const t = useT();
|
|
152
149
|
return (
|
|
153
|
-
<div
|
|
154
|
-
|
|
155
|
-
"min-w-0 border-b border-border px-4 pb-3 pt-3",
|
|
156
|
-
reserveCloseButton && "pe-12",
|
|
157
|
-
)}
|
|
158
|
-
>
|
|
159
|
-
<div className="min-w-0 truncate text-sm font-semibold" title={title}>
|
|
160
|
-
{title}
|
|
161
|
-
</div>
|
|
162
|
-
{ownerEmail ? (
|
|
163
|
-
<div className="mt-0.5 truncate text-xs text-muted-foreground">
|
|
164
|
-
{t("shareUi.owner", { email: ownerEmail })}
|
|
165
|
-
</div>
|
|
166
|
-
) : null}
|
|
150
|
+
<div className={cn("text-xs font-medium text-muted-foreground", className)}>
|
|
151
|
+
{children}
|
|
167
152
|
</div>
|
|
168
153
|
);
|
|
169
154
|
}
|
|
@@ -197,9 +182,9 @@ export function GeneralAccessSelect({
|
|
|
197
182
|
|
|
198
183
|
return (
|
|
199
184
|
<div>
|
|
200
|
-
<
|
|
185
|
+
<ShareSectionLabel className="mb-2">
|
|
201
186
|
{t("shareUi.generalAccess")}
|
|
202
|
-
</
|
|
187
|
+
</ShareSectionLabel>
|
|
203
188
|
<div className="flex items-center gap-3">
|
|
204
189
|
<span
|
|
205
190
|
aria-hidden
|
|
@@ -245,9 +230,11 @@ export function GeneralAccessSelect({
|
|
|
245
230
|
export function MakePublicCard({
|
|
246
231
|
isPending,
|
|
247
232
|
onMakePublic,
|
|
233
|
+
secondaryAction,
|
|
248
234
|
}: {
|
|
249
235
|
isPending: boolean;
|
|
250
236
|
onMakePublic: () => void;
|
|
237
|
+
secondaryAction?: ReactNode;
|
|
251
238
|
}) {
|
|
252
239
|
const t = useT();
|
|
253
240
|
return (
|
|
@@ -259,16 +246,21 @@ export function MakePublicCard({
|
|
|
259
246
|
strokeWidth={1.8}
|
|
260
247
|
className="text-muted-foreground"
|
|
261
248
|
/>
|
|
262
|
-
<
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
249
|
+
<div className="flex items-center gap-2">
|
|
250
|
+
{secondaryAction}
|
|
251
|
+
<Button
|
|
252
|
+
type="button"
|
|
253
|
+
variant="outline"
|
|
254
|
+
size="sm"
|
|
255
|
+
className="h-7"
|
|
256
|
+
onClick={onMakePublic}
|
|
257
|
+
disabled={isPending}
|
|
258
|
+
>
|
|
259
|
+
{isPending
|
|
260
|
+
? t("shareUi.makingPublic")
|
|
261
|
+
: t("shareUi.makePublicAndCopy")}
|
|
262
|
+
</Button>
|
|
263
|
+
</div>
|
|
272
264
|
</div>
|
|
273
265
|
);
|
|
274
266
|
}
|
|
@@ -297,9 +289,7 @@ export function CopyField({
|
|
|
297
289
|
return (
|
|
298
290
|
<div>
|
|
299
291
|
{label ? (
|
|
300
|
-
<
|
|
301
|
-
{label}
|
|
302
|
-
</div>
|
|
292
|
+
<ShareSectionLabel className="mb-1">{label}</ShareSectionLabel>
|
|
303
293
|
) : null}
|
|
304
294
|
<div className="flex items-stretch gap-2">
|
|
305
295
|
<Input
|
|
@@ -704,7 +704,6 @@ export default function MeetingDetailRoute() {
|
|
|
704
704
|
) : null}
|
|
705
705
|
<ShareMeetingPopover
|
|
706
706
|
meetingId={meeting.id}
|
|
707
|
-
meetingTitle={meeting.title}
|
|
708
707
|
shareTranscript={meeting.shareTranscript === true}
|
|
709
708
|
transcriptReady={
|
|
710
709
|
meeting.transcriptStatus === "ready" &&
|