@agent-native/core 0.7.81 → 0.7.82

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 (241) hide show
  1. package/dist/action.d.ts +8 -0
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +4 -0
  4. package/dist/action.js.map +1 -1
  5. package/dist/agent/production-agent.d.ts +12 -2
  6. package/dist/agent/production-agent.d.ts.map +1 -1
  7. package/dist/agent/production-agent.js +58 -20
  8. package/dist/agent/production-agent.js.map +1 -1
  9. package/dist/agent/run-manager.d.ts +8 -1
  10. package/dist/agent/run-manager.d.ts.map +1 -1
  11. package/dist/agent/run-manager.js +11 -12
  12. package/dist/agent/run-manager.js.map +1 -1
  13. package/dist/agent/thread-data-builder.d.ts.map +1 -1
  14. package/dist/agent/thread-data-builder.js +13 -17
  15. package/dist/agent/thread-data-builder.js.map +1 -1
  16. package/dist/agent/types.d.ts +4 -0
  17. package/dist/agent/types.d.ts.map +1 -1
  18. package/dist/agent/types.js.map +1 -1
  19. package/dist/application-state/handlers.d.ts.map +1 -1
  20. package/dist/application-state/handlers.js +3 -8
  21. package/dist/application-state/handlers.js.map +1 -1
  22. package/dist/application-state/script-helpers.d.ts +2 -4
  23. package/dist/application-state/script-helpers.d.ts.map +1 -1
  24. package/dist/application-state/script-helpers.js +10 -47
  25. package/dist/application-state/script-helpers.js.map +1 -1
  26. package/dist/cli/workspace-dev.js +78 -15
  27. package/dist/cli/workspace-dev.js.map +1 -1
  28. package/dist/client/AgentPanel.d.ts.map +1 -1
  29. package/dist/client/AgentPanel.js +6 -2
  30. package/dist/client/AgentPanel.js.map +1 -1
  31. package/dist/client/AssistantChat.d.ts +0 -15
  32. package/dist/client/AssistantChat.d.ts.map +1 -1
  33. package/dist/client/AssistantChat.js +69 -57
  34. package/dist/client/AssistantChat.js.map +1 -1
  35. package/dist/client/ConnectBuilderCard.d.ts +7 -1
  36. package/dist/client/ConnectBuilderCard.d.ts.map +1 -1
  37. package/dist/client/ConnectBuilderCard.js +46 -5
  38. package/dist/client/ConnectBuilderCard.js.map +1 -1
  39. package/dist/client/ErrorBoundary.d.ts.map +1 -1
  40. package/dist/client/ErrorBoundary.js +20 -5
  41. package/dist/client/ErrorBoundary.js.map +1 -1
  42. package/dist/client/FeedbackButton.d.ts.map +1 -1
  43. package/dist/client/FeedbackButton.js +5 -1
  44. package/dist/client/FeedbackButton.js.map +1 -1
  45. package/dist/client/agent-chat-adapter.d.ts.map +1 -1
  46. package/dist/client/agent-chat-adapter.js +303 -169
  47. package/dist/client/agent-chat-adapter.js.map +1 -1
  48. package/dist/client/builder-frame.d.ts +25 -0
  49. package/dist/client/builder-frame.d.ts.map +1 -1
  50. package/dist/client/builder-frame.js +40 -0
  51. package/dist/client/builder-frame.js.map +1 -1
  52. package/dist/client/composer/ComposerPlusMenu.d.ts.map +1 -1
  53. package/dist/client/composer/ComposerPlusMenu.js +7 -2
  54. package/dist/client/composer/ComposerPlusMenu.js.map +1 -1
  55. package/dist/client/composer/PastedTextChip.d.ts +9 -0
  56. package/dist/client/composer/PastedTextChip.d.ts.map +1 -0
  57. package/dist/client/composer/PastedTextChip.js +47 -0
  58. package/dist/client/composer/PastedTextChip.js.map +1 -0
  59. package/dist/client/composer/PromptComposer.d.ts +2 -2
  60. package/dist/client/composer/PromptComposer.d.ts.map +1 -1
  61. package/dist/client/composer/PromptComposer.js +32 -4
  62. package/dist/client/composer/PromptComposer.js.map +1 -1
  63. package/dist/client/composer/TiptapComposer.d.ts +11 -1
  64. package/dist/client/composer/TiptapComposer.d.ts.map +1 -1
  65. package/dist/client/composer/TiptapComposer.js +49 -16
  66. package/dist/client/composer/TiptapComposer.js.map +1 -1
  67. package/dist/client/composer/VoiceButton.d.ts.map +1 -1
  68. package/dist/client/composer/VoiceButton.js +5 -1
  69. package/dist/client/composer/VoiceButton.js.map +1 -1
  70. package/dist/client/composer/pasted-text.d.ts +6 -0
  71. package/dist/client/composer/pasted-text.d.ts.map +1 -0
  72. package/dist/client/composer/pasted-text.js +49 -0
  73. package/dist/client/composer/pasted-text.js.map +1 -0
  74. package/dist/client/composer/useVoiceDictation.d.ts +1 -0
  75. package/dist/client/composer/useVoiceDictation.d.ts.map +1 -1
  76. package/dist/client/composer/useVoiceDictation.js +18 -0
  77. package/dist/client/composer/useVoiceDictation.js.map +1 -1
  78. package/dist/client/index.d.ts +0 -1
  79. package/dist/client/index.d.ts.map +1 -1
  80. package/dist/client/index.js +0 -1
  81. package/dist/client/index.js.map +1 -1
  82. package/dist/client/integrations/IntegrationCard.d.ts.map +1 -1
  83. package/dist/client/integrations/IntegrationCard.js +14 -2
  84. package/dist/client/integrations/IntegrationCard.js.map +1 -1
  85. package/dist/client/integrations/IntegrationsPanel.d.ts.map +1 -1
  86. package/dist/client/integrations/IntegrationsPanel.js +19 -3
  87. package/dist/client/integrations/IntegrationsPanel.js.map +1 -1
  88. package/dist/client/notifications/NotificationsBell.d.ts.map +1 -1
  89. package/dist/client/notifications/NotificationsBell.js +4 -42
  90. package/dist/client/notifications/NotificationsBell.js.map +1 -1
  91. package/dist/client/org/OrgSwitcher.d.ts +4 -6
  92. package/dist/client/org/OrgSwitcher.d.ts.map +1 -1
  93. package/dist/client/org/OrgSwitcher.js +84 -74
  94. package/dist/client/org/OrgSwitcher.js.map +1 -1
  95. package/dist/client/org/TeamPage.d.ts.map +1 -1
  96. package/dist/client/org/TeamPage.js +3 -154
  97. package/dist/client/org/TeamPage.js.map +1 -1
  98. package/dist/client/resources/ResourcesPanel.d.ts.map +1 -1
  99. package/dist/client/resources/ResourcesPanel.js +13 -35
  100. package/dist/client/resources/ResourcesPanel.js.map +1 -1
  101. package/dist/client/settings/SettingsPanel.js +1 -1
  102. package/dist/client/settings/SettingsPanel.js.map +1 -1
  103. package/dist/client/settings/useBuilderStatus.d.ts +6 -0
  104. package/dist/client/settings/useBuilderStatus.d.ts.map +1 -1
  105. package/dist/client/settings/useBuilderStatus.js +3 -0
  106. package/dist/client/settings/useBuilderStatus.js.map +1 -1
  107. package/dist/client/sse-event-processor.d.ts +15 -1
  108. package/dist/client/sse-event-processor.d.ts.map +1 -1
  109. package/dist/client/sse-event-processor.js +58 -54
  110. package/dist/client/sse-event-processor.js.map +1 -1
  111. package/dist/client/tools/ToolEditor.d.ts.map +1 -1
  112. package/dist/client/tools/ToolEditor.js +34 -4
  113. package/dist/client/tools/ToolEditor.js.map +1 -1
  114. package/dist/client/tools/ToolViewer.d.ts.map +1 -1
  115. package/dist/client/tools/ToolViewer.js +20 -1
  116. package/dist/client/tools/ToolViewer.js.map +1 -1
  117. package/dist/client/tools/ToolsListPage.d.ts.map +1 -1
  118. package/dist/client/tools/ToolsListPage.js +2 -1
  119. package/dist/client/tools/ToolsListPage.js.map +1 -1
  120. package/dist/client/transcription/BuilderTranscriptionCta.js +1 -1
  121. package/dist/client/transcription/BuilderTranscriptionCta.js.map +1 -1
  122. package/dist/client/use-chat-threads.d.ts.map +1 -1
  123. package/dist/client/use-chat-threads.js +7 -2
  124. package/dist/client/use-chat-threads.js.map +1 -1
  125. package/dist/collab/client.d.ts.map +1 -1
  126. package/dist/collab/client.js +26 -7
  127. package/dist/collab/client.js.map +1 -1
  128. package/dist/jobs/scheduler.js +0 -4
  129. package/dist/jobs/scheduler.js.map +1 -1
  130. package/dist/oauth-tokens/store.d.ts +0 -4
  131. package/dist/oauth-tokens/store.d.ts.map +1 -1
  132. package/dist/oauth-tokens/store.js +3 -24
  133. package/dist/oauth-tokens/store.js.map +1 -1
  134. package/dist/observability/routes.d.ts.map +1 -1
  135. package/dist/observability/routes.js +1 -9
  136. package/dist/observability/routes.js.map +1 -1
  137. package/dist/onboarding/default-steps.js +1 -1
  138. package/dist/onboarding/default-steps.js.map +1 -1
  139. package/dist/onboarding/plugin.d.ts.map +1 -1
  140. package/dist/onboarding/plugin.js +1 -8
  141. package/dist/onboarding/plugin.js.map +1 -1
  142. package/dist/org/accept-pending.d.ts.map +1 -1
  143. package/dist/org/accept-pending.js +1 -2
  144. package/dist/org/accept-pending.js.map +1 -1
  145. package/dist/org/context.d.ts +0 -2
  146. package/dist/org/context.d.ts.map +1 -1
  147. package/dist/org/context.js +0 -5
  148. package/dist/org/context.js.map +1 -1
  149. package/dist/resources/script-helpers.d.ts +3 -4
  150. package/dist/resources/script-helpers.d.ts.map +1 -1
  151. package/dist/resources/script-helpers.js +8 -15
  152. package/dist/resources/script-helpers.js.map +1 -1
  153. package/dist/scripts/chat/search-chats.d.ts.map +1 -1
  154. package/dist/scripts/chat/search-chats.js +4 -4
  155. package/dist/scripts/chat/search-chats.js.map +1 -1
  156. package/dist/scripts/manage-agent-loop-settings.js +2 -2
  157. package/dist/scripts/manage-agent-loop-settings.js.map +1 -1
  158. package/dist/scripts/resources/delete-memory.d.ts.map +1 -1
  159. package/dist/scripts/resources/delete-memory.js +4 -2
  160. package/dist/scripts/resources/delete-memory.js.map +1 -1
  161. package/dist/scripts/resources/delete.d.ts.map +1 -1
  162. package/dist/scripts/resources/delete.js +11 -4
  163. package/dist/scripts/resources/delete.js.map +1 -1
  164. package/dist/scripts/resources/list.d.ts.map +1 -1
  165. package/dist/scripts/resources/list.js +5 -3
  166. package/dist/scripts/resources/list.js.map +1 -1
  167. package/dist/scripts/resources/migrate-learnings.d.ts.map +1 -1
  168. package/dist/scripts/resources/migrate-learnings.js +5 -2
  169. package/dist/scripts/resources/migrate-learnings.js.map +1 -1
  170. package/dist/scripts/resources/read.d.ts.map +1 -1
  171. package/dist/scripts/resources/read.js +4 -2
  172. package/dist/scripts/resources/read.js.map +1 -1
  173. package/dist/scripts/resources/save-memory.d.ts.map +1 -1
  174. package/dist/scripts/resources/save-memory.js +4 -2
  175. package/dist/scripts/resources/save-memory.js.map +1 -1
  176. package/dist/scripts/resources/write.d.ts.map +1 -1
  177. package/dist/scripts/resources/write.js +11 -4
  178. package/dist/scripts/resources/write.js.map +1 -1
  179. package/dist/secrets/onboarding.d.ts.map +1 -1
  180. package/dist/secrets/onboarding.js +1 -9
  181. package/dist/secrets/onboarding.js.map +1 -1
  182. package/dist/secrets/routes.d.ts.map +1 -1
  183. package/dist/secrets/routes.js +2 -7
  184. package/dist/secrets/routes.js.map +1 -1
  185. package/dist/server/action-discovery.d.ts.map +1 -1
  186. package/dist/server/action-discovery.js +4 -0
  187. package/dist/server/action-discovery.js.map +1 -1
  188. package/dist/server/agent-chat-plugin.d.ts +5 -0
  189. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  190. package/dist/server/agent-chat-plugin.js +81 -20
  191. package/dist/server/agent-chat-plugin.js.map +1 -1
  192. package/dist/server/agent-discovery.d.ts.map +1 -1
  193. package/dist/server/agent-discovery.js +5 -7
  194. package/dist/server/agent-discovery.js.map +1 -1
  195. package/dist/server/auth.d.ts +16 -21
  196. package/dist/server/auth.d.ts.map +1 -1
  197. package/dist/server/auth.js +45 -315
  198. package/dist/server/auth.js.map +1 -1
  199. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  200. package/dist/server/core-routes-plugin.js +22 -13
  201. package/dist/server/core-routes-plugin.js.map +1 -1
  202. package/dist/server/credential-provider.d.ts.map +1 -1
  203. package/dist/server/credential-provider.js +1 -2
  204. package/dist/server/credential-provider.js.map +1 -1
  205. package/dist/server/google-oauth.d.ts +14 -2
  206. package/dist/server/google-oauth.d.ts.map +1 -1
  207. package/dist/server/google-oauth.js +17 -7
  208. package/dist/server/google-oauth.js.map +1 -1
  209. package/dist/server/index.d.ts +1 -1
  210. package/dist/server/index.d.ts.map +1 -1
  211. package/dist/server/index.js +1 -1
  212. package/dist/server/index.js.map +1 -1
  213. package/dist/server/oauth-helpers.d.ts +2 -4
  214. package/dist/server/oauth-helpers.d.ts.map +1 -1
  215. package/dist/server/oauth-helpers.js +2 -4
  216. package/dist/server/oauth-helpers.js.map +1 -1
  217. package/dist/server/transcribe-voice.d.ts.map +1 -1
  218. package/dist/server/transcribe-voice.js +2 -4
  219. package/dist/server/transcribe-voice.js.map +1 -1
  220. package/dist/triggers/dispatcher.d.ts.map +1 -1
  221. package/dist/triggers/dispatcher.js +0 -3
  222. package/dist/triggers/dispatcher.js.map +1 -1
  223. package/dist/vite/client.d.ts.map +1 -1
  224. package/dist/vite/client.js +6 -0
  225. package/dist/vite/client.js.map +1 -1
  226. package/docs/content/actions.md +1 -0
  227. package/docs/content/authentication.md +3 -20
  228. package/docs/content/creating-templates.md +1 -1
  229. package/docs/content/deployment.md +0 -1
  230. package/docs/content/security.md +0 -1
  231. package/docs/content/template-content.md +1 -1
  232. package/docs/content/template-starter.md +1 -1
  233. package/package.json +1 -1
  234. package/dist/client/dev-mode.d.ts +0 -14
  235. package/dist/client/dev-mode.d.ts.map +0 -1
  236. package/dist/client/dev-mode.js +0 -14
  237. package/dist/client/dev-mode.js.map +0 -1
  238. package/dist/server/local-migration.d.ts +0 -41
  239. package/dist/server/local-migration.d.ts.map +0 -1
  240. package/dist/server/local-migration.js +0 -235
  241. package/dist/server/local-migration.js.map +0 -1
