@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
@@ -35,6 +35,7 @@ import {
35
35
  getAuthStatus,
36
36
  disconnect,
37
37
  getClient,
38
+ getOAuth2Credentials,
38
39
  setAccountDisplayName,
39
40
  } from "../lib/google-auth.js";
40
41
 
@@ -103,14 +104,6 @@ function googleOAuthErrorResponse(
103
104
  }
104
105
 
105
106
  export const getGoogleAuthUrl = defineEventHandler(async (event: H3Event) => {
106
- if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
107
- setResponseStatus(event, 422);
108
- return {
109
- error: "missing_credentials",
110
- message:
111
- "Google OAuth credentials are not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.",
112
- };
113
- }
114
107
  try {
115
108
  const q = getQuery(event);
116
109
  const redirectUri = resolveOAuthRedirectUri(event);
@@ -123,6 +116,7 @@ export const getGoogleAuthUrl = defineEventHandler(async (event: H3Event) => {
123
116
  }
124
117
  const session = await getSession(event);
125
118
  const owner = session?.email;
119
+ await getOAuth2Credentials(owner);
126
120
  const desktop =
127
121
  isElectron(event) || q.desktop === "1" || q.desktop === "true";
128
122
  const flowId = desktop ? (q.flow_id as string) || undefined : undefined;
@@ -141,12 +135,20 @@ export const getGoogleAuthUrl = defineEventHandler(async (event: H3Event) => {
141
135
  returnUrl,
142
136
  flowId,
143
137
  });
144
- const url = getAuthUrl(undefined, redirectUri, state);
138
+ const url = await getAuthUrl(undefined, redirectUri, state, owner);
145
139
  if (q.redirect === "1") {
146
140
  return oauthRedirectResponse(url);
147
141
  }
148
142
  return { url };
149
143
  } catch (error: any) {
144
+ if (/GOOGLE_CLIENT_ID|GOOGLE_CLIENT_SECRET/.test(error?.message || "")) {
145
+ setResponseStatus(event, 422);
146
+ return {
147
+ error: "missing_credentials",
148
+ message:
149
+ "Google OAuth credentials are not configured. Save GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in settings.",
150
+ };
151
+ }
150
152
  setResponseStatus(event, 500);
151
153
  return { error: error.message };
152
154
  }
@@ -279,12 +281,12 @@ export const getGoogleAddAccountUrl = defineEventHandler(
279
281
  setResponseStatus(event, 401);
280
282
  return { error: "Must be logged in to add an account" };
281
283
  }
282
- if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
284
+ if (!(await getOAuth2Credentials(session.email).catch(() => null))) {
283
285
  setResponseStatus(event, 422);
284
286
  return {
285
287
  error: "missing_credentials",
286
288
  message:
287
- "Google OAuth credentials are not configured. Set GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET.",
289
+ "Google OAuth credentials are not configured. Save GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET in settings.",
288
290
  };
289
291
  }
290
292
  try {
@@ -308,7 +310,12 @@ export const getGoogleAddAccountUrl = defineEventHandler(
308
310
  app: OAUTH_STATE_APP_ID,
309
311
  flowId,
310
312
  });
311
- const url = getAuthUrl(undefined, redirectUri, state);
313
+ const url = await getAuthUrl(
314
+ undefined,
315
+ redirectUri,
316
+ state,
317
+ session.email,
318
+ );
312
319
  if (q.redirect === "1") {
313
320
  return oauthRedirectResponse(url);
314
321
  }
@@ -27,6 +27,7 @@ import {
27
27
  gmailListHistory,
28
28
  gmailGetProfile,
29
29
  } from "./google-api.js";
30
+ import { getOAuth2Credentials } from "./google-auth.js";
30
31
 
31
32
  const DEFAULT_MODEL = "claude-haiku-4-5-20251001";
32
33
  const MAX_EMAILS_PER_RUN = 50;
@@ -91,8 +92,8 @@ async function getAccessToken(accountEmail: string): Promise<string | null> {
91
92
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
92
93
  ) {
93
94
  try {
94
- const clientId = process.env.GOOGLE_CLIENT_ID!;
95
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
95
+ const { clientId, clientSecret } =
96
+ await getOAuth2Credentials(accountEmail);
96
97
  const oauth = createOAuth2Client(
97
98
  clientId,
98
99
  clientSecret,
@@ -22,7 +22,7 @@ import {
22
22
  gmailTrashThread,
23
23
  gmailUntrashThread,
24
24
  } from "./google-api.js";
25
- import { isConnected } from "./google-auth.js";
25
+ import { getOAuth2Credentials, isConnected } from "./google-auth.js";
26
26
  import { invalidateThreadCache } from "./thread-cache.js";
27
27
 
28
28
  // ---------------------------------------------------------------------------
@@ -45,8 +45,7 @@ async function refreshIfNeeded(
45
45
  tokens.expiry_date &&
46
46
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
47
47
  ) {
48
- const clientId = process.env.GOOGLE_CLIENT_ID!;
49
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
48
+ const { clientId, clientSecret } = await getOAuth2Credentials(accountId);
50
49
  const oauth = createOAuth2Client(clientId, clientSecret, "");
51
50
  const refreshed = await oauth.refreshToken(tokens.refresh_token);
52
51
  const updated = {
@@ -5,7 +5,12 @@ import {
5
5
  listOAuthAccountsByOwner,
6
6
  setOAuthDisplayName,
7
7
  } from "@agent-native/core/oauth-tokens";
8
- import { isOAuthConnected, getOAuthAccounts } from "@agent-native/core/server";
8
+ import {
9
+ isOAuthConnected,
10
+ getOAuthAccounts,
11
+ resolveSecret,
12
+ runWithRequestContext,
13
+ } from "@agent-native/core/server";
9
14
  import { getUserSetting, putUserSetting } from "@agent-native/core/settings";
10
15
  import { decodeCommonHtmlEntities } from "@shared/markdown.js";
11
16
 
@@ -46,15 +51,26 @@ interface GoogleTokens {
46
51
  scope?: string;
47
52
  }
48
53
 
49
- function getOAuth2Credentials(): {
54
+ export async function getOAuth2Credentials(owner?: string): Promise<{
50
55
  clientId: string;
51
56
  clientSecret: string;
52
- } {
53
- const clientId = process.env.GOOGLE_CLIENT_ID;
54
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET;
57
+ }> {
58
+ const resolve = async () => {
59
+ const [clientId, clientSecret] = await Promise.all([
60
+ resolveSecret("GOOGLE_CLIENT_ID"),
61
+ resolveSecret("GOOGLE_CLIENT_SECRET"),
62
+ ]);
63
+ if (!clientId || !clientSecret) return null;
64
+ return { clientId, clientSecret };
65
+ };
66
+ const credentials = owner
67
+ ? await runWithRequestContext({ userEmail: owner }, resolve)
68
+ : await resolve();
69
+ const clientId = credentials?.clientId;
70
+ const clientSecret = credentials?.clientSecret;
55
71
  if (!clientId || !clientSecret) {
56
72
  throw new Error(
57
- "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET must be set in environment",
73
+ "GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET must be saved in settings",
58
74
  );
59
75
  }
60
76
  return { clientId, clientSecret };
@@ -112,7 +128,7 @@ async function getValidAccessToken(
112
128
  );
113
129
  }
114
130
 
115
- const { clientId, clientSecret } = getOAuth2Credentials();
131
+ const { clientId, clientSecret } = await getOAuth2Credentials(owner);
116
132
  const redirectUri = "http://localhost:8080/_agent-native/google/callback";
117
133
  const oauth2 = createOAuth2Client(clientId, clientSecret, redirectUri);
118
134
  let refreshed;
@@ -157,12 +173,13 @@ async function getValidAccessToken(
157
173
  return refreshed.access_token;
158
174
  }
159
175
 
160
- export function getAuthUrl(
176
+ export async function getAuthUrl(
161
177
  origin?: string,
162
178
  redirectUri?: string,
163
179
  state?: string,
164
- ): string {
165
- const { clientId, clientSecret } = getOAuth2Credentials();
180
+ owner?: string,
181
+ ): Promise<string> {
182
+ const { clientId, clientSecret } = await getOAuth2Credentials(owner);
166
183
  const uri =
167
184
  redirectUri ||
168
185
  (origin
@@ -215,7 +232,7 @@ export async function exchangeCode(
215
232
  redirectUri?: string,
216
233
  owner?: string,
217
234
  ): Promise<string> {
218
- const { clientId, clientSecret } = getOAuth2Credentials();
235
+ const { clientId, clientSecret } = await getOAuth2Credentials(owner);
219
236
  const uri =
220
237
  redirectUri ||
221
238
  (origin
@@ -25,6 +25,7 @@ import {
25
25
  getAccountDisplayName,
26
26
  isConnected,
27
27
  gmailToEmailMessage,
28
+ getOAuth2Credentials,
28
29
  setAccountDisplayName,
29
30
  } from "./google-auth.js";
30
31
  import {
@@ -83,8 +84,8 @@ async function getAccessToken(accountEmail: string): Promise<string | null> {
83
84
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
84
85
  ) {
85
86
  try {
86
- const clientId = process.env.GOOGLE_CLIENT_ID!;
87
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
87
+ const { clientId, clientSecret } =
88
+ await getOAuth2Credentials(accountEmail);
88
89
  const oauth = createOAuth2Client(
89
90
  clientId,
90
91
  clientSecret,
@@ -8,12 +8,12 @@
8
8
  * `GoogleConnectBanner` auto-detects missing credentials and guides the
9
9
  * user through the Google Cloud Console setup.
10
10
  * 2. Agent task — hands the task to the agent, which drives the user's
11
- * browser (or falls back to verbal step-by-step instructions) and writes
12
- * the resulting credentials into the workspace `.env` via
13
- * `POST /_agent-native/env-vars`.
11
+ * browser (or falls back to verbal step-by-step instructions) and saves
12
+ * the resulting credentials as workspace-scoped DB keys.
14
13
  */
15
14
 
16
15
  import { registerOnboardingStep } from "@agent-native/core/onboarding";
16
+ import { readDeployCredentialEnv } from "@agent-native/core/server";
17
17
 
18
18
  registerOnboardingStep({
19
19
  id: "gmail",
@@ -37,10 +37,13 @@ registerOnboardingStep({
37
37
  label: "Have the agent set it up for me",
38
38
  payload: {
39
39
  prompt:
40
- 'Help me connect Gmail. Walk me through creating Google OAuth credentials by driving my browser (use any mcp__*browser* tools available, or fall back to giving me step-by-step instructions with exact URLs and values). When client_id and client_secret are ready, save them to my workspace .env via POST /_agent-native/env-vars with scope "workspace". Then tell me to click "Sign in with Google" in the mail onboarding banner to finish the OAuth sign-in.',
40
+ "Help me connect Gmail. Walk me through creating Google OAuth credentials by driving my browser (use any mcp__*browser* tools available, or fall back to giving me step-by-step instructions with exact URLs and values). When client_id and client_secret are ready, help me configure GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET as deployment or local environment variables for Mail, then restart or redeploy before clicking Sign in with Google.",
41
41
  },
42
42
  },
43
43
  ],
44
- isComplete: () =>
45
- !!process.env.GOOGLE_CLIENT_ID && !!process.env.GOOGLE_CLIENT_SECRET,
44
+ isComplete: async () =>
45
+ Boolean(
46
+ readDeployCredentialEnv("GOOGLE_CLIENT_ID") &&
47
+ readDeployCredentialEnv("GOOGLE_CLIENT_SECRET"),
48
+ ),
46
49
  });
@@ -15,7 +15,7 @@ import {
15
15
  createOAuth2Client,
16
16
  gmailGetAttachment,
17
17
  } from "../../lib/google-api.js";
18
- import { isConnected } from "../../lib/google-auth.js";
18
+ import { getOAuth2Credentials, isConnected } from "../../lib/google-auth.js";
19
19
 
20
20
  interface StoredTokens {
21
21
  access_token: string;
@@ -35,8 +35,8 @@ async function getAccessToken(accountEmail: string): Promise<string | null> {
35
35
  tokens.expiry_date < Date.now() + 5 * 60 * 1000
36
36
  ) {
37
37
  try {
38
- const clientId = process.env.GOOGLE_CLIENT_ID!;
39
- const clientSecret = process.env.GOOGLE_CLIENT_SECRET!;
38
+ const { clientId, clientSecret } =
39
+ await getOAuth2Credentials(accountEmail);
40
40
  const oauth = createOAuth2Client(
41
41
  clientId,
42
42
  clientSecret,
@@ -57,7 +57,7 @@ async function notifyOwner(input: {
57
57
  requesterEmail: string;
58
58
  requesterName: string;
59
59
  }): Promise<boolean> {
60
- if (!isEmailConfigured()) return false;
60
+ if (!(await isEmailConfigured())) return false;
61
61
  if (!input.ownerEmail || input.ownerEmail === input.requesterEmail) {
62
62
  return false;
63
63
  }
@@ -10,7 +10,6 @@ const pageTitleKeys: Record<string, string> = {
10
10
  "/": "header.plan",
11
11
  "/plans": "header.plan",
12
12
  "/settings": "header.settings",
13
- "/team": "header.team",
14
13
  };
15
14
 
16
15
  function resolveTitle(pathname: string): string {
@@ -43,6 +43,8 @@ const WHEEL_ZOOM_STEP = 0.16;
43
43
  const PINCH_ZOOM_SENSITIVITY = 0.01;
44
44
  /** Base CSS grid cell, scaled by zoom. */
45
45
  const GRID_CELL = 28;
46
+ /** Extra world-space grid on each side so the grid still fills overscrolled pans. */
47
+ const GRID_PADDING = 5000;
46
48
 
47
49
  type CanvasView = typeof DEFAULT_VIEW;
48
50
  export type CanvasViewport = CanvasView;
@@ -156,6 +158,9 @@ export function CanvasArea({
156
158
  );
157
159
  const latestViewportChangeRef = useRef<CanvasViewport>(initialView);
158
160
  const viewportChangeFrameRef = useRef<number | null>(null);
161
+ // Kept current each render so the central pan clamp (in updateView) can read
162
+ // the live board size without widening updateView's dependencies.
163
+ const boardRef = useRef({ width: 0, height: 0 });
159
164
  const queueViewportChange = useCallback(
160
165
  (nextView: CanvasViewport) => {
161
166
  latestViewportChangeRef.current = nextView;
@@ -171,7 +176,11 @@ export function CanvasArea({
171
176
  const updateView = useCallback(
172
177
  (resolve: (current: CanvasView) => CanvasView) => {
173
178
  setView((current) => {
174
- const next = resolve(current);
179
+ const next = clampPanToGrid(
180
+ resolve(current),
181
+ boardRef.current,
182
+ viewportRef.current?.getBoundingClientRect() ?? null,
183
+ );
175
184
  if (sameCanvasView(current, next)) return current;
176
185
  queueViewportChange(next);
177
186
  return next;
@@ -332,6 +341,7 @@ export function CanvasArea({
332
341
  );
333
342
  return { width: maxX + 360, height: maxY + 280 };
334
343
  }, [frames, annotations, legacyNotes]);
344
+ boardRef.current = board;
335
345
 
336
346
  const lastAutoFitKeyRef = useRef<string | null>(null);
337
347
  useEffect(() => {
@@ -385,6 +395,7 @@ export function CanvasArea({
385
395
  }, [frameLayoutKey, frames, hasSavedViewport, updateView]);
386
396
 
387
397
  const { zoom, pan } = view;
398
+ const worldTransform = `translate3d(${pan.x}px, ${pan.y}px, 0) scale(${zoom})`;
388
399
  useEffect(() => {
389
400
  queueViewportChange(view);
390
401
  }, [queueViewportChange, view]);
@@ -656,8 +667,6 @@ export function CanvasArea({
656
667
  tabIndex={0}
657
668
  style={
658
669
  {
659
- backgroundPosition: `${pan.x}px ${pan.y}px`,
660
- backgroundSize: `${GRID_CELL * zoom}px ${GRID_CELL * zoom}px`,
661
670
  overscrollBehavior: "contain",
662
671
  touchAction: "none",
663
672
  } as CSSProperties
@@ -724,11 +733,25 @@ export function CanvasArea({
724
733
  style={{
725
734
  width: board.width,
726
735
  height: board.height,
727
- transform: `translate(${pan.x}px, ${pan.y}px) scale(${zoom})`,
736
+ transform: worldTransform,
728
737
  transformOrigin: "0 0",
729
738
  willChange: "transform",
739
+ backfaceVisibility: "hidden",
730
740
  }}
731
741
  >
742
+ <div
743
+ aria-hidden="true"
744
+ className="plan-canvas-grid absolute"
745
+ data-plan-canvas-grid
746
+ style={{
747
+ left: -GRID_PADDING,
748
+ top: -GRID_PADDING,
749
+ width: board.width + GRID_PADDING * 2,
750
+ height: board.height + GRID_PADDING * 2,
751
+ backgroundSize: `${GRID_CELL}px ${GRID_CELL}px`,
752
+ }}
753
+ />
754
+
732
755
  {/* Section containers sit BEHIND the frames (lowest layer) so each
733
756
  group reads as one bounded region the artboards rest inside. */}
734
757
  {sectionRects.map(({ section, rect }) => (
@@ -2293,3 +2316,32 @@ function resolveMarkupComposerPosition(input: {
2293
2316
  function clamp(value: number, min: number, max: number) {
2294
2317
  return Math.max(min, Math.min(max, value));
2295
2318
  }
2319
+
2320
+ /**
2321
+ * Keep the visible viewport inside the rendered grid. The grid is a fixed-size
2322
+ * child of the transformed world (board + GRID_PADDING on every side), so it is
2323
+ * large but finite; without this clamp a far-enough pan scrolls past the grid
2324
+ * edge into a blank void. Screen = pan + world * zoom, and the grid spans world
2325
+ * [-GRID_PADDING, board + GRID_PADDING], so bounding pan to the range below
2326
+ * guarantees the grid always fills the viewport while still allowing the full
2327
+ * GRID_PADDING of overscroll. A no-op until the viewport has been measured.
2328
+ */
2329
+ function clampPanToGrid(
2330
+ view: CanvasView,
2331
+ board: { width: number; height: number },
2332
+ rect: DOMRect | null,
2333
+ ): CanvasView {
2334
+ if (!rect) return view;
2335
+ const { zoom } = view;
2336
+ const minPanX = rect.width - (board.width + GRID_PADDING) * zoom;
2337
+ const maxPanX = GRID_PADDING * zoom;
2338
+ const minPanY = rect.height - (board.height + GRID_PADDING) * zoom;
2339
+ const maxPanY = GRID_PADDING * zoom;
2340
+ return {
2341
+ zoom,
2342
+ pan: {
2343
+ x: minPanX <= maxPanX ? clamp(view.pan.x, minPanX, maxPanX) : view.pan.x,
2344
+ y: minPanY <= maxPanY ? clamp(view.pan.y, minPanY, maxPanY) : view.pan.y,
2345
+ },
2346
+ };
2347
+ }
@@ -255,13 +255,18 @@
255
255
  touch-action: none;
256
256
  }
257
257
 
258
- /* Infinite low-contrast grid (slightly darker than the document bg) that
259
- * moves on pan via background-position and scales with zoom both driven
260
- * inline by CanvasArea. */
258
+ /* Infinite low-contrast grid. The live grid is rendered inside the transformed
259
+ * canvas world so Chrome can composite grid + artboards together while panning. */
261
260
  .plan-canvas-viewport {
261
+ isolation: isolate;
262
+ }
263
+
264
+ .plan-canvas-grid {
265
+ pointer-events: none;
262
266
  background-image:
263
267
  linear-gradient(var(--plan-grid-line) 1px, transparent 1px),
264
268
  linear-gradient(90deg, var(--plan-grid-line) 1px, transparent 1px);
269
+ backface-visibility: hidden;
265
270
  }
266
271
 
267
272
  /* Fixed-size static artboard frame. No border / shadow / box around the
@@ -132,7 +132,7 @@ function viewForPath(pathname: string): string {
132
132
  return "plans";
133
133
  }
134
134
  if (pathname.startsWith("/extensions")) return "extensions";
135
- if (pathname.startsWith("/team")) return "team";
135
+ if (pathname.startsWith("/team")) return "settings";
136
136
  return "plans";
137
137
  }
138
138
 
@@ -183,8 +183,10 @@ function pathForView(view?: string): string {
183
183
  return "/plans";
184
184
  case "extensions":
185
185
  return "/extensions";
186
+ case "settings":
187
+ return "/settings";
186
188
  case "team":
187
- return "/team";
189
+ return "/settings#team";
188
190
  default:
189
191
  return "/";
190
192
  }
@@ -48,10 +48,6 @@ export function prewarmPlanRoutePath(path: string) {
48
48
  );
49
49
  }
50
50
 
51
- if (pathname === "/team") {
52
- jobs.push(prewarm("team", () => import("@/routes/team")));
53
- }
54
-
55
51
  return Promise.all(jobs);
56
52
  }
57
53
 
@@ -7113,7 +7113,7 @@ function PlanCanvasSkeleton() {
7113
7113
  aria-hidden="true"
7114
7114
  >
7115
7115
  <div
7116
- className="plan-canvas-viewport absolute inset-0"
7116
+ className="plan-canvas-grid absolute inset-0"
7117
7117
  style={{
7118
7118
  backgroundPosition: "96px 64px",
7119
7119
  backgroundSize: "20px 20px",
@@ -1,10 +1,11 @@
1
1
  import {
2
2
  ChangelogSettingsCard,
3
3
  LanguagePicker,
4
+ SettingsTabsPage,
4
5
  openAgentSettings,
5
6
  useT,
6
7
  } from "@agent-native/core/client";
7
- import { Link } from "react-router";
8
+ import { TeamPage } from "@agent-native/core/client/org";
8
9
 
9
10
  import { useSetPageTitle } from "@/components/layout/HeaderActions";
10
11
  import { Button } from "@/components/ui/button";
@@ -29,80 +30,81 @@ export default function SettingsRoute() {
29
30
  useSetPageTitle(t("settings.title"));
30
31
 
31
32
  return (
32
- <main className="mx-auto w-full max-w-3xl space-y-6 px-4 py-6 sm:px-6 sm:py-10">
33
- <div className="space-y-1">
34
- <h1 className="text-2xl font-semibold tracking-tight">
35
- {t("settings.title")}
36
- </h1>
37
- <p className="text-sm leading-6 text-muted-foreground">
38
- {t("settings.description")}
39
- </p>
40
- </div>
33
+ <SettingsTabsPage
34
+ teamLabel={t("header.team")}
35
+ general={
36
+ <div className="mx-auto w-full max-w-3xl space-y-6">
37
+ <p className="text-sm leading-6 text-muted-foreground">
38
+ {t("settings.description")}
39
+ </p>
41
40
 
42
- <Card>
43
- <CardHeader>
44
- <CardTitle className="text-base">
45
- {t("settings.languageTitle")}
46
- </CardTitle>
47
- <CardDescription>{t("settings.languageDescription")}</CardDescription>
48
- </CardHeader>
49
- <CardContent className="max-w-xs space-y-1.5">
50
- <Label>{t("settings.languageLabel")}</Label>
51
- <LanguagePicker label={t("settings.languageLabel")} />
52
- </CardContent>
53
- </Card>
41
+ <Card>
42
+ <CardHeader>
43
+ <CardTitle className="text-base">
44
+ {t("settings.languageTitle")}
45
+ </CardTitle>
46
+ <CardDescription>
47
+ {t("settings.languageDescription")}
48
+ </CardDescription>
49
+ </CardHeader>
50
+ <CardContent className="max-w-xs space-y-1.5">
51
+ <Label>{t("settings.languageLabel")}</Label>
52
+ <LanguagePicker label={t("settings.languageLabel")} />
53
+ </CardContent>
54
+ </Card>
54
55
 
55
- <Card>
56
- <CardHeader>
57
- <CardTitle className="text-base">
58
- {t("settings.workspaceTitle")}
59
- </CardTitle>
60
- <CardDescription>
61
- {t("settings.workspaceDescription")}
62
- </CardDescription>
63
- </CardHeader>
64
- <CardContent>
65
- <Button variant="outline" asChild>
66
- <Link to="/team">{t("settings.openTeamSettings")}</Link>
67
- </Button>
68
- </CardContent>
69
- </Card>
56
+ <Card>
57
+ <CardHeader>
58
+ <CardTitle className="text-base">
59
+ {t("settings.agentTitle")}
60
+ </CardTitle>
61
+ <CardDescription>
62
+ {t("settings.agentDescription")}
63
+ </CardDescription>
64
+ </CardHeader>
65
+ <CardContent>
66
+ <Button variant="outline" onClick={() => openAgentSettings()}>
67
+ {t("settings.openAgentSettings")}
68
+ </Button>
69
+ </CardContent>
70
+ </Card>
70
71
 
71
- <Card>
72
- <CardHeader>
73
- <CardTitle className="text-base">
74
- {t("settings.agentTitle")}
75
- </CardTitle>
76
- <CardDescription>{t("settings.agentDescription")}</CardDescription>
77
- </CardHeader>
78
- <CardContent>
79
- <Button variant="outline" onClick={() => openAgentSettings()}>
80
- {t("settings.openAgentSettings")}
81
- </Button>
82
- </CardContent>
83
- </Card>
84
-
85
- <Card>
86
- <CardHeader>
87
- <CardTitle className="text-base">
88
- {t("settings.editorTitle")}
89
- </CardTitle>
90
- <CardDescription>{t("settings.editorDescription")}</CardDescription>
91
- </CardHeader>
92
- <CardContent>
93
- <Button variant="outline" asChild>
94
- <a
95
- href="https://marketplace.visualstudio.com/items?itemName=Builder.agent-native"
96
- target="_blank"
97
- rel="noreferrer noopener"
98
- >
99
- {t("settings.openEditorExtension")}
100
- </a>
101
- </Button>
102
- </CardContent>
103
- </Card>
104
-
105
- <ChangelogSettingsCard markdown={changelog} />
106
- </main>
72
+ <Card>
73
+ <CardHeader>
74
+ <CardTitle className="text-base">
75
+ {t("settings.editorTitle")}
76
+ </CardTitle>
77
+ <CardDescription>
78
+ {t("settings.editorDescription")}
79
+ </CardDescription>
80
+ </CardHeader>
81
+ <CardContent>
82
+ <Button variant="outline" asChild>
83
+ <a
84
+ href="https://marketplace.visualstudio.com/items?itemName=Builder.agent-native"
85
+ target="_blank"
86
+ rel="noreferrer noopener"
87
+ >
88
+ {t("settings.openEditorExtension")}
89
+ </a>
90
+ </Button>
91
+ </CardContent>
92
+ </Card>
93
+ </div>
94
+ }
95
+ team={
96
+ <div className="mx-auto w-full max-w-3xl">
97
+ <TeamPage
98
+ showTitle={false}
99
+ createOrgDescription="Set up a team to share this app with your colleagues."
100
+ />
101
+ </div>
102
+ }
103
+ whatsNew={
104
+ <div className="mx-auto w-full max-w-3xl">
105
+ <ChangelogSettingsCard markdown={changelog} />
106
+ </div>
107
+ }
108
+ />
107
109
  );
108
110
  }