@everystack/cli 0.4.60 → 0.4.61

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 (116) hide show
  1. package/package.json +2 -2
  2. package/src/backfill.ts +3 -3
  3. package/src/cli/alter-type-dependents.ts +1 -1
  4. package/src/cli/apply-authority.ts +1 -1
  5. package/src/cli/apply-execute.ts +10 -10
  6. package/src/cli/audit-api.ts +4 -4
  7. package/src/cli/audit-source-api.ts +2 -2
  8. package/src/cli/authz-adoption-class.ts +4 -4
  9. package/src/cli/authz-baseline.ts +2 -2
  10. package/src/cli/authz-canonical.ts +2 -2
  11. package/src/cli/authz-compile.ts +3 -3
  12. package/src/cli/authz-contract-io.ts +2 -2
  13. package/src/cli/authz-contract.ts +4 -4
  14. package/src/cli/authz-derive.ts +2 -2
  15. package/src/cli/authz-identity.ts +1 -1
  16. package/src/cli/authz-ownership.ts +1 -1
  17. package/src/cli/authz-reconcile.ts +4 -4
  18. package/src/cli/authz-redteam.ts +1 -1
  19. package/src/cli/authz-render.ts +2 -2
  20. package/src/cli/aws.ts +53 -4
  21. package/src/cli/backfill.ts +3 -3
  22. package/src/cli/branch-db.ts +5 -5
  23. package/src/cli/bundle-weight.ts +2 -2
  24. package/src/cli/commands/analyze.ts +2 -2
  25. package/src/cli/commands/audit.ts +10 -10
  26. package/src/cli/commands/bundle.ts +6 -6
  27. package/src/cli/commands/cache.ts +75 -3
  28. package/src/cli/commands/console.ts +6 -6
  29. package/src/cli/commands/db-apply.ts +25 -25
  30. package/src/cli/commands/db-approvers.ts +4 -4
  31. package/src/cli/commands/db-authz.ts +15 -15
  32. package/src/cli/commands/db-backfill.ts +10 -10
  33. package/src/cli/commands/db-backup.ts +7 -7
  34. package/src/cli/commands/db-branch.ts +8 -8
  35. package/src/cli/commands/db-build.ts +7 -7
  36. package/src/cli/commands/db-check.ts +16 -16
  37. package/src/cli/commands/db-diff.ts +6 -6
  38. package/src/cli/commands/db-exec.ts +8 -8
  39. package/src/cli/commands/db-export.ts +10 -10
  40. package/src/cli/commands/db-fingerprint.ts +14 -14
  41. package/src/cli/commands/db-fork.ts +6 -6
  42. package/src/cli/commands/db-generate.ts +19 -19
  43. package/src/cli/commands/db-plan.ts +25 -25
  44. package/src/cli/commands/db-pull.ts +18 -18
  45. package/src/cli/commands/db-reconcile.ts +14 -14
  46. package/src/cli/commands/db-refresh.ts +7 -7
  47. package/src/cli/commands/db-snapshot.ts +5 -5
  48. package/src/cli/commands/db-swap.ts +26 -26
  49. package/src/cli/commands/db-sync.ts +18 -18
  50. package/src/cli/commands/db.ts +15 -15
  51. package/src/cli/commands/deploy.ts +39 -5
  52. package/src/cli/commands/diag.ts +4 -4
  53. package/src/cli/commands/lighthouse.ts +3 -3
  54. package/src/cli/commands/logs.ts +5 -5
  55. package/src/cli/commands/pipeline-run.ts +7 -7
  56. package/src/cli/commands/runbook.ts +5 -5
  57. package/src/cli/commands/secrets.ts +5 -5
  58. package/src/cli/commands/security-probe.ts +4 -4
  59. package/src/cli/commands/security.ts +6 -6
  60. package/src/cli/commands/status.ts +3 -3
  61. package/src/cli/commands/task-probe.ts +4 -4
  62. package/src/cli/commands/ui-audit.ts +5 -5
  63. package/src/cli/commands/update.ts +64 -8
  64. package/src/cli/component-audit.ts +5 -5
  65. package/src/cli/config.ts +2 -2
  66. package/src/cli/db-build.ts +6 -6
  67. package/src/cli/db-source.ts +2 -2
  68. package/src/cli/declared-derived.ts +5 -5
  69. package/src/cli/declared-diff.ts +5 -5
  70. package/src/cli/deploy-probe.ts +3 -3
  71. package/src/cli/derived-apply.ts +5 -5
  72. package/src/cli/derived-compile.ts +4 -4
  73. package/src/cli/derived-grants.ts +1 -1
  74. package/src/cli/derived-introspect.ts +3 -3
  75. package/src/cli/derived-lint.ts +2 -2
  76. package/src/cli/derived-plan.ts +5 -5
  77. package/src/cli/derived-render.ts +6 -6
  78. package/src/cli/direct-venue.ts +2 -2
  79. package/src/cli/discover.ts +2 -2
  80. package/src/cli/edge-plan.ts +8 -8
  81. package/src/cli/exec-digest.ts +1 -1
  82. package/src/cli/exec-execute.ts +1 -1
  83. package/src/cli/exec-log.ts +1 -1
  84. package/src/cli/exec-run.ts +2 -2
  85. package/src/cli/git-descent.ts +5 -5
  86. package/src/cli/index.ts +46 -46
  87. package/src/cli/migration-compile.ts +7 -7
  88. package/src/cli/migration-generate.ts +6 -6
  89. package/src/cli/model-api.ts +16 -16
  90. package/src/cli/model-render.ts +6 -6
  91. package/src/cli/mutation-lease.ts +1 -1
  92. package/src/cli/observability.ts +1 -1
  93. package/src/cli/refresh-execute.ts +2 -2
  94. package/src/cli/runbook/generate.ts +3 -3
  95. package/src/cli/runbook/index.ts +7 -7
  96. package/src/cli/runbook/sections.ts +2 -2
  97. package/src/cli/schema-compile.ts +4 -4
  98. package/src/cli/schema-diff.ts +1 -1
  99. package/src/cli/schema-fingerprint.ts +7 -7
  100. package/src/cli/schema-introspect.ts +3 -3
  101. package/src/cli/schema-source.ts +1 -1
  102. package/src/cli/schema-swap.ts +4 -4
  103. package/src/cli/security-catalog.ts +1 -1
  104. package/src/cli/stage-backup.ts +3 -3
  105. package/src/cli/stage-read-consistency.ts +6 -6
  106. package/src/cli/state-apply.ts +7 -7
  107. package/src/cli/swap-execute.ts +3 -3
  108. package/src/cli/swap-heartbeat.ts +1 -1
  109. package/src/cli/swap-pair.ts +7 -7
  110. package/src/cli/task-poll.ts +2 -2
  111. package/src/cli/ui-bloat.ts +1 -1
  112. package/src/cli/utils/secrets.ts +1 -1
  113. package/src/exec.ts +7 -7
  114. package/src/reconcile.ts +2 -2
  115. package/src/refresh.ts +2 -2
  116. package/src/sst.ts +1 -1
