@agent-native/core 0.137.0 → 0.137.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/app/components/AgentCompletionSound.tsx +105 -0
  3. package/corpus/templates/analytics/app/components/layout/Layout.tsx +44 -35
  4. package/corpus/templates/analytics/app/i18n-data.ts +38 -0
  5. package/corpus/templates/analytics/app/pages/Settings.tsx +53 -1
  6. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +6 -0
  7. package/corpus/templates/analytics/changelog/2026-08-04-choose-whether-analytics-plays-a-bell-when-the-agent-finishe.md +6 -0
  8. package/corpus/templates/analytics/shared/analytics-user-prefs.ts +2 -0
  9. package/corpus/templates/slides/app/components/editor/NewDeckReferenceStep.tsx +321 -0
  10. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +32 -11
  11. package/corpus/templates/slides/app/lib/recent-references.ts +82 -0
  12. package/corpus/templates/slides/app/pages/DeckEditor.tsx +3 -0
  13. package/corpus/templates/slides/app/pages/Index.tsx +236 -181
  14. package/dist/client/DefaultSpinner.d.ts +0 -12
  15. package/dist/client/DefaultSpinner.js +22 -2
  16. package/dist/client/onboarding/use-onboarding.js +3 -0
  17. package/dist/collab/awareness.d.ts +2 -2
  18. package/dist/collab/routes.d.ts +1 -1
  19. package/dist/deploy/build.js +2 -1
  20. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  21. package/dist/notifications/routes.d.ts +2 -2
  22. package/dist/observability/routes.d.ts +3 -3
  23. package/dist/resources/handlers.d.ts +1 -1
  24. package/dist/secrets/routes.d.ts +3 -3
  25. package/dist/server/transcribe-voice.d.ts +1 -1
  26. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +25 -9
  27. package/package.json +1 -1
  28. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +25 -9
package/corpus/README.md CHANGED
@@ -31,4 +31,4 @@ rg -n "defineAction|useActionQuery" node_modules/@agent-native/core/corpus
31
31
 
32
32
  ## Generated Counts
33
33
 
