@happyvertical/smrt-cli 0.51.11 → 0.51.13

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.
@@ -36,6 +36,8 @@ var SENSITIVE_QUERY_PARAMS = /* @__PURE__ */ new Set([
36
36
  "password",
37
37
  "token"
38
38
  ]);
39
+ var CONNECTION_STRING_USERINFO_PATTERN = /([a-z][a-z0-9+.-]*:\/\/[^:\s/@]*:)[^\n]*@/gi;
40
+ var SENSITIVE_QUERY_PARAM_PATTERN = /([?&](?:access_token|apikey|api_key|auth|auth_token|password|token)=)[^&\s]+/gi;
39
41
  function redactConnectionString(value) {
40
42
  let redacted = value;
41
43
  try {
@@ -44,9 +46,25 @@ function redactConnectionString(value) {
44
46
  for (const key of [...url.searchParams.keys()]) if (SENSITIVE_QUERY_PARAMS.has(key.toLowerCase())) url.searchParams.set(key, "***");
45
47
  redacted = url.toString();
46
48
  } catch {
47
- redacted = value.replace(/([a-z][a-z0-9+.-]*:\/\/[^:\s/@]+:)[^@\s]+(@)/gi, "$1***$2");
49
+ redacted = value.replace(CONNECTION_STRING_USERINFO_PATTERN, "$1***@");
48
50
  }
49
- return redacted.replace(/([?&](?:access_token|apikey|api_key|auth|auth_token|password|token)=)[^&\s]+/gi, "$1***");
51
+ return redacted.replace(SENSITIVE_QUERY_PARAM_PATTERN, "$1***");
52
+ }
53
+ /**
54
+ * Redact connection-string credentials embedded anywhere inside arbitrary
55
+ * text, rather than a standalone URL value.
56
+ *
57
+ * Command failure paths surface driver/error text (`error.message`,
58
+ * `error.stack`, wrapped `originalError`/`sql` context) that can itself
59
+ * contain the connection string a command was given — for example a
60
+ * malformed-URL parse error, or a client library that echoes the DSN it
61
+ * tried. `redactConnectionString` expects its whole input to parse as a URL;
62
+ * this scrubs matches wherever they occur in a larger, unknown-shaped string
63
+ * and never throws.
64
+ */
65
+ function redactConnectionStringsInText(text) {
66
+ if (!text) return text;
67
+ return text.replace(CONNECTION_STRING_USERINFO_PATTERN, "$1***@").replace(SENSITIVE_QUERY_PARAM_PATTERN, "$1***");
50
68
  }
51
69
  /**
52
70
  * Quote a SQL identifier (table name, column name, etc.).
@@ -204,10 +222,10 @@ var configExportCommand = {
204
222
  console.log(" };");
205
223
  console.log("");
206
224
  } catch (error) {
207
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
225
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
208
226
  else {
209
227
  console.error("\n❌ Failed to export configuration:");
210
- if (error instanceof Error) console.error(` ${error.message}`);
228
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
211
229
  }
212
230
  process.exitCode = 1;
213
231
  return;
@@ -1402,10 +1420,10 @@ var dbDiffCommand = {
1402
1420
  console.log("\n💡 Schema migrations are manifest-driven.");
1403
1421
  console.log(" Update @smrt object definitions, then run smrt db:migrate.\n");
1404
1422
  } catch (error) {
1405
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
1423
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
1406
1424
  else {
1407
1425
  console.error("\n❌ Failed to generate diff:");
1408
- if (error instanceof Error) console.error(` ${error.message}`);
1426
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
1409
1427
  }
1410
1428
  process.exitCode = 1;
1411
1429
  return;
@@ -1609,7 +1627,11 @@ var dbHistoryCommand = {
1609
1627
  failedAssessments = assessFailedMigrations(failedHistory, null);
1610
1628
  }
1611
1629
  const failedAssessmentsByName = new Map(failedAssessments.map((item) => [item.name, item]));
1612
- const annotatedHistory = history.map((m) => {
1630
+ const annotatedHistory = history.map((row) => {
1631
+ const m = {
1632
+ ...row,
1633
+ error_message: row.error_message ? redactConnectionStringsInText(row.error_message) : row.error_message
1634
+ };
1613
1635
  if (m.status !== "failed") return {
1614
1636
  ...m,
1615
1637
  classification: null,
@@ -1708,10 +1730,10 @@ var dbHistoryCommand = {
1708
1730
  console.log(" smrt db:rollback - Rollback migrations");
1709
1731
  console.log();
1710
1732
  } catch (error) {
1711
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
1733
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
1712
1734
  else {
1713
1735
  console.error("\n❌ Failed to get migration history:");
1714
- if (error instanceof Error) console.error(` ${error.message}`);
1736
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
1715
1737
  }
1716
1738
  process.exitCode = 1;
1717
1739
  return;
@@ -1763,6 +1785,21 @@ function formatOrphanCountLine(count) {
1763
1785
  const marker = count.nullable ? "" : " [NOT NULL]";
1764
1786
  return `${count.childTable}.${count.childColumn} -> ${count.parentTable}.${count.parentColumn}: ${count.orphanCount} orphan(s)${marker}`;
1765
1787
  }
1788
+ /**
1789
+ * Scrub connection-string credentials from each skipped relationship's
1790
+ * `reason`. A `probe_failed` reason is the database driver's error text,
1791
+ * which can echo the DSN, so both the JSON and human outputs render this
1792
+ * redacted copy.
1793
+ */
1794
+ function redactOrphanReport(report) {
1795
+ return {
1796
+ ...report,
1797
+ skipped: report.skipped.map((skip) => ({
1798
+ ...skip,
1799
+ reason: redactConnectionStringsInText(skip.reason)
1800
+ }))
1801
+ };
1802
+ }
1766
1803
  /** Render the full report as console lines. */
1767
1804
  function formatOrphanReport(report, options = {}) {
1768
1805
  const lines = [];
@@ -1842,7 +1879,7 @@ var dbOrphansCommand = {
1842
1879
  });
1843
1880
  await autoDiscoverAndLoad();
1844
1881
  const manifestSchemas = ObjectRegistry.getAllSchemasAsDefinitions();
1845
- const report = await collectForeignKeyOrphanCounts(db, manifestSchemas, { engineHint: dbType });
1882
+ const report = redactOrphanReport(await collectForeignKeyOrphanCounts(db, manifestSchemas, { engineHint: dbType }));
1846
1883
  if (options.json) {
1847
1884
  console.log(JSON.stringify(report, null, 2));
1848
1885
  return;
@@ -1850,10 +1887,10 @@ var dbOrphansCommand = {
1850
1887
  for (const line of formatOrphanReport(report, { verbose: options.verbose })) console.log(line);
1851
1888
  console.log();
1852
1889
  } catch (error) {
1853
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
1890
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
1854
1891
  else {
1855
1892
  console.error("\n❌ Failed to collect the orphan report:");
1856
- if (error instanceof Error) console.error(` ${error.message}`);
1893
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
1857
1894
  }
1858
1895
  process.exitCode = 1;
1859
1896
  } finally {
@@ -2044,6 +2081,21 @@ function buildPrunePolicy(configured, options) {
2044
2081
  }
2045
2082
  return policy;
2046
2083
  }
2084
+ /**
2085
+ * Scrub connection-string credentials from per-task failures. The sweep
2086
+ * never throws for a task failure; it stores the driver's error text in
2087
+ * `tasks[].error`, which can echo the DSN, so both output forms render this
2088
+ * redacted copy.
2089
+ */
2090
+ function redactSweepResult(result) {
2091
+ return {
2092
+ ...result,
2093
+ tasks: result.tasks.map((task) => task.error ? {
2094
+ ...task,
2095
+ error: redactConnectionStringsInText(task.error)
2096
+ } : task)
2097
+ };
2098
+ }
2047
2099
  /** Render a completed sweep as an operator-readable table. */
2048
2100
  function formatSweepResult(result) {
2049
2101
  const lines = [];
@@ -2124,7 +2176,7 @@ var dbPruneCommand = {
2124
2176
  const { config: smrtConfig, importOptionalDependency, runRetentionSweep } = await import("@happyvertical/smrt-core");
2125
2177
  const loaded = await loadRetentionTaskPackages((specifier) => importOptionalDependency(specifier, "Install it in the project to include its retention tasks."));
2126
2178
  const policy = buildPrunePolicy(smrtConfig.toJSON().retention, options);
2127
- const result = await runRetentionSweep(db, policy);
2179
+ const result = redactSweepResult(await runRetentionSweep(db, policy));
2128
2180
  const unmatched = unmatchedSkipNames(options.skip, result);
2129
2181
  if (options.json) console.log(JSON.stringify({
2130
2182
  ...result,
@@ -2141,7 +2193,7 @@ var dbPruneCommand = {
2141
2193
  }
2142
2194
  if (result.failed) process.exitCode = 1;
2143
2195
  } catch (error) {
2144
- const message = error instanceof Error ? error.message : String(error);
2196
+ const message = redactConnectionStringsInText(error instanceof Error ? error.message : String(error));
2145
2197
  if (options.json) console.log(JSON.stringify({ error: message }));
2146
2198
  else console.error(`\n❌ Retention sweep failed: ${message}\n`);
2147
2199
  process.exitCode = 1;
@@ -2428,7 +2480,7 @@ var dbRollbackCommand = {
2428
2480
  successCount++;
2429
2481
  } catch (error) {
2430
2482
  errorCount++;
2431
- const errorMsg = error instanceof Error ? error.message : String(error);
2483
+ const errorMsg = redactConnectionStringsInText(error instanceof Error ? error.message : String(error));
2432
2484
  if (!options.json) console.error(` ✗ ${migration.name} failed: ${errorMsg}`);
2433
2485
  results.push({
2434
2486
  name: migration.name,
@@ -2436,7 +2488,7 @@ var dbRollbackCommand = {
2436
2488
  error: errorMsg
2437
2489
  });
2438
2490
  stoppedBy = migration.name;
2439
- if (options.verbose && error instanceof Error && error.stack) console.error(`\n${error.stack}\n`);
2491
+ if (options.verbose && error instanceof Error && error.stack) console.error(`\n${redactConnectionStringsInText(error.stack)}\n`);
2440
2492
  }
2441
2493
  }
2442
2494
  if (options.json) console.log(JSON.stringify({
@@ -2459,10 +2511,10 @@ var dbRollbackCommand = {
2459
2511
  }
2460
2512
  if (errorCount > 0) process.exitCode = 1;
2461
2513
  } catch (error) {
2462
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
2514
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
2463
2515
  else {
2464
2516
  console.error("\n❌ Rollback failed:");
2465
- if (error instanceof Error) console.error(` ${error.message}`);
2517
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
2466
2518
  }
2467
2519
  process.exitCode = 1;
2468
2520
  return;
@@ -2574,7 +2626,7 @@ async function runLiveSchemaParity(options = {}) {
2574
2626
  return {
2575
2627
  report: null,
2576
2628
  database: null,
2577
- error: error instanceof Error ? error.message : String(error)
2629
+ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error))
2578
2630
  };
2579
2631
  } finally {
2580
2632
  await closeDatabaseConnection(db);
@@ -3127,7 +3179,10 @@ var dbStatusCommand = {
3127
3179
  const tracker = new MigrationTracker({ db });
3128
3180
  await tracker.initialize();
3129
3181
  const applied = await tracker.getAppliedMigrations();
3130
- const failed = await tracker.getHistory({ status: "failed" });
3182
+ const failed = (await tracker.getHistory({ status: "failed" })).map((row) => row.error_message ? {
3183
+ ...row,
3184
+ error_message: redactConnectionStringsInText(row.error_message)
3185
+ } : row);
3131
3186
  const { discovered, totalObjects } = await autoDiscoverAndLoad();
3132
3187
  const schemaContract = await evaluateSchemaContract({
3133
3188
  discovered,
@@ -3209,15 +3264,18 @@ var dbStatusCommand = {
3209
3264
  engineHint: dbType
3210
3265
  });
3211
3266
  } catch (error) {
3212
- status.parityError = error instanceof Error ? error.message : String(error);
3267
+ status.parityError = redactConnectionStringsInText(error instanceof Error ? error.message : String(error));
3213
3268
  }
3214
3269
  } else if (options.parity) status.parityError = "The configured database adapter cannot describe tables, so live-schema parity cannot be verified.";
3215
3270
  try {
3216
3271
  const orphanReport = await collectForeignKeyOrphanCounts(db, manifestSchemas, { engineHint: dbType });
3217
3272
  status.orphanedForeignKeys = affectedOrphanCounts(orphanReport);
3218
- status.orphanProbeFailures = orphanReport.skipped.filter((skip) => skip.kind === "probe_failed");
3273
+ status.orphanProbeFailures = orphanReport.skipped.filter((skip) => skip.kind === "probe_failed").map((skip) => ({
3274
+ ...skip,
3275
+ reason: redactConnectionStringsInText(skip.reason)
3276
+ }));
3219
3277
  } catch (error) {
3220
- status.orphansError = error instanceof Error ? error.message : String(error);
3278
+ status.orphansError = redactConnectionStringsInText(error instanceof Error ? error.message : String(error));
3221
3279
  }
3222
3280
  const failedAssessments = assessFailedMigrations(failed, typeof db.getTableSchema === "function" ? diff : null);
3223
3281
  status.migrations.failed = {
@@ -3347,10 +3405,10 @@ var dbStatusCommand = {
3347
3405
  console.log(" smrt db:diff - Show schema differences");
3348
3406
  console.log();
3349
3407
  } catch (error) {
3350
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
3408
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
3351
3409
  else {
3352
3410
  console.error("\n❌ Failed to get migration status:");
3353
- if (error instanceof Error) console.error(` ${error.message}`);
3411
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
3354
3412
  }
3355
3413
  process.exitCode = 1;
3356
3414
  return;
@@ -4433,12 +4491,12 @@ var exportCommand = {
4433
4491
  if (showDrafts) console.log(" Mode: Including drafts");
4434
4492
  }
4435
4493
  } catch (error) {
4436
- if (options.json) console.log(JSON.stringify({ error: error instanceof Error ? error.message : String(error) }));
4494
+ if (options.json) console.log(JSON.stringify({ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)) }));
4437
4495
  else {
4438
4496
  console.error("\n❌ Export failed:");
4439
4497
  if (error instanceof Error) {
4440
- console.error(` ${error.message}`);
4441
- if (options.verbose) console.error(error.stack);
4498
+ console.error(` ${redactConnectionStringsInText(error.message)}`);
4499
+ if (options.verbose && error.stack) console.error(redactConnectionStringsInText(error.stack));
4442
4500
  }
4443
4501
  }
4444
4502
  process.exitCode = 1;
@@ -6840,7 +6898,7 @@ var dbDropFrameworkBaseTablesCommand = {
6840
6898
  });
6841
6899
  console.log(`\n✓ Dropped ${result.droppedTables.length} table(s) and ${result.droppedIndexes.length} companion index(es): ${result.droppedTables.map((table) => quoteIdentifier(table)).join(", ")}\n`);
6842
6900
  } catch (error) {
6843
- console.error(`\n❌ Framework base-table remediation failed: ${error instanceof Error ? error.message : String(error)}\n`);
6901
+ console.error(`\n❌ Framework base-table remediation failed: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}\n`);
6844
6902
  process.exitCode = 1;
6845
6903
  } finally {
6846
6904
  await closeDatabaseConnection(db);
@@ -6890,7 +6948,7 @@ var dbMigrateAgentScheduleSlugsCommand = {
6890
6948
  });
6891
6949
  console.log(result.ran ? `✓ Backfilled ${result.updated} AgentSchedule slug(s); no schedules were run.\n` : "No schedule slug migration was needed.\n");
6892
6950
  } catch (error) {
6893
- console.error(`\n❌ AgentSchedule slug migration failed: ${error instanceof Error ? error.message : String(error)}\n`);
6951
+ console.error(`\n❌ AgentSchedule slug migration failed: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}\n`);
6894
6952
  process.exitCode = 1;
6895
6953
  } finally {
6896
6954
  await closeDatabaseConnection(db);
@@ -6984,7 +7042,7 @@ var dbMigrateInt8Command = {
6984
7042
  });
6985
7043
  console.log(result.ran ? `\n✓ Widened ${result.widenedColumns.length} column(s) to BIGINT.\n` : "\nNo widening was applied; no legacy int4 columns remain.\n");
6986
7044
  } catch (error) {
6987
- console.error(`\n❌ int8 migration failed: ${error instanceof Error ? error.message : String(error)}\n`);
7045
+ console.error(`\n❌ int8 migration failed: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}\n`);
6988
7046
  process.exitCode = 1;
6989
7047
  } finally {
6990
7048
  await closeDatabaseConnection(db);
@@ -7037,7 +7095,7 @@ var dbMigrateNullEqualIndexesCommand = {
7037
7095
  console.log(`Applied ${result.statements.length} index statements atomically.`);
7038
7096
  console.log("Refresh/restart database connections in EVERY application process to clear cached index capability probes. Until then the existing upsert fallback remains correct.");
7039
7097
  } catch (error) {
7040
- console.error(`NULL-equal conflict-index migration failed: ${error instanceof Error ? error.message : String(error)}`);
7098
+ console.error(`NULL-equal conflict-index migration failed: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}`);
7041
7099
  process.exitCode = 1;
7042
7100
  } finally {
7043
7101
  await closeDatabaseConnection(db);
@@ -7369,7 +7427,7 @@ var dbMigrateUuidCommand = {
7369
7427
  await convertPostgresUuidColumns(tx, declaredUuid, false);
7370
7428
  });
7371
7429
  } catch (error) {
7372
- console.error(`\n❌ uuid migration failed: ${error instanceof Error ? error.message : String(error)}\n`);
7430
+ console.error(`\n❌ uuid migration failed: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}\n`);
7373
7431
  process.exitCode = 1;
7374
7432
  } finally {
7375
7433
  await closeDatabaseConnection(db);
@@ -8991,7 +9049,7 @@ async function settleDeferredCompatibilityAfterMigrate(db, dbType, { verbose })
8991
9049
  const { settled } = await ensureDeferredSystemTableCompatibility(db, dbType);
8992
9050
  if (verbose) console.log(settled ? "Deferred system-table compatibility settled (_smrt_jobs, _smrt_job_events)\n" : "Deferred system-table compatibility pending (jobs tables not present)\n");
8993
9051
  } catch (error) {
8994
- console.warn(`⚠️ Deferred system-table compatibility did not complete: ${error instanceof Error ? error.message : String(error)}`);
9052
+ console.warn(`⚠️ Deferred system-table compatibility did not complete: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}`);
8995
9053
  console.warn(" It will be retried the next time the framework starts.\n");
8996
9054
  }
8997
9055
  }
@@ -9537,7 +9595,7 @@ export default testManifest;
9537
9595
  await db.query(`DROP TABLE IF EXISTS ${quoteIdentifier(tableName)}${cascade}`);
9538
9596
  console.log(` ✓ Dropped ${tableName}`);
9539
9597
  } catch (error) {
9540
- if (options.verbose) console.log(` ⚠️ Could not drop ${tableName}: ${error}`);
9598
+ if (options.verbose) console.log(` ⚠️ Could not drop ${tableName}: ${redactConnectionStringsInText(String(error))}`);
9541
9599
  throw new Error(`Refusing to continue after failing to drop ${tableName}; dependency or foreign-key constraints may still be active.`, { cause: error });
9542
9600
  }
9543
9601
  }
@@ -9555,8 +9613,8 @@ export default testManifest;
9555
9613
  try {
9556
9614
  await schemaManager.ensureTables(schemas);
9557
9615
  } catch (error) {
9558
- console.error(` ✗ Schema creation failed: ${error}`);
9559
- if (options.verbose && error instanceof Error && error.stack) console.error(`\n${error.stack}\n`);
9616
+ console.error(` ✗ Schema creation failed: ${redactConnectionStringsInText(String(error))}`);
9617
+ if (options.verbose && error instanceof Error && error.stack) console.error(`\n${redactConnectionStringsInText(error.stack)}\n`);
9560
9618
  throw new Error("Refusing to report database setup success after schema creation failed.", { cause: error });
9561
9619
  }
9562
9620
  let tablesCreated = 0;
@@ -9589,12 +9647,12 @@ export default testManifest;
9589
9647
  } catch (error) {
9590
9648
  console.error(formatSchemaCommandFailureHeader(error, "\n❌ Database setup failed:"));
9591
9649
  if (error instanceof Error) {
9592
- console.error(` ${error.message}`);
9650
+ console.error(` ${redactConnectionStringsInText(error.message)}`);
9593
9651
  if (options.verbose && error.stack) {
9594
9652
  console.error("\nStack trace:");
9595
- console.error(error.stack);
9653
+ console.error(redactConnectionStringsInText(error.stack));
9596
9654
  }
9597
- } else console.error(error);
9655
+ } else console.error(redactConnectionStringsInText(String(error)));
9598
9656
  process.exitCode = 1;
9599
9657
  return;
9600
9658
  } finally {
@@ -9626,7 +9684,7 @@ export default testManifest;
9626
9684
  }