@@ -34,11 +34,10 @@ function toWebRequest(event) {
34
34
  }
35
35
  return req;
36
36
  }
37
- import { getDbExec, isPostgres, intType, isLocalDatabase, retryOnDdlRace, } from "../db/client.js";
37
+ import { getDbExec, isPostgres, intType, retryOnDdlRace, } from "../db/client.js";
38
38
  import { getBetterAuth, getBetterAuthSync } from "./better-auth-instance.js";
39
39
  import { getAllowedCorsOrigin, readCorsAllowedOrigins, } from "./cors-origins.js";
40
40
  import { getOnboardingHtml, getResetPasswordHtml } from "./onboarding-html.js";
41
- import { migrateLocalUserData } from "./local-migration.js";
42
41
  import { readBody } from "../server/h3-helpers.js";
43
42
  import { readDesktopSso, writeDesktopSso, clearDesktopSso, } from "./desktop-sso.js";
44
43
  import { isElectron as isElectronRequest, getAppBasePath, getAppUrl, encodeOAuthState, decodeOAuthState, createOAuthSession, oauthCallbackResponse, oauthErrorPage, resolveOAuthRedirectUri, isAllowedOAuthRedirectUri, } from "./google-oauth.js";
@@ -82,36 +81,8 @@ function getOAuthStateAppId() {
82
81
  }