34
- - template files: 7555
34
+ - template files: 7559
@@ -0,0 +1,105 @@
1
+ import { appPath } from "@agent-native/core/client/api-path";
2
+ import { useActionQuery } from "@agent-native/core/client/hooks";
3
+ import { useEffect, useRef } from "react";
4
+
5
+ import {
6
+ ANALYTICS_USER_PREFS_KEY,
7
+ type AnalyticsUserPrefs,
8
+ } from "../../shared/analytics-user-prefs";
9
+
10
+ const AGENT_COMPLETION_SOUND_URL = appPath("/agent-completion.mp3");
11
+ const DEFAULT_TAB_ID = "__default__";
12
+
13
+ function getTabId(detail: unknown): string {
14
+ if (
15
+ detail &&
16
+ typeof detail === "object" &&
17
+ "tabId" in detail &&
18
+ typeof detail.tabId === "string" &&
19
+ detail.tabId
20
+ ) {
21
+ return detail.tabId;
22
+ }
23
+ return DEFAULT_TAB_ID;
24
+ }
25
+
26
+ /** Plays the shared Builder bell after a successful Analytics agent run. */
27
+ export function AgentCompletionSound() {
28
+ const { data: prefs, isError } = useActionQuery<AnalyticsUserPrefs>(
29
+ "get-user-pref",
30
+ { key: ANALYTICS_USER_PREFS_KEY },
31
+ );
32
+ const soundEnabledRef = useRef(false);
33
+ const runningTabsRef = useRef(new Set<string>());
34
+ const autoContinuingTabsRef = useRef(new Set<string>());
35
+ const failedTabsRef = useRef(new Set<string>());
36
+
37
+ useEffect(() => {
38
+ // Missing and unreadable preferences both keep the sound off until enabled.
39
+ soundEnabledRef.current = !isError && prefs?.bellSoundEnabled === true;
40
+ }, [isError, prefs]);
41
+
42
+ useEffect(() => {
43
+ const handleRunError = (event: Event) => {
44
+ const detail = (event as CustomEvent).detail;
45
+ failedTabsRef.current.add(getTabId(detail));
46
+ };
47
+
48
+ const handleAutoContinue = (event: Event) => {
49
+ const detail = (event as CustomEvent).detail;
50
+ autoContinuingTabsRef.current.add(getTabId(detail));
51
+ };
52
+
53
+ const handleChatRunning = (event: Event) => {
54
+ const detail = (event as CustomEvent).detail;
55
+ const tabId = getTabId(detail);
56
+
57
+ if (detail?.isRunning === true) {
58
+ autoContinuingTabsRef.current.delete(tabId);
59
+ failedTabsRef.current.delete(tabId);
60
+ runningTabsRef.current.add(tabId);
61
+ return;
62
+ }
63
+
64
+ if (
65
+ detail?.isRunning !== false ||
66
+ !runningTabsRef.current.delete(tabId)
67
+ ) {
68
+ return;
69
+ }
70
+
71
+ const wasAutoContinued = autoContinuingTabsRef.current.delete(tabId);
72
+ const failed = failedTabsRef.current.delete(tabId);
73
+ if (
74
+ wasAutoContinued ||
75
+ failed ||
76
+ detail.reason === "failed" ||
77
+ detail.reason === "stopped" ||
78
+ !soundEnabledRef.current ||
79
+ typeof Audio === "undefined"
80
+ ) {
81
+ return;
82
+ }
83
+
84
+ const audio = new Audio(AGENT_COMPLETION_SOUND_URL);
85
+ audio.volume = 0.5;
86
+ void audio.play().catch(() => {
87
+ // Browsers may reject playback until the user has interacted with the page.
88
+ });
89
+ };
90
+
91
+ window.addEventListener("agent-chat:run-error", handleRunError);
92
+ window.addEventListener("agent-chat:auto-continue", handleAutoContinue);
93
+ window.addEventListener("agentNative.chatRunning", handleChatRunning);
94
+ return () => {
95
+ window.removeEventListener("agent-chat:run-error", handleRunError);
96
+ window.removeEventListener(
97
+ "agent-chat:auto-continue",
98
+ handleAutoContinue,
99
+ );
100
+ window.removeEventListener("agentNative.chatRunning", handleChatRunning);
101
+ };
102
+ }, []);
103
+
104
+ return null;
105
+ }
@@ -22,6 +22,7 @@ import {
22
22
  } from "@/lib/chat-handoff";
23
23
  import { TAB_ID } from "@/lib/tab-id";
24
24
 
25
+ import { AgentCompletionSound } from "../AgentCompletionSound";
25
26
  import { Header } from "./Header";
26
27
  import { HeaderActionsProvider } from "./HeaderActions";
27
28
  import { MobileNav } from "./MobileNav";
@@ -138,7 +139,12 @@ function InteractiveLayout({ children }: LayoutProps) {
138
139
  }
139
140
 
140
141
  if (BARE_ROUTES.has(location.pathname)) {
141
- return <>{children}</>;
142
+ return (
143
+ <>
144
+ <AgentCompletionSound />
145
+ {children}
146
+ </>
147
+ );
142
148
  }
143
149
 
