@agent-native/core 0.112.0 → 0.114.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 (1902) hide show
  1. package/agent-native.eject.json +164 -0
  2. package/corpus/README.md +4 -2
  3. package/corpus/core/CHANGELOG.md +33 -0
  4. package/corpus/core/README.md +61 -174
  5. package/corpus/core/agent-native.eject.json +164 -0
  6. package/corpus/core/docs/AGENTS.md +7 -0
  7. package/corpus/core/docs/content/agent-native-toolkit.mdx +38 -0
  8. package/corpus/core/docs/content/integrations.mdx +63 -2
  9. package/corpus/core/docs/content/package-lifecycle.mdx +54 -4
  10. package/corpus/core/docs/design/provider-integration-authority.md +117 -0
  11. package/corpus/core/package.json +20 -2
  12. package/corpus/core/scripts/materialize-source-corpus.mjs +9 -2
  13. package/corpus/core/src/cli/atomic-json-file.ts +324 -0
  14. package/corpus/core/src/cli/claude-code-participant.ts +515 -0
  15. package/corpus/core/src/cli/code-agent-executor.ts +18 -10
  16. package/corpus/core/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  17. package/corpus/core/src/cli/code-agent-runs.ts +55 -62
  18. package/corpus/core/src/cli/codex-cli-participant.ts +496 -0
  19. package/corpus/core/src/cli/eject.ts +1594 -0
  20. package/corpus/core/src/cli/index.ts +16 -0
  21. package/corpus/core/src/cli/multi-frontier-runs.ts +1246 -135
  22. package/corpus/core/src/client/chat/ChatHistoryList.tsx +7 -404
  23. package/corpus/core/src/client/index.ts +4 -0
  24. package/corpus/core/src/client/resources/McpConnectionSuggestion.tsx +8 -2
  25. package/corpus/core/src/client/resources/McpIntegrationDialog.tsx +7 -2
  26. package/corpus/core/src/client/resources/ResourcesPanel.tsx +17 -3
  27. package/corpus/core/src/client/resources/index.ts +19 -0
  28. package/corpus/core/src/client/resources/mcp-integration-catalog.ts +9 -1
  29. package/corpus/core/src/client/resources/runtime.ts +1 -0
  30. package/corpus/core/src/client/setup-connections/catalog.ts +6 -0
  31. package/corpus/core/src/client/setup-connections/index.ts +1 -0
  32. package/corpus/core/src/client/setup-connections/runtime.ts +1 -0
  33. package/corpus/core/src/connections/catalog.ts +41 -24
  34. package/corpus/core/src/connections/index.ts +1 -0
  35. package/corpus/core/src/connections/runtime.ts +1 -0
  36. package/corpus/core/src/eject/provider-api-definitions.ts +193 -0
  37. package/corpus/core/src/eject/remote-mcp-presets.ts +137 -0
  38. package/corpus/core/src/eject/setup-readiness-ui.tsx +29 -0
  39. package/corpus/core/src/eject/workspace-connections.ts +92 -0
  40. package/corpus/core/src/index.ts +1 -0
  41. package/corpus/core/src/integrations/adapter-overrides.ts +12 -0
  42. package/corpus/core/src/integrations/eject/messaging-adapters.ts +85 -0
  43. package/corpus/core/src/integrations/index.ts +15 -1
  44. package/corpus/core/src/integrations/plugin.ts +34 -12
  45. package/corpus/core/src/integrations/runtime.ts +1 -0
  46. package/corpus/core/src/integrations/slack-oauth.ts +1 -0
  47. package/corpus/core/src/integrations/types.ts +3 -1
  48. package/corpus/core/src/integrations/webhook-delivery.ts +55 -0
  49. package/corpus/core/src/notifications/channels.ts +4 -10
  50. package/corpus/core/src/package-lifecycle/eject-manifest.ts +345 -0
  51. package/corpus/core/src/package-lifecycle/index.ts +1 -0
  52. package/corpus/core/src/provider-api/actions/custom-provider-registration.ts +197 -0
  53. package/corpus/core/src/provider-api/actions/delete-staged-dataset.ts +3 -42
  54. package/corpus/core/src/provider-api/actions/list-staged-datasets.ts +3 -45
  55. package/corpus/core/src/provider-api/actions/provider-api-audit.ts +88 -0
  56. package/corpus/core/src/provider-api/actions/provider-api.ts +460 -0
  57. package/corpus/core/src/provider-api/actions/query-staged-dataset.ts +3 -140
  58. package/corpus/core/src/provider-api/actions/staged-datasets.ts +359 -0
  59. package/corpus/core/src/provider-api/gong.ts +108 -0
  60. package/corpus/core/src/provider-api/index.ts +46 -12
  61. package/corpus/core/src/provider-api/runtime.ts +1 -0
  62. package/corpus/core/src/scripts/docs/source-search.ts +2 -1
  63. package/corpus/core/src/server/google-oauth-credentials.ts +80 -3
  64. package/corpus/core/src/server/index.ts +6 -0
  65. package/corpus/core/src/setup-connections/index.ts +1 -0
  66. package/corpus/core/src/shared/merge-by-id.ts +14 -0
  67. package/corpus/core/src/styles/chat-history-list.css +1 -313
  68. package/corpus/core/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  69. package/corpus/core/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +21 -9
  70. package/corpus/core/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  71. package/corpus/core/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  72. package/corpus/core/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  73. package/corpus/core/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  74. package/corpus/core/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +14 -2
  75. package/corpus/core/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  76. package/corpus/core/src/templates/default/AGENTS.md +26 -18
  77. package/corpus/core/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  78. package/corpus/core/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +21 -9
  79. package/corpus/core/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  80. package/corpus/core/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  81. package/corpus/core/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  82. package/corpus/core/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  83. package/corpus/core/src/templates/headless/AGENTS.md +8 -0
  84. package/corpus/core/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  85. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +21 -9
  86. package/corpus/core/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +7 -0
  87. package/corpus/core/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  88. package/corpus/core/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +14 -2
  89. package/corpus/core/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  90. package/corpus/core/src/templates/workspace-core/AGENTS.md +4 -0
  91. package/corpus/core/src/templates/workspace-root/AGENTS.md +4 -0
  92. package/corpus/core/src/vite/client.ts +25 -2
  93. package/corpus/templates/analytics/.agents/skills/actions/SKILL.md +32 -12
  94. package/corpus/templates/analytics/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  95. package/corpus/templates/analytics/.agents/skills/self-modifying-code/SKILL.md +14 -2
  96. package/corpus/templates/analytics/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  97. package/corpus/templates/analytics/actions/delete-staged-dataset.ts +3 -23
  98. package/corpus/templates/analytics/actions/list-staged-datasets.ts +3 -27
  99. package/corpus/templates/analytics/actions/provider-api-catalog.ts +16 -19
  100. package/corpus/templates/analytics/actions/provider-api-docs.ts +3 -5
  101. package/corpus/templates/analytics/actions/provider-api-request.ts +162 -185
  102. package/corpus/templates/analytics/actions/query-staged-dataset.ts +3 -47
  103. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +52 -161
  104. package/corpus/templates/assets/.agents/skills/actions/SKILL.md +32 -12
  105. package/corpus/templates/assets/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  106. package/corpus/templates/assets/.agents/skills/self-modifying-code/SKILL.md +14 -2
  107. package/corpus/templates/assets/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  108. package/corpus/templates/assets/app/components/layout/Sidebar.tsx +63 -160
  109. package/corpus/templates/brain/.agents/skills/actions/SKILL.md +32 -12
  110. package/corpus/templates/brain/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  111. package/corpus/templates/brain/.agents/skills/self-modifying-code/SKILL.md +14 -2
  112. package/corpus/templates/brain/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  113. package/corpus/templates/brain/actions/_schemas.ts +13 -7
  114. package/corpus/templates/brain/actions/delete-staged-dataset.ts +3 -24
  115. package/corpus/templates/brain/actions/list-staged-datasets.ts +3 -28
  116. package/corpus/templates/brain/actions/provider-api-catalog.ts +5 -11
  117. package/corpus/templates/brain/actions/provider-api-docs.ts +3 -5
  118. package/corpus/templates/brain/actions/provider-api-request.ts +3 -37
  119. package/corpus/templates/brain/actions/query-staged-dataset.ts +3 -48
  120. package/corpus/templates/brain/actions/remediate-legacy-capture-audiences.ts +167 -0
  121. package/corpus/templates/brain/actions/update-source.ts +5 -1
  122. package/corpus/templates/brain/app/components/layout/Sidebar.tsx +48 -154
  123. package/corpus/templates/brain/app/lib/brain-chat-readiness.ts +6 -0
  124. package/corpus/templates/brain/app/lib/brain.ts +55 -0
  125. package/corpus/templates/brain/app/lib/ingest-handoff.ts +35 -0
  126. package/corpus/templates/brain/app/routes/_index.tsx +8 -0
  127. package/corpus/templates/brain/app/routes.ts +1 -0
  128. package/corpus/templates/brain/changelog/2026-07-19-ask-starts-immediately-when-builder-s-managed-ai-connection-.md +6 -0
  129. package/corpus/templates/brain/changelog/2026-07-19-slack-and-granola-backfills-now-process-captures-concurrentl.md +6 -0
  130. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-can-now-join-configured-public-channels-befo.md +6 -0
  131. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-continue-across-the-configured-number-of.md +6 -0
  132. package/corpus/templates/brain/changelog/2026-07-19-slack-backfills-now-start-with-a-safe-four-week-window-and-r.md +6 -0
  133. package/corpus/templates/brain/changelog/2026-07-19-source-review-settings-now-control-knowledge-approval.md +6 -0
  134. package/corpus/templates/brain/changelog/2026-07-19-the-manage-agent-page-now-opens-correctly-from-brain-navigat.md +6 -0
  135. package/corpus/templates/brain/server/db/schema.ts +3 -0
  136. package/corpus/templates/brain/server/lib/brain.ts +41 -2
  137. package/corpus/templates/brain/server/lib/connectors.ts +432 -115
  138. package/corpus/templates/brain/server/lib/meeting-audience.ts +38 -0
  139. package/corpus/templates/brain/server/lib/slack-channel-membership.ts +44 -0
  140. package/corpus/templates/brain/server/plugins/db.ts +10 -0
  141. package/corpus/templates/brain/server/routes/api/_agent-native/brain/ingest.post.ts +6 -4
  142. package/corpus/templates/brain/shared/slack-source-config.ts +60 -0
  143. package/corpus/templates/calendar/.agents/skills/actions/SKILL.md +32 -12
  144. package/corpus/templates/calendar/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  145. package/corpus/templates/calendar/.agents/skills/self-modifying-code/SKILL.md +14 -2
  146. package/corpus/templates/calendar/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  147. package/corpus/templates/calendar/actions/delete-staged-dataset.ts +3 -24
  148. package/corpus/templates/calendar/actions/list-staged-datasets.ts +3 -28
  149. package/corpus/templates/calendar/actions/provider-api-catalog.ts +5 -11
  150. package/corpus/templates/calendar/actions/provider-api-docs.ts +3 -5
  151. package/corpus/templates/calendar/actions/provider-api-request.ts +3 -37
  152. package/corpus/templates/calendar/actions/query-staged-dataset.ts +3 -48
  153. package/corpus/templates/calendar/server/handlers/gong.ts +6 -61
  154. package/corpus/templates/calendar/server/handlers/google-auth.ts +10 -8
  155. package/corpus/templates/calendar/server/lib/google-calendar.ts +7 -45
  156. package/corpus/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  157. package/corpus/templates/chat/.agents/skills/agent-native-docs/SKILL.md +21 -9
  158. package/corpus/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  159. package/corpus/templates/chat/.agents/skills/self-modifying-code/SKILL.md +14 -2
  160. package/corpus/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  161. package/corpus/templates/chat/AGENTS.md +6 -2
  162. package/corpus/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  163. package/corpus/templates/clips/.agents/skills/actions/SKILL.md +32 -12
  164. package/corpus/templates/clips/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  165. package/corpus/templates/clips/.agents/skills/self-modifying-code/SKILL.md +14 -2
  166. package/corpus/templates/clips/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  167. package/corpus/templates/clips/AGENTS.md +11 -0
  168. package/corpus/templates/clips/actions/export-to-brain.ts +505 -171
  169. package/corpus/templates/clips/changelog/2026-07-19-ready-clips-transcripts-can-be-backfilled-to-brain-for-a-bou.md +6 -0
  170. package/corpus/templates/clips/server/lib/calendar-event-meetings.ts +1 -1
  171. package/corpus/templates/clips/server/lib/google-calendar-client.ts +12 -22
  172. package/corpus/templates/clips/server/lib/google-calendar-oauth.ts +9 -6
  173. package/corpus/templates/clips/server/lib/slack-oauth.ts +12 -47
  174. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +2 -6
  175. package/corpus/templates/clips/server/routes/api/auth/google-calendar.get.ts +4 -4
  176. package/corpus/templates/content/.agents/skills/actions/SKILL.md +32 -12
  177. package/corpus/templates/content/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  178. package/corpus/templates/content/.agents/skills/self-modifying-code/SKILL.md +14 -2
  179. package/corpus/templates/content/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  180. package/corpus/templates/content/actions/delete-staged-dataset.ts +3 -24
  181. package/corpus/templates/content/actions/list-staged-datasets.ts +3 -28
  182. package/corpus/templates/content/actions/provider-api-catalog.ts +5 -11
  183. package/corpus/templates/content/actions/provider-api-docs.ts +3 -5
  184. package/corpus/templates/content/actions/provider-api-request.ts +3 -37
  185. package/corpus/templates/content/actions/query-staged-dataset.ts +3 -48
  186. package/corpus/templates/design/.agents/skills/actions/SKILL.md +32 -12
  187. package/corpus/templates/design/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  188. package/corpus/templates/design/.agents/skills/self-modifying-code/SKILL.md +14 -2
  189. package/corpus/templates/design/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  190. package/corpus/templates/design/actions/delete-staged-dataset.ts +4 -23
  191. package/corpus/templates/design/actions/list-staged-datasets.ts +4 -27
  192. package/corpus/templates/design/actions/provider-api-catalog.ts +15 -18
  193. package/corpus/templates/design/actions/provider-api-docs.ts +57 -48
  194. package/corpus/templates/design/actions/provider-api-request.ts +140 -164
  195. package/corpus/templates/design/actions/query-staged-dataset.ts +4 -47
  196. package/corpus/templates/dispatch/.agents/skills/actions/SKILL.md +32 -12
  197. package/corpus/templates/dispatch/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  198. package/corpus/templates/dispatch/.agents/skills/self-modifying-code/SKILL.md +14 -2
  199. package/corpus/templates/dispatch/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  200. package/corpus/templates/dispatch/actions/delete-staged-dataset.ts +4 -23
  201. package/corpus/templates/dispatch/actions/list-staged-datasets.ts +4 -30
  202. package/corpus/templates/dispatch/actions/provider-api-catalog.ts +15 -18
  203. package/corpus/templates/dispatch/actions/provider-api-docs.ts +57 -48
  204. package/corpus/templates/dispatch/actions/provider-api-request.ts +138 -163
  205. package/corpus/templates/dispatch/actions/query-staged-dataset.ts +4 -47
  206. package/corpus/templates/forms/.agents/skills/actions/SKILL.md +32 -12
  207. package/corpus/templates/forms/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  208. package/corpus/templates/forms/.agents/skills/self-modifying-code/SKILL.md +14 -2
  209. package/corpus/templates/forms/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  210. package/corpus/templates/forms/server/lib/integrations.ts +23 -22
  211. package/corpus/templates/macros/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  212. package/corpus/templates/macros/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  213. package/corpus/templates/mail/.agents/skills/actions/SKILL.md +32 -12
  214. package/corpus/templates/mail/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  215. package/corpus/templates/mail/.agents/skills/self-modifying-code/SKILL.md +14 -2
  216. package/corpus/templates/mail/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  217. package/corpus/templates/mail/actions/delete-staged-dataset.ts +4 -23
  218. package/corpus/templates/mail/actions/list-staged-datasets.ts +4 -27
  219. package/corpus/templates/mail/actions/provider-api-catalog.ts +15 -18
  220. package/corpus/templates/mail/actions/provider-api-docs.ts +57 -48
  221. package/corpus/templates/mail/actions/provider-api-request.ts +146 -173
  222. package/corpus/templates/mail/actions/query-staged-dataset.ts +4 -47
  223. package/corpus/templates/mail/server/handlers/gong.ts +6 -61
  224. package/corpus/templates/mail/server/lib/google-auth.ts +10 -13
  225. package/corpus/templates/plan/.agents/skills/actions/SKILL.md +32 -12
  226. package/corpus/templates/plan/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  227. package/corpus/templates/plan/.agents/skills/self-modifying-code/SKILL.md +14 -2
  228. package/corpus/templates/plan/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  229. package/corpus/templates/plan/app/components/layout/Sidebar.tsx +47 -156
  230. package/corpus/templates/slides/.agents/skills/actions/SKILL.md +32 -12
  231. package/corpus/templates/slides/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  232. package/corpus/templates/slides/.agents/skills/self-modifying-code/SKILL.md +14 -2
  233. package/corpus/templates/slides/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  234. package/corpus/templates/slides/actions/delete-staged-dataset.ts +4 -23
  235. package/corpus/templates/slides/actions/list-staged-datasets.ts +4 -27
  236. package/corpus/templates/slides/actions/provider-api-catalog.ts +15 -18
  237. package/corpus/templates/slides/actions/provider-api-docs.ts +57 -48
  238. package/corpus/templates/slides/actions/provider-api-request.ts +145 -172
  239. package/corpus/templates/slides/actions/query-staged-dataset.ts +4 -47
  240. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +11 -36
  241. package/corpus/templates/tasks/.agents/skills/actions/SKILL.md +32 -12
  242. package/corpus/templates/tasks/.agents/skills/agent-native-docs/SKILL.md +21 -9
  243. package/corpus/templates/tasks/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  244. package/corpus/templates/tasks/.agents/skills/self-modifying-code/SKILL.md +14 -2
  245. package/corpus/templates/tasks/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  246. package/corpus/toolkit/CHANGELOG.md +131 -0
  247. package/corpus/toolkit/README.md +60 -0
  248. package/corpus/toolkit/agent-native.eject.json +411 -0
  249. package/corpus/toolkit/export-snapshot.json +35 -0
  250. package/corpus/toolkit/migration-manifest.json +4 -0
  251. package/corpus/toolkit/package.json +284 -0
  252. package/corpus/toolkit/scripts/finalize-build.mjs +55 -0
  253. package/corpus/toolkit/src/app-shell/header-actions.tsx +84 -0
  254. package/corpus/toolkit/src/app-shell/index.ts +1 -0
  255. package/corpus/toolkit/src/chat-history/ChatHistoryList.tsx +469 -0
  256. package/corpus/toolkit/src/chat-history/index.ts +7 -0
  257. package/corpus/toolkit/src/chat-history.css +314 -0
  258. package/corpus/toolkit/src/collab-ui/AgentPresenceChip.tsx +69 -0
  259. package/corpus/toolkit/src/collab-ui/LiveCursorOverlay.tsx +241 -0
  260. package/corpus/toolkit/src/collab-ui/PresenceBar.tsx +346 -0
  261. package/corpus/toolkit/src/collab-ui/RecentEditHighlights.tsx +225 -0
  262. package/corpus/toolkit/src/collab-ui/RemoteSelectionRings.tsx +227 -0
  263. package/corpus/toolkit/src/collab-ui/agent-identity.ts +16 -0
  264. package/corpus/toolkit/src/collab-ui/index.ts +39 -0
  265. package/corpus/toolkit/src/collab-ui/lead-client.ts +32 -0
  266. package/corpus/toolkit/src/collab-ui/types.ts +96 -0
  267. package/corpus/toolkit/src/composer/AgentComposerFrame.tsx +59 -0
  268. package/corpus/toolkit/src/composer/ComposerPlusMenu.tsx +983 -0
  269. package/corpus/toolkit/src/composer/MentionPopover.tsx +412 -0
  270. package/corpus/toolkit/src/composer/PastedTextChip.tsx +150 -0
  271. package/corpus/toolkit/src/composer/PromptComposer.tsx +718 -0
  272. package/corpus/toolkit/src/composer/RealtimeVoiceMode.tsx +856 -0
  273. package/corpus/toolkit/src/composer/TiptapComposer.tsx +2936 -0
  274. package/corpus/toolkit/src/composer/VoiceButton.tsx +255 -0
  275. package/corpus/toolkit/src/composer/asset-picker-url.ts +80 -0
  276. package/corpus/toolkit/src/composer/attachment-accept.ts +71 -0
  277. package/corpus/toolkit/src/composer/draft-key.ts +7 -0
  278. package/corpus/toolkit/src/composer/extensions/FileReference.tsx +55 -0
  279. package/corpus/toolkit/src/composer/extensions/MentionReference.tsx +93 -0
  280. package/corpus/toolkit/src/composer/extensions/SkillReference.tsx +56 -0
  281. package/corpus/toolkit/src/composer/index.ts +79 -0
  282. package/corpus/toolkit/src/composer/pasted-text.ts +160 -0
  283. package/corpus/toolkit/src/composer/prompt-attachments.ts +93 -0
  284. package/corpus/toolkit/src/composer/realtime-voice-audio-level.ts +64 -0
  285. package/corpus/toolkit/src/composer/realtime-voice-transcript.ts +134 -0
  286. package/corpus/toolkit/src/composer/runtime-adapters.tsx +343 -0
  287. package/corpus/toolkit/src/composer/types.ts +66 -0
  288. package/corpus/toolkit/src/composer/use-file-search.ts +64 -0
  289. package/corpus/toolkit/src/composer/use-mention-search.ts +90 -0
  290. package/corpus/toolkit/src/composer/use-skills.ts +45 -0
  291. package/corpus/toolkit/src/composer/useRealtimeVoiceMode.tsx +2117 -0
  292. package/corpus/toolkit/src/composer/useVoiceDictation.ts +1191 -0
  293. package/corpus/toolkit/src/context-ui/ContextMeter.tsx +101 -0
  294. package/corpus/toolkit/src/context-ui/ContextSegmentRow.tsx +184 -0
  295. package/corpus/toolkit/src/context-ui/ContextTreemap.tsx +125 -0
  296. package/corpus/toolkit/src/context-ui/ContextXRayPanel.tsx +377 -0
  297. package/corpus/toolkit/src/context-ui/format.ts +42 -0
  298. package/corpus/toolkit/src/context-ui/index.ts +15 -0
  299. package/corpus/toolkit/src/context-ui/types.ts +43 -0
  300. package/corpus/toolkit/src/design-tweaks/index.ts +1 -0
  301. package/corpus/toolkit/src/design-tweaks/visual-style-controls.tsx +1084 -0
  302. package/corpus/toolkit/src/editor/BubbleToolbar.tsx +253 -0
  303. package/corpus/toolkit/src/editor/CodeBlockNode.tsx +254 -0
  304. package/corpus/toolkit/src/editor/DragHandle.ts +1437 -0
  305. package/corpus/toolkit/src/editor/ImageExtension.ts +306 -0
  306. package/corpus/toolkit/src/editor/RegistryBlockContext.tsx +107 -0
  307. package/corpus/toolkit/src/editor/RegistryBlockNode.tsx +652 -0
  308. package/corpus/toolkit/src/editor/RichMarkdownEditor.tsx +81 -0
  309. package/corpus/toolkit/src/editor/RunId.ts +61 -0
  310. package/corpus/toolkit/src/editor/SharedRichEditor.tsx +321 -0
  311. package/corpus/toolkit/src/editor/SlashCommandMenu.tsx +310 -0
  312. package/corpus/toolkit/src/editor/extensions.ts +402 -0
  313. package/corpus/toolkit/src/editor/gfmDoc.ts +92 -0
  314. package/corpus/toolkit/src/editor/index.ts +93 -0
  315. package/corpus/toolkit/src/editor/registrySlashCommands.ts +131 -0
  316. package/corpus/toolkit/src/editor/surgical-apply.ts +192 -0
  317. package/corpus/toolkit/src/editor/useCollabReconcile.ts +589 -0
  318. package/corpus/toolkit/src/editor.css +510 -0
  319. package/corpus/toolkit/src/hooks/index.ts +2 -0
  320. package/corpus/toolkit/src/hooks/use-mobile.tsx +21 -0
  321. package/corpus/toolkit/src/hooks/use-toast.ts +188 -0
  322. package/corpus/toolkit/src/index.ts +8 -0
  323. package/corpus/toolkit/src/onboarding/index.ts +1 -0
  324. package/corpus/toolkit/src/provider.tsx +47 -0
  325. package/corpus/toolkit/src/sharing/VisibilityBadge.tsx +37 -0
  326. package/corpus/toolkit/src/sharing/index.ts +4 -0
  327. package/corpus/toolkit/src/styles.css +21 -0
  328. package/corpus/toolkit/src/ui/accordion.tsx +56 -0
  329. package/corpus/toolkit/src/ui/alert-dialog.tsx +141 -0
  330. package/corpus/toolkit/src/ui/alert.tsx +59 -0
  331. package/corpus/toolkit/src/ui/aspect-ratio.tsx +5 -0
  332. package/corpus/toolkit/src/ui/avatar.tsx +48 -0
  333. package/corpus/toolkit/src/ui/badge.tsx +37 -0
  334. package/corpus/toolkit/src/ui/breadcrumb.tsx +115 -0
  335. package/corpus/toolkit/src/ui/button.tsx +78 -0
  336. package/corpus/toolkit/src/ui/calendar.tsx +214 -0
  337. package/corpus/toolkit/src/ui/card.tsx +86 -0
  338. package/corpus/toolkit/src/ui/carousel.tsx +260 -0
  339. package/corpus/toolkit/src/ui/chart.tsx +375 -0
  340. package/corpus/toolkit/src/ui/checkbox.tsx +28 -0
  341. package/corpus/toolkit/src/ui/collapsible.tsx +9 -0
  342. package/corpus/toolkit/src/ui/command.tsx +174 -0
  343. package/corpus/toolkit/src/ui/context-menu.tsx +202 -0
  344. package/corpus/toolkit/src/ui/date-picker.tsx +64 -0
  345. package/corpus/toolkit/src/ui/dialog.tsx +146 -0
  346. package/corpus/toolkit/src/ui/drawer.tsx +126 -0
  347. package/corpus/toolkit/src/ui/dropdown-menu.tsx +218 -0
  348. package/corpus/toolkit/src/ui/form.tsx +177 -0
  349. package/corpus/toolkit/src/ui/hover-card.tsx +27 -0
  350. package/corpus/toolkit/src/ui/index.ts +52 -0
  351. package/corpus/toolkit/src/ui/input-otp.tsx +69 -0
  352. package/corpus/toolkit/src/ui/input.tsx +22 -0
  353. package/corpus/toolkit/src/ui/label.tsx +24 -0
  354. package/corpus/toolkit/src/ui/logo.tsx +36 -0
  355. package/corpus/toolkit/src/ui/menubar.tsx +235 -0
  356. package/corpus/toolkit/src/ui/navigation-menu.tsx +128 -0
  357. package/corpus/toolkit/src/ui/pagination.tsx +121 -0
  358. package/corpus/toolkit/src/ui/popover.tsx +44 -0
  359. package/corpus/toolkit/src/ui/progress.tsx +26 -0
  360. package/corpus/toolkit/src/ui/radio-group.tsx +42 -0
  361. package/corpus/toolkit/src/ui/resizable.tsx +43 -0
  362. package/corpus/toolkit/src/ui/scroll-area.tsx +46 -0
  363. package/corpus/toolkit/src/ui/select.tsx +158 -0
  364. package/corpus/toolkit/src/ui/separator.tsx +29 -0
  365. package/corpus/toolkit/src/ui/sheet.tsx +160 -0
  366. package/corpus/toolkit/src/ui/sidebar.tsx +777 -0
  367. package/corpus/toolkit/src/ui/skeleton.tsx +18 -0
  368. package/corpus/toolkit/src/ui/slider.tsx +26 -0
  369. package/corpus/toolkit/src/ui/sonner.tsx +58 -0
  370. package/corpus/toolkit/src/ui/spinner.tsx +17 -0
  371. package/corpus/toolkit/src/ui/switch.tsx +27 -0
  372. package/corpus/toolkit/src/ui/table.tsx +117 -0
  373. package/corpus/toolkit/src/ui/tabs.tsx +53 -0
  374. package/corpus/toolkit/src/ui/textarea.tsx +23 -0
  375. package/corpus/toolkit/src/ui/toast.tsx +127 -0
  376. package/corpus/toolkit/src/ui/toaster.tsx +33 -0
  377. package/corpus/toolkit/src/ui/toggle-group.tsx +59 -0
  378. package/corpus/toolkit/src/ui/toggle.tsx +43 -0
  379. package/corpus/toolkit/src/ui/tooltip.tsx +53 -0
  380. package/corpus/toolkit/src/ui/use-toast.ts +3 -0
  381. package/corpus/toolkit/src/utils.ts +8 -0
  382. package/corpus/toolkit/tsconfig.json +23 -0
  383. package/dist/cli/atomic-json-file.d.ts +30 -0
  384. package/dist/cli/atomic-json-file.d.ts.map +1 -0
  385. package/dist/cli/atomic-json-file.js +240 -0
  386. package/dist/cli/atomic-json-file.js.map +1 -0
  387. package/dist/cli/claude-code-participant.d.ts +77 -0
  388. package/dist/cli/claude-code-participant.d.ts.map +1 -0
  389. package/dist/cli/claude-code-participant.js +355 -0
  390. package/dist/cli/claude-code-participant.js.map +1 -0
  391. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  392. package/dist/cli/code-agent-executor.js +18 -10
  393. package/dist/cli/code-agent-executor.js.map +1 -1
  394. package/dist/cli/code-agent-runs.concurrent-worker.d.ts +2 -0
  395. package/dist/cli/code-agent-runs.concurrent-worker.d.ts.map +1 -0
  396. package/dist/cli/code-agent-runs.concurrent-worker.js +32 -0
  397. package/dist/cli/code-agent-runs.concurrent-worker.js.map +1 -0
  398. package/dist/cli/code-agent-runs.d.ts.map +1 -1
  399. package/dist/cli/code-agent-runs.js +43 -56
  400. package/dist/cli/code-agent-runs.js.map +1 -1
  401. package/dist/cli/codex-cli-participant.d.ts +77 -0
  402. package/dist/cli/codex-cli-participant.d.ts.map +1 -0
  403. package/dist/cli/codex-cli-participant.js +354 -0
  404. package/dist/cli/codex-cli-participant.js.map +1 -0
  405. package/dist/cli/eject.d.ts +21 -0
  406. package/dist/cli/eject.d.ts.map +1 -0
  407. package/dist/cli/eject.js +1145 -0
  408. package/dist/cli/eject.js.map +1 -0
  409. package/dist/cli/index.js +15 -0
  410. package/dist/cli/index.js.map +1 -1
  411. package/dist/cli/multi-frontier-runs.d.ts +115 -0
  412. package/dist/cli/multi-frontier-runs.d.ts.map +1 -1
  413. package/dist/cli/multi-frontier-runs.js +831 -113
  414. package/dist/cli/multi-frontier-runs.js.map +1 -1
  415. package/dist/client/chat/ChatHistoryList.d.ts +1 -87
  416. package/dist/client/chat/ChatHistoryList.d.ts.map +1 -1
  417. package/dist/client/chat/ChatHistoryList.js +1 -82
  418. package/dist/client/chat/ChatHistoryList.js.map +1 -1
  419. package/dist/client/index.d.ts +1 -1
  420. package/dist/client/index.d.ts.map +1 -1
  421. package/dist/client/index.js +1 -1
  422. package/dist/client/index.js.map +1 -1
  423. package/dist/client/resources/McpConnectionSuggestion.d.ts +4 -3
  424. package/dist/client/resources/McpConnectionSuggestion.d.ts.map +1 -1
  425. package/dist/client/resources/McpConnectionSuggestion.js +3 -3
  426. package/dist/client/resources/McpConnectionSuggestion.js.map +1 -1
  427. package/dist/client/resources/McpIntegrationDialog.d.ts +4 -3
  428. package/dist/client/resources/McpIntegrationDialog.d.ts.map +1 -1
  429. package/dist/client/resources/McpIntegrationDialog.js +2 -2
  430. package/dist/client/resources/McpIntegrationDialog.js.map +1 -1
  431. package/dist/client/resources/ResourcesPanel.d.ts +4 -1
  432. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  433. package/dist/client/resources/ResourcesPanel.js +9 -7
  434. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  435. package/dist/client/resources/index.d.ts +3 -0
  436. package/dist/client/resources/index.d.ts.map +1 -1
  437. package/dist/client/resources/index.js +3 -0
  438. package/dist/client/resources/index.js.map +1 -1
  439. package/dist/client/resources/mcp-integration-catalog.d.ts +2 -1
  440. package/dist/client/resources/mcp-integration-catalog.d.ts.map +1 -1
  441. package/dist/client/resources/mcp-integration-catalog.js +6 -2
  442. package/dist/client/resources/mcp-integration-catalog.js.map +1 -1
  443. package/dist/client/resources/runtime.d.ts +2 -0
  444. package/dist/client/resources/runtime.d.ts.map +1 -0
  445. package/dist/client/resources/runtime.js +2 -0
  446. package/dist/client/resources/runtime.js.map +1 -0
  447. package/dist/client/setup-connections/catalog.d.ts +2 -0
  448. package/dist/client/setup-connections/catalog.d.ts.map +1 -0
  449. package/dist/client/setup-connections/catalog.js +7 -0
  450. package/dist/client/setup-connections/catalog.js.map +1 -0
  451. package/dist/client/setup-connections/index.d.ts +1 -0
  452. package/dist/client/setup-connections/index.d.ts.map +1 -1
  453. package/dist/client/setup-connections/index.js +1 -0
  454. package/dist/client/setup-connections/index.js.map +1 -1
  455. package/dist/client/setup-connections/runtime.d.ts +2 -0
  456. package/dist/client/setup-connections/runtime.d.ts.map +1 -0
  457. package/dist/client/setup-connections/runtime.js +2 -0
  458. package/dist/client/setup-connections/runtime.js.map +1 -0
  459. package/dist/collab/awareness.d.ts +2 -2
  460. package/dist/collab/awareness.d.ts.map +1 -1
  461. package/dist/collab/routes.d.ts +1 -1
  462. package/dist/connections/catalog.d.ts +5 -3
  463. package/dist/connections/catalog.d.ts.map +1 -1
  464. package/dist/connections/catalog.js +16 -8
  465. package/dist/connections/catalog.js.map +1 -1
  466. package/dist/connections/index.d.ts +1 -1
  467. package/dist/connections/index.d.ts.map +1 -1
  468. package/dist/connections/index.js +1 -1
  469. package/dist/connections/index.js.map +1 -1
  470. package/dist/connections/runtime.d.ts +2 -0
  471. package/dist/connections/runtime.d.ts.map +1 -0
  472. package/dist/connections/runtime.js +2 -0
  473. package/dist/connections/runtime.js.map +1 -0
  474. package/dist/eject/provider-api-definitions.d.ts +34 -0
  475. package/dist/eject/provider-api-definitions.d.ts.map +1 -0
  476. package/dist/eject/provider-api-definitions.js +88 -0
  477. package/dist/eject/provider-api-definitions.js.map +1 -0
  478. package/dist/eject/remote-mcp-presets.d.ts +17 -0
  479. package/dist/eject/remote-mcp-presets.d.ts.map +1 -0
  480. package/dist/eject/remote-mcp-presets.js +81 -0
  481. package/dist/eject/remote-mcp-presets.js.map +1 -0
  482. package/dist/eject/setup-readiness-ui.d.ts +7 -0
  483. package/dist/eject/setup-readiness-ui.d.ts.map +1 -0
  484. package/dist/eject/setup-readiness-ui.js +13 -0
  485. package/dist/eject/setup-readiness-ui.js.map +1 -0
  486. package/dist/eject/workspace-connections.d.ts +11 -0
  487. package/dist/eject/workspace-connections.d.ts.map +1 -0
  488. package/dist/eject/workspace-connections.js +47 -0
  489. package/dist/eject/workspace-connections.js.map +1 -0
  490. package/dist/index.d.ts +1 -1
  491. package/dist/index.d.ts.map +1 -1
  492. package/dist/index.js +1 -1
  493. package/dist/index.js.map +1 -1
  494. package/dist/integrations/adapter-overrides.d.ts +3 -0
  495. package/dist/integrations/adapter-overrides.d.ts.map +1 -0
  496. package/dist/integrations/adapter-overrides.js +7 -0
  497. package/dist/integrations/adapter-overrides.js.map +1 -0
  498. package/dist/integrations/eject/messaging-adapters.d.ts +12 -0
  499. package/dist/integrations/eject/messaging-adapters.d.ts.map +1 -0
  500. package/dist/integrations/eject/messaging-adapters.js +49 -0
  501. package/dist/integrations/eject/messaging-adapters.js.map +1 -0
  502. package/dist/integrations/index.d.ts +5 -3
  503. package/dist/integrations/index.d.ts.map +1 -1
  504. package/dist/integrations/index.js +4 -2
  505. package/dist/integrations/index.js.map +1 -1
  506. package/dist/integrations/plugin.d.ts +32 -1
  507. package/dist/integrations/plugin.d.ts.map +1 -1
  508. package/dist/integrations/plugin.js +19 -12
  509. package/dist/integrations/plugin.js.map +1 -1
  510. package/dist/integrations/runtime.d.ts +2 -0
  511. package/dist/integrations/runtime.d.ts.map +1 -0
  512. package/dist/integrations/runtime.js +2 -0
  513. package/dist/integrations/runtime.js.map +1 -0
  514. package/dist/integrations/slack-manifest.d.ts +1 -1
  515. package/dist/integrations/slack-oauth.d.ts +1 -1
  516. package/dist/integrations/slack-oauth.d.ts.map +1 -1
  517. package/dist/integrations/slack-oauth.js +1 -0
  518. package/dist/integrations/slack-oauth.js.map +1 -1
  519. package/dist/integrations/types.d.ts +3 -1
  520. package/dist/integrations/types.d.ts.map +1 -1
  521. package/dist/integrations/types.js.map +1 -1
  522. package/dist/integrations/webhook-delivery.d.ts +23 -0
  523. package/dist/integrations/webhook-delivery.d.ts.map +1 -0
  524. package/dist/integrations/webhook-delivery.js +32 -0
  525. package/dist/integrations/webhook-delivery.js.map +1 -0
  526. package/dist/notifications/channels.d.ts.map +1 -1
  527. package/dist/notifications/channels.js +4 -9
  528. package/dist/notifications/channels.js.map +1 -1
  529. package/dist/notifications/routes.d.ts +3 -3
  530. package/dist/package-lifecycle/eject-manifest.d.ts +43 -0
  531. package/dist/package-lifecycle/eject-manifest.d.ts.map +1 -0
  532. package/dist/package-lifecycle/eject-manifest.js +219 -0
  533. package/dist/package-lifecycle/eject-manifest.js.map +1 -0
  534. package/dist/package-lifecycle/index.d.ts +1 -0
  535. package/dist/package-lifecycle/index.d.ts.map +1 -1
  536. package/dist/package-lifecycle/index.js +1 -0
  537. package/dist/package-lifecycle/index.js.map +1 -1
  538. package/dist/progress/routes.d.ts +1 -1
  539. package/dist/provider-api/actions/custom-provider-registration.d.ts +136 -0
  540. package/dist/provider-api/actions/custom-provider-registration.d.ts.map +1 -0
  541. package/dist/provider-api/actions/custom-provider-registration.js +154 -0
  542. package/dist/provider-api/actions/custom-provider-registration.js.map +1 -0
  543. package/dist/provider-api/actions/delete-staged-dataset.d.ts +1 -1
  544. package/dist/provider-api/actions/delete-staged-dataset.d.ts.map +1 -1
  545. package/dist/provider-api/actions/delete-staged-dataset.js +3 -34
  546. package/dist/provider-api/actions/delete-staged-dataset.js.map +1 -1
  547. package/dist/provider-api/actions/list-staged-datasets.d.ts +2 -3
  548. package/dist/provider-api/actions/list-staged-datasets.d.ts.map +1 -1
  549. package/dist/provider-api/actions/list-staged-datasets.js +3 -40
  550. package/dist/provider-api/actions/list-staged-datasets.js.map +1 -1
  551. package/dist/provider-api/actions/provider-api-audit.d.ts +7 -0
  552. package/dist/provider-api/actions/provider-api-audit.d.ts.map +1 -0
  553. package/dist/provider-api/actions/provider-api-audit.js +74 -0
  554. package/dist/provider-api/actions/provider-api-audit.js.map +1 -0
  555. package/dist/provider-api/actions/provider-api.d.ts +370 -0
  556. package/dist/provider-api/actions/provider-api.d.ts.map +1 -0
  557. package/dist/provider-api/actions/provider-api.js +280 -0
  558. package/dist/provider-api/actions/provider-api.js.map +1 -0
  559. package/dist/provider-api/actions/query-staged-dataset.d.ts +1 -1
  560. package/dist/provider-api/actions/query-staged-dataset.d.ts.map +1 -1
  561. package/dist/provider-api/actions/query-staged-dataset.js +3 -116
  562. package/dist/provider-api/actions/query-staged-dataset.js.map +1 -1
  563. package/dist/provider-api/actions/staged-datasets.d.ts +190 -0
  564. package/dist/provider-api/actions/staged-datasets.d.ts.map +1 -0
  565. package/dist/provider-api/actions/staged-datasets.js +210 -0
  566. package/dist/provider-api/actions/staged-datasets.js.map +1 -0
  567. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  568. package/dist/provider-api/gong.d.ts +44 -0
  569. package/dist/provider-api/gong.d.ts.map +1 -0
  570. package/dist/provider-api/gong.js +56 -0
  571. package/dist/provider-api/gong.js.map +1 -0
  572. package/dist/provider-api/index.d.ts +6 -2
  573. package/dist/provider-api/index.d.ts.map +1 -1
  574. package/dist/provider-api/index.js +25 -12
  575. package/dist/provider-api/index.js.map +1 -1
  576. package/dist/provider-api/runtime.d.ts +2 -0
  577. package/dist/provider-api/runtime.d.ts.map +1 -0
  578. package/dist/provider-api/runtime.js +2 -0
  579. package/dist/provider-api/runtime.js.map +1 -0
  580. package/dist/scripts/docs/source-search.d.ts +2 -1
  581. package/dist/scripts/docs/source-search.d.ts.map +1 -1
  582. package/dist/scripts/docs/source-search.js +2 -1
  583. package/dist/scripts/docs/source-search.js.map +1 -1
  584. package/dist/secrets/routes.d.ts +9 -9
  585. package/dist/server/google-oauth-credentials.d.ts +35 -0
  586. package/dist/server/google-oauth-credentials.d.ts.map +1 -1
  587. package/dist/server/google-oauth-credentials.js +48 -2
  588. package/dist/server/google-oauth-credentials.js.map +1 -1
  589. package/dist/server/index.d.ts +1 -1
  590. package/dist/server/index.d.ts.map +1 -1
  591. package/dist/server/index.js +1 -1
  592. package/dist/server/index.js.map +1 -1
  593. package/dist/server/transcribe-voice.d.ts +1 -1
  594. package/dist/setup-connections/index.d.ts +1 -1
  595. package/dist/setup-connections/index.d.ts.map +1 -1
  596. package/dist/setup-connections/index.js +1 -1
  597. package/dist/setup-connections/index.js.map +1 -1
  598. package/dist/shared/merge-by-id.d.ts +5 -0
  599. package/dist/shared/merge-by-id.d.ts.map +1 -0
  600. package/dist/shared/merge-by-id.js +7 -0
  601. package/dist/shared/merge-by-id.js.map +1 -0
  602. package/dist/styles/chat-history-list.css +1 -313
  603. package/dist/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  604. package/dist/templates/chat/.agents/skills/agent-native-docs/SKILL.md +21 -9
  605. package/dist/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  606. package/dist/templates/chat/.agents/skills/self-modifying-code/SKILL.md +14 -2
  607. package/dist/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  608. package/dist/templates/chat/AGENTS.md +6 -2
  609. package/dist/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  610. package/dist/templates/default/.agents/skills/actions/SKILL.md +32 -12
  611. package/dist/templates/default/.agents/skills/agent-native-docs/SKILL.md +21 -9
  612. package/dist/templates/default/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  613. package/dist/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  614. package/dist/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  615. package/dist/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  616. package/dist/templates/default/.agents/skills/self-modifying-code/SKILL.md +14 -2
  617. package/dist/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  618. package/dist/templates/default/AGENTS.md +26 -18
  619. package/dist/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  620. package/dist/templates/headless/.agents/skills/agent-native-docs/SKILL.md +21 -9
  621. package/dist/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  622. package/dist/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  623. package/dist/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  624. package/dist/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  625. package/dist/templates/headless/AGENTS.md +8 -0
  626. package/dist/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  627. package/dist/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +21 -9
  628. package/dist/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +7 -0
  629. package/dist/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  630. package/dist/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +14 -2
  631. package/dist/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  632. package/dist/templates/workspace-core/AGENTS.md +4 -0
  633. package/dist/templates/workspace-root/AGENTS.md +4 -0
  634. package/dist/vite/client.d.ts.map +1 -1
  635. package/dist/vite/client.js +22 -2
  636. package/dist/vite/client.js.map +1 -1
  637. package/docs/AGENTS.md +7 -0
  638. package/docs/content/agent-native-toolkit.mdx +38 -0
  639. package/docs/content/integrations.mdx +63 -2
  640. package/docs/content/package-lifecycle.mdx +54 -4
  641. package/docs/design/provider-integration-authority.md +117 -0
  642. package/package.json +20 -2
  643. package/src/a2a/agent-card.ts +83 -0
  644. package/src/a2a/artifact-response.ts +1648 -0
  645. package/src/a2a/auth-policy.ts +66 -0
  646. package/src/a2a/caller-auth.ts +102 -0
  647. package/src/a2a/client.ts +876 -0
  648. package/src/a2a/correlation.ts +50 -0
  649. package/src/a2a/handlers.ts +1285 -0
  650. package/src/a2a/index.ts +50 -0
  651. package/src/a2a/invoke.ts +348 -0
  652. package/src/a2a/response-text.ts +53 -0
  653. package/src/a2a/server.ts +586 -0
  654. package/src/a2a/task-store.ts +917 -0
  655. package/src/a2a/types.ts +221 -0
  656. package/src/a2a-claims.ts +52 -0
  657. package/src/action-change-marker.ts +74 -0
  658. package/src/action-ui.ts +38 -0
  659. package/src/action.ts +1406 -0
  660. package/src/adapters/cli/index.ts +6 -0
  661. package/src/adapters/cli/registry.ts +73 -0
  662. package/src/adapters/cli/shell-adapter.ts +92 -0
  663. package/src/adapters/cli/types.ts +27 -0
  664. package/src/agent/action-continuation-guidance.ts +38 -0
  665. package/src/agent/app-model-defaults.ts +201 -0
  666. package/src/agent/context-xray/actions/context-evict.ts +56 -0
  667. package/src/agent/context-xray/actions/context-manifest-get.ts +75 -0
  668. package/src/agent/context-xray/actions/context-pin.ts +56 -0
  669. package/src/agent/context-xray/actions/context-preview-get.ts +134 -0
  670. package/src/agent/context-xray/actions/context-report.ts +75 -0
  671. package/src/agent/context-xray/actions/context-restore.ts +51 -0
  672. package/src/agent/context-xray/actions/errors.ts +40 -0
  673. package/src/agent/context-xray/apply-directives.ts +137 -0
  674. package/src/agent/context-xray/directives-store.ts +178 -0
  675. package/src/agent/context-xray/identity.ts +37 -0
  676. package/src/agent/context-xray/manifest.ts +284 -0
  677. package/src/agent/context-xray/migrations.ts +32 -0
  678. package/src/agent/context-xray/plugin.ts +23 -0
  679. package/src/agent/context-xray/schema.ts +17 -0
  680. package/src/agent/context-xray/segments.ts +194 -0
  681. package/src/agent/context-xray/tokenize.ts +93 -0
  682. package/src/agent/default-model.ts +5 -0
  683. package/src/agent/durable-background.ts +547 -0
  684. package/src/agent/engine/ai-sdk-engine.ts +565 -0
  685. package/src/agent/engine/anthropic-engine.ts +320 -0
  686. package/src/agent/engine/builder-engine.ts +1110 -0
  687. package/src/agent/engine/builder-gateway-headers.ts +44 -0
  688. package/src/agent/engine/builtin.ts +122 -0
  689. package/src/agent/engine/context-directives-transform.ts +73 -0
  690. package/src/agent/engine/continuation-dispatch-retry.ts +168 -0
  691. package/src/agent/engine/credential-errors.ts +69 -0
  692. package/src/agent/engine/index.ts +54 -0
  693. package/src/agent/engine/openai-compatible-endpoint.ts +25 -0
  694. package/src/agent/engine/output-tokens.ts +181 -0
  695. package/src/agent/engine/provider-env-vars.ts +69 -0
  696. package/src/agent/engine/registry.ts +853 -0
  697. package/src/agent/engine/tool-call-journal-seed.ts +85 -0
  698. package/src/agent/engine/translate-ai-sdk.ts +407 -0
  699. package/src/agent/engine/translate-anthropic.ts +611 -0
  700. package/src/agent/engine/types.ts +310 -0
  701. package/src/agent/harness/acp-adapter.ts +893 -0
  702. package/src/agent/harness/acp-builtin.ts +70 -0
  703. package/src/agent/harness/ai-sdk-adapter.ts +509 -0
  704. package/src/agent/harness/background.ts +365 -0
  705. package/src/agent/harness/builtin.ts +50 -0
  706. package/src/agent/harness/index.ts +86 -0
  707. package/src/agent/harness/lifecycle.ts +498 -0
  708. package/src/agent/harness/registry.ts +97 -0
  709. package/src/agent/harness/runner.ts +182 -0
  710. package/src/agent/harness/store.ts +466 -0
  711. package/src/agent/harness/translate.ts +130 -0
  712. package/src/agent/harness/types.ts +129 -0
  713. package/src/agent/index.ts +32 -0
  714. package/src/agent/loop-settings.ts +186 -0
  715. package/src/agent/model-config.ts +363 -0
  716. package/src/agent/observational-memory/compactor.ts +78 -0
  717. package/src/agent/observational-memory/config.ts +78 -0
  718. package/src/agent/observational-memory/index.ts +79 -0
  719. package/src/agent/observational-memory/internal-run.ts +89 -0
  720. package/src/agent/observational-memory/message-text.ts +49 -0
  721. package/src/agent/observational-memory/migrations.ts +44 -0
  722. package/src/agent/observational-memory/observer.ts +128 -0
  723. package/src/agent/observational-memory/plugin.ts +35 -0
  724. package/src/agent/observational-memory/prompts.ts +53 -0
  725. package/src/agent/observational-memory/read.ts +131 -0
  726. package/src/agent/observational-memory/reflector.ts +119 -0
  727. package/src/agent/observational-memory/schema.ts +48 -0
  728. package/src/agent/observational-memory/store.ts +275 -0
  729. package/src/agent/observational-memory/types.ts +65 -0
  730. package/src/agent/processors.ts +209 -0
  731. package/src/agent/production-agent.ts +8254 -0
  732. package/src/agent/run-loop-with-resume.ts +394 -0
  733. package/src/agent/run-manager.ts +1825 -0
  734. package/src/agent/run-ownership.ts +75 -0
  735. package/src/agent/run-store.ts +2601 -0
  736. package/src/agent/runtime-context.ts +169 -0
  737. package/src/agent/thread-data-builder.ts +1584 -0
  738. package/src/agent/tool-call-journal.ts +368 -0
  739. package/src/agent/tool-error-redaction.ts +52 -0
  740. package/src/agent/tool-result-images.ts +178 -0
  741. package/src/agent/tool-search.ts +376 -0
  742. package/src/agent/types.ts +372 -0
  743. package/src/agent-native/index.ts +198 -0
  744. package/src/agent-web/config.ts +253 -0
  745. package/src/agent-web/generator.ts +382 -0
  746. package/src/agent-web/index.ts +36 -0
  747. package/src/appearance/actions/change-appearance.ts +35 -0
  748. package/src/application-state/emitter.ts +81 -0
  749. package/src/application-state/handlers.ts +121 -0
  750. package/src/application-state/index.ts +44 -0
  751. package/src/application-state/script-helpers.ts +155 -0
  752. package/src/application-state/store.ts +274 -0
  753. package/src/assets/branding/agent-native.icon/Assets/background.svg +3 -0
  754. package/src/assets/branding/agent-native.icon/Assets/foreground.svg +12 -0
  755. package/src/assets/branding/agent-native.icon/icon.json +49 -0
  756. package/src/assets/branding/favicon.png +0 -0
  757. package/src/assets/branding/favicon.svg +1 -0
  758. package/src/assets/branding/icon-on-dark.svg +10 -0
  759. package/src/assets/branding/icon-on-light.svg +10 -0
  760. package/src/assets/branding/mac-app-icon.svg +1 -0
  761. package/src/assets/branding/slack-bot/agent-native-1024.png +0 -0
  762. package/src/assets/branding/slack-bot/agent-native-512.png +0 -0
  763. package/src/assets/branding/tray-icon.svg +6 -0
  764. package/src/assets/branding/wordmark-on-dark.svg +21 -0
  765. package/src/assets/branding/wordmark-on-light.svg +21 -0
  766. package/src/assets/fonts/LICENSE_LIBERATION +96 -0
  767. package/src/assets/fonts/LICENSE_NOTO_NASKH_ARABIC +93 -0
  768. package/src/assets/fonts/LiberationSans-Bold.ttf +0 -0
  769. package/src/assets/fonts/LiberationSans-Regular.ttf +0 -0
  770. package/src/assets/fonts/NotoNaskhArabic-Variable.ttf +0 -0
  771. package/src/audit/actions/export-audit-events.ts +162 -0
  772. package/src/audit/actions/get-audit-event.ts +24 -0
  773. package/src/audit/actions/list-audit-events.ts +66 -0
  774. package/src/audit/cleanup-job.ts +100 -0
  775. package/src/audit/config.ts +90 -0
  776. package/src/audit/index.ts +43 -0
  777. package/src/audit/record.ts +180 -0
  778. package/src/audit/redact.ts +109 -0
  779. package/src/audit/store.ts +346 -0
  780. package/src/audit/types.ts +141 -0
  781. package/src/automation/index.ts +802 -0
  782. package/src/brand-kit/brand-signals.ts +124 -0
  783. package/src/brand-kit/fig/index.ts +64 -0
  784. package/src/brand-kit/index.ts +72 -0
  785. package/src/brand-kit/types.ts +113 -0
  786. package/src/browser-sessions/actions.ts +302 -0
  787. package/src/browser-sessions/routes.ts +234 -0
  788. package/src/browser-sessions/store.ts +679 -0
  789. package/src/browser-sessions/types.ts +84 -0
  790. package/src/changelog/parse.ts +328 -0
  791. package/src/chat-threads/emitter.ts +22 -0
  792. package/src/chat-threads/schema.ts +43 -0
  793. package/src/chat-threads/store.ts +1311 -0
  794. package/src/checkpoints/index.ts +15 -0
  795. package/src/checkpoints/service.ts +142 -0
  796. package/src/checkpoints/store.ts +153 -0
  797. package/src/cli/add.ts +425 -0
  798. package/src/cli/agent.ts +424 -0
  799. package/src/cli/agents.ts +122 -0
  800. package/src/cli/app-skill.ts +1455 -0
  801. package/src/cli/atomic-json-file.ts +324 -0
  802. package/src/cli/audit-agent-web.ts +324 -0
  803. package/src/cli/changelog.ts +199 -0
  804. package/src/cli/claude-code-participant.ts +515 -0
  805. package/src/cli/code-agent-commands.ts +270 -0
  806. package/src/cli/code-agent-connector.ts +1109 -0
  807. package/src/cli/code-agent-executor.ts +1970 -0
  808. package/src/cli/code-agent-output-smoother.ts +140 -0
  809. package/src/cli/code-agent-runs.concurrent-worker.ts +33 -0
  810. package/src/cli/code-agent-runs.ts +548 -0
  811. package/src/cli/code.ts +1805 -0
  812. package/src/cli/codex-cli-participant.ts +496 -0
  813. package/src/cli/connect.ts +2714 -0
  814. package/src/cli/content-local.ts +442 -0
  815. package/src/cli/context-xray-local.ts +2193 -0
  816. package/src/cli/create-workspace.ts +30 -0
  817. package/src/cli/create.ts +2247 -0
  818. package/src/cli/deploy-build.ts +50 -0
  819. package/src/cli/design-connect.ts +3187 -0
  820. package/src/cli/doctor.ts +472 -0
  821. package/src/cli/eject.ts +1594 -0
  822. package/src/cli/eval.ts +134 -0
  823. package/src/cli/gateway-helpers.ts +70 -0
  824. package/src/cli/index.ts +1217 -0
  825. package/src/cli/info.ts +105 -0
  826. package/src/cli/invoke.ts +288 -0
  827. package/src/cli/mcp-config-writers.ts +857 -0
  828. package/src/cli/mcp.ts +594 -0
  829. package/src/cli/migrate.ts +1813 -0
  830. package/src/cli/migration-codemod.ts +646 -0
  831. package/src/cli/multi-frontier-runs.ts +1952 -0
  832. package/src/cli/package-lifecycle.ts +823 -0
  833. package/src/cli/plan-blocks.ts +143 -0
  834. package/src/cli/plan-local.ts +3189 -0
  835. package/src/cli/plan-publish-store.ts +138 -0
  836. package/src/cli/pr-visual-recap-workflow.ts +2 -0
  837. package/src/cli/recap.ts +5 -0
  838. package/src/cli/setup-agents.ts +120 -0
  839. package/src/cli/skills-content/assets-skill.ts +83 -0
  840. package/src/cli/skills-content/canvas.ts +153 -0
  841. package/src/cli/skills-content/connection.ts +52 -0
  842. package/src/cli/skills-content/content-skill.ts +120 -0
  843. package/src/cli/skills-content/design-exploration-skill.ts +118 -0
  844. package/src/cli/skills-content/design-visual-edit-skill.ts +228 -0
  845. package/src/cli/skills-content/document-quality.ts +196 -0
  846. package/src/cli/skills-content/exemplar.ts +69 -0
  847. package/src/cli/skills-content/help.ts +77 -0
  848. package/src/cli/skills-content/index.ts +22 -0
  849. package/src/cli/skills-content/local-files.ts +100 -0
  850. package/src/cli/skills-content/plan-setup-auth.ts +80 -0
  851. package/src/cli/skills-content/visual-plan-skill.ts +493 -0
  852. package/src/cli/skills-content/visual-recap-skill.ts +553 -0
  853. package/src/cli/skills-content/visualize-repo-skill.ts +93 -0
  854. package/src/cli/skills-content/wireframe.ts +349 -0
  855. package/src/cli/skills.ts +4340 -0
  856. package/src/cli/sync-builder-starter-manifest.ts +631 -0
  857. package/src/cli/telemetry.ts +136 -0
  858. package/src/cli/templates-meta.ts +269 -0
  859. package/src/cli/upgrade.ts +956 -0
  860. package/src/cli/visualize-repo.ts +715 -0
  861. package/src/cli/workspace-dev.ts +1486 -0
  862. package/src/cli/workspacify.ts +258 -0
  863. package/src/client/AgentAskPopover.tsx +89 -0
  864. package/src/client/AgentChatHome.tsx +66 -0
  865. package/src/client/AgentNative.tsx +161 -0
  866. package/src/client/AgentNativeEmbedded.tsx +288 -0
  867. package/src/client/AgentNativeFrame.tsx +151 -0
  868. package/src/client/AgentPanel.tsx +3437 -0
  869. package/src/client/AgentTaskCard.tsx +273 -0
  870. package/src/client/AppearancePicker.tsx +79 -0
  871. package/src/client/AssistantChat.tsx +5793 -0
  872. package/src/client/ClientOnly.tsx +22 -0
  873. package/src/client/CommandMenu.tsx +726 -0
  874. package/src/client/ConnectBuilderCard.tsx +390 -0
  875. package/src/client/DefaultSpinner.tsx +47 -0
  876. package/src/client/ErrorBoundary.tsx +359 -0
  877. package/src/client/ErrorReportActions.tsx +69 -0
  878. package/src/client/FeedbackButton.tsx +553 -0
  879. package/src/client/HighlightedCodeBlock.tsx +173 -0
  880. package/src/client/IframeEmbed.tsx +151 -0
  881. package/src/client/KeepTabOpenNotice.tsx +181 -0
  882. package/src/client/MultiTabAssistantChat.tsx +2576 -0
  883. package/src/client/NewWorkspaceAppFlow.tsx +525 -0
  884. package/src/client/PoweredByBadge.tsx +284 -0
  885. package/src/client/RunStuckBanner.tsx +431 -0
  886. package/src/client/StarfieldBackground.tsx +466 -0
  887. package/src/client/Turnstile.tsx +125 -0
  888. package/src/client/active-run-state.ts +139 -0
  889. package/src/client/agent-chat/index.ts +279 -0
  890. package/src/client/agent-chat-adapter.ts +3692 -0
  891. package/src/client/agent-chat.ts +1233 -0
  892. package/src/client/agent-engine-key.ts +122 -0
  893. package/src/client/agent-page/AgentContextTab.tsx +487 -0
  894. package/src/client/agent-page/AgentEmptyState.tsx +44 -0
  895. package/src/client/agent-page/AgentJobsTab.tsx +441 -0
  896. package/src/client/agent-page/AgentTabFrame.tsx +39 -0
  897. package/src/client/agent-page/AgentTabsPage.tsx +1096 -0
  898. package/src/client/agent-page/types.ts +18 -0
  899. package/src/client/agent-page/use-jobs.ts +150 -0
  900. package/src/client/agent-sidebar-state.ts +166 -0
  901. package/src/client/analytics/index.ts +40 -0
  902. package/src/client/analytics-session.ts +70 -0
  903. package/src/client/analytics.ts +1757 -0
  904. package/src/client/api-path.ts +124 -0
  905. package/src/client/app-providers.tsx +230 -0
  906. package/src/client/appearance.ts +130 -0
  907. package/src/client/application-state.ts +154 -0
  908. package/src/client/assistant-ui-recovery.tsx +205 -0
  909. package/src/client/automation/index.ts +4 -0
  910. package/src/client/automation.ts +22 -0
  911. package/src/client/blocks/AiEditableField.tsx +30 -0
  912. package/src/client/blocks/BlockView.tsx +145 -0
  913. package/src/client/blocks/RegistryBlockDataProvider.tsx +121 -0
  914. package/src/client/blocks/SchemaBlockEditor.tsx +457 -0
  915. package/src/client/blocks/agent.ts +95 -0
  916. package/src/client/blocks/code-block-direction.ts +21 -0
  917. package/src/client/blocks/index.ts +308 -0
  918. package/src/client/blocks/library/AnnotatedCodeBlock.tsx +710 -0
  919. package/src/client/blocks/library/ApiEndpointBlock.tsx +1120 -0
  920. package/src/client/blocks/library/DataModelBlock.tsx +775 -0
  921. package/src/client/blocks/library/DiffBlock.tsx +1854 -0
  922. package/src/client/blocks/library/FileTreeBlock.tsx +868 -0
  923. package/src/client/blocks/library/HighlightedCode.tsx +260 -0
  924. package/src/client/blocks/library/JsonExplorerBlock.tsx +608 -0
  925. package/src/client/blocks/library/MermaidBlock.tsx +362 -0
  926. package/src/client/blocks/library/OpenApiSpecBlock.tsx +998 -0
  927. package/src/client/blocks/library/annotated-code.config.ts +101 -0
  928. package/src/client/blocks/library/annotation-rail.tsx +1020 -0
  929. package/src/client/blocks/library/api-endpoint.config.ts +207 -0
  930. package/src/client/blocks/library/block-copy.ts +399 -0
  931. package/src/client/blocks/library/callout.config.ts +57 -0
  932. package/src/client/blocks/library/callout.tsx +149 -0
  933. package/src/client/blocks/library/checklist.config.ts +56 -0
  934. package/src/client/blocks/library/checklist.tsx +208 -0
  935. package/src/client/blocks/library/code-filename-label.tsx +59 -0
  936. package/src/client/blocks/library/code-highlight.tsx +178 -0
  937. package/src/client/blocks/library/code-tabs.config.ts +70 -0
  938. package/src/client/blocks/library/code-tabs.tsx +606 -0
  939. package/src/client/blocks/library/code.config.ts +69 -0
  940. package/src/client/blocks/library/code.tsx +440 -0
  941. package/src/client/blocks/library/columns.config.ts +85 -0
  942. package/src/client/blocks/library/columns.tsx +334 -0
  943. package/src/client/blocks/library/data-model.config.ts +152 -0
  944. package/src/client/blocks/library/dev-doc-ui.tsx +191 -0
  945. package/src/client/blocks/library/diagram.config.ts +222 -0
  946. package/src/client/blocks/library/diagram.tsx +958 -0
  947. package/src/client/blocks/library/diff.config.ts +115 -0
  948. package/src/client/blocks/library/file-tree.config.ts +92 -0
  949. package/src/client/blocks/library/html.config.ts +79 -0
  950. package/src/client/blocks/library/html.tsx +258 -0
  951. package/src/client/blocks/library/json-explorer.config.ts +74 -0
  952. package/src/client/blocks/library/mermaid.config.ts +49 -0
  953. package/src/client/blocks/library/narrow-container.tsx +37 -0
  954. package/src/client/blocks/library/openapi-spec.config.ts +66 -0
  955. package/src/client/blocks/library/question-form.config.ts +127 -0
  956. package/src/client/blocks/library/question-form.tsx +944 -0
  957. package/src/client/blocks/library/sanitize-html.ts +343 -0
  958. package/src/client/blocks/library/server-specs.ts +338 -0
  959. package/src/client/blocks/library/specs.tsx +308 -0
  960. package/src/client/blocks/library/table.config.ts +61 -0
  961. package/src/client/blocks/library/table.tsx +449 -0
  962. package/src/client/blocks/library/tabs.config.ts +96 -0
  963. package/src/client/blocks/library/tabs.tsx +665 -0
  964. package/src/client/blocks/library/wireframe-icons.ts +210 -0
  965. package/src/client/blocks/library/wireframe-kit.tsx +1850 -0
  966. package/src/client/blocks/library/wireframe.config.ts +539 -0
  967. package/src/client/blocks/library/wireframe.tsx +535 -0
  968. package/src/client/blocks/mdx.ts +364 -0
  969. package/src/client/blocks/provider.tsx +51 -0
  970. package/src/client/blocks/registry.ts +83 -0
  971. package/src/client/blocks/schema-form/introspect.ts +201 -0
  972. package/src/client/blocks/server.ts +170 -0
  973. package/src/client/blocks/types.ts +415 -0
  974. package/src/client/browser-session-bridge.ts +548 -0
  975. package/src/client/browser-tab-id.ts +36 -0
  976. package/src/client/builder-frame.ts +194 -0
  977. package/src/client/builder-mark.tsx +21 -0
  978. package/src/client/changelog/Changelog.tsx +333 -0
  979. package/src/client/changelog/index.ts +1 -0
  980. package/src/client/chat/ChatHistoryList.tsx +7 -0
  981. package/src/client/chat/attachment-adapters.ts +426 -0
  982. package/src/client/chat/connectors.ts +1579 -0
  983. package/src/client/chat/index.ts +160 -0
  984. package/src/client/chat/markdown-renderer.tsx +693 -0
  985. package/src/client/chat/message-components.tsx +1326 -0
  986. package/src/client/chat/repo-helpers.ts +281 -0
  987. package/src/client/chat/run-recovery.tsx +994 -0
  988. package/src/client/chat/runtime.ts +1810 -0
  989. package/src/client/chat/tool-call-display.tsx +1270 -0
  990. package/src/client/chat/tool-render-registry.tsx +144 -0
  991. package/src/client/chat/use-agent-chat-lifecycle-tracking.ts +74 -0
  992. package/src/client/chat/use-reconnect-reader-owner.ts +28 -0
  993. package/src/client/chat/widgets/DataChartRenderer.tsx +242 -0
  994. package/src/client/chat/widgets/DataChartWidget.tsx +51 -0
  995. package/src/client/chat/widgets/DataInsightsWidget.tsx +59 -0
  996. package/src/client/chat/widgets/DataTableWidget.tsx +240 -0
  997. package/src/client/chat/widgets/InlineExtensionWidget.tsx +60 -0
  998. package/src/client/chat/widgets/builtin-tool-renderers.tsx +213 -0
  999. package/src/client/chat/widgets/data-widget-types.ts +1 -0
  1000. package/src/client/chat/widgets/inline-extension-result.ts +86 -0
  1001. package/src/client/chat-model-groups.ts +171 -0
  1002. package/src/client/chat-thread-url.ts +11 -0
  1003. package/src/client/chat-view-transition.ts +213 -0
  1004. package/src/client/client-action.ts +21 -0
  1005. package/src/client/client-bootstrap.ts +7 -0
  1006. package/src/client/client-surface.ts +41 -0
  1007. package/src/client/clipboard.ts +89 -0
  1008. package/src/client/code-agent-chat-adapter.ts +537 -0
  1009. package/src/client/collab/index.ts +60 -0
  1010. package/src/client/command-navigation/index.ts +15 -0
  1011. package/src/client/comments-review/index.ts +1 -0
  1012. package/src/client/components/AgentPresenceChip.tsx +4 -0
  1013. package/src/client/components/ApiKeySettings.tsx +309 -0
  1014. package/src/client/components/CodeAgentIndicator.tsx +59 -0
  1015. package/src/client/components/CodeRequiredDialog.tsx +470 -0
  1016. package/src/client/components/LiveCursorOverlay.tsx +5 -0
  1017. package/src/client/components/MissingKeyCard.tsx +61 -0
  1018. package/src/client/components/PresenceBar.tsx +4 -0
  1019. package/src/client/components/RecentEditHighlights.tsx +4 -0
  1020. package/src/client/components/RemoteSelectionRings.tsx +5 -0
  1021. package/src/client/components/icons/AgentNativeIcon.tsx +46 -0
  1022. package/src/client/components/ui/dialog.tsx +1 -0
  1023. package/src/client/components/ui/dropdown-menu.tsx +1 -0
  1024. package/src/client/components/ui/hover-card.tsx +1 -0
  1025. package/src/client/components/ui/message-scroller.tsx +131 -0
  1026. package/src/client/components/ui/popover.tsx +1 -0
  1027. package/src/client/components/ui/sheet.tsx +1 -0
  1028. package/src/client/components/ui/tooltip.tsx +1 -0
  1029. package/src/client/composer/index.ts +11 -0
  1030. package/src/client/composer/runtime-adapters.tsx +123 -0
  1031. package/src/client/composer/use-mention-search.ts +7 -0
  1032. package/src/client/composer/wired-components.tsx +53 -0
  1033. package/src/client/context-xray/ContextMeter.tsx +124 -0
  1034. package/src/client/context-xray/ContextSegmentRow.tsx +27 -0
  1035. package/src/client/context-xray/ContextTreemap.tsx +24 -0
  1036. package/src/client/context-xray/ContextXRayPanel.tsx +59 -0
  1037. package/src/client/context-xray/SegmentProvenancePopover.tsx +18 -0
  1038. package/src/client/context-xray/format.ts +27 -0
  1039. package/src/client/conversation/AgentConversation.tsx +555 -0
  1040. package/src/client/conversation/code-agent-transcript.ts +283 -0
  1041. package/src/client/conversation/index.ts +22 -0
  1042. package/src/client/conversation/types.ts +85 -0
  1043. package/src/client/conversation/use-near-bottom-autoscroll.ts +278 -0
  1044. package/src/client/create-query-client.ts +86 -0
  1045. package/src/client/db-admin/DataGrid.tsx +551 -0
  1046. package/src/client/db-admin/DbAdminPage.tsx +218 -0
  1047. package/src/client/db-admin/DevDatabaseLink.tsx +16 -0
  1048. package/src/client/db-admin/EditableCell.tsx +451 -0
  1049. package/src/client/db-admin/FilterBar.tsx +203 -0
  1050. package/src/client/db-admin/ResultsGrid.tsx +114 -0
  1051. package/src/client/db-admin/RowSidePanel.tsx +337 -0
  1052. package/src/client/db-admin/SqlEditor.tsx +840 -0
  1053. package/src/client/db-admin/TableBrowser.tsx +212 -0
  1054. package/src/client/db-admin/TableEditor.tsx +760 -0
  1055. package/src/client/db-admin/cell-format.ts +246 -0
  1056. package/src/client/db-admin/changeset.ts +296 -0
  1057. package/src/client/db-admin/export-utils.ts +78 -0
  1058. package/src/client/db-admin/index.ts +33 -0
  1059. package/src/client/db-admin/sql-storage.ts +134 -0
  1060. package/src/client/db-admin/storage.ts +68 -0
  1061. package/src/client/db-admin/useAgentSync.ts +226 -0
  1062. package/src/client/db-admin/useDbAdmin.ts +294 -0
  1063. package/src/client/dev-overlay/DevOverlay.tsx +576 -0
  1064. package/src/client/dev-overlay/builtins.ts +40 -0
  1065. package/src/client/dev-overlay/index.ts +23 -0
  1066. package/src/client/dev-overlay/registry.ts +67 -0
  1067. package/src/client/dev-overlay/types.ts +64 -0
  1068. package/src/client/dev-overlay/use-dev-option.ts +78 -0
  1069. package/src/client/dev-overlay/use-dev-overlay-shortcut.ts +31 -0
  1070. package/src/client/dynamic-suggestions.ts +455 -0
  1071. package/src/client/embed-auth.ts +544 -0
  1072. package/src/client/embed.ts +54 -0
  1073. package/src/client/error-capture.ts +690 -0
  1074. package/src/client/error-format.ts +211 -0
  1075. package/src/client/error-reporting.ts +100 -0
  1076. package/src/client/extensions/AgentNativeExtensionFrame.e2e-host.tsx +136 -0
  1077. package/src/client/extensions/AgentNativeExtensionFrame.tsx +708 -0
  1078. package/src/client/extensions/EmbeddedExtension.tsx +604 -0
  1079. package/src/client/extensions/ExtensionEditor.tsx +450 -0
  1080. package/src/client/extensions/ExtensionQueryErrorState.tsx +47 -0
  1081. package/src/client/extensions/ExtensionSlot.tsx +345 -0
  1082. package/src/client/extensions/ExtensionViewer.tsx +1502 -0
  1083. package/src/client/extensions/ExtensionViewerPage.tsx +32 -0
  1084. package/src/client/extensions/ExtensionsListPage.tsx +432 -0
  1085. package/src/client/extensions/ExtensionsSidebarSection.tsx +1259 -0
  1086. package/src/client/extensions/InlineExtensionFrame.tsx +660 -0
  1087. package/src/client/extensions/agent-native-extension-runtime.ts +495 -0
  1088. package/src/client/extensions/delete-extension.ts +76 -0
  1089. package/src/client/extensions/extension-load-error.ts +26 -0
  1090. package/src/client/extensions/extension-order.ts +49 -0
  1091. package/src/client/extensions/extension-popularity.ts +61 -0
  1092. package/src/client/extensions/iframe-bridge.ts +377 -0
  1093. package/src/client/extensions/index.ts +84 -0
  1094. package/src/client/extensions/portable-extension.ts +712 -0
  1095. package/src/client/feature-flags/FeatureFlagsPanel.tsx +519 -0
  1096. package/src/client/feature-flags/helpers.ts +77 -0
  1097. package/src/client/feature-flags/index.ts +13 -0
  1098. package/src/client/feature-flags/types.ts +29 -0
  1099. package/src/client/feature-flags/use-feature-flag.ts +26 -0
  1100. package/src/client/feedback-context.ts +90 -0
  1101. package/src/client/frame-protocol.ts +168 -0
  1102. package/src/client/frame.ts +329 -0
  1103. package/src/client/guided-questions.tsx +1152 -0
  1104. package/src/client/history/VersionHistoryPanel.tsx +175 -0
  1105. package/src/client/history/index.ts +21 -0
  1106. package/src/client/history/use-history.ts +114 -0
  1107. package/src/client/hooks/index.ts +46 -0
  1108. package/src/client/host/index.ts +170 -0
  1109. package/src/client/host-bridge.ts +1272 -0
  1110. package/src/client/host-tools.ts +190 -0
  1111. package/src/client/i18n.tsx +798 -0
  1112. package/src/client/index.ts +370 -0
  1113. package/src/client/integrations/IntegrationCard.tsx +186 -0
  1114. package/src/client/integrations/IntegrationsPanel.tsx +633 -0
  1115. package/src/client/integrations/api.ts +295 -0
  1116. package/src/client/integrations/index.ts +29 -0
  1117. package/src/client/integrations/useIntegrationStatus.ts +52 -0
  1118. package/src/client/mcp-app-host.ts +720 -0
  1119. package/src/client/mcp-apps/McpAppRenderer.tsx +760 -0
  1120. package/src/client/navigation/index.ts +54 -0
  1121. package/src/client/notifications/NotificationsBell.tsx +383 -0
  1122. package/src/client/notifications/index.ts +1 -0
  1123. package/src/client/observability/ObservabilityDashboard.tsx +890 -0
  1124. package/src/client/observability/ThumbsFeedback.tsx +160 -0
  1125. package/src/client/observability/index.ts +20 -0
  1126. package/src/client/observability/useObservability.ts +266 -0
  1127. package/src/client/onboarding/OnboardingBanner.tsx +73 -0
  1128. package/src/client/onboarding/OnboardingPanel.tsx +1036 -0
  1129. package/src/client/onboarding/SetupButton.tsx +64 -0
  1130. package/src/client/onboarding/index.ts +25 -0
  1131. package/src/client/onboarding/use-onboarding.ts +164 -0
  1132. package/src/client/onboarding/use-preview-mode.ts +40 -0
  1133. package/src/client/org/InvitationBanner.tsx +148 -0
  1134. package/src/client/org/OrgSwitcher.tsx +754 -0
  1135. package/src/client/org/RequireActiveOrg.tsx +337 -0
  1136. package/src/client/org/TeamPage.tsx +1432 -0
  1137. package/src/client/org/hooks.ts +359 -0
  1138. package/src/client/org/index.ts +70 -0
  1139. package/src/client/org/workspace-app-links.ts +367 -0
  1140. package/src/client/org-team/index.ts +1 -0
  1141. package/src/client/progress/RunsTray.tsx +680 -0
  1142. package/src/client/progress/index.ts +1 -0
  1143. package/src/client/require-session.tsx +142 -0
  1144. package/src/client/resources/BuiltinCapabilityDetail.tsx +258 -0
  1145. package/src/client/resources/McpConnectionSuggestion.tsx +276 -0
  1146. package/src/client/resources/McpIntegrationDialog.tsx +808 -0
  1147. package/src/client/resources/McpServerDetail.tsx +230 -0
  1148. package/src/client/resources/ResourceEditor.tsx +872 -0
  1149. package/src/client/resources/ResourceTree.tsx +860 -0
  1150. package/src/client/resources/ResourcesPanel.tsx +1960 -0
  1151. package/src/client/resources/index.ts +25 -0
  1152. package/src/client/resources/mcp-integration-catalog.ts +771 -0
  1153. package/src/client/resources/mcp-integration-logos.ts +108 -0
  1154. package/src/client/resources/runtime.ts +1 -0
  1155. package/src/client/resources/use-builtin-capabilities.ts +113 -0
  1156. package/src/client/resources/use-mcp-servers.ts +217 -0
  1157. package/src/client/resources/use-resources.ts +402 -0
  1158. package/src/client/review/ReviewCommentComposer.tsx +123 -0
  1159. package/src/client/review/ReviewStatusBadge.tsx +39 -0
  1160. package/src/client/review/ReviewThreadPanel.tsx +625 -0
  1161. package/src/client/review/index.ts +38 -0
  1162. package/src/client/review/use-review.ts +186 -0
  1163. package/src/client/route-chunk-recovery/index.ts +1 -0
  1164. package/src/client/route-chunk-recovery.ts +331 -0
  1165. package/src/client/route-state.ts +455 -0
  1166. package/src/client/route-warmup.tsx +543 -0
  1167. package/src/client/session-replay-iframe.e2e-host.tsx +100 -0
  1168. package/src/client/session-replay.ts +3417 -0
  1169. package/src/client/settings/AgentsSection.tsx +441 -0
  1170. package/src/client/settings/AutomationsSection.tsx +516 -0
  1171. package/src/client/settings/BackgroundAgentSection.tsx +189 -0
  1172. package/src/client/settings/BrowserSection.tsx +110 -0
  1173. package/src/client/settings/DemoModeSection.tsx +48 -0
  1174. package/src/client/settings/SecretsSection.tsx +875 -0
  1175. package/src/client/settings/SettingsPanel.tsx +3162 -0
  1176. package/src/client/settings/SettingsSection.tsx +283 -0
  1177. package/src/client/settings/SettingsTabsPage.tsx +592 -0
  1178. package/src/client/settings/UsageSection.tsx +401 -0
  1179. package/src/client/settings/VoiceTranscriptionSection.tsx +960 -0
  1180. package/src/client/settings/agent-settings-search.ts +220 -0
  1181. package/src/client/settings/index.ts +27 -0
  1182. package/src/client/settings/useBuilderStatus.ts +1055 -0
  1183. package/src/client/setup-connections/BuilderConnectCard.tsx +89 -0
  1184. package/src/client/setup-connections/ProviderReadinessBadge.tsx +73 -0
  1185. package/src/client/setup-connections/SetupConnectionsPage.tsx +94 -0
  1186. package/src/client/setup-connections/catalog.ts +6 -0
  1187. package/src/client/setup-connections/index.ts +47 -0
  1188. package/src/client/setup-connections/runtime.ts +1 -0
  1189. package/src/client/sharing/ShareButton.tsx +1748 -0
  1190. package/src/client/sharing/ShareDialog.tsx +846 -0
  1191. package/src/client/sharing/VisibilityBadge.tsx +4 -0
  1192. package/src/client/sharing/index.ts +2 -0
  1193. package/src/client/sse-event-processor.ts +2002 -0
  1194. package/src/client/terminal/AgentTerminal.tsx +488 -0
  1195. package/src/client/terminal/index.ts +7 -0
  1196. package/src/client/theme.ts +27 -0
  1197. package/src/client/tombstone/agent-presence-chip.ts +17 -0
  1198. package/src/client/tombstone/editor.ts +265 -0
  1199. package/src/client/tombstone/live-cursor-overlay.ts +21 -0
  1200. package/src/client/tombstone/presence-bar.ts +17 -0
  1201. package/src/client/tombstone/recent-edit-highlights.ts +17 -0
  1202. package/src/client/tombstone/remote-selection-rings.ts +21 -0
  1203. package/src/client/tombstone/rich-markdown-editor.ts +265 -0
  1204. package/src/client/tombstone/ui-dialog.ts +49 -0
  1205. package/src/client/tombstone/ui-dropdown-menu.ts +69 -0
  1206. package/src/client/tombstone/ui-hover-card.ts +21 -0
  1207. package/src/client/tombstone/ui-popover.ts +25 -0
  1208. package/src/client/tombstone/ui-sheet.ts +49 -0
  1209. package/src/client/tombstone/ui-tooltip.ts +29 -0
  1210. package/src/client/tombstone/visual-style-controls.ts +61 -0
  1211. package/src/client/tool-cells/BashCell.tsx +164 -0
  1212. package/src/client/tool-cells/EditCell.tsx +303 -0
  1213. package/src/client/tool-cells/FilesChangedSummary.tsx +208 -0
  1214. package/src/client/tool-cells/WriteCell.tsx +145 -0
  1215. package/src/client/tool-cells/index.ts +7 -0
  1216. package/src/client/tool-display.ts +41 -0
  1217. package/src/client/track.ts +57 -0
  1218. package/src/client/transcription/BuilderTranscriptionCta.tsx +120 -0
  1219. package/src/client/transcription/use-live-transcription.ts +292 -0
  1220. package/src/client/ui/index.ts +55 -0
  1221. package/src/client/uploads/index.ts +6 -0
  1222. package/src/client/uploads/upload-editor-image.ts +79 -0
  1223. package/src/client/uploads/use-upload-resource.ts +24 -0
  1224. package/src/client/url-scrub.ts +51 -0
  1225. package/src/client/use-action.ts +766 -0
  1226. package/src/client/use-agent-chat-context.ts +63 -0
  1227. package/src/client/use-agent-chat-home-handoff.ts +207 -0
  1228. package/src/client/use-agent-chat.ts +53 -0
  1229. package/src/client/use-agent-engine-configured.ts +211 -0
  1230. package/src/client/use-avatar.ts +127 -0
  1231. package/src/client/use-change-version.ts +150 -0
  1232. package/src/client/use-chat-models.ts +252 -0
  1233. package/src/client/use-chat-threads.ts +1262 -0
  1234. package/src/client/use-db-sync.ts +1112 -0
  1235. package/src/client/use-demo-mode-status.ts +30 -0
  1236. package/src/client/use-dev-mode.ts +177 -0
  1237. package/src/client/use-external-value.ts +40 -0
  1238. package/src/client/use-pausing-interval.ts +65 -0
  1239. package/src/client/use-pinch-zoom.ts +202 -0
  1240. package/src/client/use-run-stuck-detection.ts +427 -0
  1241. package/src/client/use-send-to-agent-chat.ts +85 -0
  1242. package/src/client/use-session.ts +114 -0
  1243. package/src/client/utils.ts +7 -0
  1244. package/src/client/visual-style-controls.tsx +1 -0
  1245. package/src/client/vite-dev-recovery-script.ts +226 -0
  1246. package/src/client/voice-provider-status.ts +44 -0
  1247. package/src/client/widgets/index.ts +41 -0
  1248. package/src/code-agents/background-controller.ts +398 -0
  1249. package/src/code-agents/background-run.ts +156 -0
  1250. package/src/code-agents/index.ts +95 -0
  1251. package/src/code-agents/prompt-attachments.ts +39 -0
  1252. package/src/code-agents/transcript-normalizer.ts +750 -0
  1253. package/src/code-agents/transcript-order.ts +73 -0
  1254. package/src/coding-tools/index.ts +742 -0
  1255. package/src/coding-tools/run-code.ts +1662 -0
  1256. package/src/coding-tools/sandbox/adapter.ts +82 -0
  1257. package/src/coding-tools/sandbox/background.ts +406 -0
  1258. package/src/coding-tools/sandbox/executions-store.ts +517 -0
  1259. package/src/coding-tools/sandbox/index.ts +132 -0
  1260. package/src/coding-tools/sandbox/local-child-process-adapter.ts +217 -0
  1261. package/src/collab/agent-identity.ts +5 -0
  1262. package/src/collab/agent-presence.ts +341 -0
  1263. package/src/collab/awareness-store.ts +196 -0
  1264. package/src/collab/awareness.ts +317 -0
  1265. package/src/collab/client-struct.ts +366 -0
  1266. package/src/collab/client.ts +1205 -0
  1267. package/src/collab/emitter.ts +31 -0
  1268. package/src/collab/follow-mode.ts +107 -0
  1269. package/src/collab/index.ts +151 -0
  1270. package/src/collab/json-to-yjs.ts +504 -0
  1271. package/src/collab/presence.ts +207 -0
  1272. package/src/collab/recent-edits.ts +215 -0
  1273. package/src/collab/routes.ts +191 -0
  1274. package/src/collab/storage.ts +228 -0
  1275. package/src/collab/struct-routes.ts +133 -0
  1276. package/src/collab/text-to-yjs.ts +79 -0
  1277. package/src/collab/undo.ts +432 -0
  1278. package/src/collab/xml-ops.ts +68 -0
  1279. package/src/collab/ydoc-manager.ts +544 -0
  1280. package/src/command-navigation/actions.ts +100 -0
  1281. package/src/command-navigation/index.ts +12 -0
  1282. package/src/comments-review/index.ts +1 -0
  1283. package/src/connections/catalog.ts +451 -0
  1284. package/src/connections/index.ts +48 -0
  1285. package/src/connections/reader.ts +911 -0
  1286. package/src/connections/runtime.ts +1 -0
  1287. package/src/credentials/index.ts +187 -0
  1288. package/src/data-programs/actions.ts +335 -0
  1289. package/src/data-programs/contract.ts +284 -0
  1290. package/src/data-programs/execute.ts +693 -0
  1291. package/src/data-programs/index.ts +72 -0
  1292. package/src/data-programs/schema.ts +148 -0
  1293. package/src/data-programs/store.ts +755 -0
  1294. package/src/data-widgets/index.ts +376 -0
  1295. package/src/db/client.ts +1627 -0
  1296. package/src/db/create-get-db.ts +579 -0
  1297. package/src/db/ddl-guard.ts +302 -0
  1298. package/src/db/drizzle-config.ts +190 -0
  1299. package/src/db/ensure-additive-columns.ts +430 -0
  1300. package/src/db/index.ts +57 -0
  1301. package/src/db/migrations.ts +691 -0
  1302. package/src/db/request-telemetry.ts +154 -0
  1303. package/src/db/runtime-diagnostics.ts +331 -0
  1304. package/src/db/schema.ts +121 -0
  1305. package/src/db/widen-columns.ts +75 -0
  1306. package/src/db-admin/agent-tools.ts +202 -0
  1307. package/src/db-admin/index.ts +26 -0
  1308. package/src/db-admin/operations.ts +803 -0
  1309. package/src/db-admin/routes.ts +174 -0
  1310. package/src/db-admin/types.ts +110 -0
  1311. package/src/demo/browser-state.ts +47 -0
  1312. package/src/demo/fetch-interceptor.ts +175 -0
  1313. package/src/demo/redact.ts +575 -0
  1314. package/src/deploy/build.ts +3935 -0
  1315. package/src/deploy/immutable-assets.ts +65 -0
  1316. package/src/deploy/route-discovery.ts +458 -0
  1317. package/src/deploy/workspace-core.ts +282 -0
  1318. package/src/deploy/workspace-deploy.ts +1488 -0
  1319. package/src/eject/provider-api-definitions.ts +193 -0
  1320. package/src/eject/remote-mcp-presets.ts +137 -0
  1321. package/src/eject/setup-readiness-ui.tsx +29 -0
  1322. package/src/eject/workspace-connections.ts +92 -0
  1323. package/src/embedding/agent.ts +159 -0
  1324. package/src/embedding/bridge.ts +297 -0
  1325. package/src/embedding/index.ts +43 -0
  1326. package/src/embedding/protocol.ts +185 -0
  1327. package/src/embedding/react.tsx +319 -0
  1328. package/src/embeddings/index.ts +233 -0
  1329. package/src/eval/agent-runner.ts +210 -0
  1330. package/src/eval/define-eval.ts +55 -0
  1331. package/src/eval/index.ts +49 -0
  1332. package/src/eval/report.ts +75 -0
  1333. package/src/eval/runner.ts +369 -0
  1334. package/src/eval/scorer.ts +244 -0
  1335. package/src/eval/types.ts +188 -0
  1336. package/src/event-bus/bus.ts +140 -0
  1337. package/src/event-bus/index.ts +3 -0
  1338. package/src/event-bus/registry.ts +79 -0
  1339. package/src/event-bus/types.ts +29 -0
  1340. package/src/extensions/actions.ts +1636 -0
  1341. package/src/extensions/change-marker.ts +54 -0
  1342. package/src/extensions/content-patch.ts +468 -0
  1343. package/src/extensions/fetch-tool.ts +461 -0
  1344. package/src/extensions/html-shell.ts +803 -0
  1345. package/src/extensions/local.ts +462 -0
  1346. package/src/extensions/path.ts +40 -0
  1347. package/src/extensions/proxy-security.ts +171 -0
  1348. package/src/extensions/routes.ts +1080 -0
  1349. package/src/extensions/schema.ts +269 -0
  1350. package/src/extensions/session-replay-iframe.ts +131 -0
  1351. package/src/extensions/slots/routes.ts +126 -0
  1352. package/src/extensions/slots/schema.ts +87 -0
  1353. package/src/extensions/slots/store.ts +450 -0
  1354. package/src/extensions/store.ts +1347 -0
  1355. package/src/extensions/theme.ts +114 -0
  1356. package/src/extensions/url-safety.ts +316 -0
  1357. package/src/extensions/web-content.ts +663 -0
  1358. package/src/extensions/web-search-tool.ts +437 -0
  1359. package/src/feature-flags/a2a-action-route.ts +56 -0
  1360. package/src/feature-flags/actions/get-feature-flags.ts +24 -0
  1361. package/src/feature-flags/actions/list-feature-flags.ts +69 -0
  1362. package/src/feature-flags/actions/set-feature-flag.ts +89 -0
  1363. package/src/feature-flags/index.ts +21 -0
  1364. package/src/feature-flags/permissions.ts +53 -0
  1365. package/src/feature-flags/plugin.ts +44 -0
  1366. package/src/feature-flags/registry.ts +96 -0
  1367. package/src/feature-flags/store.ts +176 -0
  1368. package/src/file-upload/actions/upload-image.ts +213 -0
  1369. package/src/file-upload/builder.ts +431 -0
  1370. package/src/file-upload/index.ts +24 -0
  1371. package/src/file-upload/pre-upload-attachments.ts +305 -0
  1372. package/src/file-upload/registry.ts +125 -0
  1373. package/src/file-upload/types.ts +89 -0
  1374. package/src/guards/db-tool-scoping.ts +129 -0
  1375. package/src/guards/index.ts +23 -0
  1376. package/src/guards/no-drizzle-push.ts +116 -0
  1377. package/src/guards/no-env-credentials.ts +229 -0
  1378. package/src/guards/no-env-mutation.ts +114 -0
  1379. package/src/guards/no-localhost-fallback.ts +124 -0
  1380. package/src/guards/no-unscoped-credentials.ts +227 -0
  1381. package/src/guards/no-unscoped-queries.ts +834 -0
  1382. package/src/guards/scan-utils.ts +105 -0
  1383. package/src/guards/types.ts +30 -0
  1384. package/src/history/actions/create-resource-version.ts +92 -0
  1385. package/src/history/actions/get-resource-version.ts +60 -0
  1386. package/src/history/actions/list-resource-history.ts +53 -0
  1387. package/src/history/actions/list-resource-versions.ts +43 -0
  1388. package/src/history/actions/restore-resource-version.ts +96 -0
  1389. package/src/history/index.ts +26 -0
  1390. package/src/history/registry.ts +111 -0
  1391. package/src/history/store.ts +379 -0
  1392. package/src/history/types.ts +69 -0
  1393. package/src/index.browser.ts +155 -0
  1394. package/src/index.ts +408 -0
  1395. package/src/ingestion/docx.ts +158 -0
  1396. package/src/ingestion/figma-node-to-html.ts +1860 -0
  1397. package/src/ingestion/figma.ts +548 -0
  1398. package/src/ingestion/index.ts +107 -0
  1399. package/src/ingestion/media.ts +264 -0
  1400. package/src/ingestion/notion.ts +121 -0
  1401. package/src/ingestion/office.ts +213 -0
  1402. package/src/ingestion/orchestration.ts +160 -0
  1403. package/src/ingestion/pptx.ts +331 -0
  1404. package/src/ingestion/selection.ts +81 -0
  1405. package/src/ingestion/website.ts +151 -0
  1406. package/src/integrations/a2a-continuation-marker.ts +2 -0
  1407. package/src/integrations/a2a-continuation-processor.ts +888 -0
  1408. package/src/integrations/a2a-continuations-store.ts +643 -0
  1409. package/src/integrations/adapter-overrides.ts +12 -0
  1410. package/src/integrations/adapters/discord.ts +364 -0
  1411. package/src/integrations/adapters/email.ts +1164 -0
  1412. package/src/integrations/adapters/google-docs.ts +371 -0
  1413. package/src/integrations/adapters/index.ts +29 -0
  1414. package/src/integrations/adapters/microsoft-teams.ts +413 -0
  1415. package/src/integrations/adapters/slack.ts +1914 -0
  1416. package/src/integrations/adapters/telegram.ts +386 -0
  1417. package/src/integrations/adapters/whatsapp.ts +358 -0
  1418. package/src/integrations/awaiting-input-store.ts +130 -0
  1419. package/src/integrations/catalog.ts +571 -0
  1420. package/src/integrations/computer-supervision-store.ts +423 -0
  1421. package/src/integrations/computer-supervision.ts +213 -0
  1422. package/src/integrations/config-store.ts +131 -0
  1423. package/src/integrations/controls-store.ts +187 -0
  1424. package/src/integrations/eject/messaging-adapters.ts +85 -0
  1425. package/src/integrations/google-docs-poller.ts +671 -0
  1426. package/src/integrations/identity-links-store.ts +210 -0
  1427. package/src/integrations/identity.ts +196 -0
  1428. package/src/integrations/index.ts +220 -0
  1429. package/src/integrations/installations-store.ts +677 -0
  1430. package/src/integrations/integration-memory.ts +187 -0
  1431. package/src/integrations/internal-token.ts +106 -0
  1432. package/src/integrations/pending-tasks-retry-job.ts +286 -0
  1433. package/src/integrations/pending-tasks-store.ts +468 -0
  1434. package/src/integrations/plugin.ts +3048 -0
  1435. package/src/integrations/remote-commands-store.ts +690 -0
  1436. package/src/integrations/remote-devices-store.ts +492 -0
  1437. package/src/integrations/remote-json-safety.ts +127 -0
  1438. package/src/integrations/remote-push-delivery-job.ts +48 -0
  1439. package/src/integrations/remote-push-delivery.ts +370 -0
  1440. package/src/integrations/remote-push-store.ts +664 -0
  1441. package/src/integrations/remote-retry-job.ts +55 -0
  1442. package/src/integrations/remote-run-events-store.ts +222 -0
  1443. package/src/integrations/remote-types.ts +186 -0
  1444. package/src/integrations/runtime.ts +1 -0
  1445. package/src/integrations/scope-store.ts +498 -0
  1446. package/src/integrations/slack-manifest.ts +78 -0
  1447. package/src/integrations/slack-oauth.ts +344 -0
  1448. package/src/integrations/task-queue-stats.ts +144 -0
  1449. package/src/integrations/thread-mapping-store.ts +134 -0
  1450. package/src/integrations/types.ts +485 -0
  1451. package/src/integrations/usage-budget-store.ts +906 -0
  1452. package/src/integrations/webhook-delivery.ts +55 -0
  1453. package/src/integrations/webhook-handler.ts +1939 -0
  1454. package/src/jobs/actions/list-recurring-jobs.ts +105 -0
  1455. package/src/jobs/actions/manage-recurring-job.ts +85 -0
  1456. package/src/jobs/cron.ts +126 -0
  1457. package/src/jobs/index.ts +9 -0
  1458. package/src/jobs/scheduler.ts +703 -0
  1459. package/src/jobs/tools.ts +367 -0
  1460. package/src/local-artifacts/index.ts +1372 -0
  1461. package/src/localization/actions/get-localization-preference.ts +24 -0
  1462. package/src/localization/actions/set-localization-preference.ts +32 -0
  1463. package/src/localization/default-messages.ts +1009 -0
  1464. package/src/localization/index.ts +2 -0
  1465. package/src/localization/server.ts +131 -0
  1466. package/src/localization/shared.ts +208 -0
  1467. package/src/mcp/actions/call-mcp-tool.ts +19 -0
  1468. package/src/mcp/actions/create-org-service-token.ts +87 -0
  1469. package/src/mcp/actions/list-mcp-tools.ts +18 -0
  1470. package/src/mcp/actions/list-org-service-tokens.ts +44 -0
  1471. package/src/mcp/actions/revoke-org-service-token.ts +30 -0
  1472. package/src/mcp/actions/service-token-access.ts +121 -0
  1473. package/src/mcp/ask-app-inline-tasks.ts +125 -0
  1474. package/src/mcp/build-server.ts +2356 -0
  1475. package/src/mcp/builtin-tools.ts +1506 -0
  1476. package/src/mcp/connect-route.ts +1460 -0
  1477. package/src/mcp/connect-store.ts +680 -0
  1478. package/src/mcp/embed-app.ts +2051 -0
  1479. package/src/mcp/embed-route.ts +84 -0
  1480. package/src/mcp/external-agent-policy.ts +18 -0
  1481. package/src/mcp/index.ts +47 -0
  1482. package/src/mcp/oauth-route.ts +1016 -0
  1483. package/src/mcp/oauth-store.ts +581 -0
  1484. package/src/mcp/oauth-token.ts +227 -0
  1485. package/src/mcp/org-directory.ts +343 -0
  1486. package/src/mcp/route-paths.ts +34 -0
  1487. package/src/mcp/screen-memory-stdio.ts +290 -0
  1488. package/src/mcp/server.ts +507 -0
  1489. package/src/mcp/stdio.ts +328 -0
  1490. package/src/mcp/workspace-resolve.ts +261 -0
  1491. package/src/mcp-client/app-api.ts +136 -0
  1492. package/src/mcp-client/app-result.ts +64 -0
  1493. package/src/mcp-client/builtin-capabilities.ts +146 -0
  1494. package/src/mcp-client/builtin-store.ts +93 -0
  1495. package/src/mcp-client/config.ts +281 -0
  1496. package/src/mcp-client/errors.ts +54 -0
  1497. package/src/mcp-client/hub-client.ts +172 -0
  1498. package/src/mcp-client/hub-routes.ts +198 -0
  1499. package/src/mcp-client/index.ts +504 -0
  1500. package/src/mcp-client/manager.ts +968 -0
  1501. package/src/mcp-client/oauth-client.ts +462 -0
  1502. package/src/mcp-client/oauth-routes.ts +307 -0
  1503. package/src/mcp-client/remote-store.ts +674 -0
  1504. package/src/mcp-client/remote-url.ts +97 -0
  1505. package/src/mcp-client/routes.ts +1093 -0
  1506. package/src/mcp-client/screen-memory-local.ts +461 -0
  1507. package/src/mcp-client/tool-policy.ts +182 -0
  1508. package/src/mcp-client/visibility.ts +56 -0
  1509. package/src/mcp-client/workspace-servers.ts +379 -0
  1510. package/src/navigation/index.ts +170 -0
  1511. package/src/notifications/actions.ts +151 -0
  1512. package/src/notifications/channels.ts +410 -0
  1513. package/src/notifications/index.ts +22 -0
  1514. package/src/notifications/registry.ts +216 -0
  1515. package/src/notifications/routes.ts +106 -0
  1516. package/src/notifications/store.ts +236 -0
  1517. package/src/notifications/types.ts +52 -0
  1518. package/src/oauth-tokens/google-refresh.ts +175 -0
  1519. package/src/oauth-tokens/index.ts +15 -0
  1520. package/src/oauth-tokens/store.ts +384 -0
  1521. package/src/observability/cleanup-job.ts +124 -0
  1522. package/src/observability/evals.ts +507 -0
  1523. package/src/observability/experiments.ts +359 -0
  1524. package/src/observability/feedback.ts +332 -0
  1525. package/src/observability/hosted-model-experiment.ts +118 -0
  1526. package/src/observability/index.ts +62 -0
  1527. package/src/observability/plugin.ts +31 -0
  1528. package/src/observability/routes.ts +431 -0
  1529. package/src/observability/sentiment.ts +261 -0
  1530. package/src/observability/store.ts +1347 -0
  1531. package/src/observability/traces.ts +789 -0
  1532. package/src/observability/tracing.ts +157 -0
  1533. package/src/observability/tracking-identity.ts +55 -0
  1534. package/src/observability/types.ts +211 -0
  1535. package/src/onboarding/default-steps.ts +428 -0
  1536. package/src/onboarding/index.ts +22 -0
  1537. package/src/onboarding/plugin.ts +262 -0
  1538. package/src/onboarding/registry.ts +47 -0
  1539. package/src/onboarding/types.ts +96 -0
  1540. package/src/org/accept-pending.ts +98 -0
  1541. package/src/org/auto-join-domain.ts +113 -0
  1542. package/src/org/context.ts +614 -0
  1543. package/src/org/free-email-providers.ts +124 -0
  1544. package/src/org/handlers.ts +1153 -0
  1545. package/src/org/index.ts +63 -0
  1546. package/src/org/migrations.ts +105 -0
  1547. package/src/org/permissions.ts +30 -0
  1548. package/src/org/plugin.ts +255 -0
  1549. package/src/org/schema.ts +28 -0
  1550. package/src/org/types.ts +57 -0
  1551. package/src/org-team/index.ts +1 -0
  1552. package/src/package-lifecycle/deprecated-imports.ts +179 -0
  1553. package/src/package-lifecycle/eject-manifest.ts +345 -0
  1554. package/src/package-lifecycle/index.ts +7 -0
  1555. package/src/package-lifecycle/manifest.ts +120 -0
  1556. package/src/package-lifecycle/migration-manifest.ts +159 -0
  1557. package/src/package-lifecycle/migration-message.ts +6 -0
  1558. package/src/package-lifecycle/tombstone.ts +58 -0
  1559. package/src/package-lifecycle/upgrade-error.ts +37 -0
  1560. package/src/private-blob/index.ts +18 -0
  1561. package/src/private-blob/registry.ts +242 -0
  1562. package/src/private-blob/types.ts +55 -0
  1563. package/src/progress/actions.ts +179 -0
  1564. package/src/progress/index.ts +16 -0
  1565. package/src/progress/registry.ts +127 -0
  1566. package/src/progress/routes.ts +89 -0
  1567. package/src/progress/store.ts +353 -0
  1568. package/src/progress/types.ts +59 -0
  1569. package/src/provider-api/actions/custom-provider-registration.ts +197 -0
  1570. package/src/provider-api/actions/delete-staged-dataset.ts +5 -0
  1571. package/src/provider-api/actions/github-repo-files.ts +266 -0
  1572. package/src/provider-api/actions/list-staged-datasets.ts +5 -0
  1573. package/src/provider-api/actions/provider-api-audit.ts +88 -0
  1574. package/src/provider-api/actions/provider-api.ts +460 -0
  1575. package/src/provider-api/actions/query-staged-dataset.ts +5 -0
  1576. package/src/provider-api/actions/staged-datasets.ts +359 -0
  1577. package/src/provider-api/corpus-jobs-store.ts +522 -0
  1578. package/src/provider-api/corpus-jobs.ts +1817 -0
  1579. package/src/provider-api/custom-registry.ts +456 -0
  1580. package/src/provider-api/github-repo.ts +675 -0
  1581. package/src/provider-api/gong.ts +108 -0
  1582. package/src/provider-api/index.ts +5444 -0
  1583. package/src/provider-api/quota-governor.ts +562 -0
  1584. package/src/provider-api/runtime.ts +1 -0
  1585. package/src/provider-api/staged-datasets-aggregate.ts +304 -0
  1586. package/src/provider-api/staged-datasets-store.ts +441 -0
  1587. package/src/provider-api/staging.ts +483 -0
  1588. package/src/resources/agents.ts +65 -0
  1589. package/src/resources/emitter.ts +54 -0
  1590. package/src/resources/handlers.ts +728 -0
  1591. package/src/resources/index.ts +4 -0
  1592. package/src/resources/metadata.ts +252 -0
  1593. package/src/resources/script-helpers.ts +160 -0
  1594. package/src/resources/store.ts +1618 -0
  1595. package/src/review/actions/consume-review-feedback.ts +48 -0
  1596. package/src/review/actions/create-review-comment.ts +108 -0
  1597. package/src/review/actions/delete-review-comment.ts +67 -0
  1598. package/src/review/actions/get-review-feedback.ts +49 -0
  1599. package/src/review/actions/list-review-comments.ts +87 -0
  1600. package/src/review/actions/reply-review-comment.ts +118 -0
  1601. package/src/review/actions/resolve-review-thread.ts +94 -0
  1602. package/src/review/actions/send-review-thread-to-agent.ts +62 -0
  1603. package/src/review/actions/set-review-status.ts +58 -0
  1604. package/src/review/identity.ts +101 -0
  1605. package/src/review/index.ts +45 -0
  1606. package/src/review/mentions.ts +44 -0
  1607. package/src/review/registry.ts +111 -0
  1608. package/src/review/store.ts +997 -0
  1609. package/src/review/types.ts +101 -0
  1610. package/src/router/index.ts +24 -0
  1611. package/src/scripts/agent-engines/list-agent-engines.ts +130 -0
  1612. package/src/scripts/agent-engines/manage-agent-engine.ts +197 -0
  1613. package/src/scripts/agent-engines/set-agent-engine.ts +84 -0
  1614. package/src/scripts/agent-engines/test-agent-engine.ts +174 -0
  1615. package/src/scripts/call-agent.ts +792 -0
  1616. package/src/scripts/chat/index.ts +8 -0
  1617. package/src/scripts/chat/open-chat.ts +56 -0
  1618. package/src/scripts/chat/search-chats.ts +121 -0
  1619. package/src/scripts/core-scripts.ts +22 -0
  1620. package/src/scripts/db/check-scoping.ts +212 -0
  1621. package/src/scripts/db/exec.ts +791 -0
  1622. package/src/scripts/db/index.ts +19 -0
  1623. package/src/scripts/db/migrate-encrypt-credentials.ts +223 -0
  1624. package/src/scripts/db/migrate-encrypt-oauth-tokens.ts +213 -0
  1625. package/src/scripts/db/migrate-user-api-keys.ts +257 -0
  1626. package/src/scripts/db/patch.ts +820 -0
  1627. package/src/scripts/db/query.ts +299 -0
  1628. package/src/scripts/db/reset-dev-owner.ts +285 -0
  1629. package/src/scripts/db/safety.ts +286 -0
  1630. package/src/scripts/db/schema.ts +364 -0
  1631. package/src/scripts/db/scoping.ts +341 -0
  1632. package/src/scripts/db/sqlite-client.ts +78 -0
  1633. package/src/scripts/db/tool-mode.ts +23 -0
  1634. package/src/scripts/db/tool-schemas.ts +31 -0
  1635. package/src/scripts/db/wipe-leaked-builder-keys.ts +201 -0
  1636. package/src/scripts/dev/index.ts +296 -0
  1637. package/src/scripts/dev/list-files.ts +119 -0
  1638. package/src/scripts/dev/read-file.ts +77 -0
  1639. package/src/scripts/dev/search-files.ts +151 -0
  1640. package/src/scripts/dev/shell.ts +111 -0
  1641. package/src/scripts/dev/write-file.ts +56 -0
  1642. package/src/scripts/dev-session.ts +96 -0
  1643. package/src/scripts/docs/index.ts +8 -0
  1644. package/src/scripts/docs/search.ts +274 -0
  1645. package/src/scripts/docs/source-search.ts +363 -0
  1646. package/src/scripts/index.ts +15 -0
  1647. package/src/scripts/manage-agent-loop-settings.ts +84 -0
  1648. package/src/scripts/parse-args.ts +46 -0
  1649. package/src/scripts/resources/delete-memory.ts +67 -0
  1650. package/src/scripts/resources/delete.ts +69 -0
  1651. package/src/scripts/resources/effective.ts +71 -0
  1652. package/src/scripts/resources/index.ts +18 -0
  1653. package/src/scripts/resources/list.ts +103 -0
  1654. package/src/scripts/resources/migrate-learnings.ts +40 -0
  1655. package/src/scripts/resources/read.ts +107 -0
  1656. package/src/scripts/resources/save-memory.ts +99 -0
  1657. package/src/scripts/resources/write.ts +158 -0
  1658. package/src/scripts/runner.ts +339 -0
  1659. package/src/scripts/utils.ts +130 -0
  1660. package/src/search/index.ts +413 -0
  1661. package/src/search-utils/index.ts +112 -0
  1662. package/src/secrets/crypto.ts +228 -0
  1663. package/src/secrets/index.ts +65 -0
  1664. package/src/secrets/onboarding.ts +101 -0
  1665. package/src/secrets/register-framework-secrets.ts +228 -0
  1666. package/src/secrets/register.ts +129 -0
  1667. package/src/secrets/routes.ts +697 -0
  1668. package/src/secrets/schema.ts +52 -0
  1669. package/src/secrets/storage.ts +561 -0
  1670. package/src/secrets/substitution.ts +305 -0
  1671. package/src/server/__snapshots__/agent-chat-plugin.surface.spec.ts.snap +150 -0
  1672. package/src/server/action-change.ts +66 -0
  1673. package/src/server/action-discovery.ts +774 -0
  1674. package/src/server/action-routes.ts +608 -0
  1675. package/src/server/agent-access.ts +72 -0
  1676. package/src/server/agent-chat/action-filters-a2a.ts +339 -0
  1677. package/src/server/agent-chat/browser-team-tools.ts +510 -0
  1678. package/src/server/agent-chat/context-tools.ts +599 -0
  1679. package/src/server/agent-chat/framework-prompts.ts +467 -0
  1680. package/src/server/agent-chat/lazy-fs.ts +11 -0
  1681. package/src/server/agent-chat/mcp-glue.ts +91 -0
  1682. package/src/server/agent-chat/plugin-options.ts +379 -0
  1683. package/src/server/agent-chat/process-run-failure.ts +62 -0
  1684. package/src/server/agent-chat/prompt-resources.ts +1004 -0
  1685. package/src/server/agent-chat/recurring-jobs-runtime.ts +80 -0
  1686. package/src/server/agent-chat/request-surface.ts +71 -0
  1687. package/src/server/agent-chat/run-code-tools.ts +67 -0
  1688. package/src/server/agent-chat/script-entries.ts +796 -0
  1689. package/src/server/agent-chat/shared-thread.ts +301 -0
  1690. package/src/server/agent-chat/skill-frontmatter.ts +41 -0
  1691. package/src/server/agent-chat-plugin.ts +5930 -0
  1692. package/src/server/agent-discovery.ts +706 -0
  1693. package/src/server/agent-engine-api-key-route.ts +236 -0
  1694. package/src/server/agent-run-context.ts +204 -0
  1695. package/src/server/agent-teams-run-queue.ts +344 -0
  1696. package/src/server/agent-teams.ts +2257 -0
  1697. package/src/server/agents-bundle.ts +464 -0
  1698. package/src/server/analytics.ts +105 -0
  1699. package/src/server/app-base-path.ts +79 -0
  1700. package/src/server/app-name.ts +53 -0
  1701. package/src/server/app-url.ts +184 -0
  1702. package/src/server/attachment-actions.ts +276 -0
  1703. package/src/server/attribution.ts +214 -0
  1704. package/src/server/auth-marketing.ts +260 -0
  1705. package/src/server/auth-plugin.ts +27 -0
  1706. package/src/server/auth.ts +3803 -0
  1707. package/src/server/better-auth-instance.ts +1197 -0
  1708. package/src/server/builder-browser.ts +1701 -0
  1709. package/src/server/builder-design-systems.ts +668 -0
  1710. package/src/server/builder-space.ts +176 -0
  1711. package/src/server/captcha.ts +63 -0
  1712. package/src/server/capture-error.ts +64 -0
  1713. package/src/server/cli-capture.ts +141 -0
  1714. package/src/server/collab-plugin.ts +391 -0
  1715. package/src/server/complete-text.ts +231 -0
  1716. package/src/server/cookie-namespace.ts +159 -0
  1717. package/src/server/core-routes-plugin.ts +4122 -0
  1718. package/src/server/cors-origins.ts +60 -0
  1719. package/src/server/create-server.ts +268 -0
  1720. package/src/server/credential-provider.ts +1202 -0
  1721. package/src/server/csrf.ts +229 -0
  1722. package/src/server/date-utils.ts +42 -0
  1723. package/src/server/deep-link.ts +119 -0
  1724. package/src/server/derived-secret.ts +32 -0
  1725. package/src/server/design-token-utils.ts +1032 -0
  1726. package/src/server/desktop-sso.ts +83 -0
  1727. package/src/server/edge.ts +69 -0
  1728. package/src/server/email-actions.ts +218 -0
  1729. package/src/server/email-template.ts +192 -0
  1730. package/src/server/email-templates.ts +148 -0
  1731. package/src/server/email.ts +219 -0
  1732. package/src/server/embed-route.ts +283 -0
  1733. package/src/server/embed-session.ts +805 -0
  1734. package/src/server/embedded.ts +252 -0
  1735. package/src/server/entry-server.tsx +154 -0
  1736. package/src/server/framework-request-handler.ts +848 -0
  1737. package/src/server/fusion-app.ts +447 -0
  1738. package/src/server/google-auth-mode.ts +34 -0
  1739. package/src/server/google-auth-plugin.ts +496 -0
  1740. package/src/server/google-oauth-credentials.ts +128 -0
  1741. package/src/server/google-oauth.ts +972 -0
  1742. package/src/server/google-realtime-session.ts +182 -0
  1743. package/src/server/h3-helpers.ts +174 -0
  1744. package/src/server/http-response-telemetry.ts +396 -0
  1745. package/src/server/identity-sso-store.ts +304 -0
  1746. package/src/server/identity-sso.ts +514 -0
  1747. package/src/server/index.ts +593 -0
  1748. package/src/server/missing-key.ts +36 -0
  1749. package/src/server/oauth-helpers.ts +44 -0
  1750. package/src/server/oauth-public-origin.ts +44 -0
  1751. package/src/server/oauth-return-url.ts +120 -0
  1752. package/src/server/og-fonts-data.ts +15 -0
  1753. package/src/server/og-fonts.ts +75 -0
  1754. package/src/server/onboarding-html.ts +4040 -0
  1755. package/src/server/open-route.ts +311 -0
  1756. package/src/server/org-admin.ts +28 -0
  1757. package/src/server/poll-events.ts +88 -0
  1758. package/src/server/poll.ts +1224 -0
  1759. package/src/server/prompts/framework-core-compact.ts +107 -0
  1760. package/src/server/prompts/framework-core.ts +143 -0
  1761. package/src/server/prompts/index.ts +16 -0
  1762. package/src/server/prompts/model-overlays.ts +54 -0
  1763. package/src/server/prompts/shared-rules.ts +104 -0
  1764. package/src/server/realtime-voice.ts +967 -0
  1765. package/src/server/recap-image-route.ts +242 -0
  1766. package/src/server/recap-image-store.ts +185 -0
  1767. package/src/server/request-context.ts +416 -0
  1768. package/src/server/request-origin.ts +67 -0
  1769. package/src/server/resources-plugin.ts +119 -0
  1770. package/src/server/schema-prompt.ts +429 -0
  1771. package/src/server/scoped-key-storage.ts +223 -0
  1772. package/src/server/security-headers.ts +170 -0
  1773. package/src/server/self-dispatch.ts +224 -0
  1774. package/src/server/sentry-config.ts +73 -0
  1775. package/src/server/sentry-plugin.ts +138 -0
  1776. package/src/server/sentry.ts +444 -0
  1777. package/src/server/short-lived-token.ts +170 -0
  1778. package/src/server/social-og-image.ts +454 -0
  1779. package/src/server/sse.ts +102 -0
  1780. package/src/server/ssr-handler.ts +466 -0
  1781. package/src/server/transcribe-voice.ts +1076 -0
  1782. package/src/server/voice-providers-status.ts +118 -0
  1783. package/src/server/workspace-oauth.ts +31 -0
  1784. package/src/server/workspace-provider-oauth.ts +970 -0
  1785. package/src/session-replay-iframe-protocol.ts +58 -0
  1786. package/src/settings/handlers.ts +44 -0
  1787. package/src/settings/index.ts +34 -0
  1788. package/src/settings/org-settings.ts +83 -0
  1789. package/src/settings/script-helpers.ts +24 -0
  1790. package/src/settings/store.ts +247 -0
  1791. package/src/settings/user-settings.ts +47 -0
  1792. package/src/setup-connections/index.ts +90 -0
  1793. package/src/setup-connections/onboarding.ts +47 -0
  1794. package/src/shared/agent-access.ts +112 -0
  1795. package/src/shared/agent-chat.ts +124 -0
  1796. package/src/shared/agent-env.ts +46 -0
  1797. package/src/shared/agent-readable-resource.ts +111 -0
  1798. package/src/shared/agent-sidebar-url.ts +39 -0
  1799. package/src/shared/cache-control.ts +25 -0
  1800. package/src/shared/cloudflare-globals.d.ts +34 -0
  1801. package/src/shared/context-xray.ts +172 -0
  1802. package/src/shared/embed-auth.ts +6 -0
  1803. package/src/shared/index.ts +83 -0
  1804. package/src/shared/llm-connection.ts +42 -0
  1805. package/src/shared/markdown-block-split.ts +129 -0
  1806. package/src/shared/mcp-connect-content.ts +130 -0
  1807. package/src/shared/mcp-embed-headers.ts +175 -0
  1808. package/src/shared/mcp-integration-config.ts +101 -0
  1809. package/src/shared/merge-by-id.ts +14 -0
  1810. package/src/shared/oauth-state.ts +39 -0
  1811. package/src/shared/reasoning-effort.ts +228 -0
  1812. package/src/shared/route-warmup-config.ts +128 -0
  1813. package/src/shared/runtime.ts +31 -0
  1814. package/src/shared/social-meta.ts +82 -0
  1815. package/src/shared/streaming-text-smoothing.ts +184 -0
  1816. package/src/shared/truncate.ts +13 -0
  1817. package/src/shared/workspace-app-audience.ts +177 -0
  1818. package/src/shared/workspace-app-id.ts +54 -0
  1819. package/src/sharing/access.ts +585 -0
  1820. package/src/sharing/actions/create-agent-resource-link.ts +91 -0
  1821. package/src/sharing/actions/extension-change.ts +22 -0
  1822. package/src/sharing/actions/list-resource-shares.ts +93 -0
  1823. package/src/sharing/actions/set-resource-visibility.ts +91 -0
  1824. package/src/sharing/actions/share-resource.ts +322 -0
  1825. package/src/sharing/actions/unshare-resource.ts +72 -0
  1826. package/src/sharing/index.ts +35 -0
  1827. package/src/sharing/registry.ts +201 -0
  1828. package/src/sharing/schema.ts +99 -0
  1829. package/src/styles/agent-conversation.css +766 -0
  1830. package/src/styles/agent-native.css +938 -0
  1831. package/src/styles/blocks.css +1717 -0
  1832. package/src/styles/chat-history-list.css +1 -0
  1833. package/src/styles/rich-markdown-editor.css +1 -0
  1834. package/src/tailwind.preset.ts +140 -0
  1835. package/src/templates/chat/.agents/skills/actions/SKILL.md +32 -12
  1836. package/src/templates/chat/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1837. package/src/templates/chat/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1838. package/src/templates/chat/.agents/skills/self-modifying-code/SKILL.md +14 -2
  1839. package/src/templates/chat/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1840. package/src/templates/chat/AGENTS.md +6 -2
  1841. package/src/templates/chat/app/components/layout/Sidebar.tsx +51 -157
  1842. package/src/templates/default/.agents/skills/actions/SKILL.md +32 -12
  1843. package/src/templates/default/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1844. package/src/templates/default/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1845. package/src/templates/default/.agents/skills/integration-webhooks/SKILL.md +323 -0
  1846. package/src/templates/default/.agents/skills/onboarding/SKILL.md +56 -0
  1847. package/src/templates/default/.agents/skills/secrets/SKILL.md +273 -0
  1848. package/src/templates/default/.agents/skills/self-modifying-code/SKILL.md +14 -2
  1849. package/src/templates/default/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1850. package/src/templates/default/AGENTS.md +26 -18
  1851. package/src/templates/headless/.agents/skills/actions/SKILL.md +512 -0
  1852. package/src/templates/headless/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1853. package/src/templates/headless/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1854. package/src/templates/headless/.agents/skills/integration-webhooks/SKILL.md +323 -0
  1855. package/src/templates/headless/.agents/skills/secrets/SKILL.md +273 -0
  1856. package/src/templates/headless/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1857. package/src/templates/headless/AGENTS.md +8 -0
  1858. package/src/templates/workspace-core/.agents/skills/actions/SKILL.md +32 -12
  1859. package/src/templates/workspace-core/.agents/skills/agent-native-docs/SKILL.md +21 -9
  1860. package/src/templates/workspace-core/.agents/skills/agent-native-toolkit/SKILL.md +7 -0
  1861. package/src/templates/workspace-core/.agents/skills/customizing-agent-native/SKILL.md +145 -0
  1862. package/src/templates/workspace-core/.agents/skills/self-modifying-code/SKILL.md +14 -2
  1863. package/src/templates/workspace-core/.agents/skills/upgrade-agent-native/SKILL.md +6 -0
  1864. package/src/templates/workspace-core/AGENTS.md +4 -0
  1865. package/src/templates/workspace-root/AGENTS.md +4 -0
  1866. package/src/terminal/cli-registry.ts +57 -0
  1867. package/src/terminal/index.ts +22 -0
  1868. package/src/terminal/pty-server.ts +389 -0
  1869. package/src/terminal/terminal-plugin.ts +265 -0
  1870. package/src/testing.ts +23 -0
  1871. package/src/tracking/index.ts +10 -0
  1872. package/src/tracking/providers.ts +422 -0
  1873. package/src/tracking/registry.ts +102 -0
  1874. package/src/tracking/route.ts +108 -0
  1875. package/src/tracking/types.ts +16 -0
  1876. package/src/transcription/builder-transcription.ts +118 -0
  1877. package/src/triggers/actions/list-automations.ts +99 -0
  1878. package/src/triggers/actions/manage-automation.ts +78 -0
  1879. package/src/triggers/actions.ts +333 -0
  1880. package/src/triggers/condition-evaluator.ts +163 -0
  1881. package/src/triggers/dispatcher.ts +536 -0
  1882. package/src/triggers/index.ts +13 -0
  1883. package/src/triggers/routes.ts +322 -0
  1884. package/src/triggers/types.ts +42 -0
  1885. package/src/types/pglite.d.ts +26 -0
  1886. package/src/usage/store.ts +698 -0
  1887. package/src/vite/action-types-plugin.ts +481 -0
  1888. package/src/vite/agent-web-plugin.ts +78 -0
  1889. package/src/vite/agents-bundle-plugin.ts +185 -0
  1890. package/src/vite/client.ts +3039 -0
  1891. package/src/vite/index.ts +21 -0
  1892. package/src/voice/index.ts +18 -0
  1893. package/src/voice/voice-cleanup-prompt.ts +38 -0
  1894. package/src/voice/voice-context.ts +217 -0
  1895. package/src/voice/voice-replacements.ts +75 -0
  1896. package/src/workspace-connections/credentials.ts +603 -0
  1897. package/src/workspace-connections/index.ts +72 -0
  1898. package/src/workspace-connections/lifecycle.ts +43 -0
  1899. package/src/workspace-connections/store.ts +1943 -0
  1900. package/src/workspace-files/index.ts +18 -0
  1901. package/src/workspace-files/store.ts +339 -0
  1902. package/src/workspace-files/tool.ts +266 -0