83
82
  const DEFAULT_MAX_AGE = 60 * 60 * 24 * 30; // 30 days
84
83
  // ---------------------------------------------------------------------------
85
- // AUTH_MODE detection
84
+ // Environment helpers
86
85
  // ---------------------------------------------------------------------------
87
- let _warnedRemoteLocalMode = false;
88
- /**
89
- * Check if the app is in local-only mode (no auth).
90
- *
91
- * Returns true when AUTH_MODE=local is explicitly set.
92
- *
93
- * Local mode is an explicit escape hatch for when you want to guarantee
94
- * no auth is used. In development, getSession() also falls back to
95
- * local@localhost automatically if no other auth method succeeds, so
96
- * apps are always usable without configuration in dev.
97
- *
98
- * Refuses to enable on any non-local database (Postgres, Turso, D1): local
99
- * mode uses a single shared virtual user with no per-machine scoping, so on
100
- * a shared DB every developer would land on the same account and collide.
101
- */
102
- async function isLocalModeEnabled() {
103
- if (process.env.AUTH_MODE !== "local")
104
- return false;
105
- if (!isLocalDatabase()) {
106
- if (!_warnedRemoteLocalMode) {
107
- _warnedRemoteLocalMode = true;
108
- console.warn("[agent-native] AUTH_MODE=local ignored: database is not local SQLite. " +
109
- "local@localhost has no per-user scoping and would collide across developers on a shared DB.");
110
- }
111
- return false;
112
- }
113
- return true;
114
- }
115
86
  /**
116
87
  * Check if we're in a development/test environment.
117
88
  * Used for cookie security settings, not for auth bypass.
@@ -348,7 +319,6 @@ export async function getSessionEmail(token) {
348
319
  // getSession — the auth contract
349
320
  // ---------------------------------------------------------------------------
350
321
  let customGetSession = null;
351
- let authDisabledMode = false;
352
322
  let _authGuardConfig = null;
353
323
  const _genericGoogleOAuthRoutesEnabled = new WeakMap();
354
324
  function setGenericGoogleOAuthRoutesEnabled(app, enabled) {
@@ -477,17 +447,6 @@ export async function runAuthGuard(event) {
477
447
  return; // Auth not mounted (local mode, etc.)
478
448
  return _authGuardFn(event);
479
449
  }
480
- /**
481
- * The framework's dev-mode bypass identity. When `AUTH_MODE=local` (or
482
- * dev-mode falls back), `getSession()` returns `{ email: DEV_MODE_USER_EMAIL }`.
483
- * Production code that needs to check whether the current request is the
484
- * dev-mode user (or filter it out of mailers, dashboards, etc.) should
485
- * compare against this constant instead of inlining the literal —
486
- * `guard-no-localhost-fallback.mjs` blocks the literal everywhere except
487
- * `auth.ts` and a handful of dev-mode helpers.
488
- */
489
- export const DEV_MODE_USER_EMAIL = "local@localhost";
490
- const LOCAL_SESSION = { email: DEV_MODE_USER_EMAIL };
491
450
  // ---------------------------------------------------------------------------
