@agent-native/core 0.145.7 → 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.
- package/corpus/README.md +1 -1
- package/corpus/templates/analytics/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/analytics/app/pages/settings/AlertRulesSettingsCard.tsx +3 -2
- package/corpus/templates/analytics/changelog/2026-08-07-settings-skeleton-placeholders.md +6 -0
- package/corpus/templates/analytics/netlify.toml +1 -1
- package/corpus/templates/analytics/package.json +1 -0
- package/corpus/templates/analytics/scripts/migrate-production.ts +24 -0
- package/corpus/templates/analytics/server/jobs/analytics-rollup-backfill.ts +9 -0
- package/corpus/templates/analytics/server/plugins/db.ts +14 -3
- package/corpus/templates/assets/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/brain/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/calendar/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/chat/AGENTS.md +3 -0
- package/corpus/templates/clips/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/content/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/crm/app/components/crm/IntelligenceSettings.tsx +21 -3
- package/corpus/templates/crm/app/components/crm/settings/ConnectionSettings.tsx +23 -5
- package/corpus/templates/crm/app/components/crm/settings/FieldsSettings.tsx +24 -5
- package/corpus/templates/crm/app/components/crm/settings/ListsSettings.tsx +23 -3
- package/corpus/templates/crm/changelog/2026-08-07-settings-loading-skeletons.md +6 -0
- package/corpus/templates/design/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/dispatch/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/factory/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/forms/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/macros/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/mail/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/plan/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/slides/.agents/skills/frontend-design/SKILL.md +5 -1
- package/corpus/templates/tasks/.agents/skills/frontend-design/SKILL.md +5 -1
- package/dist/client/components/ApiKeySettings.js +2 -5
- package/dist/client/org/TeamPage.js +4 -2
- package/dist/client/settings/AccountSettingsCard.js +2 -1
- package/dist/client/settings/AgentsSection.js +2 -1
- package/dist/client/settings/SecretsSection.js +3 -2
- package/dist/client/settings/SettingsPanel.js +6 -12
- package/dist/client/settings/SettingsSkeleton.d.ts +12 -0
- package/dist/client/settings/SettingsSkeleton.js +12 -0
- package/dist/client/settings/VoiceTranscriptionSection.js +5 -4
- package/dist/client/settings/index.d.ts +1 -0
- package/dist/client/settings/index.js +1 -0
- package/dist/collab/struct-routes.d.ts +1 -1
- package/dist/db/client.d.ts +13 -7
- package/dist/db/client.js +124 -7
- package/dist/db/ddl-guard.js +3 -1
- package/dist/db/ensure-additive-columns.d.ts +2 -0
- package/dist/db/ensure-additive-columns.js +5 -2
- package/dist/db/index.d.ts +2 -2
- package/dist/db/index.js +2 -2
- package/dist/db/migrations.d.ts +11 -54
- package/dist/db/migrations.js +70 -0
- package/dist/file-upload/actions/upload-image.d.ts +1 -1
- package/dist/jobs/index.d.ts +1 -0
- package/dist/jobs/index.js +1 -0
- package/dist/jobs/run-history.d.ts +4 -0
- package/dist/jobs/run-history.js +44 -0
- package/dist/notifications/routes.d.ts +2 -2
- package/dist/observability/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +9 -9
- package/dist/provider-api/actions/provider-api.d.ts +12 -12
- package/dist/provider-api/corpus-jobs.d.ts +2 -2
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +6 -6
- package/dist/server/agent-chat-plugin.js +6 -4
- package/dist/server/auth-plugin.js +5 -0
- package/dist/server/better-auth-instance.js +0 -61
- package/dist/server/better-auth-migrations.d.ts +8 -0
- package/dist/server/better-auth-migrations.js +179 -0
- package/dist/server/edge.d.ts +2 -0
- package/dist/server/edge.js +2 -0
- package/dist/server/index.d.ts +2 -0
- package/dist/server/index.js +2 -0
- package/dist/server/release-migrations.d.ts +8 -0
- package/dist/server/release-migrations.js +24 -0
- package/dist/server/sweep-runtime.d.ts +1 -1
- package/dist/server/sweep-runtime.js +15 -0
- package/dist/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -1
- package/dist/templates/chat/AGENTS.md +3 -0
- package/dist/templates/default/.agents/skills/frontend-design/SKILL.md +5 -1
- package/dist/templates/default/AGENTS.md +3 -0
- package/dist/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +5 -1
- package/dist/templates/workspace-core/AGENTS.md +3 -0
- package/dist/templates/workspace-root/AGENTS.md +3 -0
- package/package.json +1 -1
- package/src/templates/chat/.agents/skills/frontend-design/SKILL.md +5 -1
- package/src/templates/chat/AGENTS.md +3 -0
- package/src/templates/default/.agents/skills/frontend-design/SKILL.md +5 -1
- package/src/templates/default/AGENTS.md +3 -0
- package/src/templates/workspace-core/.agents/skills/frontend-design/SKILL.md +5 -1
- package/src/templates/workspace-core/AGENTS.md +3 -0
- package/src/templates/workspace-root/AGENTS.md +3 -0
package/dist/db/migrations.d.ts
CHANGED
|
@@ -19,6 +19,13 @@ export declare function isDuplicateColumnError(err: unknown): boolean;
|
|
|
19
19
|
*/
|
|
20
20
|
export declare function isPermissionError(err: unknown): boolean;
|
|
21
21
|
export interface RunMigrationsOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Run migrations even inside a serverless request runtime. Off by default:
|
|
24
|
+
* see the guard in {@link runMigrations} for why request-path DDL is what
|
|
25
|
+
* took analytics down. Only set this when the caller has no scheduled or
|
|
26
|
+
* background runtime that could migrate instead.
|
|
27
|
+
*/
|
|
28
|
+
runInServerlessRequest?: boolean;
|
|
22
29
|
/**
|
|
23
30
|
* Name of the migrations bookkeeping table. REQUIRED — there is intentionally
|
|
24
31
|
* no default. Two templates that share a database (e.g. via the same Neon URL)
|
|
@@ -85,61 +92,11 @@ export interface MigrationEntry {
|
|
|
85
92
|
run?: () => Promise<MigrationRunResult>;
|
|
86
93
|
}
|
|
87
94
|
/**
|
|
88
|
-
*
|
|
89
|
-
* per-table bookkeeping row (`options.table`) so repeated boots only apply
|
|
90
|
-
* new migrations.
|
|
91
|
-
*
|
|
92
|
-
* ## Name-based tracking (why it exists)
|
|
93
|
-
*
|
|
94
|
-
* The legacy gate is purely numeric: `SELECT MAX(version)` from the
|
|
95
|
-
* bookkeeping table, then apply every entry whose `version` is greater. That
|
|
96
|
-
* scheme silently breaks down when **two independent branches each extend the
|
|
97
|
-
* same migration list with different DDL under the same version numbers** —
|
|
98
|
-
* exactly what happened to the analytics template's v75-v83 range. Branch A
|
|
99
|
-
* shipped alert-rule tables as v75-v78; branch B shipped unrelated DDL as its
|
|
100
|
-
* own v75-v83. Whichever branch deployed first recorded "v75..v83 applied"
|
|
101
|
-
* in the bookkeeping table. When the other branch merged and deployed, its
|
|
102
|
-
* migrations at those same version numbers were never applied — `MAX(version)`
|
|
103
|
-
* was already ≥ their version, so the gate treated them as done even though
|
|
104
|
-
* their actual DDL had never run. The result: `analytics_migrations` showed
|
|
105
|
-
* rows for 1..83 with no gaps, yet `analytics_alert_rules`,
|
|
106
|
-
* `analytics_alert_incidents`, and `session_recordings.network_error_count`
|
|
107
|
-
* did not exist in production. Version numbers are not a stable identity —
|
|
108
|
-
* they're just sequence position, and sequence position collides across
|
|
109
|
-
* branches.
|
|
110
|
-
*
|
|
111
|
-
* Name-based tracking fixes this by keying application on a stable, unique
|
|
112
|
-
* **string slug** instead of a position in a shared integer sequence:
|
|
113
|
-
*
|
|
114
|
-
* - Entries with a `name` are recorded in a companion table,
|
|
115
|
-
* `${table}_named` (`name TEXT PRIMARY KEY`), and APPLY IFF their name is
|
|
116
|
-
* absent from that table — completely independent of version numbers or
|
|
117
|
-
* the legacy `MAX(version)` gate. Two branches can both ship a migration
|
|
118
|
-
* named `"analytics-alert-rules-table"` at version 75, or one at version 75
|
|
119
|
-
* and the other at version 90 after a rebase — either way it applies
|
|
120
|
-
* exactly once per database, keyed on the name.
|
|
121
|
-
* - Entries WITHOUT a `name` keep the exact legacy behavior
|
|
122
|
-
* (`version > MAX(recorded version)`), so nothing changes for existing
|
|
123
|
-
* unnamed migrations.
|
|
124
|
-
* - Named migrations still execute in list order, interleaved with unnamed
|
|
125
|
-
* ones exactly as written.
|
|
126
|
-
* - When a named migration's DDL runs, we record BOTH the named row (always)
|
|
127
|
-
* and — if its `version` is greater than the current legacy max — the
|
|
128
|
-
* legacy version row too, in the SAME atomic batch/transaction as the DDL.
|
|
129
|
-
* This keeps the legacy `MAX(version)` gate monotonically advancing for
|
|
130
|
-
* any unnamed migrations that come after it in the list, while ensuring a
|
|
131
|
-
* named migration is never "double recorded" in a way that would let it
|
|
132
|
-
* re-apply.
|
|
133
|
-
* - A duplicate `name` across the migration list throws at startup — that's
|
|
134
|
-
* a programmer error (copy-paste or merge mistake), not a runtime data
|
|
135
|
-
* problem, and failing loud beats silently tracking the wrong row.
|
|
95
|
+
* Run an explicit release-time migration job with migration duty enabled.
|
|
136
96
|
*
|
|
137
|
-
*
|
|
138
|
-
*
|
|
139
|
-
* same list — but if a table is EVER at risk of being shared across parallel
|
|
140
|
-
* branches (any template's own migrations qualify, since branches routinely
|
|
141
|
-
* extend the same list concurrently), giving new entries a name is what makes
|
|
142
|
-
* them immune to the collision class described above.
|
|
97
|
+
* The flag is process-local and restored even when the job fails, so a build
|
|
98
|
+
* step can opt in without creating a permanent escape hatch for request code.
|
|
143
99
|
*/
|
|
100
|
+
export declare function withMigrationRuntime<T>(run: () => Promise<T>): Promise<T>;
|
|
144
101
|
export declare function runMigrations(migrations: Array<MigrationEntry>, options: RunMigrationsOptions): NitroPluginDef;
|
|
145
102
|
export {};
|
package/dist/db/migrations.js
CHANGED
|
@@ -226,6 +226,56 @@ function resolveMigrationSql(sql, pg) {
|
|
|
226
226
|
* extend the same list concurrently), giving new entries a name is what makes
|
|
227
227
|
* them immune to the collision class described above.
|
|
228
228
|
*/
|
|
229
|
+
/**
|
|
230
|
+
* True in a production serverless runtime that serves user REQUESTS.
|
|
231
|
+
*
|
|
232
|
+
* Deliberately mirrors the analytics template's own predicate rather than
|
|
233
|
+
* importing it: `packages/core/src/db` must not depend on a template, and the
|
|
234
|
+
* agent/background modules that carry the sibling predicates would introduce a
|
|
235
|
+
* cycle here.
|
|
236
|
+
*/
|
|
237
|
+
function isServerlessRequestRuntime() {
|
|
238
|
+
if (process.env.NODE_ENV !== "production")
|
|
239
|
+
return false;
|
|
240
|
+
return (process.env.NETLIFY === "true" ||
|
|
241
|
+
Boolean(process.env.NETLIFY_FUNCTION_NAME) ||
|
|
242
|
+
Boolean(process.env.AWS_LAMBDA_FUNCTION_NAME) ||
|
|
243
|
+
Boolean(process.env.LAMBDA_TASK_ROOT) ||
|
|
244
|
+
process.env.AWS_EXECUTION_ENV?.startsWith("AWS_Lambda") === true ||
|
|
245
|
+
process.env.VERCEL === "1");
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* A runtime that is ALLOWED to migrate: scheduled jobs and durable background
|
|
249
|
+
* workers, which are off the request path and may take as long as they need.
|
|
250
|
+
*
|
|
251
|
+
* Set by whichever runtime claims migration duty. Analytics sets its own
|
|
252
|
+
* equivalent flag before running the scheduled rollup.
|
|
253
|
+
*/
|
|
254
|
+
function isMigrationAuthorizedRuntime() {
|
|
255
|
+
return (globalThis.__AGENT_NATIVE_MIGRATION_RUNTIME__ === true);
|
|
256
|
+
}
|
|
257
|
+
/**
|
|
258
|
+
* Run an explicit release-time migration job with migration duty enabled.
|
|
259
|
+
*
|
|
260
|
+
* The flag is process-local and restored even when the job fails, so a build
|
|
261
|
+
* step can opt in without creating a permanent escape hatch for request code.
|
|
262
|
+
*/
|
|
263
|
+
export async function withMigrationRuntime(run) {
|
|
264
|
+
const runtime = globalThis;
|
|
265
|
+
const previous = runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__;
|
|
266
|
+
runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__ = true;
|
|
267
|
+
try {
|
|
268
|
+
return await run();
|
|
269
|
+
}
|
|
270
|
+
finally {
|
|
271
|
+
if (previous === undefined) {
|
|
272
|
+
delete runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__;
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__ = previous;
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
}
|
|
229
279
|
export function runMigrations(migrations, options) {
|
|
230
280
|
const table = options?.table;
|
|
231
281
|
if (!table ||
|
|
@@ -256,6 +306,26 @@ export function runMigrations(migrations, options) {
|
|
|
256
306
|
return async () => { };
|
|
257
307
|
const namedTable = `${table}_named`;
|
|
258
308
|
return async () => {
|
|
309
|
+
// Migrations are schema DDL plus an introspection pass. On serverless
|
|
310
|
+
// "first touch" is EVERY cold start, so this lands on the critical path of
|
|
311
|
+
// a user request — measured at ~5.5-8.6s for the version check alone on a
|
|
312
|
+
// 180-table database, with 4-6 copies running concurrently under load.
|
|
313
|
+
//
|
|
314
|
+
// Guarded HERE rather than at each call site on purpose. The analytics
|
|
315
|
+
// template guarded its own runner in #2708; three core plugins
|
|
316
|
+
// (org, context-xray, observational-memory) kept calling this unguarded,
|
|
317
|
+
// so the probe storm survived the fix that was supposed to end it. A
|
|
318
|
+
// fourth special case would have shipped the same bug a fourth time.
|
|
319
|
+
//
|
|
320
|
+
// Schema still has to exist: a scheduled/background runtime sets
|
|
321
|
+
// `__AGENT_NATIVE_MIGRATION_RUNTIME__`, and `runInServerlessRequest` is
|
|
322
|
+
// the explicit opt-in for a caller that genuinely cannot defer.
|
|
323
|
+
if (options?.runInServerlessRequest !== true &&
|
|
324
|
+
isServerlessRequestRuntime() &&
|
|
325
|
+
!isMigrationAuthorizedRuntime()) {
|
|
326
|
+
console.info(`[migrations] Skipping "${table}" migrations in a serverless request runtime`);
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
259
329
|
try {
|
|
260
330
|
// Check for Cloudflare D1 binding (only if DATABASE_URL not set)
|
|
261
331
|
const d1 = getDialect() === "d1"
|
|
@@ -17,11 +17,11 @@ declare const _default: import("../../action.js").ActionDefinition<{
|
|
|
17
17
|
id?: undefined;
|
|
18
18
|
provider?: undefined;
|
|
19
19
|
} | {
|
|
20
|
+
error?: undefined;
|
|
20
21
|
configured?: undefined;
|
|
21
22
|
connectPath?: undefined;
|
|
22
23
|
url: string;
|
|
23
24
|
id: string;
|
|
24
25
|
provider: string;
|
|
25
|
-
error?: undefined;
|
|
26
26
|
}>;
|
|
27
27
|
export default _default;
|
package/dist/jobs/index.d.ts
CHANGED
|
@@ -3,3 +3,4 @@ export { processRecurringJobs, parseJobFrontmatter, buildJobContent, type JobFro
|
|
|
3
3
|
export { getAutomationSchedulerHealth, recordAutomationSchedulerHealth, type AutomationSchedulerHealth, } from "./scheduler-health.js";
|
|
4
4
|
export { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "./scheduler-dispatch.js";
|
|
5
5
|
export { createJobTools } from "./tools.js";
|
|
6
|
+
export { AUTOMATION_RUN_MIGRATIONS, runAutomationRunMigrations, } from "./run-history.js";
|
package/dist/jobs/index.js
CHANGED
|
@@ -3,3 +3,4 @@ export { processRecurringJobs, parseJobFrontmatter, buildJobContent, } from "./s
|
|
|
3
3
|
export { getAutomationSchedulerHealth, recordAutomationSchedulerHealth, } from "./scheduler-health.js";
|
|
4
4
|
export { RECURRING_JOBS_SWEEP_PATH, RECURRING_JOBS_SWEEP_TOKEN_SUBJECT, } from "./scheduler-dispatch.js";
|
|
5
5
|
export { createJobTools } from "./tools.js";
|
|
6
|
+
export { AUTOMATION_RUN_MIGRATIONS, runAutomationRunMigrations, } from "./run-history.js";
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type MigrationEntry } from "../db/migrations.js";
|
|
1
2
|
/**
|
|
2
3
|
* "interrupted" is derived at read time, never stored: a process killed
|
|
3
4
|
* mid-run cannot write its own outcome, so a row left running long past the
|
|
@@ -30,6 +31,9 @@ export interface StartAutomationRunInput {
|
|
|
30
31
|
/** A pre-created row still waiting for its background worker handoff. */
|
|
31
32
|
dispatchPending?: boolean;
|
|
32
33
|
}
|
|
34
|
+
/** Authoritative release-time schema for durable automation history. */
|
|
35
|
+
export declare const AUTOMATION_RUN_MIGRATIONS: MigrationEntry[];
|
|
36
|
+
export declare function runAutomationRunMigrations(nitroApp: unknown): Promise<void>;
|
|
33
37
|
/**
|
|
34
38
|
* Record an automation execution. Manual runs create the row before dispatch,
|
|
35
39
|
* so `dispatchPending` distinguishes that durable handoff from a run that has
|
package/dist/jobs/run-history.js
CHANGED
|
@@ -2,6 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import { z } from "zod";
|
|
3
3
|
import { getDbExec, intType, isPostgres } from "../db/client.js";
|
|
4
4
|
import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
|
|
5
|
+
import { runMigrations } from "../db/migrations.js";
|
|
5
6
|
import { emit as emitBusEvent, registerEvent } from "../event-bus/index.js";
|
|
6
7
|
registerEvent({
|
|
7
8
|
name: "automation.run.finished",
|
|
@@ -32,6 +33,49 @@ const INTERRUPTED_RUN_MESSAGE = "Worker stopped before a terminal result was rec
|
|
|
32
33
|
const CLAIM_LEASE_MS = RUN_LIVENESS_CEILING_MS;
|
|
33
34
|
/** Rows kept per automation, so a per-minute schedule cannot grow forever. */
|
|
34
35
|
const RUNS_RETAINED_PER_AUTOMATION = 50;
|
|
36
|
+
/** Authoritative release-time schema for durable automation history. */
|
|
37
|
+
export const AUTOMATION_RUN_MIGRATIONS = [
|
|
38
|
+
{
|
|
39
|
+
version: 1,
|
|
40
|
+
name: "automation-runs-table",
|
|
41
|
+
sql: `
|
|
42
|
+
CREATE TABLE IF NOT EXISTS ${TABLE} (
|
|
43
|
+
id TEXT PRIMARY KEY,
|
|
44
|
+
owner TEXT NOT NULL,
|
|
45
|
+
automation TEXT NOT NULL,
|
|
46
|
+
path TEXT NOT NULL,
|
|
47
|
+
scope TEXT,
|
|
48
|
+
org_id TEXT,
|
|
49
|
+
run_id TEXT,
|
|
50
|
+
thread_id TEXT,
|
|
51
|
+
status TEXT NOT NULL DEFAULT 'running',
|
|
52
|
+
started_at INTEGER NOT NULL,
|
|
53
|
+
finished_at INTEGER,
|
|
54
|
+
error TEXT,
|
|
55
|
+
claimed_at INTEGER,
|
|
56
|
+
dispatch_pending INTEGER NOT NULL DEFAULT 0
|
|
57
|
+
);
|
|
58
|
+
CREATE INDEX IF NOT EXISTS idx_${TABLE}_owner_automation
|
|
59
|
+
ON ${TABLE} (owner, automation, started_at)
|
|
60
|
+
`,
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
version: 2,
|
|
64
|
+
name: "automation-runs-claimed-at",
|
|
65
|
+
sql: `ALTER TABLE ${TABLE} ADD COLUMN IF NOT EXISTS claimed_at INTEGER`,
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
version: 3,
|
|
69
|
+
name: "automation-runs-dispatch-pending",
|
|
70
|
+
sql: `ALTER TABLE ${TABLE}
|
|
71
|
+
ADD COLUMN IF NOT EXISTS dispatch_pending INTEGER NOT NULL DEFAULT 0`,
|
|
72
|
+
},
|
|
73
|
+
];
|
|
74
|
+
export async function runAutomationRunMigrations(nitroApp) {
|
|
75
|
+
await runMigrations(AUTOMATION_RUN_MIGRATIONS, {
|
|
76
|
+
table: "_automation_run_migrations",
|
|
77
|
+
})(nitroApp);
|
|
78
|
+
}
|
|
35
79
|
let _initPromise;
|
|
36
80
|
async function ensureTable() {
|
|
37
81
|
if (!_initPromise) {
|
|
@@ -13,13 +13,13 @@
|
|
|
13
13
|
export declare function createNotificationsHandler(): import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<"" | import("./types.js").Notification[] | {
|
|
14
14
|
count: number;
|
|
15
15
|
updated?: undefined;
|
|
16
|
-
error?: undefined;
|
|
17
16
|
ok?: undefined;
|
|
17
|
+
error?: undefined;
|
|
18
18
|
} | {
|
|
19
19
|
count?: undefined;
|
|
20
20
|
updated: number;
|
|
21
|
-
error?: undefined;
|
|
22
21
|
ok?: undefined;
|
|
22
|
+
error?: undefined;
|
|
23
23
|
} | {
|
|
24
24
|
count?: undefined;
|
|
25
25
|
updated?: undefined;
|
|
@@ -75,8 +75,9 @@ export declare function createCustomProviderRegistrationAction<TSchema extends Z
|
|
|
75
75
|
user: "user";
|
|
76
76
|
}>>;
|
|
77
77
|
}, z.core.$strip>>, {
|
|
78
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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;
|
|
@@ -48,8 +48,8 @@ export declare function handleUpdateResource(event: any): Promise<import("./stor
|
|
|
48
48
|
}>;
|
|
49
49
|
/** DELETE /_agent-native/resources/:id — delete a resource */
|
|
50
50
|
export declare function handleDeleteResource(event: any): Promise<{
|
|
51
|
-
error: string;
|
|
52
51
|
ok?: undefined;
|
|
52
|
+
error: string;
|
|
53
53
|
} | {
|
|
54
54
|
error?: undefined;
|
|
55
55
|
ok: boolean;
|
package/dist/secrets/routes.d.ts
CHANGED
|
@@ -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
|
|
4889
|
-
// current invocation.
|
|
4890
|
-
//
|
|
4891
|
-
if (!isBackgroundRuntime &&
|
|
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>;
|