@agent-native/core 0.79.17 → 0.79.19

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 (355) 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/i18n.tsx +77 -65
  22. package/corpus/core/src/client/index.ts +7 -1
  23. package/corpus/core/src/client/org/OrgSwitcher.tsx +5 -5
  24. package/corpus/core/src/client/org/TeamPage.tsx +11 -3
  25. package/corpus/core/src/client/settings/SettingsTabsPage.tsx +216 -0
  26. package/corpus/core/src/client/settings/index.ts +5 -0
  27. package/corpus/core/src/file-upload/index.ts +1 -0
  28. package/corpus/core/src/file-upload/registry.ts +22 -6
  29. package/corpus/core/src/file-upload/types.ts +6 -1
  30. package/corpus/core/src/integrations/adapters/email.ts +26 -18
  31. package/corpus/core/src/integrations/adapters/slack.ts +8 -7
  32. package/corpus/core/src/integrations/adapters/telegram.ts +9 -11
  33. package/corpus/core/src/integrations/adapters/whatsapp.ts +12 -9
  34. package/corpus/core/src/integrations/plugin.ts +79 -13
  35. package/corpus/core/src/onboarding/default-steps.ts +6 -3
  36. package/corpus/core/src/onboarding/types.ts +1 -1
  37. package/corpus/core/src/org/handlers.ts +1 -1
  38. package/corpus/core/src/server/agent-chat-plugin.ts +4 -7
  39. package/corpus/core/src/server/better-auth-instance.ts +19 -62
  40. package/corpus/core/src/server/core-routes-plugin.ts +93 -180
  41. package/corpus/core/src/server/create-server.ts +55 -116
  42. package/corpus/core/src/server/email-actions.ts +3 -6
  43. package/corpus/core/src/server/email.ts +52 -17
  44. package/corpus/core/src/server/index.ts +2 -1
  45. package/corpus/core/src/server/scoped-key-storage.ts +223 -0
  46. package/corpus/core/src/shared/agent-env.ts +3 -3
  47. package/corpus/core/src/sharing/actions/share-resource.ts +1 -1
  48. package/corpus/core/src/styles/agent-native.css +47 -3
  49. package/corpus/core/src/templates/workspace-root/AGENTS.md +3 -2
  50. package/corpus/core/src/templates/workspace-root/README.md +1 -1
  51. package/corpus/core/src/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
  52. package/corpus/core/src/terminal/pty-server.ts +3 -38
  53. package/corpus/core/src/triggers/dispatcher.ts +1 -2
  54. package/corpus/templates/.retired/issues/package.json +7 -0
  55. package/corpus/templates/.retired/meeting-notes/package.json +7 -0
  56. package/corpus/templates/.retired/recruiting/package.json +7 -0
  57. package/corpus/templates/.retired/scheduling/package.json +7 -0
  58. package/corpus/templates/.retired/voice/package.json +7 -0
  59. package/corpus/templates/analytics/app/components/layout/Header.tsx +0 -1
  60. package/corpus/templates/analytics/app/components/layout/Sidebar.tsx +1 -18
  61. package/corpus/templates/analytics/app/global.css +15 -0
  62. package/corpus/templates/analytics/app/i18n/zh-TW.ts +7 -1
  63. package/corpus/templates/analytics/app/i18n-data.ts +71 -2
  64. package/corpus/templates/analytics/app/pages/Ask.tsx +1 -1
  65. package/corpus/templates/analytics/app/pages/Settings.tsx +120 -73
  66. package/corpus/templates/analytics/app/pages/sessions/SessionsPage.tsx +0 -11
  67. package/corpus/templates/analytics/app/routes/catalog.tsx +33 -176
  68. package/corpus/templates/analytics/app/routes/team.tsx +3 -2
  69. package/corpus/templates/analytics/changelog/2026-06-26-dashboard-templates-are-tucked-into-settings-and-show-simple.md +6 -0
  70. package/corpus/templates/analytics/changelog/2026-06-26-the-ask-tab-uses-a-softer-dark-gray-canvas-while-sidebar-cha.md +6 -0
  71. package/corpus/templates/analytics/changelog/2026-06-26-the-sessions-page-shows-a-single-page-title-instead-of-repea.md +6 -0
  72. package/corpus/templates/analytics/server/lib/dashboard-catalog.ts +37 -28
  73. package/corpus/templates/assets/app/routes/settings.tsx +65 -43
  74. package/corpus/templates/assets/app/routes/team.tsx +2 -10
  75. package/corpus/templates/brain/app/routes/settings.tsx +390 -358
  76. package/corpus/templates/brain/app/routes/team.tsx +2 -8
  77. package/corpus/templates/calendar/actions/db-connect.ts +5 -29
  78. package/corpus/templates/calendar/app/components/CloudUpgrade.tsx +8 -51
  79. package/corpus/templates/calendar/app/components/calendar/GoogleConnectBanner.tsx +2 -1
  80. package/corpus/templates/calendar/app/components/calendar/GoogleSetupWizard.tsx +4 -2
  81. package/corpus/templates/calendar/app/components/layout/Sidebar.tsx +0 -2
  82. package/corpus/templates/calendar/app/pages/Settings.tsx +304 -271
  83. package/corpus/templates/calendar/app/routes/_app.team.tsx +2 -17
  84. package/corpus/templates/calendar/server/handlers/google-auth.ts +22 -9
  85. package/corpus/templates/calendar/server/lib/booking-emails.ts +1 -1
  86. package/corpus/templates/calendar/server/lib/event-guest-notifications.ts +1 -1
  87. package/corpus/templates/calendar/server/lib/google-calendar.ts +48 -28
  88. package/corpus/templates/chat/app/components/layout/Header.tsx +0 -1
  89. package/corpus/templates/chat/app/hooks/use-navigation-state.ts +4 -2
  90. package/corpus/templates/chat/app/routes/settings.tsx +54 -54
  91. package/corpus/templates/chat/app/routes/team.tsx +2 -10
  92. package/corpus/templates/clips/.agents/skills/ai-video-tools/SKILL.md +7 -2
  93. package/corpus/templates/clips/.agents/skills/recording/SKILL.md +1 -1
  94. package/corpus/templates/clips/.agents/skills/video-sharing/SKILL.md +7 -0
  95. package/corpus/templates/clips/AGENTS.md +8 -0
  96. package/corpus/templates/clips/actions/invite-member.ts +1 -1
  97. package/corpus/templates/clips/actions/request-transcript.ts +1 -1
  98. package/corpus/templates/clips/app/components/library/library-layout.tsx +325 -333
  99. package/corpus/templates/clips/app/components/player/delete-recording-menu.tsx +80 -40
  100. package/corpus/templates/clips/app/components/player/transcript-panel.tsx +2 -0
  101. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +629 -643
  102. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +263 -158
  103. package/corpus/templates/clips/app/routes/share.$shareId.tsx +10 -2
  104. package/corpus/templates/clips/changelog/2026-06-26-long-desktop-recordings-are-checkpointed-so-macos-finalizati.md +6 -0
  105. package/corpus/templates/clips/changelog/2026-06-26-non-mac-desktop-recordings-wait-for-upload-transcription.md +6 -0
  106. package/corpus/templates/clips/changelog/2026-06-26-recording-details-button-stays-at-the-far-right-on-small-screen.md +6 -0
  107. package/corpus/templates/clips/changelog/2026-06-26-s3-compatible-storage-keys-now-save-securely-from-clips-sett.md +6 -0
  108. package/corpus/templates/clips/changelog/2026-06-26-shared-clip-links-guide-agents-through-processing-transcripts.md +6 -0
  109. package/corpus/templates/clips/changelog/2026-06-26-the-agent-sidebar-now-slides-in-smoothly-without-duplicate-e.md +6 -0
  110. package/corpus/templates/clips/changelog/2026-06-26-the-clip-details-sidebar-now-collapses-into-a-slide-out-pane.md +6 -0
  111. package/corpus/templates/clips/desktop/src/lib/recorder.ts +55 -3
  112. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +217 -5
  113. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  114. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +176 -5
  115. package/corpus/templates/clips/server/lib/public-agent-context.ts +31 -0
  116. package/corpus/templates/clips/server/lib/s3-upload-provider.ts +60 -14
  117. package/corpus/templates/clips/server/lib/video-storage.ts +37 -9
  118. package/corpus/templates/clips/server/routes/api/agent-transcript.json.get.ts +5 -0
  119. package/corpus/templates/content/app/components/layout/Header.tsx +0 -1
  120. package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +1 -0
  121. package/corpus/templates/content/app/routes/_app.settings.tsx +54 -55
  122. package/corpus/templates/content/app/routes/_app.team.tsx +2 -28
  123. package/corpus/templates/content/server/lib/notion.ts +43 -11
  124. package/corpus/templates/content/server/routes/api/notion/auth-url.get.ts +2 -2
  125. package/corpus/templates/content/server/routes/api/notion/status.get.ts +3 -3
  126. package/corpus/templates/design/app/routes/settings.tsx +60 -38
  127. package/corpus/templates/design/app/routes/team.tsx +2 -10
  128. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +2 -2
  129. package/corpus/templates/dispatch/app/routes/settings.tsx +70 -55
  130. package/corpus/templates/dispatch/app/routes/team.tsx +5 -1
  131. package/corpus/templates/forms/actions/db-connect.ts +7 -36
  132. package/corpus/templates/forms/actions/navigate.ts +2 -2
  133. package/corpus/templates/forms/app/components/CloudUpgrade.tsx +8 -47
  134. package/corpus/templates/forms/app/components/layout/Header.tsx +0 -1
  135. package/corpus/templates/forms/app/components/layout/Layout.tsx +42 -25
  136. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -76
  137. package/corpus/templates/forms/app/global.css +9 -25
  138. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +4 -4
  139. package/corpus/templates/forms/app/i18n/ar-SA.ts +1 -0
  140. package/corpus/templates/forms/app/i18n/de-DE.ts +1 -0
  141. package/corpus/templates/forms/app/i18n/en-US.ts +1 -0
  142. package/corpus/templates/forms/app/i18n/es-ES.ts +1 -0
  143. package/corpus/templates/forms/app/i18n/fr-FR.ts +1 -0
  144. package/corpus/templates/forms/app/i18n/hi-IN.ts +1 -0
  145. package/corpus/templates/forms/app/i18n/ja-JP.ts +1 -0
  146. package/corpus/templates/forms/app/i18n/ko-KR.ts +1 -0
  147. package/corpus/templates/forms/app/i18n/pt-BR.ts +1 -0
  148. package/corpus/templates/forms/app/i18n/zh-CN.ts +1 -0
  149. package/corpus/templates/forms/app/i18n/zh-TW.ts +1 -0
  150. package/corpus/templates/forms/app/lib/route-prewarm.ts +9 -8
  151. package/corpus/templates/forms/app/pages/AskPage.tsx +70 -0
  152. package/corpus/templates/forms/app/pages/FormsListPage.tsx +74 -81
  153. package/corpus/templates/forms/app/root.tsx +1 -1
  154. package/corpus/templates/forms/app/routes/_app.ask.tsx +14 -0
  155. package/corpus/templates/forms/app/routes/_app.settings.tsx +54 -54
  156. package/corpus/templates/forms/app/routes/_app.team.tsx +2 -9
  157. package/corpus/templates/forms/app/routes/_index.tsx +21 -130
  158. package/corpus/templates/forms/changelog/2026-06-26-ask-forms-opens-as-a-standard-app-tab-with-a-simpler-sidebar.md +6 -0
  159. package/corpus/templates/forms/changelog/2026-06-26-forms-are-shown-in-a-tighter-row-list-with-a-denser-sidebar.md +6 -0
  160. package/corpus/templates/forms/shared/navigation.ts +4 -2
  161. package/corpus/templates/macros/app/routes/settings.tsx +54 -54
  162. package/corpus/templates/macros/app/routes/team.tsx +2 -10
  163. package/corpus/templates/mail/actions/helpers.ts +2 -2
  164. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +2 -1
  165. package/corpus/templates/mail/app/pages/SettingsPage.tsx +5 -5
  166. package/corpus/templates/mail/app/routes/team.tsx +3 -2
  167. package/corpus/templates/mail/server/handlers/emails.ts +3 -2
  168. package/corpus/templates/mail/server/handlers/google-auth.ts +19 -12
  169. package/corpus/templates/mail/server/lib/automation-engine.ts +3 -2
  170. package/corpus/templates/mail/server/lib/email-state.ts +2 -3
  171. package/corpus/templates/mail/server/lib/google-auth.ts +28 -11
  172. package/corpus/templates/mail/server/lib/jobs.ts +3 -2
  173. package/corpus/templates/mail/server/onboarding.ts +9 -6
  174. package/corpus/templates/mail/server/routes/api/attachments.get.ts +3 -3
  175. package/corpus/templates/plan/actions/request-plan-access.ts +1 -1
  176. package/corpus/templates/plan/app/components/layout/Header.tsx +0 -1
  177. package/corpus/templates/plan/app/components/plan/CanvasArea.tsx +56 -4
  178. package/corpus/templates/plan/app/global.css +8 -3
  179. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +4 -2
  180. package/corpus/templates/plan/app/lib/route-prewarm.ts +0 -4
  181. package/corpus/templates/plan/app/pages/PlansPage.tsx +1 -1
  182. package/corpus/templates/plan/app/routes/settings.tsx +75 -73
  183. package/corpus/templates/plan/app/routes/team.tsx +2 -8
  184. package/corpus/templates/plan/changelog/2026-06-26-canvas-grid-panning-now-stays-smooth-and-fills-the-workspace.md +6 -0
  185. package/corpus/templates/plan/server/lib/comment-notifications.ts +1 -1
  186. package/corpus/templates/slides/actions/check-image-gen.ts +2 -1
  187. package/corpus/templates/slides/actions/db-connect.ts +7 -45
  188. package/corpus/templates/slides/actions/edit-image.ts +6 -3
  189. package/corpus/templates/slides/actions/generate-image-api.ts +1 -1
  190. package/corpus/templates/slides/actions/generate-image.ts +2 -2
  191. package/corpus/templates/slides/actions/generate-slides-ai.ts +5 -3
  192. package/corpus/templates/slides/actions/image-gen-status.ts +4 -3
  193. package/corpus/templates/slides/actions/image-search.ts +6 -3
  194. package/corpus/templates/slides/actions/search-images.ts +6 -3
  195. package/corpus/templates/slides/app/components/CloudUpgrade.tsx +8 -51
  196. package/corpus/templates/slides/app/components/layout/Header.tsx +0 -1
  197. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
  198. package/corpus/templates/slides/app/routes/settings.tsx +54 -54
  199. package/corpus/templates/slides/app/routes/team.tsx +2 -12
  200. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +9 -9
  201. package/corpus/templates/slides/server/handlers/image-gen.ts +5 -1
  202. package/corpus/templates/slides/server/handlers/image-providers/gemini.ts +9 -1
  203. package/corpus/templates/slides/server/handlers/image-providers/index.ts +18 -8
  204. package/corpus/templates/slides/server/handlers/image-providers/openai.ts +10 -4
  205. package/corpus/templates/slides/server/handlers/image-providers/types.ts +1 -0
  206. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +59 -34
  207. package/corpus/templates/slides/server/register-secrets.ts +60 -0
  208. package/corpus/templates/videos/actions/db-connect.ts +7 -45
  209. package/corpus/templates/videos/app/components/CloudUpgrade.tsx +8 -51
  210. package/corpus/templates/videos/app/components/Sidebar.tsx +1 -9
  211. package/corpus/templates/videos/app/components/layout/Header.tsx +0 -1
  212. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -3
  213. package/corpus/templates/videos/app/routes/settings.tsx +54 -54
  214. package/corpus/templates/videos/app/routes/team.tsx +2 -8
  215. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  216. package/dist/agent/engine/builder-engine.js +8 -3
  217. package/dist/agent/engine/builder-engine.js.map +1 -1
  218. package/dist/cli/mcp.d.ts.map +1 -1
  219. package/dist/cli/mcp.js +3 -4
  220. package/dist/cli/mcp.js.map +1 -1
  221. package/dist/client/AssistantChat.d.ts.map +1 -1
  222. package/dist/client/AssistantChat.js +6 -2
  223. package/dist/client/AssistantChat.js.map +1 -1
  224. package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
  225. package/dist/client/chat/markdown-renderer.js +1 -0
  226. package/dist/client/chat/markdown-renderer.js.map +1 -1
  227. package/dist/client/i18n.d.ts.map +1 -1
  228. package/dist/client/i18n.js +20 -9
  229. package/dist/client/i18n.js.map +1 -1
  230. package/dist/client/index.d.ts +1 -1
  231. package/dist/client/index.d.ts.map +1 -1
  232. package/dist/client/index.js +1 -1
  233. package/dist/client/index.js.map +1 -1
  234. package/dist/client/org/OrgSwitcher.d.ts +3 -3
  235. package/dist/client/org/OrgSwitcher.js +2 -2
  236. package/dist/client/org/OrgSwitcher.js.map +1 -1
  237. package/dist/client/org/TeamPage.d.ts +6 -1
  238. package/dist/client/org/TeamPage.d.ts.map +1 -1
  239. package/dist/client/org/TeamPage.js +2 -2
  240. package/dist/client/org/TeamPage.js.map +1 -1
  241. package/dist/client/settings/SettingsTabsPage.d.ts +27 -0
  242. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -0
  243. package/dist/client/settings/SettingsTabsPage.js +108 -0
  244. package/dist/client/settings/SettingsTabsPage.js.map +1 -0
  245. package/dist/client/settings/index.d.ts +1 -0
  246. package/dist/client/settings/index.d.ts.map +1 -1
  247. package/dist/client/settings/index.js +1 -0
  248. package/dist/client/settings/index.js.map +1 -1
  249. package/dist/file-upload/index.d.ts +1 -1
  250. package/dist/file-upload/index.d.ts.map +1 -1
  251. package/dist/file-upload/index.js +1 -1
  252. package/dist/file-upload/index.js.map +1 -1
  253. package/dist/file-upload/registry.d.ts +1 -0
  254. package/dist/file-upload/registry.d.ts.map +1 -1
  255. package/dist/file-upload/registry.js +24 -6
  256. package/dist/file-upload/registry.js.map +1 -1
  257. package/dist/file-upload/types.d.ts +6 -1
  258. package/dist/file-upload/types.d.ts.map +1 -1
  259. package/dist/file-upload/types.js.map +1 -1
  260. package/dist/integrations/adapters/email.d.ts.map +1 -1
  261. package/dist/integrations/adapters/email.js +18 -18
  262. package/dist/integrations/adapters/email.js.map +1 -1
  263. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  264. package/dist/integrations/adapters/slack.js +8 -7
  265. package/dist/integrations/adapters/slack.js.map +1 -1
  266. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  267. package/dist/integrations/adapters/telegram.js +9 -9
  268. package/dist/integrations/adapters/telegram.js.map +1 -1
  269. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  270. package/dist/integrations/adapters/whatsapp.js +10 -9
  271. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  272. package/dist/integrations/plugin.d.ts.map +1 -1
  273. package/dist/integrations/plugin.js +47 -13
  274. package/dist/integrations/plugin.js.map +1 -1
  275. package/dist/notifications/routes.d.ts +3 -3
  276. package/dist/observability/routes.d.ts +6 -6
  277. package/dist/onboarding/default-steps.d.ts.map +1 -1
  278. package/dist/onboarding/default-steps.js +6 -5
  279. package/dist/onboarding/default-steps.js.map +1 -1
  280. package/dist/onboarding/types.d.ts +1 -1
  281. package/dist/onboarding/types.d.ts.map +1 -1
  282. package/dist/onboarding/types.js.map +1 -1
  283. package/dist/org/handlers.js +1 -1
  284. package/dist/org/handlers.js.map +1 -1
  285. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  286. package/dist/server/agent-chat-plugin.js +4 -6
  287. package/dist/server/agent-chat-plugin.js.map +1 -1
  288. package/dist/server/agent-engine-api-key-route.d.ts +2 -2
  289. package/dist/server/better-auth-instance.d.ts.map +1 -1
  290. package/dist/server/better-auth-instance.js +17 -56
  291. package/dist/server/better-auth-instance.js.map +1 -1
  292. package/dist/server/core-routes-plugin.d.ts +1 -1
  293. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  294. package/dist/server/core-routes-plugin.js +67 -153
  295. package/dist/server/core-routes-plugin.js.map +1 -1
  296. package/dist/server/create-server.d.ts +3 -9
  297. package/dist/server/create-server.d.ts.map +1 -1
  298. package/dist/server/create-server.js +37 -91
  299. package/dist/server/create-server.js.map +1 -1
  300. package/dist/server/email-actions.d.ts +2 -3
  301. package/dist/server/email-actions.d.ts.map +1 -1
  302. package/dist/server/email-actions.js +3 -6
  303. package/dist/server/email-actions.js.map +1 -1
  304. package/dist/server/email.d.ts +3 -3
  305. package/dist/server/email.d.ts.map +1 -1
  306. package/dist/server/email.js +40 -19
  307. package/dist/server/email.js.map +1 -1
  308. package/dist/server/index.d.ts +3 -3
  309. package/dist/server/index.d.ts.map +1 -1
  310. package/dist/server/index.js +3 -3
  311. package/dist/server/index.js.map +1 -1
  312. package/dist/server/scoped-key-storage.d.ts +22 -0
  313. package/dist/server/scoped-key-storage.d.ts.map +1 -0
  314. package/dist/server/scoped-key-storage.js +152 -0
  315. package/dist/server/scoped-key-storage.js.map +1 -0
  316. package/dist/shared/agent-env.d.ts +3 -3
  317. package/dist/shared/agent-env.d.ts.map +1 -1
  318. package/dist/shared/agent-env.js +3 -3
  319. package/dist/shared/agent-env.js.map +1 -1
  320. package/dist/sharing/actions/share-resource.js +1 -1
  321. package/dist/sharing/actions/share-resource.js.map +1 -1
  322. package/dist/styles/agent-native.css +47 -3
  323. package/dist/templates/workspace-root/AGENTS.md +3 -2
  324. package/dist/templates/workspace-root/README.md +1 -1
  325. package/dist/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
  326. package/dist/terminal/pty-server.d.ts.map +1 -1
  327. package/dist/terminal/pty-server.js +3 -36
  328. package/dist/terminal/pty-server.js.map +1 -1
  329. package/dist/triggers/dispatcher.js +1 -1
  330. package/dist/triggers/dispatcher.js.map +1 -1
  331. package/docs/content/file-uploads.md +11 -4
  332. package/docs/content/locales/ar-SA/multi-app-workspace.md +3 -3
  333. package/docs/content/locales/de-DE/multi-app-workspace.md +3 -3
  334. package/docs/content/locales/es-ES/multi-app-workspace.md +3 -3
  335. package/docs/content/locales/fr-FR/multi-app-workspace.md +3 -3
  336. package/docs/content/locales/hi-IN/multi-app-workspace.md +3 -3
  337. package/docs/content/locales/ja-JP/multi-app-workspace.md +3 -3
  338. package/docs/content/locales/ko-KR/multi-app-workspace.md +3 -3
  339. package/docs/content/locales/pt-BR/multi-app-workspace.md +3 -3
  340. package/docs/content/locales/zh-CN/multi-app-workspace.md +3 -3
  341. package/docs/content/locales/zh-TW/multi-app-workspace.md +3 -3
  342. package/docs/content/multi-app-workspace.md +3 -3
  343. package/docs/content/template-clips.md +14 -5
  344. package/package.json +1 -1
  345. package/src/templates/workspace-root/AGENTS.md +3 -2
  346. package/src/templates/workspace-root/README.md +1 -1
  347. package/src/templates/workspace-root/scripts/repair-workspace-org.ts +29 -90
  348. package/corpus/core/src/server/env-var-writes.ts +0 -16
  349. package/corpus/templates/analytics/app/pages/Team.tsx +0 -9
  350. package/corpus/templates/calendar/app/pages/Team.tsx +0 -12
  351. package/corpus/templates/mail/app/pages/Team.tsx +0 -17
  352. package/dist/server/env-var-writes.d.ts +0 -10
  353. package/dist/server/env-var-writes.d.ts.map +0 -1
  354. package/dist/server/env-var-writes.js +0 -18
  355. package/dist/server/env-var-writes.js.map +0 -1
@@ -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
  }
@@ -0,0 +1,6 @@
1
+ ---
2
+ type: fixed
3
+ date: 2026-06-26
4
+ ---
5
+
6
+ Canvas grid panning now stays smooth and fills the workspace while navigating large plans.
@@ -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
 
@@ -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);