@geekmidas/cli 10.0.0-alpha.16 → 10.0.0-alpha.17

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 (89) hide show
  1. package/dist/{bundler-BeNDZdHQ.cjs → bundler-mjqGAvu1.cjs} +2 -2
  2. package/dist/{bundler-BeNDZdHQ.cjs.map → bundler-mjqGAvu1.cjs.map} +1 -1
  3. package/dist/{bundler-BodTL4kf.mjs → bundler-mwH7WOb1.mjs} +2 -2
  4. package/dist/{bundler-BodTL4kf.mjs.map → bundler-mwH7WOb1.mjs.map} +1 -1
  5. package/dist/{config-Q1rvKHvw.cjs → config-CdTMeMU_.cjs} +2 -2
  6. package/dist/{config-Q1rvKHvw.cjs.map → config-CdTMeMU_.cjs.map} +1 -1
  7. package/dist/{config-pqGD3hF9.mjs → config-DPnPkWyH.mjs} +2 -2
  8. package/dist/{config-pqGD3hF9.mjs.map → config-DPnPkWyH.mjs.map} +1 -1
  9. package/dist/config.cjs +2 -2
  10. package/dist/config.d.cts +2 -2
  11. package/dist/config.d.mts +2 -2
  12. package/dist/config.mjs +2 -2
  13. package/dist/{credentials-BekkKtY_.mjs → credentials-fJP5-fa1.mjs} +4 -4
  14. package/dist/{credentials-BekkKtY_.mjs.map → credentials-fJP5-fa1.mjs.map} +1 -1
  15. package/dist/{credentials-Q6F0uqJq.cjs → credentials-tvyReUAd.cjs} +4 -4
  16. package/dist/{credentials-Q6F0uqJq.cjs.map → credentials-tvyReUAd.cjs.map} +1 -1
  17. package/dist/discover-BERGFg8v.cjs.map +1 -1
  18. package/dist/discover-CK-n3w6b.mjs.map +1 -1
  19. package/dist/{github-CRwnxKmD.mjs → github-CAfKyYPN.mjs} +21 -8
  20. package/dist/github-CAfKyYPN.mjs.map +1 -0
  21. package/dist/{github-BfflNPVe.cjs → github-DVE8Gg_F.cjs} +22 -9
  22. package/dist/github-DVE8Gg_F.cjs.map +1 -0
  23. package/dist/{index-C-VLwB_Y.d.mts → index-B4H4XF7A.d.mts} +2 -2
  24. package/dist/{index-C-HkOEBt.d.cts.map → index-B4H4XF7A.d.mts.map} +1 -1
  25. package/dist/{index-C-HkOEBt.d.cts → index-RCUizGxL.d.cts} +2 -2
  26. package/dist/{index-C-VLwB_Y.d.mts.map → index-RCUizGxL.d.cts.map} +1 -1
  27. package/dist/index.cjs +161 -168
  28. package/dist/index.cjs.map +1 -1
  29. package/dist/index.mjs +156 -163
  30. package/dist/index.mjs.map +1 -1
  31. package/dist/{openapi-Dcbme-Us.cjs → openapi-BeckoaP9.cjs} +2 -2
  32. package/dist/{openapi-Dcbme-Us.cjs.map → openapi-BeckoaP9.cjs.map} +1 -1
  33. package/dist/{openapi-vy4JzhUv.mjs → openapi-DolhBm6r.mjs} +2 -2
  34. package/dist/{openapi-vy4JzhUv.mjs.map → openapi-DolhBm6r.mjs.map} +1 -1
  35. package/dist/openapi.cjs +1 -1
  36. package/dist/openapi.d.cts +1 -1
  37. package/dist/openapi.d.mts +1 -1
  38. package/dist/openapi.mjs +1 -1
  39. package/dist/reconcile/public.d.cts +1 -1
  40. package/dist/reconcile/public.d.mts +1 -1
  41. package/dist/{fullstack-secrets-DXsWO-5m.cjs → reconcile-Cq4cO83R.cjs} +45 -1
  42. package/dist/reconcile-Cq4cO83R.cjs.map +1 -0
  43. package/dist/{fullstack-secrets-BET8gqwK.mjs → reconcile-fmoluZmZ.mjs} +34 -2
  44. package/dist/reconcile-fmoluZmZ.mjs.map +1 -0
  45. package/dist/ssm-BKN1Cg4z.mjs +60 -0
  46. package/dist/ssm-BKN1Cg4z.mjs.map +1 -0
  47. package/dist/ssm-FxeSAt35.cjs +60 -0
  48. package/dist/ssm-FxeSAt35.cjs.map +1 -0
  49. package/dist/{storage-C-30BD1e.cjs → storage-DgypfSD6.cjs} +83 -4
  50. package/dist/storage-DgypfSD6.cjs.map +1 -0
  51. package/dist/{storage-P_b3w7uj.mjs → storage-TP0x118M.mjs} +77 -4
  52. package/dist/storage-TP0x118M.mjs.map +1 -0
  53. package/dist/transfer-4A4S2hcw.mjs +122 -0
  54. package/dist/transfer-4A4S2hcw.mjs.map +1 -0
  55. package/dist/transfer-DdmtKLzi.cjs +151 -0
  56. package/dist/transfer-DdmtKLzi.cjs.map +1 -0
  57. package/dist/{types-RhXmHR-e.d.cts → types-7R81hu0i.d.mts} +138 -1
  58. package/dist/types-7R81hu0i.d.mts.map +1 -0
  59. package/dist/{types-kvBQjpPo.d.mts → types-N7c2O2m7.d.cts} +140 -1
  60. package/dist/types-N7c2O2m7.d.cts.map +1 -0
  61. package/dist/workspace/index.cjs +1 -1
  62. package/dist/workspace/index.d.cts +2 -2
  63. package/dist/workspace/index.d.mts +2 -2
  64. package/dist/workspace/index.mjs +1 -1
  65. package/dist/{workspace-mFpI_ky_.cjs → workspace-B8NLb54N.cjs} +13 -2
  66. package/dist/{workspace-mFpI_ky_.cjs.map → workspace-B8NLb54N.cjs.map} +1 -1
  67. package/dist/{workspace-CgwmXEtc.mjs → workspace-DI-M3BnN.mjs} +13 -2
  68. package/dist/{workspace-CgwmXEtc.mjs.map → workspace-DI-M3BnN.mjs.map} +1 -1
  69. package/package.json +11 -11
  70. package/dist/fullstack-secrets-BET8gqwK.mjs.map +0 -1
  71. package/dist/fullstack-secrets-DXsWO-5m.cjs.map +0 -1
  72. package/dist/github-BfflNPVe.cjs.map +0 -1
  73. package/dist/github-CRwnxKmD.mjs.map +0 -1
  74. package/dist/keystore-B4PRlbgE.mjs +0 -81
  75. package/dist/keystore-B4PRlbgE.mjs.map +0 -1
  76. package/dist/keystore-DgGRj2Yy.cjs +0 -98
  77. package/dist/keystore-DgGRj2Yy.cjs.map +0 -1
  78. package/dist/reconcile-Dd2iyILf.cjs +0 -34
  79. package/dist/reconcile-Dd2iyILf.cjs.map +0 -1
  80. package/dist/reconcile-DhQ00DpU.mjs +0 -34
  81. package/dist/reconcile-DhQ00DpU.mjs.map +0 -1
  82. package/dist/storage-C-30BD1e.cjs.map +0 -1
  83. package/dist/storage-P_b3w7uj.mjs.map +0 -1
  84. package/dist/sync-B3xxXtJT.mjs +0 -88
  85. package/dist/sync-B3xxXtJT.mjs.map +0 -1
  86. package/dist/sync-D7uTIIEi.cjs +0 -111
  87. package/dist/sync-D7uTIIEi.cjs.map +0 -1
  88. package/dist/types-RhXmHR-e.d.cts.map +0 -1
  89. package/dist/types-kvBQjpPo.d.mts.map +0 -1
