@agent-native/core 0.141.5 → 0.141.7

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 (235) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/dashboard-management/SKILL.md +3 -14
  3. package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +20 -8
  4. package/corpus/templates/analytics/.agents/skills/prometheus/SKILL.md +5 -5
  5. package/corpus/templates/analytics/AGENTS.md +2 -2
  6. package/corpus/templates/analytics/actions/compose-dashboard.ts +1 -1
  7. package/corpus/templates/analytics/actions/get-first-party-analytics-health.ts +15 -1
  8. package/corpus/templates/analytics/actions/migrate-first-party-analytics-to-bigquery.ts +135 -0
  9. package/corpus/templates/analytics/actions/navigate.ts +1 -1
  10. package/corpus/templates/analytics/actions/query-agent-native-analytics.ts +2 -2
  11. package/corpus/templates/analytics/actions/update-dashboard.ts +0 -1
  12. package/corpus/templates/analytics/actions/view-screen.ts +0 -20
  13. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  14. package/corpus/templates/analytics/app/hooks/use-navigation-state.ts +5 -5
  15. package/corpus/templates/analytics/app/i18n-data.ts +330 -90
  16. package/corpus/templates/analytics/app/pages/Agents.tsx +0 -3
  17. package/corpus/templates/analytics/app/pages/DataSources.tsx +66 -30
  18. package/corpus/templates/analytics/app/pages/Settings.tsx +22 -43
  19. package/corpus/templates/analytics/app/pages/settings/settings-search.ts +23 -20
  20. package/corpus/templates/analytics/app/routes/extensions._index.tsx +1 -1
  21. package/corpus/templates/analytics/app/routes/settings.$.tsx +1 -0
  22. package/corpus/templates/analytics/app/routes/team.tsx +1 -1
  23. package/corpus/templates/analytics/changelog/2026-08-05-historical-analytics-rollups-now-repair-automatically-after-.md +6 -0
  24. package/corpus/templates/analytics/changelog/2026-08-05-settings-no-longer-includes-an-unnecessary-about-section.md +6 -0
  25. package/corpus/templates/analytics/docs/schemas/first-party-analytics.md +1 -1
  26. package/corpus/templates/analytics/netlify.toml +4 -0
  27. package/corpus/templates/analytics/scripts/emit-netlify-dashboard-report-cron.ts +109 -0
  28. package/corpus/templates/analytics/scripts/first-party-analytics-bigquery.sql +104 -0
  29. package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +342 -0
  30. package/corpus/templates/analytics/server/lib/agent-chat-plan-mode.ts +0 -2
  31. package/corpus/templates/analytics/server/lib/analytics-rollup-lock.ts +8 -0
  32. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +11 -29
  33. package/corpus/templates/analytics/server/lib/dashboards-store.ts +55 -0
  34. package/corpus/templates/analytics/server/lib/first-party-analytics-backend.ts +1058 -0
  35. package/corpus/templates/analytics/server/lib/first-party-analytics-health.ts +151 -46
  36. package/corpus/templates/analytics/server/lib/first-party-analytics-rollups.ts +15 -9
  37. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +59 -17
  38. package/corpus/templates/analytics/server/lib/real-data-actions.ts +1 -3
  39. package/corpus/templates/analytics/server/plugins/agent-chat.ts +2 -4
  40. package/corpus/templates/analytics/server/plugins/analytics-rollup-backfill-jobs.ts +61 -0
  41. package/corpus/templates/analytics/server/plugins/db.ts +58 -187
  42. package/corpus/templates/analytics/server/routes/api/analytics-rollups/backfill.post.ts +53 -0
  43. package/corpus/templates/assets/.agents/skills/asset-generation/SKILL.md +8 -6
  44. package/corpus/templates/assets/.agents/skills/library-management/SKILL.md +16 -1
  45. package/corpus/templates/assets/AGENTS.md +1 -0
  46. package/corpus/templates/assets/actions/_helpers.ts +12 -0
  47. package/corpus/templates/assets/actions/generate-image.ts +9 -3
  48. package/corpus/templates/assets/actions/import-style-from-url.ts +115 -0
  49. package/corpus/templates/assets/app/hooks/use-navigation-state.ts +3 -1
  50. package/corpus/templates/assets/app/routes/extensions._index.tsx +1 -1
  51. package/corpus/templates/assets/app/routes/settings.$.tsx +1 -0
  52. package/corpus/templates/assets/app/routes/settings.tsx +5 -0
  53. package/corpus/templates/assets/app/routes/team.tsx +1 -1
  54. package/corpus/templates/assets/changelog/2026-08-05-brand-kits-can-import-a-website-s-hydrated-visual-language-a.md +6 -0
  55. package/corpus/templates/assets/changelog/2026-08-05-generated-images-now-hand-off-embeddable-previews-to-other-w.md +6 -0
  56. package/corpus/templates/assets/server/lib/generation.ts +58 -0
  57. package/corpus/templates/assets/shared/api.ts +12 -0
  58. package/corpus/templates/brain/app/routes/extensions._index.tsx +1 -1
  59. package/corpus/templates/brain/app/routes/team.tsx +1 -1
  60. package/corpus/templates/brain/app/routes.ts +1 -1
  61. package/corpus/templates/calendar/app/components/layout/AppLayout.tsx +3 -1
  62. package/corpus/templates/calendar/app/routes/_app.extensions._index.tsx +1 -1
  63. package/corpus/templates/calendar/app/routes/_app.settings.$.tsx +1 -0
  64. package/corpus/templates/calendar/app/routes/_app.team.tsx +1 -1
  65. package/corpus/templates/chat/app/components/layout/Layout.tsx +1 -1
  66. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  67. package/corpus/templates/chat/app/root.tsx +1 -1
  68. package/corpus/templates/chat/app/routes/agent.tsx +7 -7
  69. package/corpus/templates/chat/app/routes/extensions._index.tsx +1 -1
  70. package/corpus/templates/chat/app/routes/settings.$.tsx +1 -0
  71. package/corpus/templates/chat/app/routes/team.tsx +1 -1
  72. package/corpus/templates/clips/app/components/library/library-layout.tsx +1 -1
  73. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +1 -1
  74. package/corpus/templates/clips/app/components/recorder/storage-setup-card.tsx +1 -1
  75. package/corpus/templates/clips/app/routes/_app.extensions._index.tsx +1 -1
  76. package/corpus/templates/clips/app/routes/_app.settings.$.tsx +1 -0
  77. package/corpus/templates/clips/changelog/2026-08-05-clips-overlays-now-use-clean-surfaces-without-clipped-shadow.md +6 -0
  78. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +2 -2
  79. package/corpus/templates/clips/desktop/src/styles.css +3 -54
  80. package/corpus/templates/clips/desktop/src-tauri/src/notifications.rs +3 -3
  81. package/corpus/templates/content/app/routes/_app.extensions._index.tsx +1 -1
  82. package/corpus/templates/content/app/routes/_app.settings.$.tsx +1 -0
  83. package/corpus/templates/content/app/routes/_app.team.tsx +1 -1
  84. package/corpus/templates/content/e2e/global-setup.ts +1 -1
  85. package/corpus/templates/design/.agents/skills/design-systems/SKILL.md +6 -1
  86. package/corpus/templates/design/actions/analyze-brand-assets.ts +7 -7
  87. package/corpus/templates/design/actions/get-design-system.ts +3 -1
  88. package/corpus/templates/design/actions/import-from-url.ts +6 -5
  89. package/corpus/templates/design/app/pages/DesignSystemSetup.tsx +2 -2
  90. package/corpus/templates/design/app/routes/extensions._index.tsx +1 -1
  91. package/corpus/templates/design/app/routes/settings.$.tsx +1 -0
  92. package/corpus/templates/design/app/routes/team.tsx +1 -1
  93. package/corpus/templates/design/changelog/2026-08-05-missing-design-systems-now-return-a-clear-not-found-response.md +6 -0
  94. package/corpus/templates/design/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-de.md +6 -0
  95. package/corpus/templates/design/e2e/global-setup.ts +1 -1
  96. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +1 -1
  97. package/corpus/templates/dispatch/app/routes/settings.$.tsx +1 -0
  98. package/corpus/templates/dispatch/app/routes/team.tsx +1 -1
  99. package/corpus/templates/factory/app/hooks/use-navigation-state.ts +1 -1
  100. package/corpus/templates/factory/app/routes/extensions._index.tsx +1 -1
  101. package/corpus/templates/factory/app/routes/settings.$.tsx +1 -0
  102. package/corpus/templates/factory/app/routes/team.tsx +1 -1
  103. package/corpus/templates/forms/app/routes/_app.extensions._index.tsx +1 -1
  104. package/corpus/templates/forms/app/routes/_app.settings.$.tsx +1 -0
  105. package/corpus/templates/forms/app/routes/_app.team.tsx +1 -1
  106. package/corpus/templates/forms/shared/navigation.ts +1 -1
  107. package/corpus/templates/macros/app/routes/extensions._index.tsx +1 -1
  108. package/corpus/templates/macros/app/routes/settings.$.tsx +1 -0
  109. package/corpus/templates/macros/app/routes/team.tsx +1 -1
  110. package/corpus/templates/mail/app/routes/extensions._index.tsx +1 -1
  111. package/corpus/templates/mail/app/routes/settings.$.tsx +1 -0
  112. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +1 -1
  113. package/corpus/templates/plan/app/routes/extensions._index.tsx +1 -1
  114. package/corpus/templates/plan/app/routes/settings.$.tsx +1 -0
  115. package/corpus/templates/plan/app/routes/team.tsx +1 -1
  116. package/corpus/templates/slides/.agents/skills/design-systems/SKILL.md +3 -1
  117. package/corpus/templates/slides/actions/analyze-brand-assets.ts +7 -7
  118. package/corpus/templates/slides/actions/import-from-url.ts +6 -6
  119. package/corpus/templates/slides/app/components/deck/DeckCard.tsx +2 -2
  120. package/corpus/templates/slides/app/components/design-system/DesignSystemSetup.tsx +1 -1
  121. package/corpus/templates/slides/app/components/editor/PromptDialog.tsx +3 -0
  122. package/corpus/templates/slides/app/components/editor/SlideEditor.tsx +1 -1
  123. package/corpus/templates/slides/app/components/onboarding/FirstDeckOnboardingFlow.tsx +9 -3
  124. package/corpus/templates/slides/app/context/DeckContext.tsx +71 -20
  125. package/corpus/templates/slides/app/global.css +6 -0
  126. package/corpus/templates/slides/app/i18n/en-US.ts +5 -5
  127. package/corpus/templates/slides/app/lib/create-deck-generation.ts +9 -5
  128. package/corpus/templates/slides/app/pages/DeckEditor.tsx +17 -0
  129. package/corpus/templates/slides/app/pages/Index.tsx +16 -5
  130. package/corpus/templates/slides/app/routes/extensions._index.tsx +1 -1
  131. package/corpus/templates/slides/app/routes/settings.$.tsx +1 -0
  132. package/corpus/templates/slides/app/routes/team.tsx +1 -1
  133. package/corpus/templates/slides/changelog/2026-08-05-failed-deck-creation-and-reference-uploads-now-recover-clean.md +6 -0
  134. package/corpus/templates/slides/changelog/2026-08-05-new-presentation-prompts-now-clearly-describe-presentation-g.md +6 -0
  135. package/corpus/templates/slides/changelog/2026-08-05-slides-recover-completed-generation-results-after-a-sync-hic.md +6 -0
  136. package/corpus/templates/slides/changelog/2026-08-05-website-url-imports-now-capture-hydrated-browser-computed-st.md +6 -0
  137. package/corpus/templates/tasks/app/components/layout/Header.tsx +3 -1
  138. package/corpus/templates/tasks/app/routes/extensions._index.tsx +1 -1
  139. package/corpus/templates/tasks/app/routes/settings.$.tsx +1 -0
  140. package/dist/agent/engine/ai-sdk-engine.js +49 -3
  141. package/dist/agent/production-agent.d.ts +1 -0
  142. package/dist/agent/production-agent.js +8 -0
  143. package/dist/agent/types.d.ts +7 -0
  144. package/dist/client/AssistantChat.js +1 -1
  145. package/dist/client/agent-chat-adapter.d.ts +1 -1
  146. package/dist/client/agent-chat-adapter.js +30 -3
  147. package/dist/client/agent-page/AgentWorkspaceContent.d.ts +1 -1
  148. package/dist/client/agent-page/AgentWorkspaceContent.js +13 -13
  149. package/dist/client/chat/run-recovery.d.ts +2 -1
  150. package/dist/client/chat/run-recovery.js +14 -3
  151. package/dist/client/embed-auth.js +6 -2
  152. package/dist/client/error-format.d.ts +1 -0
  153. package/dist/client/error-format.js +16 -2
  154. package/dist/client/integrations/IntegrationsPanel.js +40 -6
  155. package/dist/client/org/OrgSwitcher.js +2 -2
  156. package/dist/client/org/TeamPage.js +92 -72
  157. package/dist/client/require-session.d.ts +1 -1
  158. package/dist/client/require-session.js +3 -3
  159. package/dist/client/resources/use-mcp-servers.d.ts +5 -0
  160. package/dist/client/resources/use-mcp-servers.js +36 -0
  161. package/dist/client/settings/AccountSettingsCard.js +40 -35
  162. package/dist/client/settings/AutomationsSection.js +1 -1
  163. package/dist/client/settings/DemoModeSection.d.ts +3 -1
  164. package/dist/client/settings/DemoModeSection.js +4 -1
  165. package/dist/client/settings/ExtensionsSettingsContent.js +1 -1
  166. package/dist/client/settings/SchedulingTimezoneField.d.ts +3 -1
  167. package/dist/client/settings/SchedulingTimezoneField.js +9 -5
  168. package/dist/client/settings/SettingsPanel.d.ts +4 -1
  169. package/dist/client/settings/SettingsPanel.js +21 -21
  170. package/dist/client/settings/SettingsTabsPage.d.ts +2 -2
  171. package/dist/client/settings/SettingsTabsPage.js +98 -45
  172. package/dist/client/settings/VoiceTranscriptionSection.js +6 -1
  173. package/dist/client/settings/useSettingsPanelController.js +47 -8
  174. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  175. package/dist/ingestion/website.d.ts +30 -0
  176. package/dist/localization/default-messages.d.ts +5 -0
  177. package/dist/localization/default-messages.js +5 -0
  178. package/dist/mcp-client/oauth-routes.js +1 -1
  179. package/dist/mcp-client/routes.d.ts +1 -0
  180. package/dist/mcp-client/routes.js +49 -0
  181. package/dist/navigation/index.js +16 -5
  182. package/dist/observability/routes.d.ts +3 -3
  183. package/dist/provider-api/actions/custom-provider-registration.d.ts +13 -13
  184. package/dist/provider-api/actions/provider-api.d.ts +11 -11
  185. package/dist/scripts/call-agent.js +11 -0
  186. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  187. package/dist/server/auth.js +9 -7
  188. package/dist/server/identity-sso.js +2 -1
  189. package/dist/server/onboarding-html.js +57 -34
  190. package/dist/server/realtime-token.d.ts +1 -1
  191. package/dist/server/transcribe-voice.d.ts +1 -1
  192. package/dist/server/workspace-provider-oauth.js +1 -1
  193. package/dist/setup-connections/onboarding.js +1 -1
  194. package/dist/shared/index.d.ts +1 -1
  195. package/dist/shared/index.js +1 -1
  196. package/dist/shared/sign-in-journey.d.ts +5 -2
  197. package/dist/shared/sign-in-journey.js +10 -4
  198. package/dist/templates/chat/app/components/layout/Layout.tsx +1 -1
  199. package/dist/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  200. package/dist/templates/chat/app/root.tsx +1 -1
  201. package/dist/templates/chat/app/routes/agent.tsx +7 -7
  202. package/dist/templates/chat/app/routes/extensions._index.tsx +1 -1
  203. package/dist/templates/chat/app/routes/settings.$.tsx +1 -0
  204. package/dist/templates/chat/app/routes/team.tsx +1 -1
  205. package/dist/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  206. package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  207. package/docs/content/authentication.mdx +4 -5
  208. package/docs/content/template-analytics-developers.mdx +1 -1
  209. package/docs/content/template-calendar-developers.mdx +1 -1
  210. package/docs/content/template-chat-developers.mdx +2 -2
  211. package/docs/content/template-content-developers.mdx +1 -1
  212. package/docs/content/template-mail-developers.mdx +1 -1
  213. package/docs/content/template-plan-developers.mdx +1 -1
  214. package/docs/content/toolkit-command-navigation.mdx +6 -6
  215. package/docs/content/toolkit-org-team.mdx +1 -1
  216. package/docs/content/toolkit-settings.mdx +8 -8
  217. package/docs/content/toolkit-setup-connections.mdx +1 -1
  218. package/package.json +1 -1
  219. package/src/templates/chat/app/components/layout/Layout.tsx +1 -1
  220. package/src/templates/chat/app/hooks/use-navigation-state.ts +1 -1
  221. package/src/templates/chat/app/root.tsx +1 -1
  222. package/src/templates/chat/app/routes/agent.tsx +7 -7
  223. package/src/templates/chat/app/routes/extensions._index.tsx +1 -1
  224. package/src/templates/chat/app/routes/settings.$.tsx +1 -0
  225. package/src/templates/chat/app/routes/team.tsx +1 -1
  226. package/src/templates/workspace-core/.agents/skills/address-feedback/SKILL.md +37 -6
  227. package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +4 -2
  228. package/corpus/templates/analytics/.agents/skills/dashboard-management/references/template-catalog-and-demo.md +0 -62
  229. package/corpus/templates/analytics/actions/install-dashboard-template.ts +0 -369
  230. package/corpus/templates/analytics/actions/list-dashboard-templates.ts +0 -47
  231. package/corpus/templates/analytics/actions/list-native-v2-dashboard-templates.ts +0 -34
  232. package/corpus/templates/analytics/app/routes/catalog.tsx +0 -240
  233. package/corpus/templates/analytics/changelog/2026-08-05-historical-analytics-rollups-stay-complete-and-atomic.md +0 -6
  234. package/corpus/templates/analytics/changelog/2026-08-05-historical-rollups-stay-complete-while-live-events-arrive.md +0 -6
  235. package/src/templates/default/actions/navigate.spec.ts +0 -53
