@agent-native/core 0.91.2 → 0.92.0

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 (216) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +17 -0
  3. package/corpus/core/docs/content/faq.mdx +17 -0
  4. package/corpus/core/docs/content/notifications.mdx +12 -6
  5. package/corpus/core/package.json +1 -1
  6. package/corpus/core/src/agent/production-agent.ts +140 -46
  7. package/corpus/core/src/agent/tool-search.ts +71 -4
  8. package/corpus/core/src/cli/index.ts +20 -0
  9. package/corpus/core/src/cli/upgrade.ts +798 -0
  10. package/corpus/core/src/client/AssistantChat.tsx +1 -1
  11. package/corpus/core/src/client/HighlightedCodeBlock.tsx +20 -3
  12. package/corpus/core/src/client/agent-chat-adapter.ts +31 -6
  13. package/corpus/core/src/client/chat/message-components.tsx +85 -8
  14. package/corpus/core/src/client/chat/tool-call-display.tsx +355 -144
  15. package/corpus/core/src/client/code-agent-chat-adapter.ts +2 -9
  16. package/corpus/core/src/client/session-replay.ts +3 -97
  17. package/corpus/core/src/client/settings/SettingsPanel.tsx +533 -389
  18. package/corpus/core/src/client/settings/SettingsSection.tsx +154 -17
  19. package/corpus/core/src/client/sse-event-processor.ts +29 -2
  20. package/corpus/core/src/extensions/actions.ts +113 -5
  21. package/corpus/core/src/notifications/channels.ts +88 -25
  22. package/corpus/core/src/notifications/registry.ts +17 -3
  23. package/corpus/core/src/notifications/types.ts +4 -1
  24. package/corpus/core/src/server/agent-chat-plugin.ts +7 -3
  25. package/corpus/core/src/server/request-context.ts +7 -0
  26. package/corpus/core/src/styles/agent-conversation.css +1 -1
  27. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
  28. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  29. package/corpus/core/src/templates/default/AGENTS.md +10 -3
  30. package/corpus/core/src/templates/default/package.json +2 -1
  31. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  32. package/corpus/core/src/templates/headless/AGENTS.md +9 -3
  33. package/corpus/core/src/templates/headless/package.json +1 -0
  34. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
  35. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  36. package/corpus/core/src/templates/workspace-root/AGENTS.md +10 -4
  37. package/corpus/core/src/templates/workspace-root/package.json +1 -0
  38. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +20 -2
  39. package/corpus/templates/analytics/.agents/skills/session-replay/SKILL.md +5 -6
  40. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  41. package/corpus/templates/analytics/AGENTS.md +7 -5
  42. package/corpus/templates/analytics/actions/save-monitor.ts +14 -0
  43. package/corpus/templates/analytics/app/components/dashboard/DataTable.tsx +41 -6
  44. package/corpus/templates/analytics/app/components/dashboard/SqlChart.tsx +122 -11
  45. package/corpus/templates/analytics/app/pages/monitoring/MonitoringPage.tsx +8 -2
  46. package/corpus/templates/analytics/app/pages/monitoring/uptime/MonitorFormPage.tsx +151 -32
  47. package/corpus/templates/analytics/app/pages/monitoring/uptime/i18n.ts +17 -2
  48. package/corpus/templates/analytics/app/pages/monitoring/uptime/types.ts +4 -0
  49. package/corpus/templates/analytics/app/pages/sessions/SessionDetailPage.tsx +54 -190
  50. package/corpus/templates/analytics/changelog/2026-07-08-dashboard-tables-keep-their-size-while-loading.md +6 -0
  51. package/corpus/templates/analytics/changelog/2026-07-08-monitoring-uptime-and-errors-tabs-now-clearly-show-which-view-is-active.md +6 -0
  52. package/corpus/templates/analytics/changelog/2026-07-08-session-replay-uses-stock-rrweb-sizing-again-so-recorded.md +6 -0
  53. package/corpus/templates/analytics/changelog/2026-07-08-sidebar-dashboard-menus-now-open-above-the-dashboard-canvas.md +6 -0
  54. package/corpus/templates/analytics/changelog/2026-07-08-uptime-alerting-clarifies-in-app-inbox-vs-email-and-lets-you-paste-slack-or-webhook-urls-per-monitor.md +6 -0
  55. package/corpus/templates/analytics/docs/uptime-monitoring.md +13 -11
  56. package/corpus/templates/analytics/server/db/schema-monitoring.ts +4 -0
  57. package/corpus/templates/analytics/server/lib/uptime-monitors.ts +60 -12
  58. package/corpus/templates/analytics/server/plugins/db.ts +10 -0
  59. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +20 -2
  60. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  61. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +20 -2
  62. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  63. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +20 -2
  64. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  65. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +20 -2
  66. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  67. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +20 -2
  68. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  69. package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-notes-stay-active-from-tray-and-shortcut-controls.md +6 -0
  70. package/corpus/templates/clips/changelog/2026-07-08-desktop-meeting-popovers-can-start-notes-and-join-the-meetin.md +6 -0
  71. package/corpus/templates/clips/changelog/2026-07-08-meeting-notes-keep-their-recording-state-when-the-desktop.md +6 -0
  72. package/corpus/templates/clips/changelog/2026-07-08-meeting-reminder-dropdowns-now-expand-fully-instead-of-being.md +6 -0
  73. package/corpus/templates/clips/desktop/src/app.tsx +123 -3
  74. package/corpus/templates/clips/desktop/src/hooks/useMeetingTranscription.ts +15 -1
  75. package/corpus/templates/clips/desktop/src/overlays/meeting-notification.tsx +23 -0
  76. package/corpus/templates/clips/desktop/src/styles.css +23 -1
  77. package/corpus/templates/clips/desktop/src-tauri/src/adhoc_meetings_watcher.rs +1 -3
  78. package/corpus/templates/clips/desktop/src-tauri/src/clips/mod.rs +40 -6
  79. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +4 -2
  80. package/corpus/templates/clips/desktop/src-tauri/src/meetings_watcher.rs +3 -5
  81. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +23 -19
  82. package/corpus/templates/clips/desktop/src-tauri/src/shortcuts.rs +3 -3
  83. package/corpus/templates/clips/desktop/src-tauri/src/silence_detector.rs +0 -1
  84. package/corpus/templates/clips/desktop/src-tauri/src/state.rs +5 -0
  85. package/corpus/templates/clips/desktop/src-tauri/src/tray.rs +18 -6
  86. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +20 -2
  87. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  88. package/corpus/templates/content/actions/_batch-utils.ts +8 -0
  89. package/corpus/templates/content/actions/_builder-cms-read-client.ts +7 -5
  90. package/corpus/templates/content/actions/_database-source-utils.ts +776 -319
  91. package/corpus/templates/content/actions/_database-utils.ts +6 -1
  92. package/corpus/templates/content/actions/_property-utils.ts +168 -0
  93. package/corpus/templates/content/actions/add-content-database-source-field-property.ts +19 -12
  94. package/corpus/templates/content/actions/bind-content-database-source-field.ts +19 -12
  95. package/corpus/templates/content/actions/delete-document.ts +9 -13
  96. package/corpus/templates/content/actions/refresh-content-database-source.ts +5 -5
  97. package/corpus/templates/content/app/components/editor/body-hydration.ts +35 -11
  98. package/corpus/templates/content/app/components/editor/database/DatabaseView.tsx +47 -5
  99. package/corpus/templates/content/app/hooks/use-documents.ts +8 -2
  100. package/corpus/templates/content/changelog/2026-07-08-builder-source-sync-now-completes-reliably-on-hosted-databases.md +6 -0
  101. package/corpus/templates/content/changelog/2026-07-08-fixed-builder-database-sync-so-large-sources-continue-past-t.md +6 -0
  102. package/corpus/templates/content/server/plugins/db.ts +19 -0
  103. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +20 -2
  104. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  105. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +20 -2
  106. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  107. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +20 -2
  108. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  109. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  110. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +20 -2
  111. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  112. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +20 -2
  113. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  114. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +20 -2
  115. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  116. package/corpus/templates/videos/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  117. package/corpus/templates/voice/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  118. package/dist/agent/production-agent.d.ts +5 -1
  119. package/dist/agent/production-agent.d.ts.map +1 -1
  120. package/dist/agent/production-agent.js +112 -42
  121. package/dist/agent/production-agent.js.map +1 -1
  122. package/dist/agent/tool-search.d.ts +2 -0
  123. package/dist/agent/tool-search.d.ts.map +1 -1
  124. package/dist/agent/tool-search.js +60 -4
  125. package/dist/agent/tool-search.js.map +1 -1
  126. package/dist/cli/index.js +19 -0
  127. package/dist/cli/index.js.map +1 -1
  128. package/dist/cli/upgrade.d.ts +100 -0
  129. package/dist/cli/upgrade.d.ts.map +1 -0
  130. package/dist/cli/upgrade.js +678 -0
  131. package/dist/cli/upgrade.js.map +1 -0
  132. package/dist/client/AssistantChat.js +1 -1
  133. package/dist/client/AssistantChat.js.map +1 -1
  134. package/dist/client/HighlightedCodeBlock.d.ts +2 -0
  135. package/dist/client/HighlightedCodeBlock.d.ts.map +1 -1
  136. package/dist/client/HighlightedCodeBlock.js +10 -1
  137. package/dist/client/HighlightedCodeBlock.js.map +1 -1
  138. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  139. package/dist/client/agent-chat-adapter.js +32 -4
  140. package/dist/client/agent-chat-adapter.js.map +1 -1
  141. package/dist/client/chat/message-components.d.ts.map +1 -1
  142. package/dist/client/chat/message-components.js +61 -8
  143. package/dist/client/chat/message-components.js.map +1 -1
  144. package/dist/client/chat/tool-call-display.d.ts +12 -0
  145. package/dist/client/chat/tool-call-display.d.ts.map +1 -1
  146. package/dist/client/chat/tool-call-display.js +136 -42
  147. package/dist/client/chat/tool-call-display.js.map +1 -1
  148. package/dist/client/code-agent-chat-adapter.js +2 -9
  149. package/dist/client/code-agent-chat-adapter.js.map +1 -1
  150. package/dist/client/session-replay.d.ts +0 -8
  151. package/dist/client/session-replay.d.ts.map +1 -1
  152. package/dist/client/session-replay.js +3 -80
  153. package/dist/client/session-replay.js.map +1 -1
  154. package/dist/client/settings/SettingsPanel.d.ts.map +1 -1
  155. package/dist/client/settings/SettingsPanel.js +52 -19
  156. package/dist/client/settings/SettingsPanel.js.map +1 -1
  157. package/dist/client/settings/SettingsSection.d.ts +19 -4
  158. package/dist/client/settings/SettingsSection.d.ts.map +1 -1
  159. package/dist/client/settings/SettingsSection.js +33 -4
  160. package/dist/client/settings/SettingsSection.js.map +1 -1
  161. package/dist/client/sse-event-processor.d.ts +9 -0
  162. package/dist/client/sse-event-processor.d.ts.map +1 -1
  163. package/dist/client/sse-event-processor.js +20 -2
  164. package/dist/client/sse-event-processor.js.map +1 -1
  165. package/dist/collab/routes.d.ts +1 -1
  166. package/dist/extensions/actions.d.ts.map +1 -1
  167. package/dist/extensions/actions.js +85 -5
  168. package/dist/extensions/actions.js.map +1 -1
  169. package/dist/notifications/channels.d.ts +8 -3
  170. package/dist/notifications/channels.d.ts.map +1 -1
  171. package/dist/notifications/channels.js +61 -22
  172. package/dist/notifications/channels.js.map +1 -1
  173. package/dist/notifications/registry.d.ts.map +1 -1
  174. package/dist/notifications/registry.js +14 -3
  175. package/dist/notifications/registry.js.map +1 -1
  176. package/dist/notifications/routes.d.ts +1 -1
  177. package/dist/notifications/types.d.ts +4 -1
  178. package/dist/notifications/types.d.ts.map +1 -1
  179. package/dist/notifications/types.js.map +1 -1
  180. package/dist/observability/routes.d.ts +1 -1
  181. package/dist/resources/handlers.d.ts +1 -1
  182. package/dist/server/agent-chat-plugin.d.ts +5 -1
  183. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  184. package/dist/server/agent-chat-plugin.js +2 -2
  185. package/dist/server/agent-chat-plugin.js.map +1 -1
  186. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  187. package/dist/server/request-context.d.ts +7 -0
  188. package/dist/server/request-context.d.ts.map +1 -1
  189. package/dist/server/request-context.js.map +1 -1
  190. package/dist/styles/agent-conversation.css +1 -1
  191. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
  192. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  193. package/dist/templates/default/AGENTS.md +10 -3
  194. package/dist/templates/default/package.json +2 -1
  195. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  196. package/dist/templates/headless/AGENTS.md +9 -3
  197. package/dist/templates/headless/package.json +1 -0
  198. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
  199. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  200. package/dist/templates/workspace-root/AGENTS.md +10 -4
  201. package/dist/templates/workspace-root/package.json +1 -0
  202. package/docs/content/faq.mdx +17 -0
  203. package/docs/content/notifications.mdx +12 -6
  204. package/package.json +2 -2
  205. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +20 -2
  206. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  207. package/src/templates/default/AGENTS.md +10 -3
  208. package/src/templates/default/package.json +2 -1
  209. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  210. package/src/templates/headless/AGENTS.md +9 -3
  211. package/src/templates/headless/package.json +1 -0
  212. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +20 -2
  213. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +87 -0
  214. package/src/templates/workspace-root/AGENTS.md +10 -4
  215. package/src/templates/workspace-root/package.json +1 -0
  216. package/corpus/templates/analytics/changelog/2026-07-08-session-replay-clamps-ultra-wide-viewports-while-keeping-the.md +0 -6