144
150
  const contentFrame = (
@@ -177,40 +183,43 @@ function InteractiveLayout({ children }: LayoutProps) {
177
183
  );
178
184
 
179
185
  return (
180
- <HeaderActionsProvider>
181
- <div className="agent-layout-shell flex h-screen w-full overflow-hidden bg-background text-foreground">
182
- <div className="agent-layout-left-drawer hidden shrink-0 md:block">
183
- <Sidebar />
184
- </div>
185
- {isAskRoute ? (
186
- <div className="agent-layout-main-surface flex min-w-0 flex-1 overflow-hidden">
187
- {contentFrame}
186
+ <>
187
+ <AgentCompletionSound />
188
+ <HeaderActionsProvider>
189
+ <div className="agent-layout-shell flex h-screen w-full overflow-hidden bg-background text-foreground">
190
+ <div className="agent-layout-left-drawer hidden shrink-0 md:block">
191
+ <Sidebar />
188
192
  </div>
189
- ) : (
190
- <AgentSidebar
191
- position="right"
192
- defaultOpen={false}
193
- chatViewTransition
194
- chatViewTransitionHandoff={chatHomeHandoffPending}
195
- storageKey={ANALYTICS_CHAT_STORAGE_KEY}
196
- browserTabId={TAB_ID}
197
- openOnChatRunning={chatHomeHandoffActive}
198
- onFullscreenRequest={openAskAgentFullscreen}
199
- emptyStateText={t("chat.emptyState")}
200
- agentPageHref="/agent"
201
- suggestions={[
202
- t("chat.suggestionArrGrowth"),
203
- t("chat.suggestionChurn"),
204
- t("chat.suggestionAnomalies"),
205
- t("chat.suggestionMrr"),
206
- ]}
207
- scope={analyticsScope}
208
- composerSlot={<CreativeContextComposerChip />}
209
- >
210
- {contentFrame}
211
- </AgentSidebar>
212
- )}
213
- </div>
214
- </HeaderActionsProvider>
193
+ {isAskRoute ? (
194
+ <div className="agent-layout-main-surface flex min-w-0 flex-1 overflow-hidden">
195
+ {contentFrame}
196
+ </div>
197
+ ) : (
198
+ <AgentSidebar
199
+ position="right"
200
+ defaultOpen={false}
201
+ chatViewTransition
202
+ chatViewTransitionHandoff={chatHomeHandoffPending}
203
+ storageKey={ANALYTICS_CHAT_STORAGE_KEY}
204
+ browserTabId={TAB_ID}
205
+ openOnChatRunning={chatHomeHandoffActive}
206
+ onFullscreenRequest={openAskAgentFullscreen}
207
+ emptyStateText={t("chat.emptyState")}
208
+ agentPageHref="/agent"
209
+ suggestions={[
210
+ t("chat.suggestionArrGrowth"),
211
+ t("chat.suggestionChurn"),
212
+ t("chat.suggestionAnomalies"),
213
+ t("chat.suggestionMrr"),
214
+ ]}
215
+ scope={analyticsScope}
216
+ composerSlot={<CreativeContextComposerChip />}
217
+ >
218
+ {contentFrame}
219
+ </AgentSidebar>
220
+ )}
221
+ </div>
222
+ </HeaderActionsProvider>
223
+ </>
215
224
  );
216
225
  }
