@agent-native/core 0.79.17 → 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 +8 -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 +47 -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/player/transcript-panel.tsx +2 -0
  95. package/corpus/templates/clips/app/routes/_app.settings._index.tsx +629 -643
  96. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +219 -155
  97. package/corpus/templates/clips/changelog/2026-06-26-long-desktop-recordings-are-checkpointed-so-macos-finalizati.md +6 -0
  98. package/corpus/templates/clips/changelog/2026-06-26-non-mac-desktop-recordings-wait-for-upload-transcription.md +6 -0
  99. package/corpus/templates/clips/changelog/2026-06-26-s3-compatible-storage-keys-now-save-securely-from-clips-sett.md +6 -0
  100. package/corpus/templates/clips/changelog/2026-06-26-shared-clip-links-guide-agents-through-processing-transcripts.md +6 -0
  101. package/corpus/templates/clips/changelog/2026-06-26-the-clip-details-sidebar-now-collapses-into-a-slide-out-pane.md +6 -0
  102. package/corpus/templates/clips/desktop/src/lib/recorder.ts +55 -3
  103. package/corpus/templates/clips/desktop/src/lib/transcription-capture.ts +217 -5
  104. package/corpus/templates/clips/desktop/src-tauri/src/lib.rs +1 -0
  105. package/corpus/templates/clips/desktop/src-tauri/src/native_screen.rs +176 -5
  106. package/corpus/templates/clips/server/lib/public-agent-context.ts +31 -0
  107. package/corpus/templates/clips/server/lib/s3-upload-provider.ts +60 -14
  108. package/corpus/templates/clips/server/lib/video-storage.ts +37 -9
  109. package/corpus/templates/clips/server/routes/api/agent-transcript.json.get.ts +5 -0
  110. package/corpus/templates/content/app/components/layout/Header.tsx +0 -1
  111. package/corpus/templates/content/app/components/sidebar/NotionButton.tsx +1 -0
  112. package/corpus/templates/content/app/routes/_app.settings.tsx +54 -55
  113. package/corpus/templates/content/app/routes/_app.team.tsx +2 -28
  114. package/corpus/templates/content/server/lib/notion.ts +43 -11
  115. package/corpus/templates/content/server/routes/api/notion/auth-url.get.ts +2 -2
  116. package/corpus/templates/content/server/routes/api/notion/status.get.ts +3 -3
  117. package/corpus/templates/design/app/routes/settings.tsx +60 -38
  118. package/corpus/templates/design/app/routes/team.tsx +2 -10
  119. package/corpus/templates/dispatch/app/hooks/use-navigation-state.ts +2 -2
  120. package/corpus/templates/dispatch/app/routes/settings.tsx +70 -55
  121. package/corpus/templates/dispatch/app/routes/team.tsx +5 -1
  122. package/corpus/templates/forms/actions/db-connect.ts +7 -36
  123. package/corpus/templates/forms/actions/navigate.ts +2 -2
  124. package/corpus/templates/forms/app/components/CloudUpgrade.tsx +8 -47
  125. package/corpus/templates/forms/app/components/layout/Header.tsx +0 -1
  126. package/corpus/templates/forms/app/components/layout/Layout.tsx +42 -25
  127. package/corpus/templates/forms/app/components/layout/Sidebar.tsx +35 -76
  128. package/corpus/templates/forms/app/global.css +9 -25
  129. package/corpus/templates/forms/app/hooks/use-navigation-state.ts +4 -4
  130. package/corpus/templates/forms/app/i18n/ar-SA.ts +1 -0
  131. package/corpus/templates/forms/app/i18n/de-DE.ts +1 -0
  132. package/corpus/templates/forms/app/i18n/en-US.ts +1 -0
  133. package/corpus/templates/forms/app/i18n/es-ES.ts +1 -0
  134. package/corpus/templates/forms/app/i18n/fr-FR.ts +1 -0
  135. package/corpus/templates/forms/app/i18n/hi-IN.ts +1 -0
  136. package/corpus/templates/forms/app/i18n/ja-JP.ts +1 -0
  137. package/corpus/templates/forms/app/i18n/ko-KR.ts +1 -0
  138. package/corpus/templates/forms/app/i18n/pt-BR.ts +1 -0
  139. package/corpus/templates/forms/app/i18n/zh-CN.ts +1 -0
  140. package/corpus/templates/forms/app/i18n/zh-TW.ts +1 -0
  141. package/corpus/templates/forms/app/lib/route-prewarm.ts +9 -8
  142. package/corpus/templates/forms/app/pages/AskPage.tsx +70 -0
  143. package/corpus/templates/forms/app/pages/FormsListPage.tsx +74 -81
  144. package/corpus/templates/forms/app/root.tsx +1 -1
  145. package/corpus/templates/forms/app/routes/_app.ask.tsx +14 -0
  146. package/corpus/templates/forms/app/routes/_app.settings.tsx +54 -54
  147. package/corpus/templates/forms/app/routes/_app.team.tsx +2 -9
  148. package/corpus/templates/forms/app/routes/_index.tsx +21 -130
  149. package/corpus/templates/forms/changelog/2026-06-26-ask-forms-opens-as-a-standard-app-tab-with-a-simpler-sidebar.md +6 -0
  150. package/corpus/templates/forms/changelog/2026-06-26-forms-are-shown-in-a-tighter-row-list-with-a-denser-sidebar.md +6 -0
  151. package/corpus/templates/forms/shared/navigation.ts +4 -2
  152. package/corpus/templates/macros/app/routes/settings.tsx +54 -54
  153. package/corpus/templates/macros/app/routes/team.tsx +2 -10
  154. package/corpus/templates/mail/actions/helpers.ts +2 -2
  155. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +2 -1
  156. package/corpus/templates/mail/app/pages/SettingsPage.tsx +5 -5
  157. package/corpus/templates/mail/app/routes/team.tsx +3 -2
  158. package/corpus/templates/mail/server/handlers/emails.ts +3 -2
  159. package/corpus/templates/mail/server/handlers/google-auth.ts +19 -12
  160. package/corpus/templates/mail/server/lib/automation-engine.ts +3 -2
  161. package/corpus/templates/mail/server/lib/email-state.ts +2 -3
  162. package/corpus/templates/mail/server/lib/google-auth.ts +28 -11
  163. package/corpus/templates/mail/server/lib/jobs.ts +3 -2
  164. package/corpus/templates/mail/server/onboarding.ts +9 -6
  165. package/corpus/templates/mail/server/routes/api/attachments.get.ts +3 -3
  166. package/corpus/templates/plan/actions/request-plan-access.ts +1 -1
  167. package/corpus/templates/plan/app/components/layout/Header.tsx +0 -1
  168. package/corpus/templates/plan/app/hooks/use-navigation-state.ts +4 -2
  169. package/corpus/templates/plan/app/lib/route-prewarm.ts +0 -4
  170. package/corpus/templates/plan/app/routes/settings.tsx +75 -73
  171. package/corpus/templates/plan/app/routes/team.tsx +2 -8
  172. package/corpus/templates/plan/server/lib/comment-notifications.ts +1 -1
  173. package/corpus/templates/slides/actions/check-image-gen.ts +2 -1
  174. package/corpus/templates/slides/actions/db-connect.ts +7 -45
  175. package/corpus/templates/slides/actions/edit-image.ts +6 -3
  176. package/corpus/templates/slides/actions/generate-image-api.ts +1 -1
  177. package/corpus/templates/slides/actions/generate-image.ts +2 -2
  178. package/corpus/templates/slides/actions/generate-slides-ai.ts +5 -3
  179. package/corpus/templates/slides/actions/image-gen-status.ts +4 -3
  180. package/corpus/templates/slides/actions/image-search.ts +6 -3
  181. package/corpus/templates/slides/actions/search-images.ts +6 -3
  182. package/corpus/templates/slides/app/components/CloudUpgrade.tsx +8 -51
  183. package/corpus/templates/slides/app/components/layout/Header.tsx +0 -1
  184. package/corpus/templates/slides/app/components/layout/Sidebar.tsx +0 -2
  185. package/corpus/templates/slides/app/routes/settings.tsx +54 -54
  186. package/corpus/templates/slides/app/routes/team.tsx +2 -12
  187. package/corpus/templates/slides/server/handlers/google-docs-auth.ts +9 -9
  188. package/corpus/templates/slides/server/handlers/image-gen.ts +5 -1
  189. package/corpus/templates/slides/server/handlers/image-providers/gemini.ts +9 -1
  190. package/corpus/templates/slides/server/handlers/image-providers/index.ts +18 -8
  191. package/corpus/templates/slides/server/handlers/image-providers/openai.ts +10 -4
  192. package/corpus/templates/slides/server/handlers/image-providers/types.ts +1 -0
  193. package/corpus/templates/slides/server/lib/google-docs-oauth.ts +59 -34
  194. package/corpus/templates/slides/server/register-secrets.ts +60 -0
  195. package/corpus/templates/videos/actions/db-connect.ts +7 -45
  196. package/corpus/templates/videos/app/components/CloudUpgrade.tsx +8 -51
  197. package/corpus/templates/videos/app/components/Sidebar.tsx +1 -9
  198. package/corpus/templates/videos/app/components/layout/Header.tsx +0 -1
  199. package/corpus/templates/videos/app/components/layout/NavSidebar.tsx +0 -3
  200. package/corpus/templates/videos/app/routes/settings.tsx +54 -54
  201. package/corpus/templates/videos/app/routes/team.tsx +2 -8
  202. package/dist/agent/engine/builder-engine.d.ts.map +1 -1
  203. package/dist/agent/engine/builder-engine.js +8 -3
  204. package/dist/agent/engine/builder-engine.js.map +1 -1
  205. package/dist/cli/mcp.d.ts.map +1 -1
  206. package/dist/cli/mcp.js +3 -4
  207. package/dist/cli/mcp.js.map +1 -1
  208. package/dist/client/AssistantChat.d.ts.map +1 -1
  209. package/dist/client/AssistantChat.js +6 -2
  210. package/dist/client/AssistantChat.js.map +1 -1
  211. package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
  212. package/dist/client/chat/markdown-renderer.js +1 -0
  213. package/dist/client/chat/markdown-renderer.js.map +1 -1
  214. package/dist/client/index.d.ts +1 -1
  215. package/dist/client/index.d.ts.map +1 -1
  216. package/dist/client/index.js +1 -1
  217. package/dist/client/index.js.map +1 -1
  218. package/dist/client/org/OrgSwitcher.d.ts +3 -3
  219. package/dist/client/org/OrgSwitcher.js +2 -2
  220. package/dist/client/org/OrgSwitcher.js.map +1 -1
  221. package/dist/client/org/TeamPage.d.ts +6 -1
  222. package/dist/client/org/TeamPage.d.ts.map +1 -1
  223. package/dist/client/org/TeamPage.js +2 -2
  224. package/dist/client/org/TeamPage.js.map +1 -1
  225. package/dist/client/settings/SettingsTabsPage.d.ts +27 -0
  226. package/dist/client/settings/SettingsTabsPage.d.ts.map +1 -0
  227. package/dist/client/settings/SettingsTabsPage.js +108 -0
  228. package/dist/client/settings/SettingsTabsPage.js.map +1 -0
  229. package/dist/client/settings/index.d.ts +1 -0
  230. package/dist/client/settings/index.d.ts.map +1 -1
  231. package/dist/client/settings/index.js +1 -0
  232. package/dist/client/settings/index.js.map +1 -1
  233. package/dist/collab/routes.d.ts +1 -1
  234. package/dist/file-upload/actions/upload-image.d.ts +2 -2
  235. package/dist/file-upload/index.d.ts +1 -1
  236. package/dist/file-upload/index.d.ts.map +1 -1
  237. package/dist/file-upload/index.js +1 -1
  238. package/dist/file-upload/index.js.map +1 -1
  239. package/dist/file-upload/registry.d.ts +1 -0
  240. package/dist/file-upload/registry.d.ts.map +1 -1
  241. package/dist/file-upload/registry.js +24 -6
  242. package/dist/file-upload/registry.js.map +1 -1
  243. package/dist/file-upload/types.d.ts +6 -1
  244. package/dist/file-upload/types.d.ts.map +1 -1
  245. package/dist/file-upload/types.js.map +1 -1
  246. package/dist/integrations/adapters/email.d.ts.map +1 -1
  247. package/dist/integrations/adapters/email.js +18 -18
  248. package/dist/integrations/adapters/email.js.map +1 -1
  249. package/dist/integrations/adapters/slack.d.ts.map +1 -1
  250. package/dist/integrations/adapters/slack.js +8 -7
  251. package/dist/integrations/adapters/slack.js.map +1 -1
  252. package/dist/integrations/adapters/telegram.d.ts.map +1 -1
  253. package/dist/integrations/adapters/telegram.js +9 -9
  254. package/dist/integrations/adapters/telegram.js.map +1 -1
  255. package/dist/integrations/adapters/whatsapp.d.ts.map +1 -1
  256. package/dist/integrations/adapters/whatsapp.js +10 -9
  257. package/dist/integrations/adapters/whatsapp.js.map +1 -1
  258. package/dist/integrations/plugin.d.ts.map +1 -1
  259. package/dist/integrations/plugin.js +47 -13
  260. package/dist/integrations/plugin.js.map +1 -1
  261. package/dist/notifications/routes.d.ts +1 -1
  262. package/dist/observability/routes.d.ts +2 -2
  263. package/dist/onboarding/default-steps.d.ts.map +1 -1
  264. package/dist/onboarding/default-steps.js +6 -5
  265. package/dist/onboarding/default-steps.js.map +1 -1
  266. package/dist/onboarding/types.d.ts +1 -1
  267. package/dist/onboarding/types.d.ts.map +1 -1
  268. package/dist/onboarding/types.js.map +1 -1
  269. package/dist/org/handlers.js +1 -1
  270. package/dist/org/handlers.js.map +1 -1
  271. package/dist/progress/routes.d.ts +1 -1
  272. package/dist/resources/handlers.d.ts +3 -3
  273. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  274. package/dist/server/agent-chat-plugin.js +4 -6
  275. package/dist/server/agent-chat-plugin.js.map +1 -1
  276. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  277. package/dist/server/better-auth-instance.d.ts.map +1 -1
  278. package/dist/server/better-auth-instance.js +17 -56
  279. package/dist/server/better-auth-instance.js.map +1 -1
  280. package/dist/server/core-routes-plugin.d.ts +1 -1
  281. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  282. package/dist/server/core-routes-plugin.js +67 -153
  283. package/dist/server/core-routes-plugin.js.map +1 -1
  284. package/dist/server/create-server.d.ts +3 -9
  285. package/dist/server/create-server.d.ts.map +1 -1
  286. package/dist/server/create-server.js +37 -91
  287. package/dist/server/create-server.js.map +1 -1
  288. package/dist/server/email-actions.d.ts +2 -3
  289. package/dist/server/email-actions.d.ts.map +1 -1
  290. package/dist/server/email-actions.js +3 -6
  291. package/dist/server/email-actions.js.map +1 -1
  292. package/dist/server/email.d.ts +3 -3
  293. package/dist/server/email.d.ts.map +1 -1
  294. package/dist/server/email.js +40 -19
  295. package/dist/server/email.js.map +1 -1
  296. package/dist/server/index.d.ts +3 -3
  297. package/dist/server/index.d.ts.map +1 -1
  298. package/dist/server/index.js +3 -3
  299. package/dist/server/index.js.map +1 -1
  300. package/dist/server/scoped-key-storage.d.ts +22 -0
  301. package/dist/server/scoped-key-storage.d.ts.map +1 -0
  302. package/dist/server/scoped-key-storage.js +152 -0
  303. package/dist/server/scoped-key-storage.js.map +1 -0
  304. package/dist/server/transcribe-voice.d.ts +1 -1
  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 +47 -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