@@ -0,0 +1,3162 @@
1
+ import * as SelectPrimitive from "@radix-ui/react-select";
2
+ import {
3
+ IconChevronDown,
4
+ IconChevronRight,
5
+ IconCheck,
6
+ IconExternalLink,
7
+ IconBrain,
8
+ IconHierarchy2,
9
+ IconBrowser,
10
+ IconGitBranch,
11
+ IconCloud,
12
+ IconDatabase,
13
+ IconShield,
14
+ IconPlugConnected,
15
+ IconTopologyRing2,
16
+ IconLoader2,
17
+ IconUpload,
18
+ IconCoin,
19
+ IconMail,
20
+ IconKey,
21
+ IconMicrophone,
22
+ IconEyeOff,
23
+ IconBolt,
24
+ IconGauge,
25
+ IconUserCircle,
26
+ IconApps,
27
+ IconUsersGroup,
28
+ } from "@tabler/icons-react";
29
+ import React, {
30
+ Suspense,
31
+ lazy,
32
+ useState,
33
+ useEffect,
34
+ useCallback,
35
+ useMemo,
36
+ useRef,
37
+ } from "react";
38
+
39
+ import { PROVIDER_ENV_PLACEHOLDERS } from "../../agent/engine/provider-env-vars.js";
40
+ import { saveAgentEngineProviderSettings } from "../agent-engine-key.js";
41
+ import { agentNativePath } from "../api-path.js";
42
+ import { BuilderBMark } from "../builder-mark.js";
43
+ import {
44
+ Tooltip,
45
+ TooltipContent,
46
+ TooltipTrigger,
47
+ } from "../components/ui/tooltip.js";
48
+ import { TeamPage } from "../org/TeamPage.js";
49
+ import { BuilderConnectCard } from "../setup-connections/BuilderConnectCard.js";
50
+ import { callAction } from "../use-action.js";
51
+ import { uploadAvatar, useAvatarUrl } from "../use-avatar.js";
52
+ import { useDevMode } from "../use-dev-mode.js";
53
+ import { useSession } from "../use-session.js";
54
+ import { cn } from "../utils.js";
55
+ import {
56
+ AGENT_SETTINGS_SECTIONS,
57
+ ALL_SETTINGS_SECTIONS,
58
+ CONNECTION_SETTINGS_SECTIONS,
59
+ SETTINGS_SECTION_IDS,
60
+ WORKSPACE_SETTINGS_SECTIONS,
61
+ getAgentSettingsSearchTabs,
62
+ type SettingsSectionId,
63
+ } from "./agent-settings-search.js";
64
+ import { AgentsSection } from "./AgentsSection.js";
65
+ import { AutomationsSection } from "./AutomationsSection.js";
66
+ import { DemoModeSection } from "./DemoModeSection.js";
67
+ import { SecretsSection } from "./SecretsSection.js";
68
+ import {
69
+ SettingsSection,
70
+ SettingsSurfaceProvider,
71
+ useSettingsSurface,
72
+ type SettingsSurface,
73
+ } from "./SettingsSection.js";
74
+ import type { SettingsTabItem } from "./SettingsTabsPage.js";
75
+ import { UsageSection } from "./UsageSection.js";
76
+ import {
77
+ type BuilderConnectFlow,
78
+ useBuilderConnectFlow,
79
+ useBuilderStatus,
80
+ } from "./useBuilderStatus.js";
81
+ import { VoiceTranscriptionSection } from "./VoiceTranscriptionSection.js";
82
+
83
+ const IntegrationsPanel = lazy(() =>
84
+ import("../integrations/IntegrationsPanel.js").then((m) => ({
85
+ default: m.IntegrationsPanel,
86
+ })),
87
+ );
88
+
89
+ // ─── Shared helpers ─────────────────────────────────────────────────────────
90
+
91
+ function SettingsSkeleton({ lines = 3 }: { lines?: number }) {
92
+ return (
93
+ <div className="space-y-3 animate-pulse">
94
+ {Array.from({ length: lines }, (_, i) => (
95
+ <div key={i} className="space-y-1.5">
96
+ <div
97
+ className="h-3 rounded bg-muted-foreground/10"
98
+ style={{ width: i === 0 ? "30%" : i === 1 ? "100%" : "60%" }}
99
+ />
100
+ {i < 2 && (
101
+ <div className="h-9 rounded-md border border-border bg-muted-foreground/5" />
102
+ )}
103
+ </div>
104
+ ))}
105
+ </div>
106
+ );
107
+ }
108
+
109
+ interface SettingsSelectOption {
110
+ value: string;
111
+ label: string;
112
+ description?: string;
113
+ }
114
+
115
+ const CONTROL_STYLE = {
116
+ fontSize: 12,
117
+ lineHeight: 1,
118
+ } satisfies React.CSSProperties;
119
+
120
+ const CONTROL_STYLE_PAGE = {
121
+ fontSize: 14,
122
+ lineHeight: 1.2,
123
+ } satisfies React.CSSProperties;
124
+
125
+ // Surface-aware class helpers so section bodies (shared with the compact
126
+ // sidebar) read as roomy, shadcn-style forms on the full settings page while
127
+ // staying dense in the sidebar.
128
+ function fieldLabelClass(isPage: boolean): string {
129
+ return cn("font-medium text-foreground", isPage ? "text-sm" : "text-[12px]");
130
+ }
131
+
132
+ // Secondary label / row-title size (e.g. "This app", provider names).
133
+ function subTextClass(isPage: boolean): string {
134
+ return isPage ? "text-sm" : "text-[11px]";
135
+ }
136
+
137
+ // Helper / hint / status note size.
138
+ function noteTextClass(isPage: boolean): string {
139
+ return isPage ? "text-xs" : "text-[10px]";
140
+ }
141
+
142
+ function textInputClass(isPage: boolean): string {
143
+ return cn(
144
+ "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",
145
+ isPage ? "h-10 px-3 text-sm" : "h-9 px-3 text-[12px]",
146
+ );
147
+ }
148
+
149
+ function pillButtonClass(
150
+ isPage: boolean,
151
+ tone: "solid" | "outline" | "ghost" = "outline",
152
+ ): string {
153
+ const base = cn(
154
+ "inline-flex items-center justify-center gap-1 rounded-md font-medium transition-colors disabled:opacity-40",
155
+ isPage ? "px-3 py-1.5 text-sm" : "px-2.5 py-1 text-[10px]",
156
+ );
157
+ if (tone === "solid") {
158
+ return cn(base, "bg-accent text-foreground hover:bg-accent/80");
159
+ }
160
+ if (tone === "ghost") {
161
+ return cn(
162
+ base,
163
+ "text-muted-foreground hover:bg-accent/40 hover:text-foreground",
164
+ );
165
+ }
166
+ return cn(base, "border border-border text-foreground hover:bg-accent/40");
167
+ }
168
+
169
+ function SettingsSelect({
170
+ label,
171
+ labelAdornment,
172
+ value,
173
+ options,
174
+ onValueChange,
175
+ disabled = false,
176
+ }: {
177
+ label: string;
178
+ labelAdornment?: React.ReactNode;
179
+ value: string;
180
+ options: SettingsSelectOption[];
181
+ onValueChange: (value: string) => void;
182
+ disabled?: boolean;
183
+ }) {
184
+ const isPage = useSettingsSurface() === "page";
185
+ const controlStyle = isPage ? CONTROL_STYLE_PAGE : CONTROL_STYLE;
186
+ const selected = options.find((option) => option.value === value);
187
+
188
+ return (
189
+ <div className="space-y-1.5">
190
+ <div className="flex items-center justify-between">
191
+ <p className={fieldLabelClass(isPage)}>{label}</p>
192
+ {labelAdornment}
193
+ </div>
194
+ <SelectPrimitive.Root
195
+ value={value}
196
+ onValueChange={onValueChange}
197
+ disabled={disabled}
198
+ >
199
+ <SelectPrimitive.Trigger
200
+ className={cn(
201
+ "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 disabled:cursor-not-allowed disabled:opacity-60",
202
+ isPage ? "h-10 text-sm" : "h-9 text-[12px]",
203
+ )}
204
+ aria-label={label}
205
+ style={controlStyle}
206
+ >
207
+ <SelectPrimitive.Value>
208
+ {selected?.label ?? value}
209
+ </SelectPrimitive.Value>
210
+ <SelectPrimitive.Icon asChild>
211
+ <IconChevronDown size={16} className="text-muted-foreground" />
212
+ </SelectPrimitive.Icon>
213
+ </SelectPrimitive.Trigger>
214
+ <SelectPrimitive.Portal>
215
+ <SelectPrimitive.Content
216
+ position="popper"
217
+ sideOffset={6}
218
+ className="z-[9999] w-[var(--radix-select-trigger-width)] overflow-hidden rounded-lg border border-border bg-popover shadow-lg"
219
+ >
220
+ <SelectPrimitive.Viewport className="p-1">
221
+ {options.map((option) => (
222
+ <SelectPrimitive.Item
223
+ key={option.value}
224
+ value={option.value}
225
+ className={cn(
226
+ "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",
227
+ isPage ? "py-2.5 text-sm" : "py-2.5 text-[12px]",
228
+ )}
229
+ style={controlStyle}
230
+ >
231
+ <span className="absolute start-2 top-2.5 flex h-4 w-4 items-center justify-center text-muted-foreground">
232
+ <SelectPrimitive.ItemIndicator>
233
+ <IconCheck size={14} />
234
+ </SelectPrimitive.ItemIndicator>
235
+ </span>
236
+ <div className="flex min-w-0 flex-col">
237
+ <SelectPrimitive.ItemText>
238
+ <span className="text-foreground">{option.label}</span>
239
+ </SelectPrimitive.ItemText>
240
+ {option.description ? (
241
+ <span
242
+ className={cn(
243
+ "mt-0.5 leading-relaxed text-muted-foreground",
244
+ isPage ? "text-xs" : "text-[11px]",
245
+ )}
246
+ >
247
+ {option.description}
248
+ </span>
249
+ ) : null}
250
+ </div>
251
+ </SelectPrimitive.Item>
252
+ ))}
253
+ </SelectPrimitive.Viewport>
254
+ </SelectPrimitive.Content>
255
+ </SelectPrimitive.Portal>
256
+ </SelectPrimitive.Root>
257
+ </div>
258
+ );
259
+ }
260
+
261
+ // ─── Disconnect button for the Builder card's connected state ───────────────
262
+ //
263
+ // Two-step confirmation: first click arms the button ("Confirm?"), second
264
+ // click actually disconnects. Arm auto-reverts after 4s of idle so a user
265
+ // who wandered off doesn't come back to a disconnect waiting for them.
266
+ //
267
+ // Hits /_agent-native/builder/disconnect which removes request-scoped
268
+ // Builder credentials from app_secrets. Deployment env credentials are left
269
+ // alone and remain as fallback. On success we dispatch
270
+ // `agent-engine:configured-changed` so dependent cards refresh inline.
271
+ function DisconnectBuilderButton() {
272
+ const { status } = useBuilderStatus();
273
+ const [phase, setPhase] = useState<"idle" | "armed" | "busy">("idle");
274
+ const [err, setErr] = useState<string | null>(null);
275
+ const armedTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);
276
+
277
+ const clearArmedTimer = useCallback(() => {
278
+ if (armedTimerRef.current) {
279
+ clearTimeout(armedTimerRef.current);
280
+ armedTimerRef.current = null;
281
+ }
282
+ }, []);
283
+
284
+ useEffect(() => {
285
+ return () => clearArmedTimer();
286
+ }, [clearArmedTimer]);
287
+
288
+ const performDisconnect = useCallback(async () => {
289
+ setPhase("busy");
290
+ setErr(null);
291
+ clearArmedTimer();
292
+ try {
293
+ const res = await fetch(
294
+ agentNativePath("/_agent-native/builder/disconnect"),
295
+ {
296
+ method: "POST",
297
+ headers: { "Content-Type": "application/json" },
298
+ },
299
+ );
300
+ // Parse defensively — a nitro 404 fallback returns HTML, not JSON,
301
+ // and res.json() on that would throw.
302
+ const text = await res.text();
303
+ let body: {
304
+ ok?: boolean;
305
+ error?: string;
306
+ warnings?: Record<string, string>;
307
+ } = {};
308
+ if (text) {
309
+ try {
310
+ body = JSON.parse(text);
311
+ } catch {
312
+ // Non-JSON response — likely a 404/HTML fallback.
313
+ }
314
+ }
315
+ if (!res.ok) {
316
+ throw new Error(
317
+ body.error ||
318
+ `Failed (${res.status}). Is your dev server up to date?`,
319
+ );
320
+ }
321
+ if (body.ok !== true) {
322
+ throw new Error(body.error || "Disconnect didn't confirm ok");
323
+ }
324
+ if (body.warnings && Object.keys(body.warnings).length > 0) {
325
+ // Disconnect flag persisted (we only reach here when ok:true), so
326
+ // the user IS disconnected — but some ancillary cleanup failed.
327
+ // Log so it's visible during dev; don't block the success path.
328
+ console.warn(
329
+ "[builder-disconnect] completed with warnings:",
330
+ body.warnings,
331
+ );
332
+ }
333
+ window.dispatchEvent(new CustomEvent("agent-engine:configured-changed"));
334
+ setPhase("idle");
335
+ } catch (e) {
336
+ setErr(e instanceof Error ? e.message : "Disconnect failed");
337
+ setPhase("idle");
338
+ }
339
+ }, [clearArmedTimer]);
340
+
341
+ const handleDisconnectClick = useCallback(() => {
342
+ if (phase === "busy") return;
343
+ if (phase === "idle") {
344
+ // First click — arm the button. Auto-revert after 4s to avoid a
345
+ // stale "confirm" state someone else could hit by accident.
346
+ setPhase("armed");
347
+ setErr(null);
348
+ clearArmedTimer();
349
+ armedTimerRef.current = setTimeout(() => {
350
+ setPhase("idle");
351
+ armedTimerRef.current = null;
352
+ }, 4000);
353
+ return;
354
+ }
355
+ // phase === "armed" — user confirmed, actually disconnect.
356
+ void performDisconnect();
357
+ }, [phase, performDisconnect, clearArmedTimer]);
358
+
359
+ const handleCancel = useCallback(() => {
360
+ clearArmedTimer();
361
+ setPhase("idle");
362
+ }, [clearArmedTimer]);
363
+
364
+ // When only the deploy fallback is active there is nothing request-scoped
365
+ // for this button to remove. The early return MUST come after every hook
366
+ // above to satisfy rules-of-hooks.
367
+ if (status?.credentialSource === "env") return null;
368
+
369
+ if (phase === "armed") {
370
+ return (
371
+ <>
372
+ <button
373
+ type="button"
374
+ onClick={handleDisconnectClick}
375
+ className="inline-flex items-center gap-1 rounded border border-destructive/40 bg-destructive/10 px-2 py-0.5 text-[10px] font-medium text-destructive hover:bg-destructive/20"
376
+ >
377
+ Confirm disconnect
378
+ </button>
379
+ <button
380
+ type="button"
381
+ onClick={handleCancel}
382
+ className="inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40"
383
+ >
384
+ Cancel
385
+ </button>
386
+ </>
387
+ );
388
+ }
389
+
390
+ return (
391
+ <>
392
+ <button
393
+ type="button"
394
+ onClick={handleDisconnectClick}
395
+ disabled={phase === "busy"}
396
+ className="inline-flex items-center gap-1 rounded border border-border px-2 py-0.5 text-[10px] text-muted-foreground hover:text-foreground hover:bg-accent/40 disabled:opacity-60 disabled:cursor-wait"
397
+ aria-busy={phase === "busy"}
398
+ >
399
+ {phase === "busy" ? (
400
+ <>
401
+ <IconLoader2 size={10} className="animate-spin" />
402
+ Disconnecting…
403
+ </>
404
+ ) : (
405
+ "Disconnect"
406
+ )}
407
+ </button>
408
+ {err && <span className="text-[10px] text-destructive">{err}</span>}
409
+ </>
410
+ );
411
+ }
412
+
413
+ // ─── "Connect Builder.io" card (shared across all sections) ─────────────────
414
+
415
+ function UseBuilderCard({
416
+ builderFlow,
417
+ connectUrl,
418
+ connected,
419
+ orgName,
420
+ envManaged,
421
+ credentialSource,
422
+ trackingSource = "settings_panel_builder_card",
423
+ trackingFlow = "connect_llm",
424
+ label = "Connect Builder.io",
425
+ subtitle = "Free credits to start — no API key needed.",
426
+ dim,
427
+ }: {
428
+ builderFlow: BuilderConnectFlow;
429
+ connectUrl?: string;
430
+ connected: boolean;
431
+ orgName?: string;
432
+ envManaged?: boolean;
433
+ credentialSource?: "user" | "org" | "workspace" | "env";
434
+ trackingSource?: string;
435
+ trackingFlow?: string;
436
+ label?: string;
437
+ subtitle?: string;
438
+ dim?: boolean;
439
+ }) {
440
+ const isPage = useSettingsSurface() === "page";
441
+ const effectiveConnected = connected || builderFlow.configured;
442
+ const effectiveOrgName = builderFlow.orgName ?? orgName;
443
+ const bgClass = dim ? "" : "bg-accent/30";
444
+ const titleCls = isPage ? "text-sm" : "text-[11px]";
445
+ const bodyCls = isPage ? "text-xs" : "text-[10px]";
446
+
447
+ if (effectiveConnected) {
448
+ return (
449
+ <div
450
+ className={cn(
451
+ "rounded-md border border-border",
452
+ isPage ? "px-3.5 py-3" : "px-2.5 py-2",
453
+ bgClass,
454
+ )}
455
+ >
456
+ <div className="flex items-center justify-between">
457
+ <div className={cn("font-medium text-foreground", titleCls)}>
458
+ Builder.io
459
+ </div>
460
+ <span
461
+ className={cn("flex items-center gap-1 text-green-500", bodyCls)}
462
+ >
463
+ <IconCheck size={isPage ? 14 : 10} />
464
+ Connected
465
+ </span>
466
+ </div>
467
+ {effectiveOrgName && (
468
+ <p className={cn("text-muted-foreground mt-0.5", bodyCls)}>
469
+ {effectiveOrgName}
470
+ </p>
471
+ )}
472
+ {envManaged ? (
473
+ <p className={cn("text-muted-foreground mt-1", bodyCls)}>
474
+ {credentialSource === "env"
475
+ ? "Deployment fallback is available. Connect your own account to override it."
476
+ : "Using your connected Builder account. Deployment fallback is still available."}
477
+ </p>
478
+ ) : null}
479
+ {connectUrl || credentialSource !== "env" ? (
480
+ <div className="flex items-center gap-2 mt-2.5">
481
+ {connectUrl && (
482
+ <button
483
+ type="button"
484
+ onClick={() =>
485
+ builderFlow.start({ trackingSource, trackingFlow })
486
+ }
487
+ disabled={builderFlow.connecting}
488
+ className={cn(pillButtonClass(isPage, "ghost"), "no-underline")}
489
+ >
490
+ {builderFlow.connecting
491
+ ? "Connecting..."
492
+ : credentialSource === "env"
493
+ ? "Connect account"
494
+ : "Reconnect"}
495
+ <IconExternalLink size={isPage ? 14 : 10} />
496
+ </button>
497
+ )}
498
+ {credentialSource !== "env" ? <DisconnectBuilderButton /> : null}
499
+ </div>
500
+ ) : null}
501
+ </div>
502
+ );
503
+ }
504
+
505
+ if (!connectUrl) return null;
506
+
507
+ return (
508
+ <button
509
+ type="button"
510
+ onClick={() => builderFlow.start({ trackingSource, trackingFlow })}
511
+ disabled={builderFlow.connecting}
512
+ className={cn(
513
+ "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",
514
+ isPage ? "px-4 py-3.5" : "px-3 py-3",
515
+ )}
516
+ >
517
+ <div className="flex items-start gap-2.5">
518
+ <div
519
+ className={cn(
520
+ "flex shrink-0 items-center justify-center rounded-md bg-foreground text-background",
521
+ isPage ? "h-8 w-8" : "h-7 w-7",
522
+ )}
523
+ >
524
+ <BuilderBMark className={isPage ? "h-4 w-4" : "h-3.5 w-3.5"} />
525
+ </div>
526
+ <div className="flex-1 min-w-0">
527
+ <div className="flex items-center gap-1.5 flex-wrap">
528
+ <span
529
+ className={cn(
530
+ "font-semibold text-foreground",
531
+ isPage ? "text-sm" : "text-[12px]",
532
+ )}
533
+ >
534
+ {builderFlow.connecting ? "Connecting Builder.io..." : label}
535
+ </span>
536
+ {builderFlow.connecting && (
537
+ <IconLoader2
538
+ size={isPage ? 14 : 12}
539
+ className="shrink-0 animate-spin text-muted-foreground"
540
+ />
541
+ )}
542
+ </div>
543
+ <p
544
+ className={cn(
545
+ "text-muted-foreground mt-0.5 leading-snug",
546
+ isPage ? "text-xs" : "text-[10.5px]",
547
+ )}
548
+ >
549
+ {subtitle}
550
+ </p>
551
+ {builderFlow.error && (
552
+ <p className={cn("mt-1 text-destructive", bodyCls)}>
553
+ {builderFlow.error}
554
+ </p>
555
+ )}
556
+ </div>
557
+ <IconExternalLink
558
+ size={isPage ? 14 : 12}
559
+ className="shrink-0 text-muted-foreground mt-0.5"
560
+ />
561
+ </div>
562
+ </button>
563
+ );
564
+ }
565
+
566
+ // ─── Manual setup card ──────────────────────────────────────────────────────
567
+
568
+ function ManualSetupCard({
569
+ hint,
570
+ docsUrl,
571
+ docsLabel = "Read the docs",
572
+ children,
573
+ dim,
574
+ sourceBadge,
575
+ }: {
576
+ hint?: string;
577
+ docsUrl?: string;
578
+ docsLabel?: string;
579
+ children?: React.ReactNode;
580
+ dim?: boolean;
581
+ /** Optional "Connected via X" badge shown in the header row. */
582
+ sourceBadge?: string;
583
+ }) {
584
+ const isPage = useSettingsSurface() === "page";
585
+ const titleCls = isPage ? "text-sm" : "text-[11px]";
586
+ const bodyCls = isPage ? "text-xs" : "text-[10px]";
587
+ return (
588
+ <div
589
+ className={cn(
590
+ "rounded-md border border-border",
591
+ isPage ? "px-3.5 py-3" : "px-2.5 py-2",
592
+ dim ? "" : "bg-accent/30",
593
+ )}
594
+ >
595
+ <div className="flex items-center justify-between mb-1">
596
+ <div className={cn("font-medium text-foreground", titleCls)}>
597
+ Set up manually
598
+ </div>
599
+ {sourceBadge ? (
600
+ <span
601
+ className={cn("flex items-center gap-1 text-green-500", bodyCls)}
602
+ >
603
+ <IconCheck size={isPage ? 14 : 10} />
604
+ {sourceBadge}
605
+ </span>
606
+ ) : null}
607
+ </div>
608
+ {hint && (
609
+ <p className={cn("text-muted-foreground mb-1.5", bodyCls)}>{hint}</p>
610
+ )}
611
+ {children}
612
+ {docsUrl && (
613
+ <a
614
+ href={docsUrl}
615
+ target="_blank"
616
+ rel="noopener noreferrer"
617
+ className={cn(
618
+ pillButtonClass(isPage, "outline"),
619
+ "mt-1.5 no-underline",
620
+ )}
621
+ >
622
+ {docsLabel}
623
+ <IconExternalLink size={isPage ? 14 : 10} />
624
+ </a>
625
+ )}
626
+ </div>
627
+ );
628
+ }
629
+
630
+ // ─── LLM helpers ────────────────────────────────────────────────────────────
631
+
632
+ function friendlyModelName(model: string): string {
633
+ if (model === "z-ai/glm-5.2") return "GLM 5.2";
634
+ const claude = model.match(
635
+ /^claude-(opus|sonnet|haiku)-(\d+)(?:-(\d+))?(?:-\d{8,})?$/,
636
+ );
637
+ if (claude) {
638
+ const tier = claude[1][0].toUpperCase() + claude[1].slice(1);
639
+ return `${tier} ${claude[2]}${claude[3] ? `.${claude[3]}` : ""}`;
640
+ }
641
+ if (model.startsWith("gpt-")) {
642
+ const rest = model.slice(4);
643
+ const gpt = rest.match(/^(\d+)[.-](\d+)(?:[.-](.+))?$/);
644
+ if (gpt) {
645
+ const suffix = gpt[3]
646
+ ? ` ${gpt[3]
647
+ .split("-")
648
+ .map((part) => part[0].toUpperCase() + part.slice(1))
649
+ .join(" ")}`
650
+ : "";
651
+ return `GPT-${gpt[1]}.${gpt[2]}${suffix}`;
652
+ }
653
+ return `GPT-${rest}`;
654
+ }
655
+ if (/^o\d/.test(model)) return model;
656
+ const geminiVersioned = model.match(
657
+ /^gemini-(\d+)-(\d+)-(.+?)(?:-preview)?$/,
658
+ );
659
+ if (geminiVersioned) {
660
+ const variant = geminiVersioned[3]
661
+ .split("-")
662
+ .map((part) => part[0].toUpperCase() + part.slice(1))
663
+ .join(" ");
664
+ return `Gemini ${geminiVersioned[1]}.${geminiVersioned[2]} ${variant}`;
665
+ }
666
+ const gemini = model.match(/^gemini-(.+?)(?:-preview)?$/);
667
+ if (gemini) {
668
+ const parts = gemini[1]
669
+ .split("-")
670
+ .map((s) => s[0].toUpperCase() + s.slice(1))
671
+ .join(" ");
672
+ return `Gemini ${parts}${model.endsWith("-preview") ? " (preview)" : ""}`;
673
+ }
674
+ return model;
675
+ }
676
+
677
+ type SettingsStatus = {
678
+ engine: string;
679
+ source: "env" | "settings";
680
+ envVar: string | null;
681
+ } | null;
682
+
683
+ function computeSourceBadge(args: {
684
+ settingsConfigured: boolean;
685
+ settingsStatus: SettingsStatus;
686
+ envConfigured: boolean;
687
+ envVar: string | undefined;
688
+ builderConnected: boolean;
689
+ }): string | undefined {
690
+ const { settingsConfigured, settingsStatus } = args;
691
+ if (args.builderConnected) return "Connected via Builder";
692
+ if (settingsConfigured) {
693
+ if (settingsStatus?.source === "env") {
694
+ return `Connected via ${settingsStatus.envVar ?? args.envVar ?? "env"}`;
695
+ }
696
+ return "Connected via template (server-side)";
697
+ }
698
+ if (args.envConfigured) return `Connected via ${args.envVar ?? "env"}`;
699
+ return undefined;
700
+ }
701
+
702
+ function latestModelsOnly(models: string[]): string[] {
703
+ const seen = new Set<string>();
704
+ return models.filter((m) => {
705
+ const claude = m.match(/^claude-(opus|sonnet|haiku)-/);
706
+ if (claude) {
707
+ if (seen.has(claude[1])) return false;
708
+ seen.add(claude[1]);
709
+ return true;
710
+ }
711
+ const gemini = m.match(/^gemini-(\d+(?:\.\d+)?)-(.+?)(?:-preview)?$/);
712
+ if (gemini) {
713
+ const family = gemini[2];
714
+ if (seen.has(`gemini-${family}`)) return false;
715
+ seen.add(`gemini-${family}`);
716
+ return true;
717
+ }
718
+ return true;
719
+ });
720
+ }
721
+
722
+ export function AppDefaultModelField({
723
+ engine,
724
+ models,
725
+ value,
726
+ defaultModel,
727
+ disabled,
728
+ onValueChange,
729
+ onEnter,
730
+ }: {
731
+ engine: string;
732
+ models: string[];
733
+ value: string;
734
+ defaultModel?: string;
735
+ disabled?: boolean;
736
+ onValueChange: (value: string) => void;
737
+ onEnter?: () => void;
738
+ }) {
739
+ const isPage = useSettingsSurface() === "page";
740
+ const modelOptions: SettingsSelectOption[] = latestModelsOnly(models).map(
741
+ (model) => ({ value: model, label: friendlyModelName(model) }),
742
+ );
743
+
744
+ // Builder models are a closed catalog (and are validated server-side), so a
745
+ // real select keeps every available model visible even when one is already
746
+ // selected. Native datalists filter against the current input value, which
747
+ // made this field appear to contain only the active model.
748
+ if (engine === "builder" && modelOptions.length > 0) {
749
+ return (
750
+ <SettingsSelect
751
+ label="Model"
752
+ value={value}
753
+ options={modelOptions}
754
+ onValueChange={onValueChange}
755
+ disabled={disabled}
756
+ />
757
+ );
758
+ }
759
+
760
+ return (
761
+ <div className="space-y-1.5">
762
+ <p className={fieldLabelClass(isPage)}>Model</p>
763
+ <input
764
+ type="text"
765
+ list={`app-model-suggestions-${engine}`}
766
+ value={value}
767
+ disabled={disabled}
768
+ onChange={(event) => onValueChange(event.target.value)}
769
+ onKeyDown={(event) => {
770
+ if (event.key === "Enter") onEnter?.();
771
+ }}
772
+ placeholder={defaultModel ?? "model-id"}
773
+ spellCheck={false}
774
+ autoComplete="off"
775
+ className={cn(textInputClass(isPage), "disabled:opacity-60")}
776
+ style={isPage ? CONTROL_STYLE_PAGE : CONTROL_STYLE}
777
+ />
778
+ {modelOptions.length > 0 && (
779
+ <datalist id={`app-model-suggestions-${engine}`}>
780
+ {modelOptions.map((option) => (
781
+ <option
782
+ key={option.value}
783
+ value={option.value}
784
+ label={option.label}
785
+ />
786
+ ))}
787
+ </datalist>
788
+ )}
789
+ </div>
790
+ );
791
+ }
792
+
793
+ // ─── LLM Section ────────────────────────────────────────────────────────────
794
+
795
+ interface EngineInfo {
796
+ name: string;
797
+ label: string;
798
+ description: string;
799
+ defaultModel: string;
800
+ supportedModels: string[];
801
+ requiredEnvVars: string[];
802
+ installPackage?: string;
803
+ packageInstalled?: boolean;
804
+ }
805
+
806
+ const PROVIDER_DOCS: Record<string, string> = {
807
+ anthropic: "https://console.anthropic.com/settings/keys",
808
+ "ai-sdk:anthropic": "https://console.anthropic.com/settings/keys",
809
+ "ai-sdk:openai": "https://platform.openai.com/api-keys",
810
+ "ai-sdk:google": "https://aistudio.google.com/apikey",
811
+ "ai-sdk:openrouter": "https://openrouter.ai/keys",
812
+ "ai-sdk:groq": "https://console.groq.com/keys",
813
+ "ai-sdk:mistral": "https://console.mistral.ai/api-keys/",
814
+ "ai-sdk:cohere": "https://dashboard.cohere.com/api-keys",
815
+ };
816
+
817
+ function LLMSectionInner({
818
+ builderFlow,
819
+ builderLoading,
820
+ connectUrl,
821
+ connected,
822
+ orgName,
823
+ envManaged,
824
+ credentialSource,
825
+ open,
826
+ onToggle,
827
+ }: {
828
+ builderFlow: BuilderConnectFlow;
829
+ builderLoading?: boolean;
830
+ connectUrl?: string;
831
+ connected: boolean;
832
+ orgName?: string;
833
+ envManaged?: boolean;
834
+ credentialSource?: "user" | "org" | "workspace" | "env";
835
+ open?: boolean;
836
+ onToggle?: () => void;
837
+ }) {
838
+ const isPage = useSettingsSurface() === "page";
839
+ const [envKeys, setEnvKeys] = useState<
840
+ Array<{ key: string; configured: boolean }>
841
+ >([]);
842
+ const [apiKey, setApiKey] = useState("");
843
+ const [saving, setSaving] = useState(false);
844
+ const [saved, setSaved] = useState(false);
845
+ const [engines, setEngines] = useState<EngineInfo[]>([]);
846
+ const [currentEngine, setCurrentEngine] = useState("anthropic");
847
+ const [currentModel, setCurrentModel] = useState("");
848
+ const [selectedEngine, setSelectedEngine] = useState("anthropic");
849
+ const [selectedModel, setSelectedModel] = useState("");
850
+ const [baseUrl, setBaseUrl] = useState("");
851
+ const [baseUrlConfigured, setBaseUrlConfigured] = useState(false);
852
+ const [clearBaseUrl, setClearBaseUrl] = useState(false);
853
+ const [advancedOpen, setAdvancedOpen] = useState(false);
854
+ const [applyNote, setApplyNote] = useState(false);
855
+ const [testing, setTesting] = useState(false);
856
+ const [testResult, setTestResult] = useState<
857
+ | { ok: true; latencyMs: number; model: string }
858
+ | { ok: false; error: string }
859
+ | null
860
+ >(null);
861
+ const [settingsStatus, setSettingsStatus] = useState<SettingsStatus>(null);
862
+ const [disconnectError, setDisconnectError] = useState<string | null>(null);
863
+ const [envLoaded, setEnvLoaded] = useState(false);
864
+ const [enginesLoaded, setEnginesLoaded] = useState(false);
865
+ const [statusLoaded, setStatusLoaded] = useState(false);
866
+
867
+ const initialLoading =
868
+ !envLoaded || !enginesLoaded || !statusLoaded || !!builderLoading;
869
+
870
+ useEffect(() => {
871
+ fetch(agentNativePath("/_agent-native/env-status"))
872
+ .then((r) => (r.ok ? r.json() : []))
873
+ .then(setEnvKeys)
874
+ .catch(() => {})
875
+ .finally(() => setEnvLoaded(true));
876
+ }, [saved]);
877
+
878
+ const notifyConfigChanged = useCallback(() => {
879
+ window.dispatchEvent(new CustomEvent("agent-engine:configured-changed"));
880
+ }, []);
881
+
882
+ const refreshSettingsStatus = useCallback(() => {
883
+ fetch(agentNativePath("/_agent-native/agent-engine/status"))
884
+ .then((r) => (r.ok ? r.json() : null))
885
+ .then((data) => {
886
+ setBaseUrlConfigured(Boolean(data?.openAiBaseUrlConfigured));
887
+ if (
888
+ data?.configured &&
889
+ typeof data.engine === "string" &&
890
+ (data.source === "env" || data.source === "settings")
891
+ ) {
892
+ setSettingsStatus({
893
+ engine: data.engine,
894
+ source: data.source,
895
+ envVar: typeof data.envVar === "string" ? data.envVar : null,
896
+ });
897
+ } else {
898
+ setSettingsStatus(null);
899
+ }
900
+ })
901
+ .catch(() => {})
902
+ .finally(() => setStatusLoaded(true));
903
+ }, []);
904
+
905
+ useEffect(() => {
906
+ refreshSettingsStatus();
907
+ }, [refreshSettingsStatus]);
908
+
909
+ useEffect(() => {
910
+ callAction("manage-agent-engine" as any, { action: "list" } as any)
911
+ .then((data) => {
912
+ if (!data) return;
913
+ const engineData = data as {
914
+ engines?: EngineInfo[];
915
+ current?: { engine?: string; model?: string };
916
+ };
917
+ setEngines(engineData.engines ?? []);
918
+ const cur = engineData.current ?? {};
919
+ setCurrentEngine(cur.engine ?? "anthropic");
920
+ setCurrentModel(cur.model ?? "");
921
+ setSelectedEngine(cur.engine ?? "anthropic");
922
+ setSelectedModel(cur.model ?? "");
923
+ })
924
+ .catch(() => {})
925
+ .finally(() => setEnginesLoaded(true));
926
+ }, []);
927
+
928
+ const selectedEngineInfo = engines.find((e) => e.name === selectedEngine);
929
+ const envVar = selectedEngineInfo?.requiredEnvVars?.[0];
930
+ const selectedEnginePackageInstalled =
931
+ selectedEngineInfo?.packageInstalled !== false;
932
+ const envConfigured = envVar
933
+ ? (envKeys.find((k) => k.key === envVar)?.configured ?? false)
934
+ : false;
935
+ const settingsConfigured =
936
+ settingsStatus != null && settingsStatus.engine === currentEngine;
937
+ const builderConnected = connected || builderFlow.configured;
938
+ const anyKeyConfigured =
939
+ builderConnected ||
940
+ (selectedEnginePackageInstalled && (envConfigured || settingsConfigured));
941
+ const sourceBadge = computeSourceBadge({
942
+ settingsConfigured,
943
+ settingsStatus,
944
+ envConfigured,
945
+ envVar,
946
+ builderConnected,
947
+ });
948
+ const manualSetupHint =
949
+ selectedEngine === "ai-sdk:openrouter"
950
+ ? "Provide an OpenRouter key to use OpenRouter models like GLM 5.2."
951
+ : "Choose your AI provider and model.";
952
+
953
+ const engineChanged =
954
+ selectedEngine !== currentEngine || selectedModel !== currentModel;
955
+ const isOpenAiEngine = selectedEngine === "ai-sdk:openai";
956
+ const endpointChanged = isOpenAiEngine && (!!baseUrl.trim() || clearBaseUrl);
957
+ const providerSettingsChanged = !!apiKey.trim() || endpointChanged;
958
+
959
+ // Hide the Anthropic-via-AI-SDK alias (redundant with the native entry)
960
+ // and Ollama (no API key to set here). The currently-selected engine is
961
+ // always kept so a stale setting doesn't vanish from the picker.
962
+ const providerOptions: SettingsSelectOption[] = engines
963
+ .filter(
964
+ (e) =>
965
+ e.name === selectedEngine ||
966
+ (e.name !== "ai-sdk:anthropic" && e.name !== "ai-sdk:ollama"),
967
+ )
968
+ .map((e) => ({ value: e.name, label: e.label }));
969
+
970
+ const modelOptions: SettingsSelectOption[] = latestModelsOnly(
971
+ selectedEngineInfo?.supportedModels ?? [],
972
+ ).map((m) => ({ value: m, label: friendlyModelName(m) }));
973
+
974
+ const handleSave = async () => {
975
+ if (!providerSettingsChanged || !envVar) return;
976
+ setSaving(true);
977
+ try {
978
+ const nextBaseUrl = isOpenAiEngine ? baseUrl.trim() : "";
979
+ await saveAgentEngineProviderSettings({
980
+ key: envVar,
981
+ ...(apiKey.trim() ? { apiKey } : {}),
982
+ ...(nextBaseUrl ? { baseUrl: nextBaseUrl } : {}),
983
+ ...(isOpenAiEngine && clearBaseUrl ? { clearBaseUrl: true } : {}),
984
+ });
985
+ setSaved(true);
986
+ setApiKey("");
987
+ setBaseUrl("");
988
+ setClearBaseUrl(false);
989
+ if (nextBaseUrl) setBaseUrlConfigured(true);
990
+ if (clearBaseUrl) setBaseUrlConfigured(false);
991
+ refreshSettingsStatus();
992
+ notifyConfigChanged();
993
+ setTimeout(() => setSaved(false), 2000);
994
+ } finally {
995
+ setSaving(false);
996
+ }
997
+ };
998
+
999
+ const handleDisconnect = async () => {
1000
+ setDisconnectError(null);
1001
+ try {
1002
+ const res = await fetch(
1003
+ agentNativePath("/_agent-native/agent-engine/disconnect"),
1004
+ {
1005
+ method: "POST",
1006
+ },
1007
+ );
1008
+ if (res.ok) {
1009
+ setTestResult(null);
1010
+ setApplyNote(false);
1011
+ refreshSettingsStatus();
1012
+ notifyConfigChanged();
1013
+ return;
1014
+ }
1015
+ const body = (await res.json().catch(() => null)) as {
1016
+ error?: string;
1017
+ } | null;
1018
+ setDisconnectError(
1019
+ body?.error ??
1020
+ (res.status === 401
1021
+ ? "You must be signed in to disconnect."
1022
+ : `Disconnect failed (HTTP ${res.status})`),
1023
+ );
1024
+ } catch (err) {
1025
+ setDisconnectError(err instanceof Error ? err.message : String(err));
1026
+ }
1027
+ };
1028
+
1029
+ const handleTest = async () => {
1030
+ setTesting(true);
1031
+ setTestResult(null);
1032
+ try {
1033
+ const data = await callAction(
1034
+ "manage-agent-engine" as any,
1035
+ {
1036
+ action: "test",
1037
+ engine: selectedEngine,
1038
+ model: selectedModel || selectedEngineInfo?.defaultModel,
1039
+ } as any,
1040
+ );
1041
+ // Older action paths wrapped tool output in { result }. Accept either
1042
+ // shape while the action route normalizes JSON-string script output.
1043
+ const parsed =
1044
+ typeof data === "string"
1045
+ ? JSON.parse(data)
1046
+ : typeof data?.result === "string"
1047
+ ? JSON.parse(data.result)
1048
+ : data;
1049
+ if (parsed?.ok) {
1050
+ setTestResult({
1051
+ ok: true,
1052
+ latencyMs: parsed.latencyMs ?? 0,
1053
+ model: parsed.model ?? selectedModel,
1054
+ });
1055
+ } else {
1056
+ setTestResult({
1057
+ ok: false,
1058
+ error: parsed?.error ?? "Test failed (no error message)",
1059
+ });
1060
+ }
1061
+ } catch (err) {
1062
+ setTestResult({
1063
+ ok: false,
1064
+ error: err instanceof Error ? err.message : String(err),
1065
+ });
1066
+ } finally {
1067
+ setTesting(false);
1068
+ }
1069
+ };
1070
+
1071
+ const handleApply = async () => {
1072
+ try {
1073
+ const res = await fetch(
1074
+ agentNativePath("/_agent-native/actions/manage-agent-engine"),
1075
+ {
1076
+ method: "POST",
1077
+ headers: { "Content-Type": "application/json" },
1078
+ body: JSON.stringify({
1079
+ action: "set",
1080
+ engine: selectedEngine,
1081
+ model: selectedModel,
1082
+ }),
1083
+ },
1084
+ );
1085
+ if (res.ok) {
1086
+ setCurrentEngine(selectedEngine);
1087
+ setCurrentModel(selectedModel);
1088
+ setApplyNote(true);
1089
+ refreshSettingsStatus();
1090
+ notifyConfigChanged();
1091
+ setTimeout(() => setApplyNote(false), 4000);
1092
+ }
1093
+ } catch {}
1094
+ };
1095
+
1096
+ return (
1097
+ <SettingsSection
1098
+ id={settingsSectionDomId("llm")}
1099
+ icon={<IconBrain size={14} />}
1100
+ title="LLM"
1101
+ subtitle="Connect any major LLM — Claude, GPT, Gemini, and more."
1102
+ required
1103
+ connected={initialLoading ? undefined : anyKeyConfigured}
1104
+ open={open}
1105
+ onToggle={onToggle}
1106
+ >
1107
+ {initialLoading ? (
1108
+ <SettingsSkeleton lines={3} />
1109
+ ) : (
1110
+ <div className="space-y-2">
1111
+ <UseBuilderCard
1112
+ builderFlow={builderFlow}
1113
+ connectUrl={connectUrl}
1114
+ connected={connected}
1115
+ orgName={orgName}
1116
+ envManaged={envManaged}
1117
+ credentialSource={credentialSource}
1118
+ trackingSource="llm_settings"
1119
+ trackingFlow="connect_llm"
1120
+ label="Connect Builder.io"
1121
+ />
1122
+ {!builderConnected && (
1123
+ <ManualSetupCard
1124
+ hint={manualSetupHint}
1125
+ docsUrl={PROVIDER_DOCS[selectedEngine]}
1126
+ sourceBadge={sourceBadge}
1127
+ docsLabel="Get an API key"
1128
+ >
1129
+ <div className="space-y-2 mb-1">
1130
+ <SettingsSelect
1131
+ label="Provider"
1132
+ value={selectedEngine}
1133
+ options={providerOptions}
1134
+ onValueChange={(val) => {
1135
+ setSelectedEngine(val);
1136
+ const info = engines.find((e) => e.name === val);
1137
+ setSelectedModel(info?.defaultModel ?? "");
1138
+ setApiKey("");
1139
+ setBaseUrl("");
1140
+ setClearBaseUrl(false);
1141
+ setAdvancedOpen(false);
1142
+ }}
1143
+ />
1144
+
1145
+ {/* Free-form input so OpenRouter/Ollama custom model IDs can
1146
+ be typed — the registry's supportedModels is only suggestions. */}
1147
+ <div className="space-y-1.5">
1148
+ <p className={fieldLabelClass(isPage)}>Model</p>
1149
+ <input
1150
+ type="text"
1151
+ list={`model-suggestions-${selectedEngine}`}
1152
+ value={selectedModel}
1153
+ onChange={(e) => setSelectedModel(e.target.value)}
1154
+ placeholder={
1155
+ selectedEngineInfo?.defaultModel ?? "e.g. model-id"
1156
+ }
1157
+ spellCheck={false}
1158
+ autoComplete="off"
1159
+ className={textInputClass(isPage)}
1160
+ style={isPage ? CONTROL_STYLE_PAGE : CONTROL_STYLE}
1161
+ />
1162
+ {modelOptions.length > 0 && (
1163
+ <datalist id={`model-suggestions-${selectedEngine}`}>
1164
+ {modelOptions.map((opt) => (
1165
+ <option
1166
+ key={opt.value}
1167
+ value={opt.value}
1168
+ label={opt.label}
1169
+ />
1170
+ ))}
1171
+ </datalist>
1172
+ )}
1173
+ </div>
1174
+
1175
+ {isOpenAiEngine && (
1176
+ <div className="border-t border-border/70 pt-2">
1177
+ <button
1178
+ type="button"
1179
+ onClick={() => setAdvancedOpen((v) => !v)}
1180
+ className="flex w-full cursor-pointer items-center justify-between gap-2 rounded px-0.5 py-1 text-left hover:text-foreground"
1181
+ >
1182
+ <span className="inline-flex min-w-0 items-center gap-1.5 text-[11px] font-medium text-foreground">
1183
+ {advancedOpen ? (
1184
+ <IconChevronDown size={12} />
1185
+ ) : (
1186
+ <IconChevronRight
1187
+ size={12}
1188
+ className="rtl:-scale-x-100"
1189
+ />
1190
+ )}
1191
+ Advanced
1192
+ </span>
1193
+ <span className="truncate text-[10px] text-muted-foreground">
1194
+ OpenAI-compatible endpoint
1195
+ </span>
1196
+ </button>
1197
+
1198
+ {advancedOpen && (
1199
+ <div className="mt-1.5 space-y-1.5">
1200
+ <div className="flex items-center justify-between gap-2">
1201
+ <p className="text-[12px] font-medium text-foreground">
1202
+ Endpoint URL
1203
+ </p>
1204
+ <span className="text-[10px] text-muted-foreground">
1205
+ {baseUrlConfigured ? "Configured" : "Optional"}
1206
+ </span>
1207
+ </div>
1208
+ <input
1209
+ type="url"
1210
+ value={baseUrl}
1211
+ onChange={(e) => {
1212
+ setBaseUrl(e.target.value);
1213
+ if (e.target.value.trim()) setClearBaseUrl(false);
1214
+ }}
1215
+ onKeyDown={(e) => {
1216
+ if (e.key === "Enter") handleSave();
1217
+ }}
1218
+ placeholder={
1219
+ baseUrlConfigured
1220
+ ? "Leave blank to keep current endpoint"
1221
+ : "https://gateway.example/v1"
1222
+ }
1223
+ disabled={clearBaseUrl}
1224
+ spellCheck={false}
1225
+ autoComplete="off"
1226
+ 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 disabled:opacity-50 placeholder:text-muted-foreground/50"
1227
+ style={CONTROL_STYLE}
1228
+ />
1229
+ <p className="text-[10px] leading-relaxed text-muted-foreground">
1230
+ Use for LiteLLM or another OpenAI-compatible chat
1231
+ gateway. Leave blank for OpenAI.
1232
+ </p>
1233
+ {baseUrlConfigured && (
1234
+ <label className="flex items-center gap-1.5 text-[10px] text-muted-foreground">
1235
+ <input
1236
+ type="checkbox"
1237
+ checked={clearBaseUrl}
1238
+ onChange={(e) => {
1239
+ setClearBaseUrl(e.target.checked);
1240
+ if (e.target.checked) setBaseUrl("");
1241
+ }}
1242
+ className="h-3 w-3 accent-current"
1243
+ />
1244
+ Clear saved endpoint override
1245
+ </label>
1246
+ )}
1247
+ {envVar && envConfigured && endpointChanged && (
1248
+ <button
1249
+ type="button"
1250
+ onClick={handleSave}
1251
+ disabled={saving}
1252
+ className="rounded bg-accent px-2.5 py-1 text-[10px] font-medium text-foreground hover:bg-accent/80 disabled:opacity-40"
1253
+ >
1254
+ {saving ? (
1255
+ <IconLoader2 size={10} className="animate-spin" />
1256
+ ) : saved ? (
1257
+ <IconCheck size={10} />
1258
+ ) : (
1259
+ "Save endpoint"
1260
+ )}
1261
+ </button>
1262
+ )}
1263
+ </div>
1264
+ )}
1265
+ </div>
1266
+ )}
1267
+
1268
+ {envVar && envConfigured ? (
1269
+ <div
1270
+ className={cn(
1271
+ "flex items-center gap-1.5 text-green-500",
1272
+ isPage ? "text-xs" : "text-[10px]",
1273
+ )}
1274
+ >
1275
+ <IconCheck size={isPage ? 14 : 10} />
1276
+ {envVar} configured
1277
+ </div>
1278
+ ) : envVar ? (
1279
+ <div className="flex gap-1.5">
1280
+ <input
1281
+ type="password"
1282
+ value={apiKey}
1283
+ onChange={(e) => setApiKey(e.target.value)}
1284
+ onKeyDown={(e) => {
1285
+ if (e.key === "Enter") handleSave();
1286
+ }}
1287
+ placeholder={PROVIDER_ENV_PLACEHOLDERS[envVar] ?? "..."}
1288
+ className={cn(textInputClass(isPage), "flex-1")}
1289
+ style={isPage ? CONTROL_STYLE_PAGE : undefined}
1290
+ />
1291
+ <button
1292
+ onClick={handleSave}
1293
+ disabled={!providerSettingsChanged || saving}
1294
+ className={pillButtonClass(isPage, "solid")}
1295
+ >
1296
+ {saving ? (
1297
+ <IconLoader2
1298
+ size={isPage ? 14 : 10}
1299
+ className="animate-spin"
1300
+ />
1301
+ ) : saved ? (
1302
+ <IconCheck size={isPage ? 14 : 10} />
1303
+ ) : (
1304
+ "Save"
1305
+ )}
1306
+ </button>
1307
+ </div>
1308
+ ) : null}
1309
+
1310
+ <div className="flex items-center gap-2">
1311
+ <button
1312
+ onClick={handleTest}
1313
+ disabled={testing}
1314
+ className={pillButtonClass(isPage, "outline")}
1315
+ >
1316
+ {testing ? (
1317
+ <span className="flex items-center gap-1">
1318
+ <IconLoader2
1319
+ size={isPage ? 14 : 10}
1320
+ className="animate-spin"
1321
+ />
1322
+ Testing…
1323
+ </span>
1324
+ ) : (
1325
+ "Test"
1326
+ )}
1327
+ </button>
1328
+ {engineChanged && (
1329
+ <button
1330
+ onClick={handleApply}
1331
+ className={pillButtonClass(isPage, "solid")}
1332
+ >
1333
+ Apply
1334
+ </button>
1335
+ )}
1336
+ {settingsStatus != null && (
1337
+ <Tooltip>
1338
+ <TooltipTrigger asChild>
1339
+ <button
1340
+ onClick={handleDisconnect}
1341
+ className={cn(
1342
+ pillButtonClass(isPage, "outline"),
1343
+ "ms-auto text-muted-foreground hover:bg-destructive/10 hover:text-destructive hover:border-destructive/40",
1344
+ )}
1345
+ >
1346
+ Disconnect
1347
+ </button>
1348
+ </TooltipTrigger>
1349
+ <TooltipContent>
1350
+ Clear the saved engine — the app will fall back to the
1351
+ default until you re-apply.
1352
+ </TooltipContent>
1353
+ </Tooltip>
1354
+ )}
1355
+ </div>
1356
+ {testResult && testResult.ok && (
1357
+ <p
1358
+ className={cn(
1359
+ "flex items-center gap-1 text-green-500",
1360
+ isPage ? "text-xs" : "text-[10px]",
1361
+ )}
1362
+ >
1363
+ <IconCheck size={isPage ? 14 : 10} />
1364
+ Test passed — {testResult.latencyMs}ms
1365
+ </p>
1366
+ )}
1367
+ {testResult && testResult.ok === false && (
1368
+ <p
1369
+ className={cn(
1370
+ "text-destructive",
1371
+ isPage ? "text-xs" : "text-[10px]",
1372
+ )}
1373
+ >
1374
+ Test failed: {testResult.error}
1375
+ </p>
1376
+ )}
1377
+ {disconnectError && (
1378
+ <p
1379
+ className={cn(
1380
+ "text-destructive",
1381
+ isPage ? "text-xs" : "text-[10px]",
1382
+ )}
1383
+ >
1384
+ Disconnect failed: {disconnectError}
1385
+ </p>
1386
+ )}
1387
+ {applyNote && (
1388
+ <p
1389
+ className={cn(
1390
+ "text-muted-foreground",
1391
+ isPage ? "text-xs" : "text-[10px]",
1392
+ )}
1393
+ >
1394
+ Changes take effect on next conversation
1395
+ </p>
1396
+ )}
1397
+ </div>
1398
+ </ManualSetupCard>
1399
+ )}
1400
+ </div>
1401
+ )}
1402
+ </SettingsSection>
1403
+ );
1404
+ }
1405
+
1406
+ // ─── App Default Model Section ──────────────────────────────────────────────
1407
+
1408
+ interface AppModelDefaultEngine extends EngineInfo {
1409
+ configured: boolean;
1410
+ }
1411
+
1412
+ interface AppModelDefaultsResponse {
1413
+ appId: string;
1414
+ engine: string | null;
1415
+ model: string | null;
1416
+ scope: "org" | "user" | "default";
1417
+ source: "org" | "user" | "default";
1418
+ canUpdate: boolean;
1419
+ orgId?: string | null;
1420
+ orgName?: string | null;
1421
+ role?: string | null;
1422
+ engines: AppModelDefaultEngine[];
1423
+ }
1424
+
1425
+ function friendlyAppName(appId: string): string {
1426
+ return appId
1427
+ .split("-")
1428
+ .filter(Boolean)
1429
+ .map((part) => part[0]?.toUpperCase() + part.slice(1))
1430
+ .join(" ");
1431
+ }
1432
+
1433
+ function AppModelDefaultsSectionInner({
1434
+ open,
1435
+ onToggle,
1436
+ }: {
1437
+ open?: boolean;
1438
+ onToggle?: () => void;
1439
+ }) {
1440
+ const isPage = useSettingsSurface() === "page";
1441
+ const [settings, setSettings] = useState<AppModelDefaultsResponse | null>(
1442
+ null,
1443
+ );
1444
+ const [selectedEngine, setSelectedEngine] = useState("");
1445
+ const [selectedModel, setSelectedModel] = useState("");
1446
+ const [loading, setLoading] = useState(true);
1447
+ const [saving, setSaving] = useState(false);
1448
+ const [saved, setSaved] = useState(false);
1449
+ const [error, setError] = useState<string | null>(null);
1450
+
1451
+ const load = useCallback(() => {
1452
+ let cancelled = false;
1453
+ setLoading(true);
1454
+ fetch(agentNativePath("/_agent-native/agent-model-defaults"))
1455
+ .then((r) => (r.ok ? r.json() : null))
1456
+ .then((data: AppModelDefaultsResponse | null) => {
1457
+ if (cancelled || !data) return;
1458
+ setSettings(data);
1459
+ const firstConfigured =
1460
+ data.engines.find((engine) => engine.configured) ?? data.engines[0];
1461
+ const nextEngine = data.engine ?? firstConfigured?.name ?? "";
1462
+ const nextEngineInfo =
1463
+ data.engines.find((engine) => engine.name === nextEngine) ??
1464
+ firstConfigured;
1465
+ setSelectedEngine(nextEngine);
1466
+ setSelectedModel(data.model ?? nextEngineInfo?.defaultModel ?? "");
1467
+ })
1468
+ .catch(() => {})
1469
+ .finally(() => {
1470
+ if (!cancelled) setLoading(false);
1471
+ });
1472
+ return () => {
1473
+ cancelled = true;
1474
+ };
1475
+ }, []);
1476
+
1477
+ useEffect(() => load(), [load]);
1478
+
1479
+ const selectedEngineInfo =
1480
+ settings?.engines.find((engine) => engine.name === selectedEngine) ?? null;
1481
+ const engineOptions: SettingsSelectOption[] = (settings?.engines ?? [])
1482
+ .filter(
1483
+ (engine) =>
1484
+ engine.name === selectedEngine ||
1485
+ (engine.name !== "ai-sdk:anthropic" && engine.name !== "ai-sdk:ollama"),
1486
+ )
1487
+ .map((engine) => ({
1488
+ value: engine.name,
1489
+ label:
1490
+ engine.name === "builder"
1491
+ ? "Builder.io Gateway"
1492
+ : engine.label || engine.name,
1493
+ description: engine.configured
1494
+ ? "Configured for this workspace"
1495
+ : engine.packageInstalled === false
1496
+ ? `Install ${engine.installPackage ?? "the provider packages"} to use this provider`
1497
+ : "Credentials not detected yet",
1498
+ }));
1499
+ const hasPendingChange =
1500
+ !!settings &&
1501
+ settings.canUpdate &&
1502
+ !!selectedEngine &&
1503
+ !!selectedModel.trim() &&
1504
+ (selectedEngine !== settings.engine ||
1505
+ selectedModel.trim() !== settings.model);
1506
+ const hasAppDefault = settings?.source !== "default";
1507
+ const scopeLabel =
1508
+ settings?.scope === "org"
1509
+ ? settings.orgName
1510
+ ? `${settings.orgName} organization`
1511
+ : "organization"
1512
+ : "your account";
1513
+
1514
+ const notifyChanged = () => {
1515
+ window.dispatchEvent(new CustomEvent("agent-engine:configured-changed"));
1516
+ };
1517
+
1518
+ const save = async () => {
1519
+ if (!hasPendingChange) return;
1520
+ setSaving(true);
1521
+ setSaved(false);
1522
+ setError(null);
1523
+ try {
1524
+ const res = await fetch(
1525
+ agentNativePath("/_agent-native/agent-model-defaults"),
1526
+ {
1527
+ method: "PUT",
1528
+ headers: { "Content-Type": "application/json" },
1529
+ body: JSON.stringify({
1530
+ engine: selectedEngine,
1531
+ model: selectedModel.trim(),
1532
+ }),
1533
+ },
1534
+ );
1535
+ const body = await res.json().catch(() => ({}));
1536
+ if (!res.ok)
1537
+ throw new Error(body?.error ?? `Save failed (${res.status})`);
1538
+ const next = body as AppModelDefaultsResponse;
1539
+ setSettings(next);
1540
+ setSelectedEngine(next.engine ?? selectedEngine);
1541
+ setSelectedModel(next.model ?? selectedModel.trim());
1542
+ setSaved(true);
1543
+ notifyChanged();
1544
+ setTimeout(() => setSaved(false), 2000);
1545
+ } catch (err) {
1546
+ setError(err instanceof Error ? err.message : "Save failed");
1547
+ } finally {
1548
+ setSaving(false);
1549
+ }
1550
+ };
1551
+
1552
+ const reset = async () => {
1553
+ if (!settings?.canUpdate || !hasAppDefault) return;
1554
+ setSaving(true);
1555
+ setSaved(false);
1556
+ setError(null);
1557
+ try {
1558
+ const res = await fetch(
1559
+ agentNativePath("/_agent-native/agent-model-defaults"),
1560
+ { method: "DELETE" },
1561
+ );
1562
+ const body = await res.json().catch(() => ({}));
1563
+ if (!res.ok)
1564
+ throw new Error(body?.error ?? `Reset failed (${res.status})`);
1565
+ const next = body as AppModelDefaultsResponse;
1566
+ setSettings(next);
1567
+ const fallback = next.engines.find((engine) => engine.configured);
1568
+ setSelectedEngine(next.engine ?? fallback?.name ?? selectedEngine);
1569
+ setSelectedModel(next.model ?? fallback?.defaultModel ?? selectedModel);
1570
+ notifyChanged();
1571
+ } catch (err) {
1572
+ setError(err instanceof Error ? err.message : "Reset failed");
1573
+ } finally {
1574
+ setSaving(false);
1575
+ }
1576
+ };
1577
+
1578
+ return (
1579
+ <SettingsSection
1580
+ id={settingsSectionDomId("app-models")}
1581
+ icon={<IconApps size={14} />}
1582
+ title="App Default Model"
1583
+ subtitle="Choose the default model for this app/template when no one-off composer model is selected."
1584
+ connected={loading ? undefined : hasAppDefault}
1585
+ open={open}
1586
+ onToggle={onToggle}
1587
+ >
1588
+ {loading ? (
1589
+ <SettingsSkeleton lines={2} />
1590
+ ) : settings ? (
1591
+ <div className="space-y-2">
1592
+ <div
1593
+ className={cn(
1594
+ "rounded-md border border-border bg-accent/20",
1595
+ isPage ? "px-3.5 py-3" : "px-2.5 py-2",
1596
+ )}
1597
+ >
1598
+ <div className="mb-2 flex items-center justify-between gap-2">
1599
+ <div className="min-w-0">
1600
+ <p
1601
+ className={cn(
1602
+ "truncate font-medium text-foreground",
1603
+ subTextClass(isPage),
1604
+ )}
1605
+ >
1606
+ {friendlyAppName(settings.appId) || "This app"}
1607
+ </p>
1608
+ <p
1609
+ className={cn(
1610
+ "mt-0.5 text-muted-foreground",
1611
+ noteTextClass(isPage),
1612
+ )}
1613
+ >
1614
+ {hasAppDefault
1615
+ ? `Applies to ${scopeLabel}.`
1616
+ : "Using the global LLM default."}
1617
+ </p>
1618
+ </div>
1619
+ <span
1620
+ className={cn(
1621
+ "shrink-0 rounded-full bg-background px-2 py-0.5 font-medium text-muted-foreground",
1622
+ noteTextClass(isPage),
1623
+ )}
1624
+ >
1625
+ {settings.source}
1626
+ </span>
1627
+ </div>
1628
+
1629
+ <div className="space-y-2">
1630
+ <SettingsSelect
1631
+ label="Provider"
1632
+ value={selectedEngine}
1633
+ options={engineOptions}
1634
+ onValueChange={(value) => {
1635
+ setSelectedEngine(value);
1636
+ const info = settings.engines.find(
1637
+ (engine) => engine.name === value,
1638
+ );
1639
+ setSelectedModel(info?.defaultModel ?? "");
1640
+ setError(null);
1641
+ }}
1642
+ />
1643
+
1644
+ <AppDefaultModelField
1645
+ engine={selectedEngine}
1646
+ models={selectedEngineInfo?.supportedModels ?? []}
1647
+ value={selectedModel}
1648
+ defaultModel={selectedEngineInfo?.defaultModel}
1649
+ disabled={!settings.canUpdate || saving}
1650
+ onValueChange={(value) => {
1651
+ setSelectedModel(value);
1652
+ setError(null);
1653
+ }}
1654
+ onEnter={() => {
1655
+ if (hasPendingChange) void save();
1656
+ }}
1657
+ />
1658
+
1659
+ <div className="flex items-center gap-1.5">
1660
+ <button
1661
+ type="button"
1662
+ onClick={save}
1663
+ disabled={!hasPendingChange || saving}
1664
+ className={pillButtonClass(isPage, "solid")}
1665
+ >
1666
+ {saving ? (
1667
+ <IconLoader2
1668
+ size={isPage ? 14 : 10}
1669
+ className="animate-spin"
1670
+ />
1671
+ ) : saved ? (
1672
+ <IconCheck size={isPage ? 14 : 10} />
1673
+ ) : (
1674
+ "Save"
1675
+ )}
1676
+ </button>
1677
+ <button
1678
+ type="button"
1679
+ onClick={reset}
1680
+ disabled={!settings.canUpdate || !hasAppDefault || saving}
1681
+ className={pillButtonClass(isPage, "outline")}
1682
+ >
1683
+ Reset
1684
+ </button>
1685
+ </div>
1686
+ </div>
1687
+
1688
+ {!settings.canUpdate && (
1689
+ <p
1690
+ className={cn(
1691
+ "mt-2 text-muted-foreground",
1692
+ noteTextClass(isPage),
1693
+ )}
1694
+ >
1695
+ Only organization owners and admins can change app model
1696
+ defaults.
1697
+ </p>
1698
+ )}
1699
+ {selectedEngineInfo?.packageInstalled === false ? (
1700
+ <p
1701
+ className={cn(
1702
+ "mt-2 text-muted-foreground",
1703
+ noteTextClass(isPage),
1704
+ )}
1705
+ >
1706
+ This app does not include the optional runtime packages for this
1707
+ provider.
1708
+ </p>
1709
+ ) : selectedEngineInfo && !selectedEngineInfo.configured ? (
1710
+ <p
1711
+ className={cn(
1712
+ "mt-2 text-muted-foreground",
1713
+ noteTextClass(isPage),
1714
+ )}
1715
+ >
1716
+ Credentials for this provider were not detected; runtime will
1717
+ fall back if the model cannot be used.
1718
+ </p>
1719
+ ) : null}
1720
+ {error && (
1721
+ <p className={cn("mt-2 text-destructive", noteTextClass(isPage))}>
1722
+ {error}
1723
+ </p>
1724
+ )}
1725
+ </div>
1726
+ </div>
1727
+ ) : (
1728
+ <p className={cn("text-muted-foreground", noteTextClass(isPage))}>
1729
+ App model defaults are unavailable.
1730
+ </p>
1731
+ )}
1732
+ </SettingsSection>
1733
+ );
1734
+ }
1735
+
1736
+ // ─── Email Section ──────────────────────────────────────────────────────────
1737
+
1738
+ function EmailSectionInner({
1739
+ open,
1740
+ onToggle,
1741
+ }: {
1742
+ open?: boolean;
1743
+ onToggle?: () => void;
1744
+ }) {
1745
+ const isPage = useSettingsSurface() === "page";
1746
+ const emailInputCls = cn(textInputClass(isPage), "flex-1");
1747
+ const emailBtnCls = pillButtonClass(isPage, "solid");
1748
+ const emailIconSize = isPage ? 14 : 10;
1749
+ const [envKeys, setEnvKeys] = useState<
1750
+ Array<{ key: string; configured: boolean }>
1751
+ >([]);
1752
+ const [resendKey, setResendKey] = useState("");
1753
+ const [sendgridKey, setSendgridKey] = useState("");
1754
+ const [fromAddr, setFromAddr] = useState("");
1755
+ const [saving, setSaving] = useState(false);
1756
+ const [saved, setSaved] = useState(false);
1757
+ const [emailProvider, setEmailProvider] = useState<"resend" | "sendgrid">(
1758
+ "resend",
1759
+ );
1760
+ const [envLoaded, setEnvLoaded] = useState(false);
1761
+
1762
+ useEffect(() => {
1763
+ fetch(agentNativePath("/_agent-native/env-status"))
1764
+ .then((r) => (r.ok ? r.json() : []))
1765
+ .then(setEnvKeys)
1766
+ .catch(() => {})
1767
+ .finally(() => setEnvLoaded(true));
1768
+ }, [saved]);
1769
+
1770
+ const resendConfigured =
1771
+ envKeys.find((k) => k.key === "RESEND_API_KEY")?.configured ?? false;
1772
+ const sendgridConfigured =
1773
+ envKeys.find((k) => k.key === "SENDGRID_API_KEY")?.configured ?? false;
1774
+ const fromConfigured =
1775
+ envKeys.find((k) => k.key === "EMAIL_FROM")?.configured ?? false;
1776
+ const anyConfigured = resendConfigured || sendgridConfigured;
1777
+
1778
+ useEffect(() => {
1779
+ if (sendgridConfigured && !resendConfigured) {
1780
+ setEmailProvider("sendgrid");
1781
+ }
1782
+ }, [resendConfigured, sendgridConfigured]);
1783
+
1784
+ const save = async (vars: Array<{ key: string; value: string }>) => {
1785
+ setSaving(true);
1786
+ try {
1787
+ const res = await fetch(agentNativePath("/_agent-native/env-vars"), {
1788
+ method: "POST",
1789
+ headers: { "Content-Type": "application/json" },
1790
+ body: JSON.stringify({ vars }),
1791
+ });
1792
+ if (res.ok) {
1793
+ setSaved(true);
1794
+ setResendKey("");
1795
+ setSendgridKey("");
1796
+ setFromAddr("");
1797
+ setTimeout(() => setSaved(false), 2000);
1798
+ }
1799
+ } finally {
1800
+ setSaving(false);
1801
+ }
1802
+ };
1803
+
1804
+ const saveResend = () => {
1805
+ const vars: Array<{ key: string; value: string }> = [];
1806
+ if (resendKey.trim())
1807
+ vars.push({ key: "RESEND_API_KEY", value: resendKey.trim() });
1808
+ if (fromAddr.trim())
1809
+ vars.push({ key: "EMAIL_FROM", value: fromAddr.trim() });
1810
+ if (vars.length) save(vars);
1811
+ };
1812
+
1813
+ const saveSendgrid = () => {
1814
+ const vars: Array<{ key: string; value: string }> = [];
1815
+ if (sendgridKey.trim())
1816
+ vars.push({ key: "SENDGRID_API_KEY", value: sendgridKey.trim() });
1817
+ if (fromAddr.trim())
1818
+ vars.push({ key: "EMAIL_FROM", value: fromAddr.trim() });
1819
+ if (vars.length) save(vars);
1820
+ };
1821
+
1822
+ return (
1823
+ <SettingsSection
1824
+ id={settingsSectionDomId("email")}
1825
+ icon={<IconMail size={14} />}
1826
+ title="Email"
1827
+ subtitle="Needed before deploy for password resets, team invitations, share notifications, and dashboard email reports. Local development can run without it."
1828
+ connected={!envLoaded ? undefined : anyConfigured}
1829
+ open={open}
1830
+ onToggle={onToggle}
1831
+ >
1832
+ {!envLoaded ? (
1833
+ <SettingsSkeleton lines={2} />
1834
+ ) : (
1835
+ <div className="space-y-2">
1836
+ <label className="block space-y-1">
1837
+ <span
1838
+ className={cn(
1839
+ "uppercase tracking-wide text-muted-foreground",
1840
+ noteTextClass(isPage),
1841
+ )}
1842
+ >
1843
+ Provider
1844
+ </span>
1845
+ <select
1846
+ value={emailProvider}
1847
+ onChange={(e) =>
1848
+ setEmailProvider(e.target.value as "resend" | "sendgrid")
1849
+ }
1850
+ className={cn(textInputClass(isPage), "w-full")}
1851
+ style={isPage ? CONTROL_STYLE_PAGE : undefined}
1852
+ >
1853
+ <option value="resend">Resend</option>
1854
+ <option value="sendgrid">SendGrid</option>
1855
+ </select>
1856
+ </label>
1857
+
1858
+ {emailProvider === "resend" ? (
1859
+ <ManualSetupCard
1860
+ hint="Use Resend for transactional email."
1861
+ docsUrl="https://resend.com/api-keys"
1862
+ docsLabel="Get a Resend key"
1863
+ >
1864
+ {resendConfigured ? (
1865
+ <div
1866
+ className={cn(
1867
+ "mb-1 flex items-center gap-1.5 text-green-500",
1868
+ noteTextClass(isPage),
1869
+ )}
1870
+ >
1871
+ <IconCheck size={emailIconSize} />
1872
+ RESEND_API_KEY configured
1873
+ </div>
1874
+ ) : (
1875
+ <div className="mb-1 flex gap-1.5">
1876
+ <input
1877
+ type="password"
1878
+ value={resendKey}
1879
+ onChange={(e) => setResendKey(e.target.value)}
1880
+ onKeyDown={(e) => {
1881
+ if (e.key === "Enter") saveResend();
1882
+ }}
1883
+ placeholder="re_..."
1884
+ className={emailInputCls}
1885
+ />
1886
+ <button
1887
+ onClick={saveResend}
1888
+ disabled={!resendKey.trim() || saving}
1889
+ className={emailBtnCls}
1890
+ >
1891
+ {saving ? (
1892
+ <IconLoader2 size={10} className="animate-spin" />
1893
+ ) : saved ? (
1894
+ <IconCheck size={10} />
1895
+ ) : (
1896
+ "Save"
1897
+ )}
1898
+ </button>
1899
+ </div>
1900
+ )}
1901
+ {fromConfigured ? (
1902
+ <div
1903
+ className={cn(
1904
+ "flex items-center gap-1.5 text-green-500",
1905
+ noteTextClass(isPage),
1906
+ )}
1907
+ >
1908
+ <IconCheck size={emailIconSize} />
1909
+ EMAIL_FROM configured
1910
+ </div>
1911
+ ) : (
1912
+ <div className="flex gap-1.5">
1913
+ <input
1914
+ type="text"
1915
+ value={fromAddr}
1916
+ onChange={(e) => setFromAddr(e.target.value)}
1917
+ onKeyDown={(e) => {
1918
+ if (e.key === "Enter") saveResend();
1919
+ }}
1920
+ placeholder="From address - e.g. Acme <hi@acme.com>"
1921
+ className={emailInputCls}
1922
+ />
1923
+ {!resendConfigured ? null : (
1924
+ <button
1925
+ onClick={saveResend}
1926
+ disabled={!fromAddr.trim() || saving}
1927
+ className={emailBtnCls}
1928
+ >
1929
+ {saving ? (
1930
+ <IconLoader2 size={10} className="animate-spin" />
1931
+ ) : saved ? (
1932
+ <IconCheck size={10} />
1933
+ ) : (
1934
+ "Save"
1935
+ )}
1936
+ </button>
1937
+ )}
1938
+ </div>
1939
+ )}
1940
+ </ManualSetupCard>
1941
+ ) : (
1942
+ <ManualSetupCard
1943
+ hint="Use SendGrid for transactional email. SendGrid requires a verified from address."
1944
+ docsUrl="https://app.sendgrid.com/settings/api_keys"
1945
+ docsLabel="Get a SendGrid key"
1946
+ >
1947
+ {sendgridConfigured ? (
1948
+ <div
1949
+ className={cn(
1950
+ "mb-1 flex items-center gap-1.5 text-green-500",
1951
+ noteTextClass(isPage),
1952
+ )}
1953
+ >
1954
+ <IconCheck size={emailIconSize} />
1955
+ SENDGRID_API_KEY configured
1956
+ </div>
1957
+ ) : (
1958
+ <div className="mb-1 flex gap-1.5">
1959
+ <input
1960
+ type="password"
1961
+ value={sendgridKey}
1962
+ onChange={(e) => setSendgridKey(e.target.value)}
1963
+ onKeyDown={(e) => {
1964
+ if (e.key === "Enter") saveSendgrid();
1965
+ }}
1966
+ placeholder="SG...."
1967
+ className={emailInputCls}
1968
+ />
1969
+ <button
1970
+ onClick={saveSendgrid}
1971
+ disabled={!sendgridKey.trim() || saving}
1972
+ className={emailBtnCls}
1973
+ >
1974
+ {saving ? (
1975
+ <IconLoader2 size={10} className="animate-spin" />
1976
+ ) : saved ? (
1977
+ <IconCheck size={10} />
1978
+ ) : (
1979
+ "Save"
1980
+ )}
1981
+ </button>
1982
+ </div>
1983
+ )}
1984
+ {fromConfigured ? (
1985
+ <div
1986
+ className={cn(
1987
+ "flex items-center gap-1.5 text-green-500",
1988
+ noteTextClass(isPage),
1989
+ )}
1990
+ >
1991
+ <IconCheck size={emailIconSize} />
1992
+ EMAIL_FROM configured
1993
+ </div>
1994
+ ) : (
1995
+ <div className="flex gap-1.5">
1996
+ <input
1997
+ type="text"
1998
+ value={fromAddr}
1999
+ onChange={(e) => setFromAddr(e.target.value)}
2000
+ onKeyDown={(e) => {
2001
+ if (e.key === "Enter") saveSendgrid();
2002
+ }}
2003
+ placeholder="From address - e.g. Acme <hi@acme.com>"
2004
+ className={emailInputCls}
2005
+ />
2006
+ {!sendgridConfigured ? null : (
2007
+ <button
2008
+ onClick={saveSendgrid}
2009
+ disabled={!fromAddr.trim() || saving}
2010
+ className={emailBtnCls}
2011
+ >
2012
+ {saving ? (
2013
+ <IconLoader2 size={10} className="animate-spin" />
2014
+ ) : saved ? (
2015
+ <IconCheck size={10} />
2016
+ ) : (
2017
+ "Save"
2018
+ )}
2019
+ </button>
2020
+ )}
2021
+ </div>
2022
+ )}
2023
+ </ManualSetupCard>
2024
+ )}
2025
+ </div>
2026
+ )}
2027
+ </SettingsSection>
2028
+ );
2029
+ }
2030
+
2031
+ // ─── Agent Limits Section ──────────────────────────────────────────────────
2032
+
2033
+ interface AgentLoopSettingsResponse {
2034
+ maxIterations: number;
2035
+ defaultMaxIterations: number;
2036
+ minMaxIterations: number;
2037
+ maxMaxIterations: number;
2038
+ scope: "org" | "user" | "default";
2039
+ source: "org" | "user" | "env" | "default";
2040
+ canUpdate: boolean;
2041
+ orgName?: string | null;
2042
+ role?: string | null;
2043
+ }
2044
+
2045
+ function AgentLimitsSectionInner({
2046
+ open,
2047
+ onToggle,
2048
+ }: {
2049
+ open?: boolean;
2050
+ onToggle?: () => void;
2051
+ }) {
2052
+ const isPage = useSettingsSurface() === "page";
2053
+ const [settings, setSettings] = useState<AgentLoopSettingsResponse | null>(
2054
+ null,
2055
+ );
2056
+ const [value, setValue] = useState("");
2057
+ const [loading, setLoading] = useState(true);
2058
+ const [saving, setSaving] = useState(false);
2059
+ const [saved, setSaved] = useState(false);
2060
+ const [error, setError] = useState<string | null>(null);
2061
+
2062
+ const load = useCallback(() => {
2063
+ let cancelled = false;
2064
+ setLoading(true);
2065
+ fetch(agentNativePath("/_agent-native/agent-loop-settings"))
2066
+ .then((r) => (r.ok ? r.json() : null))
2067
+ .then((data: AgentLoopSettingsResponse | null) => {
2068
+ if (cancelled || !data) return;
2069
+ setSettings(data);
2070
+ setValue(String(data.maxIterations));
2071
+ })
2072
+ .catch(() => {})
2073
+ .finally(() => {
2074
+ if (!cancelled) setLoading(false);
2075
+ });
2076
+ return () => {
2077
+ cancelled = true;
2078
+ };
2079
+ }, []);
2080
+
2081
+ useEffect(() => load(), [load]);
2082
+
2083
+ useEffect(() => {
2084
+ const handler = (event: Event) => {
2085
+ const detail = (event as CustomEvent).detail as
2086
+ | AgentLoopSettingsResponse
2087
+ | undefined;
2088
+ if (!detail?.maxIterations) return;
2089
+ setSettings(detail);
2090
+ setValue(String(detail.maxIterations));
2091
+ };
2092
+ window.addEventListener("agent-loop-settings:changed", handler);
2093
+ return () =>
2094
+ window.removeEventListener("agent-loop-settings:changed", handler);
2095
+ }, []);
2096
+
2097
+ const numericValue = Number(value);
2098
+ const hasPendingChange =
2099
+ !!settings &&
2100
+ settings.canUpdate &&
2101
+ Number.isInteger(numericValue) &&
2102
+ numericValue !== settings.maxIterations;
2103
+ const scopeLabel =
2104
+ settings?.scope === "org"
2105
+ ? settings.orgName
2106
+ ? `${settings.orgName} organization`
2107
+ : "organization"
2108
+ : "your account";
2109
+
2110
+ const save = async () => {
2111
+ if (!settings?.canUpdate) return;
2112
+ setSaving(true);
2113
+ setSaved(false);
2114
+ setError(null);
2115
+ try {
2116
+ const res = await fetch(
2117
+ agentNativePath("/_agent-native/agent-loop-settings"),
2118
+ {
2119
+ method: "PUT",
2120
+ headers: { "Content-Type": "application/json" },
2121
+ body: JSON.stringify({ maxIterations: numericValue }),
2122
+ },
2123
+ );
2124
+ const body = await res.json().catch(() => ({}));
2125
+ if (!res.ok) {
2126
+ throw new Error(body?.error ?? `Save failed (${res.status})`);
2127
+ }
2128
+ setSettings(body as AgentLoopSettingsResponse);
2129
+ setValue(String((body as AgentLoopSettingsResponse).maxIterations));
2130
+ setSaved(true);
2131
+ window.dispatchEvent(
2132
+ new CustomEvent("agent-loop-settings:changed", { detail: body }),
2133
+ );
2134
+ setTimeout(() => setSaved(false), 2000);
2135
+ } catch (err) {
2136
+ setError(err instanceof Error ? err.message : "Save failed");
2137
+ } finally {
2138
+ setSaving(false);
2139
+ }
2140
+ };
2141
+
2142
+ const reset = async () => {
2143
+ if (!settings?.canUpdate) return;
2144
+ setSaving(true);
2145
+ setSaved(false);
2146
+ setError(null);
2147
+ try {
2148
+ const res = await fetch(
2149
+ agentNativePath("/_agent-native/agent-loop-settings"),
2150
+ { method: "DELETE" },
2151
+ );
2152
+ const body = await res.json().catch(() => ({}));
2153
+ if (!res.ok) {
2154
+ throw new Error(body?.error ?? `Reset failed (${res.status})`);
2155
+ }
2156
+ setSettings(body as AgentLoopSettingsResponse);
2157
+ setValue(String((body as AgentLoopSettingsResponse).maxIterations));
2158
+ window.dispatchEvent(
2159
+ new CustomEvent("agent-loop-settings:changed", { detail: body }),
2160
+ );
2161
+ } catch (err) {
2162
+ setError(err instanceof Error ? err.message : "Reset failed");
2163
+ } finally {
2164
+ setSaving(false);
2165
+ }
2166
+ };
2167
+
2168
+ return (
2169
+ <SettingsSection
2170
+ id={settingsSectionDomId("limits")}
2171
+ icon={<IconGauge size={14} />}
2172
+ title="Agent Limits"
2173
+ subtitle="Control how long a single agent response can work before pausing."
2174
+ connected={
2175
+ loading
2176
+ ? undefined
2177
+ : settings
2178
+ ? settings.maxIterations !== settings.defaultMaxIterations
2179
+ : false
2180
+ }
2181
+ open={open}
2182
+ onToggle={onToggle}
2183
+ >
2184
+ {loading ? (
2185
+ <SettingsSkeleton lines={2} />
2186
+ ) : settings ? (
2187
+ <div className="space-y-2">
2188
+ <div
2189
+ className={cn(
2190
+ "rounded-md border border-border bg-accent/20",
2191
+ isPage ? "px-3.5 py-3" : "px-2.5 py-2",
2192
+ )}
2193
+ >
2194
+ <div className="flex items-center justify-between gap-2">
2195
+ <div>
2196
+ <p
2197
+ className={cn(
2198
+ "font-medium text-foreground",
2199
+ subTextClass(isPage),
2200
+ )}
2201
+ >
2202
+ Max iterations
2203
+ </p>
2204
+ <p
2205
+ className={cn(
2206
+ "mt-0.5 text-muted-foreground",
2207
+ noteTextClass(isPage),
2208
+ )}
2209
+ >
2210
+ Applies to {scopeLabel}. Default is{" "}
2211
+ {settings.defaultMaxIterations.toLocaleString()}.
2212
+ </p>
2213
+ </div>
2214
+ <span
2215
+ className={cn(
2216
+ "rounded-full bg-background px-2 py-0.5 font-medium text-muted-foreground",
2217
+ noteTextClass(isPage),
2218
+ )}
2219
+ >
2220
+ {settings.source}
2221
+ </span>
2222
+ </div>
2223
+ <div className="mt-2 flex items-center gap-1.5">
2224
+ <input
2225
+ type="number"
2226
+ min={settings.minMaxIterations}
2227
+ max={settings.maxMaxIterations}
2228
+ value={value}
2229
+ disabled={!settings.canUpdate || saving}
2230
+ onChange={(e) => {
2231
+ setValue(e.target.value);
2232
+ setError(null);
2233
+ }}
2234
+ onKeyDown={(e) => {
2235
+ if (e.key === "Enter" && hasPendingChange) void save();
2236
+ }}
2237
+ className={cn(
2238
+ textInputClass(isPage),
2239
+ "min-w-0 flex-1 disabled:opacity-60",
2240
+ )}
2241
+ style={isPage ? CONTROL_STYLE_PAGE : undefined}
2242
+ />
2243
+ <button
2244
+ type="button"
2245
+ onClick={save}
2246
+ disabled={!hasPendingChange || saving}
2247
+ className={pillButtonClass(isPage, "solid")}
2248
+ >
2249
+ {saving ? (
2250
+ <IconLoader2
2251
+ size={isPage ? 14 : 10}
2252
+ className="animate-spin"
2253
+ />
2254
+ ) : saved ? (
2255
+ <IconCheck size={isPage ? 14 : 10} />
2256
+ ) : (
2257
+ "Save"
2258
+ )}
2259
+ </button>
2260
+ <button
2261
+ type="button"
2262
+ onClick={reset}
2263
+ disabled={
2264
+ !settings.canUpdate ||
2265
+ saving ||
2266
+ settings.maxIterations === settings.defaultMaxIterations
2267
+ }
2268
+ className={pillButtonClass(isPage, "outline")}
2269
+ >
2270
+ Reset
2271
+ </button>
2272
+ </div>
2273
+ {!settings.canUpdate && (
2274
+ <p
2275
+ className={cn(
2276
+ "mt-2 text-muted-foreground",
2277
+ noteTextClass(isPage),
2278
+ )}
2279
+ >
2280
+ Only organization owners and admins can change this limit.
2281
+ </p>
2282
+ )}
2283
+ {error && (
2284
+ <p className={cn("mt-2 text-destructive", noteTextClass(isPage))}>
2285
+ {error}
2286
+ </p>
2287
+ )}
2288
+ </div>
2289
+ </div>
2290
+ ) : (
2291
+ <p className={cn("text-muted-foreground", noteTextClass(isPage))}>
2292
+ Agent limit settings are unavailable.
2293
+ </p>
2294
+ )}
2295
+ </SettingsSection>
2296
+ );
2297
+ }
2298
+
2299
+ // ─── Main SettingsPanel ─────────────────────────────────────────────────────
2300
+
2301
+ export interface SettingsPanelProps {
2302
+ isDevMode: boolean;
2303
+ onToggleDevMode: () => void;
2304
+ showDevToggle: boolean;
2305
+ devAppUrl?: string;
2306
+ initialSection?: string | null;
2307
+ sectionRequestKey?: number;
2308
+ }
2309
+
2310
+ function normalizeSettingsSection(
2311
+ value?: string | null,
2312
+ ): SettingsSectionId | null {
2313
+ const normalized = value?.replace(/^#/, "").toLowerCase() ?? "";
2314
+ if (!normalized) return null;
2315
+ if (normalized.startsWith("secrets")) return "secrets";
2316
+ if (
2317
+ normalized === "workspace" ||
2318
+ normalized === "workspace-settings" ||
2319
+ normalized === "organization" ||
2320
+ normalized === "org"
2321
+ ) {
2322
+ return "secrets";
2323
+ }
2324
+ if (normalized === "agent-engine") return "llm";
2325
+ if (
2326
+ normalized === "agent-model-defaults" ||
2327
+ normalized === "app-model-defaults" ||
2328
+ normalized === "models"
2329
+ ) {
2330
+ return "app-models";
2331
+ }
2332
+ if (normalized === "agent-limits" || normalized === "loop-settings") {
2333
+ return "limits";
2334
+ }
2335
+ return SETTINGS_SECTION_IDS.has(normalized as SettingsSectionId)
2336
+ ? (normalized as SettingsSectionId)
2337
+ : null;
2338
+ }
2339
+
2340
+ function settingsSectionDomId(section: SettingsSectionId): string {
2341
+ return `agent-settings-section-${section}`;
2342
+ }
2343
+
2344
+ function initialOpenSection(): SettingsSectionId {
2345
+ if (typeof window === "undefined") return "llm";
2346
+ return normalizeSettingsSection(window.location.hash) ?? "llm";
2347
+ }
2348
+
2349
+ function firstVisibleSection(
2350
+ sections: readonly SettingsSectionId[],
2351
+ ): SettingsSectionId {
2352
+ return sections[0] ?? "llm";
2353
+ }
2354
+
2355
+ // Agent capability modes. The internal values ("production"/"development") are
2356
+ // kept for back-compat with the AGENT_MODE wiring; only the visible labels
2357
+ // changed to "App mode" / "Code mode" so this control reads as the agent
2358
+ // capability it is — not the deployment environment (NODE_ENV).
2359
+ const agentModeOptions: SettingsSelectOption[] = [
2360
+ {
2361
+ value: "production",
2362
+ label: "App mode",
2363
+ description:
2364
+ "App tools only; code, bash, and files require Builder or a local clone.",
2365
+ },
2366
+ {
2367
+ value: "development",
2368
+ label: "Code mode",
2369
+ description: "Full access to code editing, bash, and files.",
2370
+ },
2371
+ ];
2372
+
2373
+ function CapabilityStatusRow({
2374
+ label,
2375
+ value,
2376
+ active,
2377
+ }: {
2378
+ label: string;
2379
+ value: React.ReactNode;
2380
+ active: boolean;
2381
+ }) {
2382
+ return (
2383
+ <div className="flex items-center justify-between gap-2 text-[10px]">
2384
+ <span className="flex items-center gap-1.5 text-muted-foreground">
2385
+ <span
2386
+ className={`h-1.5 w-1.5 rounded-full ${active ? "bg-green-500" : "bg-muted-foreground/30"}`}
2387
+ aria-hidden="true"
2388
+ />
2389
+ {label}
2390
+ </span>
2391
+ <span className="min-w-0 truncate text-end text-foreground">{value}</span>
2392
+ </div>
2393
+ );
2394
+ }
2395
+
2396
+ function CapabilityStatusStrip({
2397
+ isDevMode,
2398
+ builderConnected,
2399
+ builderLoading,
2400
+ builderBranchesAvailable,
2401
+ onOpenLlm,
2402
+ }: {
2403
+ isDevMode: boolean;
2404
+ builderConnected: boolean;
2405
+ builderLoading: boolean;
2406
+ builderBranchesAvailable: boolean;
2407
+ onOpenLlm: () => void;
2408
+ }) {
2409
+ const codeAvailable =
2410
+ isDevMode || (builderConnected && builderBranchesAvailable);
2411
+ const codeLabel = isDevMode
2412
+ ? "Local tools"
2413
+ : builderConnected && builderBranchesAvailable
2414
+ ? "Builder branches"
2415
+ : "Desktop/local";
2416
+
2417
+ return (
2418
+ <div className="rounded-md border border-border bg-muted/20 px-2.5 py-2">
2419
+ <div className="mb-1.5 text-[10px] font-medium text-muted-foreground">
2420
+ Available now
2421
+ </div>
2422
+ <div className="space-y-1.5">
2423
+ <CapabilityStatusRow label="App" value="Chat + actions" active />
2424
+ <CapabilityStatusRow
2425
+ label="Code"
2426
+ value={codeLabel}
2427
+ active={codeAvailable}
2428
+ />
2429
+ <CapabilityStatusRow
2430
+ label="Builder"
2431
+ active={builderConnected}
2432
+ value={
2433
+ builderLoading ? (
2434
+ "Checking..."
2435
+ ) : builderConnected ? (
2436
+ "Connected"
2437
+ ) : (
2438
+ <button
2439
+ type="button"
2440
+ onClick={onOpenLlm}
2441
+ 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"
2442
+ >
2443
+ Connect
2444
+ </button>
2445
+ )
2446
+ }
2447
+ />
2448
+ </div>
2449
+ </div>
2450
+ );
2451
+ }
2452
+
2453
+ function AccountSectionInner({
2454
+ open,
2455
+ onToggle,
2456
+ }: {
2457
+ open: boolean;
2458
+ onToggle: () => void;
2459
+ }) {
2460
+ const isPage = useSettingsSurface() === "page";
2461
+ const { session, isLoading } = useSession();
2462
+ const email = session?.email;
2463
+ const avatarUrl = useAvatarUrl(email);
2464
+ const fileInputRef = useRef<HTMLInputElement>(null);
2465
+ const [uploading, setUploading] = useState(false);
2466
+ const [status, setStatus] = useState<"idle" | "saved" | "error">("idle");
2467
+
2468
+ const displayName = session?.name || email || "Signed out";
2469
+ const initials = (session?.name || email || "?")
2470
+ .split(/[ @._-]+/)
2471
+ .filter(Boolean)
2472
+ .slice(0, 2)
2473
+ .map((part) => part[0]?.toUpperCase())
2474
+ .join("");
2475
+
2476
+ const handleAvatarChange = async (
2477
+ event: React.ChangeEvent<HTMLInputElement>,
2478
+ ) => {
2479
+ const file = event.target.files?.[0];
2480
+ event.target.value = "";
2481
+ if (!file || !email) return;
2482
+ setUploading(true);
2483
+ setStatus("idle");
2484
+ try {
2485
+ await uploadAvatar(file, email);
2486
+ setStatus("saved");
2487
+ } catch {
2488
+ setStatus("error");
2489
+ } finally {
2490
+ setUploading(false);
2491
+ }
2492
+ };
2493
+
2494
+ return (
2495
+ <SettingsSection
2496
+ id={settingsSectionDomId("account")}
2497
+ icon={<IconUserCircle size={14} />}
2498
+ title="Account"
2499
+ subtitle="Your profile photo and signed-in identity."
2500
+ open={open}
2501
+ onToggle={onToggle}
2502
+ >
2503
+ <div className="flex items-center gap-3">
2504
+ <div
2505
+ className={cn(
2506
+ "flex shrink-0 items-center justify-center overflow-hidden rounded-full border border-border bg-accent font-semibold text-muted-foreground",
2507
+ isPage ? "h-14 w-14 text-[15px]" : "h-12 w-12 text-[13px]",
2508
+ )}
2509
+ >
2510
+ {avatarUrl ? (
2511
+ <img
2512
+ src={avatarUrl}
2513
+ alt=""
2514
+ className="h-full w-full object-cover"
2515
+ />
2516
+ ) : (
2517
+ initials
2518
+ )}
2519
+ </div>
2520
+ <div className="min-w-0 flex-1">
2521
+ <p
2522
+ className={cn(
2523
+ "truncate font-medium text-foreground",
2524
+ isPage ? "text-sm" : "text-[12px]",
2525
+ )}
2526
+ >
2527
+ {isLoading ? "Loading..." : displayName}
2528
+ </p>
2529
+ {email && (
2530
+ <p
2531
+ className={cn(
2532
+ "truncate text-muted-foreground",
2533
+ subTextClass(isPage),
2534
+ )}
2535
+ >
2536
+ {email}
2537
+ </p>
2538
+ )}
2539
+ {status === "saved" && (
2540
+ <p
2541
+ className={cn(
2542
+ "mt-1 text-green-600 dark:text-green-400",
2543
+ subTextClass(isPage),
2544
+ )}
2545
+ >
2546
+ Photo updated
2547
+ </p>
2548
+ )}
2549
+ {status === "error" && (
2550
+ <p className={cn("mt-1 text-destructive", subTextClass(isPage))}>
2551
+ Could not update photo
2552
+ </p>
2553
+ )}
2554
+ </div>
2555
+ <input
2556
+ ref={fileInputRef}
2557
+ type="file"
2558
+ accept="image/*"
2559
+ className="hidden"
2560
+ onChange={handleAvatarChange}
2561
+ />
2562
+ <button
2563
+ type="button"
2564
+ disabled={!email || uploading}
2565
+ onClick={() => fileInputRef.current?.click()}
2566
+ className={cn(
2567
+ pillButtonClass(isPage, "outline"),
2568
+ "shrink-0 justify-center",
2569
+ )}
2570
+ >
2571
+ {uploading ? "Uploading..." : "Change photo"}
2572
+ </button>
2573
+ </div>
2574
+ </SettingsSection>
2575
+ );
2576
+ }
2577
+
2578
+ interface SettingsPanelContentProps extends SettingsPanelProps {
2579
+ sections?: readonly SettingsSectionId[];
2580
+ showCapabilityStrip?: boolean;
2581
+ className?: string;
2582
+ surface?: SettingsSurface;
2583
+ builderConnectionOwnedExternally?: boolean;
2584
+ }
2585
+
2586
+ function SettingsPanelContent({
2587
+ isDevMode,
2588
+ onToggleDevMode,
2589
+ showDevToggle,
2590
+ devAppUrl,
2591
+ initialSection,
2592
+ sectionRequestKey,
2593
+ sections = ALL_SETTINGS_SECTIONS,
2594
+ showCapabilityStrip = true,
2595
+ className,
2596
+ surface = "sidebar",
2597
+ builderConnectionOwnedExternally = false,
2598
+ }: SettingsPanelContentProps) {
2599
+ const { status: builder, loading: builderLoading } = useBuilderStatus({
2600
+ enabled: !builderConnectionOwnedExternally,
2601
+ });
2602
+ const connected = builder?.configured ?? false;
2603
+ const connectUrl = builder?.cliAuthUrl ?? builder?.connectUrl;
2604
+ const orgName = builder?.orgName;
2605
+ const envManaged = !!builder?.envManaged;
2606
+ const credentialSource = builder?.credentialSource;
2607
+ const builderBranchesAvailable = !!builder?.builderEnabled;
2608
+ const builderFlow = useBuilderConnectFlow({
2609
+ enabled: !builderConnectionOwnedExternally,
2610
+ popupUrl: connectUrl,
2611
+ trackingSource: "settings_panel_builder_card",
2612
+ });
2613
+
2614
+ // When opened via a `#secrets:<KEY>` hash, focus that specific secret input
2615
+ // inside the "API Keys & Connections" section.
2616
+ const [focusSecretKey, setFocusSecretKey] = useState<string | undefined>(
2617
+ undefined,
2618
+ );
2619
+ const visibleSections = useMemo(() => new Set(sections), [sections]);
2620
+ const shouldShowSection = useCallback(
2621
+ (section: SettingsSectionId) => visibleSections.has(section),
2622
+ [visibleSections],
2623
+ );
2624
+
2625
+ // Accordion: only one section open at a time (null = all closed)
2626
+ const [openSection, setOpenSection] = useState<string | null>(() => {
2627
+ const initial = initialOpenSection();
2628
+ return visibleSections.has(initial)
2629
+ ? initial
2630
+ : firstVisibleSection(sections);
2631
+ });
2632
+ const toggle = (id: string) =>
2633
+ setOpenSection((prev) => (prev === id ? null : id));
2634
+
2635
+ const scrollSectionIntoView = useCallback((section: SettingsSectionId) => {
2636
+ window.requestAnimationFrame(() => {
2637
+ document.getElementById(settingsSectionDomId(section))?.scrollIntoView({
2638
+ block: "start",
2639
+ behavior: "smooth",
2640
+ });
2641
+ });
2642
+ }, []);
2643
+
2644
+ const openSettingsSection = useCallback(
2645
+ (section: SettingsSectionId, scroll = false) => {
2646
+ setOpenSection(section);
2647
+ if (scroll) scrollSectionIntoView(section);
2648
+ },
2649
+ [scrollSectionIntoView],
2650
+ );
2651
+
2652
+ useEffect(() => {
2653
+ const section = normalizeSettingsSection(initialSection);
2654
+ if (!section || !shouldShowSection(section)) return;
2655
+ if (section !== "secrets") setFocusSecretKey(undefined);
2656
+ openSettingsSection(section, true);
2657
+ }, [
2658
+ initialSection,
2659
+ sectionRequestKey,
2660
+ openSettingsSection,
2661
+ shouldShowSection,
2662
+ ]);
2663
+
2664
+ // Support `#secrets:<KEY>` hash fragments from the onboarding CTA — opens
2665
+ // the section and focuses the matching input.
2666
+ useEffect(() => {
2667
+ if (typeof window === "undefined") return;
2668
+ const handleHash = () => {
2669
+ const hash = window.location.hash?.replace(/^#/, "") ?? "";
2670
+ const section = normalizeSettingsSection(hash);
2671
+ if (!section || !shouldShowSection(section)) return;
2672
+ if (hash.startsWith("secrets:") || hash === "secrets") {
2673
+ const key = hash.slice("secrets:".length);
2674
+ setFocusSecretKey(key || undefined);
2675
+ } else {
2676
+ setFocusSecretKey(undefined);
2677
+ }
2678
+ openSettingsSection(section, true);
2679
+ };
2680
+ handleHash();
2681
+ window.addEventListener("hashchange", handleHash);
2682
+ return () => window.removeEventListener("hashchange", handleHash);
2683
+ }, [openSettingsSection, shouldShowSection]);
2684
+
2685
+ const isPage = surface === "page";
2686
+
2687
+ return (
2688
+ <SettingsSurfaceProvider surface={surface}>
2689
+ <div
2690
+ className={cn(
2691
+ isPage ? "space-y-3" : "flex-1 min-h-0 overflow-y-auto p-3 space-y-2",
2692
+ className,
2693
+ )}
2694
+ style={isPage ? undefined : { overflowY: "auto" }}
2695
+ >
2696
+ {/* Agent capability mode (App vs Code) + app link */}
2697
+ {(showDevToggle || devAppUrl) && (
2698
+ <div className="space-y-2 pb-2 border-b border-border mb-2">
2699
+ {showDevToggle && (
2700
+ <SettingsSelect
2701
+ label="Agent mode"
2702
+ labelAdornment={
2703
+ devAppUrl ? (
2704
+ <Tooltip>
2705
+ <TooltipTrigger asChild>
2706
+ <a
2707
+ href={devAppUrl}
2708
+ target="_blank"
2709
+ rel="noopener noreferrer"
2710
+ aria-label="Open app in new tab"
2711
+ className="flex items-center text-muted-foreground hover:text-foreground"
2712
+ >
2713
+ <IconExternalLink size={14} />
2714
+ </a>
2715
+ </TooltipTrigger>
2716
+ <TooltipContent>Open app in new tab</TooltipContent>
2717
+ </Tooltip>
2718
+ ) : undefined
2719
+ }
2720
+ value={isDevMode ? "development" : "production"}
2721
+ options={agentModeOptions}
2722
+ onValueChange={(next) => {
2723
+ const nextIsDev = next === "development";
2724
+ if (nextIsDev !== isDevMode) onToggleDevMode();
2725
+ }}
2726
+ />
2727
+ )}
2728
+ </div>
2729
+ )}
2730
+
2731
+ {showCapabilityStrip && (
2732
+ <CapabilityStatusStrip
2733
+ isDevMode={isDevMode}
2734
+ builderConnected={connected}
2735
+ builderLoading={builderLoading}
2736
+ builderBranchesAvailable={builderBranchesAvailable}
2737
+ onOpenLlm={() => openSettingsSection("llm", true)}
2738
+ />
2739
+ )}
2740
+
2741
+ {/* Account */}
2742
+ {shouldShowSection("account") && (
2743
+ <AccountSectionInner
2744
+ open={openSection === "account"}
2745
+ onToggle={() => toggle("account")}
2746
+ />
2747
+ )}
2748
+
2749
+ {/* LLM */}
2750
+ {shouldShowSection("llm") && (
2751
+ <LLMSectionInner
2752
+ builderFlow={builderFlow}
2753
+ builderLoading={builderLoading}
2754
+ connectUrl={connectUrl}
2755
+ connected={connected}
2756
+ orgName={orgName}
2757
+ envManaged={envManaged}
2758
+ credentialSource={credentialSource}
2759
+ open={openSection === "llm"}
2760
+ onToggle={() => toggle("llm")}
2761
+ />
2762
+ )}
2763
+
2764
+ {/* App default model */}
2765
+ {shouldShowSection("app-models") && (
2766
+ <AppModelDefaultsSectionInner
2767
+ open={openSection === "app-models"}
2768
+ onToggle={() => toggle("app-models")}
2769
+ />
2770
+ )}
2771
+
2772
+ {/* Agent limits */}
2773
+ {shouldShowSection("limits") && (
2774
+ <AgentLimitsSectionInner
2775
+ open={openSection === "limits"}
2776
+ onToggle={() => toggle("limits")}
2777
+ />
2778
+ )}
2779
+
2780
+ {/* Voice transcription */}
2781
+ {shouldShowSection("voice") && (
2782
+ <SettingsSection
2783
+ id={settingsSectionDomId("voice")}
2784
+ icon={<IconMicrophone size={14} />}
2785
+ title="Voice Transcription"
2786
+ subtitle="How the composer microphone turns your voice into text."
2787
+ open={openSection === "voice"}
2788
+ onToggle={() => toggle("voice")}
2789
+ >
2790
+ <VoiceTranscriptionSection />
2791
+ </SettingsSection>
2792
+ )}
2793
+
2794
+ {/* Demo mode */}
2795
+ {shouldShowSection("demo-mode") && (
2796
+ <SettingsSection
2797
+ id={settingsSectionDomId("demo-mode")}
2798
+ icon={<IconEyeOff size={14} />}
2799
+ title="Demo mode"
2800
+ subtitle="Replace displayed emails with realistic fake data in this browser and reshape supported charts for presentations. Backend, MCP, and agent results stay real and access-scoped."
2801
+ open={openSection === "demo-mode"}
2802
+ onToggle={() => toggle("demo-mode")}
2803
+ >
2804
+ <DemoModeSection />
2805
+ </SettingsSection>
2806
+ )}
2807
+
2808
+ {/* Automations */}
2809
+ {shouldShowSection("automations") && (
2810
+ <SettingsSection
2811
+ id={settingsSectionDomId("automations")}
2812
+ icon={<IconBolt size={14} />}
2813
+ title="Automations"
2814
+ subtitle="Event-triggered and scheduled automations."
2815
+ open={openSection === "automations"}
2816
+ onToggle={() => toggle("automations")}
2817
+ >
2818
+ <AutomationsSection />
2819
+ </SettingsSection>
2820
+ )}
2821
+
2822
+ {/* API Keys & Connections */}
2823
+ {shouldShowSection("secrets") && (
2824
+ <SettingsSection
2825
+ id={settingsSectionDomId("secrets")}
2826
+ icon={<IconKey size={14} />}
2827
+ title="API Keys & Connections"
2828
+ subtitle="Service credentials and automation keys."
2829
+ open={openSection === "secrets"}
2830
+ onToggle={() => toggle("secrets")}
2831
+ >
2832
+ <SecretsSection focusKey={focusSecretKey} />
2833
+ </SettingsSection>
2834
+ )}
2835
+
2836
+ {/* Hosting */}
2837
+ {shouldShowSection("hosting") && (
2838
+ <SettingsSection
2839
+ id={settingsSectionDomId("hosting")}
2840
+ icon={<IconCloud size={14} />}
2841
+ title="Hosting"
2842
+ subtitle="Deploy your app to the cloud."
2843
+ connected={connected}
2844
+ open={openSection === "hosting"}
2845
+ onToggle={() => toggle("hosting")}
2846
+ >
2847
+ <div className="space-y-2">
2848
+ <UseBuilderCard
2849
+ builderFlow={builderFlow}
2850
+ connectUrl={connectUrl}
2851
+ connected={connected}
2852
+ orgName={orgName}
2853
+ envManaged={envManaged}
2854
+ credentialSource={credentialSource}
2855
+ trackingSource="hosting_settings"
2856
+ trackingFlow="hosting"
2857
+ />
2858
+ <ManualSetupCard
2859
+ hint="Deploy manually to Netlify, Vercel, Cloudflare, or any Nitro-supported target."
2860
+ docsUrl="https://www.builder.io/c/docs/agent-native-deployment"
2861
+ dim={connected}
2862
+ />
2863
+ </div>
2864
+ </SettingsSection>
2865
+ )}
2866
+
2867
+ {/* Database */}
2868
+ {shouldShowSection("database") && (
2869
+ <SettingsSection
2870
+ id={settingsSectionDomId("database")}
2871
+ icon={<IconDatabase size={14} />}
2872
+ title="Database"
2873
+ subtitle="Connect a cloud database for persistent storage."
2874
+ connected={connected}
2875
+ open={openSection === "database"}
2876
+ onToggle={() => toggle("database")}
2877
+ >
2878
+ <div className="space-y-2">
2879
+ <UseBuilderCard
2880
+ builderFlow={builderFlow}
2881
+ connectUrl={connectUrl}
2882
+ connected={connected}
2883
+ orgName={orgName}
2884
+ envManaged={envManaged}
2885
+ credentialSource={credentialSource}
2886
+ trackingSource="database_settings"
2887
+ trackingFlow="database"
2888
+ />
2889
+ <ManualSetupCard
2890
+ hint="Set DATABASE_URL in your .env to connect Neon, Supabase, Turso, any Postgres/SQLite database, or local PGlite with pglite:./data/pglite."
2891
+ docsUrl="https://www.builder.io/c/docs/agent-native-database"
2892
+ dim={connected}
2893
+ />
2894
+ </div>
2895
+ </SettingsSection>
2896
+ )}
2897
+
2898
+ {/* File uploads */}
2899
+ {shouldShowSection("uploads") && (
2900
+ <SettingsSection
2901
+ id={settingsSectionDomId("uploads")}
2902
+ icon={<IconUpload size={14} />}
2903
+ title="File uploads"
2904
+ subtitle="Where user-uploaded files (avatars, chat attachments) are stored."
2905
+ connected={connected}
2906
+ open={openSection === "uploads"}
2907
+ onToggle={() => toggle("uploads")}
2908
+ >
2909
+ <div className="space-y-2">
2910
+ <UseBuilderCard
2911
+ builderFlow={builderFlow}
2912
+ connectUrl={connectUrl}
2913
+ connected={connected}
2914
+ orgName={orgName}
2915
+ envManaged={envManaged}
2916
+ credentialSource={credentialSource}
2917
+ trackingSource="file_upload_settings"
2918
+ trackingFlow="file_upload"
2919
+ />
2920
+ <ManualSetupCard
2921
+ hint="Without a provider, files are stored as base64 in your database. Fine for dev, not recommended for production."
2922
+ docsUrl="https://www.builder.io/c/docs/agent-native-file-uploads"
2923
+ dim={connected}
2924
+ />
2925
+ </div>
2926
+ </SettingsSection>
2927
+ )}
2928
+
2929
+ {/* Authentication */}
2930
+ {shouldShowSection("auth") && (
2931
+ <SettingsSection
2932
+ id={settingsSectionDomId("auth")}
2933
+ icon={<IconShield size={14} />}
2934
+ title="Authentication"
2935
+ subtitle="Set up user authentication and access control."
2936
+ connected={connected}
2937
+ open={openSection === "auth"}
2938
+ onToggle={() => toggle("auth")}
2939
+ >
2940
+ <div className="space-y-2">
2941
+ <UseBuilderCard
2942
+ builderFlow={builderFlow}
2943
+ connectUrl={connectUrl}
2944
+ connected={connected}
2945
+ orgName={orgName}
2946
+ envManaged={envManaged}
2947
+ credentialSource={credentialSource}
2948
+ trackingSource="auth_settings"
2949
+ trackingFlow="auth"
2950
+ />
2951
+ <ManualSetupCard
2952
+ hint="Configure Better Auth with BETTER_AUTH_SECRET and optional Google/GitHub OAuth providers."
2953
+ docsUrl="https://www.builder.io/c/docs/agent-native-authentication"
2954
+ dim={connected}
2955
+ />
2956
+ </div>
2957
+ </SettingsSection>
2958
+ )}
2959
+
2960
+ {/* Email */}
2961
+ {shouldShowSection("email") && (
2962
+ <EmailSectionInner
2963
+ open={openSection === "email"}
2964
+ onToggle={() => toggle("email")}
2965
+ />
2966
+ )}
2967
+
2968
+ {/* Browser Automation */}
2969
+ {shouldShowSection("browser") && (
2970
+ <SettingsSection
2971
+ id={settingsSectionDomId("browser")}
2972
+ icon={<IconBrowser size={14} />}
2973
+ title="Browser Automation"
2974
+ subtitle="Let agents control a real browser for web tasks."
2975
+ connected={builderConnectionOwnedExternally ? undefined : connected}
2976
+ open={openSection === "browser"}
2977
+ onToggle={() => toggle("browser")}
2978
+ >
2979
+ {!builderConnectionOwnedExternally ? (
2980
+ <UseBuilderCard
2981
+ builderFlow={builderFlow}
2982
+ connectUrl={connectUrl}
2983
+ connected={connected}
2984
+ orgName={orgName}
2985
+ envManaged={envManaged}
2986
+ credentialSource={credentialSource}
2987
+ trackingSource="browser_settings"
2988
+ trackingFlow="browser_automation"
2989
+ />
2990
+ ) : null}
2991
+ </SettingsSection>
2992
+ )}
2993
+
2994
+ {builderBranchesAvailable && shouldShowSection("background") && (
2995
+ <SettingsSection
2996
+ id={settingsSectionDomId("background")}
2997
+ icon={<IconGitBranch size={14} />}
2998
+ title="Background Agent"
2999
+ subtitle="Make code changes from production mode via Builder."
3000
+ connected={connected}
3001
+ open={openSection === "background"}
3002
+ onToggle={() => toggle("background")}
3003
+ >
3004
+ <UseBuilderCard
3005
+ builderFlow={builderFlow}
3006
+ connectUrl={connectUrl}
3007
+ connected={connected}
3008
+ orgName={orgName}
3009
+ envManaged={envManaged}
3010
+ credentialSource={credentialSource}
3011
+ trackingSource="background_agent_settings"
3012
+ trackingFlow="background_agent"
3013
+ />
3014
+ </SettingsSection>
3015
+ )}
3016
+
3017
+ {/* Integrations */}
3018
+ {shouldShowSection("integrations") && (
3019
+ <SettingsSection
3020
+ id={settingsSectionDomId("integrations")}
3021
+ icon={<IconPlugConnected size={14} />}
3022
+ title="Integrations"
3023
+ subtitle="Connect messaging platforms and external services."
3024
+ open={openSection === "integrations"}
3025
+ onToggle={() => toggle("integrations")}
3026
+ >
3027
+ <Suspense fallback={null}>
3028
+ <IntegrationsPanel />
3029
+ </Suspense>
3030
+ </SettingsSection>
3031
+ )}
3032
+
3033
+ {/* Usage & spend */}
3034
+ {shouldShowSection("usage") && (
3035
+ <SettingsSection
3036
+ id={settingsSectionDomId("usage")}
3037
+ icon={<IconCoin size={14} />}
3038
+ title="Usage"
3039
+ subtitle="Track token consumption and estimated cost — broken down by chat, automations, and background jobs."
3040
+ open={openSection === "usage"}
3041
+ onToggle={() => toggle("usage")}
3042
+ >
3043
+ <UsageSection />
3044
+ </SettingsSection>
3045
+ )}
3046
+
3047
+ {/* A2A Agents */}
3048
+ {shouldShowSection("a2a") && (
3049
+ <SettingsSection
3050
+ id={settingsSectionDomId("a2a")}
3051
+ icon={<IconTopologyRing2 size={14} />}
3052
+ title="Connected Agents (A2A)"
3053
+ subtitle="Manage remote agents connected via the A2A protocol."
3054
+ open={openSection === "a2a"}
3055
+ onToggle={() => toggle("a2a")}
3056
+ >
3057
+ <AgentsSection />
3058
+ </SettingsSection>
3059
+ )}
3060
+ </div>
3061
+ </SettingsSurfaceProvider>
3062
+ );
3063
+ }
3064
+
3065
+ export function SettingsPanel(props: SettingsPanelProps) {
3066
+ return <SettingsPanelContent {...props} />;
3067
+ }
3068
+
3069
+ export function ConnectionsSettingsContent({
3070
+ settingsPanelProps,
3071
+ }: {
3072
+ settingsPanelProps: SettingsPanelProps;
3073
+ }) {
3074
+ return (
3075
+ <div className="mx-auto w-full max-w-2xl space-y-4">
3076
+ <BuilderConnectCard trackingSource="settings_connections" />
3077
+ <SettingsPanelContent
3078
+ {...settingsPanelProps}
3079
+ surface="page"
3080
+ sections={CONNECTION_SETTINGS_SECTIONS}
3081
+ showCapabilityStrip={false}
3082
+ className="w-full"
3083
+ builderConnectionOwnedExternally
3084
+ />
3085
+ </div>
3086
+ );
3087
+ }
3088
+
3089
+ export function useAgentSettingsTabs(): SettingsTabItem[] {
3090
+ const { isDevMode, canToggle, setDevMode } = useDevMode();
3091
+ const baseProps = useMemo<SettingsPanelProps>(
3092
+ () => ({
3093
+ isDevMode,
3094
+ onToggleDevMode: () => {
3095
+ void setDevMode(!isDevMode);
3096
+ },
3097
+ showDevToggle: canToggle,
3098
+ }),
3099
+ [canToggle, isDevMode, setDevMode],
3100
+ );
3101
+
3102
+ return useMemo<SettingsTabItem[]>(() => {
3103
+ const searchTabs = getAgentSettingsSearchTabs();
3104
+ const searchTab = (
3105
+ id: "agent" | "connections" | "organization" | "workspace",
3106
+ ) => {
3107
+ const tab = searchTabs.find((candidate) => candidate.id === id);
3108
+ if (!tab) throw new Error(`Missing agent workspace tab: ${id}`);
3109
+ return tab;
3110
+ };
3111
+ const agent = searchTab("agent");
3112
+ const connections = searchTab("connections");
3113
+ const organization = searchTab("organization");
3114
+ const workspace = searchTab("workspace");
3115
+ return [
3116
+ {
3117
+ ...agent,
3118
+ icon: IconHierarchy2,
3119
+ group: "agent",
3120
+ content: (
3121
+ <SettingsPanelContent
3122
+ {...baseProps}
3123
+ surface="page"
3124
+ sections={AGENT_SETTINGS_SECTIONS}
3125
+ showCapabilityStrip={false}
3126
+ className="mx-auto w-full max-w-2xl"
3127
+ />
3128
+ ),
3129
+ },
3130
+ {
3131
+ ...connections,
3132
+ icon: IconPlugConnected,
3133
+ group: "agent",
3134
+ content: <ConnectionsSettingsContent settingsPanelProps={baseProps} />,
3135
+ },
3136
+ {
3137
+ ...organization,
3138
+ icon: IconUsersGroup,
3139
+ group: "workspace",
3140
+ content: (
3141
+ <div className="mx-auto w-full max-w-2xl">
3142
+ <TeamPage showTitle={false} />
3143
+ </div>
3144
+ ),
3145
+ },
3146
+ {
3147
+ ...workspace,
3148
+ icon: IconCloud,
3149
+ group: "workspace",
3150
+ content: (
3151
+ <SettingsPanelContent
3152
+ {...baseProps}
3153
+ surface="page"
3154
+ sections={WORKSPACE_SETTINGS_SECTIONS}
3155
+ showCapabilityStrip={false}
3156
+ className="mx-auto w-full max-w-2xl"
3157
+ />
3158
+ ),
3159
+ },
3160
+ ];
3161
+ }, [baseProps]);
3162
+ }