package/dist/index.mjs CHANGED
@@ -1,16 +1,15 @@
1
1
  #!/usr/bin/env -S npx tsx
2
2
  import { n as __require, t as __exportAll } from "./rolldown-runtime-BhDjJH2R.mjs";
3
3
  import { i as DEFAULT_CACHE, r as ConstructGenerator, s as isPartitionedRoutes, t as discover } from "./discover-CK-n3w6b.mjs";
4
- import { i as loadConfig, l as derivedApps, n as getAppNameFromCwd, o as loadWorkspaceConfig, r as loadAppConfig, s as parseModuleConfig } from "./config-pqGD3hF9.mjs";
5
- import { C as InvalidStages, E as stageProblems, O as getPublicEnvPrefix, T as deployedProblems, a as getAppBuildOrder, k as stripPublicPrefix, o as getAppGkmConfig, s as getDependencyEnvVars, t as allConstructGlobs, v as getDeployTargetError, w as assertDeployedStage, y as isDeployTargetSupported } from "./workspace-CgwmXEtc.mjs";
6
- import { C as storageBackendFor, S as providerOf, _ as LOCAL_CA_PATH, a as loadEnvFiles, b as cacheBackendFor, c as resolveServicePorts, d as constructGlobs, f as derivedContainers, g as COMPOSE_PATH, i as isPortAvailable, l as rewriteUrlsWithPorts, m as usesConstructs, n as createEntryWrapper, o as loadSecretsForApp, p as reconcileWorkspace, r as findAvailablePort, s as prepareEntryCredentials, t as createCredentialsPreload, u as startWorkspaceServices, v as applyPostgres, x as eventsBackendFor, y as resourceName } from "./credentials-BekkKtY_.mjs";
4
+ import { i as loadConfig, l as derivedApps, n as getAppNameFromCwd, o as loadWorkspaceConfig, r as loadAppConfig, s as parseModuleConfig } from "./config-DPnPkWyH.mjs";
5
+ import { C as InvalidStages, E as stageProblems, O as getPublicEnvPrefix, T as deployedProblems, a as getAppBuildOrder, k as stripPublicPrefix, o as getAppGkmConfig, s as getDependencyEnvVars, t as allConstructGlobs, v as getDeployTargetError, w as assertDeployedStage, y as isDeployTargetSupported } from "./workspace-DI-M3BnN.mjs";
6
+ import { C as storageBackendFor, S as providerOf, _ as LOCAL_CA_PATH, a as loadEnvFiles, b as cacheBackendFor, c as resolveServicePorts, d as constructGlobs, f as derivedContainers, g as COMPOSE_PATH, i as isPortAvailable, l as rewriteUrlsWithPorts, m as usesConstructs, n as createEntryWrapper, o as loadSecretsForApp, p as reconcileWorkspace, r as findAvailablePort, s as prepareEntryCredentials, t as createCredentialsPreload, u as startWorkspaceServices, v as applyPostgres, x as eventsBackendFor, y as resourceName } from "./credentials-fJP5-fa1.mjs";
7
7
  import { a as generateServiceCredentials, i as generateSecurePassword, n as generateConnectionUrls, o as rotateServicePassword, t as createStageSecrets } from "./generator-LfZU7NlU.mjs";
8
- import { t as getKeyPath } from "./keystore-B4PRlbgE.mjs";
9
- import { i as setCustomSecret, n as readStageSecrets, o as toEmbeddableSecrets, r as secretsExist, s as writeStageSecrets, t as maskPassword } from "./storage-P_b3w7uj.mjs";
10
- import { a as openapiCommand, c as runtimeFor, n as generateOpenApi, o as resolveOpenApiConfig, r as generateOpenApiFrom, s as EndpointGenerator, t as OPENAPI_OUTPUT_PATH$1 } from "./openapi-vy4JzhUv.mjs";
8
+ import { c as getKeyPath, i as setCustomSecret, n as readStageSecrets, o as toEmbeddableSecrets, r as secretsExist, s as writeStageSecrets, t as maskPassword } from "./storage-TP0x118M.mjs";
9
+ import { a as openapiCommand, c as runtimeFor, n as generateOpenApi, o as resolveOpenApiConfig, r as generateOpenApiFrom, s as EndpointGenerator, t as OPENAPI_OUTPUT_PATH$1 } from "./openapi-DolhBm6r.mjs";
11
10
  import { i as withRoutes, r as withCompute } from "./emit-Bzq7JsMP.mjs";
12
- import { n as writeDockerEnvFromSecrets, t as generateFullstackCustomSecrets } from "./fullstack-secrets-BET8gqwK.mjs";
13
- import { n as pullSecrets, r as pushSecrets, t as isSSMConfigured } from "./sync-B3xxXtJT.mjs";
11
+ import { i as writeDockerEnvFromSecrets, r as generateFullstackCustomSecrets } from "./reconcile-fmoluZmZ.mjs";
12
+ import { a as isRemoteStore, n as pullStageSecrets, r as pushStageSecrets, t as NoStoredSecrets } from "./transfer-4A4S2hcw.mjs";
14
13
  import { createRequire } from "node:module";
15
14
  import { Command } from "commander";
16
15
  import { stdin, stdout } from "node:process";
@@ -38,7 +37,7 @@ import { fileURLToPath, pathToFileURL } from "node:url";
38
37
  import { lookup } from "node:dns/promises";
39
38
  import prompts from "prompts";
40
39
  //#region package.json
41
- var version = "10.0.0-alpha.16";
40
+ var version = "10.0.0-alpha.17";
42
41
  //#endregion
43
42
  //#region src/auth/credentials.ts