@@ -29,10 +29,10 @@
29
29
  * runs it direct. A stage DRY-RUN (no `--apply`) reads through the `db:query` path.
30
30
  */
31
31
 
32
- import type { QueryRunner } from '../authz-contract.js';
33
- import type { SourceObject } from '../derived-source.js';
34
- import { introspectDerived } from '../derived-introspect.js';
35
- import { planReconcile, type ReconcilePlan, type ReconcileOptions } from '../derived-plan.js';
32
+ import type { QueryRunner } from '../authz-contract';
33
+ import type { SourceObject } from '../derived-source';
34
+ import { introspectDerived } from '../derived-introspect';
35
+ import { planReconcile, type ReconcilePlan, type ReconcileOptions } from '../derived-plan';
36
36
  import {
37
37
  renderReconcileSql,
38
38
  renderProvenanceUpsert,
@@ -49,16 +49,16 @@ import {
49
49
  builderOwnerMode,
50
50
  type OwnerApplyMode,
51
51
  ENSURE_RECONCILER_SQL,
52
- } from '../derived-apply.js';
53
- import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source.js';
54
- import { borrowedSessionRunner, type SessionRunner } from '../session.js';
55
- import { resolveOperatorUrlViaStage } from '../direct-venue.js';
56
- import { withMutationLease, MutationLeaseError } from '../mutation-lease.js';
57
- import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived.js';
58
- import { currentGitRef } from '../state-apply.js';
59
- import { resolveConfig, opsFunction } from '../config.js';
60
- import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws.js';
61
- import { step, success, fail, info, warn } from '../output.js';
52
+ } from '../derived-apply';
53
+ import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
54
+ import { borrowedSessionRunner, type SessionRunner } from '../session';
55
+ import { resolveOperatorUrlViaStage } from '../direct-venue';
56
+ import { withMutationLease, MutationLeaseError } from '../mutation-lease';
57
+ import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
58
+ import { currentGitRef } from '../state-apply';
59
+ import { resolveConfig, opsFunction } from '../config';
60
+ import { invokeAction, lambdaQueryRunner, lambdaSessionRunner } from '../aws';
61
+ import { step, success, fail, info, warn } from '../output';
62
62
 
63
63
  // ---------------------------------------------------------------------------
64
64
  // The testable core.
@@ -23,13 +23,13 @@
23
23
  * they did not choose.
24
24
  */
25
25
 
