@geekmidas/cli 10.0.0-alpha.46 → 10.0.0-alpha.48

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 (32) hide show
  1. package/bin/gkm.mjs +9 -1
  2. package/bin/owning-tsconfig-jsx-register.mjs +18 -0
  3. package/bin/owning-tsconfig-jsx.mjs +108 -0
  4. package/dist/backends-B9V2XD2M.cjs +82 -0
  5. package/dist/backends-B9V2XD2M.cjs.map +1 -0
  6. package/dist/backends-CSuLl0YP.mjs +59 -0
  7. package/dist/backends-CSuLl0YP.mjs.map +1 -0
  8. package/dist/encryption-C7OGMve_.cjs +91 -0
  9. package/dist/encryption-C7OGMve_.cjs.map +1 -0
  10. package/dist/encryption-DyQnPsZN.mjs +90 -0
  11. package/dist/encryption-DyQnPsZN.mjs.map +1 -0
  12. package/dist/index.cjs +131 -51
  13. package/dist/index.cjs.map +1 -1
  14. package/dist/index.mjs +123 -43
  15. package/dist/index.mjs.map +1 -1
  16. package/dist/{migrate-Dp5HFzuQ.cjs → migrate-BgEY9pdP.cjs} +2 -2
  17. package/dist/{migrate-Dp5HFzuQ.cjs.map → migrate-BgEY9pdP.cjs.map} +1 -1
  18. package/dist/{migrate-B3opyC3o.mjs → migrate-DhxTIA0z.mjs} +2 -2
  19. package/dist/{migrate-B3opyC3o.mjs.map → migrate-DhxTIA0z.mjs.map} +1 -1
  20. package/dist/{ready-V6Ou6-B6.mjs → ready-WfT-eWlm.mjs} +2 -1
  21. package/dist/{ready-V6Ou6-B6.mjs.map → ready-WfT-eWlm.mjs.map} +1 -1
  22. package/dist/{ready-L7I68yXf.cjs → ready-lr2Fm-ep.cjs} +2 -1
  23. package/dist/{ready-L7I68yXf.cjs.map → ready-lr2Fm-ep.cjs.map} +1 -1
  24. package/dist/vitest.cjs +1 -1
  25. package/dist/vitest.mjs +1 -1
  26. package/dist/{workspace-CHEC80sp.mjs → workspace-cb6U29EL.mjs} +56 -77
  27. package/dist/workspace-cb6U29EL.mjs.map +1 -0
  28. package/dist/{workspace-D9z2ymBW.cjs → workspace-vafrzZTC.cjs} +60 -99
  29. package/dist/workspace-vafrzZTC.cjs.map +1 -0
  30. package/package.json +14 -14
  31. package/dist/workspace-CHEC80sp.mjs.map +0 -1
  32. package/dist/workspace-D9z2ymBW.cjs.map +0 -1
