@agent-native/core 0.145.6 → 0.145.8

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 (95) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +5 -1
  3. package/corpus/templates/analytics/app/pages/settings/AlertRulesSettingsCard.tsx +3 -2
  4. package/corpus/templates/analytics/changelog/2026-08-07-analytics-no-longer-stalls-under-bursts-of-event-ingest-key-.md +6 -0
  5. package/corpus/templates/analytics/changelog/2026-08-07-settings-skeleton-placeholders.md +6 -0
  6. package/corpus/templates/analytics/netlify.toml +1 -1
  7. package/corpus/templates/analytics/package.json +1 -0
  8. package/corpus/templates/analytics/scripts/migrate-production.ts +24 -0
  9. package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +9 -0
  10. package/corpus/templates/analytics/server/lib/first-party-analytics.ts +65 -10
  11. package/corpus/templates/analytics/server/lib/session-replay.ts +5 -5
  12. package/corpus/templates/analytics/server/plugins/db.ts +14 -3
  13. package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +5 -1
  14. package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +5 -1
  15. package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +5 -1
  16. package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -1
  17. package/corpus/templates/chat/AGENTS.md +3 -0
  18. package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +5 -1
  19. package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +5 -1
  20. package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +21 -3
  21. package/corpus/templates/crm/app/components/crm/settings/ConnectionSettings.tsx +23 -5
  22. package/corpus/templates/crm/app/components/crm/settings/FieldsSettings.tsx +24 -5
  23. package/corpus/templates/crm/app/components/crm/settings/ListsSettings.tsx +23 -3
  24. package/corpus/templates/crm/changelog/2026-08-07-settings-loading-skeletons.md +6 -0
  25. package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +5 -1
  26. package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +5 -1
  27. package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +5 -1
  28. package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +5 -1
  29. package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +5 -1
  30. package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +5 -1
  31. package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +5 -1
  32. package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +5 -1
  33. package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +5 -1
  34. package/dist/client/components/ApiKeySettings.js +2 -5
  35. package/dist/client/org/TeamPage.js +4 -2
  36. package/dist/client/settings/AccountSettingsCard.js +2 -1
  37. package/dist/client/settings/AgentsSection.js +2 -1
  38. package/dist/client/settings/SecretsSection.js +3 -2
  39. package/dist/client/settings/SettingsPanel.js +6 -12
  40. package/dist/client/settings/SettingsSkeleton.d.ts +12 -0
  41. package/dist/client/settings/SettingsSkeleton.js +12 -0
  42. package/dist/client/settings/VoiceTranscriptionSection.js +5 -4
  43. package/dist/client/settings/index.d.ts +1 -0
  44. package/dist/client/settings/index.js +1 -0
  45. package/dist/client/use-db-sync.js +4 -0
  46. package/dist/collab/routes.d.ts +1 -1
  47. package/dist/db/client.d.ts +13 -7
  48. package/dist/db/client.js +124 -7
  49. package/dist/db/ddl-guard.js +3 -1
  50. package/dist/db/ensure-additive-columns.d.ts +2 -0
  51. package/dist/db/ensure-additive-columns.js +5 -2
  52. package/dist/db/index.d.ts +2 -2
  53. package/dist/db/index.js +2 -2
  54. package/dist/db/migrations.d.ts +11 -54
  55. package/dist/db/migrations.js +70 -0
  56. package/dist/jobs/index.d.ts +1 -0
  57. package/dist/jobs/index.js +1 -0
  58. package/dist/jobs/run-history.d.ts +4 -0
  59. package/dist/jobs/run-history.js +44 -0
  60. package/dist/notifications/routes.d.ts +3 -3
  61. package/dist/observability/routes.d.ts +3 -3
  62. package/dist/progress/routes.d.ts +1 -1
  63. package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
  64. package/dist/provider-api/actions/provider-api.d.ts +12 -12
  65. package/dist/provider-api/corpus-jobs.d.ts +2 -2
  66. package/dist/secrets/routes.d.ts +6 -6
  67. package/dist/server/agent-chat-plugin.js +6 -4
  68. package/dist/server/auth-plugin.js +5 -0
  69. package/dist/server/better-auth-instance.js +0 -61
  70. package/dist/server/better-auth-migrations.d.ts +8 -0
  71. package/dist/server/better-auth-migrations.js +179 -0
  72. package/dist/server/edge.d.ts +2 -0
  73. package/dist/server/edge.js +2 -0
  74. package/dist/server/index.d.ts +2 -0
  75. package/dist/server/index.js +2 -0
  76. package/dist/server/release-migrations.d.ts +8 -0
  77. package/dist/server/release-migrations.js +24 -0
  78. package/dist/server/sweep-runtime.d.ts +1 -1
  79. package/dist/server/sweep-runtime.js +15 -0
  80. package/dist/server/transcribe-voice.d.ts +1 -1
  81. package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -1
  82. package/dist/templates/chat/AGENTS.md +3 -0
  83. package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +5 -1
  84. package/dist/templates/default/AGENTS.md +3 -0
  85. package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +5 -1
  86. package/dist/templates/workspace-core/AGENTS.md +3 -0
  87. package/dist/templates/workspace-root/AGENTS.md +3 -0
  88. package/package.json +1 -1
  89. package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -1
  90. package/src/templates/chat/AGENTS.md +3 -0
  91. package/src/templates/default/.agents/skills/frontend-design/SKILL.md +5 -1
  92. package/src/templates/default/AGENTS.md +3 -0
  93. package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +5 -1
  94. package/src/templates/workspace-core/AGENTS.md +3 -0
  95. package/src/templates/workspace-root/AGENTS.md +3 -0