44
43
  /**
@@ -2609,7 +2608,7 @@ async function buildForProvider(provider, context, rootOutputDir, endpointGenera
2609
2608
  let masterKey;
2610
2609
  if (context.production?.bundle && !skipBundle) {
2611
2610
  logger$9.log(`\n📦 Bundling production server...`);
2612
- const { bundleServer } = await import("./bundler-BodTL4kf.mjs");
2611
+ const { bundleServer } = await import("./bundler-mwH7WOb1.mjs");
2613
2612
  const allConstructs = [
2614
2613
  ...endpoints.map((e) => e.construct),
2615
2614
  ...functions.map((f) => f.construct),
@@ -8301,7 +8300,6 @@ const DEPENDENCY_VERSIONS = {
8301
8300
  clsx: "~2.1.1",
8302
8301
  "lucide-react": "~1.48.0",
8303
8302
  "tailwind-merge": "~3.7.0",
8304
- "vite-tsconfig-paths": "~5.1.4",
8305
8303
  "@biomejs/biome": "~2.5.14",
8306
8304
  "@faker-js/faker": "~10.6.0",
8307
8305
  turbo: "~2.11.4",
@@ -8312,26 +8310,21 @@ const DEPENDENCY_VERSIONS = {
8312
8310
  "@types/aws-lambda": "~8.10.163"
8313
8311
  };
8314
8312
  /**
8315
- * The build and test toolchain, at the versions it was already on.
8316
- *
8317
- * Held here so it moves in one place, but not moved yet: it changes how every
8318
- * scaffold compiles and runs, and tranche 2 (#40) moves it together with the
8319
- * repository's own toolchain.
8313
+ * The build and test toolchain, at the versions the repository itself builds
8314
+ * and tests with (scripts/dependency-versions.json), so a scaffold compiles
8315
+ * with the compiler its own `@geekmidas` packages were checked against.
8320
8316
  */
8321
8317
  const TOOLCHAIN_VERSIONS = {
8322
- typescript: "~5.8.2",
8323
- tsx: "~4.20.0",
8324
- esbuild: "~0.27.0",
8325
- vitest: "~4.0.0",
8326
- vite: "^7.0.0",
8327
- "@vitejs/plugin-react": "^4.3.4",
8328
- storybook: "^8.4.7",
8329
- "@storybook/addon-a11y": "^8.4.7",
8330
- "@storybook/addon-essentials": "^8.4.7",
8331
- "@storybook/addon-interactions": "^8.4.7",
8332
- "@storybook/react": "^8.4.7",
8333
- "@storybook/react-vite": "^8.4.7",
8334
- "vite@storybook": "^6.0.0"
8318
+ typescript: "~7.0.2",
8319
+ tsx: "~4.23.15",
8320
+ esbuild: "~0.28.2",
8321
+ vitest: "~5.0.2",
8322
+ vite: "~8.3.1",
8323
+ "@vitejs/plugin-react": "^6.1.1",
8324
+ storybook: "^10.6.0",
8325
+ "@storybook/addon-docs": "^10.6.0",
8326
+ "@storybook/addon-a11y": "^10.6.0",
8327
+ "@storybook/react-vite": "^10.6.0"
8335
8328
  };
8336
8329
  /**
8337
8330
  * The Expo app's packages, which track an Expo SDK release (55) rather than
@@ -8361,6 +8354,15 @@ const EXPO_VERSIONS = {
8361
8354
  nativewind: "~4.2.0",
8362
8355
  tailwindcss: "~3.4.0"
8363
8356
  };
8357
+ /**
8358
+ * The pnpm a pnpm scaffold runs under, through \`packageManager\`.
8359
+ *
8360
+ * Pinned in every layout. Without it Corepack takes the newest pnpm, and 11
8361
+ * fails the first install on dependencies with build scripts (esbuild) until
8362
+ * they are approved — a single-app scaffold that did not pin it could not
8363
+ * install at all.
8364
+ */
8365
+ const PNPM_VERSION = "pnpm@10.13.1";
8364
8366
  /** The Biome config schema matching the Biome the scaffold installs. */
8365
8367
  const BIOME_SCHEMA = `https://biomejs.dev/schemas/${DEPENDENCY_VERSIONS["@biomejs/biome"].replace(/^[~^]/, "")}/schema.json`;
8366
8368
  //#endregion
