@agent-native/core 0.153.1 → 0.153.4
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/analytics/.agents/skills/adhoc-analysis/SKILL.md +21 -19
- package/corpus/templates/analytics/AGENTS.md +4 -0
- package/corpus/templates/analytics/server/plugins/agent-chat.ts +1 -0
- 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 +593 -7
- package/corpus/templates/clips/desktop/src-tauri/src/rewind_clip.rs +95 -10
- package/corpus/templates/forms/AGENTS.md +6 -0
- package/corpus/templates/forms/server/plugins/agent-chat.ts +1 -0
- package/corpus/templates/mail/AGENTS.md +5 -4
- package/corpus/templates/mail/actions/get-automation-settings.ts +17 -6
- package/corpus/templates/mail/actions/send-email.ts +17 -9
- package/corpus/templates/mail/actions/send-queued-drafts.ts +21 -11
- package/corpus/templates/mail/actions/update-automation-settings.ts +20 -6
- package/corpus/templates/mail/app/i18n/en-US.ts +5 -0
- package/corpus/templates/mail/app/pages/SettingsPage.tsx +68 -7
- package/corpus/templates/mail/server/lib/automation-settings.ts +27 -0
- package/corpus/templates/mail/server/plugins/agent-chat.ts +2 -0
- package/corpus/templates/slides/app/components/editor/EditorSidebar.tsx +3 -3
- package/corpus/templates/slides/app/components/presentation/PresentationView.tsx +17 -4
- package/corpus/templates/slides/app/context/DeckContext.tsx +3 -2
- package/corpus/templates/slides/app/pages/DeckEditor.tsx +44 -0
- package/corpus/templates/slides/changelog/2026-08-12-arrow-key-navigation-in-the-slide-film-strip-now-scrolls-sli.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-12-duplicate-a-slide-from-the-film-strip-with-cmd-ctrl-c-then-c.md +6 -0
- package/corpus/templates/slides/changelog/2026-08-12-presenting-a-deck-now-returns-you-to-the-slide-you-were-view.md +6 -0
- package/dist/client/resources/mcp-integration-catalog.d.ts +7 -0
- package/dist/client/resources/mcp-integration-catalog.js +14 -1
- package/dist/client/settings/AgentsSection.js +46 -30
- package/dist/client/sharing/ShareDialog.js +4 -2
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/observability/routes.d.ts +5 -5
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-chat-plugin.js +1 -0
- package/dist/server/agent-engine-api-key-route.d.ts +1 -1
- package/package.json +1 -1
package/corpus/README.md
CHANGED
|
@@ -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
|
|
|
@@ -48,6 +48,10 @@ Read the relevant skill before deeper work:
|
|
|
48
48
|
sibling-invocable because this app owns schema, source selection, and tools.
|
|
49
49
|
Prefer natural-language delegation; shaped reads are stable contracts, not
|
|
50
50
|
delegation workarounds.
|
|
51
|
+
- Analytics owns first-party product usage, app/template events, agent-native
|
|
52
|
+
signups, conversions, and other curated product metrics. Answer sibling-app
|
|
53
|
+
delegations with the built-in source and query catalog; sibling agents should
|
|
54
|
+
send a natural-language question, never SQL.
|
|
51
55
|
- For open-ended delegated requests, choose a safe default and label partial.
|
|
52
56
|
- Data integrity first. Never invent numbers, dimensions, filters, or source
|
|
53
57
|
semantics; only present values you actually retrieved, and state uncertainty.
|
|
@@ -105,6 +105,7 @@ export const ANALYTICS_OBSERVABILITY_INCIDENT_GUIDANCE =
|
|
|
105
105
|
"OBSERVABILITY INCIDENT WORKFLOW — For a named user's session or error question, resolve the user's email from context, then use list-session-recordings with userId over a bounded recent window to discover the relevant sessions. Do not require hasErrors=true for this initial lookup: replay/network/stuck-run evidence can exist while the recording's JavaScript errorCount is zero. Use hasErrors=true only when the user specifically asks for recordings with captured JavaScript errors or the recording metadata confirms that filter is appropriate. Use list-error-issues with userId or sessionRecordingId to identify a grouped issue, then get-error-issue for stack, breadcrumbs, occurrences, and linked recordings. For console diagnostics or failed network requests, create-session-replay-agent-link first and use its scoped diagnostics endpoint for detailed error text, stacks, request metadata, and bounded 5xx snippets; enumerate with kind/limit and fromMs/toMs or offset when needed. Use get-session-replay-summary and get-session-replay-timeline for the page-navigation and click sequence, and use get-session-replay-events only for additional bounded replay-event details. If no grouped error exists, correlate first-party observability events such as agent_chat_stuck_detected with query-agent-native-analytics. This and other read-only investigation tools remain available in Plan mode; run the query instead of deferring it to execution mode. Prefer these first-party actions over generic SQL. Report the matching evidence and do not claim a root cause without a corroborating error, event, or replay signal. ";
|
|
106
106
|
|
|
107
107
|
export const ANALYTICS_CROSS_APP_ROUTING_GUIDANCE =
|
|
108
|
+
"WORKSPACE APP ROUTING — Analytics is the sibling app for first-party product usage, app/template events, agent-native signups, conversions, and other curated product metrics. When another app delegates one of these questions with `call-agent`, answer it here using the built-in first-party source and query catalog; do not send the user back to another app or ask the caller to invent SQL. " +
|
|
108
109
|
"WORKSPACE APP ROUTING — Brain is the sibling app that owns company knowledge and indexed Slack context. Brain is not an Analytics extension and will not appear in `list-extensions`. When the user asks about company knowledge, decisions, meeting context, or Slack messages/context such as a named channel or thread, use `call-agent` with agent `brain` and a narrow natural-language question. Use `describe-workspace-apps` only when you need to confirm the sibling capability. Do not use `list-extensions` to find Brain, and do not use `provider-api-request` to call Brain. If Brain reports an access or source error, preserve that exact error; do not infer that the Slack bot is absent from a channel or tell the user to re-invite it. Stay in Analytics for metrics and aggregates over a named provider. ";
|
|
109
110
|
|
|
110
111
|
export const NON_ANALYTICS_REQUEST_GUIDANCE =
|
|
@@ -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" &&
|