492
451
  // Auth guard factory
493
452
  // ---------------------------------------------------------------------------
@@ -524,6 +483,24 @@ function applyCorsHeaders(event) {
524
483
  setResponseHeader(event, "Access-Control-Allow-Headers", "Content-Type,Authorization,X-Requested-With,X-Request-Source,X-Agent-Native-CSRF");
525
484
  return { hasOrigin: true, allowed: true };
526
485
  }
486
+ function createAuthCorsHandler() {
487
+ return defineEventHandler((event) => {
488
+ const cors = applyCorsHeaders(event);
489
+ if (getMethod(event) !== "OPTIONS")
490
+ return;
491
+ if (cors.hasOrigin && !cors.allowed) {
492
+ setResponseStatus(event, 403);
493
+ return "";
494
+ }
495
+ setResponseStatus(event, 204);
496
+ return "";
497
+ });
498
+ }
499
+ function mountAuthCorsMiddleware(app) {
500
+ const handler = createAuthCorsHandler();
501
+ app.use("/_agent-native/auth", handler);
502
+ app.use("/_agent-native/google", handler);
503
+ }
527
504
  function createAuthGuardFn() {
528
505
  return async (event) => {
529
506
  const config = _authGuardConfig;
@@ -628,8 +605,8 @@ function createAuthGuardFn() {
628
605
  });
629
606
  }
630
607
  // Auth entry pages are framework-owned pages, not app routes. When a user