@@ -1,13 +1,15 @@
1
- import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { ActionButton, Avatar, Surface, TextField, } from "@agent-native/toolkit/design-system";
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ActionButton, Avatar, TextField, } from "@agent-native/toolkit/design-system";
3
3
  import { IconCamera, IconCheck, IconLock } from "@tabler/icons-react";
4
4
  import { useEffect, useRef, useState } from "react";
5
+ import { Popover, PopoverContent, PopoverTrigger, } from "../components/ui/popover.js";
5
6
  import { useT } from "../i18n.js";
6
7
  import { useActionMutation, useActionQuery } from "../use-action.js";
7
8
  import { uploadAvatar, useAvatarUrl } from "../use-avatar.js";
8
9
  import { useSession } from "../use-session.js";
9
10
  import { cn } from "../utils.js";
10
11
  import { SchedulingTimezoneField } from "./SchedulingTimezoneField.js";
12
+ import { SettingsGroup, SettingsRow } from "./SettingsRow.js";
11
13
  function profileInitials(name) {
12
14
  return (name
13
15
  .split(/[ @._-]+/)
@@ -71,29 +73,30 @@ function PasswordSettings() {
71
73
  const hasPassword = authMethods.data?.hasPassword ?? false;
72
74
  if (!session?.email)
73
75
  return null;
74
- return (_jsxs("div", { className: "space-y-3 border-t border-border/60 pt-3", children: [_jsxs("div", { className: "flex items-start gap-2", children: [_jsx(IconLock, { className: "mt-0.5 size-4 text-muted-foreground" }), _jsxs("div", { children: [_jsx("h3", { className: "text-sm font-medium", children: hasPassword
75
- ? t("settings.passwordChange")
76
- : t("settings.passwordTitle") }), _jsx("p", { className: "text-xs leading-5 text-muted-foreground", children: t("settings.passwordDescription") })] })] }), isLoading ? (_jsx("p", { className: "text-xs text-muted-foreground", children: t("settings.passwordStatusLoading") })) : authMethods.error ? (_jsx("p", { className: "text-xs text-destructive", children: t("settings.passwordSaveError") })) : (_jsxs(_Fragment, { children: [hasPassword && (_jsx(TextField, { id: "agent-native-current-password", type: "password", label: t("settings.passwordCurrentLabel"), value: currentPassword, onChange: (value) => {
77
- clearStatus();
78
- setCurrentPassword(value);
79
- }, placeholder: t("settings.passwordPlaceholder"), autoComplete: "current-password", disabled: isPending })), _jsx(TextField, { id: "agent-native-new-password", type: "password", label: t("settings.passwordNewLabel"), value: newPassword, onChange: (value) => {
80
- clearStatus();
81
- setNewPassword(value);
82
- }, placeholder: t("settings.passwordPlaceholder"), autoComplete: hasPassword ? "new-password" : "new-password", disabled: isPending, invalid: !!error }), _jsx(TextField, { id: "agent-native-confirm-password", type: "password", label: t("settings.passwordConfirmLabel"), value: confirmPassword, onChange: (value) => {
83
- clearStatus();
84
- setConfirmPassword(value);
85
- }, placeholder: t("settings.passwordPlaceholder"), autoComplete: "new-password", disabled: isPending, invalid: !!error, errorMessage: error }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("div", { className: "min-h-4 text-xs", children: saved && (_jsxs("p", { className: "flex items-center gap-1 text-primary", children: [_jsx(IconCheck, { className: "size-3" }), t("settings.passwordSaved")] })) }), _jsx(ActionButton, { type: "button", intent: "primary", emphasis: "solid", size: "compact", pending: isPending, disabled: isPending ||
86
- !newPassword ||
87
- !confirmPassword ||
88
- (hasPassword && !currentPassword), onPress: submit, children: isPending
89
- ? t("settings.passwordSaving")
90
- : hasPassword
91
- ? t("settings.passwordChange")
92
- : t("settings.passwordAdd") })] })] }))] }));
76
+ const passwordForm = isLoading ? (_jsx("p", { className: "text-xs text-muted-foreground", children: t("settings.passwordStatusLoading") })) : authMethods.error ? (_jsx("p", { className: "text-xs text-destructive", children: t("settings.passwordSaveError") })) : (_jsxs("div", { className: "space-y-3", children: [hasPassword && (_jsx(TextField, { id: "agent-native-current-password", type: "password", label: t("settings.passwordCurrentLabel"), value: currentPassword, onChange: (value) => {
77
+ clearStatus();
78
+ setCurrentPassword(value);
79
+ }, placeholder: t("settings.passwordPlaceholder"), autoComplete: "current-password", disabled: isPending })), _jsx(TextField, { id: "agent-native-new-password", type: "password", label: t("settings.passwordNewLabel"), value: newPassword, onChange: (value) => {
80
+ clearStatus();
81
+ setNewPassword(value);
82
+ }, placeholder: t("settings.passwordPlaceholder"), autoComplete: "new-password", disabled: isPending, invalid: !!error }), _jsx(TextField, { id: "agent-native-confirm-password", type: "password", label: t("settings.passwordConfirmLabel"), value: confirmPassword, onChange: (value) => {
83
+ clearStatus();
84
+ setConfirmPassword(value);
85
+ }, placeholder: t("settings.passwordPlaceholder"), autoComplete: "new-password", disabled: isPending, invalid: !!error, errorMessage: error }), _jsxs("div", { className: "flex items-center justify-between gap-3", children: [_jsx("div", { className: "min-h-4 text-xs", children: saved && (_jsxs("p", { className: "flex items-center gap-1 text-primary", children: [_jsx(IconCheck, { className: "size-3" }), t("settings.passwordSaved")] })) }), _jsx(ActionButton, { type: "button", intent: "primary", emphasis: "solid", size: "compact", pending: isPending, disabled: isPending ||
86
+ !newPassword ||
87
+ !confirmPassword ||
88
+ (hasPassword && !currentPassword), onPress: submit, children: isPending
89
+ ? t("settings.passwordSaving")
90
+ : hasPassword
91
+ ? t("settings.passwordChange")
92
+ : t("settings.passwordAdd") })] })] }));
93
+ return (_jsx(SettingsRow, { id: "password", label: _jsxs("span", { className: "flex items-center gap-2", children: [_jsx(IconLock, { className: "size-4 text-muted-foreground" }), hasPassword
94
+ ? t("settings.passwordChange")
95
+ : t("settings.passwordTitle")] }), description: t("settings.passwordDescription"), control: _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(ActionButton, { type: "button", intent: "neutral", emphasis: "outline", size: "compact", children: "Manage" }) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: "w-[min(420px,calc(100vw-2rem))] p-4", children: passwordForm })] }) }));
93
96
  }