@@ -8380,26 +8382,26 @@ function loadPackageJson() {
8380
8382
  * Run: pnpm --filter @geekmidas/cli sync-versions
8381
8383
  */
8382
8384
  const GEEKMIDAS_VERSIONS = {
8383
- "@geekmidas/audit": "~10.0.0-alpha.16",
8384
- "@geekmidas/auth": "~10.0.0-alpha.16",
8385
- "@geekmidas/cache": "~10.0.0-alpha.16",
8386
- "@geekmidas/client": "~10.0.0-alpha.16",
8387
- "@geekmidas/cloud": "~10.0.0-alpha.16",
8388
- "@geekmidas/constructs": "~10.0.0-alpha.16",
8389
- "@geekmidas/db": "~10.0.0-alpha.16",
8390
- "@geekmidas/emailkit": "~10.0.0-alpha.16",
8391
- "@geekmidas/envkit": "~10.0.0-alpha.16",
8392
- "@geekmidas/errors": "~10.0.0-alpha.16",
8393
- "@geekmidas/events": "~10.0.0-alpha.16",
8394
- "@geekmidas/logger": "~10.0.0-alpha.16",
8395
- "@geekmidas/manifest": "~10.0.0-alpha.16",
8396
- "@geekmidas/rate-limit": "~10.0.0-alpha.16",
8397
- "@geekmidas/schema": "~10.0.0-alpha.16",
8398
- "@geekmidas/services": "~10.0.0-alpha.16",
8399
- "@geekmidas/storage": "~10.0.0-alpha.16",
8400
- "@geekmidas/studio": "~10.0.0-alpha.16",
8401
- "@geekmidas/telescope": "~10.0.0-alpha.16",
8402
- "@geekmidas/testkit": "~10.0.0-alpha.16",
8385
+ "@geekmidas/audit": "~10.0.0-alpha.17",
8386
+ "@geekmidas/auth": "~10.0.0-alpha.17",
8387
+ "@geekmidas/cache": "~10.0.0-alpha.17",
8388
+ "@geekmidas/client": "~10.0.0-alpha.17",
8389
+ "@geekmidas/cloud": "~10.0.0-alpha.17",
8390
+ "@geekmidas/constructs": "~10.0.0-alpha.17",
8391
+ "@geekmidas/db": "~10.0.0-alpha.17",
8392
+ "@geekmidas/emailkit": "~10.0.0-alpha.17",
8393
+ "@geekmidas/envkit": "~10.0.0-alpha.17",
8394
+ "@geekmidas/errors": "~10.0.0-alpha.17",
8395
+ "@geekmidas/events": "~10.0.0-alpha.17",
8396
+ "@geekmidas/logger": "~10.0.0-alpha.17",
8397
+ "@geekmidas/manifest": "~10.0.0-alpha.17",
8398
+ "@geekmidas/rate-limit": "~10.0.0-alpha.17",
8399
+ "@geekmidas/schema": "~10.0.0-alpha.17",
8400
+ "@geekmidas/services": "~10.0.0-alpha.17",
8401
+ "@geekmidas/storage": "~10.0.0-alpha.17",
8402
+ "@geekmidas/studio": "~10.0.0-alpha.17",
8403
+ "@geekmidas/telescope": "~10.0.0-alpha.17",
8404
+ "@geekmidas/testkit": "~10.0.0-alpha.17",
8403
8405
  "@geekmidas/cli": `~${loadPackageJson().version}`
8404
8406
  };
8405
8407
  //#endregion
@@ -8447,7 +8449,6 @@ function generateAuthAppFiles(options) {
8447
8449
  compilerOptions: {
8448
8450
  noEmit: true,
8449
8451
  allowImportingTsExtensions: true,
8450
- baseUrl: ".",
8451
8452
  paths: {
8452
8453
  "~/*": ["./src/*"],
8453
8454
  [`@${options.name}/*`]: ["../../packages/*/src"]
@@ -8503,10 +8504,10 @@ function stageEnv(stages) {
8503
8504
  * Vitest config content with globalSetup for database-enabled apps
8504
8505
  */
8505
8506
  const vitestConfigContent = `import { defineConfig } from 'vitest/config';
8506
- import tsconfigPaths from 'vite-tsconfig-paths';
8507
8507
 
8508
8508
  export default defineConfig({
8509
- plugins: [tsconfigPaths()],
8509
+ // Vite resolves tsconfig \`paths\` itself; no plugin needed.
8510
+ resolve: { tsconfigPaths: true },
8510
8511
  test: {
8511
8512
  environment: 'node',
8512
8513
  globalSetup: './test/globalSetup.ts',
@@ -8572,7 +8573,6 @@ export default defineConfig({${stagesBlock(options.stages)}${options.monorepo ?
8572
8573
  resolveJsonModule: true,
8573
8574
  noEmit: true,
8574
8575
  allowImportingTsExtensions: true,
8575
- baseUrl: ".",
8576
8576
  paths: { "~/*": ["./src/*"] }
8577
8577
  },
8578
8578
  include: ["src/**/*.ts"],
@@ -8696,7 +8696,6 @@ function workspaceApiTsConfig(name) {
8696
8696
  compilerOptions: {
8697
8697
  noEmit: true,
8698
8698
  allowImportingTsExtensions: true,
8699
- baseUrl: ".",
8700
8699
  paths: {
8701
8700
  "~/*": ["./src/*"],
8702
8701
  [`@${name}/constructs/*`]: ["../../constructs/*"],
@@ -8968,6 +8967,32 @@ function deploy(options) {
8968
8967
  role-to-assume: \${{ vars.AWS_ROLE_ARN }}
8969
8968
  aws-region: ${options.region}
8970
8969
  ` : "";
8970
+ const stageSecrets = sst ? `${credentials}
8971
+ # The stage's secrets, from SSM in the account the role belongs to —
8972
+ # pushed there once with \`gkm secrets:push --stage <stage> --profile …\`.
8973
+ # The stage reaches the shell as a variable, never pasted into the script:
8974
+ # on a manual run it is whatever was typed.
8975
+ - name: Stage secrets
8976
+ run: ${pm.exec} gkm secrets:pull --stage "$STAGE"
8977
+ env:
8978
+ STAGE: \${{ matrix.stage }}
8979
+ ` : `
8980
+ # The stage's secrets are kept in the encrypted .gkm/secrets/<stage>.json,
8981
+ # and each environment holds its key as GKM_SECRETS_KEY. .gkm/ is
8982
+ # gitignored, so a checkout has the key but not the file: set
8983
+ # secrets.store in gkm.config.ts to a store CI can reach before deploying
8984
+ # from here.
8985
+ # Owner-only, as the CLI writes its own keys. The stage reaches the shell
8986
+ # as a variable, never pasted into the script: on a manual run it is
8987
+ # whatever was typed.
8988
+ - name: Stage secrets key
8989
+ run: |
8990
+ mkdir -p -m 700 ~/.gkm/${options.name}
8991
+ (umask 077 && printf '%s' "$KEY" > ~/.gkm/${options.name}/"$STAGE".key)
8992
+ env:
8993
+ KEY: \${{ secrets.GKM_SECRETS_KEY }}
8994
+ STAGE: \${{ matrix.stage }}
8995
+ `;
8971
8996
  const deployEnv = sst ? "" : `
8972
8997
  DOKPLOY_API_TOKEN: \${{ secrets.DOKPLOY_API_TOKEN }}
8973
8998
  DOKPLOY_ENDPOINT: \${{ vars.DOKPLOY_ENDPOINT }}`;
@@ -9049,20 +9074,7 @@ ${pm.setup}
9049
9074
  ${pm.setup}
9050
9075
  - name: Install
9051
9076
  run: ${pm.install}
9052
-
9053
- # The stage's secrets are committed encrypted; the key never is. Each
9054
- # environment holds its own as GKM_SECRETS_KEY.
9055
- # Owner-only, as the CLI writes its own keys. The stage reaches the shell
9056
- # as a variable, never pasted into the script: on a manual run it is
9057
- # whatever was typed.
9058
- - name: Stage secrets key
9059
- run: |
9060
- mkdir -p -m 700 ~/.gkm/${options.name}
9061
- (umask 077 && printf '%s' "$KEY" > ~/.gkm/${options.name}/"$STAGE".key)
9062
- env:
9063
- KEY: \${{ secrets.GKM_SECRETS_KEY }}
9064
- STAGE: \${{ matrix.stage }}
9065
- ${credentials}
9077
+ ${stageSecrets}
9066
9078
  - name: Deploy
9067
9079
  run: ${pm.run} "deploy:$STAGE"
9068
9080
  env:
@@ -9971,7 +9983,7 @@ function generateMonorepoFiles(options, _template) {
9971
9983
  version: "0.0.1",
9972
9984
  private: true,
9973
9985
  type: "module",
9974
- packageManager: "pnpm@10.13.1",
9986
+ packageManager: PNPM_VERSION,
9975
9987
  scripts: {
9976
9988
  dev: isFullstack ? "gkm dev" : "turbo dev",
9977
9989
  build: isFullstack ? "gkm build" : "turbo build",
@@ -10125,7 +10137,6 @@ ${isSst ? "\n# SST\n.sst/\n" : ""}`;
10125
10137
  const tsConfig = {
10126
10138
  compilerOptions: {
10127
10139
  ...isFullstack ? {
10128
- baseUrl: ".",
10129
10140
  paths: { [`@${options.name}/constructs/*`]: ["./constructs/*"] },
10130
10141
  allowImportingTsExtensions: true,
10131
10142
  noEmit: true
@@ -10275,12 +10286,24 @@ ${workspaceConstructsGlobs(options.routesStructure, dirname(options.apiPath)).ma
10275
10286
  ],
10276
10287
 
10277
10288
  secrets: {
10278
- enabled: true,
10289
+ enabled: true,${secretsStore(options)}
10279
10290
  },
10280
10291
  });
10281
10292
  `;
10282
10293
  }
10283
10294
  /**
10295
+ * Where a deployed stage's secrets live. On AWS that is SSM in the stage's own
10296
+ * account, which the deploy job reaches with the role it already assumed; a
10297
+ * server target keeps the encrypted local file, the default.
10298
+ */
10299
+ function secretsStore(options) {
10300
+ if (options.deployTarget !== "sst" || !options.region) return "";
10301
+ return `
10302
+ // Deployed stages keep their secrets in SSM, in the account each stage
10303
+ // deploys to: \`gkm secrets:push --stage <stage> --profile <profile>\`.
10304
+ store: { provider: 'ssm', region: '${options.region}' },`;
10305
+ }
10306
+ /**
10284
10307
  * The workspace's constructs, at its root rather than inside an app.
10285
10308
  *
10286
10309
  * They outlive the app that used them first: a site depending on the API is a
@@ -10495,7 +10518,7 @@ const apiTemplate = {
10495
10518
  const kv = cacheFor();
10496
10519
  const db = databaseFor();
10497
10520
  const mail = emailFor();
10498
- const src = (path) => monorepo ? `~/${path}` : `./${path}`;
10521
+ const src = (path) => `~/${path}`;
10499
10522
  const declares = !monorepo;
10500
10523
  const loggerContent = `import { createLogger } from '@geekmidas/logger/${loggerType}';
10501
10524
 
@@ -10578,7 +10601,7 @@ export const healthEndpoint = router
10578
10601
  timestamp: new Date().toISOString(),
10579
10602
  }));
10580
10603
  ` : `import { z } from 'zod';
10581
- import { router } from './router.ts';
10604
+ import { router } from '~/router.ts';
10582
10605
 
10583
10606
  export const healthEndpoint = router
10584
10607
  .get('/health')
@@ -11039,8 +11062,8 @@ export const telescope = new Telescope({
11039
11062
  content: `import { Direction, InMemoryMonitoringStorage, Studio } from '@geekmidas/studio';
11040
11063
  import { Kysely, PostgresDialect } from 'kysely';
11041
11064
  import pg from 'pg';
11042
- import type { Database } from './constructs/database.ts';
11043
- import { envParser } from './config/env.ts';
11065
+ import type { Database } from '~/constructs/database.ts';
11066
+ import { envParser } from '~/config/env.ts';
11044
11067
 
11045
11068
  // The key the database construct publishes — not a hand-written DATABASE_URL.
11046
11069
  const studioConfig = envParser
@@ -11599,7 +11622,6 @@ function generatePackageJson(options, template) {
11599
11622
  devDependencies["@geekmidas/testkit"] = GEEKMIDAS_VERSIONS["@geekmidas/testkit"];
11600
11623
  devDependencies["@faker-js/faker"] = DEPENDENCY_VERSIONS["@faker-js/faker"];
11601
11624
  devDependencies["kysely-ctl"] = DEPENDENCY_VERSIONS["kysely-ctl"];
11602
- devDependencies["vite-tsconfig-paths"] = DEPENDENCY_VERSIONS["vite-tsconfig-paths"];
11603
11625
  }
11604
11626
  if (monorepo) {
11605
11627
  delete devDependencies["@biomejs/biome"];
@@ -11624,6 +11646,7 @@ function generatePackageJson(options, template) {
11624
11646
  version: "0.0.1",
11625
11647
  private: true,
11626
11648
  type: "module",
11649
+ ...!monorepo && options.packageManager === "pnpm" ? { packageManager: PNPM_VERSION } : {},
11627
11650
  exports: {
11628
11651
  "./client": OPENAPI_OUTPUT_PATH,
11629
11652
  "./endpoints": ENDPOINTS_OUTPUT_PATH
@@ -11832,9 +11855,7 @@ function generateUiPackageFiles(options) {
11832
11855
  },
11833
11856
  devDependencies: {
11834
11857
  "@storybook/addon-a11y": TOOLCHAIN_VERSIONS["@storybook/addon-a11y"],
11835
- "@storybook/addon-essentials": TOOLCHAIN_VERSIONS["@storybook/addon-essentials"],
11836
- "@storybook/addon-interactions": TOOLCHAIN_VERSIONS["@storybook/addon-interactions"],
11837
- "@storybook/react": TOOLCHAIN_VERSIONS["@storybook/react"],
11858
+ "@storybook/addon-docs": TOOLCHAIN_VERSIONS["@storybook/addon-docs"],
11838
11859
  "@storybook/react-vite": TOOLCHAIN_VERSIONS["@storybook/react-vite"],
11839
11860
  "@tailwindcss/vite": DEPENDENCY_VERSIONS["@tailwindcss/vite"],
11840
11861
  "@types/react": DEPENDENCY_VERSIONS["@types/react"],
@@ -11844,7 +11865,7 @@ function generateUiPackageFiles(options) {
11844
11865
  storybook: TOOLCHAIN_VERSIONS["storybook"],
11845
11866
  tailwindcss: DEPENDENCY_VERSIONS["tailwindcss"],
11846
11867
  typescript: TOOLCHAIN_VERSIONS["typescript"],
11847
- vite: TOOLCHAIN_VERSIONS["vite@storybook"]
11868
+ vite: TOOLCHAIN_VERSIONS["vite"]
11848
11869
  },
11849
11870
  peerDependencies: {
11850
11871
  react: ">=18.0.0",
@@ -11863,7 +11884,6 @@ function generateUiPackageFiles(options) {
11863
11884
  ],
11864
11885
  noEmit: true,
11865
11886
  allowImportingTsExtensions: true,
11866
- baseUrl: ".",
11867
11887
  paths: { "~/*": ["./src/*"] }
11868
11888
  },
11869
11889
  include: ["src/**/*"],
@@ -11898,17 +11918,17 @@ function generateUiPackageFiles(options) {
11898
11918
 
11899
11919
  const config: StorybookConfig = {
11900
11920
  stories: ['../src/**/*.stories.@(ts|tsx)'],
11901
- addons: [
11902
- '@storybook/addon-essentials',
11903
- '@storybook/addon-interactions',
11904
- '@storybook/addon-a11y',
11905
- ],
11921
+ // Controls, actions, backgrounds, viewport and interactions are part of
11922
+ // \`storybook\` itself; docs and a11y are add-ons.
11923
+ addons: ['@storybook/addon-docs', '@storybook/addon-a11y'],
11906
11924
  framework: {
11907
11925
  name: '@storybook/react-vite',
11908
11926
  options: {},
11909
11927
  },
11910
- docs: {
11911
- autodocs: 'tag',
11928
+ // \`react-docgen\` parses components itself. The TypeScript-based docgen
11929
+ // calls into TypeScript's JavaScript API, which TypeScript 7 no longer ships.
11930
+ typescript: {
11931
+ reactDocgen: 'react-docgen',
11912
11932
  },
11913
11933
  viteFinal: async (config) => {
11914
11934
  // Add Tailwind CSS v4 plugin
@@ -11921,18 +11941,21 @@ const config: StorybookConfig = {
11921
11941
 
11922
11942
  export default config;
11923
11943
  `;
11924
- const storybookPreview = `import type { Preview } from '@storybook/react';
11944
+ const storybookPreview = `import type { Preview } from '@storybook/react-vite';
11925
11945
  import '../src/styles/globals.css';
11926
11946
 
11927
11947
  const preview: Preview = {
11948
+ // The starting background is a global, not a parameter.
11949
+ initialGlobals: {
11950
+ backgrounds: { value: 'dark' },
11951
+ },
11928
11952
  parameters: {
11929
11953
  backgrounds: {
11930
- default: 'dark',
11931
- values: [
11932
- { name: 'dark', value: '#171717' },
11933
- { name: 'surface', value: '#1c1c1c' },
11934
- { name: 'light', value: '#fafafa' },
11935
- ],
11954
+ options: {
11955
+ dark: { name: 'dark', value: '#171717' },
11956
+ surface: { name: 'surface', value: '#1c1c1c' },
11957
+ light: { name: 'light', value: '#fafafa' },
11958
+ },
11936
11959
  },
11937
11960
  controls: {
11938
11961
  matchers: {
@@ -12095,7 +12118,7 @@ Button.displayName = 'Button';
12095
12118
 
12096
12119
  export { Button, buttonVariants };
12097
12120
  `;
12098
- const buttonStories = `import type { Meta, StoryObj } from '@storybook/react';
12121
+ const buttonStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12099
12122
  import { Button } from '~/components/ui/button';
12100
12123
 
12101
12124
  const meta: Meta<typeof Button> = {
@@ -12260,7 +12283,7 @@ CardFooter.displayName = 'CardFooter';
12260
12283
 
12261
12284
  export { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent };
12262
12285
  `;
12263
- const inputStories = `import type { Meta, StoryObj } from '@storybook/react';
12286
+ const inputStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12264
12287
  import { Input } from '~/components/ui/input';
12265
12288
 
12266
12289
  const meta: Meta<typeof Input> = {
@@ -12314,7 +12337,7 @@ export const WithValue: Story = {
12314
12337
  },
12315
12338
  };
12316
12339
  `;
12317
- const cardStories = `import type { Meta, StoryObj } from '@storybook/react';
12340
+ const cardStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12318
12341
  import { Button } from '~/components/ui/button';
12319
12342
  import {
12320
12343
  Card,
@@ -12401,7 +12424,7 @@ Label.displayName = LabelPrimitive.Root.displayName;
12401
12424
 
12402
12425
  export { Label };
12403
12426
  `;
12404
- const labelStories = `import type { Meta, StoryObj } from '@storybook/react';
12427
+ const labelStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12405
12428
  import { Input } from '~/components/ui/input';
12406
12429
  import { Label } from '~/components/ui/label';
12407
12430
 
@@ -12477,7 +12500,7 @@ function Badge({ className, variant, ...props }: BadgeProps) {
12477
12500
 
12478
12501
  export { Badge, badgeVariants };
12479
12502
  `;
12480
- const badgeStories = `import type { Meta, StoryObj } from '@storybook/react';
12503
+ const badgeStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12481
12504
  import { Badge } from '~/components/ui/badge';
12482
12505
 
12483
12506
  const meta: Meta<typeof Badge> = {
@@ -12553,7 +12576,7 @@ Separator.displayName = SeparatorPrimitive.Root.displayName;
12553
12576
 
12554
12577
  export { Separator };
12555
12578
  `;
12556
- const separatorStories = `import type { Meta, StoryObj } from '@storybook/react';
12579
+ const separatorStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12557
12580
  import { Separator } from '~/components/ui/separator';
12558
12581
 
12559
12582
  const meta: Meta<typeof Separator> = {
@@ -12658,7 +12681,7 @@ TabsContent.displayName = TabsPrimitive.Content.displayName;
12658
12681
 
12659
12682
  export { Tabs, TabsList, TabsTrigger, TabsContent };
12660
12683
  `;
12661
- const tabsStories = `import type { Meta, StoryObj } from '@storybook/react';
12684
+ const tabsStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12662
12685
  import { Tabs, TabsContent, TabsList, TabsTrigger } from '~/components/ui/tabs';
12663
12686
  import { Button } from '~/components/ui/button';
12664
12687
  import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '~/components/ui/card';
@@ -12762,7 +12785,7 @@ TooltipContent.displayName = TooltipPrimitive.Content.displayName;
12762
12785
 
12763
12786
  export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
12764
12787
  `;
12765
- const tooltipStories = `import type { Meta, StoryObj } from '@storybook/react';
12788
+ const tooltipStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12766
12789
  import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '~/components/ui/tooltip';
12767
12790
  import { Button } from '~/components/ui/button';
12768
12791
 
@@ -12955,7 +12978,7 @@ export {
12955
12978
  DialogDescription,
12956
12979
  };
12957
12980
  `;
12958
- const dialogStories = `import type { Meta, StoryObj } from '@storybook/react';
12981
+ const dialogStories = `import type { Meta, StoryObj } from '@storybook/react-vite';
12959
12982
  import {
12960
12983
  Dialog,
12961
12984
  DialogContent,
@@ -13287,7 +13310,6 @@ export default nextConfig;
13287
13310
  jsx: "preserve",
13288
13311
  incremental: true,
13289
13312
  plugins: [{ name: "next" }],
13290
- baseUrl: ".",
13291
13313
  paths: {
13292
13314
  "~/*": ["./src/*", "../../packages/ui/src/*"],
13293
13315
  [`${apiPackage}/client`]: ["../../apps/api/.gkm/openapi/api.ts"],
@@ -13582,8 +13604,7 @@ function generateTanStackWebFiles(options) {
13582
13604
  tailwindcss: DEPENDENCY_VERSIONS["tailwindcss"],
13583
13605
  tsx: TOOLCHAIN_VERSIONS["tsx"],
13584
13606
  typescript: TOOLCHAIN_VERSIONS["typescript"],
13585
- vite: TOOLCHAIN_VERSIONS["vite"],
13586
- "vite-tsconfig-paths": DEPENDENCY_VERSIONS["vite-tsconfig-paths"]
13607
+ vite: TOOLCHAIN_VERSIONS["vite"]
13587
13608
  }
13588
13609
  };
13589
13610
  const viteConfig = `import { Credentials } from '@geekmidas/envkit/credentials';
@@ -13591,16 +13612,16 @@ import tailwindcss from '@tailwindcss/vite';
13591
13612
  import { tanstackStart } from '@tanstack/react-start/plugin/vite';
13592
13613
  import viteReact from '@vitejs/plugin-react';
13593
13614
  import { defineConfig } from 'vite';
13594
- import tsconfigPaths from 'vite-tsconfig-paths';
13595
13615
 
13596
13616
  export default defineConfig({
13617
+ // Vite resolves tsconfig \`paths\` itself; no plugin needed.
13618
+ resolve: { tsconfigPaths: true },
13597
13619
  server: {
13598
13620
  port: Number(Credentials.PORT ?? 3001),
13599
13621
  },
13600
13622
  // VITE_* vars are inlined automatically; no manual loadEnv needed.
13601
13623
  envPrefix: 'VITE_',
13602
13624
  plugins: [
13603
- tsconfigPaths({ root: import.meta.dirname }),
13604
13625
  tailwindcss(),
13605
13626
  tanstackStart(),
13606
13627
  viteReact(),
@@ -13627,7 +13648,6 @@ export default defineConfig({
13627
13648
  isolatedModules: true,
13628
13649
  jsx: "preserve",
13629
13650
  incremental: true,
13630
- baseUrl: ".",
13631
13651
  types: ["vite/client"],
13632
13652
  paths: {
13633
13653
  "~/*": ["./src/*", "../../packages/ui/src/*"],
@@ -14890,7 +14910,7 @@ async function reconcileLocal(workspace, stage, options) {
14890
14910
  /**
14891
14911
  * Resolve secrets with priority:
14892
14912
  * 1. Local secrets exist → use them (preserves manual additions)
14893
- * 2. SSM configured and has secrets → pull and use
14913
+ * 2. A deployed stage whose store has secrets → pull and use
14894
14914
  * 3. Neither → generate fresh secrets
14895
14915
  *
14896
14916
  * --force skips checks 1 and 2 and always regenerates.
@@ -14909,18 +14929,15 @@ async function resolveSecrets(stage, workspace, options) {
14909
14929
  return reconciled ?? secrets;
14910
14930
  }
14911
14931
  }
14912
- if (isSSMConfigured(workspace)) {
14913
- logger$1.log("☁️ Checking for remote secrets in SSM...");
14932
+ if (isRemoteStore(workspace, stage)) {
14933
+ logger$1.log("☁️ Checking the secrets store...");
14914
14934
  try {
14915
- const remoteSecrets = await pullSecrets(stage, workspace);
14916
- if (remoteSecrets) {
14917
- logger$1.log("✅ Pulled secrets from SSM");
14918
- await writeStageSecrets(remoteSecrets, workspace.root);
14919
- return remoteSecrets;
14920
- }
14921
- logger$1.log(" No remote secrets found");
14935
+ const { secrets } = await pullStageSecrets(workspace, stage);
14936
+ logger$1.log("✅ Pulled secrets from the store");
14937
+ return secrets;
14922
14938
  } catch (error) {
14923
- logger$1.warn(`⚠️ Failed to pull from SSM: ${error.message}`);
14939
+ if (error instanceof NoStoredSecrets) logger$1.log(" The store holds none yet");
14940
+ else logger$1.warn(`⚠️ Could not pull from the store: ${error.message}`);
14924
14941
  }
14925
14942
  }
14926
14943
  logger$1.log("🔐 Generating fresh development secrets...");
@@ -15054,18 +15071,18 @@ async function generateFreshSecrets(stage, workspace, options) {
15054
15071
  const secrets = createFreshWorkspaceSecrets(stage, workspace, await derivedContainers(workspace, stage));
15055
15072
  await writeStageSecrets(secrets, workspace.root);
15056
15073
  logger$1.log(` Secrets written to .gkm/secrets/${stage}.json`);
15057
- if (isSSMConfigured(workspace) && !options.yes) {
15074
+ if (isRemoteStore(workspace, stage) && !options.yes) {
15058
15075
  const { shouldPush } = await prompts({
15059
15076
  type: "confirm",
15060
15077
  name: "shouldPush",
15061
- message: "Push secrets to SSM for team sharing?",
15078
+ message: `Push the "${stage}" secrets to its store?`,
15062
15079
  initial: true
15063
15080
  });
15064
15081
  if (shouldPush) try {
15065
- await pushSecrets(stage, workspace);
15066
- logger$1.log("☁️ Secrets pushed to SSM");
15082
+ await pushStageSecrets(workspace, stage);
15083
+ logger$1.log("☁️ Secrets pushed to the store");
15067
15084
  } catch (error) {
15068
- logger$1.warn(`⚠️ Failed to push to SSM: ${error.message}`);
15085
+ logger$1.warn(`⚠️ Could not push to the store: ${error.message}`);
15069
15086
  }
15070
15087
  }
15071
15088
  return secrets;
@@ -15499,7 +15516,7 @@ const program = new Command();
15499
15516
  program.name("gkm").description("GeekMidas backend framework CLI").version(version).option("--cwd <path>", "Change working directory").option("--debug", "Enable debug mode (verbose errors with stack traces)").hook("preAction", () => {
15500
15517
  if (program.opts().debug);
15501
15518
  });
15502
- program.command("init").description("Scaffold a new project").argument("[name]", "Project name").option("--template <template>", "Project template (minimal, api, serverless, worker)").option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip prompts, use defaults", false).option("--monorepo", "Setup as monorepo with packages/models", false).option("--api-path <path>", "API app path in monorepo (default: apps/api)").option("--pm <manager>", "Package manager (pnpm, npm, yarn, bun)").option("--deploy <target>", "Where it deploys (dokploy, sst, none)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").option("--stages <names>", "Deployed stages, comma-separated (e.g. staging,prod)").option("--protected-stage <name>", "Which deployed stage is production").option("--local-stage <name>", "What gkm dev runs as (e.g. dev)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").action(async (name, options) => {
15519
+ program.command("init").description("Scaffold a new project").argument("[name]", "Project name").option("--template <template>", "Project template (minimal, api, serverless, worker)").option("--skip-install", "Skip dependency installation", false).option("-y, --yes", "Skip prompts, use defaults", false).option("--monorepo", "Setup as monorepo with packages/models", false).option("--api-path <path>", "API app path in monorepo (default: apps/api)").option("--pm <manager>", "Package manager (pnpm, npm, yarn, bun)").option("--deploy <target>", "Where it deploys (dokploy, sst, none)").option("--region <region>", "AWS region for an SST deploy (e.g. eu-west-1)").option("--stages <names>", "Deployed stages, comma-separated (e.g. staging,prod)").option("--protected-stage <name>", "Which deployed stage is production").option("--local-stage <name>", "What gkm dev runs as (e.g. dev)").action(async (name, options) => {
15503
15520
  try {
15504
15521
  const globalOptions = program.opts();
15505
15522
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
@@ -15716,54 +15733,30 @@ program.command("secrets:import").description("Import secrets from a JSON file")
15716
15733
  process.exit(1);
15717
15734
  }
15718
15735
  });
15719
- program.command("secrets:push").description("Push secrets to remote provider (SSM)").requiredOption("--stage <stage>", "Stage name").action(async (options) => {
15736
+ program.command("secrets:push").description("Send a deployed stage's secrets to its store (secrets.store)").requiredOption("--stage <stage>", "A deployed stage").option("--profile <profile>", "AWS profile for the stage's account").action(async (options) => {
15720
15737
  try {
15721
15738
  const globalOptions = program.opts();
15722
15739
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
15723
15740
  const { loadWorkspaceConfig } = await import("./config.mjs");
15724
- const { pushSecrets } = await import("./sync-B3xxXtJT.mjs").then((n) => n.i);
15725
- const { reconcileMissingSecrets } = await import("./reconcile-DhQ00DpU.mjs");
15726
- const { readStageSecrets, writeStageSecrets } = await import("./storage-P_b3w7uj.mjs").then((n) => n.a);
15741
+ const { pushStageSecrets } = await import("./transfer-4A4S2hcw.mjs").then((n) => n.i);
15727
15742
  const { workspace } = await loadWorkspaceConfig();
15728
- const secrets = await readStageSecrets(options.stage, workspace.root);
15729
- if (secrets) {
15730
- const { derivedContainers } = await import("./credentials-BekkKtY_.mjs").then((n) => n.h);
15731
- const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, options.stage));
15732
- if (result) {
15733
- await writeStageSecrets(result.secrets, workspace.root);
15734
- console.log(` Reconciled ${result.addedKeys.length} missing secret(s):`);
15735
- for (const key of result.addedKeys) console.log(` + ${key}`);
15736
- }
15737
- }
15738
- await pushSecrets(options.stage, workspace);
15743
+ const { addedKeys } = await pushStageSecrets(workspace, options.stage, { profile: options.profile });
15744
+ for (const key of addedKeys) console.log(` + ${key} (reconciled)`);
15739
15745
  console.log(`\n✓ Secrets pushed for stage "${options.stage}"`);
15740
15746
  } catch (error) {
15741
15747
  console.error(formatError(error));
15742
15748
  process.exit(1);
15743
15749
  }
15744
15750
  });
15745
- program.command("secrets:pull").description("Pull secrets from remote provider (SSM)").requiredOption("--stage <stage>", "Stage name").action(async (options) => {
15751
+ program.command("secrets:pull").description("Bring a deployed stage's secrets from its store into the local copy").requiredOption("--stage <stage>", "A deployed stage").option("--profile <profile>", "AWS profile for the stage's account").action(async (options) => {
15746
15752
  try {
15747
15753
  const globalOptions = program.opts();
15748
15754
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
15749
15755
  const { loadWorkspaceConfig } = await import("./config.mjs");
15750
- const { pullSecrets } = await import("./sync-B3xxXtJT.mjs").then((n) => n.i);
15751
- const { writeStageSecrets } = await import("./storage-P_b3w7uj.mjs").then((n) => n.a);
15752
- const { reconcileMissingSecrets } = await import("./reconcile-DhQ00DpU.mjs");
15756
+ const { pullStageSecrets } = await import("./transfer-4A4S2hcw.mjs").then((n) => n.i);
15753
15757
  const { workspace } = await loadWorkspaceConfig();
15754
- let secrets = await pullSecrets(options.stage, workspace);
15755
- if (!secrets) {
15756
- console.error(`No remote secrets found for stage "${options.stage}".`);
15757
- process.exit(1);
15758
- }
15759
- const { derivedContainers } = await import("./credentials-BekkKtY_.mjs").then((n) => n.h);
15760
- const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, options.stage));
15761
- if (result) {
15762
- secrets = result.secrets;
15763
- console.log(` Reconciled ${result.addedKeys.length} missing secret(s):`);
15764
- for (const key of result.addedKeys) console.log(` + ${key}`);
15765
- }
15766
- await writeStageSecrets(secrets, workspace.root);
15758
+ const { addedKeys } = await pullStageSecrets(workspace, options.stage, { profile: options.profile });
15759
+ for (const key of addedKeys) console.log(` + ${key} (reconciled)`);
15767
15760
  console.log(`\n✓ Secrets pulled for stage "${options.stage}"`);
15768
15761
  } catch (error) {
15769
15762
  console.error(formatError(error));
@@ -15775,8 +15768,8 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
15775
15768
  const globalOptions = program.opts();
15776
15769
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
15777
15770
  const { loadWorkspaceConfig } = await import("./config.mjs");
15778
- const { reconcileMissingSecrets } = await import("./reconcile-DhQ00DpU.mjs");
15779
- const { readStageSecrets, writeStageSecrets } = await import("./storage-P_b3w7uj.mjs").then((n) => n.a);
15771
+ const { reconcileMissingSecrets } = await import("./reconcile-fmoluZmZ.mjs").then((n) => n.n);
15772
+ const { readStageSecrets, writeStageSecrets } = await import("./storage-TP0x118M.mjs").then((n) => n.a);
15780
15773
  const { workspace } = await loadWorkspaceConfig();
15781
15774
  const stage = options.stage ?? workspace.stages.local;
15782
15775
  const secrets = await readStageSecrets(stage, workspace.root);
@@ -15784,7 +15777,7 @@ program.command("secrets:reconcile").description("Backfill missing custom secret
15784
15777
  console.error(`No secrets found for stage "${stage}". Run "gkm secrets:init --stage ${stage}" first.`);
15785
15778
  process.exit(1);
15786
15779
  }
15787
- const { derivedContainers } = await import("./credentials-BekkKtY_.mjs").then((n) => n.h);
15780
+ const { derivedContainers } = await import("./credentials-fJP5-fa1.mjs").then((n) => n.h);
15788
15781
  const result = reconcileMissingSecrets(secrets, workspace, await derivedContainers(workspace, stage));
15789
15782
  if (!result) {
15790
15783
  console.log(`\n✓ Secrets for stage "${stage}" are up-to-date`);
@@ -15843,7 +15836,7 @@ program.command("deploy:github").description("Let GitHub Actions deploy a stage:
15843
15836
  try {
15844
15837
  const globalOptions = program.opts();
15845
15838
  if (globalOptions.cwd) process.chdir(globalOptions.cwd);
15846
- const { deployGithubCommand } = await import("./github-CRwnxKmD.mjs");
15839
+ const { deployGithubCommand } = await import("./github-CAfKyYPN.mjs");
15847
15840
  await deployGithubCommand(options);
15848
15841
  } catch (error) {
15849
15842
  console.error(formatError(error));