@@ -52,7 +52,12 @@ import { AgentsSection } from "./AgentsSection.js";
52
52
  import { AutomationsSection } from "./AutomationsSection.js";
53
53
  import { DemoModeSection } from "./DemoModeSection.js";
54
54
  import { SecretsSection } from "./SecretsSection.js";
55
- import { SettingsSection } from "./SettingsSection.js";
55
+ import {
56
+ SettingsSection,
57
+ SettingsSurfaceProvider,
58
+ useSettingsSurface,
59
+ type SettingsSurface,
60
+ } from "./SettingsSection.js";
56
61
  import type {
57
62
  SettingsSearchEntry,
58
63
  SettingsTabItem,
@@ -102,6 +107,45 @@ const CONTROL_STYLE = {
102
107
  lineHeight: 1,
103
108
  } satisfies React.CSSProperties;
104
109
 
110
+ const CONTROL_STYLE_PAGE = {
111
+ fontSize: 14,
112
+ lineHeight: 1.2,
113
+ } satisfies React.CSSProperties;
114
+
115
+ // Surface-aware class helpers so section bodies (shared with the compact
116
+ // sidebar) read as roomy, shadcn-style forms on the full settings page while
117
+ // staying dense in the sidebar.
118
+ function fieldLabelClass(isPage: boolean): string {
119
+ return cn("font-medium text-foreground", isPage ? "text-sm" : "text-[12px]");
120
+ }
121
+
122
+ function textInputClass(isPage: boolean): string {
123
+ return cn(
124
+ "flex w-full rounded-md border border-border bg-background text-foreground outline-none transition-colors hover:bg-accent/40 focus:ring-1 focus:ring-accent placeholder:text-muted-foreground/50",
125
+ isPage ? "h-10 px-3 text-sm" : "h-9 px-3 text-[12px]",
126
+ );
127
+ }
128
+
129
+ function pillButtonClass(
130
+ isPage: boolean,
131
+ tone: "solid" | "outline" | "ghost" = "outline",
132
+ ): string {
133
+ const base = cn(
134
+ "inline-flex items-center justify-center gap-1 rounded-md font-medium transition-colors disabled:opacity-40",
135
+ isPage ? "px-3 py-1.5 text-sm" : "px-2.5 py-1 text-[10px]",
136
+ );
137
+ if (tone === "solid") {
138
+ return cn(base, "bg-accent text-foreground hover:bg-accent/80");
139
+ }
140
+ if (tone === "ghost") {
141
+ return cn(
142
+ base,
143
+ "text-muted-foreground hover:bg-accent/40 hover:text-foreground",
144
+ );
145
+ }
146
+ return cn(base, "border border-border text-foreground hover:bg-accent/40");
147
+ }
148
+
105
149
  function SettingsSelect({
106
150
  label,
107
151
  labelAdornment,
@@ -115,25 +159,30 @@ function SettingsSelect({
115
159
  options: SettingsSelectOption[];
116
160
  onValueChange: (value: string) => void;
117
161
  }) {
162
+ const isPage = useSettingsSurface() === "page";
163
+ const controlStyle = isPage ? CONTROL_STYLE_PAGE : CONTROL_STYLE;
118
164
  const selected = options.find((option) => option.value === value);
119
165
 
120
166
  return (
121
167
  <div className="space-y-1.5">
122
168
  <div className="flex items-center justify-between">
123
- <p className="text-[12px] font-medium text-foreground">{label}</p>
169
+ <p className={fieldLabelClass(isPage)}>{label}</p>
124
170
  {labelAdornment}
125
171
  </div>
126
172
  <SelectPrimitive.Root value={value} onValueChange={onValueChange}>
127
173
  <SelectPrimitive.Trigger
128
- className="flex h-9 w-full items-center justify-between rounded-md border border-border bg-background px-3 text-start text-[12px] text-foreground outline-none transition-colors hover:bg-accent/40 data-[placeholder]:text-muted-foreground"
174
+ className={cn(
175
+ "flex w-full items-center justify-between rounded-md border border-border bg-background px-3 text-start text-foreground outline-none transition-colors hover:bg-accent/40 data-[placeholder]:text-muted-foreground",
176
+ isPage ? "h-10 text-sm" : "h-9 text-[12px]",
177
+ )}
129
178
  aria-label={label}
130
- style={CONTROL_STYLE}
179
+ style={controlStyle}
131
180
  >
132
181
  <SelectPrimitive.Value>
133
182
  {selected?.label ?? value}
134
183
  </SelectPrimitive.Value>
135
184
  <SelectPrimitive.Icon asChild>
136
- <IconChevronDown size={14} className="text-muted-foreground" />
185
+ <IconChevronDown size={16} className="text-muted-foreground" />
137
186
  </SelectPrimitive.Icon>
138
187
  </SelectPrimitive.Trigger>
139
188
  <SelectPrimitive.Portal>
@@ -147,8 +196,11 @@ function SettingsSelect({
147
196
  <SelectPrimitive.Item
148
197
  key={option.value}
149
198
  value={option.value}
150
- className="relative flex w-full cursor-pointer select-none items-start gap-2 rounded-md px-8 py-2.5 text-[12px] outline-none data-[highlighted]:bg-accent/60 data-[state=checked]:bg-accent/40"
151
- style={CONTROL_STYLE}
199
+ className={cn(
200
+ "relative flex w-full cursor-pointer select-none items-start gap-2 rounded-md px-8 outline-none data-[highlighted]:bg-accent/60 data-[state=checked]:bg-accent/40",
201
+ isPage ? "py-2.5 text-sm" : "py-2.5 text-[12px]",
202
+ )}
203
+ style={controlStyle}
152
204
  >
153
205
  <span className="absolute start-2 top-2.5 flex h-4 w-4 items-center justify-center text-muted-foreground">
154
206
  <SelectPrimitive.ItemIndicator>
@@ -160,7 +212,12 @@ function SettingsSelect({
160
212
  <span className="text-foreground">{option.label}</span>
161
213
  </SelectPrimitive.ItemText>
162
214
  {option.description ? (
163
- <span className="mt-0.5 text-[11px] leading-relaxed text-muted-foreground">
215
+ <span
216
+ className={cn(
217
+ "mt-0.5 leading-relaxed text-muted-foreground",
218
+ isPage ? "text-xs" : "text-[11px]",
219
+ )}
220
+ >
164
221
  {option.description}
165
222
  </span>
166
223
  ) : null}
@@ -354,29 +411,40 @@ function UseBuilderCard({
354
411
  subtitle?: string;
355
412
  dim?: boolean;
356
413
  }) {
414
+ const isPage = useSettingsSurface() === "page";
357
415
  const effectiveConnected = connected || builderFlow.configured;
358
416
  const effectiveOrgName = builderFlow.orgName ?? orgName;
359
417
  const bgClass = dim ? "" : "bg-accent/30";
418
+ const titleCls = isPage ? "text-sm" : "text-[11px]";
419
+ const bodyCls = isPage ? "text-xs" : "text-[10px]";
360
420
 
361
421
  if (effectiveConnected) {
362
422
  return (
363
- <div className={`rounded-md border border-border px-2.5 py-2 ${bgClass}`}>
423
+ <div
424
+ className={cn(
425
+ "rounded-md border border-border",
426
+ isPage ? "px-3.5 py-3" : "px-2.5 py-2",
427
+ bgClass,
428
+ )}
429
+ >
364
430
  <div className="flex items-center justify-between">
365
- <div className="text-[11px] font-medium text-foreground">
431
+ <div className={cn("font-medium text-foreground", titleCls)}>
366
432
  Builder.io
367
433
  </div>
368
- <span className="flex items-center gap-1 text-[10px] text-green-500">
369
- <IconCheck size={10} />
434
+ <span
435
+ className={cn("flex items-center gap-1 text-green-500", bodyCls)}
436
+ >
437
+ <IconCheck size={isPage ? 14 : 10} />
370
438
  Connected
371
439
  </span>
372
440
  </div>
373
441
  {effectiveOrgName && (
374
- <p className="text-[10px] text-muted-foreground mt-0.5">
442
+ <p className={cn("text-muted-foreground mt-0.5", bodyCls)}>
375
443
  {effectiveOrgName}
376
444
  </p>
377
445
  )}
378
446
  {envManaged ? (
379
- <p className="text-[10px] text-muted-foreground mt-1">
447
+ <p className={cn("text-muted-foreground mt-1", bodyCls)}>
380
448
  {credentialSource === "env"
381
449
  ? "Deployment fallback is available. Connect your own account to override it."
382
450
  : "Using your connected Builder account. Deployment fallback is still available."}
@@ -391,14 +459,14 @@ function UseBuilderCard({
391
459
  builderFlow.start({ trackingSource, trackingFlow })
392
460
  }
393
461
  disabled={builderFlow.connecting}
394
- className="inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] no-underline text-muted-foreground hover:text-foreground hover:bg-accent/40 disabled:opacity-60"
462
+ className={cn(pillButtonClass(isPage, "ghost"), "no-underline")}
395
463
  >
396
464
  {builderFlow.connecting
397
465
  ? "Connecting..."
398
466
  : credentialSource === "env"
399
467
  ? "Connect account"
400
468
  : "Reconnect"}
401
- <IconExternalLink size={10} />
469
+ <IconExternalLink size={isPage ? 14 : 10} />
402
470
  </button>
403
471
  )}
404
472
  {credentialSource !== "env" ? <DisconnectBuilderButton /> : null}
@@ -415,35 +483,53 @@ function UseBuilderCard({
415
483
  type="button"
416
484
  onClick={() => builderFlow.start({ trackingSource, trackingFlow })}
417
485
  disabled={builderFlow.connecting}
418
- className={`block w-full rounded-md border border-border px-3 py-3 text-start no-underline bg-gradient-to-br from-teal-500/10 via-transparent to-transparent hover:border-foreground/30 transition-colors disabled:cursor-wait disabled:opacity-70`}
486
+ className={cn(
487
+ "block w-full rounded-md border border-border text-start no-underline bg-gradient-to-br from-teal-500/10 via-transparent to-transparent hover:border-foreground/30 transition-colors disabled:cursor-wait disabled:opacity-70",
488
+ isPage ? "px-4 py-3.5" : "px-3 py-3",
489
+ )}
419
490
  >
420
491
  <div className="flex items-start gap-2.5">
421
- <div className="flex h-7 w-7 shrink-0 items-center justify-center rounded-md bg-foreground text-background">
422
- <BuilderBMark className="h-3.5 w-3.5" />
492
+ <div
493
+ className={cn(
494
+ "flex shrink-0 items-center justify-center rounded-md bg-foreground text-background",
495
+ isPage ? "h-8 w-8" : "h-7 w-7",
496
+ )}
497
+ >
498
+ <BuilderBMark className={isPage ? "h-4 w-4" : "h-3.5 w-3.5"} />
423
499
  </div>
424
500
  <div className="flex-1 min-w-0">
425
501
  <div className="flex items-center gap-1.5 flex-wrap">
426
- <span className="text-[12px] font-semibold text-foreground">
502
+ <span
503
+ className={cn(
504
+ "font-semibold text-foreground",
505
+ isPage ? "text-sm" : "text-[12px]",
506
+ )}
507
+ >
427
508
  {builderFlow.connecting ? "Connecting Builder.io..." : label}
428
509
  </span>
429
510
  {builderFlow.connecting && (
430
511
  <IconLoader2
431
- size={12}
512
+ size={isPage ? 14 : 12}
432
513
  className="shrink-0 animate-spin text-muted-foreground"
433
514
  />
434
515
  )}
435
516
  </div>
436
- <p className="text-[10.5px] text-muted-foreground mt-0.5 leading-snug">
517
+ <p
518
+ className={cn(
519
+ "text-muted-foreground mt-0.5 leading-snug",
520
+ isPage ? "text-xs" : "text-[10.5px]",
521
+ )}
522
+ >
437
523
  {subtitle}
438
524
  </p>
439
525
  {builderFlow.error && (
440
- <p className="mt-1 text-[10px] text-destructive">
526
+ <p className={cn("mt-1 text-destructive", bodyCls)}>
441
527
  {builderFlow.error}
442
528
  </p>
443
529
  )}
444
530
  </div>
445
531
  <IconExternalLink
446
- size={12}
532
+ size={isPage ? 14 : 12}
447
533
  className="shrink-0 text-muted-foreground mt-0.5"
448
534
  />
449
535
  </div>
@@ -469,23 +555,32 @@ function ManualSetupCard({
469
555
  /** Optional "Connected via X" badge shown in the header row. */
470
556
  sourceBadge?: string;
471
557
  }) {
558
+ const isPage = useSettingsSurface() === "page";
559
+ const titleCls = isPage ? "text-sm" : "text-[11px]";
560
+ const bodyCls = isPage ? "text-xs" : "text-[10px]";
472
561
  return (
473
562
  <div
474
- className={`rounded-md border border-border px-2.5 py-2 ${dim ? "" : "bg-accent/30"}`}
563
+ className={cn(
564
+ "rounded-md border border-border",
565
+ isPage ? "px-3.5 py-3" : "px-2.5 py-2",
566
+ dim ? "" : "bg-accent/30",
567
+ )}
475
568
  >
476
569
  <div className="flex items-center justify-between mb-1">
477
- <div className="text-[11px] font-medium text-foreground">
570
+ <div className={cn("font-medium text-foreground", titleCls)}>
478
571
  Set up manually
479
572
  </div>
480
573
  {sourceBadge ? (
481
- <span className="flex items-center gap-1 text-[10px] text-green-500">
482
- <IconCheck size={10} />
574
+ <span
575
+ className={cn("flex items-center gap-1 text-green-500", bodyCls)}
576
+ >
577
+ <IconCheck size={isPage ? 14 : 10} />
483
578
  {sourceBadge}
484
579
  </span>
485
580
  ) : null}
486
581
  </div>
487
582
  {hint && (
488
- <p className="text-[10px] text-muted-foreground mb-1.5">{hint}</p>
583
+ <p className={cn("text-muted-foreground mb-1.5", bodyCls)}>{hint}</p>
489
584
  )}
490
585
  {children}
491
586
  {docsUrl && (
@@ -493,10 +588,13 @@ function ManualSetupCard({
493
588
  href={docsUrl}
494
589
  target="_blank"
495
590
  rel="noopener noreferrer"
496
- className="inline-flex items-center gap-1 mt-1.5 rounded border border-border px-2.5 py-1 text-[10px] font-medium no-underline text-muted-foreground hover:text-foreground hover:bg-accent/40"
591
+ className={cn(
592
+ pillButtonClass(isPage, "outline"),
593
+ "mt-1.5 no-underline",
594
+ )}
497
595
  >
498
596
  {docsLabel}
499
- <IconExternalLink size={10} />
597
+ <IconExternalLink size={isPage ? 14 : 10} />
500
598
  </a>
501
599
  )}
502
600
  </div>
@@ -617,6 +715,7 @@ function LLMSectionInner({
617
715
  open?: boolean;
618
716
  onToggle?: () => void;
619
717
  }) {
718
+ const isPage = useSettingsSurface() === "page";
620
719
  const [envKeys, setEnvKeys] = useState<
621
720
  Array<{ key: string; configured: boolean }>
622
721
  >([]);
@@ -926,9 +1025,7 @@ function LLMSectionInner({
926
1025
  {/* Free-form input so OpenRouter/Ollama custom model IDs can
927
1026
  be typed — the registry's supportedModels is only suggestions. */}
928
1027
  <div className="space-y-1.5">
929
- <p className="text-[12px] font-medium text-foreground">
930
- Model
931
- </p>
1028
+ <p className={fieldLabelClass(isPage)}>Model</p>
932
1029
  <input
933
1030
  type="text"
934
1031
  list={`model-suggestions-${selectedEngine}`}
@@ -939,8 +1036,8 @@ function LLMSectionInner({
939
1036
  }
940
1037
  spellCheck={false}
941
1038
  autoComplete="off"
942
- className="flex h-9 w-full rounded-md border border-border bg-background px-3 text-[12px] text-foreground outline-none transition-colors hover:bg-accent/40 focus:ring-1 focus:ring-accent placeholder:text-muted-foreground/50"
943
- style={CONTROL_STYLE}
1039
+ className={textInputClass(isPage)}
1040
+ style={isPage ? CONTROL_STYLE_PAGE : CONTROL_STYLE}
944
1041
  />
945
1042
  {modelOptions.length > 0 && (
946
1043
  <datalist id={`model-suggestions-${selectedEngine}`}>
@@ -1049,8 +1146,13 @@ function LLMSectionInner({
1049
1146
  )}
1050
1147
 
1051
1148
  {envVar && envConfigured ? (
1052
- <div className="flex items-center gap-1.5 text-[10px] text-green-500">
1053
- <IconCheck size={10} />
1149
+ <div
1150
+ className={cn(
1151
+ "flex items-center gap-1.5 text-green-500",
1152
+ isPage ? "text-xs" : "text-[10px]",
1153
+ )}
1154
+ >
1155
+ <IconCheck size={isPage ? 14 : 10} />
1054
1156
  {envVar} configured
1055
1157
  </div>
1056
1158
  ) : envVar ? (
@@ -1063,17 +1165,21 @@ function LLMSectionInner({
1063
1165
  if (e.key === "Enter") handleSave();
1064
1166
  }}
1065
1167
  placeholder={PROVIDER_ENV_PLACEHOLDERS[envVar] ?? "..."}
1066
- className="flex-1 rounded border border-border bg-background px-2 py-1 text-[11px] text-foreground outline-none placeholder:text-muted-foreground/50 focus:ring-1 focus:ring-accent"
1168
+ className={cn(textInputClass(isPage), "flex-1")}
1169
+ style={isPage ? CONTROL_STYLE_PAGE : undefined}
1067
1170
  />
1068
1171
  <button
1069
1172
  onClick={handleSave}
1070
1173
  disabled={!providerSettingsChanged || saving}
1071
- className="rounded bg-accent px-2 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40"
1174
+ className={pillButtonClass(isPage, "solid")}
1072
1175
  >
1073
1176
  {saving ? (
1074
- <IconLoader2 size={10} className="animate-spin" />
1177
+ <IconLoader2
1178
+ size={isPage ? 14 : 10}
1179
+ className="animate-spin"
1180
+ />
1075
1181
  ) : saved ? (
1076
- <IconCheck size={10} />
1182
+ <IconCheck size={isPage ? 14 : 10} />
1077
1183
  ) : (
1078
1184
  "Save"
1079
1185
  )}
@@ -1085,11 +1191,14 @@ function LLMSectionInner({
1085
1191
  <button
1086
1192
  onClick={handleTest}
1087
1193
  disabled={testing}
1088
- className="rounded border border-border px-2.5 py-1 text-[10px] font-medium text-foreground hover:bg-accent/40 disabled:opacity-40"
1194
+ className={pillButtonClass(isPage, "outline")}
1089
1195
  >
1090
1196
  {testing ? (
1091
1197
  <span className="flex items-center gap-1">
1092
- <IconLoader2 size={10} className="animate-spin" />
1198
+ <IconLoader2
1199
+ size={isPage ? 14 : 10}
1200
+ className="animate-spin"
1201
+ />
1093
1202
  Testing…
1094
1203
  </span>
1095
1204
  ) : (
@@ -1099,7 +1208,7 @@ function LLMSectionInner({
1099
1208
  {engineChanged && (
1100
1209
  <button
1101
1210
  onClick={handleApply}
1102
- className="rounded bg-accent px-2.5 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80"
1211
+ className={pillButtonClass(isPage, "solid")}
1103
1212
  >
1104
1213
  Apply
1105
1214
  </button>
@@ -1109,7 +1218,10 @@ function LLMSectionInner({
1109
1218
  <TooltipTrigger asChild>
1110
1219
  <button
1111
1220
  onClick={handleDisconnect}
1112
- className="ms-auto rounded border border-border px-2.5 py-1 text-[10px] font-medium text-muted-foreground hover:bg-destructive/10 hover:text-destructive hover:border-destructive/40"
1221
+ className={cn(
1222
+ pillButtonClass(isPage, "outline"),
1223
+ "ms-auto text-muted-foreground hover:bg-destructive/10 hover:text-destructive hover:border-destructive/40",
1224
+ )}
1113
1225
  >
1114
1226
  Disconnect
1115
1227
  </button>
@@ -1122,23 +1234,43 @@ function LLMSectionInner({
1122
1234
  )}
1123
1235
  </div>
1124
1236
  {testResult && testResult.ok && (
1125
- <p className="flex items-center gap-1 text-[10px] text-green-500">
1126
- <IconCheck size={10} />
1237
+ <p
1238
+ className={cn(
1239
+ "flex items-center gap-1 text-green-500",
1240
+ isPage ? "text-xs" : "text-[10px]",
1241
+ )}
1242
+ >
1243
+ <IconCheck size={isPage ? 14 : 10} />
1127
1244
  Test passed — {testResult.latencyMs}ms
1128
1245
  </p>
1129
1246
  )}
1130
1247
  {testResult && testResult.ok === false && (
1131
- <p className="text-[10px] text-destructive">
1248
+ <p
1249
+ className={cn(
1250
+ "text-destructive",
1251
+ isPage ? "text-xs" : "text-[10px]",
1252
+ )}
1253
+ >
1132
1254
  Test failed: {testResult.error}
1133
1255
  </p>
1134
1256
  )}
1135
1257
  {disconnectError && (
1136
- <p className="text-[10px] text-destructive">
1258
+ <p
1259
+ className={cn(
1260
+ "text-destructive",
1261
+ isPage ? "text-xs" : "text-[10px]",
1262
+ )}
1263
+ >
1137
1264
  Disconnect failed: {disconnectError}
1138
1265
  </p>
1139
1266
  )}
1140
1267
  {applyNote && (
1141
- <p className="text-[10px] text-muted-foreground">
1268
+ <p
1269
+ className={cn(
1270
+ "text-muted-foreground",
1271
+ isPage ? "text-xs" : "text-[10px]",
1272
+ )}
1273
+ >
1142
1274
  Changes take effect on next conversation
1143
1275
  </p>
1144
1276
  )}
@@ -2404,6 +2536,7 @@ interface SettingsPanelContentProps extends SettingsPanelProps {
2404
2536
  sections?: readonly SettingsSectionId[];
2405
2537
  showCapabilityStrip?: boolean;
2406
2538
  className?: string;
2539
+ surface?: SettingsSurface;
2407
2540
  }
2408
2541
 
2409
2542
  function SettingsPanelContent({
@@ -2416,6 +2549,7 @@ function SettingsPanelContent({
2416
2549
  sections = ALL_SETTINGS_SECTIONS,
2417
2550
  showCapabilityStrip = true,
2418
2551
  className,
2552
+ surface = "sidebar",
2419
2553
  }: SettingsPanelContentProps) {
2420
2554
  const { status: builder, loading: builderLoading } = useBuilderStatus();
2421
2555
  const connected = builder?.configured ?? false;
@@ -2500,225 +2634,300 @@ function SettingsPanelContent({
2500
2634
  return () => window.removeEventListener("hashchange", handleHash);
2501
2635
  }, [openSettingsSection, shouldShowSection]);
2502
2636
 
2637
+ const isPage = surface === "page";
2638
+
2503
2639
  return (
2504
- <div
2505
- className={cn("flex-1 min-h-0 overflow-y-auto p-3 space-y-2", className)}
2506
- style={{ overflowY: "auto" }}
2507
- >
2508
- {/* Agent capability mode (App vs Code) + app link */}
2509
- {(showDevToggle || devAppUrl) && (
2510
- <div className="space-y-2 pb-2 border-b border-border mb-2">
2511
- {showDevToggle && (
2512
- <SettingsSelect
2513
- label="Agent mode"
2514
- labelAdornment={
2515
- devAppUrl ? (
2516
- <Tooltip>
2517
- <TooltipTrigger asChild>
2518
- <a
2519
- href={devAppUrl}
2520
- target="_blank"
2521
- rel="noopener noreferrer"
2522
- aria-label="Open app in new tab"
2523
- className="flex items-center text-muted-foreground hover:text-foreground"
2524
- >
2525
- <IconExternalLink size={14} />
2526
- </a>
2527
- </TooltipTrigger>
2528
- <TooltipContent>Open app in new tab</TooltipContent>
2529
- </Tooltip>
2530
- ) : undefined
2531
- }
2532
- value={isDevMode ? "development" : "production"}
2533
- options={agentModeOptions}
2534
- onValueChange={(next) => {
2535
- const nextIsDev = next === "development";
2536
- if (nextIsDev !== isDevMode) onToggleDevMode();
2537
- }}
2538
- />
2539
- )}
2540
- </div>
2541
- )}
2640
+ <SettingsSurfaceProvider surface={surface}>
2641
+ <div
2642
+ className={cn(
2643
+ isPage ? "space-y-3" : "flex-1 min-h-0 overflow-y-auto p-3 space-y-2",
2644
+ className,
2645
+ )}
2646
+ style={isPage ? undefined : { overflowY: "auto" }}
2647
+ >
2648
+ {/* Agent capability mode (App vs Code) + app link */}
2649
+ {(showDevToggle || devAppUrl) && (
2650
+ <div className="space-y-2 pb-2 border-b border-border mb-2">
2651
+ {showDevToggle && (
2652
+ <SettingsSelect
2653
+ label="Agent mode"
2654
+ labelAdornment={
2655
+ devAppUrl ? (
2656
+ <Tooltip>
2657
+ <TooltipTrigger asChild>
2658
+ <a
2659
+ href={devAppUrl}
2660
+ target="_blank"
2661
+ rel="noopener noreferrer"
2662
+ aria-label="Open app in new tab"
2663
+ className="flex items-center text-muted-foreground hover:text-foreground"
2664
+ >
2665
+ <IconExternalLink size={14} />
2666
+ </a>
2667
+ </TooltipTrigger>
2668
+ <TooltipContent>Open app in new tab</TooltipContent>
2669
+ </Tooltip>
2670
+ ) : undefined
2671
+ }
2672
+ value={isDevMode ? "development" : "production"}
2673
+ options={agentModeOptions}
2674
+ onValueChange={(next) => {
2675
+ const nextIsDev = next === "development";
2676
+ if (nextIsDev !== isDevMode) onToggleDevMode();
2677
+ }}
2678
+ />
2679
+ )}
2680
+ </div>
2681
+ )}
2542
2682
 
2543
- {showCapabilityStrip && (
2544
- <CapabilityStatusStrip
2545
- isDevMode={isDevMode}
2546
- builderConnected={connected}
2547
- builderLoading={builderLoading}
2548
- builderBranchesAvailable={builderBranchesAvailable}
2549
- onOpenLlm={() => openSettingsSection("llm", true)}
2550
- />
2551
- )}
2683
+ {showCapabilityStrip && (
2684
+ <CapabilityStatusStrip
2685
+ isDevMode={isDevMode}
2686
+ builderConnected={connected}
2687
+ builderLoading={builderLoading}
2688
+ builderBranchesAvailable={builderBranchesAvailable}
2689
+ onOpenLlm={() => openSettingsSection("llm", true)}
2690
+ />
2691
+ )}
2552
2692
 
2553
- {/* Account */}
2554
- {shouldShowSection("account") && (
2555
- <AccountSectionInner
2556
- open={openSection === "account"}
2557
- onToggle={() => toggle("account")}
2558
- />
2559
- )}
2693
+ {/* Account */}
2694
+ {shouldShowSection("account") && (
2695
+ <AccountSectionInner
2696
+ open={openSection === "account"}
2697
+ onToggle={() => toggle("account")}
2698
+ />
2699
+ )}
2560
2700
 
2561
- {/* LLM */}
2562
- {shouldShowSection("llm") && (
2563
- <LLMSectionInner
2564
- builderFlow={builderFlow}
2565
- builderLoading={builderLoading}
2566
- connectUrl={connectUrl}
2567
- connected={connected}
2568
- orgName={orgName}
2569
- envManaged={envManaged}
2570
- credentialSource={credentialSource}
2571
- open={openSection === "llm"}
2572
- onToggle={() => toggle("llm")}
2573
- />
2574
- )}
2701
+ {/* LLM */}
2702
+ {shouldShowSection("llm") && (
2703
+ <LLMSectionInner
2704
+ builderFlow={builderFlow}
2705
+ builderLoading={builderLoading}
2706
+ connectUrl={connectUrl}
2707
+ connected={connected}
2708
+ orgName={orgName}
2709
+ envManaged={envManaged}
2710
+ credentialSource={credentialSource}
2711
+ open={openSection === "llm"}
2712
+ onToggle={() => toggle("llm")}
2713
+ />
2714
+ )}
2575
2715
 
2576
- {/* App default model */}
2577
- {shouldShowSection("app-models") && (
2578
- <AppModelDefaultsSectionInner
2579
- open={openSection === "app-models"}
2580
- onToggle={() => toggle("app-models")}
2581
- />
2582
- )}
2716
+ {/* App default model */}
2717
+ {shouldShowSection("app-models") && (
2718
+ <AppModelDefaultsSectionInner
2719
+ open={openSection === "app-models"}
2720
+ onToggle={() => toggle("app-models")}
2721
+ />
2722
+ )}
2583
2723
 
2584
- {/* Agent limits */}
2585
- {shouldShowSection("limits") && (
2586
- <AgentLimitsSectionInner
2587
- open={openSection === "limits"}
2588
- onToggle={() => toggle("limits")}
2589
- />
2590
- )}
2724
+ {/* Agent limits */}
2725
+ {shouldShowSection("limits") && (
2726
+ <AgentLimitsSectionInner
2727
+ open={openSection === "limits"}
2728
+ onToggle={() => toggle("limits")}
2729
+ />
2730
+ )}
2591
2731
 
2592
- {/* Voice transcription */}
2593
- {shouldShowSection("voice") && (
2594
- <SettingsSection
2595
- id={settingsSectionDomId("voice")}
2596
- icon={<IconMicrophone size={14} />}
2597
- title="Voice Transcription"
2598
- subtitle="How the composer microphone turns your voice into text."
2599
- open={openSection === "voice"}
2600
- onToggle={() => toggle("voice")}
2601
- >
2602
- <VoiceTranscriptionSection />
2603
- </SettingsSection>
2604
- )}
2732
+ {/* Voice transcription */}
2733
+ {shouldShowSection("voice") && (
2734
+ <SettingsSection
2735
+ id={settingsSectionDomId("voice")}
2736
+ icon={<IconMicrophone size={14} />}
2737
+ title="Voice Transcription"
2738
+ subtitle="How the composer microphone turns your voice into text."
2739
+ open={openSection === "voice"}
2740
+ onToggle={() => toggle("voice")}
2741
+ >
2742
+ <VoiceTranscriptionSection />
2743
+ </SettingsSection>
2744
+ )}
2605
2745
 
2606
- {/* Demo mode */}
2607
- {shouldShowSection("demo-mode") && (
2608
- <SettingsSection
2609
- id={settingsSectionDomId("demo-mode")}
2610
- icon={<IconEyeOff size={14} />}
2611
- title="Demo mode"
2612
- subtitle="Replace names, emails, and numbers with realistic fake data everywhere — in the UI and what the agent sees. IDs and structure are preserved so the app keeps working."
2613
- open={openSection === "demo-mode"}
2614
- onToggle={() => toggle("demo-mode")}
2615
- >
2616
- <DemoModeSection />
2617
- </SettingsSection>
2618
- )}
2746
+ {/* Demo mode */}
2747
+ {shouldShowSection("demo-mode") && (
2748
+ <SettingsSection
2749
+ id={settingsSectionDomId("demo-mode")}
2750
+ icon={<IconEyeOff size={14} />}
2751
+ title="Demo mode"
2752
+ subtitle="Replace names, emails, and numbers with realistic fake data everywhere — in the UI and what the agent sees. IDs and structure are preserved so the app keeps working."
2753
+ open={openSection === "demo-mode"}
2754
+ onToggle={() => toggle("demo-mode")}
2755
+ >
2756
+ <DemoModeSection />
2757
+ </SettingsSection>
2758
+ )}
2619
2759
 
2620
- {/* Automations */}
2621
- {shouldShowSection("automations") && (
2622
- <SettingsSection
2623
- id={settingsSectionDomId("automations")}
2624
- icon={<IconBolt size={14} />}
2625
- title="Automations"
2626
- subtitle="Event-triggered and scheduled automations."
2627
- open={openSection === "automations"}
2628
- onToggle={() => toggle("automations")}
2629
- >
2630
- <AutomationsSection />
2631
- </SettingsSection>
2632
- )}
2760
+ {/* Automations */}
2761
+ {shouldShowSection("automations") && (
2762
+ <SettingsSection
2763
+ id={settingsSectionDomId("automations")}
2764
+ icon={<IconBolt size={14} />}
2765
+ title="Automations"
2766
+ subtitle="Event-triggered and scheduled automations."
2767
+ open={openSection === "automations"}
2768
+ onToggle={() => toggle("automations")}
2769
+ >
2770
+ <AutomationsSection />
2771
+ </SettingsSection>
2772
+ )}
2633
2773
 
2634
- {/* API Keys & Connections */}
2635
- {shouldShowSection("secrets") && (
2636
- <SettingsSection
2637
- id={settingsSectionDomId("secrets")}
2638
- icon={<IconKey size={14} />}
2639
- title="API Keys & Connections"
2640
- subtitle="Service credentials and automation keys."
2641
- open={openSection === "secrets"}
2642
- onToggle={() => toggle("secrets")}
2643
- >
2644
- <SecretsSection focusKey={focusSecretKey} />
2645
- </SettingsSection>
2646
- )}
2774
+ {/* API Keys & Connections */}
2775
+ {shouldShowSection("secrets") && (
2776
+ <SettingsSection
2777
+ id={settingsSectionDomId("secrets")}
2778
+ icon={<IconKey size={14} />}
2779
+ title="API Keys & Connections"
2780
+ subtitle="Service credentials and automation keys."
2781
+ open={openSection === "secrets"}
2782
+ onToggle={() => toggle("secrets")}
2783
+ >
2784
+ <SecretsSection focusKey={focusSecretKey} />
2785
+ </SettingsSection>
2786
+ )}
2647
2787
 
2648
- {/* Hosting */}
2649
- {shouldShowSection("hosting") && (
2650
- <SettingsSection
2651
- id={settingsSectionDomId("hosting")}
2652
- icon={<IconCloud size={14} />}
2653
- title="Hosting"
2654
- subtitle="Deploy your app to the cloud."
2655
- connected={connected}
2656
- open={openSection === "hosting"}
2657
- onToggle={() => toggle("hosting")}
2658
- >
2659
- <div className="space-y-2">
2660
- <UseBuilderCard
2661
- builderFlow={builderFlow}
2662
- connectUrl={connectUrl}
2663
- connected={connected}
2664
- orgName={orgName}
2665
- envManaged={envManaged}
2666
- credentialSource={credentialSource}
2667
- trackingSource="hosting_settings"
2668
- trackingFlow="hosting"
2669
- />
2670
- <ManualSetupCard
2671
- hint="Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target."
2672
- docsUrl="https://www.builder.io/c/docs/agent-native-deployment"
2673
- dim={connected}
2674
- />
2675
- </div>
2676
- </SettingsSection>
2677
- )}
2788
+ {/* Hosting */}
2789
+ {shouldShowSection("hosting") && (
2790
+ <SettingsSection
2791
+ id={settingsSectionDomId("hosting")}
2792
+ icon={<IconCloud size={14} />}
2793
+ title="Hosting"
2794
+ subtitle="Deploy your app to the cloud."
2795
+ connected={connected}
2796
+ open={openSection === "hosting"}
2797
+ onToggle={() => toggle("hosting")}
2798
+ >
2799
+ <div className="space-y-2">
2800
+ <UseBuilderCard
2801
+ builderFlow={builderFlow}
2802
+ connectUrl={connectUrl}
2803
+ connected={connected}
2804
+ orgName={orgName}
2805
+ envManaged={envManaged}
2806
+ credentialSource={credentialSource}
2807
+ trackingSource="hosting_settings"
2808
+ trackingFlow="hosting"
2809
+ />
2810
+ <ManualSetupCard
2811
+ hint="Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target."
2812
+ docsUrl="https://www.builder.io/c/docs/agent-native-deployment"
2813
+ dim={connected}
2814
+ />
2815
+ </div>
2816
+ </SettingsSection>
2817
+ )}
2678
2818
 
2679
- {/* Database */}
2680
- {shouldShowSection("database") && (
2681
- <SettingsSection
2682
- id={settingsSectionDomId("database")}
2683
- icon={<IconDatabase size={14} />}
2684
- title="Database"
2685
- subtitle="Connect a cloud database for persistent storage."
2686
- connected={connected}
2687
- open={openSection === "database"}
2688
- onToggle={() => toggle("database")}
2689
- >
2690
- <div className="space-y-2">
2691
- <UseBuilderCard
2692
- builderFlow={builderFlow}
2693
- connectUrl={connectUrl}
2694
- connected={connected}
2695
- orgName={orgName}
2696
- envManaged={envManaged}
2697
- credentialSource={credentialSource}
2698
- trackingSource="database_settings"
2699
- trackingFlow="database"
2700
- />
2701
- <ManualSetupCard
2702
- hint="Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite."
2703
- docsUrl="https://www.builder.io/c/docs/agent-native-database"
2704
- dim={connected}
2705
- />
2706
- </div>
2707
- </SettingsSection>
2708
- )}
2819
+ {/* Database */}
2820
+ {shouldShowSection("database") && (
2821
+ <SettingsSection
2822
+ id={settingsSectionDomId("database")}
2823
+ icon={<IconDatabase size={14} />}
2824
+ title="Database"
2825
+ subtitle="Connect a cloud database for persistent storage."
2826
+ connected={connected}
2827
+ open={openSection === "database"}
2828
+ onToggle={() => toggle("database")}
2829
+ >
2830
+ <div className="space-y-2">
2831
+ <UseBuilderCard
2832
+ builderFlow={builderFlow}
2833
+ connectUrl={connectUrl}
2834
+ connected={connected}
2835
+ orgName={orgName}
2836
+ envManaged={envManaged}
2837
+ credentialSource={credentialSource}
2838
+ trackingSource="database_settings"
2839
+ trackingFlow="database"
2840
+ />
2841
+ <ManualSetupCard
2842
+ hint="Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite."
2843
+ docsUrl="https://www.builder.io/c/docs/agent-native-database"
2844
+ dim={connected}
2845
+ />
2846
+ </div>
2847
+ </SettingsSection>
2848
+ )}
2709
2849
 
2710
- {/* File uploads */}
2711
- {shouldShowSection("uploads") && (
2712
- <SettingsSection
2713
- id={settingsSectionDomId("uploads")}
2714
- icon={<IconUpload size={14} />}
2715
- title="File uploads"
2716
- subtitle="Where user-uploaded files (avatars, chat attachments) are stored."
2717
- connected={connected}
2718
- open={openSection === "uploads"}
2719
- onToggle={() => toggle("uploads")}
2720
- >
2721
- <div className="space-y-2">
2850
+ {/* File uploads */}
2851
+ {shouldShowSection("uploads") && (
2852
+ <SettingsSection
2853
+ id={settingsSectionDomId("uploads")}
2854
+ icon={<IconUpload size={14} />}
2855
+ title="File uploads"
2856
+ subtitle="Where user-uploaded files (avatars, chat attachments) are stored."
2857
+ connected={connected}
2858
+ open={openSection === "uploads"}
2859
+ onToggle={() => toggle("uploads")}
2860
+ >
2861
+ <div className="space-y-2">
2862
+ <UseBuilderCard
2863
+ builderFlow={builderFlow}
2864
+ connectUrl={connectUrl}
2865
+ connected={connected}
2866
+ orgName={orgName}
2867
+ envManaged={envManaged}
2868
+ credentialSource={credentialSource}
2869
+ trackingSource="file_upload_settings"
2870
+ trackingFlow="file_upload"
2871
+ />
2872
+ <ManualSetupCard
2873
+ hint="Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production."
2874
+ docsUrl="https://www.builder.io/c/docs/agent-native-file-uploads"
2875
+ dim={connected}
2876
+ />
2877
+ </div>
2878
+ </SettingsSection>
2879
+ )}
2880
+
2881
+ {/* Authentication */}
2882
+ {shouldShowSection("auth") && (
2883
+ <SettingsSection
2884
+ id={settingsSectionDomId("auth")}
2885
+ icon={<IconShield size={14} />}
2886
+ title="Authentication"
2887
+ subtitle="Set up user authentication and access control."
2888
+ connected={connected}
2889
+ open={openSection === "auth"}
2890
+ onToggle={() => toggle("auth")}
2891
+ >
2892
+ <div className="space-y-2">
2893
+ <UseBuilderCard
2894
+ builderFlow={builderFlow}
2895
+ connectUrl={connectUrl}
2896
+ connected={connected}
2897
+ orgName={orgName}
2898
+ envManaged={envManaged}
2899
+ credentialSource={credentialSource}
2900
+ trackingSource="auth_settings"
2901
+ trackingFlow="auth"
2902
+ />
2903
+ <ManualSetupCard
2904
+ hint="Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers."
2905
+ docsUrl="https://www.builder.io/c/docs/agent-native-authentication"
2906
+ dim={connected}
2907
+ />
2908
+ </div>
2909
+ </SettingsSection>
2910
+ )}
2911
+
2912
+ {/* Email */}
2913
+ {shouldShowSection("email") && (
2914
+ <EmailSectionInner
2915
+ open={openSection === "email"}
2916
+ onToggle={() => toggle("email")}
2917
+ />
2918
+ )}
2919
+
2920
+ {/* Browser Automation */}
2921
+ {shouldShowSection("browser") && (
2922
+ <SettingsSection
2923
+ id={settingsSectionDomId("browser")}
2924
+ icon={<IconBrowser size={14} />}
2925
+ title="Browser Automation"
2926
+ subtitle="Let agents control a real browser for web tasks."
2927
+ connected={connected}
2928
+ open={openSection === "browser"}
2929
+ onToggle={() => toggle("browser")}
2930
+ >
2722
2931
  <UseBuilderCard
2723
2932
  builderFlow={builderFlow}
2724
2933
  connectUrl={connectUrl}
@@ -2726,30 +2935,22 @@ function SettingsPanelContent({
2726
2935
  orgName={orgName}
2727
2936
  envManaged={envManaged}
2728
2937
  credentialSource={credentialSource}
2729
- trackingSource="file_upload_settings"
2730
- trackingFlow="file_upload"
2731
- />
2732
- <ManualSetupCard
2733
- hint="Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production."
2734
- docsUrl="https://www.builder.io/c/docs/agent-native-file-uploads"
2735
- dim={connected}
2938
+ trackingSource="browser_settings"
2939
+ trackingFlow="browser_automation"
2736
2940
  />
2737
- </div>
2738
- </SettingsSection>
2739
- )}
2941
+ </SettingsSection>
2942
+ )}
2740
2943
 
2741
- {/* Authentication */}
2742
- {shouldShowSection("auth") && (
2743
- <SettingsSection
2744
- id={settingsSectionDomId("auth")}
2745
- icon={<IconShield size={14} />}
2746
- title="Authentication"
2747
- subtitle="Set up user authentication and access control."
2748
- connected={connected}
2749
- open={openSection === "auth"}
2750
- onToggle={() => toggle("auth")}
2751
- >
2752
- <div className="space-y-2">
2944
+ {builderBranchesAvailable && shouldShowSection("background") && (
2945
+ <SettingsSection
2946
+ id={settingsSectionDomId("background")}
2947
+ icon={<IconGitBranch size={14} />}
2948
+ title="Background Agent"
2949
+ subtitle="Make code changes from production mode via Builder."
2950
+ connected={connected}
2951
+ open={openSection === "background"}
2952
+ onToggle={() => toggle("background")}
2953
+ >
2753
2954
  <UseBuilderCard
2754
2955
  builderFlow={builderFlow}
2755
2956
  connectUrl={connectUrl}
@@ -2757,117 +2958,57 @@ function SettingsPanelContent({
2757
2958
  orgName={orgName}
2758
2959
  envManaged={envManaged}
2759
2960
  credentialSource={credentialSource}
2760
- trackingSource="auth_settings"
2761
- trackingFlow="auth"
2762
- />
2763
- <ManualSetupCard
2764
- hint="Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers."
2765
- docsUrl="https://www.builder.io/c/docs/agent-native-authentication"
2766
- dim={connected}
2961
+ trackingSource="background_agent_settings"
2962
+ trackingFlow="background_agent"
2767
2963
  />
2768
- </div>
2769
- </SettingsSection>
2770
- )}
2771
-
2772
- {/* Email */}
2773
- {shouldShowSection("email") && (
2774
- <EmailSectionInner
2775
- open={openSection === "email"}
2776
- onToggle={() => toggle("email")}
2777
- />
2778
- )}
2779
-
2780
- {/* Browser Automation */}
2781
- {shouldShowSection("browser") && (
2782
- <SettingsSection
2783
- id={settingsSectionDomId("browser")}
2784
- icon={<IconBrowser size={14} />}
2785
- title="Browser Automation"
2786
- subtitle="Let agents control a real browser for web tasks."
2787
- connected={connected}
2788
- open={openSection === "browser"}
2789
- onToggle={() => toggle("browser")}
2790
- >
2791
- <UseBuilderCard
2792
- builderFlow={builderFlow}
2793
- connectUrl={connectUrl}
2794
- connected={connected}
2795
- orgName={orgName}
2796
- envManaged={envManaged}
2797
- credentialSource={credentialSource}
2798
- trackingSource="browser_settings"
2799
- trackingFlow="browser_automation"
2800
- />
2801
- </SettingsSection>
2802
- )}
2803
-
2804
- {builderBranchesAvailable && shouldShowSection("background") && (
2805
- <SettingsSection
2806
- id={settingsSectionDomId("background")}
2807
- icon={<IconGitBranch size={14} />}
2808
- title="Background Agent"
2809
- subtitle="Make code changes from production mode via Builder."
2810
- connected={connected}
2811
- open={openSection === "background"}
2812
- onToggle={() => toggle("background")}
2813
- >
2814
- <UseBuilderCard
2815
- builderFlow={builderFlow}
2816
- connectUrl={connectUrl}
2817
- connected={connected}
2818
- orgName={orgName}
2819
- envManaged={envManaged}
2820
- credentialSource={credentialSource}
2821
- trackingSource="background_agent_settings"
2822
- trackingFlow="background_agent"
2823
- />
2824
- </SettingsSection>
2825
- )}
2964
+ </SettingsSection>
2965
+ )}
2826
2966
 
2827
- {/* Integrations */}
2828
- {shouldShowSection("integrations") && (
2829
- <SettingsSection
2830
- id={settingsSectionDomId("integrations")}
2831
- icon={<IconPlugConnected size={14} />}
2832
- title="Integrations"
2833
- subtitle="Connect messaging platforms and external services."
2834
- open={openSection === "integrations"}
2835
- onToggle={() => toggle("integrations")}
2836
- >
2837
- <Suspense fallback={null}>
2838
- <IntegrationsPanel />
2839
- </Suspense>
2840
- </SettingsSection>
2841
- )}
2967
+ {/* Integrations */}
2968
+ {shouldShowSection("integrations") && (
2969
+ <SettingsSection
2970
+ id={settingsSectionDomId("integrations")}
2971
+ icon={<IconPlugConnected size={14} />}
2972
+ title="Integrations"
2973
+ subtitle="Connect messaging platforms and external services."
2974
+ open={openSection === "integrations"}
2975
+ onToggle={() => toggle("integrations")}
2976
+ >
2977
+ <Suspense fallback={null}>
2978
+ <IntegrationsPanel />
2979
+ </Suspense>
2980
+ </SettingsSection>
2981
+ )}
2842
2982
 
2843
- {/* Usage & spend */}
2844
- {shouldShowSection("usage") && (
2845
- <SettingsSection
2846
- id={settingsSectionDomId("usage")}
2847
- icon={<IconCoin size={14} />}
2848
- title="Usage"
2849
- subtitle="Track token consumption and estimated cost — broken down by chat, automations, and background jobs."
2850
- open={openSection === "usage"}
2851
- onToggle={() => toggle("usage")}
2852
- >
2853
- <UsageSection />
2854
- </SettingsSection>
2855
- )}
2983
+ {/* Usage & spend */}
2984
+ {shouldShowSection("usage") && (
2985
+ <SettingsSection
2986
+ id={settingsSectionDomId("usage")}
2987
+ icon={<IconCoin size={14} />}
2988
+ title="Usage"
2989
+ subtitle="Track token consumption and estimated cost — broken down by chat, automations, and background jobs."
2990
+ open={openSection === "usage"}
2991
+ onToggle={() => toggle("usage")}
2992
+ >
2993
+ <UsageSection />
2994
+ </SettingsSection>
2995
+ )}
2856
2996
 
2857
- {/* A2A Agents */}
2858
- {shouldShowSection("a2a") && (
2859
- <SettingsSection
2860
- id={settingsSectionDomId("a2a")}
2861
- icon={<IconTopologyRing2 size={14} />}
2862
- title="Connected Agents (A2A)"
2863
- subtitle="Manage remote agents connected via the A2A protocol."
2864
- open={openSection === "a2a"}
2865
- onToggle={() => toggle("a2a")}
2866
- >
2867
- <AgentsSection />
2868
- </SettingsSection>
2869
- )}
2870
- </div>
2997
+ {/* A2A Agents */}
2998
+ {shouldShowSection("a2a") && (
2999
+ <SettingsSection
3000
+ id={settingsSectionDomId("a2a")}
3001
+ icon={<IconTopologyRing2 size={14} />}
3002
+ title="Connected Agents (A2A)"
3003
+ subtitle="Manage remote agents connected via the A2A protocol."
3004
+ open={openSection === "a2a"}
3005
+ onToggle={() => toggle("a2a")}
3006
+ >
3007
+ <AgentsSection />
3008
+ </SettingsSection>
3009
+ )}
3010
+ </div>
3011
+ </SettingsSurfaceProvider>
2871
3012
  );
2872
3013
  }
2873
3014
 
@@ -2899,9 +3040,10 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
2899
3040
  content: (
2900
3041
  <SettingsPanelContent
2901
3042
  {...baseProps}
3043
+ surface="page"
2902
3044
  sections={AGENT_SETTINGS_SECTIONS}
2903
3045
  showCapabilityStrip={false}
2904
- className="mx-auto w-full max-w-3xl p-0"
3046
+ className="mx-auto w-full max-w-2xl"
2905
3047
  />
2906
3048
  ),
2907
3049
  },
@@ -2914,9 +3056,10 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
2914
3056
  content: (
2915
3057
  <SettingsPanelContent
2916
3058
  {...baseProps}
3059
+ surface="page"
2917
3060
  sections={CONNECTION_SETTINGS_SECTIONS}
2918
3061
  showCapabilityStrip={false}
2919
- className="mx-auto w-full max-w-3xl p-0"
3062
+ className="mx-auto w-full max-w-2xl"
2920
3063
  />
2921
3064
  ),
2922
3065
  },
@@ -2929,9 +3072,10 @@ export function useAgentSettingsTabs(): SettingsTabItem[] {
2929
3072
  content: (
2930
3073
  <SettingsPanelContent
2931
3074
  {...baseProps}
3075
+ surface="page"
2932
3076
  sections={WORKSPACE_SETTINGS_SECTIONS}
2933
3077
  showCapabilityStrip={false}
2934
- className="mx-auto w-full max-w-3xl p-0"
3078
+ className="mx-auto w-full max-w-2xl"
2935
3079
  />
2936
3080
  ),
2937
3081
  },