631
- // already has a session (including AUTH_MODE=local), redirect them back to
632
- // the mounted app instead of letting React Router try to render /login.
608
+ // already has a session, redirect them back to the mounted app instead of
609
+ // letting React Router try to render /login.
633
610
  if (p === "/login" || p === "/signup") {
634
611
  const session = await getSession(event);
635
612
  if (session) {
@@ -687,51 +664,20 @@ function mapBetterAuthSession(baSession) {
687
664
  * Get the current auth session for a request.
688
665
  *
689
666
  * Resolution chain:
690
- * 1. AUTH_MODE=locallocal@localhost (explicit escape hatch)
691
- * 2. AUTH_DISABLED=truelocal@localhost (infrastructure auth)
692
- * 3. ACCESS_TOKEN → check legacy cookie-based token sessions
693
- * 4. BYOA custom getSession delegate to template callback
694
- * 5. Better Auth check session via Better Auth API (cookie or Bearer)
695
- * 6. Legacy cookiecheck an_session cookie in legacy sessions table
696
- * 7. Mobile _session query param → promote to cookie
697
- * 8. Dev-mode fallback local@localhost (never block in development)
667
+ * 1. ACCESS_TOKENcheck legacy cookie-based token sessions
668
+ * 2. BYOA custom getSession delegate to template callback
669
+ * 3. Better Auth → check session via Better Auth API (cookie or Bearer)
670
+ * 4. Legacy cookiecheck an_session cookie in legacy sessions table
671
+ * 5. Desktop SSO broker (Electron loopback only)
672
+ * 6. Mobile _session query param promote to cookie
673
+ *
674
+ * Returns `null` for unauthenticated requests. There is no dev-mode bypass:
675
+ * local development uses the same Better Auth signup flow as production. The
676
+ * onboarding/sign-in page is served by `runAuthGuard` for any unauthenticated
677
+ * page load.
698
678
  */
699
679
  export async function getSession(event) {
700
- // 1. AUTH_MODE=local explicit local-only mode
701
- if ((await isLocalModeEnabled()) || authDisabledMode) {
702
- // Check for a real session cookie first (e.g. from Google OAuth)
703
- try {
704
- const cookie = getCookie(event, COOKIE_NAME);
705
- if (cookie) {
706
- const email = await getSessionEmail(cookie);
707
- if (email)
708
- return { email, token: cookie };
709
- }
710
- }
711
- catch {
712
- // DB not ready yet
713
- }
714
- // Also try Better Auth session (for users who created an account then went local)
715
- try {
716
- const ba = getBetterAuthSync();
717
- if (ba) {
718
- const baSession = await ba.api.getSession({
719
- headers: event.headers,
720
- });
721
- if (baSession?.user?.email) {
722
- return mapBetterAuthSession(baSession);
723
- }
724
- }
725
- }
726
- catch {
727
- // Better Auth not initialized yet
728
- }
729
- const querySession = await promoteQuerySession(event);
730
- if (querySession)
731
- return querySession;
732
- return LOCAL_SESSION;
733
- }
734
- // 2. ACCESS_TOKEN check (programmatic/agent access)
680
+ // 1. ACCESS_TOKEN check (programmatic/agent access)
735
681
  const accessTokens = getAccessTokens();
736
682
  if (accessTokens.length > 0) {
737
683
  const cookie = getCookie(event, COOKIE_NAME);
@@ -741,7 +687,7 @@ export async function getSession(event) {
741
687
  return { email, token: cookie };
742
688
  }
743
689
  }
744
- // 3. BYOA custom getSession
690
+ // 2. BYOA custom getSession
745
691
  if (customGetSession) {
746
692
  const session = await customGetSession(event);
747
693
  if (session)
@@ -757,7 +703,7 @@ export async function getSession(event) {
757
703
  // Fall through to mobile _session check
758
704
  }
759
705
  else {
760
- // 4. Better Auth session (cookie or Bearer token)
706
+ // 3. Better Auth session (cookie or Bearer token)
761
707
  try {
762
708
  const ba = getBetterAuthSync();
763
709
  if (ba) {
@@ -765,9 +711,6 @@ export async function getSession(event) {
765
711
  headers: event.headers,
766
712
  });
767
713
  if (baSession?.user?.email) {
768
- // Successful real sign-in — clear the upgrade-pending marker so
769
- // the dev fallback becomes reachable again for future local work.
770
- clearUpgradePendingCookie(event);
771
714
  return mapBetterAuthSession(baSession);
772
715
  }
773
716
  }
@@ -775,16 +718,15 @@ export async function getSession(event) {
775
718
  catch (e) {
776
719
  console.error("[auth] ba.api.getSession error:", e);
777
720
  }
778
- // 5. Legacy cookie fallback (for sessions created before migration)
721
+ // 4. Legacy cookie fallback (for sessions created before migration)
779
722
  const cookie = getCookie(event, COOKIE_NAME);
780
723
  if (cookie) {
781
724
  const email = await getSessionEmail(cookie);
782
725
  if (email) {
783
- clearUpgradePendingCookie(event);
784
726
  return { email, token: cookie };
785
727
  }
786
728
  }
787
- // 5b. Desktop SSO broker fallback.
729
+ // 5. Desktop SSO broker fallback.
788
730
  // Each template in the Electron desktop app has its own database, so
789
731
  // a session token created by one template doesn't resolve in another.
790
732
  // When an Electron request has no resolvable session, trust the
@@ -795,7 +737,6 @@ export async function getSession(event) {
795
737
  // impersonate whichever email last signed into the desktop app.
796
738
  const sso = await readDesktopSsoSafely(event);
797
739
  if (sso?.email) {
798
- clearUpgradePendingCookie(event);
799
740
  return { email: sso.email, token: sso.token };
800
741
  }
801
742
  }
@@ -803,32 +744,6 @@ export async function getSession(event) {
803
744
  const querySession = await promoteQuerySession(event);
804
745
  if (querySession)
805
746
  return querySession;
806
- // 7. Dev-mode safety net — in development on a local SQLite database, fall
807
- // back to local@localhost so the app is usable without any auth configuration.
808
- // This prevents 401 errors when Better Auth isn't configured or the user
809
- // simply wants to play around locally.
810
- //
811
- // Gated on isLocalDatabase() because local@localhost has no per-user scoping:
812
- // on a shared DB (Postgres, Turso, D1) this fallback would land every
813
- // developer on the same account and expose each other's data.
814
- //
815
- // STRICT NODE_ENV check: this used to read `isDevEnvironment()` which
816
- // also accepted `NODE_ENV=test`, meaning a misconfigured prod deploy
817
- // started with `NODE_ENV=test` (or undefined NODE_ENV in some CI/build
818
- // contexts) would silently bypass auth entirely. Limiting to the literal
819
- // string "development" closes that footgun. Tests that need this branch
820
- // to fire stub NODE_ENV explicitly to "development".
821
- //
822
- // EXCEPTION: if the user has explicitly exited local mode (clicked "Upgrade
823
- // to real account"), they've signaled they want real auth. The upgrade
824
- // cookie suppresses this fallback so the onboarding/sign-in page is served
825
- // instead of silently re-authenticating them as local@localhost.
826
- if (process.env.NODE_ENV === "development" &&
827
- isLocalDatabase() &&
828
- !isUpgradePending(event) &&
829
- !hasSignInFlag(event)) {
830
- return LOCAL_SESSION;
831
- }
832
747
  return null;
833
748
  }
834
749
  async function promoteQuerySession(event) {
@@ -842,44 +757,6 @@ async function promoteQuerySession(event) {
842
757
  setResponseHeader(event, "Referrer-Policy", "no-referrer");
843
758
  return { email, token: qToken };
844
759
  }
845
- /**
846
- * Cookie set by POST /_agent-native/auth/exit-local-mode so we know the user
847
- * is in the middle of upgrading from local@localhost to a real account.
848
- * While this cookie is present we skip the dev-mode "auto local session"
849
- * fallback so the onboarding/sign-in page can actually render.
850
- * Cleared on successful sign-in/sign-up.
851
- */
852
- const UPGRADE_COOKIE = "an_upgrade_pending";
853
- function isUpgradePending(event) {
854
- try {
855
- return getCookie(event, UPGRADE_COOKIE) === "1";
856
- }
857
- catch {
858
- return false;
859
- }
860
- }
861
- function setUpgradePendingCookie(event) {
862
- setCookie(event, UPGRADE_COOKIE, "1", {
863
- httpOnly: true,
864
- ...crossSiteCookieAttrs(event),
865
- path: "/",
866
- maxAge: 60 * 60, // 1 hour — enough to complete sign-in
867
- });
868
- }
869
- /**
870
- * URL-flag fallback for third-party iframe contexts (e.g. the Builder.io
871
- * editor) where SameSite=Lax cookies from an exit-local-mode POST are not
872
- * delivered on the subsequent reload. TeamPage reloads with ?signin=1 so
873
- * we can reliably suppress the dev-mode local fallback without a cookie.
874
- */
875
- function hasSignInFlag(event) {
876
- try {
877
- return getQuery(event)?.signin === "1";
878
- }
879
- catch {
880
- return false;
881
- }
882
- }
883
760
  function isReadMethod(event) {
884
761
  const method = getMethod(event);
885
762
  return method === "GET" || method === "HEAD";
@@ -932,14 +809,6 @@ function isHttpsRequest(event) {
932
809
  }
933
810
  return false;
934
811
  }
935
- function clearUpgradePendingCookie(event) {
936
- try {
937
- deleteCookie(event, UPGRADE_COOKIE, { path: "/" });
938
- }
939
- catch {
940
- // ignore
941
- }
942
- }
943
812
  // ---------------------------------------------------------------------------
944
813
  // Public path matching
945
814
  // ---------------------------------------------------------------------------
@@ -1053,57 +922,6 @@ const TOKEN_LOGIN_HTML = `<!DOCTYPE html>
1053
922
  </body>
1054
923
  </html>`;
1055
924
  // ---------------------------------------------------------------------------
1056
- // Local mode route helpers
1057
- // ---------------------------------------------------------------------------
1058
- function localModeMarkerDisabled(event) {
1059
- setResponseStatus(event, 410);
1060
- return {
1061
- error: "The local-mode marker file has been removed. Set AUTH_MODE=local in your local shell or .env only for one-off local development.",
1062
- };
1063
- }
1064
- function exitLocalMode(event) {
1065
- // Mark the browser so getSession's dev-mode fallback won't silently
1066
- // re-authenticate the user as local@localhost on the next request.
1067
- setUpgradePendingCookie(event);
1068
- return { ok: true };
1069
- }
1070
- /**
1071
- * POST /_agent-native/auth/migrate-local-data handler. Exposed here (not
1072
- * inlined in a single mount function) because it must be registered from
1073
- * every auth-mount path — including local-mode and fallback — so the
1074
- * upgrade-from-local flow never 500s when BetterAuth init is skipped or
1075
- * failed. Previously this was only mounted inside mountBetterAuthRoutes()
1076
- * which meant that in local mode (or when BetterAuth failed to init) the
1077
- * request fell through to the Nitro SSR renderer and produced a 500.
1078
- */
1079
- const migrateLocalDataHandler = defineEventHandler(async (event) => {
1080
- if (getMethod(event) !== "POST") {
1081
- setResponseStatus(event, 405);
1082
- return { error: "Method not allowed" };
1083
- }
1084
- const session = await getSession(event);
1085
- if (!session?.email || session.email === "local@localhost") {
1086
- setResponseStatus(event, 401);
1087
- return { error: "Not authenticated as a real account" };
1088
- }
1089
- try {
1090
- const result = await migrateLocalUserData(session.email);
1091
- return { ok: true, ...result };
1092
- }
1093
- catch (e) {
1094
- console.error("[migrate-local-data] Migration threw for", session.email, e);
1095
- setResponseStatus(event, 500);
1096
- return {
1097
- error: e?.message || "Migration failed",
1098
- // Only surface the stack when explicitly enabled. `isDevEnvironment()`
1099
- // returns true on preview deploys and Lambda contexts that forget
1100
- // NODE_ENV=production, which leaked stack traces to clients. Use
1101
- // AGENT_NATIVE_DEBUG_ERRORS=1 for opt-in debug visibility.
1102
- stack: process.env.AGENT_NATIVE_DEBUG_ERRORS === "1" ? e?.stack : undefined,
1103
- };
1104
- }
1105
- });
1106
- // ---------------------------------------------------------------------------
1107
925
  // mountBetterAuthRoutes — Better Auth powered auth with backward-compat routes
1108
926
  // ---------------------------------------------------------------------------
1109
927
  async function mountBetterAuthRoutes(app, options) {
@@ -1470,23 +1288,6 @@ async function mountBetterAuthRoutes(app, options) {
1470
1288
  }
1471
1289
  return response;
1472
1290
  }));
1473
- // POST /_agent-native/auth/local-mode — legacy endpoint kept so old clients
1474
- // receive an explicit error instead of creating a persistent local marker.
1475
- app.use("/_agent-native/auth/local-mode", defineEventHandler(async (event) => {
1476
- if (getMethod(event) !== "POST") {
1477
- setResponseStatus(event, 405);
1478
- return { error: "Method not allowed" };
1479
- }
1480
- return localModeMarkerDisabled(event);
1481
- }));
1482
- // POST /_agent-native/auth/exit-local-mode — switch back to real auth
1483
- app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
1484
- if (getMethod(event) !== "POST") {
1485
- setResponseStatus(event, 405);
1486
- return { error: "Method not allowed" };
1487
- }
1488
- return exitLocalMode(event);
1489
- }));
1490
1291
  // Backward-compat: POST /_agent-native/auth/login
1491
1292
  app.use("/_agent-native/auth/login", defineEventHandler(async (event) => {
1492
1293
  if (getMethod(event) !== "POST") {
@@ -1677,10 +1478,6 @@ async function mountBetterAuthRoutes(app, options) {
1677
1478
  const session = await getSession(event);
1678
1479
  return session ?? { error: "Not authenticated" };
1679
1480
  }));
1680
- // POST /_agent-native/auth/migrate-local-data — move local-mode data to
1681
- // the currently signed-in account. Called by the UI after a user upgrades
1682
- // from local mode to a real account so they don't lose their data.
1683
- app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
1684
1481
  // GET /_agent-native/auth/reset — HTML page shown when a user clicks the
1685
1482
  // reset link in their email. Reads ?token=... and POSTs to Better Auth's
1686
1483
  // /reset-password endpoint on submit.
@@ -1748,38 +1545,12 @@ function mountTokenOnlyRoutes(app, accessTokens, publicPaths = []) {
1748
1545
  const session = await getSession(event);
1749
1546
  return session ?? { error: "Not authenticated" };
1750
1547
  }));
1751
- app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
1752
1548
  _authGuardConfig = { loginHtml: TOKEN_LOGIN_HTML, publicPaths };
1753
1549
  const guardFn = createAuthGuardFn();
1754
1550
  _authGuardFn = guardFn;
1755
1551
  app.use(defineEventHandler(guardFn));
1756
1552
  }
1757
1553
  // ---------------------------------------------------------------------------
1758
- // mountLocalModeRoutes — stub routes for AUTH_MODE=local
1759
- // ---------------------------------------------------------------------------
1760
- function mountLocalModeRoutes(app) {
1761
- app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
1762
- if (!isReadMethod(event)) {
1763
- setResponseStatus(event, 405);
1764
- return { error: "Method not allowed" };
1765
- }
1766
- return await getSession(event);
1767
- }));
1768
- app.use("/_agent-native/auth/login", defineEventHandler(() => ({ ok: true })));
1769
- app.use("/_agent-native/auth/logout", defineEventHandler(() => ({ ok: true })));
1770
- // Allow exiting local mode to switch to real auth
1771
- app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
1772
- if (getMethod(event) !== "POST") {
1773
- setResponseStatus(event, 405);
1774
- return { error: "Method not allowed" };
1775
- }
1776
- return exitLocalMode(event);
1777
- }));
1778
- // Upgrade path: migrate-local-data must be reachable from local mode
1779
- // because the user is still in local mode when they trigger the upgrade.
1780
- app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
1781
- }
1782
- // ---------------------------------------------------------------------------
1783
1554
  // mountAuthFallbackRoutes — minimal auth endpoints when Better Auth init fails
