@agent-native/core 0.79.16 → 0.79.18

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 (344) hide show
  1. package/corpus/README.md +2 -2
  2. package/corpus/core/CHANGELOG.md +14 -0
  3. package/corpus/core/docs/content/file-uploads.md +11 -4
  4. package/corpus/core/docs/content/locales/ar-SA/multi-app-workspace.md +3 -3
  5. package/corpus/core/docs/content/locales/de-DE/multi-app-workspace.md +3 -3
  6. package/corpus/core/docs/content/locales/es-ES/multi-app-workspace.md +3 -3
  7. package/corpus/core/docs/content/locales/fr-FR/multi-app-workspace.md +3 -3
  8. package/corpus/core/docs/content/locales/hi-IN/multi-app-workspace.md +3 -3
  9. package/corpus/core/docs/content/locales/ja-JP/multi-app-workspace.md +3 -3
  10. package/corpus/core/docs/content/locales/ko-KR/multi-app-workspace.md +3 -3
  11. package/corpus/core/docs/content/locales/pt-BR/multi-app-workspace.md +3 -3
  12. package/corpus/core/docs/content/locales/zh-CN/multi-app-workspace.md +3 -3
  13. package/corpus/core/docs/content/locales/zh-TW/multi-app-workspace.md +3 -3
  14. package/corpus/core/docs/content/multi-app-workspace.md +3 -3
  15. package/corpus/core/docs/content/template-clips.md +14 -5
  16. package/corpus/core/package.json +1 -1
  17. package/corpus/core/src/agent/engine/builder-engine.ts +8 -3
  18. package/corpus/core/src/cli/mcp.ts +11 -6
  19. package/corpus/core/src/client/AssistantChat.tsx +6 -2
  20. package/corpus/core/src/client/chat/markdown-renderer.tsx +1 -0
  21. package/corpus/core/src/client/index.ts +7 -1
  22. package/corpus/core/src/client/org/OrgSwitcher.tsx +5 -5
  23. package/corpus/core/src/client/org/TeamPage.tsx +11 -3
  24. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +216 -0
  25. package/corpus/core/src/client/settings/index.ts +5 -0
  26. package/corpus/core/src/file-upload/index.ts +1 -0
  27. package/corpus/core/src/file-upload/registry.ts +22 -6
  28. package/corpus/core/src/file-upload/types.ts +6 -1
  29. package/corpus/core/src/integrations/adapters/email.ts +26 -18
  30. package/corpus/core/src/integrations/adapters/slack.ts +8 -7
  31. package/corpus/core/src/integrations/adapters/telegram.ts +9 -11
  32. package/corpus/core/src/integrations/adapters/whatsapp.ts +12 -9
  33. package/corpus/core/src/integrations/plugin.ts +79 -13
  34. package/corpus/core/src/onboarding/default-steps.ts +6 -3
  35. package/corpus/core/src/onboarding/types.ts +1 -1
  36. package/corpus/core/src/org/handlers.ts +1 -1
  37. package/corpus/core/src/server/agent-chat-plugin.ts +4 -7
  38. package/corpus/core/src/server/better-auth-instance.ts +19 -62
  39. package/corpus/core/src/server/core-routes-plugin.ts +93 -180
  40. package/corpus/core/src/server/create-server.ts +55 -116
  41. package/corpus/core/src/server/email-actions.ts +3 -6
  42. package/corpus/core/src/server/email.ts +52 -17
  43. package/corpus/core/src/server/index.ts +2 -1
  44. package/corpus/core/src/server/scoped-key-storage.ts +223 -0
  45. package/corpus/core/src/shared/agent-env.ts +3 -3
  46. package/corpus/core/src/sharing/actions/share-resource.ts +1 -1
  47. package/corpus/core/src/styles/agent-native.css +55 -3
  48. package/corpus/core/src/templates/workspace-root/AGENTS.md +3 -2
  49. package/corpus/core/src/templates/workspace-root/README.md +1 -1
  50. package/corpus/core/src/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
  51. package/corpus/core/src/terminal/pty-server.ts +3 -38
  52. package/corpus/core/src/triggers/dispatcher.ts +1 -2
  53. package/corpus/templates/.retired/issues/package.json +7 -0
  54. package/corpus/templates/.retired/meeting-notes/package.json +7 -0
  55. package/corpus/templates/.retired/recruiting/package.json +7 -0
  56. package/corpus/templates/.retired/scheduling/package.json +7 -0
  57. package/corpus/templates/.retired/voice/package.json +7 -0
  58. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  59. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +0 -17
  60. package/corpus/templates/analytics/app/i18n/zh-TW.ts +7 -1
  61. package/corpus/templates/analytics/app/i18n-data.ts +71 -2
  62. package/corpus/templates/analytics/app/pages/Settings.tsx +120 -73
  63. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -11
  64. package/corpus/templates/analytics/app/routes/catalog.tsx +33 -176
  65. package/corpus/templates/analytics/app/routes/team.tsx +3 -2
  66. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-templates-are-tucked-into-settings-and-show-simple.md +6 -0
  67. package/corpus/templates/analytics/changelog/2026-06-26-the-sessions-page-shows-a-single-page-title-instead-of-repea.md +6 -0
  68. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +37 -28
  69. package/corpus/templates/assets/app/routes/settings.tsx +65 -43
  70. package/corpus/templates/assets/app/routes/team.tsx +2 -10
  71. package/corpus/templates/brain/app/routes/settings.tsx +390 -358
  72. package/corpus/templates/brain/app/routes/team.tsx +2 -8
  73. package/corpus/templates/calendar/actions/db-connect.ts +5 -29
  74. package/corpus/templates/calendar/app/components/CloudUpgrade.tsx +8 -51
  75. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +2 -1
  76. package/corpus/templates/calendar/app/components/calendar/GoogleSetupWizard.tsx +4 -2
  77. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -2
  78. package/corpus/templates/calendar/app/pages/Settings.tsx +304 -271
  79. package/corpus/templates/calendar/app/routes/_app.team.tsx +2 -17
  80. package/corpus/templates/calendar/server/handlers/google-auth.ts +22 -9
  81. package/corpus/templates/calendar/server/lib/booking-emails.ts +1 -1
  82. package/corpus/templates/calendar/server/lib/event-guest-notifications.ts +1 -1
  83. package/corpus/templates/calendar/server/lib/google-calendar.ts +48 -28
  84. package/corpus/templates/chat/app/components/layout/Header.tsx +0 -1
  85. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +4 -2
  86. package/corpus/templates/chat/app/routes/settings.tsx +54 -54
  87. package/corpus/templates/chat/app/routes/team.tsx +2 -10
  88. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +7 -2
  89. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +1 -1
  90. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +7 -0
  91. package/corpus/templates/clips/AGENTS.md +8 -0
  92. package/corpus/templates/clips/actions/invite-member.ts +1 -1
  93. package/corpus/templates/clips/actions/request-transcript.ts +1 -1
  94. package/corpus/templates/clips/app/components/library/library-layout.tsx +3 -3
  95. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -0
  96. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +629 -643
  97. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +219 -155
  98. package/corpus/templates/clips/changelog/2026-06-26-long-desktop-recordings-are-checkpointed-so-macos-finalizati.md +6 -0
  99. package/corpus/templates/clips/changelog/2026-06-26-non-mac-desktop-recordings-wait-for-upload-transcription.md +6 -0
  100. package/corpus/templates/clips/changelog/2026-06-26-s3-compatible-storage-keys-now-save-securely-from-clips-sett.md +6 -0
  101. package/corpus/templates/clips/changelog/2026-06-26-shared-clip-links-guide-agents-through-processing-transcripts.md +6 -0
  102. package/corpus/templates/clips/changelog/2026-06-26-the-clip-details-sidebar-now-collapses-into-a-slide-out-pane.md +6 -0
  103. package/corpus/templates/clips/changelog/2026-06-26-the-clips-library-now-matches-the-shared-recessed-shell-styl.md +6 -0
  104. package/corpus/templates/clips/desktop/src/lib/recorder.ts +55 -3
  105. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +217 -5
  106. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  107. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +176 -5
  108. package/corpus/templates/clips/server/lib/public-agent-context.ts +31 -0
  109. package/corpus/templates/clips/server/lib/s3-upload-provider.ts +60 -14
  110. package/corpus/templates/clips/server/lib/video-storage.ts +37 -9
  111. package/corpus/templates/clips/server/routes/api/agent-transcript.json.get.ts +5 -0
  112. package/corpus/templates/content/app/components/layout/Header.tsx +0 -1
  113. package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +1 -0
  114. package/corpus/templates/content/app/routes/_app.settings.tsx +54 -55
  115. package/corpus/templates/content/app/routes/_app.team.tsx +2 -28
  116. package/corpus/templates/content/server/lib/notion.ts +43 -11
  117. package/corpus/templates/content/server/routes/api/notion/auth-url.get.ts +2 -2
  118. package/corpus/templates/content/server/routes/api/notion/status.get.ts +3 -3
  119. package/corpus/templates/design/app/routes/settings.tsx +60 -38
  120. package/corpus/templates/design/app/routes/team.tsx +2 -10
  121. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +2 -2
  122. package/corpus/templates/dispatch/app/routes/settings.tsx +70 -55
  123. package/corpus/templates/dispatch/app/routes/team.tsx +5 -1
  124. package/corpus/templates/forms/actions/db-connect.ts +7 -36
  125. package/corpus/templates/forms/actions/navigate.ts +2 -2
  126. package/corpus/templates/forms/app/components/CloudUpgrade.tsx +8 -47
  127. package/corpus/templates/forms/app/components/layout/Header.tsx +0 -1
  128. package/corpus/templates/forms/app/components/layout/Layout.tsx +42 -25
  129. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -76
  130. package/corpus/templates/forms/app/global.css +9 -25
  131. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +4 -4
  132. package/corpus/templates/forms/app/i18n/ar-SA.ts +1 -0
  133. package/corpus/templates/forms/app/i18n/de-DE.ts +1 -0
  134. package/corpus/templates/forms/app/i18n/en-US.ts +1 -0
  135. package/corpus/templates/forms/app/i18n/es-ES.ts +1 -0
  136. package/corpus/templates/forms/app/i18n/fr-FR.ts +1 -0
  137. package/corpus/templates/forms/app/i18n/hi-IN.ts +1 -0
  138. package/corpus/templates/forms/app/i18n/ja-JP.ts +1 -0
  139. package/corpus/templates/forms/app/i18n/ko-KR.ts +1 -0
  140. package/corpus/templates/forms/app/i18n/pt-BR.ts +1 -0
  141. package/corpus/templates/forms/app/i18n/zh-CN.ts +1 -0
  142. package/corpus/templates/forms/app/i18n/zh-TW.ts +1 -0
  143. package/corpus/templates/forms/app/lib/route-prewarm.ts +9 -8
  144. package/corpus/templates/forms/app/pages/AskPage.tsx +70 -0
  145. package/corpus/templates/forms/app/pages/FormsListPage.tsx +74 -81
  146. package/corpus/templates/forms/app/root.tsx +1 -1
  147. package/corpus/templates/forms/app/routes/_app.ask.tsx +14 -0
  148. package/corpus/templates/forms/app/routes/_app.settings.tsx +54 -54
  149. package/corpus/templates/forms/app/routes/_app.team.tsx +2 -9
  150. package/corpus/templates/forms/app/routes/_index.tsx +21 -130
  151. package/corpus/templates/forms/changelog/2026-06-26-ask-forms-opens-as-a-standard-app-tab-with-a-simpler-sidebar.md +6 -0
  152. package/corpus/templates/forms/changelog/2026-06-26-forms-are-shown-in-a-tighter-row-list-with-a-denser-sidebar.md +6 -0
  153. package/corpus/templates/forms/shared/navigation.ts +4 -2
  154. package/corpus/templates/macros/app/routes/settings.tsx +54 -54
  155. package/corpus/templates/macros/app/routes/team.tsx +2 -10
  156. package/corpus/templates/mail/actions/helpers.ts +2 -2
  157. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +2 -1
  158. package/corpus/templates/mail/app/pages/SettingsPage.tsx +5 -5
  159. package/corpus/templates/mail/app/routes/team.tsx +3 -2
  160. package/corpus/templates/mail/server/handlers/emails.ts +3 -2
  161. package/corpus/templates/mail/server/handlers/google-auth.ts +19 -12
  162. package/corpus/templates/mail/server/lib/automation-engine.ts +3 -2
  163. package/corpus/templates/mail/server/lib/email-state.ts +2 -3
  164. package/corpus/templates/mail/server/lib/google-auth.ts +28 -11
  165. package/corpus/templates/mail/server/lib/jobs.ts +3 -2
  166. package/corpus/templates/mail/server/onboarding.ts +9 -6
  167. package/corpus/templates/mail/server/routes/api/attachments.get.ts +3 -3
  168. package/corpus/templates/plan/actions/request-plan-access.ts +1 -1
  169. package/corpus/templates/plan/app/components/layout/Header.tsx +0 -1
  170. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +4 -2
  171. package/corpus/templates/plan/app/lib/route-prewarm.ts +0 -4
  172. package/corpus/templates/plan/app/routes/settings.tsx +75 -73
  173. package/corpus/templates/plan/app/routes/team.tsx +2 -8
  174. package/corpus/templates/plan/server/lib/comment-notifications.ts +1 -1
  175. package/corpus/templates/slides/actions/check-image-gen.ts +2 -1
  176. package/corpus/templates/slides/actions/db-connect.ts +7 -45
  177. package/corpus/templates/slides/actions/edit-image.ts +6 -3
  178. package/corpus/templates/slides/actions/generate-image-api.ts +1 -1
  179. package/corpus/templates/slides/actions/generate-image.ts +2 -2
  180. package/corpus/templates/slides/actions/generate-slides-ai.ts +5 -3
  181. package/corpus/templates/slides/actions/image-gen-status.ts +4 -3
  182. package/corpus/templates/slides/actions/image-search.ts +6 -3
  183. package/corpus/templates/slides/actions/search-images.ts +6 -3
  184. package/corpus/templates/slides/app/components/CloudUpgrade.tsx +8 -51
  185. package/corpus/templates/slides/app/components/layout/Header.tsx +0 -1
  186. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
  187. package/corpus/templates/slides/app/routes/settings.tsx +54 -54
  188. package/corpus/templates/slides/app/routes/team.tsx +2 -12
  189. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +9 -9
  190. package/corpus/templates/slides/server/handlers/image-gen.ts +5 -1
  191. package/corpus/templates/slides/server/handlers/image-providers/gemini.ts +9 -1
  192. package/corpus/templates/slides/server/handlers/image-providers/index.ts +18 -8
  193. package/corpus/templates/slides/server/handlers/image-providers/openai.ts +10 -4
  194. package/corpus/templates/slides/server/handlers/image-providers/types.ts +1 -0
  195. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +59 -34
  196. package/corpus/templates/slides/server/register-secrets.ts +60 -0
  197. package/corpus/templates/videos/actions/db-connect.ts +7 -45
  198. package/corpus/templates/videos/app/components/CloudUpgrade.tsx +8 -51
  199. package/corpus/templates/videos/app/components/Sidebar.tsx +1 -9
  200. package/corpus/templates/videos/app/components/layout/Header.tsx +0 -1
  201. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -3
  202. package/corpus/templates/videos/app/routes/settings.tsx +54 -54
  203. package/corpus/templates/videos/app/routes/team.tsx +2 -8
  204. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  205. package/dist/agent/engine/builder-engine.js +8 -3
  206. package/dist/agent/engine/builder-engine.js.map +1 -1
  207. package/dist/cli/mcp.d.ts.map +1 -1
  208. package/dist/cli/mcp.js +3 -4
  209. package/dist/cli/mcp.js.map +1 -1
  210. package/dist/client/AssistantChat.d.ts.map +1 -1
  211. package/dist/client/AssistantChat.js +6 -2
  212. package/dist/client/AssistantChat.js.map +1 -1
  213. package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
  214. package/dist/client/chat/markdown-renderer.js +1 -0
  215. package/dist/client/chat/markdown-renderer.js.map +1 -1
  216. package/dist/client/index.d.ts +1 -1
  217. package/dist/client/index.d.ts.map +1 -1
  218. package/dist/client/index.js +1 -1
  219. package/dist/client/index.js.map +1 -1
  220. package/dist/client/org/OrgSwitcher.d.ts +3 -3
  221. package/dist/client/org/OrgSwitcher.js +2 -2
  222. package/dist/client/org/OrgSwitcher.js.map +1 -1
  223. package/dist/client/org/TeamPage.d.ts +6 -1
  224. package/dist/client/org/TeamPage.d.ts.map +1 -1
  225. package/dist/client/org/TeamPage.js +2 -2
  226. package/dist/client/org/TeamPage.js.map +1 -1
  227. package/dist/client/settings/SettingsTabsPage.d.ts +27 -0
  228. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -0
  229. package/dist/client/settings/SettingsTabsPage.js +108 -0
  230. package/dist/client/settings/SettingsTabsPage.js.map +1 -0
  231. package/dist/client/settings/index.d.ts +1 -0
  232. package/dist/client/settings/index.d.ts.map +1 -1
  233. package/dist/client/settings/index.js +1 -0
  234. package/dist/client/settings/index.js.map +1 -1
  235. package/dist/collab/awareness.d.ts +2 -2
  236. package/dist/collab/awareness.d.ts.map +1 -1
  237. package/dist/collab/routes.d.ts +1 -1
  238. package/dist/file-upload/index.d.ts +1 -1
  239. package/dist/file-upload/index.d.ts.map +1 -1
  240. package/dist/file-upload/index.js +1 -1
  241. package/dist/file-upload/index.js.map +1 -1
  242. package/dist/file-upload/registry.d.ts +1 -0
  243. package/dist/file-upload/registry.d.ts.map +1 -1
  244. package/dist/file-upload/registry.js +24 -6
  245. package/dist/file-upload/registry.js.map +1 -1
  246. package/dist/file-upload/types.d.ts +6 -1
  247. package/dist/file-upload/types.d.ts.map +1 -1
  248. package/dist/file-upload/types.js.map +1 -1
  249. package/dist/integrations/adapters/email.d.ts.map +1 -1
  250. package/dist/integrations/adapters/email.js +18 -18
  251. package/dist/integrations/adapters/email.js.map +1 -1
  252. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  253. package/dist/integrations/adapters/slack.js +8 -7
  254. package/dist/integrations/adapters/slack.js.map +1 -1
  255. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  256. package/dist/integrations/adapters/telegram.js +9 -9
  257. package/dist/integrations/adapters/telegram.js.map +1 -1
  258. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  259. package/dist/integrations/adapters/whatsapp.js +10 -9
  260. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  261. package/dist/integrations/plugin.d.ts.map +1 -1
  262. package/dist/integrations/plugin.js +47 -13
  263. package/dist/integrations/plugin.js.map +1 -1
  264. package/dist/notifications/routes.d.ts +1 -1
  265. package/dist/onboarding/default-steps.d.ts.map +1 -1
  266. package/dist/onboarding/default-steps.js +6 -5
  267. package/dist/onboarding/default-steps.js.map +1 -1
  268. package/dist/onboarding/types.d.ts +1 -1
  269. package/dist/onboarding/types.d.ts.map +1 -1
  270. package/dist/onboarding/types.js.map +1 -1
  271. package/dist/org/handlers.js +1 -1
  272. package/dist/org/handlers.js.map +1 -1
  273. package/dist/progress/routes.d.ts +1 -1
  274. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  275. package/dist/server/agent-chat-plugin.js +4 -6
  276. package/dist/server/agent-chat-plugin.js.map +1 -1
  277. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  278. package/dist/server/better-auth-instance.d.ts.map +1 -1
  279. package/dist/server/better-auth-instance.js +17 -56
  280. package/dist/server/better-auth-instance.js.map +1 -1
  281. package/dist/server/core-routes-plugin.d.ts +1 -1
  282. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  283. package/dist/server/core-routes-plugin.js +67 -153
  284. package/dist/server/core-routes-plugin.js.map +1 -1
  285. package/dist/server/create-server.d.ts +3 -9
  286. package/dist/server/create-server.d.ts.map +1 -1
  287. package/dist/server/create-server.js +37 -91
  288. package/dist/server/create-server.js.map +1 -1
  289. package/dist/server/email-actions.d.ts +2 -3
  290. package/dist/server/email-actions.d.ts.map +1 -1
  291. package/dist/server/email-actions.js +3 -6
  292. package/dist/server/email-actions.js.map +1 -1
  293. package/dist/server/email.d.ts +3 -3
  294. package/dist/server/email.d.ts.map +1 -1
  295. package/dist/server/email.js +40 -19
  296. package/dist/server/email.js.map +1 -1
  297. package/dist/server/index.d.ts +3 -3
  298. package/dist/server/index.d.ts.map +1 -1
  299. package/dist/server/index.js +3 -3
  300. package/dist/server/index.js.map +1 -1
  301. package/dist/server/scoped-key-storage.d.ts +22 -0
  302. package/dist/server/scoped-key-storage.d.ts.map +1 -0
  303. package/dist/server/scoped-key-storage.js +152 -0
  304. package/dist/server/scoped-key-storage.js.map +1 -0
  305. package/dist/shared/agent-env.d.ts +3 -3
  306. package/dist/shared/agent-env.d.ts.map +1 -1
  307. package/dist/shared/agent-env.js +3 -3
  308. package/dist/shared/agent-env.js.map +1 -1
  309. package/dist/sharing/actions/share-resource.js +1 -1
  310. package/dist/sharing/actions/share-resource.js.map +1 -1
  311. package/dist/styles/agent-native.css +55 -3
  312. package/dist/templates/workspace-root/AGENTS.md +3 -2
  313. package/dist/templates/workspace-root/README.md +1 -1
  314. package/dist/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
  315. package/dist/terminal/pty-server.d.ts.map +1 -1
  316. package/dist/terminal/pty-server.js +3 -36
  317. package/dist/terminal/pty-server.js.map +1 -1
  318. package/dist/triggers/dispatcher.js +1 -1
  319. package/dist/triggers/dispatcher.js.map +1 -1
  320. package/docs/content/file-uploads.md +11 -4
  321. package/docs/content/locales/ar-SA/multi-app-workspace.md +3 -3
  322. package/docs/content/locales/de-DE/multi-app-workspace.md +3 -3
  323. package/docs/content/locales/es-ES/multi-app-workspace.md +3 -3
  324. package/docs/content/locales/fr-FR/multi-app-workspace.md +3 -3
  325. package/docs/content/locales/hi-IN/multi-app-workspace.md +3 -3
  326. package/docs/content/locales/ja-JP/multi-app-workspace.md +3 -3
  327. package/docs/content/locales/ko-KR/multi-app-workspace.md +3 -3
  328. package/docs/content/locales/pt-BR/multi-app-workspace.md +3 -3
  329. package/docs/content/locales/zh-CN/multi-app-workspace.md +3 -3
  330. package/docs/content/locales/zh-TW/multi-app-workspace.md +3 -3
  331. package/docs/content/multi-app-workspace.md +3 -3
  332. package/docs/content/template-clips.md +14 -5
  333. package/package.json +1 -1
  334. package/src/templates/workspace-root/AGENTS.md +3 -2
  335. package/src/templates/workspace-root/README.md +1 -1
  336. package/src/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
  337. package/corpus/core/src/server/env-var-writes.ts +0 -16
  338. package/corpus/templates/analytics/app/pages/Team.tsx +0 -9
  339. package/corpus/templates/calendar/app/pages/Team.tsx +0 -12
  340. package/corpus/templates/mail/app/pages/Team.tsx +0 -17
  341. package/dist/server/env-var-writes.d.ts +0 -10
  342. package/dist/server/env-var-writes.d.ts.map +0 -1
  343. package/dist/server/env-var-writes.js +0 -18
  344. package/dist/server/env-var-writes.js.map +0 -1