9627
9685
  } catch (error) {
9628
9686
  console.error("❌ Failed to clear cache:");
9629
- if (error instanceof Error) console.error(` ${error.message}`);
9687
+ if (error instanceof Error) console.error(` ${redactConnectionStringsInText(error.message)}`);
9630
9688
  process.exit(1);
9631
9689
  }
9632
9690
  }
@@ -9764,18 +9822,18 @@ export default testManifest;
9764
9822
  } catch (error) {
9765
9823
  if (options.json) console.log(JSON.stringify({
9766
9824
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
9767
- error: error instanceof Error ? error.message : String(error),
9825
+ error: redactConnectionStringsInText(error instanceof Error ? error.message : String(error)),
9768
9826
  duration: Date.now() - startTime
9769
9827
  }, null, 2));
9770
9828
  else {
9771
9829
  console.error("\n❌ Validation failed:");
9772
9830
  if (error instanceof Error) {
9773
- console.error(` ${error.message}`);
9831
+ console.error(` ${redactConnectionStringsInText(error.message)}`);
9774
9832
  if (options.verbose && error.stack) {
9775
9833
  console.error("\nStack trace:");
9776
- console.error(error.stack);
9834
+ console.error(redactConnectionStringsInText(error.stack));
9777
9835
  }
9778
- } else console.error(error);
9836
+ } else console.error(redactConnectionStringsInText(String(error)));
9779
9837
  }