1784
1555
  // ---------------------------------------------------------------------------
1785
1556
  function mountAuthFallbackRoutes(app) {
@@ -1871,20 +1642,6 @@ function mountAuthFallbackRoutes(app) {
1871
1642
  await clearDesktopSso();
1872
1643
  return { ok: true };
1873
1644
  }));
1874
- app.use("/_agent-native/auth/local-mode", defineEventHandler(async (event) => {
1875
- if (getMethod(event) !== "POST") {
1876
- setResponseStatus(event, 405);
1877
- return { error: "Method not allowed" };
1878
- }
1879
- return localModeMarkerDisabled(event);
1880
- }));
1881
- app.use("/_agent-native/auth/exit-local-mode", defineEventHandler(async (event) => {
1882
- if (getMethod(event) !== "POST") {
1883
- setResponseStatus(event, 405);
1884
- return { error: "Method not allowed" };
1885
- }
1886
- return exitLocalMode(event);
1887
- }));
1888
1645
  app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
1889
1646
  if (!isReadMethod(event)) {
1890
1647
  setResponseStatus(event, 405);
@@ -1893,10 +1650,6 @@ function mountAuthFallbackRoutes(app) {
1893
1650
  const session = await getSession(event);
1894
1651
  return session ?? { error: "Not authenticated" };
1895
1652
  }));