94
97
  export function AccountSettingsForm({ compact = false, }) {
95
98
  const t = useT();
96
- const { session, isLoading } = useSession();
99
+ const { session } = useSession();
97
100
  const email = session?.email;
98
101
  const profileQuery = useActionQuery("get-user-profile", undefined, { enabled: !!email });
99
102
  const updateProfile = useActionMutation("update-user-profile");
@@ -135,19 +138,21 @@ export function AccountSettingsForm({ compact = false, }) {
135
138
  return;
136
139
  updateProfile.mutate({ name: nextName });
137
140
  };
138
- return (_jsxs("div", { className: cn("space-y-4", compact && "space-y-3"), children: [_jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Avatar, { name: displayName, src: avatarUrl, fallback: profileInitials(displayName), size: compact ? "default" : "large", className: cn("shrink-0 rounded-full border border-border bg-accent font-semibold text-muted-foreground", compact ? "size-12 text-[13px]" : "size-14 text-[15px]") }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsx("p", { className: cn("truncate font-medium", compact ? "text-xs" : "text-sm"), children: isLoading ? t("settings.profileLoading") : displayName }), email && (_jsx("p", { className: "truncate text-xs text-muted-foreground", children: email })), photoStatus === "saved" && (_jsxs("p", { className: "mt-1 flex items-center gap-1 text-xs text-green-600 dark:text-green-400", children: [_jsx(IconCheck, { className: "size-3" }), t("settings.profilePhotoUpdated")] })), photoStatus === "error" && (_jsx("p", { className: "mt-1 text-xs text-destructive", children: t("settings.profilePhotoError") }))] }), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", className: "hidden", onChange: handleAvatarChange }), _jsx(ActionButton, { type: "button", intent: "neutral", emphasis: "outline", size: "compact", disabled: !email || uploading, leadingIcon: _jsx(IconCamera, { className: "size-3.5" }), onPress: () => fileInputRef.current?.click(), className: "shrink-0", children: uploading
139
- ? t("settings.profileUploading")
140
- : t("settings.profileChangePhoto") })] }), _jsx("div", { className: "space-y-3", children: _jsx(TextField, { id: "agent-native-profile-name", label: t("settings.profileNameLabel"), value: name, onChange: (value) => {
141
- updateProfile.reset();
142
- setName(value);
143
- }, placeholder: t("settings.profileNamePlaceholder"), description: t("settings.profileNameDescription"), disabled: !email || profileQuery.isLoading || updateProfile.isPending }) }), _jsx("div", { className: "border-t border-border/60 pt-3", children: _jsx(SchedulingTimezoneField, {}) }), _jsxs("div", { className: "flex items-center justify-between gap-3 border-t border-border/60 pt-3", children: [_jsxs("div", { className: "min-h-4 text-xs", children: [updateProfile.isSuccess && (_jsx("p", { className: "text-primary", children: t("settings.profileSaved") })), updateProfile.error && (_jsx("p", { className: "text-destructive", children: t("settings.profileSaveError") }))] }), _jsx(ActionButton, { type: "button", intent: "primary", emphasis: "solid", size: "compact", pending: updateProfile.isPending, disabled: !email ||
144
- profileQuery.isLoading ||
145
- updateProfile.isPending ||
146
- !name.trim(), onPress: handleProfileSave, children: updateProfile.isPending
147
- ? t("settings.profileSaving")
148
- : t("settings.profileSave") })] })] }));
141
+ const profileStatus = photoStatus === "saved" ? (_jsx("span", { className: "text-primary", children: t("settings.profilePhotoUpdated") })) : photoStatus === "error" ? (_jsx("span", { className: "text-destructive", children: t("settings.profilePhotoError") })) : email ? (email) : undefined;
142
+ return (_jsxs(SettingsGroup, { id: "account", title: t("settings.profileTitle"), description: t("settings.profileDescription"), className: cn(compact && "[&>div:last-child>div>div]:py-3"), children: [_jsx(SettingsRow, { id: "profile", label: t("settings.profileTitle"), description: profileStatus, control: _jsxs("div", { className: "flex items-center gap-3", children: [_jsx(Avatar, { name: displayName, src: avatarUrl, fallback: profileInitials(displayName), size: "default", className: "size-10 shrink-0 rounded-full border border-border bg-accent font-semibold text-muted-foreground" }), _jsx("input", { ref: fileInputRef, type: "file", accept: "image/*", className: "hidden", onChange: handleAvatarChange }), _jsx(ActionButton, { type: "button", intent: "neutral", emphasis: "outline", size: "compact", disabled: !email || uploading, leadingIcon: _jsx(IconCamera, { className: "size-3.5" }), onPress: () => fileInputRef.current?.click(), children: uploading
143
+ ? t("settings.profileUploading")
144
+ : t("settings.profileChangePhoto") })] }) }), _jsx(SettingsRow, { id: "profile-name", label: t("settings.profileNameLabel"), description: updateProfile.isSuccess ? (_jsx("span", { className: "text-primary", children: t("settings.profileSaved") })) : updateProfile.error ? (_jsx("span", { className: "text-destructive", children: t("settings.profileSaveError") })) : (t("settings.profileNameDescription")), control: _jsxs("div", { className: "flex w-full items-center gap-2 sm:w-80", children: [_jsx(TextField, { id: "agent-native-profile-name", value: name, onChange: (value) => {
145
+ updateProfile.reset();
146
+ setName(value);
147
+ }, placeholder: t("settings.profileNamePlaceholder"), disabled: !email || profileQuery.isLoading || updateProfile.isPending, "aria-label": t("settings.profileNameLabel"), className: "min-w-0 flex-1" }), _jsx(ActionButton, { type: "button", intent: "primary", emphasis: "solid", size: "compact", pending: updateProfile.isPending, disabled: !email ||
148
+ profileQuery.isLoading ||
149
+ updateProfile.isPending ||
150
+ !name.trim(), onPress: handleProfileSave, children: updateProfile.isPending
151
+ ? t("settings.profileSaving")
152
+ : t("settings.profileSave") })] }) }), _jsx(SettingsRow, { id: "timezone", label: t("settings.timezoneLabel", { defaultValue: "Timezone" }), description: t("settings.timezoneHint", {
153
+ defaultValue: "Used for timestamps and scheduled automations.",
154
+ }), control: _jsx(SchedulingTimezoneField, { compact: true }) }), _jsx(PasswordSettings, {})] }));
149
155
  }