9780
9838
  process.exit(1);
9781
9839
  }
@@ -10018,7 +10076,7 @@ export default testManifest;
10018
10076
  try {
10019
10077
  beforeCount = await countOrphanRows(db, countSql);
10020
10078
  } catch (error) {
10021
- console.log(` ✗ ${item.tableName}.${item.column}: orphan-count probe failed, withholding this disposition: ${error instanceof Error ? error.message : String(error)}`);
10079
+ console.log(` ✗ ${item.tableName}.${item.column}: orphan-count probe failed, withholding this disposition: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}`);
10022
10080
  continue;
10023
10081
  }
10024
10082
  if (!item.action.foreignKey) continue;
@@ -10306,10 +10364,10 @@ export default testManifest;
10306
10364
  skippedCount += results.filter((result) => result.success && (result.skipped || result.applied === false || result.execution_time_ms === 0)).length;
10307
10365
  } catch (error) {
10308
10366
  errorCount++;
10309
- const errorMsg = error instanceof Error ? error.message : String(error);
10367
+ const errorMsg = redactConnectionStringsInText(error instanceof Error ? error.message : String(error));
10310
10368
  console.error(` ✗ atomic schema migration failed: ${errorMsg}`);
10311
- if (error instanceof Error && getErrorContext(error)?.originalError) console.error(` Cause: ${getErrorContext(error)?.originalError}`);
10312
- if (options.verbose && error instanceof Error && error.stack) console.error(`\n${error.stack}\n`);
10369
+ if (error instanceof Error && getErrorContext(error)?.originalError) console.error(` Cause: ${redactConnectionStringsInText(String(getErrorContext(error)?.originalError))}`);
10370
+ if (options.verbose && error instanceof Error && error.stack) console.error(`\n${redactConnectionStringsInText(error.stack)}\n`);
10313
10371
  console.error(deferredIndexMigrations > 0 ? " Non-index changes in this batch were committed; concurrent index builds that did not finish are recorded failed and will be retried on the next db:migrate." : " Rolled back all schema changes from this migration batch, including any successful steps shown above.");
10314
10372
  }