@@ -75,8 +75,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
75
75
  user: "user";
76
76
  }>>;
77
77
  }, z.core.$strip>>, {
78
- id?: undefined;
78
+ message?: undefined;
79
79
  deleted?: undefined;
80
+ found?: undefined;
80
81
  providers: {
81
82
  id: string;
82
83
  label: string;
@@ -88,21 +89,21 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
88
89
  }[];
89
90
  count: number;
90
91
  provider?: undefined;
91
- found?: undefined;
92
92
  registered?: undefined;
93
+ id?: undefined;
93
94
  label?: undefined;
94
- message?: undefined;
95
95
  } | {
96
- id?: undefined;
96
+ message?: undefined;
97
97
  deleted?: undefined;
98
98
  providers?: undefined;
99
99
  count?: undefined;
100
100
  found: boolean;
101
101
  provider: import("../custom-registry.js").CustomProviderConfig;
102
102
  registered?: undefined;
103
+ id?: undefined;
103
104
  label?: undefined;
104
- message?: undefined;
105
105
  } | {
106
+ message?: undefined;
106
107
  deleted?: undefined;
107
108
  providers?: undefined;
108
109
  count?: undefined;
@@ -111,23 +112,22 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
111
112
  id: string;
112
113
  registered?: undefined;
113
114
  label?: undefined;
114
- message?: undefined;
115
115
  } | {
116
+ message?: undefined;
117
+ found?: undefined;
116
118
  providers?: undefined;
117
119
  count?: undefined;
118
120
  provider?: undefined;
119
- found?: undefined;
120
121
  deleted: boolean;
121
122
  id: string;
122
123
  registered?: undefined;
123
124
  label?: undefined;
124
- message?: undefined;
125
125
  } | {
126
126
  deleted?: undefined;
127
+ found?: undefined;
127
128
  providers?: undefined;
128
129
  count?: undefined;
129
130
  provider?: undefined;
130
- found?: undefined;
131
131
  registered: boolean;
132
132
  id: string;
133
133
  label: string;
@@ -311,9 +311,11 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
311
311
  notes?: string | undefined;
312
312
  scope?: "org" | "user" | undefined;
313
313
  }, {
314
+ deleted?: undefined;
314
315
  id?: undefined;
315
316
  provider?: undefined;
316
- deleted?: undefined;
317
+ found?: undefined;
318
+ message?: undefined;
317
319
  providers: {
318
320
  id: string;
319
321
  label: string;
@@ -324,46 +326,44 @@ export declare function createProviderApiActions(runtime: Pick<ProviderApiRuntim
324
326
  updatedAt: number;
325
327
  }[];
326
328
  count: number;
327
- found?: undefined;
328
329
  registered?: undefined;
329
330
  label?: undefined;
330
- message?: undefined;
331
331
  } | {
332
- id?: undefined;
333
- count?: undefined;
334
332
  deleted?: undefined;
333
+ count?: undefined;
334
+ id?: undefined;
335
+ message?: undefined;
335
336
  providers?: undefined;
336
337
  found: boolean;
337
338
  provider: import("../custom-registry.js").CustomProviderConfig;
338
339
  registered?: undefined;
339
340
  label?: undefined;
340
- message?: undefined;
341
341
  } | {
342
+ deleted?: undefined;
342
343
  count?: undefined;
343
344
  provider?: undefined;
344
- deleted?: undefined;
345
+ message?: undefined;
345
346
  providers?: undefined;
346
347
  found: boolean;
347
348
  id: string;
348
349
  registered?: undefined;
349
350
  label?: undefined;
350
- message?: undefined;
351
351
  } | {
352
352
  count?: undefined;
353
353
  provider?: undefined;
354
- providers?: undefined;
355
354
  found?: undefined;
355
+ message?: undefined;
356
+ providers?: undefined;
356
357
  deleted: boolean;
357
358
  id: string;
358
359
  registered?: undefined;
359
360
  label?: undefined;
360
- message?: undefined;
361
361
  } | {
362
+ deleted?: undefined;
362
363
  count?: undefined;
363
364
  provider?: undefined;
364
- deleted?: undefined;
365
- providers?: undefined;
366
365
  found?: undefined;
366
+ providers?: undefined;
367
367
  registered: boolean;
368
368
  id: string;
369
369
  label: string;
@@ -73,6 +73,7 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
73
73
  offset?: unknown;
74
74
  limit?: unknown;
75
75
  }, {
76
+ deleted?: undefined;
76
77
  jobs: {
77
78
  id: string;
78
79
  name: string;
@@ -83,7 +84,6 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
83
84
  updatedAt: string;
84
85
  }[];
85
86
  total: number;
86
- deleted?: undefined;
87
87
  jobId?: undefined;
88
88
  } | {
89
89
  jobs?: undefined;
@@ -91,9 +91,9 @@ export declare function createProviderCorpusJobAction(options: CreateProviderCor
91
91
  deleted: boolean;
92
92
  jobId: string;
93
93
  } | {
94
+ deleted?: undefined;
94
95
  jobs?: undefined;
95
96
  total?: undefined;
96
- deleted?: undefined;
97
97
  jobId?: undefined;
98
98
  hits: Record<string, unknown>[];
99
99
  offset: number;
@@ -37,17 +37,17 @@ export declare function createWriteSecretHandler(): import("h3").EventHandlerWit
37
37
  ok?: undefined;
38
38
  status?: undefined;
39
39
  } | {
40
+ error?: undefined;
40
41
  ok: boolean;
41
42
  status: string;
42
- error?: undefined;
43
43
  } | {
44
44
  ok?: undefined;
45
45
  error: string;
46
46
  removed?: undefined;
47
47
  } | {
48
+ error?: undefined;
48
49
  ok: boolean;
49
50
  removed: boolean;
50
- error?: undefined;
51
51
  }>>;
52
52
  /**
53
53
  * POST /_agent-native/secrets/:key/test — validate an optional candidate value
@@ -58,13 +58,13 @@ export declare function createTestSecretHandler(): import("h3").EventHandlerWith
58
58
  error: string;
59
59
  note?: undefined;
60
60
  } | {
61
+ error?: undefined;
61
62
  ok: boolean;
62
63
  note?: undefined;
63
- error?: undefined;
64
64
  } | {
65
+ error?: undefined;
65
66
  ok: boolean;
66
67
  note: string;
67
- error?: undefined;
68
68
  } | {
69
69
  note?: undefined;
70
70
  ok: boolean;
@@ -95,11 +95,11 @@ export interface AdHocSecretPayload {
95
95
  export declare function createAdHocSecretHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<AdHocSecretPayload[] | {
96
96
  error: string;
97
97
  } | {
98
+ error?: undefined;
98
99
  ok: boolean;
99
100
  key: string;
100
- error?: undefined;
101
101
  } | {
102
+ error?: undefined;
102
103
  ok: boolean;
103
104
  removed: boolean;
104
- error?: undefined;
105
105
  }>>;
@@ -4885,10 +4885,12 @@ Non-code requests are still fine on this surface: read data, navigate the UI, su
4885
4885
  catch (error) {
4886
4886
  console.warn("[recurring-jobs] Scheduler module unavailable:", error instanceof Error ? error.message : error);
4887
4887
  }
4888
- // A non-Netlify self-dispatch only waits for the request to leave the
4889
- // current invocation. Keep the durable history row as a retryable queue
4890
- // so a frozen serverless handoff is recovered on the next sweep.
4891
- if (!isBackgroundRuntime && !sweepsDisabled) {
4888
+ // A synchronous self-dispatch only waits for the request to leave the
4889
+ // current invocation. Long-lived runtimes keep this retryable-queue
4890
+ // backstop; serverless runtimes use their durable scheduler instead.
4891
+ if (!isBackgroundRuntime &&
4892
+ !disableRecurringJobsRuntime &&
4893
+ !sweepsDisabled) {
4892
4894
  (() => {
4893
4895
  let inFlight = false;
4894
4896
  const sweep = async () => {
@@ -1,10 +1,15 @@
1
1
  import { autoMountAuth } from "./auth.js";
2
+ import { runBetterAuthMigrations } from "./better-auth-migrations.js";
2
3
  import { getH3App, awaitBootstrap, markDefaultPluginProvided, trackPluginInit, } from "./framework-request-handler.js";
3
4
  export function createAuthPlugin(options) {
4
5
  return (nitroApp) => {
5
6
  markDefaultPluginProvided(nitroApp, "auth");
6
7
  const initPromise = (async () => {
7
8
  await awaitBootstrap(nitroApp);
9
+ // guard:allow-boot-data-work — local/long-lived runtimes provision auth
10
+ // before mounting routes; production functions are rejected by the
11
+ // migration runner and use the release job instead.
12
+ await runBetterAuthMigrations(nitroApp);
8
13
  await autoMountAuth(getH3App(nitroApp), options);
9
14
  })();
10
15
  trackPluginInit(nitroApp, initPromise, {
@@ -17,7 +17,6 @@ import { sqliteTable, text as sqliteText, integer as sqliteInteger, } from "driz
17
17
  import { TEMPLATES } from "../cli/templates-meta.js";
18
18
  import { getDbExec, isPostgres } from "../db/client.js";
19
19
  import { getDialect, getDatabaseUrl, getDatabaseAuthToken, closePgliteClients, getPgliteClient, isPgliteUrl, loadPgliteDrizzle, pgPoolOptions, neonPoolOptions, attachNeonPoolErrorLogger, sharedDbPool, onSharedDbPoolsClosed, onSharedDbPoolReplaced, } from "../db/client.js";
20
- import { ensureTableExists } from "../db/ddl-guard.js";
21
20
  import { CORE_RESET_PASSWORD_EMAIL_ID, CORE_VERIFY_SIGNUP_EMAIL_ID, } from "../email-catalog/system-emails.js";
22
21
  import { saveOAuthTokens } from "../oauth-tokens/store.js";
23
22
  import { acceptPendingInvitationsForEmail } from "../org/accept-pending.js";
@@ -518,65 +517,6 @@ async function mirrorGoogleAccountToOAuthTokens(account) {
518
517
  tokens.id_token = account.idToken;
519
518
  await saveOAuthTokens("google", email, tokens, email);
520
519
  }
521
- async function ensureBetterAuthTables() {
522
- const db = getDbExec();
523
- // PG guard: probe information_schema first (no lock) for each table; run
524
- // DDL only when missing, bounded by a transaction-scoped lock_timeout.
525
- // Probe names are UNQUOTED (what information_schema.tables.table_name stores);
526
- // createSql keeps the QUOTED "user"/"session"/… form required by Postgres.
527
- if (isPostgres()) {
528
- const pgTables = [
529
- [
530
- "user",
531
- `CREATE TABLE IF NOT EXISTS "user" (id TEXT PRIMARY KEY, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE, email_verified BOOLEAN NOT NULL DEFAULT FALSE, image TEXT, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL)`,
532
- ],
533
- [
534
- "session",
535
- `CREATE TABLE IF NOT EXISTS "session" (id TEXT PRIMARY KEY, expires_at TIMESTAMPTZ NOT NULL, token TEXT NOT NULL UNIQUE, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL, ip_address TEXT, user_agent TEXT, user_id TEXT NOT NULL, active_organization_id TEXT)`,
536
- ],
537
- [
538
- "account",
539
- `CREATE TABLE IF NOT EXISTS "account" (id TEXT PRIMARY KEY, account_id TEXT NOT NULL, provider_id TEXT NOT NULL, user_id TEXT NOT NULL, access_token TEXT, refresh_token TEXT, id_token TEXT, access_token_expires_at TIMESTAMPTZ, refresh_token_expires_at TIMESTAMPTZ, scope TEXT, password TEXT, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL)`,
540
- ],
541
- [
542
- "verification",
543
- `CREATE TABLE IF NOT EXISTS "verification" (id TEXT PRIMARY KEY, identifier TEXT NOT NULL, value TEXT NOT NULL, expires_at TIMESTAMPTZ NOT NULL, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL)`,
544
- ],
545
- [
546
- "organization",
547
- `CREATE TABLE IF NOT EXISTS "organization" (id TEXT PRIMARY KEY, name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, logo TEXT, metadata TEXT, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL)`,
548
- ],
549
- [
550
- "member",
551
- `CREATE TABLE IF NOT EXISTS "member" (id TEXT PRIMARY KEY, organization_id TEXT NOT NULL, user_id TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'member', created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL)`,
552
- ],
553
- [
554
- "invitation",
555
- `CREATE TABLE IF NOT EXISTS "invitation" (id TEXT PRIMARY KEY, organization_id TEXT NOT NULL, email TEXT NOT NULL, role TEXT, status TEXT NOT NULL DEFAULT 'pending', expires_at TIMESTAMPTZ NOT NULL, inviter_id TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL, updated_at TIMESTAMPTZ NOT NULL)`,
556
- ],
557
- [
558
- "jwks",
559
- `CREATE TABLE IF NOT EXISTS "jwks" (id TEXT PRIMARY KEY, public_key TEXT NOT NULL, private_key TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL, expires_at TIMESTAMPTZ)`,
560
- ],
561
- ];
562
- for (const [name, sql] of pgTables)
563
- await ensureTableExists(name, sql);
564
- return;
565
- }
566
- // SQLite (local dev): no lock problem — keep the original behaviour.
567
- const sqliteStatements = [
568
- `CREATE TABLE IF NOT EXISTS user (id TEXT PRIMARY KEY, name TEXT NOT NULL, email TEXT NOT NULL UNIQUE, email_verified INTEGER NOT NULL DEFAULT 0, image TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
569
- `CREATE TABLE IF NOT EXISTS session (id TEXT PRIMARY KEY, expires_at INTEGER NOT NULL, token TEXT NOT NULL UNIQUE, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, ip_address TEXT, user_agent TEXT, user_id TEXT NOT NULL, active_organization_id TEXT)`,
570
- `CREATE TABLE IF NOT EXISTS account (id TEXT PRIMARY KEY, account_id TEXT NOT NULL, provider_id TEXT NOT NULL, user_id TEXT NOT NULL, access_token TEXT, refresh_token TEXT, id_token TEXT, access_token_expires_at INTEGER, refresh_token_expires_at INTEGER, scope TEXT, password TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
571
- `CREATE TABLE IF NOT EXISTS verification (id TEXT PRIMARY KEY, identifier TEXT NOT NULL, value TEXT NOT NULL, expires_at INTEGER NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
572
- `CREATE TABLE IF NOT EXISTS organization (id TEXT PRIMARY KEY, name TEXT NOT NULL, slug TEXT NOT NULL UNIQUE, logo TEXT, metadata TEXT, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
573
- `CREATE TABLE IF NOT EXISTS member (id TEXT PRIMARY KEY, organization_id TEXT NOT NULL, user_id TEXT NOT NULL, role TEXT NOT NULL DEFAULT 'member', created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
574
- `CREATE TABLE IF NOT EXISTS invitation (id TEXT PRIMARY KEY, organization_id TEXT NOT NULL, email TEXT NOT NULL, role TEXT, status TEXT NOT NULL DEFAULT 'pending', expires_at INTEGER NOT NULL, inviter_id TEXT NOT NULL, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL)`,
575
- `CREATE TABLE IF NOT EXISTS jwks (id TEXT PRIMARY KEY, public_key TEXT NOT NULL, private_key TEXT NOT NULL, created_at INTEGER NOT NULL, expires_at INTEGER)`,
576
- ];
577
- for (const sql of sqliteStatements)
578
- await db.execute(sql);
579
- }
580
520
  /**
581
521
  * Get or create the Better Auth instance.
582
522
  * Lazily initialized on first call — the database must be reachable by then.
@@ -860,7 +800,6 @@ function resetAuthOnPoolClose(driver, url) {
860
800
  async function createBetterAuthInstance(config) {
861
801
  const dialect = getDialect();
862
802
  const basePath = config?.basePath ?? "/_agent-native/auth/ba";
863
- await ensureBetterAuthTables();
864
803
  // Build social providers from env vars
865
804
  const socialProviders = {
866
805
  ...config?.socialProviders,
@@ -0,0 +1,8 @@
1
+ import { type MigrationEntry } from "../db/migrations.js";
2
+ /**
3
+ * Better Auth's framework-owned schema. This is deliberately a release
4
+ * migration, not a fallback inside `getBetterAuth()`: request functions must
5
+ * be able to construct the auth adapter without probing or creating tables.
6
+ */
7
+ export declare const BETTER_AUTH_MIGRATIONS: MigrationEntry[];
8
+ export declare function runBetterAuthMigrations(nitroApp: unknown): Promise<void>;
@@ -0,0 +1,179 @@
1
+ import { runMigrations } from "../db/migrations.js";
2
+ /**
3
+ * Better Auth's framework-owned schema. This is deliberately a release
4
+ * migration, not a fallback inside `getBetterAuth()`: request functions must
5
+ * be able to construct the auth adapter without probing or creating tables.
6
+ */
7
+ export const BETTER_AUTH_MIGRATIONS = [
8
+ {
9
+ version: 1,
10
+ name: "better-auth-core-tables",
11
+ sql: {
12
+ postgres: `
13
+ CREATE TABLE IF NOT EXISTS "user" (
14
+ id TEXT PRIMARY KEY,
15
+ name TEXT NOT NULL,
16
+ email TEXT NOT NULL UNIQUE,
17
+ email_verified BOOLEAN NOT NULL DEFAULT FALSE,
18
+ image TEXT,
19
+ created_at TIMESTAMPTZ NOT NULL,
20
+ updated_at TIMESTAMPTZ NOT NULL
21
+ );
22
+ CREATE TABLE IF NOT EXISTS "session" (
23
+ id TEXT PRIMARY KEY,
24
+ expires_at TIMESTAMPTZ NOT NULL,
25
+ token TEXT NOT NULL UNIQUE,
26
+ created_at TIMESTAMPTZ NOT NULL,
27
+ updated_at TIMESTAMPTZ NOT NULL,
28
+ ip_address TEXT,
29
+ user_agent TEXT,
30
+ user_id TEXT NOT NULL,
31
+ active_organization_id TEXT
32
+ );
33
+ CREATE TABLE IF NOT EXISTS "account" (
34
+ id TEXT PRIMARY KEY,
35
+ account_id TEXT NOT NULL,
36
+ provider_id TEXT NOT NULL,
37
+ user_id TEXT NOT NULL,
38
+ access_token TEXT,
39
+ refresh_token TEXT,
40
+ id_token TEXT,
41
+ access_token_expires_at TIMESTAMPTZ,
42
+ refresh_token_expires_at TIMESTAMPTZ,
43
+ scope TEXT,
44
+ password TEXT,
45
+ created_at TIMESTAMPTZ NOT NULL,
46
+ updated_at TIMESTAMPTZ NOT NULL
47
+ );
48
+ CREATE TABLE IF NOT EXISTS "verification" (
49
+ id TEXT PRIMARY KEY,
50
+ identifier TEXT NOT NULL,
51
+ value TEXT NOT NULL,
52
+ expires_at TIMESTAMPTZ NOT NULL,
53
+ created_at TIMESTAMPTZ NOT NULL,
54
+ updated_at TIMESTAMPTZ NOT NULL
55
+ );
56
+ CREATE TABLE IF NOT EXISTS "organization" (
57
+ id TEXT PRIMARY KEY,
58
+ name TEXT NOT NULL,
59
+ slug TEXT NOT NULL UNIQUE,
60
+ logo TEXT,
61
+ metadata TEXT,
62
+ created_at TIMESTAMPTZ NOT NULL,
63
+ updated_at TIMESTAMPTZ NOT NULL
64
+ );
65
+ CREATE TABLE IF NOT EXISTS "member" (
66
+ id TEXT PRIMARY KEY,
67
+ organization_id TEXT NOT NULL,
68
+ user_id TEXT NOT NULL,
69
+ role TEXT NOT NULL DEFAULT 'member',
70
+ created_at TIMESTAMPTZ NOT NULL,
71
+ updated_at TIMESTAMPTZ NOT NULL
72
+ );
73
+ CREATE TABLE IF NOT EXISTS "invitation" (
74
+ id TEXT PRIMARY KEY,
75
+ organization_id TEXT NOT NULL,
76
+ email TEXT NOT NULL,
77
+ role TEXT,
78
+ status TEXT NOT NULL DEFAULT 'pending',
79
+ expires_at TIMESTAMPTZ NOT NULL,
80
+ inviter_id TEXT NOT NULL,
81
+ created_at TIMESTAMPTZ NOT NULL,
82
+ updated_at TIMESTAMPTZ NOT NULL
83
+ );
84
+ CREATE TABLE IF NOT EXISTS "jwks" (
85
+ id TEXT PRIMARY KEY,
86
+ public_key TEXT NOT NULL,
87
+ private_key TEXT NOT NULL,
88
+ created_at TIMESTAMPTZ NOT NULL,
89
+ expires_at TIMESTAMPTZ
90
+ )
91
+ `,
92
+ sqlite: `
93
+ CREATE TABLE IF NOT EXISTS user (
94
+ id TEXT PRIMARY KEY,
95
+ name TEXT NOT NULL,
96
+ email TEXT NOT NULL UNIQUE,
97
+ email_verified INTEGER NOT NULL DEFAULT 0,
98
+ image TEXT,
99
+ created_at INTEGER NOT NULL,
100
+ updated_at INTEGER NOT NULL
101
+ );
102
+ CREATE TABLE IF NOT EXISTS session (
103
+ id TEXT PRIMARY KEY,
104
+ expires_at INTEGER NOT NULL,
105
+ token TEXT NOT NULL UNIQUE,
106
+ created_at INTEGER NOT NULL,
107
+ updated_at INTEGER NOT NULL,
108
+ ip_address TEXT,
109
+ user_agent TEXT,
110
+ user_id TEXT NOT NULL,
111
+ active_organization_id TEXT
112
+ );
113
+ CREATE TABLE IF NOT EXISTS account (
114
+ id TEXT PRIMARY KEY,
115
+ account_id TEXT NOT NULL,
116
+ provider_id TEXT NOT NULL,
117
+ user_id TEXT NOT NULL,
118
+ access_token TEXT,
119
+ refresh_token TEXT,
120
+ id_token TEXT,
121
+ access_token_expires_at INTEGER,
122
+ refresh_token_expires_at INTEGER,
123
+ scope TEXT,
124
+ password TEXT,
125
+ created_at INTEGER NOT NULL,
126
+ updated_at INTEGER NOT NULL
127
+ );
128
+ CREATE TABLE IF NOT EXISTS verification (
129
+ id TEXT PRIMARY KEY,
130
+ identifier TEXT NOT NULL,
131
+ value TEXT NOT NULL,
132
+ expires_at INTEGER NOT NULL,
133
+ created_at INTEGER NOT NULL,
134
+ updated_at INTEGER NOT NULL
135
+ );
136
+ CREATE TABLE IF NOT EXISTS organization (
137
+ id TEXT PRIMARY KEY,
138
+ name TEXT NOT NULL,
139
+ slug TEXT NOT NULL UNIQUE,
140
+ logo TEXT,
141
+ metadata TEXT,
142
+ created_at INTEGER NOT NULL,
143
+ updated_at INTEGER NOT NULL
144
+ );
145
+ CREATE TABLE IF NOT EXISTS member (
146
+ id TEXT PRIMARY KEY,
147
+ organization_id TEXT NOT NULL,
148
+ user_id TEXT NOT NULL,
149
+ role TEXT NOT NULL DEFAULT 'member',
150
+ created_at INTEGER NOT NULL,
151
+ updated_at INTEGER NOT NULL
152
+ );
153
+ CREATE TABLE IF NOT EXISTS invitation (
154
+ id TEXT PRIMARY KEY,
155
+ organization_id TEXT NOT NULL,
156
+ email TEXT NOT NULL,
157
+ role TEXT,
158
+ status TEXT NOT NULL DEFAULT 'pending',
159
+ expires_at INTEGER NOT NULL,
160
+ inviter_id TEXT NOT NULL,
161
+ created_at INTEGER NOT NULL,
162
+ updated_at INTEGER NOT NULL
163
+ );
164
+ CREATE TABLE IF NOT EXISTS jwks (
165
+ id TEXT PRIMARY KEY,
166
+ public_key TEXT NOT NULL,
167
+ private_key TEXT NOT NULL,
168
+ created_at INTEGER NOT NULL,
169
+ expires_at INTEGER
170
+ )
171
+ `,
172
+ },
173
+ },
174
+ ];
175
+ export async function runBetterAuthMigrations(nitroApp) {
176
+ await runMigrations(BETTER_AUTH_MIGRATIONS, {
177
+ table: "_better_auth_migrations",
178
+ })(nitroApp);
179
+ }
@@ -1,4 +1,6 @@
1
1
  export { createAuthPlugin, defaultAuthPlugin } from "./auth-plugin.js";
2
+ export { BETTER_AUTH_MIGRATIONS, runBetterAuthMigrations, } from "./better-auth-migrations.js";
3
+ export { runFrameworkReleaseMigrations } from "./release-migrations.js";
2
4
  export { createAgentChatPlugin, defaultAgentChatPlugin, refreshGlobalMcpManager, type AgentChatPluginOptions, } from "./agent-chat-plugin.js";
3
5
  export { createContextXrayPlugin, defaultContextXrayPlugin, } from "../agent/context-xray/plugin.js";
4
6
  export { createCoreRoutesPlugin, defaultCoreRoutesPlugin, FRAMEWORK_ROUTE_PREFIX, type CoreRoutesPluginOptions, } from "./core-routes-plugin.js";
@@ -1,4 +1,6 @@
1
1
  export { createAuthPlugin, defaultAuthPlugin } from "./auth-plugin.js";
2
+ export { BETTER_AUTH_MIGRATIONS, runBetterAuthMigrations, } from "./better-auth-migrations.js";
3
+ export { runFrameworkReleaseMigrations } from "./release-migrations.js";
2
4
  export { createAgentChatPlugin, defaultAgentChatPlugin, refreshGlobalMcpManager, } from "./agent-chat-plugin.js";
3
5
  export { createContextXrayPlugin, defaultContextXrayPlugin, } from "../agent/context-xray/plugin.js";
4
6
  export { createCoreRoutesPlugin, defaultCoreRoutesPlugin, FRAMEWORK_ROUTE_PREFIX, } from "./core-routes-plugin.js";
@@ -22,6 +22,8 @@ export { createDevScriptRegistry } from "../scripts/dev/index.js";
22
22
  export { createPollHandler, recordChange, getVersion, getChangesSince, getPollEmitter, canSeeChangeForUser, POLL_CHANGE_EVENT, } from "./poll.js";
23
23
  export { createPollEventsHandler } from "./poll-events.js";
24
24
  export { createAuthPlugin, defaultAuthPlugin } from "./auth-plugin.js";
25
+ export { BETTER_AUTH_MIGRATIONS, runBetterAuthMigrations, } from "./better-auth-migrations.js";
26
+ export { runFrameworkReleaseMigrations } from "./release-migrations.js";
25
27
  export { initServerSentry, isServerSentryEnabled, setSentryUserForRequest, captureRouteError, type RouteErrorContext, } from "./sentry.js";
26
28
  export { captureError, captureServerError, registerErrorCaptureProvider, type CaptureErrorContext, type CaptureErrorProvider, } from "./capture-error.js";
27
29
  export { createSentryPlugin, defaultSentryPlugin } from "./sentry-plugin.js";
@@ -22,6 +22,8 @@ export { createDevScriptRegistry } from "../scripts/dev/index.js";
22
22
  export { createPollHandler, recordChange, getVersion, getChangesSince, getPollEmitter, canSeeChangeForUser, POLL_CHANGE_EVENT, } from "./poll.js";
23
23
  export { createPollEventsHandler } from "./poll-events.js";
24
24
  export { createAuthPlugin, defaultAuthPlugin } from "./auth-plugin.js";
25
+ export { BETTER_AUTH_MIGRATIONS, runBetterAuthMigrations, } from "./better-auth-migrations.js";
26
+ export { runFrameworkReleaseMigrations } from "./release-migrations.js";
25
27
  export { initServerSentry, isServerSentryEnabled, setSentryUserForRequest, captureRouteError, } from "./sentry.js";
26
28
  export { captureError, captureServerError, registerErrorCaptureProvider, } from "./capture-error.js";
27
29
  export { createSentryPlugin, defaultSentryPlugin } from "./sentry-plugin.js";
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Apply framework-owned schema in one explicit release step.
3
+ *
4
+ * Template migrations are intentionally supplied by the template's own
5
+ * release script. Keeping that boundary explicit prevents a template's
6
+ * private schema from being silently coupled to every framework deployment.
7
+ */
8
+ export declare function runFrameworkReleaseMigrations(nitroApp: unknown): Promise<void>;
@@ -0,0 +1,24 @@
1
+ import { CONTEXT_XRAY_MIGRATIONS } from "../agent/context-xray/migrations.js";
2
+ import { OBSERVATIONAL_MEMORY_MIGRATIONS } from "../agent/observational-memory/migrations.js";
3
+ import { runMigrations } from "../db/migrations.js";
4
+ import { runAutomationRunMigrations } from "../jobs/run-history.js";
5
+ import { ORG_MIGRATIONS } from "../org/migrations.js";
6
+ import { runBetterAuthMigrations } from "./better-auth-migrations.js";
7
+ /**
8
+ * Apply framework-owned schema in one explicit release step.
9
+ *
10
+ * Template migrations are intentionally supplied by the template's own
11
+ * release script. Keeping that boundary explicit prevents a template's
12
+ * private schema from being silently coupled to every framework deployment.
13
+ */
14
+ export async function runFrameworkReleaseMigrations(nitroApp) {
15
+ await runBetterAuthMigrations(nitroApp);
16
+ await runMigrations(ORG_MIGRATIONS, { table: "_org_migrations" })(nitroApp);
17
+ await runMigrations(CONTEXT_XRAY_MIGRATIONS, {
18
+ table: "_context_xray_migrations",
19
+ })(nitroApp);
20
+ await runMigrations(OBSERVATIONAL_MEMORY_MIGRATIONS, {
21
+ table: "_observational_memory_migrations",
22
+ })(nitroApp);
23
+ await runAutomationRunMigrations(nitroApp);
24
+ }
@@ -1,4 +1,4 @@
1
- type SweepRuntimeEnvKey = "AGENT_NATIVE_DISABLE_INPROCESS_SWEEPS";
1
+ type SweepRuntimeEnvKey = "AGENT_NATIVE_DISABLE_INPROCESS_SWEEPS" | "AWS_LAMBDA_FUNCTION_NAME" | "AWS_LAMBDA_FUNCTION_VERSION" | "AWS_EXECUTION_ENV" | "LAMBDA_TASK_ROOT" | "NETLIFY" | "NETLIFY_FUNCTION_NAME" | "NETLIFY_LOCAL" | "NODE_ENV" | "VERCEL_FUNCTION_ID" | "VERCEL_REGION";
2
2
  type SweepRuntimeEnv = Partial<Record<SweepRuntimeEnvKey, string | undefined>>;
3
3
  /**
4
4
  * Kill switch for the `setInterval` backstop sweeps.
@@ -5,6 +5,19 @@
5
5
  function isTruthyEnv(value) {
6
6
  return /^(1|true|yes|on)$/i.test(value?.trim() ?? "");
7
7
  }
8
+ function isProductionServerlessFunction(env) {
9
+ if (env.NODE_ENV !== "production" || env.NETLIFY_LOCAL === "true") {
10
+ return false;
11
+ }
12
+ return Boolean(env.NETLIFY === "true" ||
13
+ env.NETLIFY_FUNCTION_NAME ||
14
+ env.AWS_LAMBDA_FUNCTION_NAME ||
15
+ env.AWS_LAMBDA_FUNCTION_VERSION ||
16
+ env.LAMBDA_TASK_ROOT ||
17
+ env.AWS_EXECUTION_ENV?.startsWith("AWS_Lambda") === true ||
18
+ env.VERCEL_FUNCTION_ID ||
19
+ env.VERCEL_REGION);
20
+ }
8
21
  /**
9
22
  * Kill switch for the `setInterval` backstop sweeps.
10
23
  *
@@ -24,5 +37,7 @@ function isTruthyEnv(value) {
24
37
  * eventually adopt instead of needing this switch at all.
25
38
  */
26
39
  export function shouldDisableInProcessSweeps(env = process.env) {
40
+ if (isProductionServerlessFunction(env))
41
+ return true;
27
42
  return isTruthyEnv(env.AGENT_NATIVE_DISABLE_INPROCESS_SWEEPS);
28
43
  }
@@ -20,6 +20,6 @@ export declare function createTranscribeVoiceHandler(): import("h3").EventHandle
20
20
  error: string;
21
21
  text?: undefined;
22
22
  } | {
23
- error?: undefined;
24
23
  text: string;
24
+ error?: undefined;
25
25
  }>>;
@@ -199,7 +199,11 @@ as an operator would use it repeatedly:
199
199
  - Use full `Card` composition when the content has a title, description, content, or actions. Do not dump complex cards into a single `CardContent`.
200
200
  - Use `ToggleGroup` for small option sets, `Switch` for binary settings, `Checkbox` for multi-select, `RadioGroup` for one-of-many, and `Slider`/inputs for numeric values.
201
201
  - For forms, prefer the app's existing shadcn form pattern. If newer `Field`, `FieldGroup`, or `InputGroup` primitives are installed or appropriate to add, use them instead of raw layout divs.
202
- - Loading states use `Skeleton`, `Progress`, `Spinner`, or the app's existing loading primitives. Empty states should have one clear next action.
202
+ - Page and section data loading uses layout-matching `Skeleton` geometry. Do
203
+ not show generic "Loading..." text for content loads; reserve `Spinner` for
204
+ brief mutations, uploads, and progress actions. Use the app's existing
205
+ loading primitive when it is a genuine design-system adapter. Empty states
206
+ should have one clear next action.
203
207
 
204
208
  ## Anti-Patterns
205
209
 
@@ -23,6 +23,9 @@ workflow needs durable UI around the conversation.
23
23
  - Keep the first viewport sparse and task-focused. Use progressive disclosure
24
24
  and domain-specific navigation, and never use sparkle, wand, magic, or robot
25
25
  icons as AI affordances.
26
+ - Page and section data loads use layout-matching `Skeleton` geometry, never a
27
+ generic "Loading..." label. Reserve `Spinner` for brief mutations, uploads,
28
+ and progress actions.
26
29
  - Use a sans-first SaaS hierarchy with one restrained visual cue; reserve serif
27
30
  type for content previews. Give the AgentSidebar a subtle surface/divider
28
31
  boundary, and stack original/generated review vertically by default.