1896
- // Must be reachable from fallback mode too — otherwise a user who
1897
- // upgrades-from-local on a server that couldn't init Better Auth gets a
1898
- // 500 instead of a clear 401.
1899
- app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
1900
1653
  }
1901
1654
  // ---------------------------------------------------------------------------
1902
1655
  // autoMountAuth — the recommended entry point
@@ -1904,14 +1657,16 @@ function mountAuthFallbackRoutes(app) {
1904
1657
  /**
1905
1658
  * Automatically configure auth based on environment and configuration:
1906
1659
  *
1907
- * - **AUTH_MODE=local**: Auth bypassed. `getSession()` returns `{ email: "local@localhost" }`.
1908
- * This is the explicit escape hatch for solo local development.
1909
1660
  * - **BYOA (custom getSession)**: Template-provided auth callback handles everything.
1910
- * - **AUTH_DISABLED=true**: Auth bypassed (for infrastructure-level auth like Cloudflare Access).
1911
1661
  * - **ACCESS_TOKEN/ACCESS_TOKENS**: Simple token-based auth.
1912
1662
  * - **Default**: Better Auth with email/password, social providers, organizations, and JWT.
1913
1663
  * Users see an onboarding page to create an account on first visit.
1914
1664
  *
1665
+ * Local development uses the same Better Auth flow as production. Email
1666
+ * verification is automatically skipped in dev/test environments and when
1667
+ * no email provider is configured (see `shouldSkipEmailVerification`), so a
1668
+ * fresh local clone only needs an email + password to get started.
1669
+ *
1915
1670
  * Returns true if auth was mounted, false if skipped.
1916
1671
  */
1917
1672
  export async function autoMountAuth(app, options = {}) {
@@ -1959,8 +1714,7 @@ export async function autoMountAuth(app, options = {}) {
1959
1714
  _authGuardConfig = null;
1960
1715
  _mountedApp = app;
1961
1716
  if (!app) {
1962
- if ((await isLocalModeEnabled()) || isDevEnvironment()) {
1963
- authDisabledMode = false;
1717
+ if (isDevEnvironment()) {
1964
1718
  customGetSession = null;
1965
1719
  return false;
1966
1720
  }
@@ -1968,27 +1722,12 @@ export async function autoMountAuth(app, options = {}) {
1968
1722
  }
1969
1723
  // Reset globals
1970
1724
  customGetSession = null;
1971
- authDisabledMode = false;
1972
1725
  sessionMaxAge = options.maxAge ?? DEFAULT_MAX_AGE;
1973
1726
  const publicPaths = options.publicPaths ?? [];
1727
+ mountAuthCorsMiddleware(app);
1974
1728
  if (options.getSession) {
1975
1729
  customGetSession = options.getSession;
1976
1730
  }
1977
- // AUTH_MODE=local — explicit local-only mode (escape hatch)
1978
- if (await isLocalModeEnabled()) {
1979
- try {
1980
- // Mount the standard auth endpoints and guard even in local mode so the
1981
- // app can switch back to real auth immediately after AUTH_MODE is
1982
- // cleared, without waiting for a server restart/remount.
1983
- await mountBetterAuthRoutes(app, options);
1984
- }
1985
- catch (err) {
1986
- console.error("[agent-native] Failed to initialize Better Auth in local mode:", err);
1987
- mountLocalModeRoutes(app);
1988
- }
1989
- console.log("[agent-native] Auth mode: local (upgrade path enabled).");
1990
- return false;
1991
- }
1992
1731
  // BYOA — custom getSession provider
1993
1732
  if (customGetSession) {
1994
1733
  app.use("/_agent-native/auth/session", defineEventHandler(async (event) => {
@@ -2009,7 +1748,6 @@ export async function autoMountAuth(app, options = {}) {
2009
1748
  await clearDesktopSso();
2010
1749
  return { ok: true };
2011
1750
  }));
2012
- app.use("/_agent-native/auth/migrate-local-data", migrateLocalDataHandler);
2013
1751
  const byoaLoginHtml = options.loginHtml ?? TOKEN_LOGIN_HTML;
2014
1752
  _authGuardConfig = { loginHtml: byoaLoginHtml, publicPaths };
2015
1753
  const guardFn = createAuthGuardFn();
@@ -2019,14 +1757,6 @@ export async function autoMountAuth(app, options = {}) {
2019
1757
  console.log("[agent-native] Auth enabled — custom getSession provider.");
2020
1758
  return true;
2021
1759
  }
2022
- // AUTH_DISABLED — skip auth (infrastructure-level auth)
2023
- if (process.env.AUTH_DISABLED === "true") {
2024
- authDisabledMode = true;
2025
- console.warn("[agent-native] AUTH_DISABLED=true — running without auth. " +
2026
- "Ensure this app is behind infrastructure-level auth (Cloudflare Access, VPN, etc.).");
2027
- mountLocalModeRoutes(app);
2028
- return false;
2029
- }
2030
1760
  // ACCESS_TOKEN-only mode
2031
1761
  const tokens = getAccessTokens();
2032
1762
  if (tokens.length > 0) {