150
156
  export function AccountSettingsCard({ className }) {
151
- const t = useT();
152
- return (_jsxs(Surface, { as: "section", id: "account", elevation: "low", padding: "none", className: cn("mx-auto w-full max-w-2xl scroll-mt-4 rounded-lg border border-border bg-card p-5 text-card-foreground shadow-sm", className), children: [_jsxs("div", { className: "space-y-1", children: [_jsx("h2", { className: "text-base font-semibold", children: t("settings.profileTitle") }), _jsx("p", { className: "text-sm leading-6 text-muted-foreground", children: t("settings.profileDescription") })] }), _jsxs("div", { className: "mt-5", children: [_jsx(AccountSettingsForm, {}), _jsx(PasswordSettings, {})] })] }));
157
+ return (_jsx("div", { className: cn("w-full", className), children: _jsx(AccountSettingsForm, {}) }));
153
158
  }
@@ -11,7 +11,7 @@ export function AutomationsSection() {
11
11
  const t = useT();
12
12
  return (_jsxs("div", { className: "space-y-3", children: [_jsx("p", { className: "text-xs leading-5 text-muted-foreground", children: t("jobs.settingsSummary", {
13
13
  defaultValue: "Manage scheduled and event-triggered agent tasks together from the Automations page.",
14
- }) }), _jsxs("div", { className: "flex flex-wrap gap-2 text-[11px] text-muted-foreground", children: [_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-1", children: [_jsx(IconClock, { className: "size-3" }), t("jobs.scheduledTrigger", { defaultValue: "Scheduled" })] }), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-1", children: [_jsx(IconBolt, { className: "size-3" }), t("jobs.eventTrigger", { defaultValue: "Event-triggered" })] })] }), _jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsxs(Link, { to: "/settings#agent:automations", children: [t("jobs.openAutomations", {
14
+ }) }), _jsxs("div", { className: "flex flex-wrap gap-2 text-[11px] text-muted-foreground", children: [_jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-1", children: [_jsx(IconClock, { className: "size-3" }), t("jobs.scheduledTrigger", { defaultValue: "Scheduled" })] }), _jsxs("span", { className: "inline-flex items-center gap-1 rounded-full bg-muted px-2 py-1", children: [_jsx(IconBolt, { className: "size-3" }), t("jobs.eventTrigger", { defaultValue: "Event-triggered" })] })] }), _jsx(Button, { asChild: true, variant: "outline", size: "sm", children: _jsxs(Link, { to: "/settings/agent/automations", children: [t("jobs.openAutomations", {
15
15
  defaultValue: "Open Automations",
16
16
  }), _jsx(IconArrowRight, { className: "size-3.5" })] }) })] }));
17
17
  }
@@ -1,2 +1,4 @@
1
1
  /** Browser-local presentation toggle. Backend and agent results stay real. */
2
- export declare function DemoModeSection(): import("react").JSX.Element;
2
+ export declare function DemoModeSection({ compact }: {
3
+ compact?: boolean;
4
+ }): import("react").JSX.Element;
@@ -3,7 +3,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Switch } from "@agent-native/toolkit/design-system";
4
4
  import { setBrowserDemoModeEnabled } from "../../demo/browser-state.js";
5
5
  import { useDemoModeStatus } from "../use-demo-mode-status.js";
6
- export function DemoModeSection() {
6
+ export function DemoModeSection({ compact = false }) {
7
7
  const { enabled } = useDemoModeStatus();
8
+ if (compact) {
9
+ return (_jsx(Switch, { checked: enabled, onChange: (checked) => setBrowserDemoModeEnabled(checked), "aria-label": "Enable demo mode", className: "shrink-0" }));
10
+ }
8
11
  return (_jsxs("div", { className: "flex items-start justify-between gap-3 rounded-md border border-border bg-accent/30 px-2.5 py-2", children: [_jsxs("div", { className: "min-w-0", children: [_jsx("div", { className: "text-[11px] font-medium text-foreground", children: "Enable demo mode" }), _jsx("p", { className: "text-[10px] text-muted-foreground mt-0.5", children: "Anonymize displayed emails in this browser and reshape supported dashboard charts for presentations. Backend, agent integrations, and agent results stay real and access-scoped." })] }), _jsx(Switch, { checked: enabled, onChange: (checked) => setBrowserDemoModeEnabled(checked), "aria-label": "Enable demo mode", className: "shrink-0" })] }));
9
12
  }
@@ -5,5 +5,5 @@ const ExtensionsListPage = lazy(() => import("../extensions/ExtensionsListPage.j
5
5
  default: module.ExtensionsListPage,
6
6
  })));
7
7
  export function ExtensionsSettingsContent() {
8
- return (_jsx("div", { className: "mx-auto w-full max-w-5xl", children: _jsx(Suspense, { fallback: _jsx("div", { className: "flex min-h-[28rem] items-center justify-center text-muted-foreground", children: _jsx(IconLoader2, { className: "size-5 animate-spin", "aria-label": "Loading" }) }), children: _jsx(ExtensionsListPage, { embedded: true }) }) }));
8
+ return (_jsx("div", { className: "w-full", children: _jsx(Suspense, { fallback: _jsx("div", { className: "flex min-h-[28rem] items-center justify-center text-muted-foreground", children: _jsx(IconLoader2, { className: "size-5 animate-spin", "aria-label": "Loading" }) }), children: _jsx(ExtensionsListPage, { embedded: true }) }) }));
9
9
  }
@@ -6,4 +6,6 @@
6
6
  * browser at all (cron ticks, chat integrations, A2A), and those callers would
7
7
  * otherwise fall back to the host zone and schedule the user's 8am job in UTC.
8
8
  */
9
- export declare function SchedulingTimezoneField(): import("react").JSX.Element;
9
+ export declare function SchedulingTimezoneField({ compact, }: {
10
+ compact?: boolean;
11
+ }): import("react").JSX.Element;
@@ -11,7 +11,7 @@ const SYSTEM = "system";
11
11
  * browser at all (cron ticks, chat integrations, A2A), and those callers would
12
12
  * otherwise fall back to the host zone and schedule the user's 8am job in UTC.
13
13
  */
