betterstart-cli 0.0.91 → 0.0.92

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.
package/dist/cli.js CHANGED
@@ -317,7 +317,7 @@ function requireInitializedProject(command) {
317
317
 
318
318
  // adapters/next/commands/add.ts
319
319
  import path27 from "path";
320
- import * as p8 from "@clack/prompts";
320
+ import * as p9 from "@clack/prompts";
321
321
 
322
322
  // core-engine/config/serialize.ts
323
323
  import fs3 from "fs";
@@ -866,10 +866,93 @@ async function resolveConfigOrExit(cwd) {
866
866
  }
867
867
 
868
868
  // adapters/next/generators/post-generate.ts
869
- import { execFileSync as execFileSync2 } from "child_process";
869
+ import { execFile } from "child_process";
870
870
  import fs8 from "fs";
871
871
  import path10 from "path";
872
- import * as p5 from "@clack/prompts";
872
+ import { promisify } from "util";
873
+ import * as p6 from "@clack/prompts";
874
+
875
+ // core-engine/utils/spinner.ts
876
+ import { stripVTControlCharacters } from "util";
877
+ import * as p3 from "@clack/prompts";
878
+ var RENDER_OVERHEAD = 7;
879
+ var MIN_MESSAGE_WIDTH = 8;
880
+ function fitSpinnerMessage(message) {
881
+ const normalized = message.replace(/\t/g, " ");
882
+ const columns = process.stdout.columns ?? 80;
883
+ const max = Math.max(columns - RENDER_OVERHEAD, MIN_MESSAGE_WIDTH);
884
+ const visible = stripVTControlCharacters(normalized);
885
+ if (visible.length <= max) return normalized;
886
+ return `${visible.slice(0, max - 1)}\u2026`;
887
+ }
888
+ var CLACK_LINE_ROWS = 2;
889
+ var LOG_PREFIX_WIDTH = 3;
890
+ function clackPromptRows(message, value) {
891
+ const columns = process.stdout.columns ?? 80;
892
+ const rows = (text7) => Math.max(1, Math.ceil((stripVTControlCharacters(text7).length + LOG_PREFIX_WIDTH) / columns));
893
+ return 1 + rows(message) + rows(value);
894
+ }
895
+ function clackLogRows(message) {
896
+ const columns = process.stdout.columns ?? 80;
897
+ const width = stripVTControlCharacters(message).length + LOG_PREFIX_WIDTH;
898
+ return 1 + Math.max(1, Math.ceil(width / columns));
899
+ }
900
+ function eraseRows(rows) {
901
+ if (rows <= 0 || !process.stdout.isTTY || process.env.CI === "true") return;
902
+ process.stdout.write(`\x1B[${rows}A\x1B[${rows}M`);
903
+ }
904
+ function eraseRowsAbove(rows, rowsBelow) {
905
+ if (rows <= 0 || rowsBelow < 0 || !process.stdout.isTTY || process.env.CI === "true") {
906
+ return;
907
+ }
908
+ const up = rows + rowsBelow;
909
+ const restore = rowsBelow > 0 ? `\x1B[${rowsBelow}B` : "";
910
+ process.stdout.write(`\x1B[${up}A\x1B[${rows}M${restore}`);
911
+ }
912
+ function eraseClackLine(options = {}) {
913
+ if (!process.stdout.isTTY || process.env.CI === "true") return;
914
+ const below = (options.linesBelow ?? 0) * CLACK_LINE_ROWS;
915
+ const up = below + CLACK_LINE_ROWS;
916
+ const restore = below > 0 ? `\x1B[${below}B` : "";
917
+ process.stdout.write(`\x1B[${up}A\x1B[${CLACK_LINE_ROWS}M${restore}`);
918
+ }
919
+ var activeSpinners = 0;
920
+ function hasActiveSpinner() {
921
+ return activeSpinners > 0;
922
+ }
923
+ function spinner2(options) {
924
+ const inner = p3.spinner({ ...options, cancelMessage: "Setup cancelled." });
925
+ const guided = options?.withGuide !== false;
926
+ let started = false;
927
+ const setStarted = (next) => {
928
+ if (started === next) return;
929
+ started = next;
930
+ activeSpinners += next ? 1 : -1;
931
+ };
932
+ return {
933
+ start: (message = "") => {
934
+ if (started) {
935
+ inner.message(fitSpinnerMessage(message));
936
+ return;
937
+ }
938
+ setStarted(true);
939
+ inner.start(fitSpinnerMessage(message));
940
+ },
941
+ message: (message = "") => inner.message(fitSpinnerMessage(message)),
942
+ stop: (message = "") => {
943
+ setStarted(false);
944
+ inner.stop(message);
945
+ },
946
+ clear: () => {
947
+ if (!started) return;
948
+ setStarted(false);
949
+ inner.clear();
950
+ if (guided && process.stdout.isTTY && process.env.CI !== "true") {
951
+ process.stdout.write("\x1B[1A\x1B[2K");
952
+ }
953
+ }
954
+ };
955
+ }
873
956
 
874
957
  // adapters/next/init/scaffolders/dependencies.ts
875
958
  import { spawn } from "child_process";
@@ -1752,7 +1835,7 @@ async function syncProjectCliDependency(cwd, pm) {
1752
1835
  // adapters/next/utils/drizzle-push.ts
1753
1836
  import { spawn as spawn2 } from "child_process";
1754
1837
  import path9 from "path";
1755
- import * as p3 from "@clack/prompts";
1838
+ import * as p4 from "@clack/prompts";
1756
1839
  var PG_SSL_WARNING_START = "Warning: SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.";
1757
1840
  var PG_SSL_WARNING_END = "See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode definitions.";
1758
1841
  var NODE_TRACE_WARNING_HINT = "(Use `node --trace-warnings";
@@ -1928,7 +2011,7 @@ function runDrizzlePush(cwd, options = {}) {
1928
2011
  }
1929
2012
  if (stdoutTtySuppressor.sawError() || stderrTtySuppressor.sawError()) {
1930
2013
  notifyOutput();
1931
- p3.log.info("Database changes need your input \u2014 continuing in drizzle-kit.");
2014
+ p4.log.info("Database changes need your input \u2014 continuing in drizzle-kit.");
1932
2015
  const attached = spawn2(drizzleBin, ["push", "--force"], {
1933
2016
  cwd,
1934
2017
  stdio: "inherit",
@@ -1974,7 +2057,7 @@ ${stderr}`.trim();
1974
2057
  }
1975
2058
 
1976
2059
  // adapters/next/utils/next-steps.ts
1977
- import * as p4 from "@clack/prompts";
2060
+ import * as p5 from "@clack/prompts";
1978
2061
  function printNextSteps(options) {
1979
2062
  const steps = [`1. Review ${options.reviewLabel}`];
1980
2063
  if (options.needsMigration) {
@@ -1983,11 +2066,12 @@ function printNextSteps(options) {
1983
2066
  } else {
1984
2067
  steps.push(`2. Start the dev server and visit ${options.route}`);
1985
2068
  }
1986
- p4.note(steps.join("\n"), "Next steps");
2069
+ p5.note(steps.join("\n"), "Next steps");
1987
2070
  }
1988
2071
 
1989
2072
  // adapters/next/generators/post-generate.ts
1990
2073
  var BIOME_FORMAT_TIMEOUT_MS = 3e4;
2074
+ var execFileAsync = promisify(execFile);
1991
2075
  function loadEnvFile(cwd) {
1992
2076
  const envPath = path10.join(cwd, ".env.local");
1993
2077
  if (!fs8.existsSync(envPath)) return;
@@ -2011,10 +2095,10 @@ function loadEnvFile(cwd) {
2011
2095
  }
2012
2096
  }
2013
2097
  }
2014
- function runPmScript(pm, script, cwd, timeout) {
2098
+ async function runPmScript(pm, script, cwd, timeout) {
2015
2099
  const args = pm === "bun" ? ["run", script] : [script];
2016
2100
  try {
2017
- execFileSync2(pm, args, { cwd, stdio: "pipe", timeout });
2101
+ await execFileAsync(pm, args, { cwd, timeout });
2018
2102
  return true;
2019
2103
  } catch {
2020
2104
  return false;
@@ -2025,7 +2109,7 @@ function getExistingTrackedFilePaths(cwd) {
2025
2109
  (filePath) => fs8.existsSync(path10.join(cwd, ...filePath.split("/")))
2026
2110
  );
2027
2111
  }
2028
- function runBiomeCheckWrite(cwd) {
2112
+ async function runBiomeCheckWrite(cwd) {
2029
2113
  const biomeBin = path10.join(cwd, "node_modules", ".bin", "biome");
2030
2114
  if (!fs8.existsSync(biomeBin)) {
2031
2115
  return false;
@@ -2044,9 +2128,8 @@ function runBiomeCheckWrite(cwd) {
2044
2128
  ...configPath ? ["--config-path", configPath] : [],
2045
2129
  ...chunk
2046
2130
  ];
2047
- execFileSync2(biomeBin, args, {
2131
+ await execFileAsync(biomeBin, args, {
2048
2132
  cwd,
2049
- stdio: "pipe",
2050
2133
  timeout: BIOME_FORMAT_TIMEOUT_MS
2051
2134
  });
2052
2135
  }
@@ -2063,18 +2146,15 @@ function buildAddDependencyArgs(pm, dependency, dev) {
2063
2146
  return ["install", ...devFlag ? [devFlag] : [], dependency];
2064
2147
  }
2065
2148
  }
2066
- function installDependency(cwd, pm, dependency, dev = false) {
2149
+ async function installDependency(cwd, pm, dependency, dev = false) {
2067
2150
  try {
2068
- execFileSync2(pm, buildAddDependencyArgs(pm, dependency, dev), {
2069
- cwd,
2070
- stdio: "pipe"
2071
- });
2151
+ await execFileAsync(pm, buildAddDependencyArgs(pm, dependency, dev), { cwd });
2072
2152
  return true;
2073
2153
  } catch {
2074
2154
  return false;
2075
2155
  }
2076
2156
  }
2077
- function ensureDatabasePushDependencies(cwd, pm) {
2157
+ async function ensureDatabasePushDependencies(cwd, pm) {
2078
2158
  const missing = [];
2079
2159
  if (!hasPostgresRuntimeDependency(cwd)) {
2080
2160
  missing.push({ name: POSTGRES_RUNTIME_DEP, dev: false });
@@ -2085,25 +2165,25 @@ function ensureDatabasePushDependencies(cwd, pm) {
2085
2165
  if (missing.length === 0) {
2086
2166
  return true;
2087
2167
  }
2088
- p5.log.info(
2168
+ p6.log.info(
2089
2169
  `Installing database push dependencies (${missing.map((dependency) => dependency.name).join(", ")})...`
2090
2170
  );
2091
2171
  for (const dependency of missing) {
2092
- const installed2 = installDependency(cwd, pm, dependency.name, dependency.dev);
2172
+ const installed2 = await installDependency(cwd, pm, dependency.name, dependency.dev);
2093
2173
  if (!installed2) {
2094
- p5.log.warn(`Failed to install ${dependency.name}`);
2174
+ p6.log.warn(`Failed to install ${dependency.name}`);
2095
2175
  return false;
2096
2176
  }
2097
2177
  }
2098
2178
  const ready = hasPostgresRuntimeDependency(cwd) && hasDrizzleKitPostgresDriverDependency(cwd);
2099
2179
  if (ready) {
2100
- p5.log.success("Database push dependencies installed");
2180
+ p6.log.success("Database push dependencies installed");
2101
2181
  } else {
2102
2182
  const unresolved = [
2103
2183
  !hasPostgresRuntimeDependency(cwd) ? POSTGRES_RUNTIME_DEP : null,
2104
2184
  !hasDrizzleKitPostgresDriverDependency(cwd) ? DRIZZLE_KIT_POSTGRES_DRIVER_DEP : null
2105
2185
  ].filter((dependency) => Boolean(dependency));
2106
- p5.log.warn(`Installed dependencies but could not resolve ${unresolved.join(", ")}`);
2186
+ p6.log.warn(`Installed dependencies but could not resolve ${unresolved.join(", ")}`);
2107
2187
  }
2108
2188
  return ready;
2109
2189
  }
@@ -2146,8 +2226,8 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2146
2226
  "Formatting: skipped (biome refuses files with conflict markers)",
2147
2227
  ...(options.conflictPaths ?? []).map((conflictPath) => ` - ${conflictPath}`)
2148
2228
  ];
2149
- p5.log.warn(lines.join("\n"));
2150
- p5.log.message(
2229
+ p6.log.warn(lines.join("\n"));
2230
+ p6.log.message(
2151
2231
  "Resolve markers in the files above and re-run the BetterStart command that wrote them. Post-write tasks run automatically once every file is clean."
2152
2232
  );
2153
2233
  return result;
@@ -2157,62 +2237,83 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2157
2237
  const dbUrl = process.env.DATABASE_URL;
2158
2238
  if (!dbUrl) {
2159
2239
  result.dbPush = "no-db-url";
2160
- p5.log.warn(
2240
+ p6.log.warn(
2161
2241
  [
2162
2242
  "Database: skipped (no DATABASE_URL configured)",
2163
2243
  " To sync later: run db:push after setting DATABASE_URL"
2164
2244
  ].join("\n")
2165
2245
  );
2166
- } else if (!ensureDatabasePushDependencies(cwd, pm)) {
2246
+ } else if (!await ensureDatabasePushDependencies(cwd, pm)) {
2167
2247
  result.dbPush = "failed";
2168
- p5.log.warn(
2248
+ p6.log.warn(
2169
2249
  "Database push failed (install database dependencies and run drizzle-kit push manually)"
2170
2250
  );
2171
2251
  } else if (hasPkgScript(cwd, "db:push")) {
2172
- p5.log.info("Running db:push...");
2173
- const ok = runPmScript(pm, "db:push", cwd);
2252
+ const s = spinner2();
2253
+ s.start("Pushing database schema");
2254
+ const ok = await runPmScript(pm, "db:push", cwd);
2174
2255
  result.dbPush = ok ? "success" : "failed";
2175
2256
  if (ok) {
2176
- p5.log.success("Database schema synced");
2257
+ s.stop("Database schema synced");
2177
2258
  } else {
2178
- p5.log.warn("Database push failed (run db:push manually)");
2259
+ s.clear();
2260
+ p6.log.warn("Database push failed (run db:push manually)");
2179
2261
  }
2180
2262
  } else {
2181
- p5.log.info("Running drizzle-kit push...");
2263
+ const s = spinner2();
2264
+ let spinnerVisible = true;
2265
+ const clearSpinner = () => {
2266
+ if (!spinnerVisible) return;
2267
+ spinnerVisible = false;
2268
+ s.clear();
2269
+ };
2270
+ s.start("Pushing database schema");
2182
2271
  try {
2183
- const pushResult = await runDrizzlePush(cwd, { interactive: true });
2272
+ const pushResult = await runDrizzlePush(cwd, {
2273
+ interactive: true,
2274
+ onOutput: clearSpinner
2275
+ });
2184
2276
  if (!pushResult.success) {
2185
2277
  throw new Error(pushResult.error ?? "drizzle-kit push failed");
2186
2278
  }
2187
2279
  result.dbPush = "success";
2188
- p5.log.success("Database schema synced");
2280
+ if (spinnerVisible) {
2281
+ spinnerVisible = false;
2282
+ s.stop("Database schema synced");
2283
+ } else {
2284
+ p6.log.success("Database schema synced");
2285
+ }
2189
2286
  } catch {
2190
2287
  result.dbPush = "failed";
2191
- p5.log.warn("Database push failed (run drizzle-kit push manually)");
2288
+ clearSpinner();
2289
+ p6.log.warn("Database push failed (run drizzle-kit push manually)");
2192
2290
  }
2193
2291
  }
2194
2292
  } else {
2195
- p5.log.info(`Database: skipped (${options.skipMigrationMessage ?? "--skip-migration"})`);
2293
+ p6.log.info(`Database: skipped (${options.skipMigrationMessage ?? "--skip-migration"})`);
2196
2294
  }
2295
+ const formatSpinner = spinner2();
2296
+ formatSpinner.start("Formatting generated files");
2197
2297
  if (hasPkgScript(cwd, "lint:fix")) {
2198
- p5.log.info("Running lint:fix...");
2199
- const ok = runPmScript(pm, "lint:fix", cwd, BIOME_FORMAT_TIMEOUT_MS);
2298
+ const ok = await runPmScript(pm, "lint:fix", cwd, BIOME_FORMAT_TIMEOUT_MS);
2200
2299
  result.lintFix = ok ? "success" : "failed";
2201
2300
  if (ok) {
2202
- p5.log.success("Code formatted");
2301
+ formatSpinner.stop("Code formatted");
2203
2302
  } else {
2204
- p5.log.warn("Lint fix had issues (run lint:fix manually)");
2303
+ formatSpinner.clear();
2304
+ p6.log.warn("Lint fix had issues (run lint:fix manually)");
2205
2305
  }
2206
2306
  } else {
2207
2307
  try {
2208
- if (!runBiomeCheckWrite(cwd)) {
2308
+ if (!await runBiomeCheckWrite(cwd)) {
2209
2309
  throw new Error("Biome binary not found");
2210
2310
  }
2211
2311
  result.lintFix = "success";
2212
- p5.log.success("Code formatted with Biome");
2312
+ formatSpinner.stop("Code formatted with Biome");
2213
2313
  } catch {
2214
2314
  result.lintFix = "failed";
2215
- p5.log.warn("Biome formatting had issues (run biome check --write manually)");
2315
+ formatSpinner.clear();
2316
+ p6.log.warn("Biome formatting had issues (run biome check --write manually)");
2216
2317
  }
2217
2318
  }
2218
2319
  if (options.showNextSteps !== false) {
@@ -2229,7 +2330,7 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2229
2330
  // adapters/next/integration-runtime.ts
2230
2331
  import fs14 from "fs";
2231
2332
  import path17 from "path";
2232
- import * as p6 from "@clack/prompts";
2333
+ import * as p7 from "@clack/prompts";
2233
2334
 
2234
2335
  // core-engine/schema/schema-reader.ts
2235
2336
  import fs9 from "fs";
@@ -3555,12 +3656,12 @@ async function resolveTextEnvValue(options) {
3555
3656
  if (existingValue) {
3556
3657
  return existingValue;
3557
3658
  }
3558
- const result = await p6.text({
3659
+ const result = await p7.text({
3559
3660
  message: options.message,
3560
3661
  defaultValue: options.defaultValue,
3561
3662
  validate: options.validate
3562
3663
  });
3563
- if (p6.isCancel(result)) {
3664
+ if (p7.isCancel(result)) {
3564
3665
  throw new Error(options.cancelMessage);
3565
3666
  }
3566
3667
  options.overwriteEnvKeys.add(options.key);
@@ -3571,11 +3672,11 @@ async function resolvePasswordEnvValue(options) {
3571
3672
  if (existingValue) {
3572
3673
  return existingValue;
3573
3674
  }
3574
- const result = await p6.password({
3675
+ const result = await p7.password({
3575
3676
  message: options.message,
3576
3677
  validate: options.validate
3577
3678
  });
3578
- if (p6.isCancel(result)) {
3679
+ if (p7.isCancel(result)) {
3579
3680
  throw new Error(options.cancelMessage);
3580
3681
  }
3581
3682
  options.overwriteEnvKeys.add(options.key);
@@ -17924,7 +18025,7 @@ function readPresetTemplate(presetId, relativePath) {
17924
18025
  // adapters/next/snapshots/apply.ts
17925
18026
  import fs20 from "fs";
17926
18027
  import path24 from "path";
17927
- import * as p7 from "@clack/prompts";
18028
+ import * as p8 from "@clack/prompts";
17928
18029
 
17929
18030
  // core-engine/snapshots/ast-substitution.ts
17930
18031
  import { Node, Project } from "ts-morph";
@@ -18286,7 +18387,7 @@ function hasConflictMarkers(content) {
18286
18387
  }
18287
18388
 
18288
18389
  // adapters/next/snapshots/format-for-merge.ts
18289
- import { execFileSync as execFileSync3 } from "child_process";
18390
+ import { execFileSync as execFileSync2 } from "child_process";
18290
18391
  import fs18 from "fs";
18291
18392
  import path22 from "path";
18292
18393
  var BIOME_FORMAT_TIMEOUT_MS2 = 15e3;
@@ -18336,7 +18437,7 @@ function formatContentForSnapshotMerge(cwd, filePath, content) {
18336
18437
  const configPath = findBiomeConfig(cwd);
18337
18438
  const targetPath = path22.join(cwd, ...filePath.split("/"));
18338
18439
  try {
18339
- return execFileSync3(
18440
+ return execFileSync2(
18340
18441
  biomeBin,
18341
18442
  [
18342
18443
  "check",
@@ -18591,7 +18692,7 @@ function isInteractiveSession2(interactive) {
18591
18692
  return interactive && Boolean(process.stdin.isTTY) && process.env.CI !== "true";
18592
18693
  }
18593
18694
  async function promptNoBaseDecision(filePath) {
18594
- const answer = await p7.select({
18695
+ const answer = await p8.select({
18595
18696
  message: `File already exists without snapshot base: ${filePath}`,
18596
18697
  options: [
18597
18698
  { value: "backup", label: "Backup and overwrite", hint: "recommended" },
@@ -18600,7 +18701,7 @@ async function promptNoBaseDecision(filePath) {
18600
18701
  ],
18601
18702
  initialValue: "backup"
18602
18703
  });
18603
- if (p7.isCancel(answer)) {
18704
+ if (p8.isCancel(answer)) {
18604
18705
  throw new Error("Generation cancelled.");
18605
18706
  }
18606
18707
  return answer;
@@ -19481,18 +19582,18 @@ async function runAddCommand(items, options) {
19481
19582
  const presetIds = items.filter(isPresetId);
19482
19583
  const integrationIds = items.filter(isIntegrationId);
19483
19584
  if (!installIntegrationsMode && integrationIds.length > 0) {
19484
- p8.log.error(
19585
+ p9.log.error(
19485
19586
  `Integration IDs require --integration. Run \`betterstart add --integration ${integrationIds.join(" ")}\`.`
19486
19587
  );
19487
19588
  process.exit(1);
19488
19589
  }
19489
19590
  if (installIntegrationsMode && presetIds.length > 0) {
19490
- p8.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
19591
+ p9.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
19491
19592
  process.exit(1);
19492
19593
  }
19493
19594
  const invalidItems = installIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
19494
19595
  if (invalidItems.length > 0) {
19495
- p8.log.error(
19596
+ p9.log.error(
19496
19597
  installIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
19497
19598
  );
19498
19599
  process.exit(1);
@@ -19503,7 +19604,7 @@ async function runAddCommand(items, options) {
19503
19604
  const pm = detectPackageManager(cwd);
19504
19605
  const cliSyncResult = await syncProjectCliDependency(cwd, pm);
19505
19606
  if (cliSyncResult && !cliSyncResult.success) {
19506
- p8.log.error(cliSyncResult.error ?? "Failed to sync betterstart-cli");
19607
+ p9.log.error(cliSyncResult.error ?? "Failed to sync betterstart-cli");
19507
19608
  process.exit(1);
19508
19609
  }
19509
19610
  if (installIntegrationsMode) {
@@ -19517,10 +19618,10 @@ async function runAddCommand(items, options) {
19517
19618
  });
19518
19619
  writeConfigFile(cwd, result2.config);
19519
19620
  if (result2.warnings.length > 0) {
19520
- p8.note(result2.warnings.join("\n"), "Warnings");
19621
+ p9.note(result2.warnings.join("\n"), "Warnings");
19521
19622
  }
19522
19623
  if (result2.installed.length === 0 && result2.activated.length === 0 && result2.skipped.length > 0) {
19523
- p8.outro(`No changes made. Already installed: ${result2.skipped.join(", ")}`);
19624
+ p9.outro(`No changes made. Already installed: ${result2.skipped.join(", ")}`);
19524
19625
  return;
19525
19626
  }
19526
19627
  const conflictPaths2 = scanConflictPaths(cwd);
@@ -19542,12 +19643,12 @@ async function runAddCommand(items, options) {
19542
19643
  result2.installed.length > 0 ? `Installed integration${result2.installed.length === 1 ? "" : "s"}: ${result2.installed.join(", ")}` : null,
19543
19644
  result2.activated.length > 0 ? `Activated integration${result2.activated.length === 1 ? "" : "s"}: ${result2.activated.join(", ")}` : null
19544
19645
  ].filter(Boolean);
19545
- p8.outro(messages.join("\n"));
19646
+ p9.outro(messages.join("\n"));
19546
19647
  return;
19547
19648
  }
19548
19649
  const invalidPresets = items.filter((presetId) => !isPresetId(presetId));
19549
19650
  if (invalidPresets.length > 0) {
19550
- p8.log.error(formatUnknownPresetMessage(invalidPresets));
19651
+ p9.log.error(formatUnknownPresetMessage(invalidPresets));
19551
19652
  process.exit(1);
19552
19653
  }
19553
19654
  const result = await installPresets({
@@ -19560,11 +19661,11 @@ async function runAddCommand(items, options) {
19560
19661
  });
19561
19662
  writeConfigFile(cwd, result.config);
19562
19663
  if (result.installed.length === 0 && result.skipped.length > 0) {
19563
- p8.outro(`No changes made. Already installed: ${result.skipped.join(", ")}`);
19664
+ p9.outro(`No changes made. Already installed: ${result.skipped.join(", ")}`);
19564
19665
  return;
19565
19666
  }
19566
19667
  if (result.warnings.length > 0) {
19567
- p8.note(result.warnings.join("\n"), "Warnings");
19668
+ p9.note(result.warnings.join("\n"), "Warnings");
19568
19669
  }
19569
19670
  const installedSchemaNames = result.installed.flatMap(
19570
19671
  (presetId) => getPresetDefinition(presetId).schemaFiles.map((schemaFile) => schemaFile.replace(/\.json$/, ""))
@@ -19581,7 +19682,7 @@ async function runAddCommand(items, options) {
19581
19682
  if (conflictPaths.length === 0) {
19582
19683
  printAddNextSteps("preset", hasSchemaChanges, postGenerateResult, adminRoutePath);
19583
19684
  }
19584
- p8.outro(
19685
+ p9.outro(
19585
19686
  `Installed preset${result.installed.length === 1 ? "" : "s"}: ${result.installed.join(", ")}`
19586
19687
  );
19587
19688
  }
@@ -20332,88 +20433,6 @@ function diffSchemas(before, after) {
20332
20433
  };
20333
20434
  }
20334
20435
 
20335
- // core-engine/utils/spinner.ts
20336
- import { stripVTControlCharacters } from "util";
20337
- import * as p9 from "@clack/prompts";
20338
- var RENDER_OVERHEAD = 7;
20339
- var MIN_MESSAGE_WIDTH = 8;
20340
- function fitSpinnerMessage(message) {
20341
- const normalized = message.replace(/\t/g, " ");
20342
- const columns = process.stdout.columns ?? 80;
20343
- const max = Math.max(columns - RENDER_OVERHEAD, MIN_MESSAGE_WIDTH);
20344
- const visible = stripVTControlCharacters(normalized);
20345
- if (visible.length <= max) return normalized;
20346
- return `${visible.slice(0, max - 1)}\u2026`;
20347
- }
20348
- var CLACK_LINE_ROWS = 2;
20349
- var LOG_PREFIX_WIDTH = 3;
20350
- function clackPromptRows(message, value) {
20351
- const columns = process.stdout.columns ?? 80;
20352
- const rows = (text7) => Math.max(1, Math.ceil((stripVTControlCharacters(text7).length + LOG_PREFIX_WIDTH) / columns));
20353
- return 1 + rows(message) + rows(value);
20354
- }
20355
- function clackLogRows(message) {
20356
- const columns = process.stdout.columns ?? 80;
20357
- const width = stripVTControlCharacters(message).length + LOG_PREFIX_WIDTH;
20358
- return 1 + Math.max(1, Math.ceil(width / columns));
20359
- }
20360
- function eraseRows(rows) {
20361
- if (rows <= 0 || !process.stdout.isTTY || process.env.CI === "true") return;
20362
- process.stdout.write(`\x1B[${rows}A\x1B[${rows}M`);
20363
- }
20364
- function eraseRowsAbove(rows, rowsBelow) {
20365
- if (rows <= 0 || rowsBelow < 0 || !process.stdout.isTTY || process.env.CI === "true") {
20366
- return;
20367
- }
20368
- const up = rows + rowsBelow;
20369
- const restore = rowsBelow > 0 ? `\x1B[${rowsBelow}B` : "";
20370
- process.stdout.write(`\x1B[${up}A\x1B[${rows}M${restore}`);
20371
- }
20372
- function eraseClackLine(options = {}) {
20373
- if (!process.stdout.isTTY || process.env.CI === "true") return;
20374
- const below = (options.linesBelow ?? 0) * CLACK_LINE_ROWS;
20375
- const up = below + CLACK_LINE_ROWS;
20376
- const restore = below > 0 ? `\x1B[${below}B` : "";
20377
- process.stdout.write(`\x1B[${up}A\x1B[${CLACK_LINE_ROWS}M${restore}`);
20378
- }
20379
- var activeSpinners = 0;
20380
- function hasActiveSpinner() {
20381
- return activeSpinners > 0;
20382
- }
20383
- function spinner2(options) {
20384
- const inner = p9.spinner({ ...options, cancelMessage: "Setup cancelled." });
20385
- const guided = options?.withGuide !== false;
20386
- let started = false;
20387
- const setStarted = (next) => {
20388
- if (started === next) return;
20389
- started = next;
20390
- activeSpinners += next ? 1 : -1;
20391
- };
20392
- return {
20393
- start: (message = "") => {
20394
- if (started) {
20395
- inner.message(fitSpinnerMessage(message));
20396
- return;
20397
- }
20398
- setStarted(true);
20399
- inner.start(fitSpinnerMessage(message));
20400
- },
20401
- message: (message = "") => inner.message(fitSpinnerMessage(message)),
20402
- stop: (message = "") => {
20403
- setStarted(false);
20404
- inner.stop(message);
20405
- },
20406
- clear: () => {
20407
- if (!started) return;
20408
- setStarted(false);
20409
- inner.clear();
20410
- if (guided && process.stdout.isTTY && process.env.CI !== "true") {
20411
- process.stdout.write("\x1B[1A\x1B[2K");
20412
- }
20413
- }
20414
- };
20415
- }
20416
-
20417
20436
  // adapters/next/commands/generate.ts
20418
20437
  function isInteractiveSession3() {
20419
20438
  return Boolean(process.stdin.isTTY) && process.env.CI !== "true";
@@ -22403,7 +22422,7 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
22403
22422
  }
22404
22423
 
22405
22424
  // adapters/next/commands/init.ts
22406
- import { execFileSync as execFileSync5, spawn as spawn6 } from "child_process";
22425
+ import { execFileSync as execFileSync4, spawn as spawn6 } from "child_process";
22407
22426
  import fs41 from "fs";
22408
22427
  import path52 from "path";
22409
22428
  import { PassThrough } from "stream";
@@ -22468,7 +22487,7 @@ function redactSecrets(text7) {
22468
22487
  }
22469
22488
 
22470
22489
  // adapters/next/init/prompts/database.ts
22471
- import { execFileSync as execFileSync4 } from "child_process";
22490
+ import { execFileSync as execFileSync3 } from "child_process";
22472
22491
  import * as p15 from "@clack/prompts";
22473
22492
  import pc from "picocolors";
22474
22493
  var VERCEL_NEON_URL = "https://vercel.com/dashboard/integrations/checkout/neon";
@@ -22548,11 +22567,11 @@ function openBrowser(url) {
22548
22567
  try {
22549
22568
  const platform = process.platform;
22550
22569
  if (platform === "darwin") {
22551
- execFileSync4("open", [url], { stdio: "ignore" });
22570
+ execFileSync3("open", [url], { stdio: "ignore" });
22552
22571
  } else if (platform === "win32") {
22553
- execFileSync4("cmd", ["/c", "start", url], { stdio: "ignore" });
22572
+ execFileSync3("cmd", ["/c", "start", url], { stdio: "ignore" });
22554
22573
  } else {
22555
- execFileSync4("xdg-open", [url], { stdio: "ignore" });
22574
+ execFileSync3("xdg-open", [url], { stdio: "ignore" });
22556
22575
  }
22557
22576
  } catch {
22558
22577
  }
@@ -27214,10 +27233,10 @@ async function runSeedCommand(options) {
27214
27233
  }
27215
27234
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
27216
27235
  fs40.writeFileSync(seedPath, buildSeedScript(`${namespace.apiPath}/auth`), "utf-8");
27217
- const { execFile } = await import("child_process");
27236
+ const { execFile: execFile2 } = await import("child_process");
27218
27237
  const tsxBin = path51.join(cwd, "node_modules", ".bin", "tsx");
27219
27238
  const runSeed2 = (overwrite) => new Promise((resolve, reject) => {
27220
- execFile(
27239
+ execFile2(
27221
27240
  tsxBin,
27222
27241
  [seedPath],
27223
27242
  {
@@ -28192,9 +28211,9 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28192
28211
  if (isFreshProject) {
28193
28212
  s.start("Creating initial git commit");
28194
28213
  try {
28195
- execFileSync5("git", ["init"], { cwd, stdio: "pipe" });
28196
- execFileSync5("git", ["add", "."], { cwd, stdio: "pipe" });
28197
- execFileSync5("git", ["commit", "-m", "Initial commit from BetterStart"], {
28214
+ execFileSync4("git", ["init"], { cwd, stdio: "pipe" });
28215
+ execFileSync4("git", ["add", "."], { cwd, stdio: "pipe" });
28216
+ execFileSync4("git", ["commit", "-m", "Initial commit from BetterStart"], {
28198
28217
  cwd,
28199
28218
  stdio: "pipe"
28200
28219
  });
@@ -29466,7 +29485,7 @@ async function runUninstallCommand(options) {
29466
29485
  }
29467
29486
 
29468
29487
  // adapters/next/commands/update-component.ts
29469
- import { execFileSync as execFileSync6 } from "child_process";
29488
+ import { execFileSync as execFileSync5 } from "child_process";
29470
29489
  import fs45 from "fs";
29471
29490
  import path59 from "path";
29472
29491
  import * as clack4 from "@clack/prompts";
@@ -31745,7 +31764,7 @@ function runShadcnPresetUpdate({
31745
31764
  if (only) {
31746
31765
  args.push("--only", only);
31747
31766
  }
31748
- execFileSync6(shadcnBin, args, { cwd, stdio: "inherit" });
31767
+ execFileSync5(shadcnBin, args, { cwd, stdio: "inherit" });
31749
31768
  } catch {
31750
31769
  failed = true;
31751
31770
  } finally {