10315
10373
  }
@@ -10324,7 +10382,7 @@ export default testManifest;
10324
10382
  const afterCount = await countOrphanRows(db, pending.countSql);
10325
10383
  console.log(` ✓ ${pending.tableName}.${pending.column}: nulled ${Math.max(pending.beforeCount - afterCount, 0)} orphan reference(s) (${afterCount} remaining)`);
10326
10384
  } catch (error) {
10327
- console.log(` ✓ ${pending.tableName}.${pending.column}: orphan references nulled and foreign key added (post-apply count unavailable: ${error instanceof Error ? error.message : String(error)})`);
10385
+ console.log(` ✓ ${pending.tableName}.${pending.column}: orphan references nulled and foreign key added (post-apply count unavailable: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))})`);
10328
10386
  }
10329
10387
  console.log();
10330
10388
  }
@@ -10385,8 +10443,8 @@ export default testManifest;
10385
10443
  } else if (repair.conflicts.length === 0) stiSkippedCount++;
10386
10444
  } catch (error) {
10387
10445
  const qualifiedName = resolution.currentQualifiedName;
10388
- const errorMsg = error instanceof Error ? error.message : String(error);
10389
- const originalError = getErrorContext(error)?.originalError;
10446
+ const errorMsg = redactConnectionStringsInText(error instanceof Error ? error.message : String(error));
10447
+ const originalError = getErrorContext(error)?.originalError ? redactConnectionStringsInText(String(getErrorContext(error)?.originalError)) : void 0;
10390
10448
  console.error(` ✗ ${tableName}: "${metaType}" → "${qualifiedName}" failed: ${originalError || errorMsg}`);
10391
10449
  stiErrorCount++;
10392
10450
  }