@@ -1,4 +1,3 @@
1
- import path from "node:path";
2
1
  import { defineEventHandler, setResponseStatus, setResponseHeader, getMethod, getHeader, getCookie, setCookie, deleteCookie, getRequestURL, } from "h3";
3
2
  import { readMultipartFormData } from "h3";
4
3
  import { DEFAULT_MODEL } from "../agent/default-model.js";
@@ -10,15 +9,13 @@ import { getState, putState, deleteState, listComposeDrafts, getComposeDraft, pu
10
9
  import { mountBrowserSessionRoutes } from "../browser-sessions/routes.js";
11
10
  import { mountDbAdminRoutes } from "../db-admin/routes.js";
12
11
  import { getDbExec } from "../db/client.js";
13
- import { uploadFile, getActiveFileUploadProvider, listFileUploadProviders, } from "../file-upload/index.js";
12
+ import { uploadFile, getActiveFileUploadProviderForRequest, listFileUploadProviders, } from "../file-upload/index.js";
14
13
  import { handleMcpConnect } from "../mcp/connect-route.js";
15
14
  import { handleMcpOAuth, handleMcpOAuthAuthorizationServerMetadata, handleMcpOAuthProtectedResourceMetadata, } from "../mcp/oauth-route.js";
16
15
  import { registerBuiltinNotificationChannels } from "../notifications/channels.js";
17
16
  import { createNotificationsHandler } from "../notifications/routes.js";
18
- import { listOnboardingSteps } from "../onboarding/registry.js";
19
17
  import { getOrgContext } from "../org/context.js";
20
18
  import { createProgressHandler } from "../progress/routes.js";
21
- import { findWorkspaceRoot } from "../scripts/utils.js";
22
19
  import { registerFrameworkSecrets } from "../secrets/register-framework-secrets.js";
23
20
  import { createListSecretsHandler, createWriteSecretHandler, createTestSecretHandler, createAdHocSecretHandler, } from "../secrets/routes.js";
24
21
  import { getSetting, putSetting, deleteSetting } from "../settings/store.js";
@@ -38,10 +35,8 @@ import { getSession } from "./auth.js";
38
35
  import { BUILDER_CONNECT_PARAM, BUILDER_CONNECT_OWNER_COOKIE, BUILDER_ENV_KEYS, BUILDER_OPENER_PARAM, BUILDER_STATE_PARAM, appendBuilderConnectToken, builderConnectTrackingProperties, buildBuilderCliAuthUrl, createBuilderBrowserCallbackErrorPage, createBuilderBrowserCallbackPage, getBuilderConnectTrackingParams, getBuilderCliAuthCallbackOriginForEvent, getBuilderBrowserOriginForEvent, resolveBuilderCallbackReturnUrl, getBuilderBrowserStatusForEvent, resolveBuilderBranchProjectId, resolveSafePreviewUrl, runBuilderAgent, signBuilderCallbackState, verifyBuilderConnectTokenAndGetOwner, verifyBuilderCallbackStateAndGetOwner, signBuilderConnectToken, } from "./builder-browser.js";
39
36
  import { captureError } from "./capture-error.js";
40
37
  import { getAllowedCorsOrigin, readCorsAllowedOrigins, } from "./cors-origins.js";
41
- import { upsertEnvFile } from "./create-server.js";
42
38
  import { canUseDeployCredentialFallbackForRequest, resolveSecret, } from "./credential-provider.js";
43
39
  import { createEmbedStartRouteHandler } from "./embed-route.js";
44
- import { isEnvVarWriteAllowed } from "./env-var-writes.js";
45
40
  import { getH3App, awaitBootstrap, markDefaultPluginProvided, trackPluginInit, } from "./framework-request-handler.js";
46
41
  import { getAppBasePath, getOrigin } from "./google-oauth.js";
47
42
  import { createGoogleRealtimeSessionHandler } from "./google-realtime-session.js";
@@ -52,6 +47,7 @@ import { createOpenRouteHandler } from "./open-route.js";
52
47
  import { createPollEventsHandler } from "./poll-events.js";
53
48
  import { createPollHandler } from "./poll.js";
54
49
  import { runWithRequestContext } from "./request-context.js";
50
+ import { findUnsupportedScopedKeyNames, saveKeyValuesToScopedSecrets, ScopedKeyStorageError, } from "./scoped-key-storage.js";
55
51
  import { createTranscribeVoiceHandler } from "./transcribe-voice.js";
56
52
  import { createVoiceProvidersStatusHandler } from "./voice-providers-status.js";
57
53
  /**
@@ -181,7 +177,6 @@ function parseBuilderCallbackBoolean(value) {
181
177
  return null;
182
178
  return /^(1|true)$/i.test(value);
183
179
  }
184
- const PROVIDER_ENV_VAR_KEYS = new Set(Object.values(PROVIDER_ENV_META).map(({ envVar }) => envVar));
185
180
  // Raster-only data-URI allowlist for avatar writes. SVG is deliberately absent:
186
181
  // data:image/svg+xml payloads can carry inline <script> and event-handler
187
182
  // attributes that execute when the browser renders them as an <img> src or
@@ -367,7 +362,7 @@ function redactValues(text, values) {
367
362
  * GET /_agent-native/ping — health check
368
363
  * GET /_agent-native/health — DB liveness probe + scale-to-zero warmup
369
364
  * GET /_agent-native/env-status — env key configuration status (when envKeys provided)
370
- * POST /_agent-native/env-vars — save env vars to .env (when envKeys provided)
365
+ * POST /_agent-native/env-vars — compatibility route that saves keys to scoped DB secrets
371
366
  * GET /_agent-native/application-state/:key — read application state
372
367
  * PUT /_agent-native/application-state/:key — write application state
373
368
  * DELETE /_agent-native/application-state/:key — delete application state
@@ -393,33 +388,17 @@ export function createCoreRoutesPlugin(options = {}) {
393
388
  });
394
389
  try {
395
390
  await awaitBootstrap(nitroApp);
396
- // Restore env vars from the settings table. On serverless, .env
397
- // writes don't persist across invocations the DB is the durable
398
- // store. Only set keys that are currently empty so explicit env
399
- // vars (Netlify dashboard, process-level) always win.
400
- //
401
- // GATED: only rehydrate into `process.env` on local-dev SQLite (or
402
- // with the explicit single-tenant opt-in). On a shared-DB hosted
403
- // multi-tenant deploy the `persisted-env-vars` row is deployment-wide
404
- // global state — pushing user-supplied values into `process.env` from
405
- // it would let any one tenant's writes (or a stale dev seed) leak
406
- // into every other tenant's process. The opt-out scrub of legacy
407
- // BUILDER_* values still runs unconditionally so existing rows on
408
- // multi-tenant deploys self-heal, but new env-var writes never land
409
- // in `process.env` outside the allowed contexts.
391
+ // Legacy cleanup: key saves now go to scoped app_secrets rows. Do not
392
+ // rehydrate the old deployment-global `persisted-env-vars` row into
393
+ // process.env; keep only the Builder scrub so stale leaked keys self-heal.
410
394
  try {
411
395
  const persisted = (await getSetting("persisted-env-vars"));
412
396
  if (persisted) {
413
397
  const builderKeys = new Set(BUILDER_ENV_KEYS);
414
- const writesAllowed = isEnvVarWriteAllowed();
415
398
  let scrubbed = 0;
416
- for (const [k, v] of Object.entries(persisted)) {
399
+ for (const k of Object.keys(persisted)) {
417
400
  if (builderKeys.has(k)) {
418
401
  scrubbed++;
419
- continue;
420
- }
421
- if (writesAllowed && typeof v === "string" && !process.env[k]) {
422
- process.env[k] = v;
423
402
  }
424
403
  }
425
404
  if (scrubbed > 0) {
@@ -1588,24 +1567,7 @@ export function createCoreRoutesPlugin(options = {}) {
1588
1567
  ];
1589
1568
  {
1590
1569
  const envKeys = [...frameworkEnvKeys, ...(options.envKeys ?? [])];
1591
- // Onboarding form fields are resolved per-request so late-registered
1592
- // steps (and template overrides) are picked up without a restart.
1593
- // Builder CLI auth writes scoped Builder credentials through the
1594
- // credential provider, never through the deploy-global env sink.
1595
- const collectOnboardingKeys = () => {
1596
- const keys = new Set();
1597
- for (const step of listOnboardingSteps()) {
1598
- for (const method of step.methods) {
1599
- if (method.kind === "form") {
1600
- for (const field of method.payload.fields) {
1601
- if (field?.key)
1602
- keys.add(field.key);
1603
- }
1604
- }
1605
- }
1606
- }
1607
- return keys;
1608
- };
1570
+ const allowedEnvKeyNames = envKeys.map(({ key }) => key);
1609
1571
  getH3App(nitroApp).use(`${P}/env-status`, defineEventHandler(async (event) => {
1610
1572
  const session = await getSession(event).catch(() => null);
1611
1573
  const userEmail = session?.email;
@@ -1620,10 +1582,8 @@ export function createCoreRoutesPlugin(options = {}) {
1620
1582
  }
1621
1583
  }
1622
1584
  return Promise.all(envKeys.map(async (cfg) => {
1623
- const isProviderKey = PROVIDER_ENV_VAR_KEYS.has(cfg.key);
1624
- const configured = isProviderKey
1625
- ? await runWithRequestContext({ userEmail, orgId }, () => resolveSecret(cfg.key).then(Boolean))
1626
- : !!process.env[cfg.key];
1585
+ const configured = Boolean(process.env[cfg.key]) ||
1586
+ (await runWithRequestContext({ userEmail, orgId }, () => resolveSecret(cfg.key).then(Boolean)));
1627
1587
  return {
1628
1588
  key: cfg.key,
1629
1589
  label: cfg.label,
@@ -1638,80 +1598,27 @@ export function createCoreRoutesPlugin(options = {}) {
1638
1598
  setResponseStatus(event, 405);
1639
1599
  return { error: "Method not allowed" };
1640
1600
  }
1641
- // Env vars are deployment-wide globals, not per-tenant. On any
1642
- // shared-DB multi-tenant deploy, allowing authenticated users to
1643
- // write here lets one tenant overwrite Stripe / OpenAI / Sentry
1644
- // keys for every other tenant. Disable the endpoint outside of
1645
- // local-dev SQLite or an explicit single-tenant opt-in, and
1646
- // direct callers to scoped secret/credential stores instead.
1647
- if (!isEnvVarWriteAllowed()) {
1648
- setResponseStatus(event, 403);
1649
- return {
1650
- error: "env-vars endpoint disabled on multi-tenant deployments. Use scoped secrets or credentials for user/org API keys.",
1651
- };
1652
- }
1653
1601
  const body = await readBody(event);
1654
- const { vars } = body;
1655
- if (!Array.isArray(vars) || vars.length === 0) {
1602
+ const { vars, scope } = body;
1603
+ const unsupportedKeys = findUnsupportedScopedKeyNames(vars, allowedEnvKeyNames);
1604
+ if (unsupportedKeys.length > 0) {
1656
1605
  setResponseStatus(event, 400);
1657
- return { error: "vars array required" };
1658
- }
1659
- const allowedKeys = new Set([
1660
- ...envKeys.map((k) => k.key),
1661
- ...collectOnboardingKeys(),
1662
- ]);
1663
- const blockedEnvVarWriteKeys = new Set(BUILDER_ENV_KEYS);
1664
- const isWritableEnvKey = (key) => allowedKeys.has(key) && !blockedEnvVarWriteKeys.has(key);
1665
- const filtered = vars.filter((v) => typeof v.key === "string" &&
1666
- isWritableEnvKey(v.key) &&
1667
- typeof v.value === "string" &&
1668
- v.value.trim().length > 0);
1669
- if (filtered.length === 0) {
1670
- setResponseStatus(event, 400);
1671
- const rejectedEmpty = vars.some((v) => typeof v.key === "string" &&
1672
- isWritableEnvKey(v.key) &&
1673
- (typeof v.value !== "string" || v.value.trim().length === 0));
1674
1606
  return {
1675
- error: rejectedEmpty
1676
- ? "Env values must be non-empty — refusing to clear a saved key"
1677
- : "No recognized env keys in request",
1607
+ error: `Unsupported env key${unsupportedKeys.length === 1 ? "" : "s"}: ${unsupportedKeys.join(", ")}`,
1678
1608
  };
1679
1609
  }
1680
- // Write to .env file. When inside a workspace, write to the
1681
- // workspace root .env so keys are shared across every app. The
1682
- // per-app .env still wins at load time if it also defines a key.
1683
- try {
1684
- const scope = body?.scope ?? "auto";
1685
- const workspaceRoot = findWorkspaceRoot(process.cwd());
1686
- const envPath = scope === "app"
1687
- ? path.join(process.cwd(), ".env")
1688
- : workspaceRoot
1689
- ? path.join(workspaceRoot, ".env")
1690
- : path.join(process.cwd(), ".env");
1691
- await upsertEnvFile(envPath, filtered);
1692
- }
1693
- catch {
1694
- // Edge runtime — skip file write
1695
- }
1696
- // Update process.env immediately
1697
- for (const { key, value } of filtered) {
1698
- process.env[key] = value;
1699
- }
1700
- // Persist to settings table for serverless cold-start recovery.
1701
1610
  try {
1702
- const envMap = {};
1703
- for (const { key, value } of filtered)
1704
- envMap[key] = value;
1705
- const existing = (await getSetting("persisted-env-vars")) ?? {};
1706
- await putSetting("persisted-env-vars", {
1707
- ...existing,
1708
- ...envMap,
1709
- });
1611
+ const result = await saveKeyValuesToScopedSecrets(event, vars, scope);
1612
+ return { saved: result.saved, storage: "scoped-secrets" };
1710
1613
  }
1711
- catch {
1712
- // DB not ready yet — skip
1614
+ catch (err) {
1615
+ if (err instanceof ScopedKeyStorageError) {
1616
+ setResponseStatus(event, err.statusCode);
1617
+ return { error: err.message };
1618
+ }
1619
+ setResponseStatus(event, 500);
1620
+ return { error: "Failed to save keys" };
1713
1621
  }
1714
- return { saved: filtered.map((v) => v.key) };
1715
1622
  }));
1716
1623
  }
1717
1624
  getH3App(nitroApp).use(`${P}/agent-engine/api-key`, createAgentEngineApiKeyHandler());
@@ -1993,51 +1900,58 @@ export function createCoreRoutesPlugin(options = {}) {
1993
1900
  // GET /_agent-native/file-upload/status — report active provider
1994
1901
  // POST /_agent-native/file-upload — upload a file, return { url }
1995
1902
  getH3App(nitroApp).use(`${P}/file-upload/status`, defineEventHandler(async (event) => {
1996
- const active = getActiveFileUploadProvider();
1997
1903
  // resolveBuilderPrivateKey() reads per-user credentials from app_secrets
1998
1904
  // (DB), which requires request context (AsyncLocalStorage) to know which
1999
1905
  // user to scope by. Without runWithRequestContext() the ALS store is empty
2000
1906
  // and it falls back to process.env only — missing OAuth-connected users.
2001
1907
  const session = await getSession(event).catch(() => null);
2002
1908
  const userEmail = session?.email;
2003
- let builderConfigured = !!process.env.BUILDER_PRIVATE_KEY;
2004
- try {
2005
- const { resolveBuilderPrivateKey } = await import("./credential-provider.js");
2006
- const resolve = () => resolveBuilderPrivateKey().then((k) => !!k);
2007
- builderConfigured = userEmail
2008
- ? await runWithRequestContext({ userEmail, orgId: session?.orgId }, resolve)
2009
- : await resolve();
2010
- }
2011
- catch {
2012
- // fall back to env check above
2013
- }
2014
- // When the builder builtin is selected via env var, its sync
2015
- // isConfigured() doesn't reflect per-user OAuth credentials. Use the
2016
- // async builderConfigured check so the status accurately represents
2017
- // whether this specific user can actually upload (thread 7 fix).
2018
- const isBuilderEnvActive = active?.id === "builder";
2019
- const configured = isBuilderEnvActive
2020
- ? builderConfigured
2021
- : !!active || builderConfigured;
2022
- const activeProvider = isBuilderEnvActive
2023
- ? builderConfigured
2024
- ? { id: "builder", name: "Builder.io" }
2025
- : null
2026
- : active
2027
- ? { id: active.id, name: active.name }
2028
- : builderConfigured
1909
+ const resolveStatus = async () => {
1910
+ const active = await getActiveFileUploadProviderForRequest();
1911
+ let builderConfigured = !!process.env.BUILDER_PRIVATE_KEY;
1912
+ try {
1913
+ const { resolveBuilderPrivateKey } = await import("./credential-provider.js");
1914
+ builderConfigured = await resolveBuilderPrivateKey().then((k) => !!k);
1915
+ }
1916
+ catch {
1917
+ // fall back to env check above
1918
+ }
1919
+ const providers = await Promise.all(listFileUploadProviders().map(async (p) => {
1920
+ const scopedConfigured = p.isConfiguredForRequest
1921
+ ? await p.isConfiguredForRequest().catch(() => false)
1922
+ : false;
1923
+ return {
1924
+ id: p.id,
1925
+ name: p.name,
1926
+ configured: p.isConfigured() || scopedConfigured,
1927
+ };
1928
+ }));
1929
+ // When the builder builtin is selected via env var, its sync
1930
+ // isConfigured() doesn't reflect per-user OAuth credentials. Use
1931
+ // builderConfigured so status reflects this specific request.
1932
+ const isBuilderEnvActive = active?.id === "builder";
1933
+ const configured = isBuilderEnvActive
1934
+ ? builderConfigured
1935
+ : !!active || builderConfigured;
1936
+ const activeProvider = isBuilderEnvActive
1937
+ ? builderConfigured
2029
1938
  ? { id: "builder", name: "Builder.io" }
2030
- : null;
2031
- return {
2032
- configured,
2033
- activeProvider,
2034
- providers: listFileUploadProviders().map((p) => ({
2035
- id: p.id,
2036
- name: p.name,
2037
- configured: p.isConfigured(),
2038
- })),
2039
- builderConfigured,
1939
+ : null
1940
+ : active
1941
+ ? { id: active.id, name: active.name }
1942
+ : builderConfigured
1943
+ ? { id: "builder", name: "Builder.io" }
1944
+ : null;
1945
+ return {
1946
+ configured,
1947
+ activeProvider,
1948
+ providers,
1949
+ builderConfigured,
1950
+ };
2040
1951
  };
1952
+ return userEmail
1953
+ ? runWithRequestContext({ userEmail, orgId: session?.orgId }, resolveStatus)
1954
+ : resolveStatus();
2041
1955
  }));
2042
1956
  getH3App(nitroApp).use(`${P}/file-upload`, defineEventHandler(async (event) => {
2043
1957
  if (getMethod(event) !== "POST") {