@@ -35,6 +35,7 @@ import {
35
35
  getAuthStatus,
36
36
  disconnect,
37
37
  getClient,
38
+ getOAuth2Credentials,
38
39
  setAccountDisplayName,
39
40
  } from "../lib/google-auth.js";
40
41
 
@@ -103,14 +104,6 @@ function googleOAuthErrorResponse(
103
104
  }
104
105
 
105
106
  export const getGoogleAuthUrl = defineEventHandler(async (event: H3Event) => {
106
- if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
107
- setResponseStatus(event, 422);
108
- return {
109
- error: "missing_credentials",
110
- message:
111
- "Google OAuth credentials are not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.",
112
- };
113
- }
114
107
  try {
115
108
  const q = getQuery(event);
116
109
  const redirectUri = resolveOAuthRedirectUri(event);
@@ -123,6 +116,7 @@ export const getGoogleAuthUrl = defineEventHandler(async (event: H3Event) => {
123
116
  }
124
117
  const session = await getSession(event);
125
118
  const owner = session?.email;
119
+ await getOAuth2Credentials(owner);
126
120
  const desktop =
127
121
  isElectron(event) || q.desktop === "1" || q.desktop === "true";
128
122
  const flowId = desktop ? (q.flow_id as string) || undefined : undefined;
@@ -141,12 +135,20 @@ export const getGoogleAuthUrl = defineEventHandler(async (event: H3Event) => {
141
135
  returnUrl,
142
136
  flowId,
143
137
  });
144
- const url = getAuthUrl(undefined, redirectUri, state);
138
+ const url = await getAuthUrl(undefined, redirectUri, state, owner);
145
139
  if (q.redirect === "1") {
146
140
  return oauthRedirectResponse(url);
147
141
  }
148
142
  return { url };
149
143
  } catch (error: any) {
144
+ if (/GOOGLE_CLIENT_ID|GOOGLE_CLIENT_SECRET/.test(error?.message || "")) {
145
+ setResponseStatus(event, 422);
146
+ return {
147
+ error: "missing_credentials",
148
+ message:
149
+ "Google OAuth credentials are not configured. Save GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in settings.",
150
+ };
151
+ }
150
152
  setResponseStatus(event, 500);
151
153
  return { error: error.message };
152
154
  }
@@ -279,12 +281,12 @@ export const getGoogleAddAccountUrl = defineEventHandler(
279
281
  setResponseStatus(event, 401);
280
282
  return { error: "Must be logged in to add an account" };
281
283
  }
282
- if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
284
+ if (!(await getOAuth2Credentials(session.email).catch(() => null))) {
283
285
  setResponseStatus(event, 422);
284
286
  return {
285
287
  error: "missing_credentials",
286
288
  message:
287
- "Google OAuth credentials are not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.",
289
+ "Google OAuth credentials are not configured. Save GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in settings.",
288
290
  };
289
291
  }
290
292
  try {
@@ -308,7 +310,12 @@ export const getGoogleAddAccountUrl = defineEventHandler(
308
310
  app: OAUTH_STATE_APP_ID,
309
311
  flowId,
310
312
  });
311
- const url = getAuthUrl(undefined, redirectUri, state);
313
+ const url = await getAuthUrl(
314
+ undefined,
315
+ redirectUri,
316
+ state,
317
+ session.email,
318
+ );
312
319
  if (q.redirect === "1") {
313
320
  return oauthRedirectResponse(url);
314
321
  }
@@ -27,6 +27,7 @@ import {
27
27
  gmailListHistory,
28
28
  gmailGetProfile,
29
29
  } from "./google-api.js";
30
+ import { getOAuth2Credentials } from "./google-auth.js";
30
31
 
31
32
  const DEFAULT_MODEL = "claude-haiku-4-5-20251001";
32
33
  const MAX_EMAILS_PER_RUN = 50;
@@ -91,8 +92,8 @@ async function getAccessToken(accountEmail: string): Promise<string | null> {
91
92
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
92
93
  ) {
93
94
  try {
94
- const clientId = process.env.GOOGLE_CLIENT_ID!;
95
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
95
+ const { clientId, clientSecret } =
96
+ await getOAuth2Credentials(accountEmail);
96
97
  const oauth = createOAuth2Client(
97
98
  clientId,
98
99
  clientSecret,
@@ -22,7 +22,7 @@ import {
22
22
  gmailTrashThread,
23
23
  gmailUntrashThread,
24
24
  } from "./google-api.js";
25
- import { isConnected } from "./google-auth.js";
25
+ import { getOAuth2Credentials, isConnected } from "./google-auth.js";
26
26
  import { invalidateThreadCache } from "./thread-cache.js";
27
27
 
28
28
  // ---------------------------------------------------------------------------
@@ -45,8 +45,7 @@ async function refreshIfNeeded(
45
45
  tokens.expiry_date &&
46
46
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
47
47
  ) {
48
- const clientId = process.env.GOOGLE_CLIENT_ID!;
49
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
48
+ const { clientId, clientSecret } = await getOAuth2Credentials(accountId);
50
49
  const oauth = createOAuth2Client(clientId, clientSecret, "");
51
50
  const refreshed = await oauth.refreshToken(tokens.refresh_token);
52
51
  const updated = {
@@ -5,7 +5,12 @@ import {
5
5
  listOAuthAccountsByOwner,
6
6
  setOAuthDisplayName,
7
7
  } from "@agent-native/core/oauth-tokens";
8
- import { isOAuthConnected, getOAuthAccounts } from "@agent-native/core/server";
8
+ import {
9
+ isOAuthConnected,
10
+ getOAuthAccounts,
11
+ resolveSecret,
12
+ runWithRequestContext,
13
+ } from "@agent-native/core/server";
9
14
  import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
10
15
  import { decodeCommonHtmlEntities } from "@shared/markdown.js";
11
16
 
@@ -46,15 +51,26 @@ interface GoogleTokens {
46
51
  scope?: string;
47
52
  }
48
53
 
49
- function getOAuth2Credentials(): {
54
+ export async function getOAuth2Credentials(owner?: string): Promise<{
50
55
  clientId: string;
51
56
  clientSecret: string;
52
- } {
53
- const clientId = process.env.GOOGLE_CLIENT_ID;
54
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
57
+ }> {
58
+ const resolve = async () => {
59
+ const [clientId, clientSecret] = await Promise.all([
60
+ resolveSecret("GOOGLE_CLIENT_ID"),
61
+ resolveSecret("GOOGLE_CLIENT_SECRET"),
62
+ ]);
63
+ if (!clientId || !clientSecret) return null;
64
+ return { clientId, clientSecret };
65
+ };
66
+ const credentials = owner
67
+ ? await runWithRequestContext({ userEmail: owner }, resolve)
68
+ : await resolve();
69
+ const clientId = credentials?.clientId;
70
+ const clientSecret = credentials?.clientSecret;
55
71
  if (!clientId || !clientSecret) {
56
72
  throw new Error(
57
- "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET must be set in environment",
73
+ "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET must be saved in settings",
58
74
  );
59
75
  }
60
76
  return { clientId, clientSecret };
@@ -112,7 +128,7 @@ async function getValidAccessToken(
112
128
  );
113
129
  }
114
130
 
115
- const { clientId, clientSecret } = getOAuth2Credentials();
131
+ const { clientId, clientSecret } = await getOAuth2Credentials(owner);
116
132
  const redirectUri = "http://localhost:8080/_agent-native/google/callback";
117
133
  const oauth2 = createOAuth2Client(clientId, clientSecret, redirectUri);
118
134
  let refreshed;
@@ -157,12 +173,13 @@ async function getValidAccessToken(
157
173
  return refreshed.access_token;
158
174
  }
159
175
 
160
- export function getAuthUrl(
176
+ export async function getAuthUrl(
161
177
  origin?: string,
162
178
  redirectUri?: string,
163
179
  state?: string,
164
- ): string {
165
- const { clientId, clientSecret } = getOAuth2Credentials();
180
+ owner?: string,
181
+ ): Promise<string> {
182
+ const { clientId, clientSecret } = await getOAuth2Credentials(owner);
166
183
  const uri =
167
184
  redirectUri ||
168
185
  (origin
@@ -215,7 +232,7 @@ export async function exchangeCode(
215
232
  redirectUri?: string,
216
233
  owner?: string,
217
234
  ): Promise<string> {
218
- const { clientId, clientSecret } = getOAuth2Credentials();
235
+ const { clientId, clientSecret } = await getOAuth2Credentials(owner);
219
236
  const uri =
220
237
  redirectUri ||
221
238
  (origin
@@ -25,6 +25,7 @@ import {
25
25
  getAccountDisplayName,
26
26
  isConnected,
27
27
  gmailToEmailMessage,
28
+ getOAuth2Credentials,
28
29
  setAccountDisplayName,
29
30
  } from "./google-auth.js";
30
31
  import {
@@ -83,8 +84,8 @@ async function getAccessToken(accountEmail: string): Promise<string | null> {
83
84
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
84
85
  ) {
85
86
  try {
86
- const clientId = process.env.GOOGLE_CLIENT_ID!;
87
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
87
+ const { clientId, clientSecret } =
88
+ await getOAuth2Credentials(accountEmail);
88
89
  const oauth = createOAuth2Client(
89
90
  clientId,
90
91
  clientSecret,
@@ -8,12 +8,12 @@
8
8
  * `GoogleConnectBanner` auto-detects missing credentials and guides the
9
9
  * user through the Google Cloud Console setup.
10
10
  * 2. Agent task — hands the task to the agent, which drives the user's
11
- * browser (or falls back to verbal step-by-step instructions) and writes
12
- * the resulting credentials into the workspace `.env` via
13
- * `POST /_agent-native/env-vars`.
11
+ * browser (or falls back to verbal step-by-step instructions) and saves
12
+ * the resulting credentials as workspace-scoped DB keys.
14
13
  */
15
14
 
16
15
  import { registerOnboardingStep } from "@agent-native/core/onboarding";
16
+ import { readDeployCredentialEnv } from "@agent-native/core/server";
17
17
 
18
18
  registerOnboardingStep({
19
19
  id: "gmail",
@@ -37,10 +37,13 @@ registerOnboardingStep({
37
37
  label: "Have the agent set it up for me",
38
38
  payload: {
39
39
  prompt:
40
- 'Help me connect Gmail. Walk me through creating Google OAuth credentials by driving my browser (use any mcp__*browser* tools available, or fall back to giving me step-by-step instructions with exact URLs and values). When client_id and client_secret are ready, save them to my workspace .env via POST /_agent-native/env-vars with scope "workspace". Then tell me to click "Sign in with Google" in the mail onboarding banner to finish the OAuth sign-in.',
40
+ "Help me connect Gmail. Walk me through creating Google OAuth credentials by driving my browser (use any mcp__*browser* tools available, or fall back to giving me step-by-step instructions with exact URLs and values). When client_id and client_secret are ready, help me configure GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET as deployment or local environment variables for Mail, then restart or redeploy before clicking Sign in with Google.",
41
41
  },
42
42
  },
43
43
  ],
44
- isComplete: () =>
45
- !!process.env.GOOGLE_CLIENT_ID && !!process.env.GOOGLE_CLIENT_SECRET,
44
+ isComplete: async () =>
45
+ Boolean(
46
+ readDeployCredentialEnv("GOOGLE_CLIENT_ID") &&
47
+ readDeployCredentialEnv("GOOGLE_CLIENT_SECRET"),
48
+ ),
46
49
  });
@@ -15,7 +15,7 @@ import {
15
15
  createOAuth2Client,
16
16
  gmailGetAttachment,
17
17
  } from "../../lib/google-api.js";
18
- import { isConnected } from "../../lib/google-auth.js";
18
+ import { getOAuth2Credentials, isConnected } from "../../lib/google-auth.js";
19
19
 
20
20
  interface StoredTokens {
21
21
  access_token: string;
@@ -35,8 +35,8 @@ async function getAccessToken(accountEmail: string): Promise<string | null> {
35
35
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
36
36
  ) {
37
37
  try {
38
- const clientId = process.env.GOOGLE_CLIENT_ID!;
39
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
38
+ const { clientId, clientSecret } =
39
+ await getOAuth2Credentials(accountEmail);
40
40
  const oauth = createOAuth2Client(
41
41
  clientId,
42
42
  clientSecret,
@@ -57,7 +57,7 @@ async function notifyOwner(input: {
57
57
  requesterEmail: string;
58
58
  requesterName: string;
59
59
  }): Promise<boolean> {
60
- if (!isEmailConfigured()) return false;
60
+ if (!(await isEmailConfigured())) return false;
61
61
  if (!input.ownerEmail || input.ownerEmail === input.requesterEmail) {
62
62
  return false;
63
63
  }
@@ -10,7 +10,6 @@ const pageTitleKeys: Record<string, string> = {
10
10
  "/": "header.plan",
11
11
  "/plans": "header.plan",
12
12
  "/settings": "header.settings",
13
- "/team": "header.team",
14
13
  };
15
14
 
16
15
  function resolveTitle(pathname: string): string {
@@ -132,7 +132,7 @@ function viewForPath(pathname: string): string {
132
132
  return "plans";
133
133
  }
134
134
  if (pathname.startsWith("/extensions")) return "extensions";
135
- if (pathname.startsWith("/team")) return "team";
135
+ if (pathname.startsWith("/team")) return "settings";
136
136
  return "plans";
137
137
  }
138
138
 
@@ -183,8 +183,10 @@ function pathForView(view?: string): string {
183
183
  return "/plans";
184
184
  case "extensions":
185
185
  return "/extensions";
186
+ case "settings":
187
+ return "/settings";
186
188
  case "team":
187
- return "/team";
189
+ return "/settings#team";
188
190
  default:
189
191
  return "/";
190
192
  }
@@ -48,10 +48,6 @@ export function prewarmPlanRoutePath(path: string) {
48
48
  );
49
49
  }
50
50
 
51
- if (pathname === "/team") {
52
- jobs.push(prewarm("team", () => import("@/routes/team")));
53
- }
54
-
55
51
  return Promise.all(jobs);
56
52
  }
57
53
 
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  ChangelogSettingsCard,
3
3
  LanguagePicker,
4
+ SettingsTabsPage,
4
5
  openAgentSettings,
5
6
  useT,
6
7
  } from "@agent-native/core/client";
7
- import { Link } from "react-router";
8
+ import { TeamPage } from "@agent-native/core/client/org";
8
9
 
9
10
  import { useSetPageTitle } from "@/components/layout/HeaderActions";
10
11
  import { Button } from "@/components/ui/button";
@@ -29,80 +30,81 @@ export default function SettingsRoute() {
29
30
  useSetPageTitle(t("settings.title"));
30
31
 
31
32
  return (
32
- <main className="mx-auto w-full max-w-3xl space-y-6 px-4 py-6 sm:px-6 sm:py-10">
33
- <div className="space-y-1">
34
- <h1 className="text-2xl font-semibold tracking-tight">
35
- {t("settings.title")}
36
- </h1>
37
- <p className="text-sm leading-6 text-muted-foreground">
38
- {t("settings.description")}
39
- </p>
40
- </div>
33
+ <SettingsTabsPage
34
+ teamLabel={t("header.team")}
35
+ general={
36
+ <div className="mx-auto w-full max-w-3xl space-y-6">
37
+ <p className="text-sm leading-6 text-muted-foreground">
38
+ {t("settings.description")}
39
+ </p>
41
40
 
42
- <Card>
43
- <CardHeader>
44
- <CardTitle className="text-base">
45
- {t("settings.languageTitle")}
46
- </CardTitle>
47
- <CardDescription>{t("settings.languageDescription")}</CardDescription>
48
- </CardHeader>
49
- <CardContent className="max-w-xs space-y-1.5">
50
- <Label>{t("settings.languageLabel")}</Label>
51
- <LanguagePicker label={t("settings.languageLabel")} />
52
- </CardContent>
53
- </Card>
41
+ <Card>
42
+ <CardHeader>
43
+ <CardTitle className="text-base">
44
+ {t("settings.languageTitle")}
45
+ </CardTitle>
46
+ <CardDescription>
47
+ {t("settings.languageDescription")}
48
+ </CardDescription>
49
+ </CardHeader>
50
+ <CardContent className="max-w-xs space-y-1.5">
51
+ <Label>{t("settings.languageLabel")}</Label>
52
+ <LanguagePicker label={t("settings.languageLabel")} />
53
+ </CardContent>
54
+ </Card>
54
55
 
55
- <Card>
56
- <CardHeader>
57
- <CardTitle className="text-base">
58
- {t("settings.workspaceTitle")}
59
- </CardTitle>
60
- <CardDescription>
61
- {t("settings.workspaceDescription")}
62
- </CardDescription>
63
- </CardHeader>
64
- <CardContent>
65
- <Button variant="outline" asChild>
66
- <Link to="/team">{t("settings.openTeamSettings")}</Link>
67
- </Button>
68
- </CardContent>
69
- </Card>
56
+ <Card>
57
+ <CardHeader>
58
+ <CardTitle className="text-base">
59
+ {t("settings.agentTitle")}
60
+ </CardTitle>
61
+ <CardDescription>
62
+ {t("settings.agentDescription")}
63
+ </CardDescription>
64
+ </CardHeader>
65
+ <CardContent>
66
+ <Button variant="outline" onClick={() => openAgentSettings()}>
67
+ {t("settings.openAgentSettings")}
68
+ </Button>
69
+ </CardContent>
70
+ </Card>
70
71
 
71
- <Card>
72
- <CardHeader>
73
- <CardTitle className="text-base">
74
- {t("settings.agentTitle")}
75
- </CardTitle>
76
- <CardDescription>{t("settings.agentDescription")}</CardDescription>
77
- </CardHeader>
78
- <CardContent>
79
- <Button variant="outline" onClick={() => openAgentSettings()}>
80
- {t("settings.openAgentSettings")}
81
- </Button>
82
- </CardContent>
83
- </Card>
84
-
85
- <Card>
86
- <CardHeader>
87
- <CardTitle className="text-base">
88
- {t("settings.editorTitle")}
89
- </CardTitle>
90
- <CardDescription>{t("settings.editorDescription")}</CardDescription>
91
- </CardHeader>
92
- <CardContent>
93
- <Button variant="outline" asChild>
94
- <a
95
- href="https://marketplace.visualstudio.com/items?itemName=Builder.agent-native"
96
- target="_blank"
97
- rel="noreferrer noopener"
98
- >
99
- {t("settings.openEditorExtension")}
100
- </a>
101
- </Button>
102
- </CardContent>
103
- </Card>
104
-
105
- <ChangelogSettingsCard markdown={changelog} />
106
- </main>
72
+ <Card>
73
+ <CardHeader>
74
+ <CardTitle className="text-base">
75
+ {t("settings.editorTitle")}
76
+ </CardTitle>
77
+ <CardDescription>
78
+ {t("settings.editorDescription")}
79
+ </CardDescription>
80
+ </CardHeader>
81
+ <CardContent>
82
+ <Button variant="outline" asChild>
83
+ <a
84
+ href="https://marketplace.visualstudio.com/items?itemName=Builder.agent-native"
85
+ target="_blank"
86
+ rel="noreferrer noopener"
87
+ >
88
+ {t("settings.openEditorExtension")}
89
+ </a>
90
+ </Button>
91
+ </CardContent>
92
+ </Card>
93
+ </div>
94
+ }
95
+ team={
96
+ <div className="mx-auto w-full max-w-3xl">
97
+ <TeamPage
98
+ showTitle={false}
99
+ createOrgDescription="Set up a team to share this app with your colleagues."
100
+ />
101
+ </div>
102
+ }
103
+ whatsNew={
104
+ <div className="mx-auto w-full max-w-3xl">
105
+ <ChangelogSettingsCard markdown={changelog} />
106
+ </div>
107
+ }
108
+ />
107
109
  );
108
110
  }
@@ -1,6 +1,5 @@
1
- import { TeamPage } from "@agent-native/core/client/org";
1
+ import { Navigate } from "react-router";
2
2
 
3
- import { useSetPageTitle } from "@/components/layout/HeaderActions";
4
3
  import { APP_TITLE } from "@/lib/app-config";
5
4
 
6
5
  export function meta() {
@@ -8,10 +7,5 @@ export function meta() {
8
7
  }
9
8
 
10
9
  export default function TeamRoute() {
11
- useSetPageTitle("Team");
12
- return (
13
- <main className="mx-auto w-full max-w-3xl px-4 py-6 sm:px-6 sm:py-10">
14
- <TeamPage createOrgDescription="Set up a team to share this app with your colleagues." />
15
- </main>
16
- );
10
+ return <Navigate to="/settings#team" replace />;
17
11
  }
@@ -230,7 +230,7 @@ export async function notifyPlanCommentRecipients({
230
230
  insertedCommentIds,
231
231
  priorComments,
232
232
  }: CommentNotificationInput): Promise<void> {
233
- if (insertedCommentIds.length === 0 || !isEmailConfigured()) return;
233
+ if (insertedCommentIds.length === 0 || !(await isEmailConfigured())) return;
234
234
 
235
235
  const db = getDb();
236
236
  const [planRow] = await db
@@ -1,4 +1,5 @@
1
1
  import { defineAction } from "@agent-native/core";
2
+ import { resolveSecret } from "@agent-native/core/server";
2
3
  import { z } from "zod";
3
4
 
4
5
  export default defineAction({
@@ -8,7 +9,7 @@ export default defineAction({
8
9
  http: { method: "GET" },
9
10
  run: async () => {
10
11
  return {
11
- gemini: !!process.env.GEMINI_API_KEY,
12
+ gemini: !!(await resolveSecret("GEMINI_API_KEY")),
12
13
  };
13
14
  },
14
15
  });
@@ -1,6 +1,3 @@
1
- import fs from "fs";
2
- import path from "path";
3
-
4
1
  function parseArgs(args: string[]): Record<string, string> {
5
2
  const result: Record<string, string> = {};
6
3
  for (let i = 0; i < args.length; i++) {
@@ -19,24 +16,6 @@ function parseArgs(args: string[]): Record<string, string> {
19
16
  return result;
20
17
  }
21
18
 
22
- function upsertEnvLine(lines: string[], key: string, value: string): string[] {
23
- // Reject values with newlines, carriage returns, or null bytes
24
- if (/[\r\n\0]/.test(value)) {
25
- throw new Error(
26
- `Invalid value for ${key}: must not contain newlines or null bytes`,
27
- );
28
- }
29
-
30
- const idx = lines.findIndex((l) => l.startsWith(`${key}=`));
31
- const line = `${key}=${value}`;
32
- if (idx >= 0) {
33
- lines[idx] = line;
34
- } else {
35
- lines.push(line);
36
- }
37
- return lines;
38
- }
39
-
40
19
  export default async function main(args: string[]) {
41
20
  const { url, token, help } = parseArgs(args);
42
21
 
@@ -44,7 +23,9 @@ export default async function main(args: string[]) {
44
23
  console.log(
45
24
  "Usage: pnpm action db-connect --url <DATABASE_URL> [--token <DATABASE_AUTH_TOKEN>]",
46
25
  );
47
- console.log("\nWrites DATABASE_URL and DATABASE_AUTH_TOKEN to .env");
26
+ console.log(
27
+ "\nDATABASE_URL and DATABASE_AUTH_TOKEN are deployment-level settings.",
28
+ );
48
29
  return;
49
30
  }
50
31
 
@@ -53,31 +34,12 @@ export default async function main(args: string[]) {
53
34
  throw new Error("Script failed");
54
35
  }
55
36
 
56
- const envPath = path.join(process.cwd(), ".env");
57
- let lines: string[] = [];
58
-
59
- if (fs.existsSync(envPath)) {
60
- lines = fs.readFileSync(envPath, "utf8").split("\n");
61
- }
62
-
63
- try {
64
- upsertEnvLine(lines, "DATABASE_URL", url);
65
- if (token) {
66
- upsertEnvLine(lines, "DATABASE_AUTH_TOKEN", token);
67
- }
68
- } catch (err) {
69
- console.error(
70
- `Error: ${err instanceof Error ? err.message : "Invalid value"}`,
71
- );
72
- throw new Error("Script failed");
73
- }
74
-
75
- fs.writeFileSync(envPath, lines.join("\n"));
76
-
77
- console.log(`\nDatabase connection saved to .env`);
37
+ console.log(`\nDatabase connection not written locally`);
78
38
  console.log(
79
39
  ` DATABASE_URL=${url.startsWith("file:") ? url : url.replace(/\/\/.*@/, "//***@")}`,
80
40
  );
81
41
  if (token) console.log(` DATABASE_AUTH_TOKEN=***`);
82
- console.log(`\nRestart the dev server for changes to take effect.`);
42
+ console.log(
43
+ `\nConfigure these as deployment environment variables with your host, then redeploy.`,
44
+ );
83
45
  }
@@ -6,6 +6,8 @@
6
6
  * pnpm action edit-image --input public/generated/slide5-v3.png --prompt "Remove the background and make it transparent. Remove any logos." --output public/assets/generated/slide5-edited
7
7
  */
8
8
 
9
+ import { resolveSecret } from "@agent-native/core/server";
10
+
9
11
  const config = async () => {
10
12
  try {
11
13
  const m = await import("dotenv");
@@ -49,13 +51,14 @@ export default async function main(args: string[]) {
49
51
  throw new Error("Script failed");
50
52
  }
51
53
 
52
- if (!process.env.GEMINI_API_KEY) {
53
- console.error("Error: GEMINI_API_KEY not set");
54
+ const apiKey = await resolveSecret("GEMINI_API_KEY");
55
+ if (!apiKey) {
56
+ console.error("Error: GEMINI_API_KEY not configured");
54
57
  throw new Error("Script failed");
55
58
  }
56
59
 
57
60
  const { GoogleGenAI } = await import("@google/genai");
58
- const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
61
+ const client = new GoogleGenAI({ apiKey });
59
62
 
60
63
  // Read the input image
61
64
  const imgBuffer = readFileSync(inputPath);
@@ -43,7 +43,7 @@ export default defineAction({
43
43
  // Get the appropriate provider
44
44
  const { getProvider } =
45
45
  await import("../server/handlers/image-providers/index.js");
46
- const provider = getProvider(args.model || "auto");
46
+ const provider = await getProvider(args.model || "auto");
47
47
 
48
48
  const refImages: ReferenceImage[] = [];
49
49