package/dist/index.mjs CHANGED
@@ -5,10 +5,11 @@ import { d as parseModuleConfig, f as appKey, l as loadWorkspaceConfig, n as Not
5
5
  import { D as assertDeployedStage, E as TEST_STAGE, O as deployedProblems, T as InvalidStages, a as getAppBuildOrder, b as getDeployTargetError, k as stageProblems, m as stripPublicPrefix, o as getAppGkmConfig, p as getPublicEnvPrefix, t as allConstructGlobs, x as isDeployTargetSupported } from "./workspace-DNzWgM1J.mjs";
6
6
  import { a as withCustomSecret, i as toEmbeddableSecrets, n as maskPassword, t as initStageSecrets } from "./storage-BzaUxmqe.mjs";
7
7
  import { a as getKeyPath, i as FileSecretsStore, n as secretsStoreFor } from "./store-DeGATCS-.mjs";
8
- import { C as createEntryWrapper, D as loadSecretsForApp, E as loadEnvFiles, O as prepareEntryCredentials, S as createCredentialsPreload, T as isPortAvailable, _ as primaryPortKey, a as reconcileWorkspace, b as providerOf, c as LOCAL_CA_PATH, d as postgresDatabaseNames, f as quoteIdentifier, g as fakeKey, h as rootSite, i as derivedContainers, l as forgetState, m as resourceName, n as backendsOf$1, p as pgClient, r as constructGlobs, s as COMPOSE_PATH, t as FAKE_ENV, u as applyPostgres, v as cacheBackendFor, w as findAvailablePort, x as storageBackendFor, y as eventsBackendFor } from "./workspace-CHEC80sp.mjs";
8
+ import { C as loadEnvFiles, S as isPortAvailable, T as prepareEntryCredentials, _ as fakeKey, a as reconcileWorkspace, b as createEntryWrapper, c as LOCAL_CA_PATH, d as postgresDatabaseNames, f as quoteIdentifier, g as describeServices, h as rootSite, i as derivedContainers, l as forgetState, m as resourceName, n as backendsOf$1, p as pgClient, r as constructGlobs, s as COMPOSE_PATH, t as FAKE_ENV, u as applyPostgres, v as primaryPortKey, w as loadSecretsForApp, x as findAvailablePort, y as createCredentialsPreload } from "./workspace-cb6U29EL.mjs";
9
9
  import { n as EndpointGenerator, r as runtimeFor } from "./OpenApiTsGenerator-BzIGy8KE.mjs";
10
10
  import { generateOpenApi, openapiCommand, resolveOpenApiConfig } from "./openapi.mjs";
11
- import { a as writeTestHarness, c as driversFor, i as TEST_MANIFEST_ENV, n as TEST_READY_FILE, o as SubscriberGenerator, s as cacheBackendsIn, t as TEST_READY_ENV } from "./ready-V6Ou6-B6.mjs";
11
+ import { a as writeTestHarness, c as driversFor, i as TEST_MANIFEST_ENV, n as TEST_READY_FILE, o as SubscriberGenerator, s as cacheBackendsIn, t as TEST_READY_ENV } from "./ready-WfT-eWlm.mjs";
12
+ import { i as storageBackendFor, n as eventsBackendFor, r as providerOf, t as cacheBackendFor } from "./backends-CSuLl0YP.mjs";
12
13
  import { n as withCompute, r as withRoutes, t as manifestModule } from "./emit-C1e8qD08.mjs";
13
14
  import { createRequire } from "node:module";
14
15
  import { Command } from "commander";
@@ -24,6 +25,7 @@ import fg from "fast-glob";
24
25
  import chokidar from "chokidar";
25
26
  import { createCipheriv, createHash, randomBytes } from "node:crypto";
26
27
  import { fileURLToPath, pathToFileURL } from "node:url";
28
+ import { generateKeyring } from "@geekmidas/constructs/encryption";
27
29
  import { ownerRole, readerRole, roleStatements } from "@geekmidas/db/pg/roles";
28
30
  import { Client } from "pg";
29
31
  import { parse as parse$1, parseDocument } from "yaml";
@@ -40,7 +42,7 @@ import { Queue } from "@geekmidas/constructs/queue";
40
42
  import { Topic } from "@geekmidas/constructs/topic";
41
43
  import { lookup } from "node:dns/promises";
42
44
  //#region package.json
43
- var version = "10.0.0-alpha.46";
45
+ var version = "10.0.0-alpha.48";
44
46
  //#endregion
45
47
  //#region src/auth/credentials.ts
46
48
  /**
@@ -336,6 +338,45 @@ function normalizeRoutes(routes) {
336
338
  return Array.isArray(routes) ? routes : [routes];
337
339
  }
338
340
  //#endregion
341
+ //#region src/owningTsconfigJsx.ts
342
+ const REGISTER = "owning-tsconfig-jsx-register.mjs";
343
+ /** The CLI's `bin/` was not found above the module looking for it. */
344
+ var OwningTsconfigJsxHookMissing = class extends Error {
345
+ from;
346
+ constructor(from) {
347
+ super(`Could not find bin/${REGISTER} in any directory above '${from}'. It ships with @geekmidas/cli beside bin/gkm.mjs; reinstall the package if it is missing.`);
348
+ this.from = from;
349
+ this.name = "OwningTsconfigJsxHookMissing";
350
+ }
351
+ };
352
+ /**
353
+ * The CLI's `bin/owning-tsconfig-jsx-register.mjs`, as a file URL. Searched
354
+ * upward because this module runs from `src/` in the repo and from a chunk in
355
+ * `dist/` once built, and `bin/` sits beside both.
356
+ */
357
+ function registerUrl() {
358
+ const from = dirname(fileURLToPath(import.meta.url));
359
+ for (let dir = from;; dir = dirname(dir)) {
360
+ const candidate = join(dir, "bin", REGISTER);
361
+ if (existsSync(candidate)) return pathToFileURL(candidate).href;
362
+ if (dirname(dir) === dir) throw new OwningTsconfigJsxHookMissing(from);
363
+ }
364
+ }
365
+ /**
366
+ * `NODE_OPTIONS` for a process that runs app code through tsx, with the hook
367
+ * that compiles each `.tsx` with its own tsconfig's JSX settings (see
368
+ * `bin/owning-tsconfig-jsx.mjs`) put in front of every other `--import`, so it
369
+ * is registered before tsx and reads the source on tsx's behalf.
370
+ *
371
+ * `bin/gkm.mjs` already starts the CLI this way, and its children inherit it;
372
+ * this is for those that set `NODE_OPTIONS` themselves, or whose CLI was
373
+ * started with tsx already imported.
374
+ */
375
+ function withOwningTsconfigJsx(nodeOptions = "") {
376
+ if (nodeOptions.includes(REGISTER)) return nodeOptions;
377
+ return [`--import=${registerUrl()}`, nodeOptions].filter(Boolean).join(" ");
378
+ }
379
+ //#endregion
339
380
  //#region src/trust/index.ts
340
381
  /**
341
382
  * Installing the local edge's certificate authority into the OS trust store.
@@ -1196,9 +1237,9 @@ async function devCommand(options) {
1196
1237
  stage: workspace.stages.local,
1197
1238
  ...options.fake ? { fake: true } : {}
1198
1239
  });
1199
- if (reconciled.changed && reconciled.plan.containers.length > 0) {
1200
- logger$9.log(`🐳 Services: ${reconciled.plan.containers.join(", ")}`);
1201
- for (const [container, address] of Object.entries(reconciled.addresses)) logger$9.log(` ${container}: ${address}`);
1240
+ if (reconciled.services.length > 0) {
1241
+ logger$9.log("🐳 Services");
1242
+ for (const line of describeServices(reconciled.services)) logger$9.log(line);
1202
1243
  }
1203
1244
  Object.assign(appSecrets, reconciled.env);
1204
1245
  const own = reconciled.plan.resources.find((r) => (r.kind === "rest-api" || r.kind === "site") && appKey(r.id) === workspaceAppName);
@@ -1479,9 +1520,9 @@ async function workspaceDevCommand(workspace, options) {
1479
1520
  stage: workspace.stages.local,
1480
1521
  ...options.fake ? { fake: true } : {}
1481
1522
  });
1482
- if (reconciled.changed && reconciled.plan.containers.length > 0) {
1483
- logger$9.log(`🐳 Services: ${reconciled.plan.containers.join(", ")}`);
1484
- for (const [container, address] of Object.entries(reconciled.addresses)) logger$9.log(` ${container}: ${address}`);
1523
+ if (reconciled.services.length > 0) {
1524
+ logger$9.log("🐳 Services");
1525
+ for (const line of describeServices(reconciled.services)) logger$9.log(line);
1485
1526
  }
1486
1527
  const secretsEnv = {
1487
1528
  ...rawSecrets,
@@ -1490,9 +1531,9 @@ async function workspaceDevCommand(workspace, options) {
1490
1531
  const fakes = options.fake ? await serveFakes(reconciled.fakes, reconciled.ports) : [];
1491
1532
  for (const { id, port } of fakes) logger$9.log(`🎭 ${id} fake: http://localhost:${port}`);
1492
1533
  if (options.migrate || options.seed) {
1493
- const { prepareDevDatabases } = await import("./migrate-B3opyC3o.mjs");
1534
+ const { prepareDevDatabases } = await import("./migrate-DhxTIA0z.mjs");
1494
1535
  await prepareDevDatabases(workspace, reconciled.env, { seed: !!options.seed });
1495
- } else await import("./migrate-B3opyC3o.mjs").then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
1536
+ } else await import("./migrate-DhxTIA0z.mjs").then(({ reportPendingMigrations }) => reportPendingMigrations(workspace, reconciled.env)).catch((error) => {
1496
1537
  logger$9.log(`⚠️ Could not check for pending migrations: ${error instanceof Error ? error.message : String(error)}`);
1497
1538
  });
1498
1539
  const appUrls = {};
@@ -1688,7 +1729,8 @@ var EntryRunner = class {
1688
1729
  async runProcess() {
1689
1730
  const env = {
1690
1731
  ...process.env,
1691
- PORT: String(this.port)
1732
+ PORT: String(this.port),
1733
+ NODE_OPTIONS: withOwningTsconfigJsx(process.env.NODE_OPTIONS)
1692
1734
  };
1693
1735
  this.childProcess = spawn(...tsxCommand(dirname(this.wrapperPath), [this.wrapperPath]), {
1694
1736
  stdio: "inherit",
@@ -1938,7 +1980,8 @@ var DevServer = class {
1938
1980
  env: {
1939
1981
  ...process.env,
1940
1982
  NODE_ENV: "development",
1941
- GKM_DEV_PID: String(process.pid)
1983
+ GKM_DEV_PID: String(process.pid),
1984
+ NODE_OPTIONS: withOwningTsconfigJsx(process.env.NODE_OPTIONS)
1942
1985
  },
1943
1986
  detached: true
1944
1987
  });
@@ -3370,6 +3413,19 @@ const PROVISIONERS = {
3370
3413
  return { provides: { [key]: supplied(declaration.id, key, context) } };
3371
3414
  },
3372
3415
  /**
3416
+ * The keyring the stage keeps in its secrets.
3417
+ *
3418
+ * Generated on the first deploy (`withGeneratedSecrets`) and rotated only
3419
+ * by `gkm encryption:rotate`, so a redeploy never changes a key and nothing
3420
+ * written becomes unreadable. Nothing is created in Dokploy: the process
3421
+ * holds the keyring.
3422
+ */
3423
+ encryption: async (declaration, context) => {
3424
+ if (declaration.kind !== "encryption") throw new WrongKind(declaration.kind);
3425
+ const key = provideKey(declaration.id, "url");
3426
+ return { provides: { [key]: supplied(declaration.id, key, context) } };
3427
+ },
3428
+ /**
3373
3429
  * A third party's credentials, as the stage was given them.
3374
3430
  *
3375
3431
  * Nothing is created and nothing derived: the value was issued by somebody
@@ -6373,6 +6429,8 @@ function validateEnvVars(requiredVars, context) {
6373
6429
  * who could read the repo.
6374
6430
  * - **Each `secret` construct's value** — an auth server's signing secret —
6375
6431
  * random, rather than derived.
6432
+ * - **Each `encryption` construct's keyring** — one random key and an index
6433
+ * key. Later keys are added by `gkm encryption:rotate`, never by a deploy.
6376
6434
  *
6377
6435
  * Both are generated on the first deploy that needs them and written to the
6378
6436
  * stage's store, so every later deploy reads the same values: sessions survive
@@ -6388,10 +6446,10 @@ function withGeneratedSecrets(secrets, manifest) {
6388
6446
  const generated = [];
6389
6447
  const custom = { ...secrets.custom };
6390
6448
  for (const declaration of Object.values(manifest)) {
6391
- if (declaration?.kind !== "secret") continue;
6449
+ if (declaration?.kind !== "secret" && declaration?.kind !== "encryption") continue;
6392
6450
  const key = declaration.provides?.[0];
6393
6451
  if (!key || custom[key]) continue;
6394
- custom[key] = random();
6452
+ custom[key] = declaration.kind === "encryption" ? generateKeyring() : random();
6395
6453
  generated.push(key);
6396
6454
  }
6397
6455
  const seed = secrets.seed ?? random();
@@ -6749,7 +6807,7 @@ async function sniffEntryFile(entryPath, appPath, workspacePath) {
6749
6807
  ],
6750
6808
  env: {
6751
6809
  ...process.env,
6752
- NODE_OPTIONS: "--import=tsx"
6810
+ NODE_OPTIONS: withOwningTsconfigJsx("--import=tsx")
6753
6811
  }
6754
6812
  });
6755
6813
  let stdout = "";
@@ -9065,26 +9123,26 @@ function loadPackageJson() {
9065
9123
  * Run: pnpm --filter @geekmidas/cli sync-versions
9066
9124
  */
9067
9125
  const GEEKMIDAS_VERSIONS = {
9068
- "@geekmidas/audit": "~10.0.0-alpha.46",
9069
- "@geekmidas/auth": "~10.0.0-alpha.46",
9070
- "@geekmidas/cache": "~10.0.0-alpha.46",
9071
- "@geekmidas/client": "~10.0.0-alpha.46",
9072
- "@geekmidas/cloud": "~10.0.0-alpha.46",
9073
- "@geekmidas/constructs": "~10.0.0-alpha.46",
9074
- "@geekmidas/db": "~10.0.0-alpha.46",
9075
- "@geekmidas/emailkit": "~10.0.0-alpha.46",
9076
- "@geekmidas/envkit": "~10.0.0-alpha.46",
9077
- "@geekmidas/errors": "~10.0.0-alpha.46",
9078
- "@geekmidas/events": "~10.0.0-alpha.46",
9079
- "@geekmidas/logger": "~10.0.0-alpha.46",
9080
- "@geekmidas/manifest": "~10.0.0-alpha.46",
9081
- "@geekmidas/rate-limit": "~10.0.0-alpha.46",
9082
- "@geekmidas/schema": "~10.0.0-alpha.46",
9083
- "@geekmidas/services": "~10.0.0-alpha.46",
9084
- "@geekmidas/storage": "~10.0.0-alpha.46",
9085
- "@geekmidas/studio": "~10.0.0-alpha.46",
9086
- "@geekmidas/telescope": "~10.0.0-alpha.46",
9087
- "@geekmidas/testkit": "~10.0.0-alpha.46",
9126
+ "@geekmidas/audit": "~10.0.0-alpha.48",
9127
+ "@geekmidas/auth": "~10.0.0-alpha.48",
9128
+ "@geekmidas/cache": "~10.0.0-alpha.48",
9129
+ "@geekmidas/client": "~10.0.0-alpha.48",
9130
+ "@geekmidas/cloud": "~10.0.0-alpha.48",
9131
+ "@geekmidas/constructs": "~10.0.0-alpha.48",
9132
+ "@geekmidas/db": "~10.0.0-alpha.48",
9133
+ "@geekmidas/emailkit": "~10.0.0-alpha.48",
9134
+ "@geekmidas/envkit": "~10.0.0-alpha.48",
9135
+ "@geekmidas/errors": "~10.0.0-alpha.48",
9136
+ "@geekmidas/events": "~10.0.0-alpha.48",
9137
+ "@geekmidas/logger": "~10.0.0-alpha.48",
9138
+ "@geekmidas/manifest": "~10.0.0-alpha.48",
9139
+ "@geekmidas/rate-limit": "~10.0.0-alpha.48",
9140
+ "@geekmidas/schema": "~10.0.0-alpha.48",
9141
+ "@geekmidas/services": "~10.0.0-alpha.48",
9142
+ "@geekmidas/storage": "~10.0.0-alpha.48",
9143
+ "@geekmidas/studio": "~10.0.0-alpha.48",
9144
+ "@geekmidas/telescope": "~10.0.0-alpha.48",
9145
+ "@geekmidas/testkit": "~10.0.0-alpha.48",
9088
9146
  "@geekmidas/cli": `~${loadPackageJson().version}`
9089
9147
  };
9090
9148
  //#endregion
@@ -15493,8 +15551,8 @@ async function reconcileLocal(workspace, stage, options) {
15493
15551
  logger$1.log("🐳 Services already up to date");
15494
15552
  return;
15495
15553
  }
15496
- logger$1.log(`🐳 Services: ${result.plan.containers.join(", ")}`);
15497
- for (const [container, address] of Object.entries(result.addresses)) logger$1.log(` ${container}: ${address}`);
15554
+ logger$1.log("🐳 Services");
15555
+ for (const line of describeServices(result.services)) logger$1.log(line);
15498
15556
  const url = result.plan.resources.filter((r) => r.kind === "rest-api" || r.kind === "site" || r.kind === "file-server").map((r) => result.env[r.envKey]).find((address) => address?.startsWith("https://"));
15499
15557
  if (url) await ensureTrusted(workspace.root, url, { ...options.yes ? { assumeYes: true } : {} });
15500
15558
  }