@@ -10440,17 +10498,17 @@ export default testManifest;
10440
10498
  } catch (error) {
10441
10499
  console.error(formatSchemaCommandFailureHeader(error, "\n❌ Migration failed:"));
10442
10500
  if (error instanceof Error) {
10443
- console.error(` ${error.message}`);
10501
+ console.error(` ${redactConnectionStringsInText(error.message)}`);
10444
10502
  const ctx = getErrorContext(error);
10445
10503
  if (ctx) {
10446
- if (ctx.originalError) console.error(` Database error: ${ctx.originalError}`);
10447
- if (ctx.sql) console.error(` Failed SQL: ${ctx.sql}`);
10504
+ if (ctx.originalError) console.error(` Database error: ${redactConnectionStringsInText(String(ctx.originalError))}`);
10505
+ if (ctx.sql) console.error(` Failed SQL: ${redactConnectionStringsInText(String(ctx.sql))}`);
10448
10506
  }
10449
10507
  if (options.verbose && error.stack) {
10450
10508
  console.error("\nStack trace:");
10451
- console.error(error.stack);
10509
+ console.error(redactConnectionStringsInText(error.stack));
10452
10510
  }
10453
- } else console.error(error);
10511
+ } else console.error(redactConnectionStringsInText(String(error)));
10454
10512
  process.exitCode = 1;
