@agent-native/core 0.164.4 → 0.164.12

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 (268) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/calendar/.agents/skills/event-management/SKILL.md +84 -0
  3. package/corpus/templates/calendar/AGENTS.md +5 -0
  4. package/corpus/templates/calendar/actions/delete-event.ts +1 -1
  5. package/corpus/templates/calendar/actions/delete-events.ts +508 -0
  6. package/corpus/templates/calendar/actions/event-action-helpers.ts +1 -1
  7. package/corpus/templates/calendar/actions/list-events.ts +53 -0
  8. package/corpus/templates/calendar/app/components/calendar/CreateEventDialog.tsx +36 -47
  9. package/corpus/templates/calendar/app/components/calendar/DayView.tsx +3 -0
  10. package/corpus/templates/calendar/app/components/calendar/EventDetailPopover.tsx +18 -1
  11. package/corpus/templates/calendar/app/components/calendar/InlineEventPickers.tsx +256 -38
  12. package/corpus/templates/calendar/app/hooks/use-google-auth.ts +43 -3
  13. package/corpus/templates/calendar/app/i18n-data.ts +120 -0
  14. package/corpus/templates/calendar/app/lib/event-form-utils.ts +113 -0
  15. package/corpus/templates/calendar/changelog/2026-08-18-the-agent-can-now-remove-many-meetings-at-once-such-as-every.md +6 -0
  16. package/corpus/templates/calendar/server/handlers/google-auth.ts +119 -3
  17. package/corpus/templates/calendar/server/lib/event-weekday.ts +112 -0
  18. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  19. package/corpus/templates/calendar/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  20. package/corpus/templates/calendar/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  21. package/corpus/templates/calendar/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  22. package/corpus/templates/clips/app/components/player/video-player.tsx +12 -0
  23. package/corpus/templates/clips/app/routes/_app.dictate.tsx +18 -4
  24. package/corpus/templates/clips/app/routes/r.$recordingId.tsx +114 -20
  25. package/corpus/templates/clips/app/routes/share.$shareId.tsx +83 -78
  26. package/corpus/templates/clips/changelog/2026-08-19-clips-nightly-builds-are-available-for-trying-the-latest-upd.md +6 -0
  27. package/corpus/templates/clips/changelog/2026-08-19-social-preview-video-frames.md +1 -0
  28. package/corpus/templates/clips/desktop/README.md +19 -4
  29. package/corpus/templates/clips/desktop/src/app.tsx +78 -16
  30. package/corpus/templates/clips/desktop/src-tauri/Cargo.toml +3 -2
  31. package/corpus/templates/clips/desktop/src-tauri/tauri.conf.json +1 -0
  32. package/corpus/templates/clips/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  33. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.get.ts +41 -3
  34. package/corpus/templates/clips/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  35. package/corpus/templates/clips/server/routes/_agent-native/google/callback.get.ts +22 -1
  36. package/corpus/templates/clips/server/routes/api/clips-updater.json.get.ts +41 -22
  37. package/corpus/templates/factory/AGENTS.md +3 -2
  38. package/corpus/templates/factory/actions/get-factory-graph-version.ts +69 -0
  39. package/corpus/templates/factory/actions/list-factory-automations.ts +4 -0
  40. package/corpus/templates/factory/actions/list-factory-graph-versions.ts +82 -0
  41. package/corpus/templates/factory/actions/restore-factory-graph-version.ts +163 -0
  42. package/corpus/templates/factory/actions/save-factory-graph.ts +93 -60
  43. package/corpus/templates/factory/actions/start-builder-for-item.ts +19 -17
  44. package/corpus/templates/factory/app/components/factory/FactoryAuditView.tsx +100 -36
  45. package/corpus/templates/factory/app/components/factory/FactoryHistoryView.tsx +709 -0
  46. package/corpus/templates/factory/app/components/factory/FactoryInspector.tsx +62 -2
  47. package/corpus/templates/factory/app/components/ui/alert-dialog.tsx +1 -0
  48. package/corpus/templates/factory/app/i18n/en-US.ts +47 -0
  49. package/corpus/templates/factory/app/routes/factory.tsx +324 -61
  50. package/corpus/templates/factory/server/connectors/slack.ts +44 -2
  51. package/corpus/templates/factory/server/plugins/agent-chat.ts +12 -8
  52. package/corpus/templates/factory/server/plugins/factory-scheduler-job.ts +13 -0
  53. package/corpus/templates/factory/server/triage/slack-client.ts +5 -0
  54. package/corpus/templates/factory/server/triage/slack-poller.ts +72 -4
  55. package/corpus/templates/mail/actions/view-screen.ts +1 -1
  56. package/corpus/templates/mail/app/components/GoogleConnectBanner.tsx +100 -18
  57. package/corpus/templates/mail/server/handlers/google-auth.ts +125 -24
  58. package/corpus/templates/mail/server/lib/gmail-query.ts +5 -2
  59. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/add-account/auth-url.post.ts +1 -0
  60. package/corpus/templates/mail/server/routes/[base]/_agent-native/google/auth-url.post.ts +1 -0
  61. package/corpus/templates/mail/server/routes/_agent-native/google/add-account/auth-url.post.ts +1 -0
  62. package/corpus/templates/mail/server/routes/_agent-native/google/auth-url.post.ts +1 -0
  63. package/corpus/templates/plan/app/pages/PlansPage.tsx +0 -12
  64. package/corpus/templates/plan/changelog/2026-08-19-plan-prompts-now-guide-you-to-connect-ai-before-sending-and-.md +6 -0
  65. package/corpus/templates/slides/actions/approve-deck-access-request.ts +234 -0
  66. package/corpus/templates/slides/actions/get-deck-access-status.ts +35 -2
  67. package/corpus/templates/slides/actions/request-deck-access.ts +263 -64
  68. package/corpus/templates/slides/app/components/editor/MissingDeckAccessPane.tsx +196 -0
  69. package/corpus/templates/slides/app/components/editor/RequestDeckAccessDialog.tsx +101 -0
  70. package/corpus/templates/slides/app/hooks/use-deck-access.ts +7 -4
  71. package/corpus/templates/slides/app/i18n/en-US.ts +29 -6
  72. package/corpus/templates/slides/app/pages/DeckEditor.tsx +147 -169
  73. package/corpus/templates/slides/app/routes/access-request.approve.tsx +250 -0
  74. package/corpus/templates/slides/server/db/schema.ts +8 -0
  75. package/corpus/templates/slides/server/lib/access-request-email.ts +36 -0
  76. package/corpus/templates/slides/server/lib/emails.ts +26 -0
  77. package/corpus/templates/slides/server/plugins/agent-chat.ts +7 -0
  78. package/corpus/templates/slides/server/plugins/db.ts +50 -0
  79. package/corpus/templates/slides/shared/deck-access.ts +31 -0
  80. package/dist/a2a/task-store.d.ts +1 -0
  81. package/dist/a2a/task-store.js +1 -1
  82. package/dist/agent/observational-memory/store.d.ts +1 -0
  83. package/dist/agent/observational-memory/store.js +1 -1
  84. package/dist/agent/run-store.d.ts +1 -0
  85. package/dist/agent/run-store.js +1 -1
  86. package/dist/agent/tool-approval-store.d.ts +1 -0
  87. package/dist/agent/tool-approval-store.js +1 -1
  88. package/dist/application-state/store.d.ts +1 -0
  89. package/dist/application-state/store.js +1 -1
  90. package/dist/browser-sessions/store.d.ts +1 -0
  91. package/dist/browser-sessions/store.js +1 -1
  92. package/dist/checkpoints/store.d.ts +1 -0
  93. package/dist/checkpoints/store.js +1 -1
  94. package/dist/cli/code-agent-schedules.d.ts +11 -0
  95. package/dist/cli/code-agent-schedules.js +44 -5
  96. package/dist/client/AgentPanel.d.ts +5 -1
  97. package/dist/client/AgentPanel.js +2 -2
  98. package/dist/client/AssistantChat.d.ts +5 -1
  99. package/dist/client/AssistantChat.js +40 -6
  100. package/dist/client/EnvironmentBadge.d.ts +7 -13
  101. package/dist/client/EnvironmentBadge.js +43 -92
  102. package/dist/client/agent-chat/index.d.ts +1 -0
  103. package/dist/client/agent-chat/index.js +1 -0
  104. package/dist/client/agent-chat-adapter.js +76 -50
  105. package/dist/client/app-providers.js +4 -4
  106. package/dist/client/chat/message-components.d.ts +4 -0
  107. package/dist/client/chat/message-components.js +28 -1
  108. package/dist/client/chat/run-recovery.js +26 -0
  109. package/dist/client/chat-first/apps-rail.d.ts +1 -0
  110. package/dist/client/chat-first/apps-rail.js +28 -2
  111. package/dist/client/sse-event-processor.js +13 -8
  112. package/dist/client/use-active-agent-chat-run.d.ts +2 -0
  113. package/dist/client/use-active-agent-chat-run.js +22 -0
  114. package/dist/coding-tools/sandbox/executions-store.d.ts +1 -0
  115. package/dist/coding-tools/sandbox/executions-store.js +1 -1
  116. package/dist/collab/awareness-store.d.ts +1 -0
  117. package/dist/collab/awareness-store.js +1 -1
  118. package/dist/collab/routes.d.ts +1 -1
  119. package/dist/collab/storage.d.ts +1 -0
  120. package/dist/collab/storage.js +1 -1
  121. package/dist/collab/struct-routes.d.ts +1 -1
  122. package/dist/db/client.js +3 -3
  123. package/dist/db/ddl-guard.js +8 -0
  124. package/dist/db/migration-runtime.d.ts +23 -0
  125. package/dist/db/migration-runtime.js +41 -0
  126. package/dist/db/migrations.d.ts +1 -2
  127. package/dist/db/migrations.js +2 -24
  128. package/dist/email-catalog/log.d.ts +1 -0
  129. package/dist/email-catalog/log.js +1 -1
  130. package/dist/guards/index.d.ts +1 -0
  131. package/dist/guards/index.js +1 -0
  132. package/dist/guards/release-schema-complete.d.ts +22 -0
  133. package/dist/guards/release-schema-complete.js +144 -0
  134. package/dist/integrations/a2a-continuations-store.d.ts +1 -0
  135. package/dist/integrations/a2a-continuations-store.js +1 -1
  136. package/dist/integrations/awaiting-input-store.d.ts +1 -0
  137. package/dist/integrations/awaiting-input-store.js +1 -1
  138. package/dist/integrations/config-store.d.ts +1 -0
  139. package/dist/integrations/config-store.js +1 -1
  140. package/dist/integrations/controls-store.d.ts +1 -0
  141. package/dist/integrations/controls-store.js +1 -1
  142. package/dist/integrations/identity-links-store.d.ts +1 -0
  143. package/dist/integrations/identity-links-store.js +1 -1
  144. package/dist/integrations/installations-store.d.ts +1 -0
  145. package/dist/integrations/installations-store.js +1 -1
  146. package/dist/integrations/remote-commands-store.d.ts +1 -0
  147. package/dist/integrations/remote-commands-store.js +1 -1
  148. package/dist/integrations/remote-devices-store.d.ts +1 -0
  149. package/dist/integrations/remote-devices-store.js +1 -1
  150. package/dist/integrations/remote-push-store.d.ts +1 -0
  151. package/dist/integrations/remote-push-store.js +1 -1
  152. package/dist/integrations/remote-run-events-store.d.ts +1 -0
  153. package/dist/integrations/remote-run-events-store.js +1 -1
  154. package/dist/integrations/scope-store.d.ts +1 -0
  155. package/dist/integrations/scope-store.js +1 -1
  156. package/dist/integrations/thread-mapping-store.d.ts +1 -0
  157. package/dist/integrations/thread-mapping-store.js +1 -1
  158. package/dist/integrations/usage-budget-store.d.ts +1 -0
  159. package/dist/integrations/usage-budget-store.js +1 -1
  160. package/dist/jobs/background-automation-runner.js +111 -9
  161. package/dist/jobs/run-history.d.ts +1 -0
  162. package/dist/jobs/run-history.js +1 -1
  163. package/dist/jobs/scheduler-health.d.ts +1 -0
  164. package/dist/jobs/scheduler-health.js +1 -1
  165. package/dist/mcp/approval-store.d.ts +1 -0
  166. package/dist/mcp/approval-store.js +1 -1
  167. package/dist/mcp/connect-store.d.ts +1 -0
  168. package/dist/mcp/connect-store.js +1 -1
  169. package/dist/mcp/oauth-store.d.ts +1 -0
  170. package/dist/mcp/oauth-store.js +1 -1
  171. package/dist/notifications/store.d.ts +1 -0
  172. package/dist/notifications/store.js +1 -1
  173. package/dist/oauth-tokens/store.d.ts +1 -0
  174. package/dist/oauth-tokens/store.js +1 -1
  175. package/dist/observability/routes.d.ts +5 -5
  176. package/dist/progress/routes.d.ts +1 -1
  177. package/dist/progress/store.d.ts +1 -0
  178. package/dist/progress/store.js +1 -1
  179. package/dist/provider-api/actions/custom-provider-registration.d.ts +5 -5
  180. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  181. package/dist/provider-api/corpus-jobs-store.d.ts +1 -0
  182. package/dist/provider-api/corpus-jobs-store.js +1 -1
  183. package/dist/provider-api/custom-registry.d.ts +1 -0
  184. package/dist/provider-api/custom-registry.js +1 -1
  185. package/dist/provider-api/quota-governor.d.ts +1 -0
  186. package/dist/provider-api/quota-governor.js +1 -1
  187. package/dist/provider-api/staged-datasets-store.d.ts +1 -0
  188. package/dist/provider-api/staged-datasets-store.js +1 -1
  189. package/dist/resources/handlers.d.ts +3 -3
  190. package/dist/resources/store.d.ts +1 -0
  191. package/dist/resources/store.js +1 -1
  192. package/dist/scripts/dev/index.js +15 -1
  193. package/dist/search/index.js +3 -0
  194. package/dist/secrets/routes.d.ts +9 -9
  195. package/dist/secrets/storage.d.ts +1 -0
  196. package/dist/secrets/storage.js +1 -1
  197. package/dist/server/agent-chat-plugin.js +38 -9
  198. package/dist/server/agent-engine-api-key-route.d.ts +1 -1
  199. package/dist/server/agent-teams-run-queue.d.ts +1 -0
  200. package/dist/server/agent-teams-run-queue.js +1 -1
  201. package/dist/server/auth-marketing.js +3 -1
  202. package/dist/server/auth.d.ts +18 -1
  203. package/dist/server/auth.js +370 -154
  204. package/dist/server/embed-session.d.ts +1 -0
  205. package/dist/server/embed-session.js +1 -1
  206. package/dist/server/google-auth-plugin.js +3 -1
  207. package/dist/server/google-oauth.d.ts +10 -0
  208. package/dist/server/google-oauth.js +25 -1
  209. package/dist/server/identity-sso-store.d.ts +1 -0
  210. package/dist/server/identity-sso-store.js +1 -1
  211. package/dist/server/index.d.ts +1 -1
  212. package/dist/server/index.js +1 -1
  213. package/dist/server/onboarding-html.js +200 -31
  214. package/dist/server/poll.d.ts +2 -0
  215. package/dist/server/poll.js +19 -1
  216. package/dist/server/realtime-token.d.ts +1 -1
  217. package/dist/server/release-migrations.js +5 -0
  218. package/dist/server/release-schema.d.ts +46 -0
  219. package/dist/server/release-schema.js +307 -0
  220. package/dist/settings/store.d.ts +1 -0
  221. package/dist/settings/store.js +1 -1
  222. package/dist/shared/environment-lanes.d.ts +28 -0
  223. package/dist/shared/environment-lanes.js +61 -0
  224. package/dist/sharing/actions/share-resource.js +22 -2
  225. package/dist/styles/agent-native.css +17 -15
  226. package/dist/triggers/routes.d.ts +11 -0
  227. package/dist/triggers/routes.js +10 -0
  228. package/dist/usage/alerts-store.d.ts +1 -0
  229. package/dist/usage/alerts-store.js +1 -1
  230. package/dist/usage/store.d.ts +1 -0
  231. package/dist/usage/store.js +1 -1
  232. package/docs/content/actions-access-control.mdx +136 -2
  233. package/docs/content/actions-agent-tools.mdx +101 -0
  234. package/docs/content/actions-defining.mdx +2 -2
  235. package/docs/content/audit-log.mdx +1 -1
  236. package/docs/content/authentication.mdx +1 -1
  237. package/docs/content/cloudflare.mdx +43 -0
  238. package/docs/content/creating-templates.mdx +1 -1
  239. package/docs/content/deploy-an-app.mdx +109 -0
  240. package/docs/content/deployment-environment-variables.mdx +101 -0
  241. package/docs/content/deployment.mdx +125 -792
  242. package/docs/content/docs-components.mdx +2 -2
  243. package/docs/content/environment-variables.mdx +41 -41
  244. package/docs/content/file-uploads.mdx +74 -40
  245. package/docs/content/harness-agents.mdx +2 -2
  246. package/docs/content/internationalization.mdx +61 -65
  247. package/docs/content/key-concepts.mdx +3 -3
  248. package/docs/content/multi-app-workspace.mdx +2 -2
  249. package/docs/content/netlify.mdx +47 -0
  250. package/docs/content/node-docker.mdx +138 -0
  251. package/docs/content/organizations-teams-permissions.mdx +5 -5
  252. package/docs/content/other-platforms.mdx +27 -0
  253. package/docs/content/ssr-caching.mdx +45 -0
  254. package/docs/content/template-assets-developers.mdx +2 -2
  255. package/docs/content/template-chat-developers.mdx +2 -2
  256. package/docs/content/template-content-developers.mdx +2 -2
  257. package/docs/content/{local-file-mode.mdx → template-content-local-files.mdx} +2 -1
  258. package/docs/content/template-content-sync.mdx +2 -2
  259. package/docs/content/toolkit-agent-ux.mdx +1 -1
  260. package/docs/content/toolkit-resources.mdx +2 -2
  261. package/docs/content/updating-ui-in-production.mdx +35 -0
  262. package/docs/content/vercel.mdx +38 -0
  263. package/docs/content/what-is-agent-native.mdx +1 -1
  264. package/docs/content/workspace-deployment.mdx +350 -0
  265. package/package.json +2 -2
  266. package/docs/content/agents.mdx +0 -9
  267. package/docs/content/database.mdx +0 -317
  268. package/docs/content/human-approval.mdx +0 -156
