@happyvertical/smrt-cli 0.55.2 → 0.55.4

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 (27) hide show
  1. package/AGENTS.md +1 -1
  2. package/agents/db-migrate-concurrency.md +55 -0
  3. package/dist/{AuditLogCollection-WDHL-_AF-CICn3ykM.js → AuditLogCollection-WDHL-_AF-haJnEgEw.js} +1 -1
  4. package/dist/{OidcIdentity-BUblgQLs-tEgHhtuW.js → OidcIdentity-BUblgQLs-cXrwoGy2.js} +2 -2
  5. package/dist/{OidcIdentityCollection-ClOyaHeF-DekKuRWf.js → OidcIdentityCollection-ClOyaHeF-D8hWcfjc.js} +1 -1
  6. package/dist/{ProfileAssetCollection-CRMcjLJ--BDBGju83.js → ProfileAssetCollection-CRMcjLJ--DSixQRF0.js} +3 -3
  7. package/dist/{ProfileCollection-C4INKh7Y-DFI7PkHq.js → ProfileCollection-C4INKh7Y-CAcLm37B.js} +17 -17
  8. package/dist/{ProfileLinkCollection-DFfZRsgv-DM1Fvdmp.js → ProfileLinkCollection-DFfZRsgv-CMVtl2w5.js} +2 -2
  9. package/dist/{ProfileMetadataCollection-BIYKy4Y3-Bms52D92.js → ProfileMetadataCollection-BIYKy4Y3-CG6Q8fbO.js} +1 -1
  10. package/dist/{ProfileMetafieldCollection-Buz7gzag-D114BiEu.js → ProfileMetafieldCollection-Buz7gzag-BfXstbny.js} +1 -1
  11. package/dist/{ProfileRelationshipCollection-C4g_QLI4-D4BlqOng.js → ProfileRelationshipCollection-C4g_QLI4-g3WbyvBs.js} +1 -1
  12. package/dist/{ProfileTypeCollection-B7kwi1mU-DmJhE1J9.js → ProfileTypeCollection-B7kwi1mU-BbhxwTX6.js} +2 -2
  13. package/dist/commands/utilities.d.ts.map +1 -1
  14. package/dist/{commands-DKomWuM0.js → commands-BZWmjRRq.js} +46 -27
  15. package/dist/{config-hqNo4lzH.js → config-CdJRSMRi.js} +2 -1
  16. package/dist/config.d.ts.map +1 -1
  17. package/dist/{dist-D8UeHLmJ.js → dist-BVKOxK_t.js} +4 -4
  18. package/dist/{dist-BtQYiFJl.js → dist-COxOlFvi.js} +16 -16
  19. package/dist/dist-D82tjV_R.js +21 -0
  20. package/dist/{dist-Bd7Vrmjk.js → dist-DpgpJAky.js} +3 -3
  21. package/dist/{dist-COLaRvbz.js → dist-aqWgbUb1.js} +16 -4
  22. package/dist/index.js +14 -14
  23. package/dist/{json-validator-BiAdsE1O.js → json-validator-CF2oQNDw.js} +1 -1
  24. package/dist/{oidcProvisioningPrimitives-DNP9EZlU-CV2h9ajo.js → oidcProvisioningPrimitives-DNP9EZlU-CUuuJzgv.js} +3 -3
  25. package/dist/{resolveIdentity-CkyqvctR-BESNBdig.js → resolveIdentity-CkyqvctR-C-wjeI_9.js} +14 -14
  26. package/package.json +16 -16
  27. package/dist/dist-lQnuqeJb.js +0 -21
package/AGENTS.md CHANGED
@@ -11,7 +11,7 @@ smrt doctor --db # Add the live-schema parity section (see below)
11
11
  smrt db:status # Pending schema changes + failed migration classification (+ tenant natural-key findings: a missing tenant-led unique exits 1, a surviving legacy global unique warns until `db:migrate --drop-legacy-natural-key`: src/commands/tenant-natural-keys.ts)
12
12
  smrt db:status --parity # Same, plus live-schema parity (see below)
13
13
  smrt db:orphans # agents/db-orphans.md
14
- smrt db:migrate # agents/type-drift.md
14
+ smrt db:migrate # agents/type-drift.md, agents/db-migrate-concurrency.md
15
15
  smrt db:migrate --postgres-safe # PostgreSQL concurrent-index mode (see below)
16
16
  smrt db:migrate --force-migration <exact-id> [--force-migration <exact-id>...] # Force exact generated migrations in one atomic batch
17
17
  smrt db:migrate --apply-unblocked / --null-orphans # agents/db-migrate-partial-apply.md
