@voltro/cli 0.45.0 → 0.47.0

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 (117) hide show
  1. package/CHANGELOG.md +206 -0
  2. package/dist/apiBuild-BsooZpw2.js +2 -0
  3. package/dist/{apiBuild-CDQBNRDx.js → apiBuild-FpHCWiv6.js} +2 -2
  4. package/dist/bin.d.ts +8 -0
  5. package/dist/bin.js +1 -1
  6. package/dist/{build-yvsLG77U.js → build-zVygXxGB.js} +8 -8
  7. package/dist/{checkCommand-lrzwOzV1.js → checkCommand-B2Fw73lu.js} +1 -1
  8. package/dist/{checkCommand-Boxov8lr.js → checkCommand-D0dAKciE.js} +4 -4
  9. package/dist/{codegen-sbN1Y8PB.js → codegen-CrMXs4hb.js} +176 -162
  10. package/dist/codegen-DiMn2KkZ.js +2 -0
  11. package/dist/{codegenCommand-CQOLytL-.js → codegenCommand-BTtsnRus.js} +16 -16
  12. package/dist/{codemodRunner-5ZhDH3rB.js → codemodRunner-DSZjgyCL.js} +8 -0
  13. package/dist/{commands-CEkVoFM5.js → commands-BrFKxnYW.js} +24 -24
  14. package/dist/{dashboardCommand-0ahyp-zA.js → dashboardCommand-D9SjDc8E.js} +3 -3
  15. package/dist/{dataCommand-D4IlZcih.js → dataCommand-Dl11q14e.js} +271 -230
  16. package/dist/dbCommand-BUD4Fd8v.js +2 -0
  17. package/dist/{dbCommand-B237qI-j.js → dbCommand-jbrmzwW_.js} +110 -110
  18. package/dist/{dev-P4HyeY9W.js → dev-CaIfZnw5.js} +1 -1
  19. package/dist/{dev-DAM5CnAa.js → dev-RjB7eE_B.js} +2081 -2058
  20. package/dist/devActivity.d.ts +8 -0
  21. package/dist/doctorCommand-5zv6PN-G.js +2 -0
  22. package/dist/{doctorCommand-DW2cwAvC.js → doctorCommand-D7X29cw6.js} +16 -16
  23. package/dist/{doctorSourceRelations-CPjSwYuZ.js → doctorSourceRelations-Dd48LPvO.js} +15 -10
  24. package/dist/{dormancyCommand-BqQz7lbM.js → dormancyCommand-BGOP27fz.js} +1 -1
  25. package/dist/{embeddingsCommand-DJyArpU4.js → embeddingsCommand-D72E22bw.js} +1 -1
  26. package/dist/{envCommand-CviRZx1L.js → envCommand-BHSxz6wC.js} +2 -2
  27. package/dist/{evalCommand-6RUfPen4.js → evalCommand-Db01Kbng.js} +24 -24
  28. package/dist/{evolveCommand-qdlP-R9G.js → evolveCommand-C2ofGGlz.js} +2 -2
  29. package/dist/{frameworkTableAssembly-oMPBKqlE.js → frameworkTableAssembly-BvZ0Lil_.js} +97 -89
  30. package/dist/frameworkTableAssembly-DDKtwsy2.js +2 -0
  31. package/dist/index.d.ts +8 -0
  32. package/dist/index.js +1 -1
  33. package/dist/{infoCommand-CNWPSUcW.js → infoCommand-CuNl9cbh.js} +1 -1
  34. package/dist/inspectState.d.ts +8 -0
  35. package/dist/interruptedReplace-C1ZI84xi.js +27 -0
  36. package/dist/interruptedReplace-DNJ7MKph.js +2 -0
  37. package/dist/{migrate-DN47p2PG.js → migrate-odCPGHPq.js} +27 -27
  38. package/dist/{runtimeTrace-BDZSt9W_.js → runtimeTrace-C_OKr0jY.js} +1 -1
  39. package/dist/{sdkgen-sNaD3oZB.js → sdkgen-D9trW7sl.js} +1 -1
  40. package/dist/{seedRunner-IdHEprqf.js → seedRunner-Dgsiwk_e.js} +59 -59
  41. package/dist/serveCommand-BU0wfV6V.js +1931 -0
  42. package/dist/serveCommand-Bwrn_9Fn.js +2 -0
  43. package/dist/serveEntry.d.ts +8 -0
  44. package/dist/serveEntry.js +1 -1
  45. package/dist/{start-Ds3xyn8R.js → start-7HcSIKEp.js} +1 -1
  46. package/dist/{start-BAlGcjF5.js → start-DvlYDyAr.js} +1 -1
  47. package/dist/startEntry.d.ts +8 -0
  48. package/dist/startEntry.js +1 -1
  49. package/dist/startup.d.ts +8 -0
  50. package/dist/{test-CHb7UwvE.js → test-rXFq4S76.js} +1 -1
  51. package/dist/{updateCommand-rCnhaj84.js → updateCommand-BlyXavoG.js} +1 -1
  52. package/dist/updateCommand-CT5AvVg7.js +2 -0
  53. package/dist/{webDev-101csg6Q.js → webDev-B4IEMB0n.js} +6 -6
  54. package/dist/webDev-B79ji8M5.js +2 -0
  55. package/dist/{webhooksCommand-C0iZZfaI.js → webhooksCommand-BqcWcbuW.js} +1 -1
  56. package/package.json +23 -17
  57. package/templates/AGENTS.md +1 -1
  58. package/templates/agent-docs/_index.md +1 -1
  59. package/templates/agent-docs/cli.md +166 -2
  60. package/templates/agent-docs/data.md +70 -4
  61. package/templates/agent-docs/whats-new.md +14 -87
  62. package/templates/apps/api-ai/package.json +7 -7
  63. package/templates/apps/api-auth/package.json +8 -8
  64. package/templates/apps/api-backend/package.json +7 -7
  65. package/templates/apps/api-backend-deactivation/package.json +7 -7
  66. package/templates/apps/api-backend-mail/package.json +8 -8
  67. package/templates/apps/api-backend-mariadb/package.json +9 -9
  68. package/templates/apps/api-backend-sqlite/package.json +8 -8
  69. package/templates/apps/api-backend-storage/package.json +8 -8
  70. package/templates/apps/api-cms/package.json +10 -10
  71. package/templates/apps/api-collab/package.json +8 -8
  72. package/templates/apps/api-data-advanced/package.json +8 -8
  73. package/templates/apps/api-durable/package.json +8 -8
  74. package/templates/apps/api-feature-flags/package.json +9 -9
  75. package/templates/apps/api-governance/package.json +8 -8
  76. package/templates/apps/api-kv/package.json +8 -8
  77. package/templates/apps/api-moderation/package.json +8 -8
  78. package/templates/apps/api-observability/package.json +8 -8
  79. package/templates/apps/api-ratelimit/package.json +8 -8
  80. package/templates/apps/api-rbac/package.json +8 -8
  81. package/templates/apps/api-rest/package.json +7 -7
  82. package/templates/apps/api-saas/package.json +11 -11
  83. package/templates/apps/api-saas-starter/package.json +10 -10
  84. package/templates/apps/api-search/package.json +8 -8
  85. package/templates/apps/api-status/package.json +8 -8
  86. package/templates/apps/api-versioning/package.json +8 -8
  87. package/templates/apps/api-webhooks/package.json +9 -9
  88. package/templates/apps/changelog/package.json +6 -6
  89. package/templates/apps/edge-functions/package.json +2 -2
  90. package/templates/apps/frontend-admin/package.json +8 -8
  91. package/templates/apps/frontend-app/package.json +9 -9
  92. package/templates/apps/frontend-auth/package.json +8 -8
  93. package/templates/apps/frontend-blank/package.json +7 -7
  94. package/templates/apps/frontend-cms/package.json +9 -9
  95. package/templates/apps/frontend-collab/package.json +10 -10
  96. package/templates/apps/frontend-contact/package.json +7 -7
  97. package/templates/apps/frontend-dashboard/package.json +7 -7
  98. package/templates/apps/frontend-docs/package.json +7 -7
  99. package/templates/apps/frontend-i18n/package.json +6 -6
  100. package/templates/apps/frontend-landing/package.json +7 -7
  101. package/templates/apps/frontend-portal/package.json +8 -8
  102. package/templates/apps/frontend-saas/package.json +8 -8
  103. package/templates/apps/frontend-spa/package.json +7 -7
  104. package/templates/apps/frontend-ssr/package.json +7 -7
  105. package/templates/apps/frontend-ssr-api/package.json +8 -8
  106. package/templates/apps/frontend-static-blog/package.json +6 -6
  107. package/templates/apps/frontend-status/package.json +8 -8
  108. package/templates/apps/mobile-app/package.json +4 -4
  109. package/dist/apiBuild-yJCqJYQ8.js +0 -2
  110. package/dist/codegen-DcE2li1i.js +0 -2
  111. package/dist/dbCommand-BvQeKQOb.js +0 -2
  112. package/dist/doctorCommand-2K1dIzYk.js +0 -2
  113. package/dist/frameworkTableAssembly-DgylYh9_.js +0 -2
  114. package/dist/serveCommand-BBhT2U94.js +0 -1885
  115. package/dist/serveCommand-DY2jLy0o.js +0 -2
  116. package/dist/updateCommand-BH6EGuCc.js +0 -2
  117. package/dist/webDev-BLKBO34K.js +0 -2