10455
10513
  return;
10456
10514
  } finally {
package/dist/index.js CHANGED
@@ -49,63 +49,63 @@ var _playgroundCommands = null;
49
49
  var _workbenchCommands = null;
50
50
  async function getGnodeCommands() {
51
51
  if (!_gnodeCommands) {
52
- const { gnodeCommands } = await import("./commands-D2o62iRL.js");
52
+ const { gnodeCommands } = await import("./commands-BQwEHPr9.js");
53
53
  _gnodeCommands = gnodeCommands;
54
54
  }
55
55
  return _gnodeCommands;
56
56
  }
57
57
  async function getGitCommands() {
58
58
  if (!_gitCommands) {
59
- const { gitCommands } = await import("./commands-D2o62iRL.js");
59
+ const { gitCommands } = await import("./commands-BQwEHPr9.js");
60
60
  _gitCommands = gitCommands;
61
61
  }
62
62
  return _gitCommands;
63
63
  }
64
64
  async function getGenerateCommands() {
65
65
  if (!_generateCommands) {
66
- const { generateCommands } = await import("./commands-D2o62iRL.js");
66
+ const { generateCommands } = await import("./commands-BQwEHPr9.js");
67
67
  _generateCommands = generateCommands;
68
68
  }
69
69
  return _generateCommands;
70
70
  }
71
71
  async function getInitCommands() {
72
72
  if (!_initCommands) {
73
- const { initCommands } = await import("./commands-D2o62iRL.js");
73
+ const { initCommands } = await import("./commands-BQwEHPr9.js");
74
74
  _initCommands = initCommands;
75
75
  }
76
76
  return _initCommands;
77
77
  }
78
78
  async function getUtilityCommands() {
79
79
  if (!_utilityCommands) {
80
- const { utilityCommands } = await import("./commands-D2o62iRL.js");
80
+ const { utilityCommands } = await import("./commands-BQwEHPr9.js");
81
81
  _utilityCommands = utilityCommands;
82
82
  }
83
83
  return _utilityCommands;
84
84
  }
85
85
  async function getDispatchCommands() {
86
86
  if (!_dispatchCommands) {
87
- const { dispatchCommands } = await import("./commands-D2o62iRL.js");
87
+ const { dispatchCommands } = await import("./commands-BQwEHPr9.js");
88
88
  _dispatchCommands = dispatchCommands;
89
89
  }
90
90
  return _dispatchCommands;
91
91
  }
92
92
  async function getDocsCommands() {
93
93
  if (!_docsCommands) {
94
- const { docsCommands } = await import("./commands-D2o62iRL.js");
94
+ const { docsCommands } = await import("./commands-BQwEHPr9.js");
95
95
  _docsCommands = docsCommands;
96
96
  }
97
97
  return _docsCommands;
98
98
  }
99
99
  async function getPlaygroundCommands() {
100
100
  if (!_playgroundCommands) {
101
- const { playgroundCommands } = await import("./commands-D2o62iRL.js");
101
+ const { playgroundCommands } = await import("./commands-BQwEHPr9.js");
102
102
  _playgroundCommands = playgroundCommands;
103
103
  }
104
104
  return _playgroundCommands;
105
105
  }
106
106
  async function getWorkbenchCommands() {
107
107
  if (!_workbenchCommands) {
108
- const { workbenchCommands } = await import("./commands-D2o62iRL.js");
108
+ const { workbenchCommands } = await import("./commands-BQwEHPr9.js");
109
109
  _workbenchCommands = workbenchCommands;
110
110
  }
111
111
  return _workbenchCommands;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@happyvertical/smrt-cli",
3
- "version": "0.51.11",
3
+ "version": "0.51.13",
4
4
  "description": "Developer CLI for SMRT framework - introspection, testing, and project management",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -25,17 +25,17 @@
25
25
  }
26
26
  },