@@ -0,0 +1,55 @@
1
+ # `db:migrate` concurrency (#3634)
2
+
3
+ Two processes migrating one PostgreSQL database at once — two workloads that
4
+ gate startup on `db:migrate`, a rolling restart, a break-glass Job beside running
5
+ pods — used to both compare the live schema, plan the same batch, and the
6
+ second failed part way with `42701`/`42P07` "already exists" or a `40P01`
7
+ deadlock. The tracker's per-migration `running` rows cannot prevent that: they
8
+ are written after the diff, when both runs have already planned.
9
+
10
+ ## Contract
11
+
12
+ - A non-dry-run `db:migrate` on PostgreSQL calls core `acquireMigrationLock()`
13
+ right after connecting, before the system-timestamp step, tracker bootstrap,
14
+ and schema comparison, and releases it in the handler's `finally`.
15
+ - The lock is `pg_try_advisory_lock(hashtext('smrt'), hashtext('db:migrate'))`
16
+ (`MIGRATION_ADVISORY_LOCK_KEYS`) on its own `acquireSession()` connection,
17
+ polled once a second. Polling, not a blocking `pg_advisory_lock`, so the
18
+ connection's `lock_timeout` never cuts the wait short and the wait can be
19
+ logged. Never change the keys: runs of an old and a new release must still
20
+ exclude each other.
21
+ - A waiting run logs `Another db:migrate run holds the migration lock…`, then,
22
+ once it holds the lock, compares a current schema and applies nothing.
23
+ - The wait is bounded by `migrations.postgres.migrationLockTimeout` (default
24
+ `15min`; `ms`/`s`/`min`/`h` forms; `0` waits indefinitely). On expiry the run
25
+ fails with `MigrationLockTimeoutError` before reading any schema.
26
+ - The lock dies with its connection: a crashed or killed migrator never strands
27
+ it. `SessionHandle.release()` runs `pg_advisory_unlock_all()` and destroys the
28
+ connection.
29
+ - The flip side: if the lock's own connection dies mid-run (failover, an
30
+ idle-connection reaper, a terminated backend) PostgreSQL frees the lock while
31
+ the run's pool connections carry on. The handler calls `lock.assertHeld()`
32
+ (a `pg_locks` probe on the pinned session) before applying and again before
33
+ the post-apply contract check; a lost lock fails the run with
34
+ `MigrationLockLostError` and exit 1, and the next run converges. The lock
35
+ session sets `idle_session_timeout = 0` (PostgreSQL 14+), because it idles for
36
+ the whole run and a role- or database-level setting would reap it first.
37
+ - Session advisory locks need a real session: a transaction-pooling proxy
38
+ (PgBouncer `pool_mode=transaction`) between `db:migrate` and PostgreSQL
39
+ defeats them. Migrate through a direct or session-pooled connection.
40
+ - `--dry-run` only reads and never waits. SQLite/DuckDB need no lock (no-op).
41
+ A PostgreSQL adapter without `acquireSession()` is refused
42
+ (`MigrationLockUnsupportedError`) rather than run unserialized.
43
+ - The maintenance-window `db:migrate-*` subcommands do not take this lock; run
44
+ them with application migrators stopped.
45
+
46
+ ## Tests
47
+
48
+ - `packages/core/src/migrations/__tests__/migration-lock.test.ts` — contract.
49
+ - `…/migration-lock-postgres.optional.test.ts` — real waits, timeout, release
50
+ on a terminated holder backend (and the holder's `assertHeld()` failing),
51
+ survival under a 1s server `idle_session_timeout`.
52
+ - `packages/cli/src/commands/__tests__/db-migrate-concurrent-postgres.test.ts`
53
+ — two concurrent CLI runs apply one batch; a held lock blocks a run before it
54
+ touches schema. Each run gets its own pool (`getDatabase` caches one pool per
55
+ identity in-process, which two real processes would not share).
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as tenantId, r as TenantScoped } from "./dist-COLaRvbz.js";
2
+ import { i as tenantId, r as TenantScoped } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
4
  import { SmrtCollection, SmrtObject, field, foreignKey, smrt } from "@happyvertical/smrt-core";
5
5
  //#region ../profiles/dist/chunks/AuditLogCollection-WDHL-_AF.js