@@ -5,18 +5,18 @@ import { n as i } from "./appModuleLoader-C9r9mxZt.js";
5
5
  import { a, i as o, n as s, t as c } from "./cliArgs-D4p8n7EE.js";
6
6
  import { r as l } from "./dialectDriver-czCHYpeH.js";
7
7
  import { a as u } from "./connectionConfig-Bk9IC7D0.js";
8
- import { i as d, n as f, r as p, s as m, t as h } from "./seedRunner-IdHEprqf.js";
9
- import { n as g, s as _, y as v } from "./frameworkTableAssembly-oMPBKqlE.js";
8
+ import { i as d, n as f, r as p, s as m, t as h } from "./seedRunner-Dgsiwk_e.js";
9
+ import { n as g, s as _, y as v } from "./frameworkTableAssembly-BvZ0Lil_.js";
10
10
  import { b as y, x as b } from "./fileConventions-Cof68_BL.js";
11
11
  import { r as x, t as S } from "./inspectGateHint-BjnFubmH.js";
12
12
  import { basename as ee, join as C, relative as w, resolve as T } from "node:path";
13
13
  import { promises as E, writeSync as te } from "node:fs";
14
14
  import { pathToFileURL as D } from "node:url";
15
15
  import { createLogger as O } from "@voltro/logger";
16
- import { Effect as k } from "effect";
17
- import { SqlClient as A } from "@effect/sql";
18
- import { DEFAULT_CDC_CHANNEL as j, applyPlan as ne, applySchema as re, assessRollingDeployGate as ie, branchRehearsalExitCode as ae, declaredSnapshot as oe, destructiveScope as se, fingerprintSchema as ce, formatBranchRehearsal as le, ignoreTablesFromEnv as M, introspectSchema as N, pendingFileMigrationIds as ue, planMigrations as P, recordUpToDate as de, rehearseMigrationOnBranch as fe, rollbackFileBasedMigration as pe, rollingDeployUnsafeOps as me, runFileBasedMigrations as he, shortFingerprint as F, squashMigrationPlans as ge, unblockLossy as _e } from "@voltro/database/sql";
19
- import { actorsTable as ve, branchNamespaceName as ye, decodeFieldValue as be, encodeFieldValue as xe, frameworkTables as Se, isEncrypted as I, isMigrationDefinition as Ce, isRawEncoding as we, makeNamespaceBranchExecutor as Te, provisionBranch as Ee, quoteIdent as De, registerCoreTables as Oe, resolveBranchMechanism as ke, teardownBranch as Ae } from "@voltro/database";
16
+ import { actorsTable as k, branchNamespaceName as ne, decodeFieldValue as re, encodeFieldValue as ie, frameworkTables as ae, isEncrypted as A, isMigrationDefinition as oe, isRawEncoding as se, makeNamespaceBranchExecutor as ce, provisionBranch as le, quoteIdent as ue, registerCoreTables as de, resolveBranchMechanism as fe, teardownBranch as pe } from "@voltro/database";
17
+ import { Effect as j } from "effect";
18
+ import { SqlClient as M } from "@effect/sql";
19
+ import { DEFAULT_CDC_CHANNEL as me, applyPlan as he, applySchema as ge, assessRollingDeployGate as _e, branchRehearsalExitCode as ve, declaredSnapshot as ye, destructiveScope as be, fingerprintSchema as xe, formatBranchRehearsal as Se, ignoreTablesFromEnv as N, introspectSchema as P, pendingFileMigrationIds as Ce, planMigrations as F, recordUpToDate as we, rehearseMigrationOnBranch as Te, rollbackFileBasedMigration as Ee, rollingDeployUnsafeOps as De, runFileBasedMigrations as Oe, shortFingerprint as I, squashMigrationPlans as ke, unblockLossy as Ae } from "@voltro/database/sql";
20
20
  import { InMemoryDataStore as je, makeFieldCipher as Me } from "@voltro/runtime";
21
21
  import { createHash as Ne } from "node:crypto";
22
22
  //#region src/adoptPlan.ts