@@ -198,6 +198,10 @@ const enUS = {
198
198
  errorEmailNotificationsDescription:
199
199
  "Send an email when a new JavaScript error is captured. Off by default.",
200
200
  errorEmailNotificationsSaveFailed: "Couldn't save the email preference.",
201
+ bellSound: "Bell sound",
202
+ bellSoundDescription:
203
+ "Play a sound when the agent finishes a run. Off by default.",
204
+ bellSoundSaveFailed: "Couldn't save the sound preference.",
201
205
  about: "About",
202
206
  aboutDescription:
203
207
  "Analytics is a tool for connecting data sources and building custom dashboards. Connect Google Analytics, BigQuery, Stripe, and more, then ask the agent to create dashboards.",
@@ -4261,6 +4265,9 @@ export const messagesByLocale = {
4261
4265
  errorEmailNotificationsDescription:
4262
4266
  "捕获新的 JavaScript 错误时发送电子邮件。默认关闭。",
4263
4267
  errorEmailNotificationsSaveFailed: "无法保存电子邮件偏好设置。",
4268
+ bellSound: "提示音",
4269
+ bellSoundDescription: "代理完成运行时播放提示音。默认关闭。",
4270
+ bellSoundSaveFailed: "无法保存提示音偏好设置。",
4264
4271
  about: "关于",
4265
4272
  aboutDescription:
4266
4273
  "Analytics 用于连接数据源并构建自定义仪表板。连接 Google Analytics、BigQuery、Stripe 等,然后让代理创建仪表板。",
@@ -4484,6 +4491,10 @@ export const messagesByLocale = {
4484
4491
  "Envía un email cuando se capture un nuevo error de JavaScript. Desactivado de forma predeterminada.",
4485
4492
  errorEmailNotificationsSaveFailed:
4486
4493
  "No se pudo guardar la preferencia de email.",
4494
+ bellSound: "Sonido de campana",
4495
+ bellSoundDescription:
4496
+ "Reproduce un sonido cuando el agente termina una ejecución. Desactivado de forma predeterminada.",
4497
+ bellSoundSaveFailed: "No se pudo guardar la preferencia de sonido.",
4487
4498
  about: "Acerca de",
4488
4499
  aboutDescription:
4489
4500
  "Analytics conecta fuentes de datos y crea paneles personalizados. Conecta Google Analytics, BigQuery, Stripe y más, y pide al agente que cree paneles.",
@@ -4712,6 +4723,10 @@ export const messagesByLocale = {
4712
4723
  "Envoyer un e-mail lorsqu’une nouvelle erreur JavaScript est capturée. Désactivé par défaut.",
4713
4724
  errorEmailNotificationsSaveFailed:
4714
4725
  "Impossible d’enregistrer la préférence e-mail.",
4726
+ bellSound: "Son de notification",
4727
+ bellSoundDescription:
4728
+ "Jouer un son lorsque l’agent termine une exécution. Désactivé par défaut.",
4729
+ bellSoundSaveFailed: "Impossible d’enregistrer la préférence sonore.",
4715
4730
  about: "À propos",
4716
4731
  aboutDescription:
4717
4732
  "Analytics connecte des sources de données et crée des tableaux de bord personnalisés. Connectez Google Analytics, BigQuery, Stripe et plus encore, puis demandez à l'agent de créer des tableaux de bord.",
@@ -4946,6 +4961,11 @@ export const messagesByLocale = {
4946
4961
  "Eine E-Mail senden, wenn ein neuer JavaScript-Fehler erfasst wird. Standardmäßig deaktiviert.",
4947
4962
  errorEmailNotificationsSaveFailed:
4948
4963
  "Die E-Mail-Einstellung konnte nicht gespeichert werden.",
4964
+ bellSound: "Signalton",
4965
+ bellSoundDescription:
4966
+ "Einen Ton abspielen, wenn der Agent einen Lauf beendet. Standardmäßig deaktiviert.",
4967
+ bellSoundSaveFailed:
4968
+ "Die Toneinstellung konnte nicht gespeichert werden.",
4949
4969
  about: "Info",
4950
4970
  aboutDescription:
4951
4971
  "Analytics verbindet Datenquellen und erstellt benutzerdefinierte Dashboards. Verbinde Google Analytics, BigQuery, Stripe und mehr und bitte den Agenten, Dashboards zu erstellen.",
@@ -5170,6 +5190,10 @@ export const messagesByLocale = {
5170
5190
  errorEmailNotificationsDescription:
5171
5191
  "新しい JavaScript エラーが記録されたときにメールを送信します。デフォルトではオフです。",
5172
5192
  errorEmailNotificationsSaveFailed: "メール設定を保存できませんでした。",
5193
+ bellSound: "完了サウンド",
5194
+ bellSoundDescription:
5195
+ "エージェントが実行を完了したときにサウンドを再生します。デフォルトでオフです。",
5196
+ bellSoundSaveFailed: "サウンド設定を保存できませんでした。",
5173
5197
  about: "概要",
5174
5198
  aboutDescription:
5175
5199
  "Analytics はデータソースを接続し、カスタムダッシュボードを作成するツールです。Google Analytics、BigQuery、Stripe などを接続し、エージェントにダッシュボード作成を依頼できます。",
@@ -5393,6 +5417,10 @@ export const messagesByLocale = {
5393
5417
  errorEmailNotificationsDescription:
5394
5418
  "새 JavaScript 오류가 캡처되면 이메일을 보냅니다. 기본값은 꺼져 있습니다.",
5395
5419
  errorEmailNotificationsSaveFailed: "이메일 설정을 저장하지 못했습니다.",
5420
+ bellSound: "완료 소리",
5421
+ bellSoundDescription:
5422
+ "에이전트가 실행을 완료하면 소리를 재생합니다. 기본값은 꺼짐입니다.",
5423
+ bellSoundSaveFailed: "소리 설정을 저장하지 못했습니다.",
5396
5424
  about: "정보",
5397
5425
  aboutDescription:
5398
5426
  "Analytics는 데이터 소스를 연결하고 사용자 지정 대시보드를 만드는 도구입니다. Google Analytics, BigQuery, Stripe 등을 연결한 뒤 에이전트에게 대시보드를 만들게 하세요.",
@@ -5621,6 +5649,10 @@ export const messagesByLocale = {
5621
5649
  "Envie um e-mail quando um novo erro de JavaScript for capturado. Desativado por padrão.",
5622
5650
  errorEmailNotificationsSaveFailed:
5623
5651
  "Não foi possível salvar a preferência de e-mail.",
5652
+ bellSound: "Som de conclusão",
5653
+ bellSoundDescription:
5654
+ "Reproduzir um som quando o agente concluir uma execução. Desativado por padrão.",
5655
+ bellSoundSaveFailed: "Não foi possível salvar a preferência de som.",
5624
5656
  about: "Sobre",
5625
5657
  aboutDescription:
5626
5658
  "Analytics conecta fontes de dados e cria dashboards personalizados. Conecte Google Analytics, BigQuery, Stripe e outros, depois peça ao agente para criar dashboards.",
@@ -5843,6 +5875,9 @@ export const messagesByLocale = {
5843
5875
  errorEmailNotificationsDescription:
5844
5876
  "नया JavaScript त्रुटि कैप्चर होने पर ईमेल भेजें। डिफ़ॉल्ट रूप से बंद।",
5845
5877
  errorEmailNotificationsSaveFailed: "ईमेल प्राथमिकता सहेजी नहीं जा सकी।",
5878
+ bellSound: "पूर्णता ध्वनि",
5879
+ bellSoundDescription: "एजेंट के रन पूरा करने पर ध्वनि चलाएं। डिफ़ॉल्ट रूप से बंद।",
5880
+ bellSoundSaveFailed: "ध्वनि प्राथमिकता सहेजी नहीं जा सकी।",
5846
5881
  about: "परिचय",
5847
5882
  aboutDescription:
5848
5883
  "Analytics डेटा स्रोतों को जोड़ने और कस्टम डैशबोर्ड बनाने का टूल है। Google Analytics, BigQuery, Stripe आदि जोड़ें, फिर एजेंट से डैशबोर्ड बनवाएं।",
@@ -6065,6 +6100,9 @@ export const messagesByLocale = {
6065
6100
  errorEmailNotificationsDescription:
6066
6101
  "إرسال بريد إلكتروني عند التقاط خطأ JavaScript جديد. معطّل افتراضيًا.",
6067
6102
  errorEmailNotificationsSaveFailed: "تعذّر حفظ تفضيل البريد الإلكتروني.",
6103
+ bellSound: "صوت الجرس",
6104
+ bellSoundDescription: "تشغيل صوت عند اكتمال تشغيل الوكيل. معطّل افتراضيًا.",
6105
+ bellSoundSaveFailed: "تعذّر حفظ تفضيل الصوت.",
6068
6106
  about: "حول",
6069
6107
  aboutDescription:
6070
6108
  "Analytics أداة لربط مصادر البيانات وبناء لوحات معلومات مخصصة. اربط Google Analytics وBigQuery وStripe وغيرها، ثم اطلب من الوكيل إنشاء اللوحات.",
@@ -54,18 +54,34 @@ export default function Settings() {
54
54
  const [errorEmailEnabledOverride, setErrorEmailEnabledOverride] = useState<
55
55
  boolean | null
56
56
  >(null);
57
+ const [bellSoundEnabledOverride, setBellSoundEnabledOverride] = useState<
58
+ boolean | null
59
+ >(null);
57
60
 
58
61
  useEffect(() => {
59
62
  if (analyticsPrefs) {
60
63
  setErrorEmailEnabledOverride(
61
64
  analyticsPrefs.errorEmailNotifications === true,
62
65
  );
66
+ setBellSoundEnabledOverride(analyticsPrefs.bellSoundEnabled === true);
63
67
  }
64
68
  }, [analyticsPrefs]);
65
69
 
66
70
  const errorEmailEnabled =
67
71
  errorEmailEnabledOverride ??
68
72
  analyticsPrefs?.errorEmailNotifications === true;
73
+ const bellSoundEnabled =
74
+ bellSoundEnabledOverride ?? analyticsPrefs?.bellSoundEnabled === true;
75
+
76
+ const currentAnalyticsPrefs: AnalyticsUserPrefs = {
77
+ ...(analyticsPrefs ?? {}),
78
+ ...(errorEmailEnabledOverride === null
79
+ ? {}
80
+ : { errorEmailNotifications: errorEmailEnabledOverride }),
81
+ ...(bellSoundEnabledOverride === null
82
+ ? {}
83
+ : { bellSoundEnabled: bellSoundEnabledOverride }),
84
+ };
69
85
 
70
86
  const saveErrorEmailPreference = (enabled: boolean) => {
71
87
  const previous = errorEmailEnabled;
@@ -73,7 +89,10 @@ export default function Settings() {
73
89
  void saveAnalyticsPrefs
74
90
  .mutateAsync({
75
91
  key: ANALYTICS_USER_PREFS_KEY,
76
- value: { errorEmailNotifications: enabled },
92
+ value: {
93
+ ...currentAnalyticsPrefs,
94
+ errorEmailNotifications: enabled,
95
+ },
77
96
  })
78
97
  .catch((error) => {
79
98
  setErrorEmailEnabledOverride(previous);
@@ -85,6 +104,24 @@ export default function Settings() {
85
104
  });
86
105
  };
87
106
 
107
+ const saveBellSoundPreference = (enabled: boolean) => {
108
+ const previous = bellSoundEnabled;
109
+ setBellSoundEnabledOverride(enabled);
110
+ void saveAnalyticsPrefs
111
+ .mutateAsync({
112
+ key: ANALYTICS_USER_PREFS_KEY,
113
+ value: { ...currentAnalyticsPrefs, bellSoundEnabled: enabled },
114
+ })
115
+ .catch((error) => {
116
+ setBellSoundEnabledOverride(previous);
117
+ toast.error(
118
+ error instanceof Error
119
+ ? error.message
120
+ : t("settings.bellSoundSaveFailed"),
121
+ );
122
+ });
123
+ };
124
+
88
125
  const extraTabs = useMemo<SettingsTabItem[]>(
89
126
  () => [
90
127
  {
@@ -170,6 +207,21 @@ export default function Settings() {
170
207
  />
171
208
  }
172
209
  />
210
+ <SettingsRow
211
+ id="bell-sound"
212
+ label={t("settings.bellSound")}
213
+ description={t("settings.bellSoundDescription")}
214
+ control={
215
+ <Switch
216
+ aria-label={t("settings.bellSound")}
217
+ checked={bellSoundEnabled}
218
+ disabled={
219
+ analyticsPrefsLoading || saveAnalyticsPrefs.isPending
220
+ }
221
+ onCheckedChange={saveBellSoundPreference}
222
+ />
223
+ }
224
+ />
173
225
  </SettingsGroup>
174
226
 
175
227
  {replayStorageStatus.data?.configured ? (
@@ -57,6 +57,12 @@ export function buildAnalyticsGeneralSettingsSearchEntries(
57
57
  keywords: "email notifications errors alerts javascript monitoring",
58
58
  hash: "error-email-notifications",
59
59
  },
60
+ {
61
+ id: "analytics-bell-sound",
62
+ label: t("settings.bellSound"),
63
+ keywords: "sound audio ding agent completion notification",
64
+ hash: "bell-sound",
65
+ },
60
66
  {
61
67
  id: "analytics-about",
62
68
  label: t("settings.about"),
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: added
3
+ date: 2026-08-04
4
+ ---
5
+
6
+ Choose whether Analytics plays a bell when the agent finishes a run
@@ -4,4 +4,6 @@ export const ANALYTICS_USER_PREFS_KEY = "analytics-user-prefs";
4
4
  export type AnalyticsUserPrefs = {
5
5
  /** New JavaScript error emails are opt-in. */
6
6
  errorEmailNotifications?: boolean;
7
+ /** Play the completion sound when an agent run finishes successfully. */
8
+ bellSoundEnabled?: boolean;
7
9
  };