26
- import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source.js';
27
- import { loadDeclaredDerived } from '../declared-derived.js';
28
- import { executeRefresh, matviewIdentities, type RefreshRun } from '../refresh-execute.js';
29
- import { resolveConfig, opsFunction } from '../config.js';
30
- import { resolveOperatorUrlViaStage } from '../direct-venue.js';
31
- import { invokeAction } from '../aws.js';
32
- import { step, success, fail, info } from '../output.js';
26
+ import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
27
+ import { loadDeclaredDerived } from '../declared-derived';
28
+ import { executeRefresh, matviewIdentities, type RefreshRun } from '../refresh-execute';
29
+ import { resolveConfig, opsFunction } from '../config';
30
+ import { resolveOperatorUrlViaStage } from '../direct-venue';
31
+ import { invokeAction } from '../aws';
32
+ import { step, success, fail, info } from '../output';
33
33
 
34
34
  export async function dbRefreshCommand(flags: Record<string, string>): Promise<void> {
35
35
  // The declared matviews, in dependency order (a dependent matview reads its parents' fresh rows).
@@ -7,11 +7,11 @@
7
7
  * docs/plans/db-backup-restore.md.
8
8
  */
9
9
 
10
- import { resolveConfig, type CliConfig } from '../config.js';
11
- import { createRdsSnapshot, describeRdsSnapshots, type RdsSnapshotSummary } from '../aws.js';
12
- import { utcStamp } from '../backup.js';
13
- import { rdsSnapshotIdentifier } from '../rds-snapshot.js';
14
- import { step, success, fail, info } from '../output.js';
10
+ import { resolveConfig, type CliConfig } from '../config';
11
+ import { createRdsSnapshot, describeRdsSnapshots, type RdsSnapshotSummary } from '../aws';
12
+ import { utcStamp } from '../backup';
13
+ import { rdsSnapshotIdentifier } from '../rds-snapshot';
14
+ import { step, success, fail, info } from '../output';
15
15
 
16
16
  /**
17
17
  * Resolve the RDS DB instance identifier: explicit `--instance` wins, else the deployed
@@ -22,32 +22,32 @@ import { Transform } from 'node:stream';
22
22
  import { pipeline } from 'node:stream/promises';
23
23
  import { Readable } from 'node:stream';
24
24
  import type { ModelDescriptor } from '@everystack/model';
25
- import { fingerprintModels } from '../schema-fingerprint.js';
26
- import { resolveModelsPath } from '../models-path.js';
27
- import { loadModels } from './db-generate.js';
28
- import { loadDeclaredDerived } from '../declared-derived.js';
29
- import type { SourceObject } from '../derived-source.js';
30
- import { pairedDerivedSchemas, renderPairedDerivedBuild, renderSwapSchemaUsage, swapSchemaRoles, expectedIncomingObjects, renderPairedProvenance } from '../swap-pair.js';
31
- import { introspectDerived } from '../derived-introspect.js';
32
- import { legacyFunctionIdentity } from '../pg-argtypes.js';
33
- import { createUrlRunner } from '../db-source.js';
34
- import { borrowedSessionRunner, type SessionRunner } from '../session.js';
35
- import type { QueryRunner } from '../authz-contract.js';
36
- import { executeSwap, type SwapVerdict } from '../swap-execute.js';
37
- import { startHeartbeat, humanElapsed } from '../swap-heartbeat.js';
38
- import { formatBytes } from '../bundle-weight.js';
39
- import { rewriteStatementLine, opensCopyData, closesCopyData } from '../schema-rewrite.js';
40
- import { resolveOperatorUrlViaStage } from '../direct-venue.js';
41
- import { withMutationLease, MutationLeaseError } from '../mutation-lease.js';
42
- import { resolveConfig, opsFunction, type CliConfig } from '../config.js';
43
- import { invokeAction, presignGet, createRdsSnapshot, describeRdsSnapshots } from '../aws.js';
44
- import { keyForArtifactId, metaKey, utcStamp } from '../backup.js';
45
- import { rdsSnapshotIdentifier } from '../rds-snapshot.js';
46
- import { pollTaskUntilStopped } from '../task-poll.js';
47
- import { decideSnapshotMode, confirmPhysicalSnapshot, interpretBackupPoll, type SnapshotModeRequest } from '../swap-snapshot.js';
48
- import { runStageBackup, stageBackupDeps } from '../stage-backup.js';
49
- import { pgEnvFromUrl, pgKeepaliveConninfo } from './db.js';
50
- import { step, success, fail, warn, info } from '../output.js';
25
+ import { fingerprintModels } from '../schema-fingerprint';
26
+ import { resolveModelsPath } from '../models-path';
27
+ import { loadModels } from './db-generate';
28
+ import { loadDeclaredDerived } from '../declared-derived';
29
+ import type { SourceObject } from '../derived-source';
30
+ import { pairedDerivedSchemas, renderPairedDerivedBuild, renderSwapSchemaUsage, swapSchemaRoles, expectedIncomingObjects, renderPairedProvenance } from '../swap-pair';
31
+ import { introspectDerived } from '../derived-introspect';
32
+ import { legacyFunctionIdentity } from '../pg-argtypes';
33
+ import { createUrlRunner } from '../db-source';
34
+ import { borrowedSessionRunner, type SessionRunner } from '../session';
35
+ import type { QueryRunner } from '../authz-contract';
36
+ import { executeSwap, type SwapVerdict } from '../swap-execute';
37
+ import { startHeartbeat, humanElapsed } from '../swap-heartbeat';
38
+ import { formatBytes } from '../bundle-weight';
39
+ import { rewriteStatementLine, opensCopyData, closesCopyData } from '../schema-rewrite';
40
+ import { resolveOperatorUrlViaStage } from '../direct-venue';
41
+ import { withMutationLease, MutationLeaseError } from '../mutation-lease';
42
+ import { resolveConfig, opsFunction, type CliConfig } from '../config';
43
+ import { invokeAction, presignGet, createRdsSnapshot, describeRdsSnapshots } from '../aws';
44
+ import { keyForArtifactId, metaKey, utcStamp } from '../backup';
45
+ import { rdsSnapshotIdentifier } from '../rds-snapshot';
46
+ import { pollTaskUntilStopped } from '../task-poll';
47
+ import { decideSnapshotMode, confirmPhysicalSnapshot, interpretBackupPoll, type SnapshotModeRequest } from '../swap-snapshot';
48
+ import { runStageBackup, stageBackupDeps } from '../stage-backup';
49
+ import { pgEnvFromUrl, pgKeepaliveConninfo } from './db';
50
+ import { step, success, fail, warn, info } from '../output';
51
51
 
52
52
  /** A COPY-aware line transform that rewrites the schema token on statement lines only. */
53
53
  function schemaRewriteStream(from: string, to: string): Transform {
@@ -30,12 +30,12 @@
30
30
  import fs from 'node:fs/promises';
31
31
  import path from 'node:path';
32
32
  import type { ModelDescriptor } from '@everystack/model';
33
- import { introspectContract, type QueryRunner } from '../authz-contract.js';
34
- import { introspectSchema } from '../schema-introspect.js';
35
- import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog.js';
36
- import { generateMigrationSql, unmodeledTables } from '../migration-generate.js';
33
+ import { introspectContract, type QueryRunner } from '../authz-contract';
34
+ import { introspectSchema } from '../schema-introspect';
35
+ import { FUNCTIONS_SQL, contractFunctionRow } from '../security-catalog';
36
+ import { generateMigrationSql, unmodeledTables } from '../migration-generate';
37
37
  import type { SequenceDescriptor } from '@everystack/model';
38
- import type { SourceObject } from '../derived-source.js';
38
+ import type { SourceObject } from '../derived-source';
39
39
  import {
40
40
  applyStateAndVerify,
41
41
  classifyGeneratedStatements,
@@ -43,19 +43,19 @@ import {
43
43
  currentGitRef,
44
44
  type ClassifiedStatements,
45
45
  type StateSyncOutcome,
46
- } from '../state-apply.js';
47
- import { fingerprintModels } from '../schema-fingerprint.js';
48
- import { compileDrizzleSource } from '../schema-source.js';
49
- import type { SourceFile } from '../derived-source.js';
50
- import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source.js';
51
- import { borrowedSessionRunner, type SessionRunner } from '../session.js';
52
- import { planBackfills, readBackfillLog } from '../backfill.js';
53
- import { resolveModelsPath } from '../models-path.js';
54
- import { executeReconcile, buildReconcileReport, type ReconcileRun } from './db-reconcile.js';
55
- import { loadModels } from './db-generate.js';
56
- import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived.js';
57
- import { reportPipelineLastRun } from './pipeline-run.js';
58
- import { step, success, fail, info, warn } from '../output.js';
46
+ } from '../state-apply';
47
+ import { fingerprintModels } from '../schema-fingerprint';
48
+ import { compileDrizzleSource } from '../schema-source';
49
+ import type { SourceFile } from '../derived-source';
50
+ import { resolveDbSource, createUrlRunner, connectingVia, type DbSource } from '../db-source';
51
+ import { borrowedSessionRunner, type SessionRunner } from '../session';
52
+ import { planBackfills, readBackfillLog } from '../backfill';
53
+ import { resolveModelsPath } from '../models-path';
54
+ import { executeReconcile, buildReconcileReport, type ReconcileRun } from './db-reconcile';
55
+ import { loadModels } from './db-generate';
56
+ import { loadDeclaredDerived, retiredSqlDirAnywhere, retiredSqlDirFlagRefusal, type DeclaredDerived } from '../declared-derived';
57
+ import { reportPipelineLastRun } from './pipeline-run';
58
+ import { step, success, fail, info, warn } from '../output';
59
59
 
60
60
  const DEFAULT_SCHEMA_OUT = 'db/schema.generated.ts';
61
61
 
@@ -5,10 +5,10 @@
5
5
  * No HTTP endpoints, no shared secrets — IAM is the authorization layer.
6
6
  */
7
7
 
8
- import { resolveConfig, opsFunction } from '../config.js';
9
- import { invokeAction } from '../aws.js';
10
- import { step, success, fail, info, warn } from '../output.js';
11
- import { opsAdviceLines, IAM_ADVICE } from '../ops-advice.js';
8
+ import { resolveConfig, opsFunction } from '../config';
9
+ import { invokeAction } from '../aws';
10
+ import { step, success, fail, info, warn } from '../output';
11
+ import { opsAdviceLines, IAM_ADVICE } from '../ops-advice';
12
12
 
13
13
  /** Secret-store keys that may hold the privileged (operator) connection URL,
14
14
  * in precedence order. Names vary by deployment; --secret-name overrides. */
@@ -488,8 +488,8 @@ export async function dbProvisionCommand(flags: Record<string, string>): Promise
488
488
 
489
489
  // Load the stage secrets once — the direct venue reads the privileged URL from here (never
490
490
  // from argv), and the writer below reuses them.
491
- const { loadSstSecrets, putSstSecrets } = await import('../utils/secrets.js');
492
- const { parseAppName } = await import('../discover.js');
491
+ const { loadSstSecrets, putSstSecrets } = await import('../utils/secrets');
492
+ const { parseAppName } = await import('../discover');
493
493
  const secretsCtx = { appName: await parseAppName(), stage: flags.stage, region: config.region };
494
494
  let stageSecrets: Record<string, string> = {};
495
495
  try {
@@ -527,12 +527,12 @@ export async function dbProvisionCommand(flags: Record<string, string>): Promise
527
527
  // all-public app sets no path (unchanged behavior).
528
528
  let declaredSchemas: string[] = [];
529
529
  try {
530
- const { resolveModelsPath } = await import('../models-path.js');
531
- const { loadModels } = await import('./db-generate.js');
530
+ const { resolveModelsPath } = await import('../models-path');
531
+ const { loadModels } = await import('./db-generate');
532
532
  const models = await loadModels(resolveModelsPath(flags.models));
533
533
  let derivedObjects: Array<{ schema: string }> = [];
534
534
  try {
535
- const { loadDeclaredDerived } = await import('../declared-derived.js');
535
+ const { loadDeclaredDerived } = await import('../declared-derived');
536
536
  const declared = await loadDeclaredDerived(flags.models);
537
537
  if (declared) derivedObjects = declared.objects;
538
538
  } catch {
@@ -555,7 +555,7 @@ export async function dbProvisionCommand(flags: Record<string, string>): Promise
555
555
  // and the auto-fallback below.
556
556
  const provisionDirect = async (url: string): Promise<any> => {
557
557
  const { runProvision } = await loadServerProvision();
558
- const { createUrlRunner } = await import('../db-source.js');
558
+ const { createUrlRunner } = await import('../db-source');
559
559
  const { runner, end } = await createUrlRunner(url);
560
560
  try {
561
561
  return await runProvision({ authPassword, adminPassword, searchPath }, {
@@ -746,7 +746,7 @@ function printDoctorReport(report: any): void {
746
746
  */
747
747
  async function runDoctorDirect(apiUrl: string, adminUrl: string, sourceLabel: string): Promise<boolean> {
748
748
  const { runDoctorProbe } = await loadServerDoctor();
749
- const { createUrlRunner } = await import('../db-source.js');
749
+ const { createUrlRunner } = await import('../db-source');
750
750
  step('Probing database connections (api + operator)...');
751
751
  const apiConn = await createUrlRunner(apiUrl);
752
752
  const opsConn = await createUrlRunner(adminUrl);
@@ -797,8 +797,8 @@ export async function dbDoctorCommand(flags: Record<string, string>): Promise<vo
797
797
 
798
798
  // Load the stage secrets once — the direct venue (--direct, and the no-Ops auto-fallback)
799
799
  // reads DATABASE_URL + ADMIN_DATABASE_URL from here, never from argv.
800
- const { loadSstSecrets } = await import('../utils/secrets.js');
801
- const { parseAppName } = await import('../discover.js');
800
+ const { loadSstSecrets } = await import('../utils/secrets');
801
+ const { parseAppName } = await import('../discover');
802
802
  let stageSecrets: Record<string, string> = {};
803
803
  try {
804
804
  stageSecrets = await loadSstSecrets({ appName: await parseAppName(), stage: flags.stage, region: config.region });
@@ -957,8 +957,8 @@ export async function dbPsqlCommand(flags: Record<string, string>): Promise<void
957
957
  step('Resolving the admin connection from the secret store...');
958
958
  let secrets: Record<string, string>;
959
959
  try {
960
- const { loadSstSecrets } = await import('../utils/secrets.js');
961
- const { parseAppName } = await import('../discover.js');
960
+ const { loadSstSecrets } = await import('../utils/secrets');
961
+ const { parseAppName } = await import('../discover');
962
962
  const appName = await parseAppName();
963
963
  secrets = await loadSstSecrets({ appName, stage: flags.stage, region: config.region });
964
964
  } catch (err: any) {
@@ -11,10 +11,11 @@
11
11
  */
12
12
 
13
13
  import { spawn } from 'node:child_process';
14
- import { step, success, fail, info, warn } from '../output.js';
15
- import { invalidateCachedConfig } from '../discover.js';
16
- import { resolveConfig } from '../config.js';
17
- import { probeDeployedFunctions } from '../deploy-probe.js';
14
+ import { step, success, fail, info, warn } from '../output';
15
+ import { invalidateCachedConfig } from '../discover';
16
+ import { resolveConfig } from '../config';
17
+ import { probeDeployedFunctions } from '../deploy-probe';
18
+ import { getDistributionStatus } from '../aws';
18
19
 
19
20
  /** The `sst` argv `everystack deploy` runs. Pure, so the mapping is unit-tested. */
20
21
  export function buildDeployArgs(flags: Record<string, string>): string[] {
@@ -68,8 +69,9 @@ export async function deployCommand(flags: Record<string, string>): Promise<void
68
69
  // `sst deploy` exiting 0 only proves the code UPLOADED — a bundle that crashes at INIT still
69
70
  // deploys "green" and takes the whole ops plane down until the next verb trips over it. Probe
70
71
  // the deployed functions now so the operator learns here, with the real cause attached.
72
+ let config: Awaited<ReturnType<typeof resolveConfig>> | undefined;
71
73
  try {
72
- const config = await resolveConfig(stage);
74
+ config = await resolveConfig(stage);
73
75
  const { fatal } = await probeDeployedFunctions(stage, config);
74
76
  if (fatal) {
75
77
  fail('Deploy landed, but a deployed function cannot serve — every --stage verb will fail until this is fixed and redeployed.');
@@ -81,8 +83,40 @@ export async function deployCommand(flags: Record<string, string>): Promise<void
81
83
  info(`Skipped the post-deploy probe: ${err?.message ?? err}`);
82
84
  }
83
85
 
86
+ // Wait for CloudFront distribution to finish propagating.
87
+ if (config?.distributionId) {
88
+ step('Waiting for CloudFront distribution...');
89
+ const deployed = await waitForDistribution(config.region, config.distributionId);
90
+ if (deployed) {
91
+ success('Distribution deployed.');
92
+ } else {
93
+ warn('Distribution did not reach Deployed within timeout. It may still be propagating.');
94
+ }
95
+ }
96
+
84
97
  // The 0.4 flow: schema changes ride db:plan → db:apply. Migration-based apps still have
85
98
  // db:migrate, but the copy-paste hint must advertise the canonical path — this exact
86
99
  // line got copied into consumer runbooks with the retired verb.
87
100
  info('Next: schema changes via `everystack db:plan --stage ' + stage + '` → `db:apply`; `everystack update` to publish the app bundle.');
88
101
  }
102
+
103
+ const DISTRIBUTION_POLL_MS = 10_000;
104
+ const DISTRIBUTION_TIMEOUT_MS = 300_000;
105
+
106
+ /** @internal Exported for testing. */
107
+ export async function waitForDistribution(
108
+ region: string,
109
+ distributionId: string,
110
+ ): Promise<boolean> {
111
+ const deadline = Date.now() + DISTRIBUTION_TIMEOUT_MS;
112
+ while (Date.now() < deadline) {
113
+ try {
114
+ const status = await getDistributionStatus(region, distributionId);
115
+ if (status === 'Deployed') return true;
116
+ } catch {
117
+ // Permission error or transient — keep trying.
118
+ }
119
+ await new Promise((r) => setTimeout(r, DISTRIBUTION_POLL_MS));
120
+ }
121
+ return false;
122
+ }
@@ -13,10 +13,10 @@
13
13
  * everystack diag [url] --hydration # Analyze SSR hydration issues
14
14
  */
15
15
 
16
- import { resolveConfig } from '../config.js';
17
- import { getFromS3 } from '../aws.js';
18
- import { step, success, fail, info, warn } from '../output.js';
19
- import { analyzeHtml, generateHydrationReport } from '../hydration-analyzer.js';
16
+ import { resolveConfig } from '../config';
17
+ import { getFromS3 } from '../aws';
18
+ import { step, success, fail, info, warn } from '../output';
19
+ import { analyzeHtml, generateHydrationReport } from '../hydration-analyzer';
20
20
 
21
21
  interface DiagResult {
22
22
  url: string;
@@ -20,9 +20,9 @@ import {
20
20
  formatLighthouseReport,
21
21
  type ExtractedRun,
22
22
  type LhReport,
23
- } from '../lighthouse.js';
24
- import { resolveConfig } from '../config.js';
25
- import { step, info, fail, warn } from '../output.js';
23
+ } from '../lighthouse';
24
+ import { resolveConfig } from '../config';
25
+ import { step, info, fail, warn } from '../output';
26
26
 
27
27
  function runLighthouse(url: string, outPath: string): LhReport {
28
28
  // Warm the edge so we measure the real-user (cached-HTML) experience.
@@ -10,11 +10,11 @@
10
10
  * immune to the Lambda hash rotating on redeploy.
11
11
  */
12
12
 
13
- import { resolveConfig } from '../config.js';
14
- import { resolveLogGroup, fetchRecentLogEvents, importOptionalAws } from '../aws.js';
15
- import { summarizeRuntimeFailures } from '../ops-diagnostics.js';
16
- import { queryLogArchive, type ObservabilityQuery } from '../observability.js';
17
- import { step, success, fail, info } from '../output.js';
13
+ import { resolveConfig } from '../config';
14
+ import { resolveLogGroup, fetchRecentLogEvents, importOptionalAws } from '../aws';
15
+ import { summarizeRuntimeFailures } from '../ops-diagnostics';
16
+ import { queryLogArchive, type ObservabilityQuery } from '../observability';
17
+ import { step, success, fail, info } from '../output';
18
18
 
19
19
  /** Default S3 key prefix for the observability archive (loggingPlugin default). */
20
20
  const DEFAULT_PREFIX = '_observability';
@@ -18,19 +18,19 @@ import { randomUUID } from 'node:crypto';
18
18
  import { existsSync } from 'node:fs';
19
19
  import path from 'node:path';
20
20
  import { pathToFileURL } from 'node:url';
21
- import { resolveDbSource, createUrlPipelineRunner, connectingVia, type DbSource } from '../db-source.js';
22
- import { resolvePipelinePath, PIPELINE_HOMES } from '../pipeline-path.js';
23
- import { resolveConfig, opsFunction } from '../config.js';
24
- import { invokeAction } from '../aws.js';
25
- import { currentGitRef } from '../state-apply.js';
26
- import { step, success, fail, info, warn } from '../output.js';
21
+ import { resolveDbSource, createUrlPipelineRunner, connectingVia, type DbSource } from '../db-source';
22
+ import { resolvePipelinePath, PIPELINE_HOMES } from '../pipeline-path';
23
+ import { resolveConfig, opsFunction } from '../config';
24
+ import { invokeAction } from '../aws';
25
+ import { currentGitRef } from '../state-apply';
26
+ import { step, success, fail, info, warn } from '../output';
27
27
  import {
28
28
  loadServerPipeline,
29
29
  type Pipeline,
30
30
  type PipelineLane,
31
31
  type RunPipelineOptions,
32
32
  type PipelineRunOutcome,
33
- } from '../pipeline-loader.js';
33
+ } from '../pipeline-loader';
34
34
 
35
35
  /** --rebuild → rebuild, --curate → curate, neither → all. Both is a contradiction. */
36
36
  export function pipelineLaneFromFlags(flags: Record<string, string>): PipelineLane {
@@ -16,11 +16,11 @@
16
16
  import fs from 'node:fs';
17
17
  import path from 'node:path';
18
18
  import { pathToFileURL } from 'node:url';
19
- import { detectProjectReality } from '../runbook/detect.js';
20
- import { generateRunbook, type RunbookResult } from '../runbook/generate.js';
21
- import { renderDataModelSection } from '../runbook/model-section.js';
22
- import { parseRunbook, sha8 } from '../runbook/markers.js';
23
- import { fail, info, step, success, warn } from '../output.js';
19
+ import { detectProjectReality } from '../runbook/detect';
20
+ import { generateRunbook, type RunbookResult } from '../runbook/generate';
21
+ import { renderDataModelSection } from '../runbook/model-section';
22
+ import { parseRunbook, sha8 } from '../runbook/markers';
23
+ import { fail, info, step, success, warn } from '../output';
24
24
 
25
25
  const OUT_REL = path.join('docs', 'RUNBOOK.md');
26
26
 
@@ -15,10 +15,10 @@
15
15
 
16
16
  import fs from 'node:fs/promises';
17
17
  import path from 'node:path';
18
- import { step, success, fail, info, warn } from '../output.js';
19
- import { loadSstSecrets, putSstSecrets } from '../utils/secrets.js';
20
- import { parseDotenv, serializeDotenv } from '../utils/dotenv.js';
21
- import { isMissingOptionalDependencyError } from '../aws.js';
18
+ import { step, success, fail, info, warn } from '../output';
19
+ import { loadSstSecrets, putSstSecrets } from '../utils/secrets';
20
+ import { parseDotenv, serializeDotenv } from '../utils/dotenv';
21
+ import { isMissingOptionalDependencyError } from '../aws';
22
22
 
23
23
  interface SecretsContext {
24
24
  appName: string;
@@ -34,7 +34,7 @@ async function resolveContext(flags: Record<string, string>): Promise<SecretsCon
34
34
  process.exit(1);
35
35
  }
36
36
 
37
- const { parseAppName } = await import('../discover.js');
37
+ const { parseAppName } = await import('../discover');
38
38
  const appName = await parseAppName();
39
39
  const region = process.env.AWS_REGION || process.env.AWS_DEFAULT_REGION || 'us-east-1';
40
40
 
@@ -25,10 +25,10 @@ import {
25
25
  type CatalogColumn,
26
26
  type CatalogGrant,
27
27
  type ProbeResult,
28
- } from '../security-probe.js';
29
- import { resolveConfig, opsFunction } from '../config.js';
30
- import { invokeAction } from '../aws.js';
31
- import { step, info, fail, success, warn } from '../output.js';
28
+ } from '../security-probe';
29
+ import { resolveConfig, opsFunction } from '../config';
30
+ import { invokeAction } from '../aws';
31
+ import { step, info, fail, success, warn } from '../output';
32
32
 
33
33
  const SYS_SCHEMAS = "('pg_catalog','information_schema','pg_toast')";
34
34
 
@@ -22,17 +22,17 @@ import {
22
22
  type AuditReport,
23
23
  type FunctionDescriptor,
24
24
  type ViewDescriptor,
25
- } from '../security-audit.js';
25
+ } from '../security-audit';
26
26
  import {
27
27
  FUNCTIONS_SQL,
28
28
  RELATIONS_SQL,
29
29
  catalogFunctionToDescriptor,
30
30
  catalogRelationToDescriptor,
31
- } from '../security-catalog.js';
32
- import { SCHEMA_ACL_SQL, parseSchemaAcl } from '../authz-contract.js';
33
- import { resolveConfig, opsFunction } from '../config.js';
34
- import { invokeAction } from '../aws.js';
35
- import { step, success, fail, info, warn } from '../output.js';
31
+ } from '../security-catalog';
32
+ import { SCHEMA_ACL_SQL, parseSchemaAcl } from '../authz-contract';
33
+ import { resolveConfig, opsFunction } from '../config';
34
+ import { invokeAction } from '../aws';
35
+ import { step, success, fail, info, warn } from '../output';
36
36
 
37
37
  const MIGRATION_DIRS = ['drizzle', 'db/migrations', 'migrations', 'db/drizzle'];
38
38
  const WAIVER_FILES = ['security-audit.json', '.security-audit.json'];
@@ -11,9 +11,9 @@
11
11
  * CDN and Lambda metrics still work with nothing but IAM credentials.
12
12
  */
13
13
 
14
- import { resolveConfig, opsFunction, type CliConfig } from '../config.js';
15
- import { invokeAction, importOptionalAws } from '../aws.js';
16
- import { fail, info, step } from '../output.js';
14
+ import { resolveConfig, opsFunction, type CliConfig } from '../config';
15
+ import { invokeAction, importOptionalAws } from '../aws';
16
+ import { fail, info, step } from '../output';
17
17
 
18
18
  export interface MetricSpec {
19
19
  namespace: string;
@@ -11,10 +11,10 @@
11
11
  * run id so the operator can reconcile (the task_log row + ECS both carry it).
12
12
  */
13
13
 
14
- import { resolveConfig, opsFunction } from '../config.js';
15
- import { invokeAction } from '../aws.js';
16
- import { pollTaskUntilStopped } from '../task-poll.js';
17
- import { step, success, fail, info } from '../output.js';
14
+ import { resolveConfig, opsFunction } from '../config';
15
+ import { invokeAction } from '../aws';
16
+ import { pollTaskUntilStopped } from '../task-poll';
17
+ import { step, success, fail, info } from '../output';
18
18
 
19
19
  const DEADLINE_MS = 10 * 60_000; // 10 min — Fargate cold start + pull + handshake, with headroom.
20
20
 
@@ -14,11 +14,11 @@
14
14
 
15
15
  import fs from 'node:fs';
16
16
  import path from 'node:path';
17
- import { discoverComponents } from '../component-model.js';
18
- import { auditComponents } from '../component-audit.js';
19
- import { resolveUiBloatBudget } from '../ui-bloat.js';
20
- import { summarize, type AuditFinding } from '../bundle-audit.js';
21
- import { fail, info, step, success, warn } from '../output.js';
17
+ import { discoverComponents } from '../component-model';
18
+ import { auditComponents } from '../component-audit';
19
+ import { resolveUiBloatBudget } from '../ui-bloat';
20
+ import { summarize, type AuditFinding } from '../bundle-audit';
21
+ import { fail, info, step, success, warn } from '../output';
22
22
 
23
23
  export interface UiAuditResult {
24
24
  findings: AuditFinding[];