@@ -84,6 +84,7 @@ export declare const SANDBOX_EXECUTION_DEFAULT_MAX_ATTEMPTS = 2;
84
84
  * the caller's `maxOutputChars`) is applied first; this bounds even that.
85
85
  */
86
86
  export declare const SANDBOX_EXECUTION_MAX_STORED_OUTPUT_CHARS = 200000;
87
+ export declare function ensureTable(): Promise<void>;
87
88
  /** Test-only: forget the memoized init so a fresh in-memory DB re-creates. */
88
89
  export declare function resetSandboxExecutionsStoreForTests(): void;
89
90
  /** Enqueue a new execution row in `queued` state. */
@@ -40,7 +40,7 @@ export const SANDBOX_EXECUTION_DEFAULT_MAX_ATTEMPTS = 2;
40
40
  export const SANDBOX_EXECUTION_MAX_STORED_OUTPUT_CHARS = 200_000;
41
41
  const TABLE = "sandbox_executions";
42
42
  let _initPromise;
43
- async function ensureTable() {
43
+ export async function ensureTable() {
44
44
  if (!_initPromise) {
45
45
  _initPromise = _doEnsureTable().catch((err) => {
46
46
  // Don't cache the rejection — let the next caller retry a fresh init.
@@ -14,6 +14,7 @@
14
14
  * state hasn't changed; expired rows are purged opportunistically.
15
15
  */
16
16
  import type { AwarenessEntry } from "./awareness.js";
17
+ export declare function ensureTable(): Promise<void>;
17
18
  /**
18
19
  * Mirror a client's awareness state to SQL. Throttled: unchanged state is
19
20
  * rewritten at most every {@link WRITE_THROTTLE_MS} (to refresh last_seen).
@@ -22,7 +22,7 @@ const WRITE_THROTTLE_MS = 2_000;
22
22
  /** Minimum interval between opportunistic purges per document. */
23
23
  const PURGE_INTERVAL_MS = 30_000;
24
24
  let _initPromise;
25
- async function ensureTable() {
25
+ export async function ensureTable() {
26
26
  if (!_initPromise) {
27
27
  _initPromise = (async () => {
28
28
  const client = getDbExec();
@@ -26,8 +26,8 @@ export declare const getCollabState: import("h3").EventHandlerWithFetch<import("
26
26
  * Body: { update: string (base64), requestSource?: string }
27
27
  */
28
28
  export declare const postCollabUpdate: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
29
- ok?: undefined;
30
29
  error: string;
30
+ ok?: undefined;
31
31
  } | {
32
32
  error?: undefined;
33
33
  ok: boolean;
@@ -4,6 +4,7 @@
4
4
  * Uses a framework-level `_collab_docs` table (TEXT columns with base64
5
5
  * encoding for binary Yjs state) that works across SQLite and Postgres.
6
6
  */
7
+ export declare function ensureTable(): Promise<void>;
7
8
  export interface YDocStateRecord {
8
9
  state: Uint8Array;
9
10
  version: number;
@@ -33,7 +33,7 @@ async function executeWithSqliteRetry(client, statement) {
33
33
  }
34
34
  }
35
35
  }
36
- async function ensureTable() {
36
+ export async function ensureTable() {
37
37
  if (!_initPromise) {
38
38
  _initPromise = (async () => {
39
39
  const client = getDbExec();
@@ -13,8 +13,8 @@
13
13
  * Body: { json: any, fieldName?: string, type?: "map"|"array", requestSource?: string }
14
14
  */
15
15
  export declare const postCollabJson: import("h3").EventHandlerWithFetch<import("h3").EventHandlerRequest, Promise<{
16
- ok?: undefined;
17
16
  error: string;
17
+ ok?: undefined;
18
18
  } | {
19
19
  error?: undefined;
20
20
  ok: boolean;
package/dist/db/client.js CHANGED
@@ -1,3 +1,4 @@
1
+ import path from "path";
1
2
  /**
2
3
  * Central database client abstraction.
3
4
  *
@@ -8,7 +9,7 @@
8
9
  * (dynamic import) so this module can be loaded in any runtime (Node.js,
9
10
  * Cloudflare Workers, edge) without failing on missing native deps.
10
11
  */
11
- import path from "path";
12
+ import { isMigrationAuthorizedRuntime } from "./migration-runtime.js";
12
13
  import { beginDatabaseOperation, recordDatabaseRetry, } from "./request-telemetry.js";
13
14
  const recyclingPostgresPools = new WeakSet();
14
15
  const loggedNeonPools = new WeakSet();
@@ -803,9 +804,8 @@ export function isSchemaMutationStatement(statement) {
803
804
  * is the only supported production opt-in.
804
805
  */
805
806
  export function assertSchemaMutationAllowed(statement) {
806
- const migrationRuntime = globalThis.__AGENT_NATIVE_MIGRATION_RUNTIME__ === true;
807
807
  if (isProductionServerlessFunctionRuntime() &&
808
- !migrationRuntime &&
808
+ !isMigrationAuthorizedRuntime() &&
809
809
  isSchemaMutationStatement(statement)) {
810
810
  throw new Error("Schema mutation attempted in a production serverless request. Run migrations in the release job instead.");
811
811
  }
@@ -29,6 +29,7 @@
29
29
  * behaviour there.
30
30
  */
31
31
  import { getDbExec, isPostgres, isProductionServerlessFunctionRuntime, } from "./client.js";
32
+ import { isMigrationAuthorizedRuntime } from "./migration-runtime.js";
32
33
  const PLAIN_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
33
34
  /**
34
35
  * Skip on-demand schema DDL entirely. For deployments that run real migrations,
@@ -45,6 +46,13 @@ const PLAIN_IDENTIFIER = /^[A-Za-z_][A-Za-z0-9_]*$/;
45
46
  * down the DDL path this flag exists to avoid.
46
47
  */
47
48
  function schemaEnsureDisabled() {
49
+ // The release runner is the deployment that OWNS schema creation, so it is the
50
+ // one caller that must never be skipped. Without this, the skip below applies
51
+ // to `migrate:production` too — the Netlify build environment also sets
52
+ // `NETLIFY=true` — and the release step reports success having created
53
+ // nothing.
54
+ if (isMigrationAuthorizedRuntime())
55
+ return false;
48
56
  if (isProductionServerlessFunctionRuntime())
49
57
  return true;
50
58
  const raw = process.env.AGENT_NATIVE_SKIP_ENSURE_TABLES?.trim();
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Migration duty: the process-local claim that the current call is allowed to
3
+ * create or alter schema.
4
+ *
5
+ * Its own module, and deliberately dependency-free, because both `./client.js`
6
+ * and `./ddl-guard.js` need to read it. Putting the reader on `client.js` would
7
+ * mean every `vi.mock("../db/client.js")` in the codebase has to stub one more
8
+ * export to keep `ensureTable()` working — the exact coupling `ddl-guard.ts`
9
+ * was split out to avoid.
10
+ */
11
+ /**
12
+ * A runtime that is ALLOWED to migrate: release scripts, scheduled jobs, and
13
+ * durable background workers, which are off the request path and may take as
14
+ * long as they need. Claimed with {@link withMigrationRuntime}.
15
+ */
16
+ export declare function isMigrationAuthorizedRuntime(): boolean;
17
+ /**
18
+ * Run an explicit release-time migration job with migration duty enabled.
19
+ *
20
+ * The flag is process-local and restored even when the job fails, so a build
21
+ * step can opt in without creating a permanent escape hatch for request code.
22
+ */
23
+ export declare function withMigrationRuntime<T>(run: () => Promise<T>): Promise<T>;
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Migration duty: the process-local claim that the current call is allowed to
3
+ * create or alter schema.
4
+ *
5
+ * Its own module, and deliberately dependency-free, because both `./client.js`
6
+ * and `./ddl-guard.js` need to read it. Putting the reader on `client.js` would
7
+ * mean every `vi.mock("../db/client.js")` in the codebase has to stub one more
8
+ * export to keep `ensureTable()` working — the exact coupling `ddl-guard.ts`
9
+ * was split out to avoid.
10
+ */
11
+ /**
12
+ * A runtime that is ALLOWED to migrate: release scripts, scheduled jobs, and
13
+ * durable background workers, which are off the request path and may take as
14
+ * long as they need. Claimed with {@link withMigrationRuntime}.
15
+ */
16
+ export function isMigrationAuthorizedRuntime() {
17
+ return (globalThis
18
+ .__AGENT_NATIVE_MIGRATION_RUNTIME__ === true);
19
+ }
20
+ /**
21
+ * Run an explicit release-time migration job with migration duty enabled.
22
+ *
23
+ * The flag is process-local and restored even when the job fails, so a build
24
+ * step can opt in without creating a permanent escape hatch for request code.
25
+ */
26
+ export async function withMigrationRuntime(run) {
27
+ const runtime = globalThis;
28
+ const previous = runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__;
29
+ runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__ = true;
30
+ try {
31
+ return await run();
32
+ }
33
+ finally {
34
+ if (previous === undefined) {
35
+ delete runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__;
36
+ }
37
+ else {
38
+ runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__ = previous;
39
+ }
40
+ }
41
+ }
@@ -97,6 +97,5 @@ export interface MigrationEntry {
97
97
  * The flag is process-local and restored even when the job fails, so a build
98
98
  * step can opt in without creating a permanent escape hatch for request code.
99
99
  */
100
- export declare function withMigrationRuntime<T>(run: () => Promise<T>): Promise<T>;
100
+ export { withMigrationRuntime } from "./migration-runtime.js";
101
101
  export declare function runMigrations(migrations: Array<MigrationEntry>, options: RunMigrationsOptions): NitroPluginDef;
102
- export {};
@@ -1,4 +1,5 @@
1
1
  import { getDbExec, createDbExec, isPostgres, getDialect, getMigrationDatabaseUrl, getCloudflareD1Binding, retrySqliteBusy, } from "./client.js";
2
+ import { isMigrationAuthorizedRuntime } from "./migration-runtime.js";
2
3
  // ---------------------------------------------------------------------------
3
4
  // Shared direct-endpoint exec across concurrent migration runners per boot.
4
5
  //
@@ -252,36 +253,13 @@ function appMigratesAtRelease() {
252
253
  const raw = process.env.AGENT_NATIVE_RELEASE_MIGRATIONS?.trim();
253
254
  return !!raw && ["1", "true", "yes", "on"].includes(raw.toLowerCase());
254
255
  }
255
- /**
256
- * A runtime that is ALLOWED to migrate: release scripts, scheduled jobs, and
257
- * durable background workers, which are off the request path and may take as
258
- * long as they need. Claimed with {@link withMigrationRuntime}.
259
- */
260
- function isMigrationAuthorizedRuntime() {
261
- return (globalThis.__AGENT_NATIVE_MIGRATION_RUNTIME__ === true);
262
- }
263
256
  /**
264
257
  * Run an explicit release-time migration job with migration duty enabled.
265
258
  *
266
259
  * The flag is process-local and restored even when the job fails, so a build
267
260
  * step can opt in without creating a permanent escape hatch for request code.
268
261
  */
269
- export async function withMigrationRuntime(run) {
270
- const runtime = globalThis;
271
- const previous = runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__;
272
- runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__ = true;
273
- try {
274
- return await run();
275
- }
276
- finally {
277
- if (previous === undefined) {
278
- delete runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__;
279
- }
280
- else {
281
- runtime.__AGENT_NATIVE_MIGRATION_RUNTIME__ = previous;
282
- }
283
- }
284
- }
262
+ export { withMigrationRuntime } from "./migration-runtime.js";
285
263
  export function runMigrations(migrations, options) {
286
264
  const table = options?.table;
287
265
  if (!table ||
@@ -5,6 +5,7 @@
5
5
  * to report per-email send counts and last-sent without depending on the
6
6
  * provider's activity retention window.
7
7
  */
8
+ export declare function ensureTable(): Promise<void>;
8
9
  export interface RecordEmailSendArgs {
9
10
  orgId?: string | null;
10
11
  templateId?: string;
@@ -10,7 +10,7 @@ import { getDbExec, isPostgres } from "../db/client.js";
10
10
  import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
11
11
  import { getRequestOrgId } from "../server/request-context.js";
12
12
  let _initPromise;
13
- async function ensureTable() {
13
+ export async function ensureTable() {
14
14
  if (!_initPromise) {
15
15
  _initPromise = (async () => {
16
16
  const { EMAIL_LOG_CREATE_SQL, EMAIL_LOG_ORG_APP_INDEX_SQL, EMAIL_LOG_TEMPLATE_INDEX_SQL, } = await import("./schema.js");
@@ -14,6 +14,7 @@ export type { DbToolScopingOptions } from "./db-tool-scoping.js";
14
14
  export { scanExplicitCollabAccess } from "./explicit-collab-access.js";
15
15
  export { scanDrizzlePush } from "./no-drizzle-push.js";
16
16
  export { scanEmptyMigrations } from "./no-empty-migrations.js";
17
+ export { scanReleaseSchemaCoverage } from "./release-schema-complete.js";
17
18
  export type { EmptyMigrationsSourceOptions } from "./no-empty-migrations.js";
18
19
  export { analyzeEmptyMigrationsSource, shouldScanEmptyMigrationsFile, } from "./no-empty-migrations.js";
19
20
  export { scanEnvCredentials } from "./no-env-credentials.js";
@@ -13,6 +13,7 @@ export { scanDbToolScoping } from "./db-tool-scoping.js";
13
13
  export { scanExplicitCollabAccess } from "./explicit-collab-access.js";
14
14
  export { scanDrizzlePush } from "./no-drizzle-push.js";
15
15
  export { scanEmptyMigrations } from "./no-empty-migrations.js";
16
+ export { scanReleaseSchemaCoverage } from "./release-schema-complete.js";
16
17
  export { analyzeEmptyMigrationsSource, shouldScanEmptyMigrationsFile, } from "./no-empty-migrations.js";
17
18
  export { scanEnvCredentials } from "./no-env-credentials.js";
18
19
  export { scanEnvMutation } from "./no-env-mutation.js";
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Every store that defines schema through `ensureTableExists()` must be listed
3
+ * in `server/release-schema.ts`.
4
+ *
5
+ * A store's `ensureTable()` is the only definition of its tables — there is no
6
+ * second copy in a migration list. Production serverless can never run one
7
+ * (`schemaEnsureDisabled()` reports every table present so a cold start skips
8
+ * ~390 probes), so a store missing from the release list has no path to
9
+ * creation on a hosted deploy at all. Nothing fails at deploy time; the first
10
+ * symptom is `relation "..." does not exist` from a user request, long after
11
+ * the commit that caused it.
12
+ *
13
+ * That is not hypothetical. `settings`, `application_state`, `app_secrets` and
14
+ * `resources` were absent from the release path for twelve days, and published
15
+ * sites came up with an empty database while the deploy reported success.
16
+ */
17
+ import type { GuardResult, GuardScanOptions } from "./types.js";
18
+ export interface ReleaseSchemaScanOptions extends GuardScanOptions {
19
+ /** Defaults to `<root>/packages/core`. */
20
+ corePackageDir?: string;
21
+ }
22
+ export declare function scanReleaseSchemaCoverage(options: ReleaseSchemaScanOptions): GuardResult;
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Every store that defines schema through `ensureTableExists()` must be listed
3
+ * in `server/release-schema.ts`.
4
+ *
5
+ * A store's `ensureTable()` is the only definition of its tables — there is no
6
+ * second copy in a migration list. Production serverless can never run one
7
+ * (`schemaEnsureDisabled()` reports every table present so a cold start skips
8
+ * ~390 probes), so a store missing from the release list has no path to
9
+ * creation on a hosted deploy at all. Nothing fails at deploy time; the first
10
+ * symptom is `relation "..." does not exist` from a user request, long after
11
+ * the commit that caused it.
12
+ *
13
+ * That is not hypothetical. `settings`, `application_state`, `app_secrets` and
14
+ * `resources` were absent from the release path for twelve days, and published
15
+ * sites came up with an empty database while the deploy reported success.
16
+ */
17
+ import path from "node:path";
18
+ import { readFileSafe, relPosix, walk } from "./scan-utils.js";
19
+ /**
20
+ * What counts as "this module creates a table". `ensureTableExists` is the
21
+ * intended helper, but a store that executes its DDL through the raw client
22
+ * creates schema just as much, and needs the release pass just as much. Missing
23
+ * that second form is how `extensions/slots/store.ts` stayed invisible to the
24
+ * first version of this guard.
25
+ *
26
+ * Keyed on EXECUTING the DDL, not on containing it. A `schema.ts` that exports
27
+ * `CREATE TABLE` strings and a migration list that stores them both mention the
28
+ * SQL without ever running it: the first is executed by its own store, which is
29
+ * on the list, and the second is applied by `runMigrations`.
30
+ */
31
+ const ENSURE_TABLE_RE = /\bensureTableExists\s*\(/;
32
+ const EXECUTES_RE = /\.execute\s*\(/;
33
+ const CREATE_TABLE_RE = /\bCREATE\s+TABLE\b/i;
34
+ /**
35
+ * DDL that lives in another module, the way `extensions/slots` keeps its SQL in
36
+ * `slots/schema.ts`. Keyed on the `_CREATE_SQL` / `_TABLE_SQL` / `_INDEX_SQL`
37
+ * naming rather than on any executed constant, so a plain
38
+ * `execute(DB_PRESSURE_SQL)` SELECT is not mistaken for schema.
39
+ */
40
+ const DDL_CONST_RE = /\b[A-Z][A-Z0-9_]*_(?:CREATE|TABLE|INDEX)_SQL(?:_[A-Z0-9]+)?\b/;
41
+ /**
42
+ * Whether this module CREATES tables, in any of the three shapes the codebase
43
+ * actually uses. Deliberately NOT keyed on the name of the executed expression:
44
+ * stores run their DDL from a local `createSql` or `ddl` variable as often as
45
+ * from a named constant, so requiring a recognisable name would let the
46
+ * commonest shape of all walk past the guard.
47
+ */
48
+ const definesSchema = (code) => ENSURE_TABLE_RE.test(code) ||
49
+ (EXECUTES_RE.test(code) &&
50
+ (CREATE_TABLE_RE.test(code) || DDL_CONST_RE.test(code)));
51
+ const ALLOW_MARKER_RE = /guard:allow-unreleased-schema\s*[—-]\s*\S/;
52
+ const SOURCE_EXTENSIONS = /\.(?:ts|tsx|mts|cts)$/i;
53
+ const TEST_FILE = /\.(?:spec|test)\.(?:ts|tsx|mts|cts)$/i;
54
+ /**
55
+ * The two halves of the release path. `release-schema.ts` runs the stores' own
56
+ * ensure functions; `release-migrations.ts` runs the versioned migration lists
57
+ * and a few schema runners of its own (better-auth). A module reached by either
58
+ * one is created at release, so both count as coverage.
59
+ */
60
+ const RELEASE_LIST = "src/server/release-schema.ts";
61
+ const RELEASE_MIGRATIONS = "src/server/release-migrations.ts";
62
+ const DDL_GUARD = "src/db/ddl-guard.ts";
63
+ /** The migration runner executes migration-list DDL; `runMigrations` owns it. */
64
+ const MIGRATION_RUNNER = "src/db/migrations.ts";
65
+ /** Guards describe this rule in prose; they never own schema. */
66
+ const GUARDS_DIR = "src/guards/";
67
+ /**
68
+ * Blank out comments so a file that only NAMES `ensureTableExists` — this guard,
69
+ * a doc block, a changelog note — is not reported as defining schema.
70
+ */
71
+ function stripComments(source) {
72
+ return source
73
+ .replace(/\/\*[\s\S]*?\*\//g, " ")
74
+ .replace(/(^|[^:])\/\/[^\n]*/g, "$1 ");
75
+ }
76
+ /**
77
+ * Import specifiers in `release-schema.ts`, resolved to repo-relative paths so
78
+ * they can be compared against the files that actually call `ensureTableExists`.
79
+ */
80
+ function coveredModules(coreDir, sources) {
81
+ const covered = new Set();
82
+ // Static `from "..."` and dynamic `import("...")`; the list uses the latter.
83
+ const importRe = /(?:from\s+|import\s*\(\s*)"([^"]+)"/g;
84
+ for (const match of sources.join("\n").matchAll(importRe)) {
85
+ const spec = match[1];
86
+ if (!spec.startsWith("."))
87
+ continue;
88
+ const fromDir = path.join(coreDir, "src", "server");
89
+ const resolved = path.resolve(fromDir, spec).replace(/\.js$/, ".ts");
90
+ covered.add(relPosix(coreDir, resolved));
91
+ }
92
+ return covered;
93
+ }
94
+ export function scanReleaseSchemaCoverage(options) {
95
+ const coreDir = options.corePackageDir ?? path.join(options.root, "packages", "core");
96
+ const findings = [];
97
+ const listSource = readFileSafe(path.join(coreDir, RELEASE_LIST));
98
+ if (listSource === null) {
99
+ // Not "nothing to check" — the list this guard exists to audit is gone.
100
+ findings.push({
101
+ file: RELEASE_LIST,
102
+ line: 1,
103
+ message: "release-schema.ts is missing; every framework table would stop being created at release time.",
104
+ });
105
+ return { name: "release-schema-complete", findings };
106
+ }
107
+ const covered = coveredModules(coreDir, [
108
+ listSource,
109
+ readFileSafe(path.join(coreDir, RELEASE_MIGRATIONS)) ?? "",
110
+ ]);
111
+ const srcDir = path.join(coreDir, "src");
112
+ for (const file of walk(srcDir)) {
113
+ if (!SOURCE_EXTENSIONS.test(file) || TEST_FILE.test(file))
114
+ continue;
115
+ const rel = relPosix(coreDir, file);
116
+ if (rel === RELEASE_LIST || rel === RELEASE_MIGRATIONS)
117
+ continue;
118
+ if (rel === DDL_GUARD)
119
+ continue;
120
+ if (rel === MIGRATION_RUNNER)
121
+ continue;
122
+ if (rel.startsWith(GUARDS_DIR))
123
+ continue;
124
+ const source = readFileSafe(file);
125
+ if (source === null)
126
+ continue;
127
+ const code = stripComments(source);
128
+ if (!definesSchema(code))
129
+ continue;
130
+ if (covered.has(rel))
131
+ continue;
132
+ if (ALLOW_MARKER_RE.test(source))
133
+ continue;
134
+ const lines = code.split("\n");
135
+ const line = lines.findIndex((text) => definesSchema(text)) + 1;
136
+ findings.push({
137
+ file: rel,
138
+ line: line > 0 ? line : 1,
139
+ message: "creates tables but is not imported by src/server/release-schema.ts, so they are never created on a hosted deploy.",
140
+ });
141
+ }
142
+ findings.sort((a, b) => a.file.localeCompare(b.file));
143
+ return { name: "release-schema-complete", findings };
144
+ }
@@ -1,5 +1,6 @@
1
1
  import type { A2AArtifactIdentity } from "../a2a/artifact-response.js";
2
2
  import type { IncomingMessage, PlatformRunProgressRef } from "./types.js";
3
+ export declare function ensureTable(): Promise<void>;
3
4
  export declare function ensureA2AContinuationsTable(): Promise<void>;
4
5
  export type A2AContinuationStatus = "pending" | "processing" | "delivering" | "completed" | "failed";
5
6
  export type A2ATerminalDeliveryKind = "success" | "failure";
@@ -42,7 +42,7 @@ function buildCreateSql() {
42
42
  )
43
43
  `;
44
44
  }
45
- async function ensureTable() {
45
+ export async function ensureTable() {
46
46
  if (!_initPromise) {
47
47
  _initPromise = (async () => {
48
48
  const client = getDbExec();
@@ -1,5 +1,6 @@
1
1
  /** Channel-thread clarification windows are deliberately short-lived. */
2
2
  export declare const INTEGRATION_AWAITING_INPUT_TTL_MS: number;
3
+ export declare function ensureTable(): Promise<void>;
3
4
  /**
4
5
  * Open (or refresh) the bounded reply window after an integration explicitly
5
6
  * asks the originating Slack user a question. The workspace-qualified external
@@ -3,7 +3,7 @@ import { ensureTableExists } from "../db/ddl-guard.js";
3
3
  let initPromise;
4
4
  /** Channel-thread clarification windows are deliberately short-lived. */
5
5
  export const INTEGRATION_AWAITING_INPUT_TTL_MS = 24 * 60 * 60 * 1000;
6
- async function ensureTable() {
6
+ export async function ensureTable() {
7
7
  if (!initPromise) {
8
8
  initPromise = (async () => {
9
9
  const client = getDbExec();
@@ -1,3 +1,4 @@
1
+ export declare function ensureTable(): Promise<void>;
1
2
  export declare function integrationConfigWriteEpoch(): number;
2
3
  export interface IntegrationConfig {
3
4
  platform: string;
@@ -1,7 +1,7 @@
1
1
  import { getDbExec, isPostgres, intType } from "../db/client.js";
2
2
  import { ensureTableExists } from "../db/ddl-guard.js";
3
3
  let _initPromise;
4
- async function ensureTable() {
4
+ export async function ensureTable() {
5
5
  if (!_initPromise) {
6
6
  _initPromise = (async () => {
7
7
  const client = getDbExec();
@@ -16,6 +16,7 @@ export interface IntegrationControl {
16
16
  status: "pending" | "claimed" | "expired";
17
17
  expiresAt: number;
18
18
  }
19
+ export declare function ensureTable(): Promise<void>;
19
20
  export declare function _resetIntegrationControlsStoreForTests(): void;
20
21
  export declare function createIntegrationControl(input: {
21
22
  action: IntegrationControlAction;
@@ -3,7 +3,7 @@ import { getDbExec, intType, isPostgres } from "../db/client.js";
3
3
  import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
4
4
  import { isDuplicateColumnError } from "../db/migrations.js";
5
5
  let initPromise;
6
- async function ensureTable() {
6
+ export async function ensureTable() {
7
7
  if (!initPromise) {
8
8
  initPromise = (async () => {
9
9
  const sql = `CREATE TABLE IF NOT EXISTS integration_controls (
@@ -12,6 +12,7 @@ export interface IntegrationIdentityLink {
12
12
  createdAt: number;
13
13
  updatedAt: number;
14
14
  }
15
+ export declare function ensureTable(): Promise<void>;
15
16
  /** Persist a verified mapping and fail closed if it changes identity later. */
16
17
  export declare function upsertVerifiedIntegrationIdentity(input: {
17
18
  platform: string;
@@ -32,7 +32,7 @@ const INDEXES = [
32
32
  ON ${TABLE}(org_id, user_email)`,
33
33
  ],
34
34
  ];
35
- async function ensureTable() {
35
+ export async function ensureTable() {
36
36
  if (!_initPromise) {
37
37
  _initPromise = (async () => {
38
38
  const client = getDbExec();
@@ -83,6 +83,7 @@ export interface IntegrationInstallationUpdate {
83
83
  lastHealthyAt?: number | null;
84
84
  tokenExpiresAt?: number | null;
85
85
  }
86
+ export declare function ensureTable(): Promise<void>;
86
87
  /**
87
88
  * Create or refresh a managed install. Re-installs may rotate tokens inside
88
89
  * the same owner/org scope, but cannot silently move an existing provider
@@ -61,7 +61,7 @@ const INDEXES = [
61
61
  `CREATE INDEX IF NOT EXISTS idx_integration_installations_org ON ${TABLE}(org_id, updated_at)`,
62
62
  ],
63
63
  ];
64
- async function ensureTable() {
64
+ export async function ensureTable() {
65
65
  if (!_initPromise) {
66
66
  _initPromise = (async () => {
67
67
  const client = getDbExec();
@@ -1,4 +1,5 @@
1
1
  import type { ComputerCommandEnvelope, ComputerOperationClass, RemoteCommand, RemoteCommandKind } from "./remote-types.js";
2
+ export declare function ensureTable(): Promise<void>;
2
3
  export declare function isRemoteCommandKind(value: unknown): value is RemoteCommandKind;
3
4
  export declare function enqueueRemoteCommand(input: {
4
5
  deviceId: string;
@@ -16,7 +16,7 @@ const REMOTE_COMMAND_KINDS = [
16
16
  "status",
17
17
  ];
18
18
  const TERMINAL_STATUSES = new Set(["completed", "failed"]);
19
- async function ensureTable() {
19
+ export async function ensureTable() {
20
20
  if (!_initPromise) {
21
21
  _initPromise = (async () => {
22
22
  const client = getDbExec();
@@ -1,4 +1,5 @@
1
1
  import type { PublicRemoteDevice, RemoteComputerCapabilities, RemoteDevice, RemoteDeviceMetadata, RemoteExecutionCapabilities } from "./remote-types.js";
2
+ export declare function ensureTable(): Promise<void>;
2
3
  export declare function toPublicRemoteDevice(device: RemoteDevice): PublicRemoteDevice;
3
4
  export declare function getRemoteComputerCapabilities(device: Pick<RemoteDevice, "metadata">): RemoteComputerCapabilities | null;
4
5
  export declare function getRemoteExecutionCapabilities(device: Pick<RemoteDevice, "metadata">): RemoteExecutionCapabilities | null;
@@ -1,7 +1,7 @@
1
1
  import { getDbExec, intType, isPostgres, retryOnDdlRace, } from "../db/client.js";
2
2
  import { ensureColumnExists, ensureIndexExists, ensureTableExists, } from "../db/ddl-guard.js";
3
3
  let _initPromise;
4
- async function ensureTable() {
4
+ export async function ensureTable() {
5
5
  if (!_initPromise) {
6
6
  _initPromise = (async () => {
7
7
  const client = getDbExec();
@@ -1,4 +1,5 @@
1
1
  import type { PublicRemotePushRegistration, RemotePushNotification, RemotePushRegistration } from "./remote-types.js";
2
+ export declare function ensureTables(): Promise<void>;
2
3
  export declare function toPublicRemotePushRegistration(registration: RemotePushRegistration): PublicRemotePushRegistration;
3
4
  export declare function upsertRemotePushRegistration(input: {
4
5
  ownerEmail: string;
@@ -43,7 +43,7 @@ function buildCreateNotificationsSql() {
43
43
  )
44
44
  `;
45
45
  }
46
- async function ensureTables() {
46
+ export async function ensureTables() {
47
47
  if (!_initPromise) {
48
48
  _initPromise = (async () => {
49
49
  const client = getDbExec();
@@ -1,4 +1,5 @@
1
1
  import type { RemoteLiveViewEvent, RemoteRunEvent } from "./remote-types.js";
2
+ export declare function ensureTable(): Promise<void>;
2
3
  export declare function insertRemoteRunEvents(input: {
3
4
  deviceId: string;
4
5
  remoteRunId: string;
@@ -18,7 +18,7 @@ function buildCreateSql() {
18
18
  )
19
19
  `;
20
20
  }
21
- async function ensureTable() {
21
+ export async function ensureTable() {
22
22
  if (!_initPromise) {
23
23
  _initPromise = (async () => {
24
24
  const client = getDbExec();
@@ -42,6 +42,7 @@ export interface SaveIntegrationScopeInput extends IntegrationScopeKey {
42
42
  defaultModel?: string | null;
43
43
  policy?: Partial<IntegrationScopePolicy>;
44
44
  }
45
+ export declare function ensureTable(): Promise<void>;
45
46
  /** A stable, non-secret subject key suitable for a scope budget. */
46
47
  export declare function integrationScopeSubjectKey(key: IntegrationScopeKey): string;
47
48
  export declare function getIntegrationScope(keyInput: IntegrationScopeKey, accessInput: IntegrationScopeAccess): Promise<IntegrationScope | null>;