14
- export function SchedulingTimezoneField() {
14
+ export function SchedulingTimezoneField({ compact = false, }) {
15
15
  const t = useT();
16
16
  const detected = browserTimezone();
17
17
  const preference = useActionQuery("get-localization-preference");
@@ -20,10 +20,14 @@ export function SchedulingTimezoneField() {
20
20
  const stored = preference.data?.timezone ?? SYSTEM;
21
21
  const pending = save.isPending ? save.variables?.timezone : undefined;
22
22
  const value = pending ?? stored;
23
- return (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", htmlFor: "agent-native-scheduling-timezone", children: t("settings.timezoneLabel", { defaultValue: "Timezone" }) }), _jsx(TimezoneSelect, { id: "agent-native-scheduling-timezone", value: value, disabled: preference.isLoading || save.isPending, suggested: [detected], systemLabel: t("settings.timezoneSystem", {
24
- defaultValue: "Follow this browser ({{zone}})",
25
- zone: detected,
26
- }), onChange: (timezone) => save.mutate({ timezone }) }), _jsx("p", { className: "min-h-4 text-xs text-muted-foreground", children: save.error ? (_jsx("span", { className: "text-destructive", children: save.error.message })) : (t("settings.timezoneHint", {
23
+ const select = (_jsx(TimezoneSelect, { id: "agent-native-scheduling-timezone", value: value, disabled: preference.isLoading || save.isPending, suggested: [detected], systemLabel: t("settings.timezoneSystem", {
24
+ defaultValue: "Follow this browser ({{zone}})",
25
+ zone: detected,
26
+ }), onChange: (timezone) => save.mutate({ timezone }) }));
27
+ if (compact) {
28
+ return (_jsxs("div", { className: "w-full sm:w-72", children: [select, save.error && (_jsx("p", { className: "mt-1 text-xs text-destructive", children: save.error.message }))] }));
29
+ }
30
+ return (_jsxs("div", { className: "space-y-2", children: [_jsx("label", { className: "text-sm font-medium", htmlFor: "agent-native-scheduling-timezone", children: t("settings.timezoneLabel", { defaultValue: "Timezone" }) }), select, _jsx("p", { className: "min-h-4 text-xs text-muted-foreground", children: save.error ? (_jsx("span", { className: "text-destructive", children: save.error.message })) : (t("settings.timezoneHint", {
27
31
  defaultValue: "Used for timestamps and scheduled automations.",
28
32
  })) })] }));
29
33
  }
@@ -24,14 +24,17 @@ export interface AgentSettingsTabsOptions {
24
24
  * app capability and stay hidden unless the host opts in.
25
25
  */
26
26
  extensionTools?: boolean;
27
+ /** Optional page-level settings to show in the Agent section. */
28
+ agentAdditionalContent?: React.ReactNode;
27
29
  }
28
30
  export declare function areExtensionSettingsEnabled(options?: AgentSettingsTabsOptions): boolean;
29
31
  export declare function SettingsPanel(props: SettingsPanelProps): React.JSX.Element;
30
32
  export declare function ConnectionsSettingsContent({ settingsPanelProps, }: {
31
33
  settingsPanelProps: SettingsPanelProps;
32
34
  }): React.JSX.Element;
33
- export declare function AgentSettingsContent({ className, sections, }?: {
35
+ export declare function AgentSettingsContent({ className, sections, agentAdditionalContent, }?: {
34
36
  className?: string;
35
37
  sections?: readonly SettingsSectionId[];
38
+ agentAdditionalContent?: React.ReactNode;
36
39
  }): React.JSX.Element;
37
40
  export declare function useAgentSettingsTabs(options?: AgentSettingsTabsOptions): SettingsTabItem[];
@@ -2,9 +2,10 @@ import { Fragment as _Fragment, jsx as _jsx, jsxs as _jsxs } from "react/jsx-run
2
2
  import { Checkbox, Picker, TextField, } from "@agent-native/toolkit/design-system";
3
3
  import { Button as ToolkitButton } from "@agent-native/toolkit/ui/button";
4
4
  import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, } from "@agent-native/toolkit/ui/command";
5
- import { IconChevronDown, IconChevronRight, IconCheck, IconExternalLink, IconBrain, IconHierarchy2, IconBrowser, IconGitBranch, IconCloud, IconDatabase, IconFolder, IconShield, IconShieldLock, IconPlugConnected, IconTopologyRing2, IconLoader2, IconUpload, IconCoin, IconMail, IconKey, IconMicrophone, IconEyeOff, IconBolt, IconGauge, IconApps, IconUsersGroup, IconTool, } from "@tabler/icons-react";
5
+ import { IconChevronDown, IconChevronRight, IconCheck, IconExternalLink, IconBrain, IconHierarchy2, IconBrowser, IconGitBranch, IconCloud, IconDatabase, IconFolder, IconShield, IconPlugConnected, IconTopologyRing2, IconLoader2, IconUpload, IconCoin, IconMail, IconKey, IconMicrophone, IconEyeOff, IconBolt, IconGauge, IconApps, IconUsersGroup, IconTool, } from "@tabler/icons-react";
6
6
  import React, { Suspense, lazy, useState, useEffect, useCallback, useMemo, useRef, } from "react";
7
7
  import { PROVIDER_ENV_PLACEHOLDERS } from "../../agent/engine/provider-env-vars.js";
8
+ import { buildSettingsRoute } from "../../navigation/index.js";
8
9
  import { saveAgentEngineProviderSettings } from "../agent-engine-key.js";
9
10
  import { AgentWorkspaceContent } from "../agent-page/AgentWorkspaceContent.js";
10
11
  import { agentNativePath } from "../api-path.js";
@@ -40,6 +41,9 @@ const IntegrationsPanel = lazy(() => import("../integrations/IntegrationsPanel.j
40
41
  function SettingsSkeleton({ lines = 3 }) {
41
42
  return (_jsx("div", { className: "space-y-3 animate-pulse", children: Array.from({ length: lines }, (_, i) => (_jsxs("div", { className: "space-y-1.5", children: [_jsx("div", { className: "h-3 rounded bg-muted-foreground/10", style: { width: i === 0 ? "30%" : i === 1 ? "100%" : "60%" } }), i < 2 && (_jsx("div", { className: "h-9 rounded-md border border-border bg-muted-foreground/5" }))] }, i))) }));
42
43
  }
44
+ function SettingsLoadingRow({ label, description, controlCount = 1, }) {
45
+ return (_jsxs("div", { className: "flex items-center justify-between gap-4 px-5 py-4 sm:px-6", children: [_jsxs("div", { className: "min-w-0 space-y-2", children: [_jsx("div", { className: "text-sm font-medium text-foreground", children: label }), description ? (_jsx("p", { className: "text-sm leading-5 text-muted-foreground", children: description })) : null] }), _jsx("div", { className: "flex shrink-0 items-center gap-2", "aria-hidden": "true", children: Array.from({ length: controlCount }, (_, index) => (_jsx("div", { className: cn("h-9 animate-pulse rounded-md border border-border bg-muted-foreground/10", index === 0 ? "w-28" : "w-20") }, index))) })] }));
46
+ }
43
47
  const CONTROL_STYLE = {
44
48
  fontSize: 12,
45
49
  lineHeight: 1,
@@ -549,7 +553,7 @@ function LLMSectionInner({ builderFlow, builderLoading, connectUrl, connected, o
549
553
  }
550
554
  catch { }
551
555
  };
552
- return (_jsx(SettingsSection, { id: settingsSectionDomId("llm"), icon: _jsx(IconBrain, { size: 14 }), title: "LLM", subtitle: "Use Builder.io free credits or your own LLM provider.", required: true, connected: initialLoading ? undefined : anyKeyConfigured, grouped: isPage && grouped, open: open, onToggle: onToggle, children: initialLoading ? (_jsx("div", { className: cn(isPage && "px-5 py-4 sm:px-6"), children: _jsx(SettingsSkeleton, { lines: 3 }) })) : (_jsxs("div", { className: cn(isPage
556
+ return (_jsx(SettingsSection, { id: settingsSectionDomId("llm"), icon: _jsx(IconBrain, { size: 14 }), title: "LLM", subtitle: "Use Builder.io free credits or your own LLM provider.", required: true, connected: initialLoading ? undefined : anyKeyConfigured, grouped: isPage && grouped, open: open, onToggle: onToggle, children: initialLoading ? (_jsx(SettingsLoadingRow, { label: "Connect an LLM", description: "Use Builder.io free credits or your own provider.", controlCount: 2 })) : (_jsxs("div", { className: cn(isPage
553
557
  ? "flex items-center justify-between gap-4 px-5 py-4 sm:px-6"
554
558
  : "space-y-2"), children: [isPage && (_jsxs("div", { className: "min-w-0", children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Connect an LLM" }), _jsx("p", { className: "mt-1 text-sm leading-6 text-muted-foreground", children: "Use Builder.io free credits or your own provider." })] })), _jsxs("div", { className: cn(isPage && "flex flex-wrap items-center justify-end gap-2"), children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "llm_settings", trackingFlow: "connect_llm", label: "Connect Builder.io", compact: isPage }), builderConnected && !isPage && (_jsxs(Button, { type: "button", intent: "neutral", emphasis: "ghost", "aria-expanded": manualSetupOpen, "aria-controls": "llm-manual-setup", onClick: () => setManualSetupOpen((open) => !open), className: cn("inline-flex items-center gap-1 px-0.5 text-muted-foreground hover:text-foreground", isPage ? "text-xs" : "text-[10px]"), children: [t("agentPanel.addOwnKeys", {
555
559
  defaultValue: "Add your own keys",
@@ -600,8 +604,10 @@ function AppDefaultModelPicker({ engines, value, disabled, onChange, }) {
600
604
  : "Global default";
601
605
  const openIntegrations = () => {
602
606
  setOpen(false);
603
- if (typeof window !== "undefined")
604
- window.location.hash = "integrations";
607
+ if (typeof window !== "undefined") {
608
+ window.history.pushState(null, "", buildSettingsRoute("integrations"));
609
+ window.dispatchEvent(new Event("popstate"));
610
+ }
605
611
  };
606
612
  return (_jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { asChild: true, children: _jsxs(Button, { type: "button", disabled: disabled, "aria-label": "Default model", className: "inline-flex h-10 min-w-[230px] max-w-[320px] items-center justify-between gap-3 rounded-md border border-border bg-background px-3 text-start text-sm text-foreground transition-colors hover:bg-accent/40 disabled:cursor-not-allowed disabled:opacity-60", children: [_jsx("span", { className: "truncate", children: selectedLabel }), _jsx(IconChevronDown, { size: 15, className: "shrink-0 text-muted-foreground" })] }) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: "w-[min(380px,calc(100vw-2rem))] p-0", children: _jsxs(Command, { filter: (candidate, search) => candidate.toLowerCase().includes(search.toLowerCase()) ? 1 : 0, children: [_jsx(CommandInput, { placeholder: "Search providers or models..." }), _jsxs(CommandList, { className: "max-h-[min(420px,calc(100vh-8rem))]", children: [_jsx(CommandEmpty, { children: "No models found." }), _jsx(CommandGroup, { heading: "Default", children: _jsxs(CommandItem, { value: "global default shared llm", onSelect: () => {
607
613
  onChange("__global__");
@@ -758,7 +764,7 @@ function AppModelDefaultsSectionInner({ grouped = false, open, onToggle, }) {
758
764
  setSaving(false);
759
765
  }
760
766
  };
761
- return (_jsx(SettingsSection, { id: settingsSectionDomId("app-models"), icon: _jsx(IconApps, { size: 14 }), title: "App Default Model", subtitle: "Choose the model used by this app by default.", connected: loading ? undefined : hasAppDefault, grouped: isPage && grouped, open: open, onToggle: onToggle, children: loading ? (_jsx(SettingsSkeleton, { lines: 2 })) : settings ? (isPage ? (_jsxs(SettingsRow, { className: grouped ? undefined : "-mx-5 sm:-mx-6", label: "Default model", description: hasAppDefault
767
+ return (_jsx(SettingsSection, { id: settingsSectionDomId("app-models"), icon: _jsx(IconApps, { size: 14 }), title: "App Default Model", subtitle: "Choose the model used by this app by default.", connected: loading ? undefined : hasAppDefault, grouped: isPage && grouped, open: open, onToggle: onToggle, children: loading ? (_jsx(SettingsLoadingRow, { label: "Default model", description: "Choose the model used by this app by default." })) : settings ? (isPage ? (_jsxs(SettingsRow, { className: grouped ? undefined : "-mx-5 sm:-mx-6", label: "Default model", description: hasAppDefault
762
768
  ? `Used by ${friendlyAppName(settings.appId) || "this app"} · ${scopeLabel}.`
763
769
  : "Uses the global LLM default.", status: _jsx("span", { className: "text-xs text-muted-foreground", children: settings.source }), control: _jsx(AppDefaultModelPicker, { engines: settings.engines, value: hasAppDefault
764
770
  ? `${selectedEngine}::${selectedModel}`
@@ -981,7 +987,7 @@ function AgentLimitsSectionInner({ grouped = false, open, onToggle, }) {
981
987
  ? undefined
982
988
  : settings
983
989
  ? settings.maxIterations !== settings.defaultMaxIterations
984
- : false, grouped: isPage && grouped, open: open, onToggle: onToggle, children: loading ? (_jsx(SettingsSkeleton, { lines: 2 })) : settings ? (isPage ? (_jsx(SettingsRow, { className: grouped ? undefined : "-mx-5 sm:-mx-6", label: "Max iterations", description: `Default ${settings.defaultMaxIterations.toLocaleString()} · applies to ${scopeLabel}.`, status: _jsx("span", { className: "text-xs text-muted-foreground", children: settings.source }), control: _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(ManageButton, {}) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: "w-80 p-4", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Max iterations" }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Choose how long a response can work before pausing." })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("input", { type: "number", min: settings.minMaxIterations, max: settings.maxMaxIterations, value: value, disabled: !settings.canUpdate || saving, onChange: (event) => {
990
+ : false, grouped: isPage && grouped, open: open, onToggle: onToggle, children: loading ? (_jsx(SettingsLoadingRow, { label: "Max iterations", description: "Set how long a response can work before pausing." })) : settings ? (isPage ? (_jsx(SettingsRow, { className: grouped ? undefined : "-mx-5 sm:-mx-6", label: "Max iterations", description: `Default ${settings.defaultMaxIterations.toLocaleString()} · applies to ${scopeLabel}.`, status: _jsx("span", { className: "text-xs text-muted-foreground", children: settings.source }), control: _jsxs(Popover, { children: [_jsx(PopoverTrigger, { asChild: true, children: _jsx(ManageButton, {}) }), _jsx(PopoverContent, { align: "end", sideOffset: 6, className: "w-80 p-4", children: _jsxs("div", { className: "space-y-3", children: [_jsxs("div", { children: [_jsx("p", { className: "text-sm font-medium text-foreground", children: "Max iterations" }), _jsx("p", { className: "mt-1 text-xs text-muted-foreground", children: "Choose how long a response can work before pausing." })] }), _jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("input", { type: "number", min: settings.minMaxIterations, max: settings.maxMaxIterations, value: value, disabled: !settings.canUpdate || saving, onChange: (event) => {
985
991
  setValue(event.target.value);
986
992
  setError(null);
987
993
  }, onKeyDown: (event) => {
@@ -1016,7 +1022,7 @@ function CapabilityStatusStrip({ isDevMode, builderConnected, builderLoading, bu
1016
1022
  : "Desktop/local";
1017
1023
  return (_jsxs("div", { className: "rounded-md border border-border bg-muted/20 px-2.5 py-2", children: [_jsx("div", { className: "mb-1.5 text-[10px] font-medium text-muted-foreground", children: "Available now" }), _jsxs("div", { className: "space-y-1.5", children: [_jsx(CapabilityStatusRow, { label: "App", value: "Chat + actions", active: true }), _jsx(CapabilityStatusRow, { label: "Code", value: codeLabel, active: codeAvailable }), _jsx(CapabilityStatusRow, { label: "Builder", active: builderConnected, value: builderLoading ? ("Checking...") : builderConnected ? ("Connected") : (_jsx(Button, { type: "button", intent: "neutral", emphasis: "outline", onClick: onOpenLlm, className: "rounded border border-border px-1.5 py-0.5 text-[10px] text-muted-foreground transition-colors hover:bg-accent/40 hover:text-foreground", children: "Connect" })) })] })] }));
1018
1024
  }
1019
- function SettingsPanelContent({ isDevMode, initialSection, sectionRequestKey, sections = ALL_SETTINGS_SECTIONS, showCapabilityStrip = true, className, surface = "sidebar", builderConnectionOwnedExternally = false, }) {
1025
+ function SettingsPanelContent({ isDevMode, initialSection, sectionRequestKey, sections = ALL_SETTINGS_SECTIONS, showCapabilityStrip = true, className, surface = "sidebar", builderConnectionOwnedExternally = false, agentAdditionalContent, }) {
1020
1026
  const { status: builder, loading: builderLoading } = useBuilderStatus({
1021
1027
  enabled: !builderConnectionOwnedExternally,
1022
1028
  });
@@ -1047,9 +1053,10 @@ function SettingsPanelContent({ isDevMode, initialSection, sectionRequestKey, se
1047
1053
  });
1048
1054
  const openSettingsSection = useCallback((section, scroll = false) => openControllerSection(section, { scroll }), [openControllerSection]);
1049
1055
  const isPage = surface === "page";
1056
+ const isWorkspacePage = isPage && sections.includes("hosting");
1050
1057
  return (_jsx(SettingsSurfaceProvider, { surface: surface, children: _jsxs("div", { className: cn(isPage ? "space-y-8" : "flex-1 min-h-0 overflow-y-auto p-3 space-y-2", className), style: isPage ? undefined : { overflowY: "auto" }, children: [showCapabilityStrip && (_jsx(CapabilityStatusStrip, { isDevMode: isDevMode, builderConnected: connected, builderLoading: builderLoading, builderBranchesAvailable: builderBranchesAvailable, onOpenLlm: () => openSettingsSection("llm", true) })), isPage &&
1051
- ["llm", "app-models", "limits", "voice"].some((section) => shouldShowSection(section)) && (_jsxs(SettingsGroup, { title: "Agent", children: [shouldShowSection("llm") && (_jsx(LLMSectionInner, { builderFlow: builderFlow, builderLoading: builderLoading, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, grouped: true, open: openSection === "llm", onToggle: () => toggle("llm") })), shouldShowSection("app-models") && (_jsx(AppModelDefaultsSectionInner, { grouped: true, open: openSection === "app-models", onToggle: () => toggle("app-models") })), shouldShowSection("limits") && (_jsx(AgentLimitsSectionInner, { grouped: true, open: openSection === "limits", onToggle: () => toggle("limits") })), shouldShowSection("voice") && (_jsx(SettingsSection, { id: settingsSectionDomId("voice"), icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "Choose how voice input is transcribed.", grouped: true, flat: true, open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, { compact: true }) }))] })), isPage &&
1052
- ["automations", "background"].some((section) => shouldShowSection(section)) && (_jsxs(SettingsGroup, { title: "Agent workflows", children: [shouldShowSection("automations") && (_jsx(SettingsSection, { id: settingsSectionDomId("automations"), icon: _jsx(IconBolt, { size: 14 }), title: "Automations", subtitle: "Scheduled and event-triggered agent tasks.", grouped: true, flat: true, open: openSection === "automations", onToggle: () => toggle("automations"), children: _jsx(SettingsRow, { label: "Automations", description: "Schedule agent tasks or run them from events.", control: _jsxs("a", { href: "/settings#agent:automations", className: "inline-flex items-center gap-1 rounded-md border border-border px-3 py-1.5 text-sm font-medium text-foreground no-underline transition-colors hover:bg-accent/40", children: ["Open automations", _jsx(IconExternalLink, { size: 14 })] }) }) })), shouldShowSection("background") && (_jsx(SettingsSection, { id: settingsSectionDomId("background"), icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", grouped: true, flat: true, connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(SettingsRow, { label: "Background agent", description: "Make code changes from production mode via Builder.", control: _jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "background_agent_settings", trackingFlow: "background_agent", compact: true }) }) }))] })), !isPage && shouldShowSection("llm") && (_jsx(LLMSectionInner, { builderFlow: builderFlow, builderLoading: builderLoading, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, open: openSection === "llm", onToggle: () => toggle("llm") })), !isPage && shouldShowSection("app-models") && (_jsx(AppModelDefaultsSectionInner, { open: openSection === "app-models", onToggle: () => toggle("app-models") })), !isPage && shouldShowSection("limits") && (_jsx(AgentLimitsSectionInner, { open: openSection === "limits", onToggle: () => toggle("limits") })), !isPage && shouldShowSection("voice") && (_jsx(SettingsSection, { id: settingsSectionDomId("voice"), icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "How the composer microphone turns your voice into text.", flat: true, open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, {}) })), shouldShowSection("demo-mode") && (_jsx(SettingsSection, { id: settingsSectionDomId("demo-mode"), icon: _jsx(IconEyeOff, { size: 14 }), title: "Demo mode", subtitle: "Replace displayed emails with realistic fake data in this browser and reshape supported charts for presentations. Backend, agent integrations, and agent results stay real and access-scoped.", flat: true, open: openSection === "demo-mode", onToggle: () => toggle("demo-mode"), children: _jsx(DemoModeSection, {}) })), !isPage && shouldShowSection("automations") && (_jsx(SettingsSection, { id: settingsSectionDomId("automations"), icon: _jsx(IconBolt, { size: 14 }), title: "Automations", subtitle: "Scheduled and event-triggered agent tasks.", flat: true, open: openSection === "automations", onToggle: () => toggle("automations"), children: _jsx(AutomationsSection, {}) })), shouldShowSection("secrets") && (_jsx(SettingsSection, { id: settingsSectionDomId("secrets"), icon: _jsx(IconKey, { size: 14 }), title: "API keys", subtitle: "Service credentials and automation keys.", flat: true, open: openSection === "secrets", onToggle: () => toggle("secrets"), children: _jsx(SecretsSection, { focusKey: focusSecretKey }) })), shouldShowSection("hosting") && (_jsx(SettingsSection, { id: settingsSectionDomId("hosting"), icon: _jsx(IconCloud, { size: 14 }), title: "Hosting", subtitle: "Deploy your app to the cloud.", flat: true, connected: connected, open: openSection === "hosting", onToggle: () => toggle("hosting"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "hosting_settings", trackingFlow: "hosting" }), _jsx(ManualSetupCard, { hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=deployment_settings", dim: connected })] }) })), shouldShowSection("database") && (_jsx(SettingsSection, { id: settingsSectionDomId("database"), icon: _jsx(IconDatabase, { size: 14 }), title: "Database", subtitle: "Connect a cloud database for persistent storage.", flat: true, connected: connected, open: openSection === "database", onToggle: () => toggle("database"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "database_settings", trackingFlow: "database" }), _jsx(ManualSetupCard, { hint: "Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite.", docsUrl: "https://www.builder.io/c/docs/agent-native-database?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=database_settings", dim: connected })] }) })), shouldShowSection("uploads") && (_jsx(SettingsSection, { id: settingsSectionDomId("uploads"), icon: _jsx(IconUpload, { size: 14 }), title: "File uploads", subtitle: "Where user-uploaded files (avatars, chat attachments) are stored.", flat: true, connected: connected, open: openSection === "uploads", onToggle: () => toggle("uploads"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "file_upload_settings", trackingFlow: "file_upload" }), _jsx(ManualSetupCard, { hint: "Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=file_upload_settings", dim: connected })] }) })), shouldShowSection("auth") && (_jsx(SettingsSection, { id: settingsSectionDomId("auth"), icon: _jsx(IconShield, { size: 14 }), title: "Authentication", subtitle: "Set up user authentication and access control.", flat: true, connected: connected, open: openSection === "auth", onToggle: () => toggle("auth"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "auth_settings", trackingFlow: "auth" }), _jsx(ManualSetupCard, { hint: "Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=authentication_settings", dim: connected })] }) })), shouldShowSection("email") && (_jsx(EmailSectionInner, { open: openSection === "email", onToggle: () => toggle("email") })), shouldShowSection("browser") && (_jsx(SettingsSection, { id: settingsSectionDomId("browser"), icon: _jsx(IconBrowser, { size: 14 }), title: "Browser Automation", subtitle: "Let agents control a real browser for web tasks.", flat: true, connected: builderConnectionOwnedExternally ? undefined : connected, open: openSection === "browser", onToggle: () => toggle("browser"), children: !builderConnectionOwnedExternally ? (_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "browser_settings", trackingFlow: "browser_automation" })) : null })), !isPage &&
1058
+ ["llm", "app-models", "limits", "voice"].some((section) => shouldShowSection(section)) && (_jsxs(SettingsGroup, { title: "Agent", children: [shouldShowSection("llm") && (_jsx(LLMSectionInner, { builderFlow: builderFlow, builderLoading: builderLoading, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, grouped: true, open: openSection === "llm", onToggle: () => toggle("llm") })), shouldShowSection("app-models") && (_jsx(AppModelDefaultsSectionInner, { grouped: true, open: openSection === "app-models", onToggle: () => toggle("app-models") })), shouldShowSection("limits") && (_jsx(AgentLimitsSectionInner, { grouped: true, open: openSection === "limits", onToggle: () => toggle("limits") })), shouldShowSection("voice") && (_jsx(SettingsSection, { id: settingsSectionDomId("voice"), icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "Choose how voice input is transcribed.", grouped: true, flat: true, open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, { compact: true }) }))] })), isPage && agentAdditionalContent ? (_jsx(SettingsGroup, { title: "Notifications", children: agentAdditionalContent })) : null, isPage &&
1059
+ ["automations", "background"].some((section) => shouldShowSection(section)) && (_jsxs(SettingsGroup, { title: "Agent workflows", children: [shouldShowSection("automations") && (_jsx(SettingsSection, { id: settingsSectionDomId("automations"), icon: _jsx(IconBolt, { size: 14 }), title: "Automations", subtitle: "Scheduled and event-triggered agent tasks.", grouped: true, flat: true, open: openSection === "automations", onToggle: () => toggle("automations"), children: _jsx(SettingsRow, { label: "Automations", description: "Schedule agent tasks or run them from events.", control: _jsxs("a", { href: "/settings/agent/automations", className: "inline-flex items-center gap-1 rounded-md border border-border px-3 py-1.5 text-sm font-medium text-foreground no-underline transition-colors hover:bg-accent/40", children: ["Open automations", _jsx(IconExternalLink, { size: 14 })] }) }) })), shouldShowSection("background") && (_jsx(SettingsSection, { id: settingsSectionDomId("background"), icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", grouped: true, flat: true, connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(SettingsRow, { label: "Background agent", description: "Make code changes from production mode via Builder.", control: _jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "background_agent_settings", trackingFlow: "background_agent", compact: true }) }) }))] })), isWorkspacePage && (_jsxs(SettingsGroup, { title: "Workspace", children: [shouldShowSection("demo-mode") && (_jsx(SettingsRow, { id: settingsSectionDomId("demo-mode"), label: "Demo mode", description: "Use sample data in this browser for presentations.", control: _jsx(DemoModeSection, { compact: true }) })), shouldShowSection("hosting") && (_jsx(SettingsRow, { id: settingsSectionDomId("hosting"), label: "Hosting", description: "Deploy the app to the cloud.", control: _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "hosting_settings", trackingFlow: "hosting", compact: true }), _jsx(ManualSetupCard, { title: "Set up manually", hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=deployment_settings", dim: connected, bare: true, popover: true, popoverLabel: "Manage" })] }) })), shouldShowSection("database") && (_jsx(SettingsRow, { id: settingsSectionDomId("database"), label: "Database", description: "Connect persistent app storage.", control: _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "database_settings", trackingFlow: "database", compact: true }), _jsx(ManualSetupCard, { title: "Set up manually", hint: "Set DATABASE_URL in your .env to connect a supported database.", docsUrl: "https://www.builder.io/c/docs/agent-native-database?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=database_settings", dim: connected, bare: true, popover: true, popoverLabel: "Manage" })] }) })), shouldShowSection("uploads") && (_jsx(SettingsRow, { id: settingsSectionDomId("uploads"), label: "File uploads", description: "Store avatars and chat attachments.", control: _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "file_upload_settings", trackingFlow: "file_upload", compact: true }), _jsx(ManualSetupCard, { title: "Set up manually", hint: "Configure your own file or object storage provider.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=file_upload_settings", dim: connected, bare: true, popover: true, popoverLabel: "Manage" })] }) })), shouldShowSection("auth") && (_jsx(SettingsRow, { id: settingsSectionDomId("auth"), label: "Authentication", description: "Set up sign-in and access control.", control: _jsxs("div", { className: "flex flex-wrap items-center justify-end gap-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "auth_settings", trackingFlow: "auth", compact: true }), _jsx(ManualSetupCard, { title: "Set up manually", hint: "Configure Better Auth and optional Google or GitHub providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=authentication_settings", dim: connected, bare: true, popover: true, popoverLabel: "Manage" })] }) }))] })), !isPage && shouldShowSection("llm") && (_jsx(LLMSectionInner, { builderFlow: builderFlow, builderLoading: builderLoading, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, open: openSection === "llm", onToggle: () => toggle("llm") })), !isPage && shouldShowSection("app-models") && (_jsx(AppModelDefaultsSectionInner, { open: openSection === "app-models", onToggle: () => toggle("app-models") })), !isPage && shouldShowSection("limits") && (_jsx(AgentLimitsSectionInner, { open: openSection === "limits", onToggle: () => toggle("limits") })), !isPage && shouldShowSection("voice") && (_jsx(SettingsSection, { id: settingsSectionDomId("voice"), icon: _jsx(IconMicrophone, { size: 14 }), title: "Voice Transcription", subtitle: "How the composer microphone turns your voice into text.", flat: true, open: openSection === "voice", onToggle: () => toggle("voice"), children: _jsx(VoiceTranscriptionSection, {}) })), !isPage && shouldShowSection("demo-mode") && (_jsx(SettingsSection, { id: settingsSectionDomId("demo-mode"), icon: _jsx(IconEyeOff, { size: 14 }), title: "Demo mode", subtitle: "Replace displayed emails with realistic fake data in this browser and reshape supported charts for presentations. Backend, agent integrations, and agent results stay real and access-scoped.", flat: true, open: openSection === "demo-mode", onToggle: () => toggle("demo-mode"), children: _jsx(DemoModeSection, {}) })), !isPage && shouldShowSection("automations") && (_jsx(SettingsSection, { id: settingsSectionDomId("automations"), icon: _jsx(IconBolt, { size: 14 }), title: "Automations", subtitle: "Scheduled and event-triggered agent tasks.", flat: true, open: openSection === "automations", onToggle: () => toggle("automations"), children: _jsx(AutomationsSection, {}) })), shouldShowSection("secrets") && (_jsx(SettingsSection, { id: settingsSectionDomId("secrets"), icon: _jsx(IconKey, { size: 14 }), title: "API keys", subtitle: "Service credentials and automation keys.", flat: true, open: openSection === "secrets", onToggle: () => toggle("secrets"), children: _jsx(SecretsSection, { focusKey: focusSecretKey }) })), !isPage && shouldShowSection("hosting") && (_jsx(SettingsSection, { id: settingsSectionDomId("hosting"), icon: _jsx(IconCloud, { size: 14 }), title: "Hosting", subtitle: "Deploy your app to the cloud.", flat: true, connected: connected, open: openSection === "hosting", onToggle: () => toggle("hosting"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "hosting_settings", trackingFlow: "hosting" }), _jsx(ManualSetupCard, { hint: "Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target.", docsUrl: "https://www.builder.io/c/docs/agent-native-deployment?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=deployment_settings", dim: connected })] }) })), !isPage && shouldShowSection("database") && (_jsx(SettingsSection, { id: settingsSectionDomId("database"), icon: _jsx(IconDatabase, { size: 14 }), title: "Database", subtitle: "Connect a cloud database for persistent storage.", flat: true, connected: connected, open: openSection === "database", onToggle: () => toggle("database"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "database_settings", trackingFlow: "database" }), _jsx(ManualSetupCard, { hint: "Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite.", docsUrl: "https://www.builder.io/c/docs/agent-native-database?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=database_settings", dim: connected })] }) })), !isPage && shouldShowSection("uploads") && (_jsx(SettingsSection, { id: settingsSectionDomId("uploads"), icon: _jsx(IconUpload, { size: 14 }), title: "File uploads", subtitle: "Where user-uploaded files (avatars, chat attachments) are stored.", flat: true, connected: connected, open: openSection === "uploads", onToggle: () => toggle("uploads"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "file_upload_settings", trackingFlow: "file_upload" }), _jsx(ManualSetupCard, { hint: "Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production.", docsUrl: "https://www.builder.io/c/docs/agent-native-file-uploads?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=file_upload_settings", dim: connected })] }) })), !isPage && shouldShowSection("auth") && (_jsx(SettingsSection, { id: settingsSectionDomId("auth"), icon: _jsx(IconShield, { size: 14 }), title: "Authentication", subtitle: "Set up user authentication and access control.", flat: true, connected: connected, open: openSection === "auth", onToggle: () => toggle("auth"), children: _jsxs("div", { className: "space-y-2", children: [_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "auth_settings", trackingFlow: "auth" }), _jsx(ManualSetupCard, { hint: "Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers.", docsUrl: "https://www.builder.io/c/docs/agent-native-authentication?utm_source=agent-native&utm_medium=product&utm_campaign=onboarding&utm_content=authentication_settings", dim: connected })] }) })), shouldShowSection("email") && (_jsx(EmailSectionInner, { open: openSection === "email", onToggle: () => toggle("email") })), shouldShowSection("browser") && (_jsx(SettingsSection, { id: settingsSectionDomId("browser"), icon: _jsx(IconBrowser, { size: 14 }), title: "Browser Automation", subtitle: "Let agents control a real browser for web tasks.", flat: true, connected: builderConnectionOwnedExternally ? undefined : connected, open: openSection === "browser", onToggle: () => toggle("browser"), children: !builderConnectionOwnedExternally ? (_jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "browser_settings", trackingFlow: "browser_automation" })) : null })), !isPage &&
1053
1060
  builderBranchesAvailable &&
1054
1061
  shouldShowSection("background") && (_jsx(SettingsSection, { id: settingsSectionDomId("background"), icon: _jsx(IconGitBranch, { size: 14 }), title: "Background Agent", subtitle: "Make code changes from production mode via Builder.", flat: true, connected: connected, open: openSection === "background", onToggle: () => toggle("background"), children: _jsx(UseBuilderCard, { builderFlow: builderFlow, connectUrl: connectUrl, connected: connected, orgName: orgName, envManaged: envManaged, credentialSource: credentialSource, trackingSource: "background_agent_settings", trackingFlow: "background_agent" }) })), shouldShowSection("integrations") && (_jsx(SettingsSection, { id: settingsSectionDomId("integrations"), icon: _jsx(IconPlugConnected, { size: 14 }), title: "Integrations", subtitle: "Connect messaging platforms and external services.", flat: true, open: openSection === "integrations", onToggle: () => toggle("integrations"), children: _jsx(Suspense, { fallback: null, children: _jsx(IntegrationsPanel, {}) }) })), shouldShowSection("usage") && (_jsx(SettingsSection, { id: settingsSectionDomId("usage"), icon: _jsx(IconCoin, { size: 14 }), title: "Usage", subtitle: "Track token consumption and estimated cost \u2014 broken down by chat, automations, and background jobs.", flat: true, open: openSection === "usage", onToggle: () => toggle("usage"), children: _jsx(UsageSection, {}) })), shouldShowSection("a2a") && (_jsx(SettingsSection, { id: settingsSectionDomId("a2a"), icon: _jsx(IconTopologyRing2, { size: 14 }), title: "Connected Agents (A2A)", subtitle: "Manage remote agents connected via the A2A protocol.", flat: true, open: openSection === "a2a", onToggle: () => toggle("a2a"), children: _jsx(AgentsSection, {}) }))] }) }));
1055
1062
  }
@@ -1059,7 +1066,7 @@ export function SettingsPanel(props) {
1059
1066
  export function ConnectionsSettingsContent({ settingsPanelProps, }) {
1060
1067
  return (_jsxs("div", { className: "w-full space-y-8", children: [_jsx(Suspense, { fallback: null, children: _jsx(IntegrationsPanel, {}) }), _jsx(BuilderConnectCard, { trackingSource: "settings_connections" }), _jsx(SettingsPanelContent, { ...settingsPanelProps, surface: "page", sections: INTEGRATION_SETTINGS_SECTIONS.filter((section) => section !== "integrations"), showCapabilityStrip: false, className: "w-full", builderConnectionOwnedExternally: true })] }));
1061
1068
  }
1062
- export function AgentSettingsContent({ className, sections = AGENT_SETTINGS_SECTIONS, } = {}) {
1069
+ export function AgentSettingsContent({ className, sections = AGENT_SETTINGS_SECTIONS, agentAdditionalContent, } = {}) {
1063
1070
  const { isDevMode, canToggle, setDevMode } = useDevMode();
1064
1071
  const settingsPanelProps = useMemo(() => ({
1065
1072
  isDevMode,
@@ -1068,11 +1075,12 @@ export function AgentSettingsContent({ className, sections = AGENT_SETTINGS_SECT
1068
1075
  },
1069
1076
  showDevToggle: canToggle,
1070
1077
  }), [canToggle, isDevMode, setDevMode]);
1071
- return (_jsx(SettingsPanelContent, { ...settingsPanelProps, surface: "page", sections: sections, showCapabilityStrip: false, className: cn("w-full", className) }));
1078
+ return (_jsx(SettingsPanelContent, { ...settingsPanelProps, surface: "page", sections: sections, showCapabilityStrip: false, className: cn("w-full", className), agentAdditionalContent: agentAdditionalContent }));
1072
1079
  }
1073
1080
  export function useAgentSettingsTabs(options = {}) {
1074
1081
  const { isDevMode, canToggle, setDevMode } = useDevMode();
1075
1082
  const extensionToolsEnabled = areExtensionSettingsEnabled(options);
1083
+ const agentAdditionalContent = options.agentAdditionalContent;
1076
1084
  const baseProps = useMemo(() => ({
1077
1085
  isDevMode,
1078
1086
  onToggleDevMode: () => {
@@ -1196,7 +1204,7 @@ export function useAgentSettingsTabs(options = {}) {
1196
1204
  group: "agent",
1197
1205
  keywords: agent.keywords,
1198
1206
  searchEntries: overviewSearchEntries,
1199
- content: (_jsx(AgentWorkspaceContent, { activeTab: "overview", overview: _jsx(AgentSettingsContent, { className: "w-full", sections: AGENT_SETTINGS_SECTIONS.filter((section) => section !== "automations" && section !== "a2a") }) })),
1207
+ content: (_jsx(AgentWorkspaceContent, { activeTab: "overview", overview: _jsx(AgentSettingsContent, { className: "w-full", agentAdditionalContent: agentAdditionalContent, sections: AGENT_SETTINGS_SECTIONS.filter((section) => section !== "automations" && section !== "a2a") }) })),
1200
1208
  },
1201
1209
  {
1202
1210
  id: "agent:resources",
@@ -1245,14 +1253,6 @@ export function useAgentSettingsTabs(options = {}) {
1245
1253
  ],
1246
1254
  content: _jsx(AgentWorkspaceContent, { activeTab: "agents", overview: null }),
1247
1255
  },
1248
- {
1249
- id: "agent:access",
1250
- label: "Access",
1251
- icon: IconShieldLock,
1252
- group: "agent",
1253
- keywords: "access sharing permissions clients",
1254
- content: _jsx(AgentWorkspaceContent, { activeTab: "access", overview: null }),
1255
- },
1256
1256
  ];
1257
- }, [baseProps, extensionToolsEnabled]);
1257
+ }, [agentAdditionalContent, baseProps, extensionToolsEnabled]);
1258
1258
  }
@@ -73,8 +73,8 @@ export interface SettingsTabsPageProps {
73
73
  * Controlled active tab id. When provided, the parent owns tab state (and is
74
74
  * responsible for URL/app-state sync). Recognized top-level tab hashes still
75
75
  * report through `onValueChange`, so shared links such as
76
- * `/settings#organization` can select the matching controlled Team tab.
77
- * Leave undefined for the default uncontrolled, hash-driven behavior.
76
+ * `/settings/organization` can select the matching controlled Team tab.
77
+ * Legacy hash links remain supported and are canonicalized on load.
78
78
  */
79
79
  value?: string;
80
80
  /**