@@ -237,11 +237,11 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
237
237
  }, Qe = (e, t, n, r) => {
238
238
  let i = `WHERE ${Ge(t, n)}`, a = We(t, n).replace(/^LOWER\((.*)\)$/s, "$1");
239
239
  return n === "mssql" ? `SELECT TOP (${r}) ${a} AS v FROM ${e}\n ${i}` : `SELECT ${a} AS v FROM ${e}\n ${i}\n LIMIT ${r}`;
240
- }, $e = async (e, t, n, r, i) => (await k.runPromise(e.unsafe(Qe(t, n, r, i)))).map((e) => {
240
+ }, $e = async (e, t, n, r, i) => (await j.runPromise(e.unsafe(Qe(t, n, r, i)))).map((e) => {
241
241
  let t = Object.values(e)[0];
242
242
  return typeof t == "string" ? t : JSON.stringify(t ?? null);
243
243
  }), et = async (e, t) => {
244
- let n = await k.runPromise(e.unsafe(t));
244
+ let n = await j.runPromise(e.unsafe(t));
245
245
  return Number(Object.values(n[0] ?? { n: 0 })[0] ?? 0);
246
246
  }, tt = async (e, t, n, r) => {
247
247
  let i = [];
@@ -323,7 +323,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
323
323
  t.warn("migration: failed to import", { file: r }, e);
324
324
  continue;
325
325
  }
326
- let i = (e.default && Ce(e.default) ? e.default : void 0) ?? Object.values(e).find(Ce);
326
+ let i = (e.default && oe(e.default) ? e.default : void 0) ?? Object.values(e).find(oe);
327
327
  if (!i) {
328
328
  t.warn("migration: no defineMigration export", { file: r });
329
329
  continue;
@@ -343,12 +343,12 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
343
343
  return [...n].sort((e, t) => e.definition.id < t.definition.id ? -1 : 1);
344
344
  }, ot = async (e) => {
345
345
  let t = (process.env.DB_DIALECT ?? "postgres").toLowerCase(), n = t === "memory" ? "postgres" : t, r = n, i = t === "memory" ? void 0 : await l(n).then((e) => e.retryFilter, () => void 0);
346
- return k.runPromise(re(Se, r, void 0, i === void 0 ? {} : { retryFilter: i }).pipe(k.provide(e)));
347
- }, st = (e) => k.runPromise(k.gen(function* () {
348
- let e = yield* (yield* A.SqlClient)`SELECT id, status, hash, "appliedAt" FROM "_voltro_migrations"`.pipe(k.orElseSucceed(() => []));
346
+ return j.runPromise(ge(ae, r, void 0, i === void 0 ? {} : { retryFilter: i }).pipe(j.provide(e)));
347
+ }, st = (e) => j.runPromise(j.gen(function* () {
348
+ let e = yield* (yield* M.SqlClient)`SELECT id, status, hash, "appliedAt" FROM "_voltro_migrations"`.pipe(j.orElseSucceed(() => []));
349
349
  return new Map(e.map((e) => [e.id, e]));
350
- }).pipe(k.provide(e))), z = (e, t) => k.runPromise(k.gen(function* () {
351
- yield* (yield* A.SqlClient)`
350
+ }).pipe(j.provide(e))), z = (e, t) => j.runPromise(j.gen(function* () {
351
+ yield* (yield* M.SqlClient)`
352
352
  INSERT INTO "_voltro_migrations"
353
353
  (id, name, hash, status, "appliedAt", "durationMs", "errorMessage", "errorStack")
354
354
  VALUES
@@ -363,7 +363,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
363
363
  "errorStack" = EXCLUDED."errorStack",
364
364
  "updatedAt" = now()
365
365
  `;
366
- }).pipe(k.provide(e))), ct = async (e, t, n) => {
366
+ }).pipe(j.provide(e))), ct = async (e, t, n) => {
367
367
  if (e.length === 0) return {
368
368
  applied: [],
369
369
  failed: null,
@@ -405,7 +405,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
405
405
  for (let e of s.definition.steps) {
406
406
  let n = Date.now();
407
407
  try {
408
- await k.runPromise(e.apply.pipe(k.provide(t))), l.push({
408
+ await j.runPromise(e.apply.pipe(j.provide(t))), l.push({
409
409
  stepName: e.name,
410
410
  status: "applied",
411
411
  durationMs: Date.now() - n
@@ -491,7 +491,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
491
491
  for (let n = e.definition.steps.length - 1; n >= 0; n--) {
492
492
  let o = e.definition.steps[n], s = Date.now();
493
493
  try {
494
- await k.runPromise(o.undo.pipe(k.provide(t))), i.push({
494
+ await j.runPromise(o.undo.pipe(j.provide(t))), i.push({
495
495
  stepName: o.name,
496
496
  status: "applied",
497
497
  durationMs: Date.now() - s
@@ -602,10 +602,10 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
602
602
  }, _t = (e, t, n) => {
603
603
  if (e == null) return;
604
604
  let r = typeof e == "string" ? e : String(e);
605
- if (r === "" || I(r)) return;
606
- let i = xe(t, r), a;
605
+ if (r === "" || A(r)) return;
606
+ let i = ie(t, r), a;
607
607
  try {
608
- a = be(t, i);
608
+ a = re(t, i);
609
609
  } catch (e) {
610
610
  throw Error(`${n.table}.${n.column}: the value could not be read back the way the app reads it (${e.message ?? String(e)}). Nothing was written.`);
611
611
  }
@@ -628,18 +628,18 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
628
628
  " the column may hold a mix while you deploy. Run this again afterwards to",
629
629
  " catch anything written in between — it skips what is already encrypted."
630
630
  ].join("\n"), Ct = (e, t, n) => {
631
- if (typeof e != "string" || !I(e)) return;
631
+ if (typeof e != "string" || !A(e)) return;
632
632
  let r;
633
633
  try {
634
- r = we(t, e);
634
+ r = se(t, e);
635
635
  } catch {
636
636
  return;
637
637
  }
638
638
  if (r !== !0) return;
639
- let i = be(t, e);
639
+ let i = re(t, e);
640
640
  if (typeof i != "string") return;
641
- let a = xe(t, i);
642
- if (be(t, a) !== i) throw Error(`${n.table}.${n.column}: re-encoding did not round-trip. Nothing was written.`);
641
+ let a = ie(t, i);
642
+ if (re(t, a) !== i) throw Error(`${n.table}.${n.column}: re-encoding did not round-trip. Nothing was written.`);
643
643
  return a;
644
644
  }, wt = (e, t, n) => e === "sqlite" ? `SELECT NULL AS n FROM pragma_table_info('${t.table}') WHERE name = '${t.column}'` : `SELECT character_maximum_length AS n FROM information_schema.columns\n WHERE ${n} AND table_name = '${t.table}' AND column_name = '${t.column}'`, Tt = (e) => {
645
645
  if (e == null) return;
@@ -692,7 +692,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
692
692
  let e = (process.env.DB_DIALECT ?? "postgres").toLowerCase();
693
693
  if (e === "memory") throw new r("voltro db: subcommands require a real dialect, not DB_DIALECT=memory.");
694
694
  return e;
695
- }, G = (e) => De(e, W()), K = (e) => e === "mysql" || e === "mariadb" ? "table_schema = DATABASE()" : e === "mssql" ? "table_schema = SCHEMA_NAME()" : "table_schema = 'public'", q = async () => (await l(W())).makeSqlLayer(U()), At = async (e) => {
695
+ }, G = (e) => ue(e, W()), K = (e) => e === "mysql" || e === "mariadb" ? "table_schema = DATABASE()" : e === "mssql" ? "table_schema = SCHEMA_NAME()" : "table_schema = 'public'", q = async () => (await l(W())).makeSqlLayer(U()), At = async (e) => {
696
696
  let t = H(e), n = e.includes("--dry-run"), r = await at(await V(t, it), B);
697
697
  if (r.length === 0) return B.info("no migrations found", { root: t }), 0;
698
698
  if (n) {
@@ -785,9 +785,9 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
785
785
  return n;
786
786
  }, Lt = (e) => {
787
787
  let t = new Map(e.map((e) => [e.tableName, e]));
788
- t.has("actors") || t.set("actors", ve);
788
+ t.has("actors") || t.set("actors", k);
789
789
  let n = t.get("actors"), r = t.get("tenants");
790
- return Oe({
790
+ return de({
791
791
  actors: () => n,
792
792
  ...r === void 0 ? {} : { tenants: () => r }
793
793
  }), [...t.values()];
@@ -799,19 +799,19 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
799
799
  }
800
800
  return [...t.values()];
801
801
  }, zt = (e) => {
802
- let t = se(process.env.VOLTRO_DESTRUCTIVE_OK);
802
+ let t = be(process.env.VOLTRO_DESTRUCTIVE_OK);
803
803
  if (t === void 0 || !e.operations.filter((e) => e.blocked).every((e) => e.classification === "lossy")) return {
804
804
  plan: e,
805
805
  acknowledged: !1
806
806
  };
807
- let n = _e(e, t);
807
+ let n = Ae(e, t);
808
808
  return {
809
809
  plan: n,
810
810
  acknowledged: !n.operations.some((e) => e.blocked)
811
811
  };
812
- }, J = async (e, t) => k.runPromise(t.pipe(k.provide(e))), Y = async (e) => {
812
+ }, J = async (e, t) => j.runPromise(t.pipe(j.provide(e))), Y = async (e) => {
813
813
  try {
814
- return await J(e, A.SqlClient.pipe(k.flatMap(N)));
814
+ return await J(e, M.SqlClient.pipe(j.flatMap(P)));
815
815
  } catch (e) {
816
816
  let t = String(e?.message ?? e);
817
817
  if (Ot(e) || /connection error/i.test(t)) {
@@ -901,7 +901,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
901
901
  if (i === void 0 || a === void 0) continue;
902
902
  let o = 0;
903
903
  try {
904
- let e = await J(t, A.SqlClient.pipe(k.flatMap((e) => e.unsafe(`SELECT COUNT(*) AS n FROM ${De(i, W())}`))));
904
+ let e = await J(t, M.SqlClient.pipe(j.flatMap((e) => e.unsafe(`SELECT COUNT(*) AS n FROM ${ue(i, W())}`))));
905
905
  o = Number(Object.values(e[0] ?? { n: 0 })[0] ?? 0);
906
906
  } catch {
907
907
  continue;
@@ -915,9 +915,9 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
915
915
  }
916
916
  }, Ut = async (e, t) => {
917
917
  if (W() !== "postgres") return;
918
- let n = j, r;
918
+ let n = me, r;
919
919
  try {
920
- r = await J(t, A.SqlClient.pipe(k.flatMap((t) => m(t, e, n))));
920
+ r = await J(t, M.SqlClient.pipe(j.flatMap((t) => m(t, e, n))));
921
921
  } catch {
922
922
  return;
923
923
  }
@@ -925,7 +925,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
925
925
  if (a.length === 0) return;
926
926
  B.info(i.missing.length + i.stale.length > 0 ? `db apply: installing change triggers on ${i.missing.length} table(s)` + (i.stale.length > 0 ? `, removing ${i.stale.length} stale one(s)` : "") + (i.functionOutdated ? ", replacing an outdated notify function" : "") : "db apply: replacing an outdated change-notify function (no table drift)");
927
927
  let o = 0;
928
- for (let e of a) await J(t, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(e)))), o += 1;
928
+ for (let e of a) await J(t, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(e)))), o += 1;
929
929
  B.info(`db apply: change triggers converged (${o} statement(s))`, {
930
930
  installed: i.missing.length,
931
931
  removed: i.stale.length,
@@ -940,17 +940,17 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
940
940
  for (let t of e.operations) console.log(Vt(t));
941
941
  console.log(), console.log(` safe: ${t.safe} needs-default: ${t.needsDefault} needs-backfill: ${t.needsBackfill}`), console.log(` rename: ${t.needsRenameAnnotation} lossy: ${t.lossy} blocked: ${t.blocked}`), console.log(` fingerprint: ${e.fromFingerprint.slice(0, 16)} → ${e.toFingerprint.slice(0, 16)}\n`), Wt(e);
942
942
  }, Wt = (e) => {
943
- let t = me(e.operations);
943
+ let t = De(e.operations);
944
944
  if (t.length !== 0) {
945
945
  console.log(` ⚠ ${t.length} operation(s) UNSAFE under a rolling deploy`), console.log(" (old + new instances overlap → old code breaks against the new schema):");
946
946
  for (let e of t) console.log(` • ${e.op.op.kind}: ${e.reason}`), console.log(` → ${e.remedy}`);
947
947
  console.log(" Deploy with a maintenance window / scale-to-zero, or split into"), console.log(" expand → deploy → contract. See docs: deployment/production-hardening.\n");
948
948
  }
949
949
  }, Gt = (e, t) => {
950
- let n = ie({
950
+ let n = _e({
951
951
  enabled: process.env.VOLTRO_ROLLING_DEPLOY === "1",
952
952
  forced: t.includes("--force"),
953
- unsafeCount: me(e.operations).length
953
+ unsafeCount: De(e.operations).length
954
954
  });
955
955
  return n.refuse ? (B.error(`db apply: ${n.message}`), !0) : (n.warnForced && B.warn(`db apply: ${n.message}`), !1);
956
956
  }, Kt = (e) => {
@@ -965,7 +965,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
965
965
  let n = await g({ root: e });
966
966
  return Lt(Rt([
967
967
  ...t,
968
- ...Se,
968
+ ...ae,
969
969
  ...n
970
970
  ]));
971
971
  }, Q = async (e, t, n) => {
@@ -1005,11 +1005,11 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1005
1005
  if (!i.ok) return B.error(`db plan --against: remote returned ${i.status}`, { url: e }), x(i.status) && console.error(` ${S(i.status)}`), 1;
1006
1006
  let a = (await i.json()).drift?.liveSnapshot;
1007
1007
  if (!a) return B.error("db plan --against: remote inspect payload missing drift.liveSnapshot", { url: e }), 1;
1008
- let s = P({
1008
+ let s = F({
1009
1009
  declared: r,
1010
1010
  live: a,
1011
1011
  dialect: W(),
1012
- ...M(),
1012
+ ...N(),
1013
1013
  ...t === void 0 ? {} : { onlineAfter: t }
1014
1014
  });
1015
1015
  return console.log(`\n[--against ${e}] — diff vs remote live schema:\n`), X(s), s.summary.blocked > 0 ? 2 : 0;
@@ -1017,11 +1017,11 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1017
1017
  return B.error(`db plan --against: ${e.message}`), 1;
1018
1018
  }
1019
1019
  }
1020
- let a = await Y(await q()), o = P({
1020
+ let a = await Y(await q()), o = F({
1021
1021
  declared: r,
1022
1022
  live: a,
1023
1023
  dialect: W(),
1024
- ...M(),
1024
+ ...N(),
1025
1025
  ...t === void 0 ? {} : { onlineAfter: t }
1026
1026
  });
1027
1027
  return e.includes("--json") ? (te(1, `${JSON.stringify(o, null, 2)}\n`), o.summary.blocked > 0 ? 2 : 0) : (X(o), o.summary.blocked > 0 ? 2 : 0);
@@ -1036,13 +1036,13 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1036
1036
  if (!Array.isArray(r?.operations) || typeof r?.fromFingerprint != "string" || typeof r?.toFingerprint != "string") return B.error(`db apply --plan: '${e}' is not a valid plan file (expected the output of \`voltro db plan --json\`).`), 1;
1037
1037
  let i = await Z(n);
1038
1038
  if (i === void 0) return B.warn("db apply --plan: no schema files found", { root: n }), 1;
1039
- let a = await q(), o = await J(a, A.SqlClient.pipe(k.flatMap((e) => ue(e, n)))).catch(() => []);
1039
+ let a = await q(), o = await J(a, M.SqlClient.pipe(j.flatMap((e) => Ce(e, n)))).catch(() => []);
1040
1040
  if (o.length > 0) return B.error(`db apply --plan: refusing — ${o.length} pending file-based migration(s).`), console.error(` ${o.join("\n ")}`), console.error(""), console.error(" These perform the changes a state diff cannot infer, so they change the shape"), console.error(" this plan was computed against. Apply them and regenerate the plan:"), console.error(""), console.error(" voltro db files ."), console.error(" voltro db plan --json > plan.json"), console.error(" voltro db apply --plan plan.json"), 1;
1041
- let c = await Y(a), l = P({
1041
+ let c = await Y(a), l = F({
1042
1042
  declared: i,
1043
1043
  live: c,
1044
1044
  dialect: W(),
1045
- ...M()
1045
+ ...N()
1046
1046
  });
1047
1047
  if (l.fromFingerprint !== r.fromFingerprint) return B.error("db apply --plan: refusing — the live schema has drifted since this plan was generated."), console.error(` plan.from=${r.fromFingerprint.slice(0, 16)} live=${l.fromFingerprint.slice(0, 16)}`), console.error(" Regenerate against the current live schema: `voltro db plan --json > plan.json`"), 2;
1048
1048
  if (l.toFingerprint !== r.toFingerprint) return B.error("db apply --plan: refusing — the declared schema differs from what this plan targets."), console.error(` plan.to=${r.toFingerprint.slice(0, 16)} declared=${l.toFingerprint.slice(0, 16)}`), console.error(" The schema files changed since the plan was generated. Regenerate the plan."), 2;
@@ -1050,7 +1050,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1050
1050
  if (d.summary.blocked > 0 && !u.acknowledged) return X(d), B.error(`db apply --plan: refusing — ${l.summary.blocked} blocked operation(s). See the fix hints above.`), process.env.VOLTRO_DESTRUCTIVE_OK !== void 0 && (B.error(" VOLTRO_DESTRUCTIVE_OK is set but did not cover this plan — it only relaxes"), B.error(" `lossy` operations, and only the tables it names. Anything else stays refused.")), 2;
1051
1051
  if (u.acknowledged && B.warn("db apply --plan: proceeding with acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)"), Gt(d, t)) return 2;
1052
1052
  if (d.operations.length === 0) {
1053
- let e = await J(a, A.SqlClient.pipe(k.flatMap((e) => de(e, d, {
1053
+ let e = await J(a, M.SqlClient.pipe(j.flatMap((e) => we(e, d, {
1054
1054
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:plan",
1055
1055
  environment: $(),
1056
1056
  source: "file"
@@ -1058,17 +1058,17 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1058
1058
  return B.info(e === "recorded" ? `db apply --plan: schema is up to date — no DDL to apply, recorded fingerprint=${d.toFingerprint.slice(0, 16)} (change triggers are reconciled separately below)` : "db apply --plan: schema is up to date — no DDL to apply (change triggers are reconciled separately below)"), Q(n, i, a);
1059
1059
  }
1060
1060
  X(d);
1061
- let f = s(t, "--note"), p = await J(a, A.SqlClient.pipe(k.flatMap((e) => ne(e, d, {
1061
+ let f = s(t, "--note"), p = await J(a, M.SqlClient.pipe(j.flatMap((e) => he(e, d, {
1062
1062
  declared: i,
1063
1063
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:plan",
1064
1064
  environment: $(),
1065
1065
  source: "file",
1066
1066
  ...f ? { notes: f } : {},
1067
- replan: (e) => N(e).pipe(k.map((e) => P({
1067
+ replan: (e) => P(e).pipe(j.map((e) => F({
1068
1068
  declared: i,
1069
1069
  live: e,
1070
1070
  dialect: W(),
1071
- ...M()
1071
+ ...N()
1072
1072
  })))
1073
1073
  }))));
1074
1074
  return B.info(`db apply --plan: applied ${p.appliedOps} op(s) in ${p.durationMs}ms`, {
@@ -1090,11 +1090,11 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1090
1090
  if (a === void 0) return B.warn("db apply: no schema files found", { root: n }), 1;
1091
1091
  let o = await q(), c = await mn(n, o);
1092
1092
  if ("failed" in c) return B.error("db apply: a file-based migration FAILED — the schema diff was NOT run"), console.error(c.failed), console.error("Fix the migration and re-run. `voltro db files` runs them alone."), 1;
1093
- let l = await Y(o), u = P({
1093
+ let l = await Y(o), u = F({
1094
1094
  declared: a,
1095
1095
  live: l,
1096
1096
  dialect: W(),
1097
- ...M(),
1097
+ ...N(),
1098
1098
  ...r === void 0 ? {} : { onlineAfter: r }
1099
1099
  });
1100
1100
  X(u), await Ht(u, o);
@@ -1103,24 +1103,24 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1103
1103
  if (d.acknowledged && B.warn(`db apply: proceeding with ${u.summary.blocked} acknowledged lossy operation(s) (VOLTRO_DESTRUCTIVE_OK)`), Gt(f, e)) return 2;
1104
1104
  if (f.operations.length === 0) {
1105
1105
  B.info("db apply: schema is up to date — no DDL to apply (change triggers are reconciled separately below)");
1106
- let t = await J(o, A.SqlClient.pipe(k.flatMap((e) => de(e, f, {
1106
+ let t = await J(o, M.SqlClient.pipe(j.flatMap((e) => we(e, f, {
1107
1107
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:apply",
1108
1108
  environment: $(),
1109
1109
  source: "auto-diff"
1110
1110
  }))));
1111
1111
  return t === "recorded" && B.info(`db apply: recorded fingerprint=${f.toFingerprint.slice(0, 16)} (0 operations)`), await ln(o), s(e, "--note") !== void 0 && t !== "recorded" && (B.warn("db apply: --note was ignored — this schema is already the latest recorded one, so there is no new history row to attach it to."), console.error("To record that the CURRENT live schema is the accepted baseline, use `voltro db drift --accept`.")), Q(n, a, o);
1112
1112
  }
1113
- let p = s(e, "--note"), m = await J(o, A.SqlClient.pipe(k.flatMap((e) => ne(e, f, {
1113
+ let p = s(e, "--note"), m = await J(o, M.SqlClient.pipe(j.flatMap((e) => he(e, f, {
1114
1114
  declared: a,
1115
1115
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user",
1116
1116
  environment: $(),
1117
1117
  source: "auto-diff",
1118
1118
  ...p ? { notes: p } : {},
1119
- replan: (e) => N(e).pipe(k.map((e) => P({
1119
+ replan: (e) => P(e).pipe(j.map((e) => F({
1120
1120
  declared: a,
1121
1121
  live: e,
1122
1122
  dialect: W(),
1123
- ...M(),
1123
+ ...N(),
1124
1124
  ...r === void 0 ? {} : { onlineAfter: r }
1125
1125
  })))
1126
1126
  }))));
@@ -1177,7 +1177,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1177
1177
  root: t,
1178
1178
  hint: "looked for *.entity.ts / *.schema.ts / schema.ts"
1179
1179
  }), 1;
1180
- let f = U(), p = ke({
1180
+ let f = U(), p = fe({
1181
1181
  seed: n,
1182
1182
  ...f.url === void 0 ? {} : { dbUrl: f.url },
1183
1183
  ...i === void 0 ? {} : { prefer: i }
@@ -1185,22 +1185,22 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1185
1185
  if (p === "neon-cow") return B.error("voltro db branch: this connection resolves to the Neon copy-on-write mechanism, which the CLI cannot execute."), console.error(" A Neon CoW branch is a single call to Neon's branch REST API and needs a Neon API token;"), console.error(" the framework ships the PLAN, and the cloud control plane executes it."), console.error(" Re-run with `--prefer namespace` to rehearse on a schema-per-branch copy instead"), console.error(` (portable, no vendor API — it copies ${n === "copy" ? "every row" : "the schema only"}).`), 1;
1186
1186
  let m = f.schema ?? "public", h = s(e, "--name") ?? ee(t), g = s(e, "--pr"), _ = g === void 0 ? 0 : Number(g);
1187
1187
  if (!Number.isInteger(_) || _ < 0) throw new r(`voltro db branch: --pr must be a non-negative integer, got "${String(g)}"`);
1188
- let v = ye(h, _), y = await l(u), b = y.makeSqlLayer(f), x = y.makeSqlLayer({
1188
+ let v = ne(h, _), y = await l(u), b = y.makeSqlLayer(f), x = y.makeSqlLayer({
1189
1189
  ...f,
1190
1190
  schema: v
1191
- }), S = await Y(b), C = P({
1191
+ }), S = await Y(b), C = F({
1192
1192
  declared: d,
1193
1193
  live: S,
1194
1194
  dialect: u,
1195
- ...M(),
1195
+ ...N(),
1196
1196
  ...c === void 0 ? {} : { onlineAfter: c }
1197
- }), w = S.tables.map((e) => e.name), T = Qt(S), E = $t(S), D = Te({ run: (e) => J(b, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(e)), k.asVoid)) }), O = async () => P({
1197
+ }), w = S.tables.map((e) => e.name), T = Qt(S), E = $t(S), D = ce({ run: (e) => J(b, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(e)), j.asVoid)) }), O = async () => F({
1198
1198
  declared: d,
1199
1199
  live: await Y(x),
1200
1200
  dialect: u,
1201
- ...M(),
1201
+ ...N(),
1202
1202
  ...c === void 0 ? {} : { onlineAfter: c }
1203
- }), j = await fe({
1203
+ }), k = await Te({
1204
1204
  branchId: v,
1205
1205
  mechanism: p,
1206
1206
  branchedTables: w.length,
@@ -1210,7 +1210,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1210
1210
  o || B.info(`db branch: ${e}`);
1211
1211
  },
1212
1212
  provision: async () => {
1213
- await Ee({
1213
+ await le({
1214
1214
  appSlug: h,
1215
1215
  prNumber: _,
1216
1216
  seed: n,
@@ -1225,23 +1225,23 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1225
1225
  fidelityPlan: async () => en(C, await O()),
1226
1226
  plan: O,
1227
1227
  apply: async (e) => {
1228
- await J(x, A.SqlClient.pipe(k.flatMap((t) => ne(t, e, {
1228
+ await J(x, M.SqlClient.pipe(j.flatMap((t) => he(t, e, {
1229
1229
  declared: d,
1230
1230
  appliedBy: "cli:db-branch",
1231
1231
  environment: $(),
1232
1232
  source: "auto-diff",
1233
1233
  notes: `migration rehearsal on branch ${v}`,
1234
- replan: () => k.promise(O)
1234
+ replan: () => j.promise(O)
1235
1235
  }))));
1236
1236
  },
1237
1237
  replan: async () => await O(),
1238
1238
  teardown: async () => {
1239
- await Ae(v, "namespace", D);
1239
+ await pe(v, "namespace", D);
1240
1240
  }
1241
1241
  });
1242
- return o ? te(1, `${JSON.stringify(j, null, 2)}\n`) : console.log(`\n${le(j)}\n`), ae(j);
1242
+ return o ? te(1, `${JSON.stringify(k, null, 2)}\n`) : console.log(`\n${Se(k)}\n`), ve(k);
1243
1243
  }, an = async (e) => {
1244
- let t = Math.max(1, Number(s(e, "--limit") ?? "20")), n = await J(await q(), A.SqlClient.pipe(k.flatMap((e) => e`
1244
+ let t = Math.max(1, Number(s(e, "--limit") ?? "20")), n = await J(await q(), M.SqlClient.pipe(j.flatMap((e) => e`
1245
1245
  SELECT ${e("id")}, ${e("fingerprint")}, ${e("operations")},
1246
1246
  ${e("appliedBy")}, ${e("environment")}, ${e("source")},
1247
1247
  ${e("durationMs")}, ${e("notes")}, ${e("appliedAt")}
@@ -1256,13 +1256,13 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1256
1256
  try {
1257
1257
  t = JSON.parse(un(e.operations)).length;
1258
1258
  } catch {}
1259
- console.log(` ${e.id} fp=${F(e.fingerprint)} env=${e.environment} src=${e.source} ${t} op(s) ${e.durationMs}ms ${dn(e.appliedAt)} by=${e.appliedBy}`), e.notes && console.log(` [2mnote: ${e.notes}[0m`);
1259
+ console.log(` ${e.id} fp=${I(e.fingerprint)} env=${e.environment} src=${e.source} ${t} op(s) ${e.durationMs}ms ${dn(e.appliedAt)} by=${e.appliedBy}`), e.notes && console.log(` [2mnote: ${e.notes}[0m`);
1260
1260
  }
1261
1261
  return console.log(), 0;
1262
1262
  }, on = async (e) => {
1263
1263
  let t = e[0];
1264
1264
  if (!t) return console.error("voltro db restore-snapshot <plan-id>"), console.error(" Renames soft-dropped columns/tables from a plan back to their original names."), console.error(" Requires the plan to have been applied with VOLTRO_SOFT_DROP=1."), 2;
1265
- let n = await q(), r = await J(n, A.SqlClient.pipe(k.flatMap((e) => e`SELECT ${e("id")}, ${e("operations")}
1265
+ let n = await q(), r = await J(n, M.SqlClient.pipe(j.flatMap((e) => e`SELECT ${e("id")}, ${e("operations")}
1266
1266
  FROM ${e("_voltro_migration_plans")} WHERE ${e("id")} = ${t}`)));
1267
1267
  if (r.length === 0) return console.error(`restore-snapshot: plan '${t}' not found`), 1;
1268
1268
  let i;
@@ -1281,7 +1281,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1281
1281
  if (a.length === 0 && o.length === 0) return console.log(`restore-snapshot: plan '${t}' has no drop-column / drop-table ops to restore`), 0;
1282
1282
  let s = 0;
1283
1283
  for (let e of a) {
1284
- let t = await J(n, A.SqlClient.pipe(k.flatMap((t) => t`
1284
+ let t = await J(n, M.SqlClient.pipe(j.flatMap((t) => t`
1285
1285
  SELECT column_name FROM information_schema.columns
1286
1286
  WHERE ${t.unsafe(K(W()))}
1287
1287
  AND table_name = ${e.table}
@@ -1293,11 +1293,11 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1293
1293
  continue;
1294
1294
  }
1295
1295
  let r = t[0].column_name;
1296
- await J(n, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table)} RENAME COLUMN ${G(r)} TO ${G(e.column)}`)))), s++, console.log(` ↩ restored ${e.table}.${e.column} (from ${r})`);
1296
+ await J(n, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table)} RENAME COLUMN ${G(r)} TO ${G(e.column)}`)))), s++, console.log(` ↩ restored ${e.table}.${e.column} (from ${r})`);
1297
1297
  }
1298
1298
  let c = 0;
1299
1299
  for (let e of o) {
1300
- let t = await J(n, A.SqlClient.pipe(k.flatMap((t) => t`
1300
+ let t = await J(n, M.SqlClient.pipe(j.flatMap((t) => t`
1301
1301
  SELECT table_name FROM information_schema.tables
1302
1302
  WHERE ${t.unsafe(K(W()))}
1303
1303
  AND table_name LIKE ${e.table + "__dropped_%"}
@@ -1308,7 +1308,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1308
1308
  continue;
1309
1309
  }
1310
1310
  let r = t[0].table_name;
1311
- await J(n, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(`ALTER TABLE ${G(r)} RENAME TO ${G(e.table)}`)))), c++, console.log(` ↩ restored table ${e.table} (from ${r})`);
1311
+ await J(n, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`ALTER TABLE ${G(r)} RENAME TO ${G(e.table)}`)))), c++, console.log(` ↩ restored table ${e.table} (from ${r})`);
1312
1312
  }
1313
1313
  return console.log(`\n✓ restored ${s} column(s) + ${c} table(s) from plan '${t}'\n`), 0;
1314
1314
  }, sn = async (e) => {
@@ -1316,10 +1316,10 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1316
1316
  if (!t) return console.error("voltro db gc-snapshots --before <date> [--dry-run]"), console.error(" Permanently drops soft-dropped columns/tables (<name>__dropped_<ts>) older than <date>."), console.error(" <date> is ISO — e.g. 2026-01-01 or 2026-01-01T00:00:00Z. NOT reversible."), 2;
1317
1317
  let n = t.replace(/[^0-9]/g, "");
1318
1318
  if (n.length < 8) return console.error(`gc-snapshots: --before must be at least a full date (YYYY-MM-DD), got "${t}"`), 2;
1319
- let r = (n + "00000000000000").slice(0, 14), i = e.includes("--dry-run"), a = await q(), o = await J(a, A.SqlClient.pipe(k.flatMap((e) => e`
1319
+ let r = (n + "00000000000000").slice(0, 14), i = e.includes("--dry-run"), a = await q(), o = await J(a, M.SqlClient.pipe(j.flatMap((e) => e`
1320
1320
  SELECT table_name, column_name FROM information_schema.columns
1321
1321
  WHERE ${e.unsafe(K(W()))} AND column_name LIKE ${"%__dropped_%"}
1322
- `))), c = await J(a, A.SqlClient.pipe(k.flatMap((e) => e`
1322
+ `))), c = await J(a, M.SqlClient.pipe(j.flatMap((e) => e`
1323
1323
  SELECT table_name FROM information_schema.tables
1324
1324
  WHERE ${e.unsafe(K(W()))} AND table_name LIKE ${"%__dropped_%"}
1325
1325
  `))), l = (e) => {
@@ -1328,11 +1328,11 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1328
1328
  }, u = 0;
1329
1329
  for (let e of o) {
1330
1330
  let t = l(e.column_name);
1331
- t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop column" : "dropping column"} ${e.table_name}.${e.column_name}`), i || await J(a, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table_name)} DROP COLUMN ${G(e.column_name)}`)))), u++);
1331
+ t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop column" : "dropping column"} ${e.table_name}.${e.column_name}`), i || await J(a, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`ALTER TABLE ${G(e.table_name)} DROP COLUMN ${G(e.column_name)}`)))), u++);
1332
1332
  }
1333
1333
  for (let e of c) {
1334
1334
  let t = l(e.table_name);
1335
- t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop table" : "dropping table"} ${e.table_name}`), i || await J(a, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(`DROP TABLE ${G(e.table_name)}`)))), u++);
1335
+ t === null || t >= r || (console.log(` ${i ? "[dry-run] would drop table" : "dropping table"} ${e.table_name}`), i || await J(a, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(`DROP TABLE ${G(e.table_name)}`)))), u++);
1336
1336
  }
1337
1337
  return console.log(`\n${i ? `[dry-run] ${u} snapshot(s) would be dropped` : `✓ dropped ${u} snapshot(s)`} (older than ${r}).\n`), 0;
1338
1338
  }, cn = async (e) => {
@@ -1342,23 +1342,23 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1342
1342
  if (Number.isNaN(new Date(n).getTime())) return console.error(`voltro db squash: --before '${n}' is not a valid ISO date`), 2;
1343
1343
  let r = s(e, "--note"), i = H(e), a = await Z(i);
1344
1344
  if (a === void 0) return B.warn("db squash: no schema files found", { root: i }), 1;
1345
- let o = ce(oe(a)), c = await q();
1345
+ let o = xe(ye(a)), c = await q();
1346
1346
  try {
1347
- let e = await J(c, ge({
1347
+ let e = await J(c, ke({
1348
1348
  before: n,
1349
1349
  fingerprint: o,
1350
1350
  appliedBy: process.env.USER ?? "cli",
1351
1351
  environment: $(),
1352
1352
  ...r === void 0 ? {} : { note: r }
1353
1353
  }));
1354
- return console.log(`\n✓ squashed ${e.squashedCount} migration plan(s)\n snapshot id: ${e.snapshotId}\n fingerprint: ${F(e.snapshotFingerprint)}\n`), 0;
1354
+ return console.log(`\n✓ squashed ${e.squashedCount} migration plan(s)\n snapshot id: ${e.snapshotId}\n fingerprint: ${I(e.snapshotFingerprint)}\n`), 0;
1355
1355
  } catch (e) {
1356
1356
  return console.error(`squash refused: ${e.message}`), 1;
1357
1357
  }
1358
1358
  }, ln = async (e) => {
1359
1359
  try {
1360
- let t = await Y(e), n = ce(t);
1361
- await J(e, A.SqlClient.pipe(k.flatMap((e) => e`
1360
+ let t = await Y(e), n = xe(t);
1361
+ await J(e, M.SqlClient.pipe(j.flatMap((e) => e`
1362
1362
  UPDATE ${e("_voltro_migration_plans")}
1363
1363
  SET ${e("liveFingerprint")} = ${n}
1364
1364
  WHERE ${e("id")} = (
@@ -1380,23 +1380,23 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1380
1380
  accept: !0,
1381
1381
  reason: "converged"
1382
1382
  }, pn = async (e) => {
1383
- let t = e.includes("--accept"), n = await q(), r = await J(n, A.SqlClient.pipe(k.flatMap((e) => e`
1383
+ let t = e.includes("--accept"), n = await q(), r = await J(n, M.SqlClient.pipe(j.flatMap((e) => e`
1384
1384
  SELECT * FROM ${e("_voltro_migration_plans")}
1385
1385
  ORDER BY ${e("appliedAt")} DESC
1386
1386
  LIMIT 1
1387
- `))), i = await Y(n), a = ce(i);
1388
- if (r.length === 0) return B.info("db drift: no _voltro_migration_plans rows yet"), console.log(`live user-schema fingerprint: ${F(a)}`), console.log("No baseline to compare against. Run `voltro db apply` to lock in the current state."), 0;
1387
+ `))), i = await Y(n), a = xe(i);
1388
+ if (r.length === 0) return B.info("db drift: no _voltro_migration_plans rows yet"), console.log(`live user-schema fingerprint: ${I(a)}`), console.log("No baseline to compare against. Run `voltro db apply` to lock in the current state."), 0;
1389
1389
  let o = r[0];
1390
- if (o.liveFingerprint === null || o.liveFingerprint === void 0) return B.warn("db drift: no drift baseline recorded yet — cannot compare"), console.log(), console.log(` last applied: ${o.id} at ${dn(o.appliedAt)}`), console.log(` live now: ${F(a)}`), console.log(), console.log("That row was written before the framework recorded a live-schema baseline,"), console.log("and the value it does carry is the DECLARED snapshot's hash — not comparable"), console.log("with a live one. Run `voltro db apply` once to establish the baseline (a no-op"), console.log("apply backfills it too); use `voltro db plan` meanwhile, which compares declared"), console.log("against live directly."), console.log(), console.log("Exit code 3 — NOT 0. \"Did not compare\" is not \"clean\", and a gate on the exit"), console.log("code has to be able to tell them apart."), 3;
1391
- if (o.liveFingerprint === a) return B.info(`db drift: live matches last applied (${F(a)})`), 0;
1390
+ if (o.liveFingerprint === null || o.liveFingerprint === void 0) return B.warn("db drift: no drift baseline recorded yet — cannot compare"), console.log(), console.log(` last applied: ${o.id} at ${dn(o.appliedAt)}`), console.log(` live now: ${I(a)}`), console.log(), console.log("That row was written before the framework recorded a live-schema baseline,"), console.log("and the value it does carry is the DECLARED snapshot's hash — not comparable"), console.log("with a live one. Run `voltro db apply` once to establish the baseline (a no-op"), console.log("apply backfills it too); use `voltro db plan` meanwhile, which compares declared"), console.log("against live directly."), console.log(), console.log("Exit code 3 — NOT 0. \"Did not compare\" is not \"clean\", and a gate on the exit"), console.log("code has to be able to tell them apart."), 3;
1391
+ if (o.liveFingerprint === a) return B.info(`db drift: live matches last applied (${I(a)})`), 0;
1392
1392
  let s = await (async () => {
1393
1393
  try {
1394
1394
  let t = await Z(H(e));
1395
- return t === void 0 ? void 0 : P({
1395
+ return t === void 0 ? void 0 : F({
1396
1396
  declared: t,
1397
1397
  live: i,
1398
1398
  dialect: W(),
1399
- ...M()
1399
+ ...N()
1400
1400
  }).operations;
1401
1401
  } catch {
1402
1402
  return;
@@ -1410,7 +1410,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1410
1410
  for (let e of s.slice(0, 10)) console.log(` - ${e.op.kind} ${"table" in e.op ? `[${e.op.table}]` : ""}`);
1411
1411
  return s.length > 10 && console.log(` … and ${s.length - 10} more`), console.log(), console.log("`--accept` records the CURRENT live schema as the applied baseline. It is for a"), console.log("change that already landed out of band and left the schema correct — not for one"), console.log("that has not landed. Run `voltro db apply` instead; it writes a real baseline."), 4;
1412
1412
  }
1413
- return await J(n, A.SqlClient.pipe(k.flatMap((e) => e`
1413
+ return await J(n, M.SqlClient.pipe(j.flatMap((e) => e`
1414
1414
  UPDATE ${e("_voltro_migration_plans")}
1415
1415
  SET ${e("liveFingerprint")} = ${a}
1416
1416
  WHERE ${e("id")} = (
@@ -1419,13 +1419,13 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1419
1419
  ORDER BY ${e("appliedAt")} DESC LIMIT 1
1420
1420
  ) AS ${e("newest")}
1421
1421
  )
1422
- `))), B.info(`db drift: accepted the live schema as the baseline (${F(a)})`), console.log(), console.log("`voltro db plan` reports 0 operations against this schema, so the live state already"), console.log("matches your declaration — only the ledger did not know. It does now."), console.log(), console.log("No history entry was invented: the latest row's baseline was updated in place,"), console.log("because no migration ran."), 0;
1422
+ `))), B.info(`db drift: accepted the live schema as the baseline (${I(a)})`), console.log(), console.log("`voltro db plan` reports 0 operations against this schema, so the live state already"), console.log("matches your declaration — only the ledger did not know. It does now."), console.log(), console.log("No history entry was invented: the latest row's baseline was updated in place,"), console.log("because no migration ran."), 0;
1423
1423
  }
1424
- return B.error("db drift: live schema DIVERGED from last applied state"), console.log(), console.log(` baseline: ${F(o.liveFingerprint)} at ${dn(o.appliedAt)} (${o.id})`), console.log(` live now: ${F(a)}`), console.log(), console.log("Something changed the live schema after the last apply. This command can see"), console.log("THAT it changed, not what or who — the fingerprints are hashes, not a diff."), console.log(), s === void 0 ? (console.log("No schema files found here, so the declared side could not be compared."), console.log("Run `voltro db plan` from your project root for the actual difference."), 4) : s.length === 0 ? (console.log("Your DECLARED schema is already satisfied — `voltro db plan` reports 0 operations"), console.log("against this database. So the live schema is not wrong, only unrecorded: something"), console.log("applied a change without going through the planner (a hand-run ALTER, a DBA"), console.log("window, a restored dump), or it touched a table your code does not declare."), console.log(), console.log("If that was deliberate and the schema is right, record it:"), console.log(), console.log(" voltro db drift --accept"), console.log(), console.log("It updates the latest ledger row's baseline to the live schema and invents no"), console.log("history entry. Drift then measures from here."), 4) : (console.log(`\`voltro db plan\` reports ${s.length} operation(s) still pending against your`), console.log("declared schema, so this is not merely an unrecorded change — run it for the diff,"), console.log("then `voltro db apply`, which writes a fresh baseline of its own."), 4);
1424
+ return B.error("db drift: live schema DIVERGED from last applied state"), console.log(), console.log(` baseline: ${I(o.liveFingerprint)} at ${dn(o.appliedAt)} (${o.id})`), console.log(` live now: ${I(a)}`), console.log(), console.log("Something changed the live schema after the last apply. This command can see"), console.log("THAT it changed, not what or who — the fingerprints are hashes, not a diff."), console.log(), s === void 0 ? (console.log("No schema files found here, so the declared side could not be compared."), console.log("Run `voltro db plan` from your project root for the actual difference."), 4) : s.length === 0 ? (console.log("Your DECLARED schema is already satisfied — `voltro db plan` reports 0 operations"), console.log("against this database. So the live schema is not wrong, only unrecorded: something"), console.log("applied a change without going through the planner (a hand-run ALTER, a DBA"), console.log("window, a restored dump), or it touched a table your code does not declare."), console.log(), console.log("If that was deliberate and the schema is right, record it:"), console.log(), console.log(" voltro db drift --accept"), console.log(), console.log("It updates the latest ledger row's baseline to the live schema and invents no"), console.log("history entry. Drift then measures from here."), 4) : (console.log(`\`voltro db plan\` reports ${s.length} operation(s) still pending against your`), console.log("declared schema, so this is not merely an unrecorded change — run it for the diff,"), console.log("then `voltro db apply`, which writes a fresh baseline of its own."), 4);
1425
1425
  }, mn = async (e, t) => {
1426
1426
  let n = $();
1427
1427
  try {
1428
- let r = await J(t, A.SqlClient.pipe(k.flatMap((t) => he(t, {
1428
+ let r = await J(t, M.SqlClient.pipe(j.flatMap((t) => Oe(t, {
1429
1429
  projectRoot: e,
1430
1430
  env: n,
1431
1431
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user"
@@ -1436,8 +1436,8 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1436
1436
  }
1437
1437
  }, hn = async (e) => {
1438
1438
  let t = H(e), n = await q(), r = $();
1439
- await J(n, re(Se, W(), void 0, { retryFilter: (await l(W())).retryFilter }));
1440
- let i = await J(n, A.SqlClient.pipe(k.flatMap((e) => he(e, {
1439
+ await J(n, ge(ae, W(), void 0, { retryFilter: (await l(W())).retryFilter }));
1440
+ let i = await J(n, M.SqlClient.pipe(j.flatMap((e) => Oe(e, {
1441
1441
  projectRoot: t,
1442
1442
  env: r,
1443
1443
  appliedBy: process.env.USER ? `cli:${process.env.USER}` : "cli:user"
@@ -1450,7 +1450,7 @@ var Pe = (e) => typeof e != "string", Fe = (e, t, n, r) => {
1450
1450
  let n = H(e), r = c(e, Dt);
1451
1451
  if (!r) return B.error("voltro db rollback-file <migration-id>"), 2;
1452
1452
  if ((process.env.NODE_ENV ?? "").toLowerCase() === "production") return B.error("voltro db rollback-file: refusing on prod — schema rollback runs as an explicit deploy step." + t()), 3;
1453
- let i = await J(await q(), A.SqlClient.pipe(k.flatMap((e) => pe(e, {
1453
+ let i = await J(await q(), M.SqlClient.pipe(j.flatMap((e) => Ee(e, {
1454
1454
  projectRoot: n,
1455
1455
  id: r
1456
1456
  }))));
@@ -1529,14 +1529,14 @@ export default defineMigration({
1529
1529
  into: r,
1530
1530
  map: o.map,
1531
1531
  ...o.leaveUnset ? { leaveUnset: o.leaveUnset } : {}
1532
- }, c = W(), l = await q(), u = await J(l, A.SqlClient.pipe(k.flatMap(N))), d = (e) => u.tables.find((t) => t.name === e)?.columns.map((e) => ({
1532
+ }, c = W(), l = await q(), u = await J(l, M.SqlClient.pipe(j.flatMap(P))), d = (e) => u.tables.find((t) => t.name === e)?.columns.map((e) => ({
1533
1533
  name: e.name,
1534
1534
  nullable: e.nullable,
1535
1535
  hasDefault: e.defaultValue !== void 0 && e.defaultValue !== null
1536
1536
  })), f = d(n), p = d(r);
1537
1537
  if (f === void 0) return console.error(`voltro db adopt: '${n}' does not exist in the database`), 1;
1538
1538
  if (p === void 0) return console.error(`voltro db adopt: '${r}' does not exist in the database — boot once so the plugin's table is created`), 1;
1539
- let m = async (e) => await J(l, A.SqlClient.pipe(k.flatMap((t) => t.unsafe(e)))), h = async (e) => Number(Object.values((await m(`SELECT COUNT(*) AS n FROM "${e}"`))[0] ?? { n: 0 })[0] ?? 0), g = Fe(s, f, p, await h(r));
1539
+ let m = async (e) => await J(l, M.SqlClient.pipe(j.flatMap((t) => t.unsafe(e)))), h = async (e) => Number(Object.values((await m(`SELECT COUNT(*) AS n FROM "${e}"`))[0] ?? { n: 0 })[0] ?? 0), g = Fe(s, f, p, await h(r));
1540
1540
  for (let e of Le(s, g, await h(n))) console.log(e);
1541
1541
  if (g.fatal) return 1;
1542
1542
  if (!e.includes("--apply")) return console.log(""), console.log(" (dry run — nothing written. Re-run with --apply.)"), 0;
@@ -1555,7 +1555,7 @@ export default defineMigration({
1555
1555
  column: o
1556
1556
  });
1557
1557
  }
1558
- let i = [...Ue, ...n], a = await J(await q(), A.SqlClient.pipe(k.flatMap((e) => k.promise(() => tt(e, t, i, G)))));
1558
+ let i = [...Ue, ...n], a = await J(await q(), M.SqlClient.pipe(j.flatMap((e) => j.promise(() => tt(e, t, i, G)))));
1559
1559
  return console.log(nt(a, t)), rt(a);
1560
1560
  },
1561
1561
  "encrypt-column": async (e) => {
@@ -1568,15 +1568,15 @@ export default defineMigration({
1568
1568
  if (d.length === 0) throw new r("voltro db encrypt-column: name at least one <table>.<column>");
1569
1569
  let f = await q(), p = [];
1570
1570
  for (let e of d) {
1571
- let a = G(e.table), o = G(e.column), l = await J(f, A.SqlClient.pipe(k.flatMap((n) => k.promise(async () => {
1572
- let i = await k.runPromise(n.unsafe(wt(t, e, K(t))));
1571
+ let a = G(e.table), o = G(e.column), l = await J(f, M.SqlClient.pipe(j.flatMap((n) => j.promise(async () => {
1572
+ let i = await j.runPromise(n.unsafe(wt(t, e, K(t))));
1573
1573
  if (i.length === 0) throw new r(`voltro db encrypt-column: ${e.table}.${e.column} does not exist on this database`);
1574
1574
  return Tt(Object.values(i[0])[0]);
1575
- })))), d = await J(f, A.SqlClient.pipe(k.flatMap((e) => k.promise(async () => await k.runPromise(e.unsafe(`SELECT ${G("id")} AS id, ${o} AS v FROM ${a}`)))))), m = 0;
1576
- for (let e of d) typeof e.v != "string" || I(e.v) || (m = Math.max(m, yt(e.v)));
1575
+ })))), d = await J(f, M.SqlClient.pipe(j.flatMap((e) => j.promise(async () => await j.runPromise(e.unsafe(`SELECT ${G("id")} AS id, ${o} AS v FROM ${a}`)))))), m = 0;
1576
+ for (let e of d) typeof e.v != "string" || A(e.v) || (m = Math.max(m, yt(e.v)));
1577
1577
  let h = mt(m, l);
1578
1578
  if (!h.fits) return console.error(` ✗ ${ht(e, h)}`), 1;
1579
- if (bt(d.map((e) => e.v).find((e) => typeof e == "string" && I(e)), u) === !1) return console.error(` ✗ ${xt(e, c)}`), 1;
1579
+ if (bt(d.map((e) => e.v).find((e) => typeof e == "string" && A(e)), u) === !1) return console.error(` ✗ ${xt(e, c)}`), 1;
1580
1580
  let g = d.filter((t) => _t(t.v, u, e) !== void 0 || Ct(t.v, u, e) !== void 0).length;
1581
1581
  if (!n && !i) return console.error(` ✗ ${e.table}.${e.column}: ${g} row(s) would be rewritten in place. Re-run with --yes, or --dry-run to see the counts without writing.`), 1;
1582
1582
  let _ = 0, v = 0, y = 0, b = 0, x = [];
@@ -1585,7 +1585,7 @@ export default defineMigration({
1585
1585
  y += 1;
1586
1586
  continue;
1587
1587
  }
1588
- if (typeof t.v == "string" && I(t.v)) {
1588
+ if (typeof t.v == "string" && A(t.v)) {
1589
1589
  let n = Ct(t.v, u, e);
1590
1590
  if (n === void 0) {
1591
1591
  _ += 1;
@@ -1609,8 +1609,8 @@ export default defineMigration({
1609
1609
  }
1610
1610
  if (!n && x.length > 0) for (let t = 0; t < x.length; t += s) {
1611
1611
  let n = x.slice(t, t + s);
1612
- await J(f, A.SqlClient.pipe(k.flatMap((t) => k.promise(async () => {
1613
- for (let r of n) await k.runPromise(t`UPDATE ${t(e.table)} SET ${t(e.column)} = ${r.value} WHERE ${t("id")} = ${r.id}`);
1612
+ await J(f, M.SqlClient.pipe(j.flatMap((t) => j.promise(async () => {
1613
+ for (let r of n) await j.runPromise(t`UPDATE ${t(e.table)} SET ${t(e.column)} = ${r.value} WHERE ${t("id")} = ${r.id}`);
1614
1614
  })))), B.info(`encrypt-column ${e.table}.${e.column}: ${Math.min(t + n.length, x.length)}/${x.length}`);
1615
1615
  }
1616
1616
  p.push({