27
27
  "dependencies": {
28
- "@happyvertical/ai": "^0.89.11",
29
- "@happyvertical/files": "^0.89.11",
30
- "@happyvertical/logger": "^0.89.11",
31
- "@happyvertical/smrt-agents": "0.51.11",
32
- "@happyvertical/smrt-config": "0.51.11",
33
- "@happyvertical/smrt-core": "0.51.11",
34
- "@happyvertical/smrt-dev-mcp": "0.51.11",
35
- "@happyvertical/smrt-playground": "0.51.11",
36
- "@happyvertical/smrt-types": "0.51.11",
37
- "@happyvertical/sql": "^0.89.11",
38
- "@happyvertical/utils": "^0.89.11",
28
+ "@happyvertical/ai": "^0.89.12",
29
+ "@happyvertical/files": "^0.89.12",
30
+ "@happyvertical/logger": "^0.89.12",
31
+ "@happyvertical/smrt-agents": "0.51.13",
32
+ "@happyvertical/smrt-config": "0.51.13",
33
+ "@happyvertical/smrt-core": "0.51.13",
34
+ "@happyvertical/smrt-dev-mcp": "0.51.13",
35
+ "@happyvertical/smrt-playground": "0.51.13",
36
+ "@happyvertical/smrt-types": "0.51.13",
37
+ "@happyvertical/sql": "^0.89.12",
38
+ "@happyvertical/utils": "^0.89.12",
39
39
  "acorn": "^8.17.0",
40
40
  "fast-glob": "3.3.3",
41
41
  "tar": "^7.5.19"