@@ -42,7 +42,7 @@ var OidcIdentity = class extends SmrtObject {
42
42
  * Find identity by issuer and subject
43
43
  */
44
44
  static async findBySubject(issuer, subject, options = {}) {
45
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-ClOyaHeF-DekKuRWf.js").then((n) => n.r).then((n) => n.r);
45
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-ClOyaHeF-D8hWcfjc.js").then((n) => n.r).then((n) => n.r);
46
46
  return await (await OidcIdentityCollection.create(options)).findBySubject(issuer, subject);
47
47
  }
48
48
  /** Build the collision-free natural key for one OIDC issuer subject. */
@@ -65,7 +65,7 @@ var OidcIdentity = class extends SmrtObject {
65
65
  static async findOrCreate(profile, oidcData, options = {}) {
66
66
  const profileId = profile.id;
67
67
  if (typeof profileId !== "string" || !profileId) throw new Error("OidcIdentity.findOrCreate() requires a saved Profile.");
68
- const { reuseExistingOidcIdentityForProfile } = await import("./resolveIdentity-CkyqvctR-BESNBdig.js").then((n) => n.i).then((n) => n.i);
68
+ const { reuseExistingOidcIdentityForProfile } = await import("./resolveIdentity-CkyqvctR-C-wjeI_9.js").then((n) => n.i).then((n) => n.i);
69
69
  const profileOptions = profile.options ?? {};
70
70
  return (await reuseExistingOidcIdentityForProfile(profileId, {
71
71
  email: oidcData.email,
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
2
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
3
- import { t as OidcIdentity } from "./OidcIdentity-BUblgQLs-tEgHhtuW.js";
3
+ import { t as OidcIdentity } from "./OidcIdentity-BUblgQLs-cXrwoGy2.js";
4
4
  import { SmrtCollection } from "@happyvertical/smrt-core";
5
5
  //#region ../profiles/dist/chunks/OidcIdentityCollection-ClOyaHeF.js
6
6
  var OidcIdentityCollection_ClOyaHeF_exports = /* @__PURE__ */ __exportAll({
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as tenantId, r as TenantScoped } from "./dist-COLaRvbz.js";
2
+ import { i as tenantId, r as TenantScoped } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
- import { a as getOwnedAssetsFromCollection, o as removeOwnedAssetFromCollection, t as addOwnedAssetFromCollection } from "./dist-Bd7Vrmjk.js";
4
+ import { a as getOwnedAssetsFromCollection, o as removeOwnedAssetFromCollection, t as addOwnedAssetFromCollection } from "./dist-DpgpJAky.js";
5
5
  import { SmrtJunction, SmrtObject, crossPackageRef, field, foreignKey, smrt } from "@happyvertical/smrt-core";
6
6
  //#region ../profiles/dist/chunks/ProfileAssetCollection-CRMcjLJ-.js
7
7
  var ProfileAssetCollection_CRMcjLJ__exports = /* @__PURE__ */ __exportAll({
@@ -84,7 +84,7 @@ var ProfileAssetCollection = class extends SmrtJunction {
84
84
  profileCollectionPromise = null;
85
85
  async getProfileCollection() {
86
86
  if (!this.profileCollectionPromise) {
87
- const { ProfileCollection } = await import("./ProfileCollection-C4INKh7Y-DFI7PkHq.js").then((n) => n.o).then((n) => n.r);
87
+ const { ProfileCollection } = await import("./ProfileCollection-C4INKh7Y-CAcLm37B.js").then((n) => n.o).then((n) => n.r);
88
88
  this.profileCollectionPromise = ProfileCollection.create({ db: this.db });
89
89
  }
90
90
  return this.profileCollectionPromise;
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { a as queryGlobal, c as getTenantId, i as tenantId, n as resolvePrompt, o as queryWithGlobals, r as TenantScoped, t as definePrompt, u as withSystemContext } from "./dist-COLaRvbz.js";
2
+ import { a as queryGlobal, c as getTenantId, i as tenantId, n as resolvePrompt, o as queryWithGlobals, r as TenantScoped, t as definePrompt, u as withSystemContext } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
- import { a as getOwnedAssetsFromCollection, i as assertValidOwnedAssetSortOrder, n as assertAssetLinkable, o as removeOwnedAssetFromCollection, r as assertValidOwnedAssetRelationship, s as resolveOwnedAssetsById, t as addOwnedAssetFromCollection } from "./dist-Bd7Vrmjk.js";
4
+ import { a as getOwnedAssetsFromCollection, i as assertValidOwnedAssetSortOrder, n as assertAssetLinkable, o as removeOwnedAssetFromCollection, r as assertValidOwnedAssetRelationship, s as resolveOwnedAssetsById, t as addOwnedAssetFromCollection } from "./dist-DpgpJAky.js";
5
5
  import { RuntimeError, SmrtCollection, SmrtObject, ValidationError, field, foreignKey, isAbortedTransactionError, oneToMany, smrt } from "@happyvertical/smrt-core";
6
6
  import { BackfillTableUnavailableError, BackfillTracker } from "@happyvertical/smrt-core/migrations";
7
7
  //#region ../profiles/dist/chunks/ProfileCollection-C4INKh7Y.js
@@ -435,7 +435,7 @@ var Profile = class extends SmrtObject {
435
435
  async getTypeSlug() {
436
436
  const tenantId2 = this.tenantId || getTenantId();
437
437
  if (this.typeId && tenantId2) {
438
- const { ProfileTypeCollection } = await import("./ProfileTypeCollection-B7kwi1mU-DmJhE1J9.js").then((n) => n.n).then((n) => n.n);
438
+ const { ProfileTypeCollection } = await import("./ProfileTypeCollection-B7kwi1mU-BbhxwTX6.js").then((n) => n.n).then((n) => n.n);
439
439
  return (await (await ProfileTypeCollection.create(this.options)).getAvailableById(this.typeId, tenantId2))?.slug ?? "";
440
440
  }
441
441
  return (await this.loadRelated("typeId"))?.slug || "";
@@ -458,8 +458,8 @@ var Profile = class extends SmrtObject {
458
458
  * @param value - The value to set
459
459
  */
460
460
  async addMetadata(metafieldSlug, value) {
461
- const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-Buz7gzag-D114BiEu.js").then((n) => n.r).then((n) => n.n);
462
- const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3-Bms52D92.js").then((n) => n.r).then((n) => n.n);
461
+ const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-Buz7gzag-BfXstbny.js").then((n) => n.r).then((n) => n.n);
462
+ const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3-CG6Q8fbO.js").then((n) => n.r).then((n) => n.n);
463
463
  const metafield = await this.resolveMetafield(await ProfileMetafieldCollection.create(this.options), metafieldSlug);
464
464
  if (!metafield) throw new Error(`Metafield '${metafieldSlug}' not found`);
465
465
  await metafield.validateValue(value);
@@ -492,7 +492,7 @@ var Profile = class extends SmrtObject {
492
492
  * @returns Object with metafield slugs as keys
493
493
  */
494
494
  async getMetadata() {
495
- const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3-Bms52D92.js").then((n) => n.r).then((n) => n.n);
495
+ const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3-CG6Q8fbO.js").then((n) => n.r).then((n) => n.n);
496
496
  return await (await ProfileMetadataCollection.create(this.options)).getMetadataObject(this.id);
497
497
  }
498
498
  /**
@@ -509,8 +509,8 @@ var Profile = class extends SmrtObject {
509
509
  * @param metafieldSlug - The slug of the metafield to remove
510
510
  */
511
511
  async removeMetadata(metafieldSlug) {
512
- const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-Buz7gzag-D114BiEu.js").then((n) => n.r).then((n) => n.n);
513
- const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3-Bms52D92.js").then((n) => n.r).then((n) => n.n);
512
+ const { ProfileMetafieldCollection } = await import("./ProfileMetafieldCollection-Buz7gzag-BfXstbny.js").then((n) => n.r).then((n) => n.n);
513
+ const { ProfileMetadataCollection } = await import("./ProfileMetadataCollection-BIYKy4Y3-CG6Q8fbO.js").then((n) => n.r).then((n) => n.n);
514
514
  const metafield = await this.resolveMetafield(await ProfileMetafieldCollection.create(this.options), metafieldSlug);
515
515
  if (!metafield) throw new Error(`Metafield '${metafieldSlug}' not found`);
516
516
  const existing = await (await ProfileMetadataCollection.create(this.options)).list({
@@ -535,7 +535,7 @@ var Profile = class extends SmrtObject {
535
535
  return candidates.find((candidate) => ownerTenantId && candidate.tenantId === ownerTenantId) ?? candidates.find((candidate) => !candidate.tenantId) ?? null;
536
536
  }
537
537
  async getProfileLinkCollection() {
538
- const { ProfileLinkCollection } = await import("./ProfileLinkCollection-DFfZRsgv-DM1Fvdmp.js").then((n) => n.i).then((n) => n.r);
538
+ const { ProfileLinkCollection } = await import("./ProfileLinkCollection-DFfZRsgv-CMVtl2w5.js").then((n) => n.i).then((n) => n.r);
539
539
  return ProfileLinkCollection.create({ db: this.db });
540
540
  }
541
541
  /** This profile's web links in display order. */
@@ -552,7 +552,7 @@ var Profile = class extends SmrtObject {
552
552
  return (await this.getProfileLinkCollection()).replaceForProfile(this.id, links);
553
553
  }
554
554
  async getProfileAssetCollection() {
555
- const { ProfileAssetCollection } = await import("./ProfileAssetCollection-CRMcjLJ--BDBGju83.js").then((n) => n.r).then((n) => n.n);
555
+ const { ProfileAssetCollection } = await import("./ProfileAssetCollection-CRMcjLJ--DSixQRF0.js").then((n) => n.r).then((n) => n.n);
556
556
  return ProfileAssetCollection.create({ db: this.db });
557
557
  }
558
558
  async getAssets(relationship) {
@@ -584,7 +584,7 @@ var Profile = class extends SmrtObject {
584
584
  */
585
585
  async addRelationship(toProfile, relationshipSlug, contextProfile) {
586
586
  const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-_n22WqTb-DiZUWvev.js").then((n) => n.n).then((n) => n.n);
587
- const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4-D4BlqOng.js").then((n) => n.r).then((n) => n.n);
587
+ const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4-g3WbyvBs.js").then((n) => n.r).then((n) => n.n);
588
588
  const { ProfileRelationshipType } = await import("./ProfileRelationshipType-U7IwF6Wf-DNavf24e.js").then((n) => n.n).then((n) => n.n);
589
589
  const relationshipType = await (await ProfileRelationshipTypeCollection.create(this.options)).getBySlug(relationshipSlug);
590
590
  if (!relationshipType) throw new Error(`Relationship type '${relationshipSlug}' not found`);
@@ -609,7 +609,7 @@ var Profile = class extends SmrtObject {
609
609
  * @returns Array of ProfileRelationship instances
610
610
  */
611
611
  async getRelationships(options) {
612
- const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4-D4BlqOng.js").then((n) => n.r).then((n) => n.n);
612
+ const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4-g3WbyvBs.js").then((n) => n.r).then((n) => n.n);
613
613
  const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-_n22WqTb-DiZUWvev.js").then((n) => n.n).then((n) => n.n);
614
614
  const relationshipCollection = await ProfileRelationshipCollection.create(this.options);
615
615
  const direction = options?.direction || "all";
@@ -654,7 +654,7 @@ var Profile = class extends SmrtObject {
654
654
  */
655
655
  async removeRelationship(toProfile, relationshipSlug) {
656
656
  const { ProfileRelationshipTypeCollection } = await import("./ProfileRelationshipTypeCollection-_n22WqTb-DiZUWvev.js").then((n) => n.n).then((n) => n.n);
657
- const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4-D4BlqOng.js").then((n) => n.r).then((n) => n.n);
657
+ const { ProfileRelationshipCollection } = await import("./ProfileRelationshipCollection-C4g_QLI4-g3WbyvBs.js").then((n) => n.r).then((n) => n.n);
658
658
  const relationshipType = await (await ProfileRelationshipTypeCollection.create(this.options)).getBySlug(relationshipSlug);
659
659
  if (!relationshipType) throw new Error(`Relationship type '${relationshipSlug}' not found`);
660
660
  const relationshipCollection = await ProfileRelationshipCollection.create(this.options);
@@ -778,7 +778,7 @@ var Profile = class extends SmrtObject {
778
778
  * @returns Array of OIDC identity records
779
779
  */
780
780
  async getOidcIdentities() {
781
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-ClOyaHeF-DekKuRWf.js").then((n) => n.r).then((n) => n.r);
781
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-ClOyaHeF-D8hWcfjc.js").then((n) => n.r).then((n) => n.r);
782
782
  return await (await OidcIdentityCollection.create(this.options)).findByProfile(this.id);
783
783
  }
784
784
  /**
@@ -791,7 +791,7 @@ var Profile = class extends SmrtObject {
791
791
  * type, but refuses to create or rebind authority.
792
792
  */
793
793
  async linkOidcIdentity(oidcData) {
794
- const { OidcIdentityCollection } = await import("./OidcIdentityCollection-ClOyaHeF-DekKuRWf.js").then((n) => n.r).then((n) => n.r);
794
+ const { OidcIdentityCollection } = await import("./OidcIdentityCollection-ClOyaHeF-D8hWcfjc.js").then((n) => n.r).then((n) => n.r);
795
795
  return await (await OidcIdentityCollection.create(this.options)).linkToProfile(this, oidcData);
796
796
  }
797
797
  /**
@@ -820,7 +820,7 @@ var Profile = class extends SmrtObject {
820
820
  * @returns Array of audit log entries
821
821
  */
822
822
  async getAuditLogs(limit = 50) {
823
- const { AuditLogCollection } = await import("./AuditLogCollection-WDHL-_AF-CICn3ykM.js").then((n) => n.r).then((n) => n.n);
823
+ const { AuditLogCollection } = await import("./AuditLogCollection-WDHL-_AF-haJnEgEw.js").then((n) => n.r).then((n) => n.n);
824
824
  return await (await AuditLogCollection.create(this.options)).getRecentActivity(this.id, limit);
825
825
  }
826
826
  /**
@@ -830,7 +830,7 @@ var Profile = class extends SmrtObject {
830
830
  * @returns The created audit log entry
831
831
  */
832
832
  async recordAction(options) {
833
- const { AuditLogCollection } = await import("./AuditLogCollection-WDHL-_AF-CICn3ykM.js").then((n) => n.r).then((n) => n.n);
833
+ const { AuditLogCollection } = await import("./AuditLogCollection-WDHL-_AF-haJnEgEw.js").then((n) => n.r).then((n) => n.n);
834
834
  return await (await AuditLogCollection.create(this.options)).record({
835
835
  profile: this,
836
836
  ...options
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as tenantId, r as TenantScoped } from "./dist-COLaRvbz.js";
2
+ import { i as tenantId, r as TenantScoped } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
4
  import { SmrtCollection, SmrtObject, field, foreignKey, isEmbeddedDatabase, smrt, withEmbeddedWriteTransaction } from "@happyvertical/smrt-core";
5
5
  //#region ../profiles/dist/chunks/ProfileLinkCollection-DFfZRsgv.js
@@ -203,7 +203,7 @@ var ProfileLinkCollection = class ProfileLinkCollection extends SmrtCollection {
203
203
  /** The profile's tenant; throws when the profile is not visible here. */
204
204
  async requireProfileTenant(profileId) {
205
205
  if (!profileId) throw new Error("A profile link needs a profile");
206
- const { ProfileCollection } = await import("./ProfileCollection-C4INKh7Y-DFI7PkHq.js").then((n) => n.o).then((n) => n.r);
206
+ const { ProfileCollection } = await import("./ProfileCollection-C4INKh7Y-CAcLm37B.js").then((n) => n.o).then((n) => n.r);
207
207
  const profile = await (await ProfileCollection.create({ db: this.db })).get({ id: profileId });
208
208
  if (!profile) throw new Error(`Profile '${profileId}' not found`);
209
209
  return profile.tenantId ?? null;
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as tenantId, r as TenantScoped } from "./dist-COLaRvbz.js";
2
+ import { i as tenantId, r as TenantScoped } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
4
  import { SmrtCollection, SmrtObject, field, foreignKey, smrt } from "@happyvertical/smrt-core";
5
5
  //#region ../profiles/dist/chunks/ProfileMetadataCollection-BIYKy4Y3.js
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as tenantId, r as TenantScoped } from "./dist-COLaRvbz.js";
2
+ import { i as tenantId, r as TenantScoped } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
4
  import { SmrtCollection, SmrtObject, field, smrt } from "@happyvertical/smrt-core";
5
5
  //#region ../profiles/dist/chunks/ProfileMetafieldCollection-Buz7gzag.js
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { i as tenantId, r as TenantScoped } from "./dist-COLaRvbz.js";
2
+ import { i as tenantId, r as TenantScoped } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
4
  import { SmrtCollection, SmrtObject, foreignKey, oneToMany, smrt } from "@happyvertical/smrt-core";
5
5
  //#region ../profiles/dist/chunks/ProfileRelationshipCollection-C4g_QLI4.js
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { l as isSystemContext, s as withTenantGlobalRead } from "./dist-COLaRvbz.js";
2
+ import { l as isSystemContext, s as withTenantGlobalRead } from "./dist-aqWgbUb1.js";
3
3
  import { n as __exportAll$1 } from "./NostrIdentity-AC8fAdxe-DKxKyu_a.js";
4
- import { s as ProfileType } from "./ProfileCollection-C4INKh7Y-DFI7PkHq.js";
4
+ import { s as ProfileType } from "./ProfileCollection-C4INKh7Y-CAcLm37B.js";
5
5
  import { SmrtCollection } from "@happyvertical/smrt-core";
6
6
  //#region ../profiles/dist/chunks/ProfileTypeCollection-B7kwi1mU.js
7
7
  var ProfileTypeCollection_B7kwi1mU_exports = /* @__PURE__ */ __exportAll({
@@ -1 +1 @@
1
- {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/commands/utilities.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"utilities.d.ts","sourceRoot":"","sources":["../../src/commands/utilities.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { t as resolveManifestEntryPackageName } from "./index.js";
2
2
  import { a as redactDatabaseUrlsInText, i as quoteIdentifier, r as formatDatabaseDisplayUrl, t as closeDatabaseConnection } from "./db-command-utils-Cn8tjy7N.js";
3
- import { t as DEFAULT_CLI_CONFIG } from "./config-hqNo4lzH.js";
3
+ import { t as DEFAULT_CLI_CONFIG } from "./config-CdJRSMRi.js";
4
4
  import { addMcpAppsRuntime, assertMcpAppsPluginName, configureMcpAppsConsumerRegistry, mcpAppsCommands, scaffoldMcpAppsPackage, validateMcpAppsPackage } from "./mcp-apps-packaging-CixRnxz_.js";
5
5
  import { createRequire } from "node:module";
6
6
  import * as fs from "node:fs";
@@ -85,7 +85,7 @@ var configExportCommand = {
85
85
  process.exit(1);
86
86
  }
87
87
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
88
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
88
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
89
89
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
90
90
  if (!config.database?.url || config.database.url === ":memory:") {
91
91
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -1216,7 +1216,7 @@ var dbDiffCommand = {
1216
1216
  return;
1217
1217
  }
1218
1218
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
1219
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
1219
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
1220
1220
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
1221
1221
  if (!config.database?.url || config.database.url === ":memory:") {
1222
1222
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -1558,7 +1558,7 @@ var dbHistoryCommand = {
1558
1558
  let db;
1559
1559
  try {
1560
1560
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
1561
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
1561
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
1562
1562
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
1563
1563
  if (!config.database?.url || config.database.url === ":memory:") {
1564
1564
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -1826,7 +1826,7 @@ var dbOrphansCommand = {
1826
1826
  let db;
1827
1827
  try {
1828
1828
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
1829
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
1829
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
1830
1830
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
1831
1831
  if (!config.database?.url || config.database.url === ":memory:") {
1832
1832
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -2128,7 +2128,7 @@ var dbPruneCommand = {
2128
2128
  let db;
2129
2129
  try {
2130
2130
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
2131
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
2131
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
2132
2132
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
2133
2133
  if (!config.database?.url) {
2134
2134
  const message = "Database not configured. Set database.url in smrt.config.ts.";
@@ -2288,7 +2288,7 @@ var dbRollbackCommand = {
2288
2288
  const markOnly = options["mark-only"] ?? options.markOnly;
2289
2289
  try {
2290
2290
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
2291
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
2291
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
2292
2292
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
2293
2293
  if (!config.database?.url || config.database.url === ":memory:") {
2294
2294
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -2563,7 +2563,7 @@ async function runLiveSchemaParity(options = {}) {
2563
2563
  let db;
2564
2564
  try {
2565
2565
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
2566
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
2566
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
2567
2567
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
2568
2568
  if (!config.database?.url || config.database.url === ":memory:") return {
2569
2569
  report: null,
@@ -3223,7 +3223,7 @@ var dbStatusCommand = {
3223
3223
  let db;
3224
3224
  try {
3225
3225
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
3226
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
3226
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
3227
3227
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
3228
3228
  if (!config.database?.url || config.database.url === ":memory:") {
3229
3229
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -3523,7 +3523,7 @@ async function getDispatchBus() {
3523
3523
  const { createDispatchBus } = await import("@happyvertical/smrt-core");
3524
3524
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
3525
3525
  const { getDatabase } = await import("@happyvertical/sql");
3526
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
3526
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
3527
3527
  const dbConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG).database;
3528
3528
  if (!dbConfig?.url) throw new Error("Database not configured. Set database.url in smrt.config.ts or use --db option.");
3529
3529
  let db;
@@ -4458,7 +4458,7 @@ var exportCommand = {
4458
4458
  let db;
4459
4459
  try {
4460
4460
  const { getConfig, getPackageConfig } = await import("@happyvertical/smrt-config");
4461
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
4461
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
4462
4462
  const smrtConfig = getConfig();
4463
4463
  const cliConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
4464
4464
  if (!smrtConfig) {
@@ -6966,7 +6966,7 @@ var dbDropFrameworkBaseTablesCommand = {
6966
6966
  const dryRun = Boolean(options["dry-run"]);
6967
6967
  try {
6968
6968
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
6969
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
6969
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
6970
6970
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
6971
6971
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:drop-framework-base-tables. Configure database.url in smrt.config.ts (or DATABASE_URL).");
6972
6972
  const dbType = config.database.type || "sqlite";
@@ -7046,12 +7046,12 @@ var dbMaterializeTenantHierarchyCommand = {
7046
7046
  let db;
7047
7047
  try {
7048
7048
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7049
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7049
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
7050
7050
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7051
7051
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:materialize-tenant-hierarchy. Configure database.url in smrt.config.ts (or DATABASE_URL).");
7052
7052
  const dbType = config.database.type || "sqlite";
7053
7053
  const { getDatabase } = await import("@happyvertical/sql");
7054
- const { materializeTenantHierarchy, TenantHierarchyMaterializationError } = await import("./dist-BtQYiFJl.js");
7054
+ const { materializeTenantHierarchy, TenantHierarchyMaterializationError } = await import("./dist-COxOlFvi.js");
7055
7055
  db = await getDatabase({
7056
7056
  type: dbType,
7057
7057
  url: config.database.url
@@ -7104,7 +7104,7 @@ var dbMigrateAgentScheduleSlugsCommand = {
7104
7104
  let db;
7105
7105
  try {
7106
7106
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7107
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7107
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
7108
7108
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7109
7109
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:migrate-agent-schedule-slugs. Configure database.url in smrt.config.ts (or DATABASE_URL).");
7110
7110
  const dbType = config.database.type || "sqlite";
@@ -7174,7 +7174,7 @@ var dbMigrateInt8Command = {
7174
7174
  const dryRun = Boolean(options["dry-run"]);
7175
7175
  try {
7176
7176
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7177
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7177
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
7178
7178
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7179
7179
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:migrate-int8. Configure database.url in smrt.config.ts (or DATABASE_URL).");
7180
7180
  await autoDiscoverAndLoad();
@@ -7253,14 +7253,14 @@ var dbMigrateLedgerAccountsCommand = {
7253
7253
  let db;
7254
7254
  try {
7255
7255
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7256
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7256
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
7257
7257
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7258
7258
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:migrate-ledger-accounts. Configure database.url in smrt.config.ts (or DATABASE_URL).");
7259
7259
  const dbType = config.database.type || "sqlite";
7260
7260
  if (dbType !== "postgres") throw new Error("db:migrate-ledger-accounts currently supports PostgreSQL only; no changes were made. See the smrt-ledgers README for SQLite.");
7261
7261
  await autoDiscoverAndLoad();
7262
7262
  const { getDatabase } = await import("@happyvertical/sql");
7263
- const { migrateLedgerAccountsTable, planLedgerAccountsTableMove } = await import("./dist-D8UeHLmJ.js");
7263
+ const { migrateLedgerAccountsTable, planLedgerAccountsTableMove } = await import("./dist-BVKOxK_t.js");
7264
7264
  db = await getDatabase({
7265
7265
  type: dbType,
7266
7266
  url: config.database.url
@@ -7306,7 +7306,7 @@ var dbMigrateNullEqualIndexesCommand = {
7306
7306
  let db;
7307
7307
  try {
7308
7308
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7309
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7309
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
7310
7310
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7311
7311
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required: set database.url in smrt.config.ts (or DATABASE_URL).");
7312
7312
  await autoDiscoverAndLoad();
@@ -7619,7 +7619,7 @@ var dbMigrateUuidCommand = {
7619
7619
  let db;
7620
7620
  try {
7621
7621
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7622
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7622
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
7623
7623
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7624
7624
  if (!config.database?.url || config.database.url === ":memory:") {
7625
7625
  console.error("\n❌ Database configuration required for db:migrate-uuid");
@@ -8339,7 +8339,7 @@ async function columnIsUuid(db, table, column) {
8339
8339
  */
8340
8340
  async function connect() {
8341
8341
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
8342
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
8342
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
8343
8343
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
8344
8344
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("No persistent database is configured. Set `database.url` in smrt.config.ts (or DATABASE_URL).");
8345
8345
  const dbType = config.database.type || "sqlite";
@@ -9869,7 +9869,7 @@ export default testManifest;
9869
9869
  let db;
9870
9870
  try {
9871
9871
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
9872
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
9872
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
9873
9873
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
9874
9874
  if (!config.database?.url || config.database.url === ":memory:") {
9875
9875
  console.error("❌ Database configuration required for db:setup");
@@ -10113,7 +10113,7 @@ export default testManifest;
10113
10113
  handler: async (_args, options) => {
10114
10114
  const startTime = Date.now();
10115
10115
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
10116
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
10116
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
10117
10117
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
10118
10118
  if (!options.data && config.database?.type === "postgres") {
10119
10119
  const permissions = await runPostgresPermissions({}, true);
@@ -10123,7 +10123,7 @@ export default testManifest;
10123
10123
  }
10124
10124
  }
10125
10125
  try {
10126
- const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-BiAdsE1O.js");
10126
+ const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-CF2oQNDw.js");
10127
10127
  const dataPath = await resolveDataPath(options.data);
10128
10128
  if (!dataPath) {
10129
10129
  console.error("\n❌ Could not find data directory");
@@ -10310,12 +10310,13 @@ export default testManifest;
10310
10310
  handler: async (_args, options) => {
10311
10311
  console.log("\n🔄 Migrating database schema...\n");
10312
10312
  let db;
10313
+ let migrationLock;
10313
10314
  try {
10314
10315
  const forceSelection = resolveForceMigrationSelection(options.force, options["force-migration"]);
10315
10316
  const postgresTimestampMigration = resolvePostgresTimestampMigration(options["postgres-timestamp-legacy-timezone"]);
10316
10317
  const isDryRun = options["dry-run"] ?? false;
10317
10318
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
10318
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
10319
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
10319
10320
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
10320
10321
  if (!config.database?.url || config.database.url === ":memory:") {
10321
10322
  console.error("❌ Database configuration required for db:migrate");
@@ -10391,6 +10392,18 @@ export default testManifest;
10391
10392
  return;
10392
10393
  }
10393
10394
  console.log(`✓ Connected to ${formatDatabaseDisplayUrl(dbType, dbUrl)}\n`);
10395
+ if (!isDryRun) {
10396
+ const { acquireMigrationLock, DEFAULT_MIGRATION_LOCK_WAIT_TIMEOUT_MS, parsePostgresTimeoutMs } = await import("@happyvertical/smrt-core/migrations");
10397
+ const lock = await acquireMigrationLock(db, {
10398
+ engineHint: dbType,
10399
+ timeoutMs: parsePostgresTimeoutMs(config.migrations?.postgres?.migrationLockTimeout, DEFAULT_MIGRATION_LOCK_WAIT_TIMEOUT_MS),
10400
+ onWait: () => {
10401
+ console.log("⏳ Another db:migrate run holds the migration lock on this database; waiting for it to finish...\n");
10402
+ }
10403
+ });
10404
+ migrationLock = lock;
10405
+ if (lock.held && lock.waitedMs > 0) console.log(`✓ Migration lock acquired after ${Math.round(lock.waitedMs / 1e3)}s; re-reading the schema\n`);
10406
+ }
10394
10407
  const systemTimestampPreview = postgresTimestampMigration && isDryRun ? await planPostgresSystemTimestampMigrations(db, postgresTimestampMigration, dbType) : [];
10395
10408
  if (postgresTimestampMigration && !isDryRun) await migratePostgresSystemTimestamps(db, postgresTimestampMigration, dbType);
10396
10409
  const { buildConcurrentIndexPlan, MigrationTracker, parsePostgresTimeoutMs, shortChecksum } = await import("@happyvertical/smrt-core/migrations");
@@ -10654,6 +10667,7 @@ export default testManifest;
10654
10667
  let migrationResults = [];
10655
10668
  const schemaChangeCount = diff.added_tables.length + migrations.length + deferredForeignKeyMigrations.length;
10656
10669
  if (applySchemaMigrations && schemaChangeCount > 0) {
10670
+ await migrationLock?.assertHeld();
10657
10671
  const migrationDefs = [];
10658
10672
  const migrationLogs = /* @__PURE__ */ new Map();
10659
10673
  const pushMigrationDef = (migration) => {
@@ -10887,6 +10901,7 @@ export default testManifest;
10887
10901
  dryRun: isDryRun
10888
10902
  })) process.exitCode = 1;
10889
10903
  if (!isDryRun) {
10904
+ await migrationLock?.assertHeld();
10890
10905
  await settleDeferredCompatibilityAfterMigrate(db, dbType, { verbose: Boolean(options.verbose) });
10891
10906
  assertSchemaContract(await evaluateSchemaContract({
10892
10907
  discovered,
@@ -10916,7 +10931,11 @@ export default testManifest;
10916
10931
  process.exitCode = 1;
10917
10932
  return;
10918
10933
  } finally {
10919
- await closeDatabaseConnection(db);
10934
+ try {
10935
+ await migrationLock?.release();
10936
+ } finally {
10937
+ await closeDatabaseConnection(db);
10938
+ }
10920
10939
  }
10921
10940
  }
10922
10941
  },
@@ -11119,7 +11138,7 @@ export default testManifest;
11119
11138
  check("src/lib/server/smrt.ts exists", existsSync(resolve(cwd, "src/lib/server/smrt.ts")), "Missing server config - run: smrt init");
11120
11139
  try {
11121
11140
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
11122
- const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
11141
+ const { DEFAULT_CLI_CONFIG } = await import("./config-CdJRSMRi.js").then((n) => n.n);
11123
11142
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
11124
11143
  if (config.database?.url && config.database.url !== ":memory:") check(`Database configured (${config.database.type || "sqlite"})`, true);
11125
11144
  else check("Database configured", false, void 0, "Using in-memory database - set DATABASE_URL for persistence");
@@ -20,7 +20,8 @@ var DEFAULT_CLI_CONFIG = {
20
20
  postgres: {
21
21
  useConcurrently: true,
22
22
  lockTimeout: "30s",
23
- statementTimeout: "60s"
23
+ statementTimeout: "60s",
24
+ migrationLockTimeout: "15min"
24
25
  }
25
26
  },
26
27
  schemaContract: {},
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EACV,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,GACrB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,mBAAmB,CAAC,EAAE,yBAAyB,CAAC;IAChD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE;QACT;;;WAGG;QACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;QAE7B;;;WAGG;QACH,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IAEF;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;OAEG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAE7C;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CACvC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CACvC,GACC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAyBtC,CAAC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,EACrB,MAAM,4BAA4B,CAAC;AAGpC,YAAY,EACV,gBAAgB,EAChB,wBAAwB,EACxB,yBAAyB,EACzB,oBAAoB,GACrB,CAAC;AAEF,MAAM,WAAW,SAAS;IACxB,mBAAmB,CAAC,EAAE,yBAAyB,CAAC;IAChD;;;;OAIG;IACH,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,QAAQ,CAAC,EAAE;QACT;;;WAGG;QACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;QAE7B;;;WAGG;QACH,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IAEF;;OAEG;IACH,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAE9B;;OAEG;IACH,cAAc,CAAC,EAAE,oBAAoB,CAAC;IAEtC;;;OAGG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAElB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IAE7C;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,eAAO,MAAM,kBAAkB,EAAE,QAAQ,CACvC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,CACvC,GACC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CA0BtC,CAAC"}