@@ -15841,7 +15899,7 @@ function testDatabases(reconciled) {
15841
15899
  * starts without the reference data the app needs.
15842
15900
  */
15843
15901
  async function migrateTestStage(workspace, env) {
15844
- const { migrateAndSeed } = await import("./migrate-B3opyC3o.mjs");
15902
+ const { migrateAndSeed } = await import("./migrate-DhxTIA0z.mjs");
15845
15903
  const { discover } = await import("./discover-Cf2jAcgF.mjs").then((n) => n.n);
15846
15904
  const sources = {};
15847
15905
  const manifest = await discover({
@@ -16272,7 +16330,7 @@ program.command("migrate").description("Apply each database construct's migratio
16272
16330
  try {
16273
16331
  const globalOptions = program.opts();
16274
16332
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16275
- const { migrateCommand } = await import("./migrate-B3opyC3o.mjs");
16333
+ const { migrateCommand } = await import("./migrate-DhxTIA0z.mjs");
16276
16334
  await migrateCommand({
16277
16335
  ...options,
16278
16336
  ...construct ? { construct } : {}
@@ -16286,7 +16344,7 @@ program.command("seed").description("Migrate, then run each database construct's
16286
16344
  try {
16287
16345
  const globalOptions = program.opts();
16288
16346
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16289
- const { seedCommand } = await import("./migrate-B3opyC3o.mjs");
16347
+ const { seedCommand } = await import("./migrate-DhxTIA0z.mjs");
16290
16348
  await seedCommand({
16291
16349
  ...options,
16292
16350
  ...construct ? { construct } : {}
@@ -16300,7 +16358,7 @@ program.command("migration").description("Write a construct's next migration: an
16300
16358
  try {
16301
16359
  const globalOptions = program.opts();
16302
16360
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16303
- const { migrationCommand } = await import("./migrate-B3opyC3o.mjs");
16361
+ const { migrationCommand } = await import("./migrate-DhxTIA0z.mjs");
16304
16362
  await migrationCommand({
16305
16363
  construct,
16306
16364
  ...name ? { name } : {}
@@ -16394,6 +16452,28 @@ program.command("secrets:set").description("Set a custom secret for a stage").ar
16394
16452
  process.exit(1);
16395
16453
  }
16396
16454
  });
16455
+ program.command("encryption:rotate").description("Add a new current key to an Encryption construct's keyring on a server stage").argument("<construct>", "The Encryption construct (e.g. Pii)").requiredOption("--stage <stage>", "A deployed stage").action(async (construct, options) => {
16456
+ try {
16457
+ const globalOptions = program.opts();
16458
+ if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16459
+ const { encryptionRotateCommand } = await import("./encryption-DyQnPsZN.mjs");
16460
+ await encryptionRotateCommand(construct, options);
16461
+ } catch (error) {
16462
+ console.error(formatError(error));
16463
+ process.exit(1);
16464
+ }
16465
+ });
16466
+ program.command("encryption:retire").description("Remove an old key from an Encryption construct's keyring, once nothing is under it").argument("<construct>", "The Encryption construct (e.g. Pii)").argument("<key>", "The key to retire (e.g. k1)").requiredOption("--stage <stage>", "A deployed stage").action(async (construct, key, options) => {
16467
+ try {
16468
+ const globalOptions = program.opts();
16469
+ if (globalOptions.cwd) process.chdir(globalOptions.cwd);
16470
+ const { encryptionRetireCommand } = await import("./encryption-DyQnPsZN.mjs");
16471
+ await encryptionRetireCommand(construct, key, options);
16472
+ } catch (error) {
16473
+ console.error(formatError(error));
16474
+ process.exit(1);
16475
+ }
16476
+ });
16397
16477
  program.command("secrets:show").description("Show secrets for a stage").requiredOption("--stage <stage>", "Stage name").option("--reveal", "Show actual secret values (not masked)").action(async (options) => {
16398
16478
  try {
16399
16479
  const globalOptions = program.opts();
@@ -16439,7 +16519,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
16439
16519
  console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
16440
16520
  process.exit(1);
16441
16521
  }
16442
- const { derivedContainers } = await import("./workspace-CHEC80sp.mjs").then((n) => n.o);
16522
+ const { derivedContainers } = await import("./workspace-cb6U29EL.mjs").then((n) => n.o);
16443
16523
  const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
16444
16524
  if (!result) {
16445
16525
  console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);