@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
@@ -192,10 +192,10 @@ Options:
192
192
  const modelChoice = opts["model"] || "auto";
193
193
  let provider: Awaited<ReturnType<typeof getProvider>>;
194
194
  try {
195
- provider = getProvider(modelChoice);
195
+ provider = await getProvider(modelChoice);
196
196
  } catch {
197
197
  console.error(
198
- "Error: No image generation provider configured. Set GEMINI_API_KEY or OPENAI_API_KEY.",
198
+ "Error: No image generation provider configured. Save GEMINI_API_KEY or OPENAI_API_KEY in settings.",
199
199
  );
200
200
  throw new Error("Script failed");
201
201
  }
@@ -1,4 +1,5 @@
1
1
  import { defineAction } from "@agent-native/core";
2
+ import { resolveSecret } from "@agent-native/core/server";
2
3
  import type { GeneratedSlide } from "@shared/api";
3
4
  import { z } from "zod";
4
5
 
@@ -21,9 +22,10 @@ export default defineAction({
21
22
  .describe("Whether to include image prompts (default: true)"),
22
23
  }),
23
24
  run: async (args) => {
24
- if (!process.env.GEMINI_API_KEY) {
25
+ const apiKey = await resolveSecret("GEMINI_API_KEY");
26
+ if (!apiKey) {
25
27
  throw new Error(
26
- "Gemini API key not configured. Set GEMINI_API_KEY environment variable.",
28
+ "Gemini API key not configured. Save GEMINI_API_KEY in settings.",
27
29
  );
28
30
  }
29
31
 
@@ -37,7 +39,7 @@ export default defineAction({
37
39
  const includeImages = args.includeImages !== false;
38
40
 
39
41
  const { GoogleGenAI } = await import("@google/genai");
40
- const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
42
+ const client = new GoogleGenAI({ apiKey });
41
43
 
42
44
  const imageInstruction = includeImages
43
45
  ? `For slides where a visual would enhance the message, set the layout to "image" and provide an "imagePrompt" field with a detailed description of what image to generate. The imagePrompt should describe a professional, high-quality image that supports the slide content. Include imagePrompt for roughly 30-40% of slides (not the title slide).`
@@ -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({
@@ -9,11 +10,11 @@ export default defineAction({
9
10
  run: async () => {
10
11
  const { getConfiguredProviders } =
11
12
  await import("../server/handlers/image-providers/index.js");
12
- const configured = getConfiguredProviders();
13
- const geminiStatus = process.env.GEMINI_API_KEY
13
+ const configured = await getConfiguredProviders();
14
+ const geminiStatus = (await resolveSecret("GEMINI_API_KEY"))
14
15
  ? "Configured"
15
16
  : "Not configured";
16
- const openaiStatus = process.env.OPENAI_API_KEY
17
+ const openaiStatus = (await resolveSecret("OPENAI_API_KEY"))
17
18
  ? "Configured"
18
19
  : "Not configured";
19
20
  const autoProvider =
@@ -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({
@@ -18,12 +19,14 @@ export default defineAction({
18
19
  throw new Error("--query is required");
19
20
  }
20
21
 
21
- const apiKey = process.env.GOOGLE_API_KEY;
22
- const cx = process.env.GOOGLE_SEARCH_CX;
22
+ const [apiKey, cx] = await Promise.all([
23
+ resolveSecret("GOOGLE_API_KEY"),
24
+ resolveSecret("GOOGLE_SEARCH_CX"),
25
+ ]);
23
26
 
24
27
  if (!apiKey || !cx) {
25
28
  throw new Error(
26
- "GOOGLE_API_KEY and GOOGLE_SEARCH_CX environment variables are required.",
29
+ "GOOGLE_API_KEY and GOOGLE_SEARCH_CX must be saved in settings.",
27
30
  );
28
31
  }
29
32
 
@@ -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({
@@ -13,12 +14,14 @@ export default defineAction({
13
14
  throw new Error("Missing query parameter 'q'");
14
15
  }
15
16
 
16
- const apiKey = process.env.GOOGLE_API_KEY;
17
- const cx = process.env.GOOGLE_SEARCH_CX;
17
+ const [apiKey, cx] = await Promise.all([
18
+ resolveSecret("GOOGLE_API_KEY"),
19
+ resolveSecret("GOOGLE_SEARCH_CX"),
20
+ ]);
18
21
 
19
22
  if (!apiKey || !cx) {
20
23
  throw new Error(
21
- "Google Search not configured. Set GOOGLE_API_KEY and GOOGLE_SEARCH_CX environment variables.",
24
+ "Google Search not configured. Save GOOGLE_API_KEY and GOOGLE_SEARCH_CX in settings.",
22
25
  );
23
26
  }
24
27
 
@@ -1,4 +1,4 @@
1
- import { agentNativePath, useT } from "@agent-native/core/client";
1
+ import { useT } from "@agent-native/core/client";
2
2
  import {
3
3
  IconX,
4
4
  IconCheck,
@@ -106,63 +106,20 @@ export function CloudUpgrade({
106
106
  connectingRef.current = true;
107
107
 
108
108
  if (!dbUrl.trim()) {
109
- setErrorMsg("Database URL is required");
109
+ setErrorMsg(
110
+ "Database settings are deployment-level. Configure DATABASE_URL with your host and redeploy the app.",
111
+ );
110
112
  setStatus("error");
111
113
  connectingRef.current = false;
112
114
  return;
113
115
  }
114
116
 
115
117
  try {
116
- setStatus("saving");
118
+ setStatus("error");
117
119
  setErrorMsg("");
118
-
119
- const vars: Array<{ key: string; value: string }> = [
120
- { key: "DATABASE_URL", value: dbUrl.trim() },
121
- ];
122
- if (authToken.trim()) {
123
- vars.push({ key: "DATABASE_AUTH_TOKEN", value: authToken.trim() });
124
- }
125
-
126
- const saveRes = await fetch(agentNativePath("/_agent-native/env-vars"), {
127
- method: "POST",
128
- headers: { "Content-Type": "application/json" },
129
- body: JSON.stringify({ vars }),
130
- });
131
-
132
- if (!saveRes.ok) {
133
- const data = await saveRes.json().catch(() => ({}));
134
- throw new Error(data.error || "Failed to save credentials");
135
- }
136
-
137
- // Poll db-health until it returns ok
138
- setStatus("polling");
139
- let ok = false;
140
- for (let i = 0; i < 30; i++) {
141
- await new Promise((r) => setTimeout(r, 1000));
142
- try {
143
- const healthRes = await fetch(
144
- agentNativePath("/_agent-native/actions/db-health"),
145
- );
146
- const health = await healthRes.json();
147
- if (health.ok && health.local === false) {
148
- ok = true;
149
- break;
150
- }
151
- } catch {
152
- // Keep polling
153
- }
154
- }
155
-
156
- if (!ok) {
157
- throw new Error(
158
- "Database connection failed after 30 attempts. Check your credentials.",
159
- );
160
- }
161
-
162
- setStatus("success");
163
- setTimeout(() => {
164
- window.location.reload();
165
- }, 1500);
120
+ throw new Error(
121
+ "Database settings are deployment-level. Configure DATABASE_URL and DATABASE_AUTH_TOKEN with your host, redeploy, then check sharing again.",
122
+ );
166
123
  } catch (e) {
167
124
  setErrorMsg(
168
125
  e instanceof Error ? e.message : t("raw.cloudConnectionFailed"),
@@ -10,7 +10,6 @@ const pageTitleKeys: Record<string, string> = {
10
10
  "/": "header.decks",
11
11
  "/design-systems": "header.designSystems",
12
12
  "/settings": "header.settings",
13
- "/team": "header.team",
14
13
  "/extensions": "header.extensions",
15
14
  };
16
15
 
@@ -10,7 +10,6 @@ import {
10
10
  IconStack2,
11
11
  IconPalette,
12
12
  IconSettings,
13
- IconUsers,
14
13
  IconLayoutSidebarLeftCollapse,
15
14
  IconLayoutSidebarLeftExpand,
16
15
  } from "@tabler/icons-react";
@@ -31,7 +30,6 @@ const navItems = [
31
30
  href: "/design-systems",
32
31
  },
33
32
  { icon: IconSettings, labelKey: "navigation.settings", href: "/settings" },
34
- { icon: IconUsers, labelKey: "navigation.team", href: "/team" },
35
33
  ];
36
34
 
37
35
  interface SidebarProps {
@@ -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,60 +30,59 @@ 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("navigation.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>
70
-
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
- <ChangelogSettingsCard markdown={changelog} />
86
- </main>
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>
71
+ </div>
72
+ }
73
+ team={
74
+ <div className="mx-auto w-full max-w-3xl">
75
+ <TeamPage
76
+ showTitle={false}
77
+ createOrgDescription={t("raw.teamDescription")}
78
+ />
79
+ </div>
80
+ }
81
+ whatsNew={
82
+ <div className="mx-auto w-full max-w-3xl">
83
+ <ChangelogSettingsCard markdown={changelog} />
84
+ </div>
85
+ }
86
+ />
87
87
  );
88
88
  }
@@ -1,7 +1,5 @@
1
- import { useT } from "@agent-native/core/client";
2
- import { TeamPage } from "@agent-native/core/client/org";
1
+ import { Navigate } from "react-router";
3
2
 
4
- import { useSetPageTitle } from "@/components/layout/HeaderActions";
5
3
  import messages from "@/i18n/en-US";
6
4
 
7
5
  export function meta() {
@@ -9,13 +7,5 @@ export function meta() {
9
7
  }
10
8
 
11
9
  export default function TeamRoute() {
12
- const t = useT();
13
- useSetPageTitle(t("navigation.team"));
14
- return (
15
- <div className="flex-1 overflow-y-auto">
16
- <main className="max-w-6xl mx-auto px-4 sm:px-6 py-6 sm:py-10">
17
- <TeamPage createOrgDescription={t("raw.teamDescription")} />
18
- </main>
19
- </div>
20
- );
10
+ return <Navigate to="/settings#team" replace />;
21
11
  }
@@ -58,12 +58,12 @@ export const getGoogleDocsAuthUrlHandler = defineEventHandler(
58
58
  return { error: "not_authenticated" };
59
59
  }
60
60
 
61
- if (!isGoogleDocsOAuthConfigured()) {
61
+ if (!(await isGoogleDocsOAuthConfigured(owner))) {
62
62
  setResponseStatus(event, 422);
63
63
  return {
64
64
  error: "missing_credentials",
65
65
  message:
66
- "Google OAuth credentials are not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.",
66
+ "Google OAuth credentials are not configured. Save GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in settings.",
67
67
  };
68
68
  }
69
69
 
@@ -96,7 +96,7 @@ export const getGoogleDocsAuthUrlHandler = defineEventHandler(
96
96
  returnUrl,
97
97
  flowId,
98
98
  });
99
- const url = getGoogleDocsAuthUrl(redirectUri, state);
99
+ const url = await getGoogleDocsAuthUrl(redirectUri, state, owner);
100
100
  if (q.redirect === "1") {
101
101
  return sendRedirect(event, url, 302);
102
102
  }
@@ -170,9 +170,9 @@ export const getGoogleDocsStatus = defineEventHandler(
170
170
 
171
171
  try {
172
172
  const accounts = await listGoogleDocsAccounts(owner);
173
- const picker = getGooglePickerConfig();
173
+ const picker = await getGooglePickerConfig(owner);
174
174
  return {
175
- configured: isGoogleDocsOAuthConfigured(),
175
+ configured: await isGoogleDocsOAuthConfigured(owner),
176
176
  connected: accounts.length > 0,
177
177
  accounts,
178
178
  pickerConfigured: !!(picker.apiKey && picker.appId),
@@ -193,22 +193,22 @@ export const getGoogleDocsPickerToken = defineEventHandler(
193
193
  return { error: "not_authenticated" };
194
194
  }
195
195
 
196
- if (!isGoogleDocsOAuthConfigured()) {
196
+ if (!(await isGoogleDocsOAuthConfigured(owner))) {
197
197
  setResponseStatus(event, 422);
198
198
  return {
199
199
  error: "missing_credentials",
200
200
  message:
201
- "Google OAuth credentials are not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.",
201
+ "Google OAuth credentials are not configured. Save GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in settings.",
202
202
  };
203
203
  }
204
204
 
205
- const picker = getGooglePickerConfig();
205
+ const picker = await getGooglePickerConfig(owner);
206
206
  if (!picker.apiKey || !picker.appId) {
207
207
  setResponseStatus(event, 422);
208
208
  return {
209
209
  error: "missing_picker_config",
210
210
  message:
211
- "Google Picker is not configured. Set GOOGLE_PICKER_API_KEY and GOOGLE_PICKER_APP_ID.",
211
+ "Google Picker is not configured. Save GOOGLE_PICKER_API_KEY and GOOGLE_PICKER_APP_ID in settings.",
212
212
  };
213
213
  }
214
214
 
@@ -1,3 +1,5 @@
1
+ import { resolveSecret } from "@agent-native/core/server";
2
+
1
3
  interface ReferenceImage {
2
4
  data: string; // base64
3
5
  mimeType: string;
@@ -35,7 +37,9 @@ export async function generateWithGemini(
35
37
  context?: { slideContent?: string; deckText?: string },
36
38
  ): Promise<{ imageData: Buffer; mimeType: string }> {
37
39
  const { GoogleGenAI } = await import("@google/genai");
38
- const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
40
+ const apiKey = await resolveSecret("GEMINI_API_KEY");
41
+ if (!apiKey) throw new Error("GEMINI_API_KEY not configured");
42
+ const client = new GoogleGenAI({ apiKey });
39
43
 
40
44
  // Randomly select 4 reference images for better style matching per generation
41
45
  const shuffled = [...referenceImages].sort(() => Math.random() - 0.5);
@@ -1,3 +1,5 @@
1
+ import { resolveSecret } from "@agent-native/core/server";
2
+
1
3
  import type {
2
4
  ImageProvider,
3
5
  ImageProviderConfig,
@@ -12,6 +14,10 @@ export class GeminiProvider implements ImageProvider {
12
14
  return !!process.env.GEMINI_API_KEY;
13
15
  }
14
16
 
17
+ async isConfiguredForRequest(): Promise<boolean> {
18
+ return !!(await resolveSecret("GEMINI_API_KEY"));
19
+ }
20
+
15
21
  async generate(
16
22
  prompt: string,
17
23
  referenceImages: ReferenceImage[] = [],
@@ -19,7 +25,9 @@ export class GeminiProvider implements ImageProvider {
19
25
  config?: ImageProviderConfig,
20
26
  ): Promise<ImageGenerationResult> {
21
27
  const { GoogleGenAI } = await import("@google/genai");
22
- const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
28
+ const apiKey = await resolveSecret("GEMINI_API_KEY");
29
+ if (!apiKey) throw new Error("GEMINI_API_KEY not configured");
30
+ const client = new GoogleGenAI({ apiKey });
23
31
 
24
32
  // Randomly select up to 4 reference images for style matching
25
33
  const shuffled = [...referenceImages].sort(() => Math.random() - 0.5);
@@ -7,12 +7,19 @@ const providers: Record<string, () => ImageProvider> = {
7
7
  openai: () => new OpenAIProvider(),
8
8
  };
9
9
 
10
- export function getProvider(name?: string): ImageProvider {
10
+ async function providerIsConfigured(provider: ImageProvider): Promise<boolean> {
11
+ if (provider.isConfiguredForRequest) {
12
+ return provider.isConfiguredForRequest();
13
+ }
14
+ return provider.isConfigured();
15
+ }
16
+
17
+ export async function getProvider(name?: string): Promise<ImageProvider> {
11
18
  if (name && name !== "auto") {
12
19
  const factory = providers[name];
13
20
  if (!factory) throw new Error(`Unknown image provider: ${name}`);
14
21
  const p = factory();
15
- if (!p.isConfigured())
22
+ if (!(await providerIsConfigured(p)))
16
23
  throw new Error(`Provider ${name} not configured (missing API key)`);
17
24
  return p;
18
25
  }
@@ -20,18 +27,21 @@ export function getProvider(name?: string): ImageProvider {
20
27
  // Auto: prefer gemini (has reference image support), fall back to openai
21
28
  for (const key of ["gemini", "openai"]) {
22
29
  const p = providers[key]!();
23
- if (p.isConfigured()) return p;
30
+ if (await providerIsConfigured(p)) return p;
24
31
  }
25
32
 
26
33
  throw new Error(
27
- "No image generation provider configured. Set GEMINI_API_KEY or OPENAI_API_KEY.",
34
+ "No image generation provider configured. Save GEMINI_API_KEY or OPENAI_API_KEY in settings.",
28
35
  );
29
36
  }
30
37
 
31
- export function getConfiguredProviders(): ImageProvider[] {
32
- return Object.values(providers)
33
- .map((f) => f())
34
- .filter((p) => p.isConfigured());
38
+ export async function getConfiguredProviders(): Promise<ImageProvider[]> {
39
+ const result: ImageProvider[] = [];
40
+ for (const factory of Object.values(providers)) {
41
+ const provider = factory();
42
+ if (await providerIsConfigured(provider)) result.push(provider);
43
+ }
44
+ return result;
35
45
  }
36
46
 
37
47
  export {
@@ -1,3 +1,5 @@
1
+ import { resolveSecret } from "@agent-native/core/server";
2
+
1
3
  import type {
2
4
  ImageProvider,
3
5
  ImageProviderConfig,
@@ -12,14 +14,18 @@ export class OpenAIProvider implements ImageProvider {
12
14
  return !!process.env.OPENAI_API_KEY;
13
15
  }
14
16
 
17
+ async isConfiguredForRequest(): Promise<boolean> {
18
+ return !!(await resolveSecret("OPENAI_API_KEY"));
19
+ }
20
+
15
21
  async generate(
16
22
  prompt: string,
17
23
  referenceImages: ReferenceImage[] = [],
18
24
  context?: { slideContent?: string; deckText?: string },
19
25
  config?: ImageProviderConfig,
20
26
  ): Promise<ImageGenerationResult> {
21
- const apiKey = process.env.OPENAI_API_KEY;
22
- if (!apiKey) throw new Error("OPENAI_API_KEY not set");
27
+ const apiKey = await resolveSecret("OPENAI_API_KEY");
28
+ if (!apiKey) throw new Error("OPENAI_API_KEY not configured");
23
29
 
24
30
  // OpenAI doesn't support reference images natively — fold style description into prompt
25
31
  const fullPrompt = buildOpenAIPrompt(prompt, referenceImages, context);
@@ -87,8 +93,8 @@ export class OpenAIProvider implements ImageProvider {
87
93
  prompt: string,
88
94
  config?: ImageProviderConfig,
89
95
  ): Promise<ImageGenerationResult> {
90
- const apiKey = process.env.OPENAI_API_KEY;
91
- if (!apiKey) throw new Error("OPENAI_API_KEY not set");
96
+ const apiKey = await resolveSecret("OPENAI_API_KEY");
97
+ if (!apiKey) throw new Error("OPENAI_API_KEY not configured");
92
98
 
93
99
  const size = mapSize(config?.aspectRatio, config?.size);
94
100
  const quality = mapQuality(config?.quality);
@@ -20,6 +20,7 @@ export interface ReferenceImage {
20
20
  export interface ImageProvider {
21
21
  name: string;
22
22
  isConfigured(): boolean;
23
+ isConfiguredForRequest?(): Promise<boolean>;
23
24
  generate(
24
25
  prompt: string,
25
26
  referenceImages?: ReferenceImage[],