betterstart-cli 0.0.90 → 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
@@ -22,10 +22,9 @@ import {
22
22
 
23
23
  // cli.ts
24
24
  import { readFileSync } from "fs";
25
- import * as p30 from "@clack/prompts";
25
+ import * as p31 from "@clack/prompts";
26
26
 
27
- // core-engine/commands/require-init.ts
28
- import path2 from "path";
27
+ // core-engine/commands/default-action.ts
29
28
  import * as p from "@clack/prompts";
30
29
 
31
30
  // core-engine/config/resolver.ts
@@ -49,22 +48,9 @@ async function loadConfigFile(configPath) {
49
48
  return mod.default || mod;
50
49
  }
51
50
 
52
- // core-engine/commands/require-init.ts
53
- var INIT_COMMAND = "init";
54
- function resolveCommandCwd(command) {
55
- const options = command.opts();
56
- return typeof options.cwd === "string" ? path2.resolve(options.cwd) : process.cwd();
57
- }
58
- function requireInitializedProject(command) {
59
- if (command.name() === INIT_COMMAND) {
60
- return;
61
- }
62
- const cwd = resolveCommandCwd(command);
63
- if (findConfigFile(cwd)) {
64
- return;
65
- }
66
- p.log.error("Couldn't find betterstart project. Please run `betterstart init` first.");
67
- process.exit(1);
51
+ // core-engine/utils/interactive.ts
52
+ function isInteractiveSession() {
53
+ return Boolean(process.stdin.isTTY) && process.env.CI !== "true";
68
54
  }
69
55
 
70
56
  // core-engine/commands/runtime.ts
@@ -196,9 +182,142 @@ function createUpdateStylesCommand(runtime) {
196
182
  return new Command("update-styles").description("Replace admin-globals.css with the latest version from the CLI").option("--cwd <path>", "Project root path").action((options) => runtime.runUpdateStyles(options));
197
183
  }
198
184
 
185
+ // core-engine/commands/default-action.ts
186
+ var ADD_COMMAND = "add";
187
+ var CREATE_COMMAND = "create";
188
+ var INIT_COMMAND = "init";
189
+ var REMOVE_COMMAND = "remove";
190
+ var REMOVE_SCHEMA_COMMAND = "remove-schema";
191
+ var CANCELLED = /* @__PURE__ */ Symbol("cancelled");
192
+ function cancelled(value) {
193
+ return value === CANCELLED;
194
+ }
195
+ async function runDefaultAction(program2, runtime) {
196
+ if (!isInteractiveSession()) {
197
+ program2.outputHelp();
198
+ return;
199
+ }
200
+ const cwd = process.cwd();
201
+ if (!findConfigFile(cwd)) {
202
+ await program2.parseAsync([INIT_COMMAND], { from: "user" });
203
+ return;
204
+ }
205
+ const argv = await promptInvocation(program2, runtime, cwd);
206
+ if (cancelled(argv)) {
207
+ p.cancel("No command selected.");
208
+ return;
209
+ }
210
+ await program2.parseAsync(argv, { from: "user" });
211
+ }
212
+ async function promptInvocation(program2, runtime, cwd) {
213
+ const name = await p.select({
214
+ message: "What do you want to do?",
215
+ options: program2.commands.map((command) => ({
216
+ value: command.name(),
217
+ label: command.name(),
218
+ hint: command.description()
219
+ }))
220
+ });
221
+ if (p.isCancel(name)) {
222
+ return CANCELLED;
223
+ }
224
+ const args = await promptRequiredArguments(name, runtime, cwd);
225
+ if (cancelled(args)) {
226
+ return CANCELLED;
227
+ }
228
+ return [name, ...args];
229
+ }
230
+ async function promptRequiredArguments(name, runtime, cwd) {
231
+ if (name === CREATE_COMMAND) {
232
+ const kind = await p.select({
233
+ message: "Schema kind",
234
+ options: CREATE_SCHEMA_KINDS.map((value) => ({ value, label: value }))
235
+ });
236
+ return p.isCancel(kind) ? CANCELLED : [kind];
237
+ }
238
+ if (name === ADD_COMMAND || name === REMOVE_COMMAND) {
239
+ return promptInstallables(name, runtime, cwd);
240
+ }
241
+ if (name === REMOVE_SCHEMA_COMMAND) {
242
+ const schemas = await runtime.listSchemaChoices(cwd);
243
+ if (schemas.length === 0) {
244
+ p.log.warn("No schemas to remove.");
245
+ return CANCELLED;
246
+ }
247
+ const schema = await p.select({
248
+ message: "Schema to remove",
249
+ options: schemas.map((value) => ({ value, label: value }))
250
+ });
251
+ return p.isCancel(schema) ? CANCELLED : [schema];
252
+ }
253
+ return [];
254
+ }
255
+ async function promptInstallables(name, runtime, cwd) {
256
+ const removing = name === REMOVE_COMMAND;
257
+ const choices = await runtime.listInstallableChoices(cwd);
258
+ const presets = choices.presets.filter((choice) => choice.installed === removing);
259
+ const integrations = choices.integrations.filter((choice) => choice.installed === removing);
260
+ if (presets.length === 0 && integrations.length === 0) {
261
+ p.log.warn(removing ? "Nothing installed to remove." : "Everything available is installed.");
262
+ return CANCELLED;
263
+ }
264
+ const family = await promptInstallableFamily(presets, integrations);
265
+ if (cancelled(family)) {
266
+ return CANCELLED;
267
+ }
268
+ const items = await p.multiselect({
269
+ message: removing ? "Items to remove" : "Items to install",
270
+ options: (family === "integration" ? integrations : presets).map((choice) => ({
271
+ value: choice.id,
272
+ label: choice.id,
273
+ hint: choice.description
274
+ }))
275
+ });
276
+ if (p.isCancel(items)) {
277
+ return CANCELLED;
278
+ }
279
+ return family === "integration" ? ["--integration", ...items] : items;
280
+ }
281
+ async function promptInstallableFamily(presets, integrations) {
282
+ if (integrations.length === 0) {
283
+ return "preset";
284
+ }
285
+ if (presets.length === 0) {
286
+ return "integration";
287
+ }
288
+ const family = await p.select({
289
+ message: "Presets or integrations?",
290
+ options: [
291
+ { value: "preset", label: "Presets", hint: "content presets (e.g. blog)" },
292
+ { value: "integration", label: "Integrations", hint: "services (e.g. r2, resend)" }
293
+ ]
294
+ });
295
+ return p.isCancel(family) ? CANCELLED : family;
296
+ }
297
+
298
+ // core-engine/commands/require-init.ts
299
+ import path2 from "path";
300
+ import * as p2 from "@clack/prompts";
301
+ var INIT_COMMAND2 = "init";
302
+ function resolveCommandCwd(command) {
303
+ const options = command.opts();
304
+ return typeof options.cwd === "string" ? path2.resolve(options.cwd) : process.cwd();
305
+ }
306
+ function requireInitializedProject(command) {
307
+ if (command.name() === INIT_COMMAND2) {
308
+ return;
309
+ }
310
+ const cwd = resolveCommandCwd(command);
311
+ if (findConfigFile(cwd)) {
312
+ return;
313
+ }
314
+ p2.log.error("Couldn't find betterstart project. Please run `betterstart init` first.");
315
+ process.exit(1);
316
+ }
317
+
199
318
  // adapters/next/commands/add.ts
200
319
  import path27 from "path";
201
- import * as p7 from "@clack/prompts";
320
+ import * as p9 from "@clack/prompts";
202
321
 
203
322
  // core-engine/config/serialize.ts
204
323
  import fs3 from "fs";
@@ -747,10 +866,93 @@ async function resolveConfigOrExit(cwd) {
747
866
  }
748
867
 
749
868
  // adapters/next/generators/post-generate.ts
750
- import { execFileSync as execFileSync2 } from "child_process";
869
+ import { execFile } from "child_process";
751
870
  import fs8 from "fs";
752
871
  import path10 from "path";
753
- import * as p4 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
+ }
754
956
 
755
957
  // adapters/next/init/scaffolders/dependencies.ts
756
958
  import { spawn } from "child_process";
@@ -1633,7 +1835,7 @@ async function syncProjectCliDependency(cwd, pm) {
1633
1835
  // adapters/next/utils/drizzle-push.ts
1634
1836
  import { spawn as spawn2 } from "child_process";
1635
1837
  import path9 from "path";
1636
- import * as p2 from "@clack/prompts";
1838
+ import * as p4 from "@clack/prompts";
1637
1839
  var PG_SSL_WARNING_START = "Warning: SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.";
1638
1840
  var PG_SSL_WARNING_END = "See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode definitions.";
1639
1841
  var NODE_TRACE_WARNING_HINT = "(Use `node --trace-warnings";
@@ -1809,7 +2011,7 @@ function runDrizzlePush(cwd, options = {}) {
1809
2011
  }
1810
2012
  if (stdoutTtySuppressor.sawError() || stderrTtySuppressor.sawError()) {
1811
2013
  notifyOutput();
1812
- p2.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.");
1813
2015
  const attached = spawn2(drizzleBin, ["push", "--force"], {
1814
2016
  cwd,
1815
2017
  stdio: "inherit",
@@ -1855,7 +2057,7 @@ ${stderr}`.trim();
1855
2057
  }
1856
2058
 
1857
2059
  // adapters/next/utils/next-steps.ts
1858
- import * as p3 from "@clack/prompts";
2060
+ import * as p5 from "@clack/prompts";
1859
2061
  function printNextSteps(options) {
1860
2062
  const steps = [`1. Review ${options.reviewLabel}`];
1861
2063
  if (options.needsMigration) {
@@ -1864,11 +2066,12 @@ function printNextSteps(options) {
1864
2066
  } else {
1865
2067
  steps.push(`2. Start the dev server and visit ${options.route}`);
1866
2068
  }
1867
- p3.note(steps.join("\n"), "Next steps");
2069
+ p5.note(steps.join("\n"), "Next steps");
1868
2070
  }
1869
2071
 
1870
2072
  // adapters/next/generators/post-generate.ts
1871
2073
  var BIOME_FORMAT_TIMEOUT_MS = 3e4;
2074
+ var execFileAsync = promisify(execFile);
1872
2075
  function loadEnvFile(cwd) {
1873
2076
  const envPath = path10.join(cwd, ".env.local");
1874
2077
  if (!fs8.existsSync(envPath)) return;
@@ -1892,10 +2095,10 @@ function loadEnvFile(cwd) {
1892
2095
  }
1893
2096
  }
1894
2097
  }
1895
- function runPmScript(pm, script, cwd, timeout) {
2098
+ async function runPmScript(pm, script, cwd, timeout) {
1896
2099
  const args = pm === "bun" ? ["run", script] : [script];
1897
2100
  try {
1898
- execFileSync2(pm, args, { cwd, stdio: "pipe", timeout });
2101
+ await execFileAsync(pm, args, { cwd, timeout });
1899
2102
  return true;
1900
2103
  } catch {
1901
2104
  return false;
@@ -1906,7 +2109,7 @@ function getExistingTrackedFilePaths(cwd) {
1906
2109
  (filePath) => fs8.existsSync(path10.join(cwd, ...filePath.split("/")))
1907
2110
  );
1908
2111
  }
1909
- function runBiomeCheckWrite(cwd) {
2112
+ async function runBiomeCheckWrite(cwd) {
1910
2113
  const biomeBin = path10.join(cwd, "node_modules", ".bin", "biome");
1911
2114
  if (!fs8.existsSync(biomeBin)) {
1912
2115
  return false;
@@ -1925,9 +2128,8 @@ function runBiomeCheckWrite(cwd) {
1925
2128
  ...configPath ? ["--config-path", configPath] : [],
1926
2129
  ...chunk
1927
2130
  ];
1928
- execFileSync2(biomeBin, args, {
2131
+ await execFileAsync(biomeBin, args, {
1929
2132
  cwd,
1930
- stdio: "pipe",
1931
2133
  timeout: BIOME_FORMAT_TIMEOUT_MS
1932
2134
  });
1933
2135
  }
@@ -1944,18 +2146,15 @@ function buildAddDependencyArgs(pm, dependency, dev) {
1944
2146
  return ["install", ...devFlag ? [devFlag] : [], dependency];
1945
2147
  }
1946
2148
  }
1947
- function installDependency(cwd, pm, dependency, dev = false) {
2149
+ async function installDependency(cwd, pm, dependency, dev = false) {
1948
2150
  try {
1949
- execFileSync2(pm, buildAddDependencyArgs(pm, dependency, dev), {
1950
- cwd,
1951
- stdio: "pipe"
1952
- });
2151
+ await execFileAsync(pm, buildAddDependencyArgs(pm, dependency, dev), { cwd });
1953
2152
  return true;
1954
2153
  } catch {
1955
2154
  return false;
1956
2155
  }
1957
2156
  }
1958
- function ensureDatabasePushDependencies(cwd, pm) {
2157
+ async function ensureDatabasePushDependencies(cwd, pm) {
1959
2158
  const missing = [];
1960
2159
  if (!hasPostgresRuntimeDependency(cwd)) {
1961
2160
  missing.push({ name: POSTGRES_RUNTIME_DEP, dev: false });
@@ -1966,25 +2165,25 @@ function ensureDatabasePushDependencies(cwd, pm) {
1966
2165
  if (missing.length === 0) {
1967
2166
  return true;
1968
2167
  }
1969
- p4.log.info(
2168
+ p6.log.info(
1970
2169
  `Installing database push dependencies (${missing.map((dependency) => dependency.name).join(", ")})...`
1971
2170
  );
1972
2171
  for (const dependency of missing) {
1973
- const installed2 = installDependency(cwd, pm, dependency.name, dependency.dev);
2172
+ const installed2 = await installDependency(cwd, pm, dependency.name, dependency.dev);
1974
2173
  if (!installed2) {
1975
- p4.log.warn(`Failed to install ${dependency.name}`);
2174
+ p6.log.warn(`Failed to install ${dependency.name}`);
1976
2175
  return false;
1977
2176
  }
1978
2177
  }
1979
2178
  const ready = hasPostgresRuntimeDependency(cwd) && hasDrizzleKitPostgresDriverDependency(cwd);
1980
2179
  if (ready) {
1981
- p4.log.success("Database push dependencies installed");
2180
+ p6.log.success("Database push dependencies installed");
1982
2181
  } else {
1983
2182
  const unresolved = [
1984
2183
  !hasPostgresRuntimeDependency(cwd) ? POSTGRES_RUNTIME_DEP : null,
1985
2184
  !hasDrizzleKitPostgresDriverDependency(cwd) ? DRIZZLE_KIT_POSTGRES_DRIVER_DEP : null
1986
2185
  ].filter((dependency) => Boolean(dependency));
1987
- p4.log.warn(`Installed dependencies but could not resolve ${unresolved.join(", ")}`);
2186
+ p6.log.warn(`Installed dependencies but could not resolve ${unresolved.join(", ")}`);
1988
2187
  }
1989
2188
  return ready;
1990
2189
  }
@@ -2027,8 +2226,8 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2027
2226
  "Formatting: skipped (biome refuses files with conflict markers)",
2028
2227
  ...(options.conflictPaths ?? []).map((conflictPath) => ` - ${conflictPath}`)
2029
2228
  ];
2030
- p4.log.warn(lines.join("\n"));
2031
- p4.log.message(
2229
+ p6.log.warn(lines.join("\n"));
2230
+ p6.log.message(
2032
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."
2033
2232
  );
2034
2233
  return result;
@@ -2038,62 +2237,83 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2038
2237
  const dbUrl = process.env.DATABASE_URL;
2039
2238
  if (!dbUrl) {
2040
2239
  result.dbPush = "no-db-url";
2041
- p4.log.warn(
2240
+ p6.log.warn(
2042
2241
  [
2043
2242
  "Database: skipped (no DATABASE_URL configured)",
2044
2243
  " To sync later: run db:push after setting DATABASE_URL"
2045
2244
  ].join("\n")
2046
2245
  );
2047
- } else if (!ensureDatabasePushDependencies(cwd, pm)) {
2246
+ } else if (!await ensureDatabasePushDependencies(cwd, pm)) {
2048
2247
  result.dbPush = "failed";
2049
- p4.log.warn(
2248
+ p6.log.warn(
2050
2249
  "Database push failed (install database dependencies and run drizzle-kit push manually)"
2051
2250
  );
2052
2251
  } else if (hasPkgScript(cwd, "db:push")) {
2053
- p4.log.info("Running db:push...");
2054
- 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);
2055
2255
  result.dbPush = ok ? "success" : "failed";
2056
2256
  if (ok) {
2057
- p4.log.success("Database schema synced");
2257
+ s.stop("Database schema synced");
2058
2258
  } else {
2059
- p4.log.warn("Database push failed (run db:push manually)");
2259
+ s.clear();
2260
+ p6.log.warn("Database push failed (run db:push manually)");
2060
2261
  }
2061
2262
  } else {
2062
- p4.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");
2063
2271
  try {
2064
- const pushResult = await runDrizzlePush(cwd, { interactive: true });
2272
+ const pushResult = await runDrizzlePush(cwd, {
2273
+ interactive: true,
2274
+ onOutput: clearSpinner
2275
+ });
2065
2276
  if (!pushResult.success) {
2066
2277
  throw new Error(pushResult.error ?? "drizzle-kit push failed");
2067
2278
  }
2068
2279
  result.dbPush = "success";
2069
- p4.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
+ }
2070
2286
  } catch {
2071
2287
  result.dbPush = "failed";
2072
- p4.log.warn("Database push failed (run drizzle-kit push manually)");
2288
+ clearSpinner();
2289
+ p6.log.warn("Database push failed (run drizzle-kit push manually)");
2073
2290
  }
2074
2291
  }
2075
2292
  } else {
2076
- p4.log.info(`Database: skipped (${options.skipMigrationMessage ?? "--skip-migration"})`);
2293
+ p6.log.info(`Database: skipped (${options.skipMigrationMessage ?? "--skip-migration"})`);
2077
2294
  }
2295
+ const formatSpinner = spinner2();
2296
+ formatSpinner.start("Formatting generated files");
2078
2297
  if (hasPkgScript(cwd, "lint:fix")) {
2079
- p4.log.info("Running lint:fix...");
2080
- const ok = runPmScript(pm, "lint:fix", cwd, BIOME_FORMAT_TIMEOUT_MS);
2298
+ const ok = await runPmScript(pm, "lint:fix", cwd, BIOME_FORMAT_TIMEOUT_MS);
2081
2299
  result.lintFix = ok ? "success" : "failed";
2082
2300
  if (ok) {
2083
- p4.log.success("Code formatted");
2301
+ formatSpinner.stop("Code formatted");
2084
2302
  } else {
2085
- p4.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)");
2086
2305
  }
2087
2306
  } else {
2088
2307
  try {
2089
- if (!runBiomeCheckWrite(cwd)) {
2308
+ if (!await runBiomeCheckWrite(cwd)) {
2090
2309
  throw new Error("Biome binary not found");
2091
2310
  }
2092
2311
  result.lintFix = "success";
2093
- p4.log.success("Code formatted with Biome");
2312
+ formatSpinner.stop("Code formatted with Biome");
2094
2313
  } catch {
2095
2314
  result.lintFix = "failed";
2096
- p4.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)");
2097
2317
  }
2098
2318
  }
2099
2319
  if (options.showNextSteps !== false) {
@@ -2110,7 +2330,7 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2110
2330
  // adapters/next/integration-runtime.ts
2111
2331
  import fs14 from "fs";
2112
2332
  import path17 from "path";
2113
- import * as p5 from "@clack/prompts";
2333
+ import * as p7 from "@clack/prompts";
2114
2334
 
2115
2335
  // core-engine/schema/schema-reader.ts
2116
2336
  import fs9 from "fs";
@@ -2916,15 +3136,15 @@ function collectSchemaSlotLayoutErrors(schema, errors) {
2916
3136
  }
2917
3137
  collectSlotLayoutErrors(input.slot, "slot", errors);
2918
3138
  }
2919
- function collectSlotLayoutErrors(value, path61, errors) {
3139
+ function collectSlotLayoutErrors(value, path62, errors) {
2920
3140
  if (!isRecord(value)) {
2921
- errors.push(`${path61} must be an object with "main" and/or "sidebar" field groups.`);
3141
+ errors.push(`${path62} must be an object with "main" and/or "sidebar" field groups.`);
2922
3142
  return;
2923
3143
  }
2924
3144
  const validKeys = /* @__PURE__ */ new Set(["main", "sidebar"]);
2925
3145
  for (const key of Object.keys(value)) {
2926
3146
  if (!validKeys.has(key)) {
2927
- errors.push(`${path61} has unsupported key "${key}". Expected "main" or "sidebar".`);
3147
+ errors.push(`${path62} has unsupported key "${key}". Expected "main" or "sidebar".`);
2928
3148
  }
2929
3149
  }
2930
3150
  const areas = [
@@ -2935,24 +3155,24 @@ function collectSlotLayoutErrors(value, path61, errors) {
2935
3155
  for (const [name, area] of areas) {
2936
3156
  if (area === void 0) continue;
2937
3157
  hasArea = true;
2938
- collectSlotAreaErrors(area, `${path61}.${name}`, errors);
3158
+ collectSlotAreaErrors(area, `${path62}.${name}`, errors);
2939
3159
  }
2940
3160
  if (!hasArea) {
2941
- errors.push(`${path61} must define at least one of "main" or "sidebar".`);
3161
+ errors.push(`${path62} must define at least one of "main" or "sidebar".`);
2942
3162
  }
2943
3163
  }
2944
- function collectSlotAreaErrors(value, path61, errors) {
3164
+ function collectSlotAreaErrors(value, path62, errors) {
2945
3165
  if (!isRecord(value)) {
2946
- errors.push(`${path61} must be an object with a "fields" array.`);
3166
+ errors.push(`${path62} must be an object with a "fields" array.`);
2947
3167
  return;
2948
3168
  }
2949
3169
  const fields = value.fields;
2950
3170
  if (!Array.isArray(fields)) {
2951
- errors.push(`${path61}.fields must be an array.`);
3171
+ errors.push(`${path62}.fields must be an array.`);
2952
3172
  return;
2953
3173
  }
2954
3174
  for (const field of fields) {
2955
- walkSlot(field, `${path61}.fields.${field.name ?? "unnamed"}`, errors);
3175
+ walkSlot(field, `${path62}.fields.${field.name ?? "unnamed"}`, errors);
2956
3176
  }
2957
3177
  }
2958
3178
  function collectInvalidHeightErrors(topLevelFields, rootPath, errors) {
@@ -3436,12 +3656,12 @@ async function resolveTextEnvValue(options) {
3436
3656
  if (existingValue) {
3437
3657
  return existingValue;
3438
3658
  }
3439
- const result = await p5.text({
3659
+ const result = await p7.text({
3440
3660
  message: options.message,
3441
3661
  defaultValue: options.defaultValue,
3442
3662
  validate: options.validate
3443
3663
  });
3444
- if (p5.isCancel(result)) {
3664
+ if (p7.isCancel(result)) {
3445
3665
  throw new Error(options.cancelMessage);
3446
3666
  }
3447
3667
  options.overwriteEnvKeys.add(options.key);
@@ -3452,11 +3672,11 @@ async function resolvePasswordEnvValue(options) {
3452
3672
  if (existingValue) {
3453
3673
  return existingValue;
3454
3674
  }
3455
- const result = await p5.password({
3675
+ const result = await p7.password({
3456
3676
  message: options.message,
3457
3677
  validate: options.validate
3458
3678
  });
3459
- if (p5.isCancel(result)) {
3679
+ if (p7.isCancel(result)) {
3460
3680
  throw new Error(options.cancelMessage);
3461
3681
  }
3462
3682
  options.overwriteEnvKeys.add(options.key);
@@ -4788,9 +5008,9 @@ function getReadFieldType(field) {
4788
5008
  }
4789
5009
  return getFieldType(field, "output");
4790
5010
  }
4791
- function collectReadSelectFields(fields, path61 = []) {
5011
+ function collectReadSelectFields(fields, path62 = []) {
4792
5012
  const matches = fields.flatMap((field) => {
4793
- const currentPath = [...path61, field.name];
5013
+ const currentPath = [...path62, field.name];
4794
5014
  const matches2 = field.type === "select" ? [{ field, path: currentPath }] : [];
4795
5015
  if (field.fields) {
4796
5016
  matches2.push(...collectReadSelectFields(field.fields, currentPath));
@@ -5837,14 +6057,14 @@ function buildStepsConstant(steps) {
5837
6057
  ${entries.join(",\n")}
5838
6058
  ]`;
5839
6059
  }
5840
- function buildComponentSource(p31) {
6060
+ function buildComponentSource(p32) {
5841
6061
  const providerOpen = ` <NuqsAdapter>
5842
6062
  <React.Suspense fallback={null}>
5843
- <${p31.pascal}FormInner />
6063
+ <${p32.pascal}FormInner />
5844
6064
  </React.Suspense>
5845
6065
  </NuqsAdapter>`;
5846
6066
  const exportWrapper = `
5847
- export function ${p31.pascal}Form() {
6067
+ export function ${p32.pascal}Form() {
5848
6068
  return (
5849
6069
  ${providerOpen}
5850
6070
  )
@@ -5853,22 +6073,22 @@ ${providerOpen}
5853
6073
  return `'use client'
5854
6074
 
5855
6075
  import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'
5856
- import { ChevronLeft, ChevronRight${p31.hasListFields ? ", Trash2" : ""} } from 'lucide-react'
6076
+ import { ChevronLeft, ChevronRight${p32.hasListFields ? ", Trash2" : ""} } from 'lucide-react'
5857
6077
  import { createParser, useQueryState } from 'nuqs'
5858
6078
  import { NuqsAdapter } from 'nuqs/adapters/next/app'
5859
6079
  import * as React from 'react'
5860
- ${p31.rhfImport}
6080
+ ${p32.rhfImport}
5861
6081
  import { z } from 'zod/v3'
5862
- import { create${p31.pascal}Submission } from '@admin/actions/${p31.actionImportPath}'
6082
+ import { create${p32.pascal}Submission } from '@admin/actions/${p32.actionImportPath}'
5863
6083
 
5864
6084
  const formSchema = z.object({
5865
- ${p31.zodFields}
6085
+ ${p32.zodFields}
5866
6086
  })
5867
6087
 
5868
6088
  type FormValues = z.infer<typeof formSchema>
5869
6089
  ${buildFieldErrorHelper()}
5870
6090
 
5871
- ${p31.stepsConst}
6091
+ ${p32.stepsConst}
5872
6092
 
5873
6093
  const stepParser = createParser({
5874
6094
  parse(value) {
@@ -5886,7 +6106,7 @@ const stepParser = createParser({
5886
6106
  }
5887
6107
  }).withDefault(0)
5888
6108
 
5889
- function ${p31.pascal}FormInner() {
6109
+ function ${p32.pascal}FormInner() {
5890
6110
  const [currentStep, setCurrentStep] = useQueryState('step', stepParser)
5891
6111
  const [submitted, setSubmitted] = React.useState(false)
5892
6112
  const [submitting, startSubmitTransition] = React.useTransition()
@@ -5894,11 +6114,11 @@ function ${p31.pascal}FormInner() {
5894
6114
  const form = useForm<FormValues>({
5895
6115
  resolver: standardSchemaResolver(formSchema),
5896
6116
  defaultValues: {
5897
- ${p31.defaults}
6117
+ ${p32.defaults}
5898
6118
  },
5899
6119
  })
5900
6120
 
5901
- ${p31.fieldArraySetup}${p31.watchSetup}
6121
+ ${p32.fieldArraySetup}${p32.watchSetup}
5902
6122
  async function handleNext() {
5903
6123
  const stepFields = STEPS[currentStep].fields as (keyof FormValues)[]
5904
6124
  const isValid = await form.trigger(stepFields, { shouldFocus: true })
@@ -5914,9 +6134,9 @@ ${p31.fieldArraySetup}${p31.watchSetup}
5914
6134
  function onSubmit(values: FormValues) {
5915
6135
  startSubmitTransition(async () => {
5916
6136
  try {
5917
- const result = await create${p31.pascal}Submission(values)
6137
+ const result = await create${p32.pascal}Submission(values)
5918
6138
  if (result.success) {
5919
- ${p31.successHandler}
6139
+ ${p32.successHandler}
5920
6140
  } else {
5921
6141
  form.setError('root', { message: result.error || 'Something went wrong' })
5922
6142
  }
@@ -5930,7 +6150,7 @@ ${p31.fieldArraySetup}${p31.watchSetup}
5930
6150
  return (
5931
6151
  <div className="rounded-sm border p-6 text-center">
5932
6152
  <h3 className="text-lg font-semibold">Thank you!</h3>
5933
- <p className="mt-2 text-muted-foreground">${p31.successMessage}</p>
6153
+ <p className="mt-2 text-muted-foreground">${p32.successMessage}</p>
5934
6154
  </div>
5935
6155
  )
5936
6156
  }
@@ -5947,7 +6167,7 @@ ${p31.fieldArraySetup}${p31.watchSetup}
5947
6167
 
5948
6168
  {/* Step content */}
5949
6169
  <div key={currentStep} className="animate-in fade-in duration-300 space-y-6">
5950
- ${p31.stepContentBlocks}
6170
+ ${p32.stepContentBlocks}
5951
6171
  </div>
5952
6172
 
5953
6173
  {form.formState.errors.root && (
@@ -5981,7 +6201,7 @@ ${p31.stepContentBlocks}
5981
6201
  onClick={() => form.handleSubmit(onSubmit)()}
5982
6202
  className="inline-flex h-9 items-center justify-center rounded-md bg-primary px-4 py-2 text-sm font-medium text-primary-foreground shadow-xs transition-colors hover:bg-primary/90 disabled:pointer-events-none disabled:opacity-50"
5983
6203
  >
5984
- {submitting ? 'Submitting...' : ${p31.submitText}}
6204
+ {submitting ? 'Submitting...' : ${p32.submitText}}
5985
6205
  </button>
5986
6206
  )}
5987
6207
  </div>
@@ -13997,14 +14217,14 @@ function safeIdentifier(value, fallback) {
13997
14217
  const base = pascal ? `${pascal.charAt(0).toLowerCase()}${pascal.slice(1)}` : fallback;
13998
14218
  return /^[A-Za-z_$]/.test(base) ? base : fallback;
13999
14219
  }
14000
- function pathExpression(path61) {
14001
- return `\`${path61.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join(".")}\``;
14220
+ function pathExpression(path62) {
14221
+ return `\`${path62.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join(".")}\``;
14002
14222
  }
14003
- function pathNameProp(path61) {
14004
- if (path61.every((part) => typeof part === "string")) {
14005
- return `"${path61.map((part) => part).join(".")}"`;
14223
+ function pathNameProp(path62) {
14224
+ if (path62.every((part) => typeof part === "string")) {
14225
+ return `"${path62.map((part) => part).join(".")}"`;
14006
14226
  }
14007
- return `{${pathExpression(path61)}}`;
14227
+ return `{${pathExpression(path62)}}`;
14008
14228
  }
14009
14229
  function findTitlePath(fields) {
14010
14230
  const stringTypes = ["string", "varchar", "text"];
@@ -14026,23 +14246,23 @@ function findTitlePath(fields) {
14026
14246
  function requiredLeafPaths(fields, prefix = []) {
14027
14247
  return fields.flatMap((field) => {
14028
14248
  if (field.hidden) return [];
14029
- const path61 = [...prefix, field.name];
14249
+ const path62 = [...prefix, field.name];
14030
14250
  if ((field.type === "group" || field.type === "section") && field.fields?.length) {
14031
- return requiredLeafPaths(field.fields, path61);
14251
+ return requiredLeafPaths(field.fields, path62);
14032
14252
  }
14033
- if (field.required) return [path61.join(".")];
14253
+ if (field.required) return [path62.join(".")];
14034
14254
  return [];
14035
14255
  });
14036
14256
  }
14037
14257
  function validationTriggerExpression(basePath, requiredPaths) {
14038
14258
  if (requiredPaths.length === 0) return `\`${basePath}.\${expandedIndex}\` as never`;
14039
- const paths = requiredPaths.map((path61) => `\`${basePath}.\${expandedIndex}.${path61}\``).join(", ");
14259
+ const paths = requiredPaths.map((path62) => `\`${basePath}.\${expandedIndex}.${path62}\``).join(", ");
14040
14260
  return `[${paths}] as never`;
14041
14261
  }
14042
- function renderTextInputField(field, indent, label, nestedHint, path61) {
14262
+ function renderTextInputField(field, indent, label, nestedHint, path62) {
14043
14263
  return `${indent}<FormField
14044
14264
  ${indent} control={form.control}
14045
- ${indent} name=${pathNameProp(path61)}
14265
+ ${indent} name=${pathNameProp(path62)}
14046
14266
  ${indent} render={({ field: formField }) => (
14047
14267
  ${indent} <FormItem${formItemProps(field)}>
14048
14268
  ${indent} ${labelWithDescription(formLabel(field, label), nestedHint, `${indent} `)}
@@ -14054,11 +14274,11 @@ ${indent} </FormItem>
14054
14274
  ${indent} )}
14055
14275
  ${indent}/>`;
14056
14276
  }
14057
- function renderNestedField(field, indent, path61, depth) {
14277
+ function renderNestedField(field, indent, path62, depth) {
14058
14278
  const nestedLabel = field.label || field.name;
14059
14279
  const nestedHint = field.hint ? `<FormDescription>${field.hint}</FormDescription>` : "";
14060
14280
  if ((field.type === "group" || field.type === "section") && field.fields?.length) {
14061
- const groupFields = field.fields.map((child) => renderNestedField(child, `${indent} `, [...path61, child.name], depth)).filter(Boolean).join("\n");
14281
+ const groupFields = field.fields.map((child) => renderNestedField(child, `${indent} `, [...path62, child.name], depth)).filter(Boolean).join("\n");
14062
14282
  if (!groupFields) return "";
14063
14283
  const heading = nestedLabel && nestedLabel !== field.name ? `${indent}<h3 className="text-base font-medium">${nestedLabel}</h3>
14064
14284
  ` : "";
@@ -14068,7 +14288,7 @@ ${groupFields}
14068
14288
  ${indent}</div>`;
14069
14289
  }
14070
14290
  if (field.type === "list" && field.fields?.length) {
14071
- return renderNestedObjectListField(field, indent, nestedLabel, path61, depth);
14291
+ return renderNestedObjectListField(field, indent, nestedLabel, path62, depth);
14072
14292
  }
14073
14293
  if (field.type === "list") {
14074
14294
  const hideLabelProp = field.label ? "" : `
@@ -14076,7 +14296,7 @@ ${indent} hideLabel`;
14076
14296
  const descriptionProp = field.hint ? `
14077
14297
  ${indent} description={${JSON.stringify(field.hint)}}` : "";
14078
14298
  return `${indent}<DynamicListField
14079
- ${indent} name={${pathExpression(path61)}}
14299
+ ${indent} name={${pathExpression(path62)}}
14080
14300
  ${indent} label="${nestedLabel}"${hideLabelProp}${descriptionProp}
14081
14301
  ${indent} disabled={isPending}${field.maxItems ? `
14082
14302
  ${indent} maxItems={${field.maxItems}}` : ""}
@@ -14086,7 +14306,7 @@ ${indent}/>`;
14086
14306
  if (field.type === "boolean") {
14087
14307
  return `${indent}<FormField
14088
14308
  ${indent} control={form.control}
14089
- ${indent} name=${pathNameProp(path61)}
14309
+ ${indent} name=${pathNameProp(path62)}
14090
14310
  ${indent} render={({ field: formField }) => (
14091
14311
  ${indent} <FormItem${formItemProps(field, "flex flex-row items-start space-x-3 space-y-0")}>
14092
14312
  ${indent} <FormControl>
@@ -14101,7 +14321,7 @@ ${indent}/>`;
14101
14321
  const acceptProp = field.type === "image" ? ' accept="image/*"' : field.type === "video" ? ' accept="video/*"' : "";
14102
14322
  return `${indent}<FormField
14103
14323
  ${indent} control={form.control}
14104
- ${indent} name=${pathNameProp(path61)}
14324
+ ${indent} name=${pathNameProp(path62)}
14105
14325
  ${indent} render={({ field: formField }) => (
14106
14326
  ${indent} <FormItem${formItemProps(field)}>
14107
14327
  ${indent} ${labelWithDescription(formLabel(field, nestedLabel), nestedHint, `${indent} `)}
@@ -14116,7 +14336,7 @@ ${indent}/>`;
14116
14336
  if (field.type === "icon") {
14117
14337
  return `${indent}<FormField
14118
14338
  ${indent} control={form.control}
14119
- ${indent} name=${pathNameProp(path61)}
14339
+ ${indent} name=${pathNameProp(path62)}
14120
14340
  ${indent} render={({ field: formField }) => (
14121
14341
  ${indent} <FormItem${formItemProps(field)}>
14122
14342
  ${indent} ${labelWithDescription(formLabel(field, nestedLabel), nestedHint, `${indent} `)}
@@ -14133,7 +14353,7 @@ ${indent}/>`;
14133
14353
  const emptyValue = field.required ? "undefined" : "null";
14134
14354
  return `${indent}<FormField
14135
14355
  ${indent} control={form.control}
14136
- ${indent} name=${pathNameProp(path61)}
14356
+ ${indent} name=${pathNameProp(path62)}
14137
14357
  ${indent} render={({ field: formField }) => (
14138
14358
  ${indent} <FormItem${formItemProps(field)}>
14139
14359
  ${indent} ${labelWithDescription(formLabel(field, nestedLabel), nestedHint, `${indent} `)}
@@ -14158,16 +14378,16 @@ ${indent} </FormItem>
14158
14378
  ${indent} )}
14159
14379
  ${indent}/>`;
14160
14380
  }
14161
- return renderTextInputField(field, indent, nestedLabel, nestedHint, path61);
14381
+ return renderTextInputField(field, indent, nestedLabel, nestedHint, path62);
14162
14382
  }
14163
- function renderNestedObjectListField(field, indent, label, path61, depth) {
14383
+ function renderNestedObjectListField(field, indent, label, path62, depth) {
14164
14384
  const singularLabel = singularize(label);
14165
14385
  const itemIndexVar = `${safeIdentifier(field.name, "nestedList")}Index${depth}`;
14166
14386
  const titlePath = findTitlePath(field.fields ?? []);
14167
14387
  const titlePathSuffix = titlePath ? `.${titlePath.join(".")}` : "";
14168
14388
  const renderTitleProp = titlePath ? `
14169
14389
  ${indent} renderTitle={(${itemIndexVar}) =>
14170
- ${indent} String(form.watch(\`${path61.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join(
14390
+ ${indent} String(form.watch(\`${path62.map((part) => typeof part === "string" ? part : `\${${part.expression}}`).join(
14171
14391
  "."
14172
14392
  )}.\${${itemIndexVar}}${titlePathSuffix}\` as never) || \`${singularLabel} \${${itemIndexVar} + 1}\`)
14173
14393
  ${indent} }` : "";
@@ -14175,7 +14395,7 @@ ${indent} }` : "";
14175
14395
  (child) => renderNestedField(
14176
14396
  child,
14177
14397
  `${indent} `,
14178
- [...path61, { expression: itemIndexVar }, child.name],
14398
+ [...path62, { expression: itemIndexVar }, child.name],
14179
14399
  depth + 1
14180
14400
  )
14181
14401
  ).filter(Boolean).join("\n");
@@ -14190,7 +14410,7 @@ ${indent} maxItems={${field.maxItems}}` : "";
14190
14410
  const validatePathsProp = validatePaths.length > 0 ? `
14191
14411
  ${indent} validatePaths={${JSON.stringify(validatePaths)}}` : "";
14192
14412
  return `${indent}<NestedObjectListField
14193
- ${indent} name={${pathExpression(path61)}}
14413
+ ${indent} name={${pathExpression(path62)}}
14194
14414
  ${indent} label={${JSON.stringify(label)}}
14195
14415
  ${indent} singularLabel={${JSON.stringify(singularLabel)}}
14196
14416
  ${indent} defaultValue={${defaultItem}}
@@ -17805,7 +18025,7 @@ function readPresetTemplate(presetId, relativePath) {
17805
18025
  // adapters/next/snapshots/apply.ts
17806
18026
  import fs20 from "fs";
17807
18027
  import path24 from "path";
17808
- import * as p6 from "@clack/prompts";
18028
+ import * as p8 from "@clack/prompts";
17809
18029
 
17810
18030
  // core-engine/snapshots/ast-substitution.ts
17811
18031
  import { Node, Project } from "ts-morph";
@@ -17826,7 +18046,7 @@ function applyTextEdits(content, edits) {
17826
18046
  content
17827
18047
  );
17828
18048
  }
17829
- function collectPreviewChanges(path61, beforeContent, afterContent) {
18049
+ function collectPreviewChanges(path62, beforeContent, afterContent) {
17830
18050
  const beforeLines = beforeContent.split("\n");
17831
18051
  const afterLines = afterContent.split("\n");
17832
18052
  const maxLength = Math.max(beforeLines.length, afterLines.length);
@@ -17838,7 +18058,7 @@ function collectPreviewChanges(path61, beforeContent, afterContent) {
17838
18058
  continue;
17839
18059
  }
17840
18060
  changes.push({
17841
- path: path61,
18061
+ path: path62,
17842
18062
  line: index + 1,
17843
18063
  before: before.trim(),
17844
18064
  after: after.trim()
@@ -18167,7 +18387,7 @@ function hasConflictMarkers(content) {
18167
18387
  }
18168
18388
 
18169
18389
  // adapters/next/snapshots/format-for-merge.ts
18170
- import { execFileSync as execFileSync3 } from "child_process";
18390
+ import { execFileSync as execFileSync2 } from "child_process";
18171
18391
  import fs18 from "fs";
18172
18392
  import path22 from "path";
18173
18393
  var BIOME_FORMAT_TIMEOUT_MS2 = 15e3;
@@ -18217,7 +18437,7 @@ function formatContentForSnapshotMerge(cwd, filePath, content) {
18217
18437
  const configPath = findBiomeConfig(cwd);
18218
18438
  const targetPath = path22.join(cwd, ...filePath.split("/"));
18219
18439
  try {
18220
- return execFileSync3(
18440
+ return execFileSync2(
18221
18441
  biomeBin,
18222
18442
  [
18223
18443
  "check",
@@ -18468,11 +18688,11 @@ function buildMergeInput(cwd, baseFile, localContent, remoteFile) {
18468
18688
  }
18469
18689
  };
18470
18690
  }
18471
- function isInteractiveSession(interactive) {
18691
+ function isInteractiveSession2(interactive) {
18472
18692
  return interactive && Boolean(process.stdin.isTTY) && process.env.CI !== "true";
18473
18693
  }
18474
18694
  async function promptNoBaseDecision(filePath) {
18475
- const answer = await p6.select({
18695
+ const answer = await p8.select({
18476
18696
  message: `File already exists without snapshot base: ${filePath}`,
18477
18697
  options: [
18478
18698
  { value: "backup", label: "Backup and overwrite", hint: "recommended" },
@@ -18481,7 +18701,7 @@ async function promptNoBaseDecision(filePath) {
18481
18701
  ],
18482
18702
  initialValue: "backup"
18483
18703
  });
18484
- if (p6.isCancel(answer)) {
18704
+ if (p8.isCancel(answer)) {
18485
18705
  throw new Error("Generation cancelled.");
18486
18706
  }
18487
18707
  return answer;
@@ -18517,7 +18737,7 @@ async function applyGeneratedFiles({
18517
18737
  const remoteFiles = sortGeneratedFiles(generatedFiles);
18518
18738
  const remotePaths = new Set(remoteFiles.map((file) => file.path));
18519
18739
  const skipped = new Set(force ? [] : manifest?.skipped ?? []);
18520
- const interactiveSession = isInteractiveSession(interactive);
18740
+ const interactiveSession = isInteractiveSession2(interactive);
18521
18741
  const aliasMap = renamePlan ? buildRenamePlanAliasMap(renamePlan) : /* @__PURE__ */ new Map();
18522
18742
  const consumedBasePaths = /* @__PURE__ */ new Set();
18523
18743
  let baseFiles = /* @__PURE__ */ new Map();
@@ -19362,18 +19582,18 @@ async function runAddCommand(items, options) {
19362
19582
  const presetIds = items.filter(isPresetId);
19363
19583
  const integrationIds = items.filter(isIntegrationId);
19364
19584
  if (!installIntegrationsMode && integrationIds.length > 0) {
19365
- p7.log.error(
19585
+ p9.log.error(
19366
19586
  `Integration IDs require --integration. Run \`betterstart add --integration ${integrationIds.join(" ")}\`.`
19367
19587
  );
19368
19588
  process.exit(1);
19369
19589
  }
19370
19590
  if (installIntegrationsMode && presetIds.length > 0) {
19371
- p7.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
19591
+ p9.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
19372
19592
  process.exit(1);
19373
19593
  }
19374
19594
  const invalidItems = installIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
19375
19595
  if (invalidItems.length > 0) {
19376
- p7.log.error(
19596
+ p9.log.error(
19377
19597
  installIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
19378
19598
  );
19379
19599
  process.exit(1);
@@ -19384,7 +19604,7 @@ async function runAddCommand(items, options) {
19384
19604
  const pm = detectPackageManager(cwd);
19385
19605
  const cliSyncResult = await syncProjectCliDependency(cwd, pm);
19386
19606
  if (cliSyncResult && !cliSyncResult.success) {
19387
- p7.log.error(cliSyncResult.error ?? "Failed to sync betterstart-cli");
19607
+ p9.log.error(cliSyncResult.error ?? "Failed to sync betterstart-cli");
19388
19608
  process.exit(1);
19389
19609
  }
19390
19610
  if (installIntegrationsMode) {
@@ -19398,10 +19618,10 @@ async function runAddCommand(items, options) {
19398
19618
  });
19399
19619
  writeConfigFile(cwd, result2.config);
19400
19620
  if (result2.warnings.length > 0) {
19401
- p7.note(result2.warnings.join("\n"), "Warnings");
19621
+ p9.note(result2.warnings.join("\n"), "Warnings");
19402
19622
  }
19403
19623
  if (result2.installed.length === 0 && result2.activated.length === 0 && result2.skipped.length > 0) {
19404
- p7.outro(`No changes made. Already installed: ${result2.skipped.join(", ")}`);
19624
+ p9.outro(`No changes made. Already installed: ${result2.skipped.join(", ")}`);
19405
19625
  return;
19406
19626
  }
19407
19627
  const conflictPaths2 = scanConflictPaths(cwd);
@@ -19423,12 +19643,12 @@ async function runAddCommand(items, options) {
19423
19643
  result2.installed.length > 0 ? `Installed integration${result2.installed.length === 1 ? "" : "s"}: ${result2.installed.join(", ")}` : null,
19424
19644
  result2.activated.length > 0 ? `Activated integration${result2.activated.length === 1 ? "" : "s"}: ${result2.activated.join(", ")}` : null
19425
19645
  ].filter(Boolean);
19426
- p7.outro(messages.join("\n"));
19646
+ p9.outro(messages.join("\n"));
19427
19647
  return;
19428
19648
  }
19429
19649
  const invalidPresets = items.filter((presetId) => !isPresetId(presetId));
19430
19650
  if (invalidPresets.length > 0) {
19431
- p7.log.error(formatUnknownPresetMessage(invalidPresets));
19651
+ p9.log.error(formatUnknownPresetMessage(invalidPresets));
19432
19652
  process.exit(1);
19433
19653
  }
19434
19654
  const result = await installPresets({
@@ -19441,11 +19661,11 @@ async function runAddCommand(items, options) {
19441
19661
  });
19442
19662
  writeConfigFile(cwd, result.config);
19443
19663
  if (result.installed.length === 0 && result.skipped.length > 0) {
19444
- p7.outro(`No changes made. Already installed: ${result.skipped.join(", ")}`);
19664
+ p9.outro(`No changes made. Already installed: ${result.skipped.join(", ")}`);
19445
19665
  return;
19446
19666
  }
19447
19667
  if (result.warnings.length > 0) {
19448
- p7.note(result.warnings.join("\n"), "Warnings");
19668
+ p9.note(result.warnings.join("\n"), "Warnings");
19449
19669
  }
19450
19670
  const installedSchemaNames = result.installed.flatMap(
19451
19671
  (presetId) => getPresetDefinition(presetId).schemaFiles.map((schemaFile) => schemaFile.replace(/\.json$/, ""))
@@ -19462,14 +19682,14 @@ async function runAddCommand(items, options) {
19462
19682
  if (conflictPaths.length === 0) {
19463
19683
  printAddNextSteps("preset", hasSchemaChanges, postGenerateResult, adminRoutePath);
19464
19684
  }
19465
- p7.outro(
19685
+ p9.outro(
19466
19686
  `Installed preset${result.installed.length === 1 ? "" : "s"}: ${result.installed.join(", ")}`
19467
19687
  );
19468
19688
  }
19469
19689
 
19470
19690
  // adapters/next/commands/add-field.ts
19471
19691
  import path30 from "path";
19472
- import * as p11 from "@clack/prompts";
19692
+ import * as p12 from "@clack/prompts";
19473
19693
 
19474
19694
  // core-engine/schema/add-field.ts
19475
19695
  import fs23 from "fs";
@@ -20121,7 +20341,7 @@ function getTabFields(tab) {
20121
20341
  // adapters/next/commands/generate.ts
20122
20342
  import fs24 from "fs";
20123
20343
  import path29 from "path";
20124
- import * as p9 from "@clack/prompts";
20344
+ import * as p10 from "@clack/prompts";
20125
20345
 
20126
20346
  // core-engine/snapshots/rename-detector.ts
20127
20347
  function levenshtein(a, b) {
@@ -20213,90 +20433,8 @@ function diffSchemas(before, after) {
20213
20433
  };
20214
20434
  }
20215
20435
 
20216
- // core-engine/utils/spinner.ts
20217
- import { stripVTControlCharacters } from "util";
20218
- import * as p8 from "@clack/prompts";
20219
- var RENDER_OVERHEAD = 7;
20220
- var MIN_MESSAGE_WIDTH = 8;
20221
- function fitSpinnerMessage(message) {
20222
- const normalized = message.replace(/\t/g, " ");
20223
- const columns = process.stdout.columns ?? 80;
20224
- const max = Math.max(columns - RENDER_OVERHEAD, MIN_MESSAGE_WIDTH);
20225
- const visible = stripVTControlCharacters(normalized);
20226
- if (visible.length <= max) return normalized;
20227
- return `${visible.slice(0, max - 1)}\u2026`;
20228
- }
20229
- var CLACK_LINE_ROWS = 2;
20230
- var LOG_PREFIX_WIDTH = 3;
20231
- function clackPromptRows(message, value) {
20232
- const columns = process.stdout.columns ?? 80;
20233
- const rows = (text7) => Math.max(1, Math.ceil((stripVTControlCharacters(text7).length + LOG_PREFIX_WIDTH) / columns));
20234
- return 1 + rows(message) + rows(value);
20235
- }
20236
- function clackLogRows(message) {
20237
- const columns = process.stdout.columns ?? 80;
20238
- const width = stripVTControlCharacters(message).length + LOG_PREFIX_WIDTH;
20239
- return 1 + Math.max(1, Math.ceil(width / columns));
20240
- }
20241
- function eraseRows(rows) {
20242
- if (rows <= 0 || !process.stdout.isTTY || process.env.CI === "true") return;
20243
- process.stdout.write(`\x1B[${rows}A\x1B[${rows}M`);
20244
- }
20245
- function eraseRowsAbove(rows, rowsBelow) {
20246
- if (rows <= 0 || rowsBelow < 0 || !process.stdout.isTTY || process.env.CI === "true") {
20247
- return;
20248
- }
20249
- const up = rows + rowsBelow;
20250
- const restore = rowsBelow > 0 ? `\x1B[${rowsBelow}B` : "";
20251
- process.stdout.write(`\x1B[${up}A\x1B[${rows}M${restore}`);
20252
- }
20253
- function eraseClackLine(options = {}) {
20254
- if (!process.stdout.isTTY || process.env.CI === "true") return;
20255
- const below = (options.linesBelow ?? 0) * CLACK_LINE_ROWS;
20256
- const up = below + CLACK_LINE_ROWS;
20257
- const restore = below > 0 ? `\x1B[${below}B` : "";
20258
- process.stdout.write(`\x1B[${up}A\x1B[${CLACK_LINE_ROWS}M${restore}`);
20259
- }
20260
- var activeSpinners = 0;
20261
- function hasActiveSpinner() {
20262
- return activeSpinners > 0;
20263
- }
20264
- function spinner2(options) {
20265
- const inner = p8.spinner({ ...options, cancelMessage: "Setup cancelled." });
20266
- const guided = options?.withGuide !== false;
20267
- let started = false;
20268
- const setStarted = (next) => {
20269
- if (started === next) return;
20270
- started = next;
20271
- activeSpinners += next ? 1 : -1;
20272
- };
20273
- return {
20274
- start: (message = "") => {
20275
- if (started) {
20276
- inner.message(fitSpinnerMessage(message));
20277
- return;
20278
- }
20279
- setStarted(true);
20280
- inner.start(fitSpinnerMessage(message));
20281
- },
20282
- message: (message = "") => inner.message(fitSpinnerMessage(message)),
20283
- stop: (message = "") => {
20284
- setStarted(false);
20285
- inner.stop(message);
20286
- },
20287
- clear: () => {
20288
- if (!started) return;
20289
- setStarted(false);
20290
- inner.clear();
20291
- if (guided && process.stdout.isTTY && process.env.CI !== "true") {
20292
- process.stdout.write("\x1B[1A\x1B[2K");
20293
- }
20294
- }
20295
- };
20296
- }
20297
-
20298
20436
  // adapters/next/commands/generate.ts
20299
- function isInteractiveSession2() {
20437
+ function isInteractiveSession3() {
20300
20438
  return Boolean(process.stdin.isTTY) && process.env.CI !== "true";
20301
20439
  }
20302
20440
  function isStoredSchemaJson(schemaJson) {
@@ -20381,7 +20519,7 @@ function assertSnapshotStateOrExit(cwd) {
20381
20519
  if (snapshotRootExists(cwd)) {
20382
20520
  return;
20383
20521
  }
20384
- p9.log.error(UNSUPPORTED_PROJECT_STATE_MESSAGE);
20522
+ p10.log.error(UNSUPPORTED_PROJECT_STATE_MESSAGE);
20385
20523
  process.exit(1);
20386
20524
  }
20387
20525
  function printSchemaDiff(scope, loaded, cwd) {
@@ -20416,14 +20554,14 @@ function printSchemaDiff(scope, loaded, cwd) {
20416
20554
  ` custom cells: +[${diff.customComponents.added.join(", ")}] -[${diff.customComponents.removed.join(", ")}]`
20417
20555
  );
20418
20556
  }
20419
- p9.log.message(lines.join("\n"));
20557
+ p10.log.message(lines.join("\n"));
20420
20558
  }
20421
20559
  async function promptConfirm(message) {
20422
- const result = await p9.confirm({
20560
+ const result = await p10.confirm({
20423
20561
  message,
20424
20562
  initialValue: true
20425
20563
  });
20426
- if (p9.isCancel(result)) {
20564
+ if (p10.isCancel(result)) {
20427
20565
  throw new Error("Generation cancelled.");
20428
20566
  }
20429
20567
  return Boolean(result);
@@ -20553,7 +20691,7 @@ async function maybeBuildRenamePlan(loaded, cwd, config, generatedFiles, options
20553
20691
  };
20554
20692
  if (finalPlan.fields.length === 0 && finalPlan.customCells.length === 0) {
20555
20693
  if (validatedCustomCells.warnings.length > 0) {
20556
- p9.log.warn(validatedCustomCells.warnings.join("\n"));
20694
+ p10.log.warn(validatedCustomCells.warnings.join("\n"));
20557
20695
  }
20558
20696
  return void 0;
20559
20697
  }
@@ -20571,10 +20709,10 @@ async function maybeBuildRenamePlan(loaded, cwd, config, generatedFiles, options
20571
20709
  if (preview.previewLines.length > previewLines.length) {
20572
20710
  renameLines.push(` ... ${preview.previewLines.length - previewLines.length} more change(s)`);
20573
20711
  }
20574
- p9.log.message(renameLines.join("\n"));
20712
+ p10.log.message(renameLines.join("\n"));
20575
20713
  const warnings = [...validatedCustomCells.warnings, ...preview.warnings];
20576
20714
  if (warnings.length > 0) {
20577
- p9.log.warn(warnings.join("\n"));
20715
+ p10.log.warn(warnings.join("\n"));
20578
20716
  }
20579
20717
  const confirmed = await promptConfirm("Apply these rename substitutions before merge?");
20580
20718
  return confirmed ? finalPlan : void 0;
@@ -20685,16 +20823,16 @@ function printApplySummary(schemaName, summary) {
20685
20823
  if (summary.skippedCleared.length > 0) {
20686
20824
  lines.push(` skip entries cleared: ${summary.skippedCleared.join(", ")}`);
20687
20825
  }
20688
- p9.log.message(lines.join("\n"));
20826
+ p10.log.message(lines.join("\n"));
20689
20827
  }
20690
20828
  async function runGenerateCommand(schemaName, options) {
20691
20829
  const cwd = options.cwd ? path29.resolve(options.cwd) : process.cwd();
20692
- const interactive = options.all ? options.interactive && isInteractiveSession2() : isInteractiveSession2();
20830
+ const interactive = options.all ? options.interactive && isInteractiveSession3() : isInteractiveSession3();
20693
20831
  let config;
20694
20832
  try {
20695
20833
  config = await resolveConfig(cwd);
20696
20834
  } catch (error) {
20697
- p9.log.error(`Error loading config: ${error instanceof Error ? error.message : String(error)}`);
20835
+ p10.log.error(`Error loading config: ${error instanceof Error ? error.message : String(error)}`);
20698
20836
  process.exit(1);
20699
20837
  }
20700
20838
  assertSnapshotStateOrExit(cwd);
@@ -20704,7 +20842,7 @@ async function runGenerateCommand(schemaName, options) {
20704
20842
  if (options.all) {
20705
20843
  const schemaNames = listSchemaNames(schemasDir);
20706
20844
  if (schemaNames.length === 0) {
20707
- p9.log.error(`No schemas found in ${schemasDir}`);
20845
+ p10.log.error(`No schemas found in ${schemasDir}`);
20708
20846
  process.exit(1);
20709
20847
  }
20710
20848
  const failed = [];
@@ -20712,14 +20850,14 @@ async function runGenerateCommand(schemaName, options) {
20712
20850
  const processedRoutes = [];
20713
20851
  let markdownDepsChecked = false;
20714
20852
  const adminRoutePath2 = resolveAdminNamespace(config.frameworkConfig.next.namespace).routePath;
20715
- p9.intro(`BetterStart Generator \u2014 regenerating ${schemaNames.length} schema(s)`);
20853
+ p10.intro(`BetterStart Generator \u2014 regenerating ${schemaNames.length} schema(s)`);
20716
20854
  for (const name of schemaNames) {
20717
20855
  if (hasTombstone(cwd, name)) {
20718
20856
  if (loadManifest(cwd, name)) {
20719
20857
  clearTombstone(cwd, name);
20720
- p9.log.warn(`${name}: tombstone cleared (manifest present)`);
20858
+ p10.log.warn(`${name}: tombstone cleared (manifest present)`);
20721
20859
  } else {
20722
- p9.log.message(`${name}: skipped (tombstoned)`);
20860
+ p10.log.message(`${name}: skipped (tombstoned)`);
20723
20861
  continue;
20724
20862
  }
20725
20863
  }
@@ -20745,7 +20883,7 @@ async function runGenerateCommand(schemaName, options) {
20745
20883
  processed.push(name);
20746
20884
  processedRoutes.push(getGeneratedSchemaRoutePath(loaded2, adminRoutePath2));
20747
20885
  } catch (error) {
20748
- p9.log.error(`${name}: ${error instanceof Error ? error.message : String(error)}`);
20886
+ p10.log.error(`${name}: ${error instanceof Error ? error.message : String(error)}`);
20749
20887
  failed.push(name);
20750
20888
  }
20751
20889
  }
@@ -20768,14 +20906,14 @@ async function runGenerateCommand(schemaName, options) {
20768
20906
  });
20769
20907
  }
20770
20908
  if (failed.length > 0) {
20771
- p9.log.error(`Failed: ${failed.join(", ")}`);
20909
+ p10.log.error(`Failed: ${failed.join(", ")}`);
20772
20910
  process.exit(1);
20773
20911
  }
20774
- p9.outro(`Regenerated ${processed.length}/${schemaNames.length} schema(s)`);
20912
+ p10.outro(`Regenerated ${processed.length}/${schemaNames.length} schema(s)`);
20775
20913
  return;
20776
20914
  }
20777
20915
  if (!schemaName) {
20778
- p9.log.error("Error: schema name is required (or use --all)");
20916
+ p10.log.error("Error: schema name is required (or use --all)");
20779
20917
  process.exit(1);
20780
20918
  }
20781
20919
  let loaded;
@@ -20783,20 +20921,20 @@ async function runGenerateCommand(schemaName, options) {
20783
20921
  loaded = loadSchema(schemasDir, schemaName);
20784
20922
  } catch (error) {
20785
20923
  if (error instanceof SchemaNotFoundError) {
20786
- p9.log.error(error.message);
20924
+ p10.log.error(error.message);
20787
20925
  } else {
20788
- p9.log.error(`Error loading schema: ${error instanceof Error ? error.message : String(error)}`);
20926
+ p10.log.error(`Error loading schema: ${error instanceof Error ? error.message : String(error)}`);
20789
20927
  }
20790
20928
  process.exit(1);
20791
20929
  }
20792
20930
  const validationErrors = validateLoadedSchema(loaded);
20793
20931
  if (validationErrors.length > 0) {
20794
- p9.log.error(
20932
+ p10.log.error(
20795
20933
  ["Schema validation failed:", ...validationErrors.map((error) => ` - ${error}`)].join("\n")
20796
20934
  );
20797
20935
  process.exit(1);
20798
20936
  }
20799
- p9.intro(`BetterStart Generator \u2014 ${loaded.schema.name}`);
20937
+ p10.intro(`BetterStart Generator \u2014 ${loaded.schema.name}`);
20800
20938
  const needsMarkdownRenderer = schemaNeedsMarkdownRenderer(loaded);
20801
20939
  await ensureMarkdownRendererDependencies(cwd, needsMarkdownRenderer);
20802
20940
  const result = await applySchemaGeneration(loaded, cwd, config, {
@@ -20821,38 +20959,38 @@ async function runGenerateCommand(schemaName, options) {
20821
20959
  adminRoutePath,
20822
20960
  schemaRoutePath: getGeneratedSchemaRoutePath(loaded, adminRoutePath)
20823
20961
  });
20824
- p9.outro(`Generated ${loaded.schema.name}`);
20962
+ p10.outro(`Generated ${loaded.schema.name}`);
20825
20963
  }
20826
20964
 
20827
20965
  // adapters/next/commands/schema-prompts.ts
20828
- import * as p10 from "@clack/prompts";
20829
- function isInteractiveSession3() {
20966
+ import * as p11 from "@clack/prompts";
20967
+ function isInteractiveSession4() {
20830
20968
  return Boolean(process.stdin.isTTY) && process.env.CI !== "true";
20831
20969
  }
20832
20970
  function fail(message) {
20833
- p10.log.error(message);
20971
+ p11.log.error(message);
20834
20972
  process.exit(1);
20835
20973
  }
20836
- function cancel2(context) {
20837
- p10.cancel(context.cancelMessage);
20974
+ function cancel3(context) {
20975
+ p11.cancel(context.cancelMessage);
20838
20976
  process.exit(0);
20839
20977
  }
20840
20978
  function cancelIfNeeded(context, value) {
20841
- if (p10.isCancel(value)) {
20842
- cancel2(context);
20979
+ if (p11.isCancel(value)) {
20980
+ cancel3(context);
20843
20981
  }
20844
20982
  return value;
20845
20983
  }
20846
20984
  async function promptConfirm2(context, message, initialValue = true) {
20847
- const confirmed = await p10.confirm({ message, initialValue });
20848
- if (p10.isCancel(confirmed)) {
20849
- cancel2(context);
20985
+ const confirmed = await p11.confirm({ message, initialValue });
20986
+ if (p11.isCancel(confirmed)) {
20987
+ cancel3(context);
20850
20988
  }
20851
20989
  return Boolean(confirmed);
20852
20990
  }
20853
20991
  async function promptText(context, message, optionsOrDefaultValue) {
20854
20992
  const options = typeof optionsOrDefaultValue === "string" ? { defaultValue: optionsOrDefaultValue } : optionsOrDefaultValue ?? {};
20855
- const value = await p10.text({
20993
+ const value = await p11.text({
20856
20994
  message,
20857
20995
  defaultValue: options.defaultValue,
20858
20996
  placeholder: options.placeholder,
@@ -20869,7 +21007,7 @@ async function promptText(context, message, optionsOrDefaultValue) {
20869
21007
  return String(cancelIfNeeded(context, value)).trim();
20870
21008
  }
20871
21009
  async function promptOptionalText(context, message) {
20872
- const value = await p10.text({
21010
+ const value = await p11.text({
20873
21011
  message,
20874
21012
  placeholder: "Leave blank to skip"
20875
21013
  });
@@ -20877,7 +21015,7 @@ async function promptOptionalText(context, message) {
20877
21015
  return result || void 0;
20878
21016
  }
20879
21017
  async function promptSelectValue(context, message, options, initialValue) {
20880
- const value = await p10.select({
21018
+ const value = await p11.select({
20881
21019
  message,
20882
21020
  options,
20883
21021
  initialValue
@@ -21096,7 +21234,7 @@ async function shouldPromptRequired(type) {
21096
21234
  return !["group", "section", "tabs", "separator"].includes(type);
21097
21235
  }
21098
21236
  async function promptFormFileOptions(context) {
21099
- const selected = await p10.multiselect({
21237
+ const selected = await p11.multiselect({
21100
21238
  message: "Field options",
21101
21239
  options: [
21102
21240
  { value: "required", label: "Required field?" },
@@ -21135,7 +21273,7 @@ async function promptFieldOptions(context, kind, type, creatable) {
21135
21273
  try {
21136
21274
  return parseInteractiveOptionsList(value);
21137
21275
  } catch (error) {
21138
- p10.log.error(error instanceof Error ? error.message : String(error));
21276
+ p11.log.error(error instanceof Error ? error.message : String(error));
21139
21277
  }
21140
21278
  }
21141
21279
  }
@@ -21253,7 +21391,7 @@ async function promptChildFields(context, kind, schemasDir, scope, fields, depth
21253
21391
  const addChild = fields.length === 0 ? await promptConfirm2(context, "Add a child field?", true) : await promptConfirm2(context, "Add another child field?", false);
21254
21392
  if (!addChild) {
21255
21393
  if (fields.length === 0) {
21256
- p10.log.warn("Containers need at least one child field.");
21394
+ p11.log.warn("Containers need at least one child field.");
21257
21395
  continue;
21258
21396
  }
21259
21397
  return;
@@ -21278,7 +21416,7 @@ async function promptTabsField(context, kind, schemasDir, scope, name, label, de
21278
21416
  const addTab = field.tabs.length === 0 ? await promptConfirm2(context, "Add a tab?", true) : await promptConfirm2(context, "Add another tab?", false);
21279
21417
  if (!addTab) {
21280
21418
  if (field.tabs.length === 0) {
21281
- p10.log.warn("Tabs need at least one tab.");
21419
+ p11.log.warn("Tabs need at least one tab.");
21282
21420
  continue;
21283
21421
  }
21284
21422
  return field;
@@ -21303,7 +21441,7 @@ async function promptTabsField(context, kind, schemasDir, scope, name, label, de
21303
21441
  const addChild = mainFields.length + sidebarFields.length === 0 ? await promptConfirm2(context, "Add a tab child field?", true) : await promptConfirm2(context, "Add another tab child field?", false);
21304
21442
  if (!addChild) {
21305
21443
  if (mainFields.length + sidebarFields.length === 0) {
21306
- p10.log.warn("Tabs need at least one child field.");
21444
+ p11.log.warn("Tabs need at least one child field.");
21307
21445
  continue;
21308
21446
  }
21309
21447
  break;
@@ -21374,7 +21512,7 @@ async function applyAdvancedOptions(context, field, kind, type, options) {
21374
21512
  if (Number.isInteger(parsed) && parsed > 0) {
21375
21513
  record.length = parsed;
21376
21514
  } else {
21377
- p10.log.warn("Skipped invalid length.");
21515
+ p11.log.warn("Skipped invalid length.");
21378
21516
  }
21379
21517
  }
21380
21518
  }
@@ -21532,11 +21670,11 @@ function hasNonInteractiveFieldOptions(options) {
21532
21670
  );
21533
21671
  }
21534
21672
  function fail2(message) {
21535
- p11.log.error(message);
21673
+ p12.log.error(message);
21536
21674
  process.exit(1);
21537
21675
  }
21538
- function cancel4(message = "Add field cancelled.") {
21539
- p11.cancel(message);
21676
+ function cancel5(message = "Add field cancelled.") {
21677
+ p12.cancel(message);
21540
21678
  process.exit(0);
21541
21679
  }
21542
21680
  function schemaNameFromLoaded(loaded) {
@@ -21641,7 +21779,7 @@ function printPreview(loaded, owner, firstTimeGeneration, insertion, options) {
21641
21779
  } else {
21642
21780
  lines.push("schema integration: none");
21643
21781
  }
21644
- p11.note(
21782
+ p12.note(
21645
21783
  `${lines.join("\n")}
21646
21784
 
21647
21785
  ${stringifyProjectJson(insertion.field).trim()}`,
@@ -21674,10 +21812,10 @@ Re-run with --yes to confirm these warning cases.`);
21674
21812
  }
21675
21813
  return;
21676
21814
  }
21677
- p11.note(warnings.join("\n"), "Warnings");
21815
+ p12.note(warnings.join("\n"), "Warnings");
21678
21816
  const confirmed = await promptConfirm3("Continue with these warnings?", true);
21679
21817
  if (!confirmed) {
21680
- cancel4();
21818
+ cancel5();
21681
21819
  }
21682
21820
  }
21683
21821
  function collectRelationshipTargetWarnings(cwd, owner, field) {
@@ -21719,7 +21857,7 @@ async function resolveSchemaNameInteractively(schemasDir, schemaName) {
21719
21857
  if (schemaName) {
21720
21858
  return schemaName;
21721
21859
  }
21722
- if (!isInteractiveSession3()) {
21860
+ if (!isInteractiveSession4()) {
21723
21861
  fail2("Schema name is required in non-interactive sessions.");
21724
21862
  }
21725
21863
  const schemaNames = listSchemaNames(schemasDir);
@@ -21747,7 +21885,7 @@ async function runAddFieldCommand(schemaName, options) {
21747
21885
  } catch (error) {
21748
21886
  fail2(error instanceof Error ? error.message : String(error));
21749
21887
  }
21750
- if (!nonInteractive && !isInteractiveSession3()) {
21888
+ if (!nonInteractive && !isInteractiveSession4()) {
21751
21889
  fail2("Interactive add-field requires a TTY. Provide --type, --field, and --label instead.");
21752
21890
  }
21753
21891
  const owner = resolveSchemaOwner(cwd, schemaNameFromLoaded(loaded));
@@ -21787,11 +21925,11 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21787
21925
  if (!nonInteractive && !options.yes) {
21788
21926
  const confirmed = await promptConfirm3("Write schema JSON and regenerate this schema?", true);
21789
21927
  if (!confirmed) {
21790
- cancel4();
21928
+ cancel5();
21791
21929
  }
21792
21930
  }
21793
21931
  writeAuthoredGeneratedSchema(loaded);
21794
- p11.log.success(`Updated ${path30.relative(cwd, loaded.filePath)}`);
21932
+ p12.log.success(`Updated ${path30.relative(cwd, loaded.filePath)}`);
21795
21933
  try {
21796
21934
  await runGenerateCommand(selectedSchemaName, {
21797
21935
  force: false,
@@ -21802,8 +21940,8 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21802
21940
  cwd
21803
21941
  });
21804
21942
  } catch (error) {
21805
- p11.log.error(error instanceof Error ? error.message : String(error));
21806
- p11.log.info(
21943
+ p12.log.error(error instanceof Error ? error.message : String(error));
21944
+ p12.log.info(
21807
21945
  `Schema JSON was kept. Re-run \`betterstart generate ${selectedSchemaName}${options.skipMigration ? " --skip-migration" : ""}\` after resolving the issue.`
21808
21946
  );
21809
21947
  process.exit(1);
@@ -21813,7 +21951,7 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21813
21951
  // adapters/next/commands/create.ts
21814
21952
  import fs25 from "fs";
21815
21953
  import path31 from "path";
21816
- import * as p12 from "@clack/prompts";
21954
+ import * as p13 from "@clack/prompts";
21817
21955
  var CREATE_PROMPT_CONTEXT = {
21818
21956
  cancelMessage: "Create schema cancelled."
21819
21957
  };
@@ -22004,7 +22142,7 @@ async function promptTabSlotFields(kind, schemasDir, titleField) {
22004
22142
  );
22005
22143
  if (!addField) {
22006
22144
  if (!hasFields) {
22007
- p12.log.warn("Tabs need at least one child field.");
22145
+ p13.log.warn("Tabs need at least one child field.");
22008
22146
  continue;
22009
22147
  }
22010
22148
  return { main, sidebar };
@@ -22052,7 +22190,7 @@ async function promptSchemaTab(kind, schemasDir, titleField, existingTabs) {
22052
22190
  while (fields.length === 0) {
22053
22191
  await promptAdditionalSchemaFields(kind, schemasDir, fields);
22054
22192
  if (fields.length === 0) {
22055
- p12.log.warn("Tabs need at least one child field.");
22193
+ p13.log.warn("Tabs need at least one child field.");
22056
22194
  }
22057
22195
  }
22058
22196
  }
@@ -22142,7 +22280,7 @@ async function promptFormSubmissionColumns(schema) {
22142
22280
  }
22143
22281
  const existingColumnNames = schema.columns ? new Set(schema.columns.map((column) => column.accessorKey)) : void 0;
22144
22282
  const initialValues = existingColumnNames ? fields.filter((field) => existingColumnNames.has(field.name)).map((field) => field.name) : fields.map((field) => field.name);
22145
- const selected = await p12.multiselect({
22283
+ const selected = await p13.multiselect({
22146
22284
  message: "Submission table columns",
22147
22285
  options: fields.map((field) => ({
22148
22286
  value: field.name,
@@ -22151,8 +22289,8 @@ async function promptFormSubmissionColumns(schema) {
22151
22289
  initialValues,
22152
22290
  required: false
22153
22291
  });
22154
- if (p12.isCancel(selected)) {
22155
- cancel2(CREATE_PROMPT_CONTEXT);
22292
+ if (p13.isCancel(selected)) {
22293
+ cancel3(CREATE_PROMPT_CONTEXT);
22156
22294
  }
22157
22295
  const selectedNames = new Set(selected);
22158
22296
  schema.columns = fields.filter((field) => selectedNames.has(field.name)).map((field) => {
@@ -22211,7 +22349,7 @@ function schemaFilePath(kind, schemasDir, schemaName) {
22211
22349
  return kind === "form" ? path31.join(schemasDir, "forms", `${schemaName}.json`) : path31.join(schemasDir, `${schemaName}.json`);
22212
22350
  }
22213
22351
  function printPreview2(loaded, cwd) {
22214
- p12.note(
22352
+ p13.note(
22215
22353
  `schema: ${loaded.name} (${loaded.kind})
22216
22354
  path: ${path31.relative(cwd, loaded.filePath)}
22217
22355
  owner: user
@@ -22226,7 +22364,7 @@ async function runCreateCommand(kindInput, schemaName, options) {
22226
22364
  if (!snapshotRootExists(cwd)) {
22227
22365
  fail(UNSUPPORTED_PROJECT_STATE_MESSAGE);
22228
22366
  }
22229
- if (!isInteractiveSession3()) {
22367
+ if (!isInteractiveSession4()) {
22230
22368
  fail("Interactive create requires a TTY.");
22231
22369
  }
22232
22370
  const config = await resolveConfigOrExit(cwd);
@@ -22258,13 +22396,13 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
22258
22396
  break;
22259
22397
  }
22260
22398
  if (action === "cancel") {
22261
- cancel2(CREATE_PROMPT_CONTEXT);
22399
+ cancel3(CREATE_PROMPT_CONTEXT);
22262
22400
  }
22263
22401
  await promptAdditionalCreateField(kind, schemasDir, schema);
22264
22402
  }
22265
22403
  fs25.mkdirSync(path31.dirname(filePath), { recursive: true });
22266
22404
  writeAuthoredGeneratedSchema(loaded);
22267
- p12.log.success(`Created ${path31.relative(cwd, filePath)}`);
22405
+ p13.log.success(`Created ${path31.relative(cwd, filePath)}`);
22268
22406
  try {
22269
22407
  await runGenerateCommand(metadata.name, {
22270
22408
  force: false,
@@ -22275,8 +22413,8 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
22275
22413
  cwd
22276
22414
  });
22277
22415
  } catch (error) {
22278
- p12.log.error(error instanceof Error ? error.message : String(error));
22279
- p12.log.info(
22416
+ p13.log.error(error instanceof Error ? error.message : String(error));
22417
+ p13.log.info(
22280
22418
  `Schema JSON was kept. Re-run \`betterstart generate ${metadata.name}${options.skipMigration ? " --skip-migration" : ""}\` after resolving the issue.`
22281
22419
  );
22282
22420
  process.exit(1);
@@ -22284,18 +22422,18 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
22284
22422
  }
22285
22423
 
22286
22424
  // adapters/next/commands/init.ts
22287
- import { execFileSync as execFileSync5, spawn as spawn6 } from "child_process";
22425
+ import { execFileSync as execFileSync4, spawn as spawn6 } from "child_process";
22288
22426
  import fs41 from "fs";
22289
22427
  import path52 from "path";
22290
22428
  import { PassThrough } from "stream";
22291
- import * as p25 from "@clack/prompts";
22429
+ import * as p26 from "@clack/prompts";
22292
22430
 
22293
22431
  // core-engine/utils/cancel-guard.ts
22294
- import * as p13 from "@clack/prompts";
22432
+ import * as p14 from "@clack/prompts";
22295
22433
  function installSetupCancelGuard() {
22296
22434
  const onSignal = () => {
22297
22435
  if (!hasActiveSpinner()) {
22298
- p13.cancel("Setup cancelled.");
22436
+ p14.cancel("Setup cancelled.");
22299
22437
  }
22300
22438
  process.exit(0);
22301
22439
  };
@@ -22349,12 +22487,12 @@ function redactSecrets(text7) {
22349
22487
  }
22350
22488
 
22351
22489
  // adapters/next/init/prompts/database.ts
22352
- import { execFileSync as execFileSync4 } from "child_process";
22353
- import * as p14 from "@clack/prompts";
22490
+ import { execFileSync as execFileSync3 } from "child_process";
22491
+ import * as p15 from "@clack/prompts";
22354
22492
  import pc from "picocolors";
22355
22493
  var VERCEL_NEON_URL = "https://vercel.com/dashboard/integrations/checkout/neon";
22356
22494
  async function promptServices() {
22357
- const choice = await p14.select({
22495
+ const choice = await p15.select({
22358
22496
  message: "Connect a PostgreSQL Database",
22359
22497
  options: [
22360
22498
  {
@@ -22375,8 +22513,8 @@ async function promptServices() {
22375
22513
  ],
22376
22514
  initialValue: "vercel"
22377
22515
  });
22378
- if (p14.isCancel(choice)) {
22379
- p14.cancel("Setup cancelled.");
22516
+ if (p15.isCancel(choice)) {
22517
+ p15.cancel("Setup cancelled.");
22380
22518
  process.exit(0);
22381
22519
  }
22382
22520
  if (choice === "vercel") {
@@ -22390,7 +22528,7 @@ async function promptServices() {
22390
22528
  }
22391
22529
  function openBrowserVercelNeon() {
22392
22530
  openBrowser(VERCEL_NEON_URL);
22393
- p14.log.info(
22531
+ p15.log.info(
22394
22532
  `Opening Vercel... Create a Neon Postgres database, then copy the ${pc.cyan("DATABASE_URL")} from the dashboard.`
22395
22533
  );
22396
22534
  }
@@ -22400,12 +22538,12 @@ function openBrowserVercelNeonResource(url) {
22400
22538
  return;
22401
22539
  }
22402
22540
  openBrowser(url);
22403
- p14.log.info(
22541
+ p15.log.info(
22404
22542
  `Opening Vercel... Copy the Neon ${pc.cyan("DATABASE_URL")} from the database dashboard, then paste it below.`
22405
22543
  );
22406
22544
  }
22407
22545
  async function promptConnectionString() {
22408
- const input = await p14.text({
22546
+ const input = await p15.text({
22409
22547
  message: "Paste your PostgreSQL connection string",
22410
22548
  placeholder: "postgres://user:pass@host/db",
22411
22549
  validate(val) {
@@ -22419,8 +22557,8 @@ async function promptConnectionString() {
22419
22557
  }
22420
22558
  }
22421
22559
  });
22422
- if (p14.isCancel(input)) {
22423
- p14.cancel("Setup cancelled.");
22560
+ if (p15.isCancel(input)) {
22561
+ p15.cancel("Setup cancelled.");
22424
22562
  process.exit(0);
22425
22563
  }
22426
22564
  return input.replace(/^['"]|['"]$/g, "").trim();
@@ -22429,18 +22567,18 @@ function openBrowser(url) {
22429
22567
  try {
22430
22568
  const platform = process.platform;
22431
22569
  if (platform === "darwin") {
22432
- execFileSync4("open", [url], { stdio: "ignore" });
22570
+ execFileSync3("open", [url], { stdio: "ignore" });
22433
22571
  } else if (platform === "win32") {
22434
- execFileSync4("cmd", ["/c", "start", url], { stdio: "ignore" });
22572
+ execFileSync3("cmd", ["/c", "start", url], { stdio: "ignore" });
22435
22573
  } else {
22436
- execFileSync4("xdg-open", [url], { stdio: "ignore" });
22574
+ execFileSync3("xdg-open", [url], { stdio: "ignore" });
22437
22575
  }
22438
22576
  } catch {
22439
22577
  }
22440
22578
  }
22441
22579
 
22442
22580
  // adapters/next/init/prompts/presets.ts
22443
- import * as p15 from "@clack/prompts";
22581
+ import * as p16 from "@clack/prompts";
22444
22582
 
22445
22583
  // adapters/next/init/scaffolders/env.ts
22446
22584
  import crypto2 from "crypto";
@@ -22605,7 +22743,7 @@ async function promptPresets(cwd, options = {}) {
22605
22743
  overwriteKeys.add(key);
22606
22744
  }
22607
22745
  };
22608
- const storage = await p15.select({
22746
+ const storage = await p16.select({
22609
22747
  message: "Choose a file storage",
22610
22748
  options: [
22611
22749
  {
@@ -22629,8 +22767,8 @@ async function promptPresets(cwd, options = {}) {
22629
22767
  ],
22630
22768
  initialValue: "vercel-blob"
22631
22769
  });
22632
- if (p15.isCancel(storage)) {
22633
- p15.cancel("Setup cancelled.");
22770
+ if (p16.isCancel(storage)) {
22771
+ p16.cancel("Setup cancelled.");
22634
22772
  process.exit(0);
22635
22773
  }
22636
22774
  if (storage === "r2") {
@@ -22640,7 +22778,7 @@ async function promptPresets(cwd, options = {}) {
22640
22778
  if (flow?.ok && flow.config) {
22641
22779
  mergeIntegrationConfig(flow.config);
22642
22780
  } else if (flow) {
22643
- p15.log.warn(
22781
+ p16.log.warn(
22644
22782
  "Continuing without Railway bucket credentials \u2014 rerun betterstart add --integration railway-bucket after fixing Railway access."
22645
22783
  );
22646
22784
  } else {
@@ -22657,7 +22795,7 @@ async function promptPresets(cwd, options = {}) {
22657
22795
  });
22658
22796
  overwriteKeys.add("BLOB_READ_WRITE_TOKEN");
22659
22797
  } else if (flow) {
22660
- p15.log.warn(
22798
+ p16.log.warn(
22661
22799
  "Continuing without a Blob token \u2014 add BLOB_READ_WRITE_TOKEN to .env.local from the store on vercel.com/dashboard/stores."
22662
22800
  );
22663
22801
  sections.push({
@@ -22666,7 +22804,7 @@ async function promptPresets(cwd, options = {}) {
22666
22804
  });
22667
22805
  } else {
22668
22806
  if (existingToken) {
22669
- p15.log.info(
22807
+ p16.log.info(
22670
22808
  `Using the existing BLOB_READ_WRITE_TOKEN from .env.local ${pc2.dim(
22671
22809
  `(${maskBlobToken(existingToken)})`
22672
22810
  )}`
@@ -22675,7 +22813,7 @@ async function promptPresets(cwd, options = {}) {
22675
22813
  mergeIntegrationConfig(await collectIntegrationConfig(cwd, ["vercel-blob"]));
22676
22814
  }
22677
22815
  }
22678
- const selectedPresets = await p15.multiselect({
22816
+ const selectedPresets = await p16.multiselect({
22679
22817
  message: "Select presets",
22680
22818
  options: [
22681
22819
  {
@@ -22687,8 +22825,8 @@ async function promptPresets(cwd, options = {}) {
22687
22825
  required: false,
22688
22826
  initialValues: ["blog"]
22689
22827
  });
22690
- if (p15.isCancel(selectedPresets)) {
22691
- p15.cancel("Setup cancelled.");
22828
+ if (p16.isCancel(selectedPresets)) {
22829
+ p16.cancel("Setup cancelled.");
22692
22830
  process.exit(0);
22693
22831
  }
22694
22832
  const integrations = [];
@@ -22715,9 +22853,9 @@ async function promptPresets(cwd, options = {}) {
22715
22853
  }
22716
22854
 
22717
22855
  // adapters/next/init/prompts/project.ts
22718
- import * as p16 from "@clack/prompts";
22856
+ import * as p17 from "@clack/prompts";
22719
22857
  async function promptProject(defaultName) {
22720
- const projectName = await p16.text({
22858
+ const projectName = await p17.text({
22721
22859
  message: "What is your project named?",
22722
22860
  placeholder: defaultName ?? "(Press Enter to use default)",
22723
22861
  defaultValue: defaultName ?? ".",
@@ -22730,15 +22868,15 @@ async function promptProject(defaultName) {
22730
22868
  return void 0;
22731
22869
  }
22732
22870
  });
22733
- if (p16.isCancel(projectName)) {
22734
- p16.cancel("Setup cancelled.");
22871
+ if (p17.isCancel(projectName)) {
22872
+ p17.cancel("Setup cancelled.");
22735
22873
  process.exit(0);
22736
22874
  }
22737
22875
  return { projectName: projectName.trim() || "." };
22738
22876
  }
22739
22877
 
22740
22878
  // adapters/next/init/providers.ts
22741
- import * as p17 from "@clack/prompts";
22879
+ import * as p18 from "@clack/prompts";
22742
22880
  var DATABASE_PROVIDERS = ["vercel", "railway", "manual"];
22743
22881
  var STORAGE_PROVIDERS = ["vercel-blob", "railway-bucket", "r2", "local"];
22744
22882
  var DEPLOY_PROVIDERS = ["vercel", "railway", "none"];
@@ -22795,7 +22933,7 @@ function validateResolvedDatabaseProvider(provider, options) {
22795
22933
  }
22796
22934
  }
22797
22935
  async function promptDeployProvider(initialValue = "none") {
22798
- const provider = await p17.select({
22936
+ const provider = await p18.select({
22799
22937
  message: "Deploy this project",
22800
22938
  options: [
22801
22939
  {
@@ -22813,8 +22951,8 @@ async function promptDeployProvider(initialValue = "none") {
22813
22951
  ],
22814
22952
  initialValue
22815
22953
  });
22816
- if (p17.isCancel(provider)) {
22817
- p17.cancel("Setup cancelled.");
22954
+ if (p18.isCancel(provider)) {
22955
+ p18.cancel("Setup cancelled.");
22818
22956
  process.exit(0);
22819
22957
  }
22820
22958
  return provider;
@@ -22823,7 +22961,7 @@ async function promptDeployProvider(initialValue = "none") {
22823
22961
  // adapters/next/init/railway/deploy.ts
22824
22962
  import fs28 from "fs";
22825
22963
  import path34 from "path";
22826
- import * as p19 from "@clack/prompts";
22964
+ import * as p20 from "@clack/prompts";
22827
22965
 
22828
22966
  // adapters/next/init/deploy/guard.ts
22829
22967
  import { spawn as spawn3 } from "child_process";
@@ -22920,7 +23058,7 @@ function guardBetterstartConfig(cwd, restores) {
22920
23058
  }
22921
23059
 
22922
23060
  // adapters/next/init/railway/project.ts
22923
- import * as p18 from "@clack/prompts";
23061
+ import * as p19 from "@clack/prompts";
22924
23062
 
22925
23063
  // adapters/next/init/railway/runner.ts
22926
23064
  import { spawn as spawn4 } from "child_process";
@@ -23204,15 +23342,15 @@ async function ensureRailwayProject(runner, options) {
23204
23342
  createWorkspace = options.workspaces[0]?.id;
23205
23343
  } else if (!createWorkspace && options.interactive && options.workspaces?.length) {
23206
23344
  projectSpinner.clear();
23207
- const workspace = await p18.select({
23345
+ const workspace = await p19.select({
23208
23346
  message: "Choose a Railway workspace",
23209
23347
  options: options.workspaces.map((candidate) => ({
23210
23348
  value: candidate.id,
23211
23349
  label: candidate.name
23212
23350
  }))
23213
23351
  });
23214
- if (p18.isCancel(workspace)) {
23215
- p18.cancel("Setup cancelled.");
23352
+ if (p19.isCancel(workspace)) {
23353
+ p19.cancel("Setup cancelled.");
23216
23354
  process.exit(0);
23217
23355
  }
23218
23356
  createWorkspace = workspace;
@@ -23738,7 +23876,7 @@ async function runRailwayDeployFlow(options) {
23738
23876
  );
23739
23877
  envSpinner.clear();
23740
23878
  for (const key of sync.failed) {
23741
- p19.log.warn(`Could not set ${pc4.cyan(key)} on Railway.`);
23879
+ p20.log.warn(`Could not set ${pc4.cyan(key)} on Railway.`);
23742
23880
  }
23743
23881
  if (sync.failed.length > 0) {
23744
23882
  return {
@@ -23753,12 +23891,12 @@ async function runRailwayDeployFlow(options) {
23753
23891
  const packageGuard = await guardProjectForDeploy(options.cwd);
23754
23892
  guardSpinner.clear();
23755
23893
  if (packageGuard.lockfile === "failed") {
23756
- p19.log.warn(
23894
+ p20.log.warn(
23757
23895
  "Could not refresh pnpm-lock.yaml after removing betterstart-cli \u2014 the remote install may fail."
23758
23896
  );
23759
23897
  }
23760
23898
  for (const dependency of packageGuard.localSpecDeps) {
23761
- p19.log.warn(
23899
+ p20.log.warn(
23762
23900
  `Dependency ${pc4.cyan(dependency)} uses a local spec that cannot install on Railway.`
23763
23901
  );
23764
23902
  }
@@ -23811,7 +23949,7 @@ ${deploy.stderr}`) ?? deploy.errorMessage
23811
23949
  }
23812
23950
 
23813
23951
  // adapters/next/init/railway/auth.ts
23814
- import * as p20 from "@clack/prompts";
23952
+ import * as p21 from "@clack/prompts";
23815
23953
  import pc5 from "picocolors";
23816
23954
  var WHOAMI_TIMEOUT_MS = 3e4;
23817
23955
  var LOGIN_TIMEOUT_MS = 3e5;
@@ -23881,7 +24019,7 @@ async function ensureRailwayAuth(runner, cwd, options) {
23881
24019
  return { authed: false, reason: existing.reason };
23882
24020
  }
23883
24021
  checkSpinner.clear();
23884
- p20.log.info(
24022
+ p21.log.info(
23885
24023
  "Sign in to Railway to continue. Railway will open your browser or show a device code."
23886
24024
  );
23887
24025
  const login = await runRailway(runner, ["login"], {
@@ -25768,11 +25906,11 @@ function scaffoldTsconfig(cwd, config) {
25768
25906
  }
25769
25907
 
25770
25908
  // adapters/next/init/vercel/flow.ts
25771
- import * as p24 from "@clack/prompts";
25909
+ import * as p25 from "@clack/prompts";
25772
25910
  import pc9 from "picocolors";
25773
25911
 
25774
25912
  // adapters/next/init/vercel/auth.ts
25775
- import * as p21 from "@clack/prompts";
25913
+ import * as p22 from "@clack/prompts";
25776
25914
  import pc6 from "picocolors";
25777
25915
 
25778
25916
  // adapters/next/init/vercel/runner.ts
@@ -26016,7 +26154,7 @@ async function ensureVercelAuth(runner, cwd, options) {
26016
26154
  checkSpinner.clear();
26017
26155
  const signInMessage = `Sign in to Vercel to continue ${pc6.dim("(or press Ctrl-C to enter a connection string manually)")}`;
26018
26156
  const signInRows = clackLogRows(signInMessage);
26019
- p21.log.info(signInMessage);
26157
+ p22.log.info(signInMessage);
26020
26158
  let streamedRows = 0;
26021
26159
  const login = await runVercel(runner, ["login"], {
26022
26160
  cwd,
@@ -26048,7 +26186,7 @@ function signedInMessage(username) {
26048
26186
  }
26049
26187
 
26050
26188
  // adapters/next/init/vercel/blob.ts
26051
- import * as p22 from "@clack/prompts";
26189
+ import * as p23 from "@clack/prompts";
26052
26190
  import pc7 from "picocolors";
26053
26191
 
26054
26192
  // adapters/next/init/vercel/env-pull.ts
@@ -26290,7 +26428,7 @@ async function provisionBlobStoreInteractive(runner, cwd, options) {
26290
26428
  if (terminalFallbackRan) break;
26291
26429
  terminalFallbackRan = true;
26292
26430
  quietSpinner.clear();
26293
- p22.log.info(
26431
+ p23.log.info(
26294
26432
  `Create your Blob store in the Vercel prompts below ${pc7.dim(
26295
26433
  "(connect it to all environments)."
26296
26434
  )}`
@@ -26489,7 +26627,7 @@ function guardEnvLocal(cwd) {
26489
26627
  }
26490
26628
 
26491
26629
  // adapters/next/init/vercel/neon.ts
26492
- import * as p23 from "@clack/prompts";
26630
+ import * as p24 from "@clack/prompts";
26493
26631
  import pc8 from "picocolors";
26494
26632
  var PROVISION_TIMEOUT_MS2 = 18e4;
26495
26633
  var INTERACTIVE_PROVISION_TIMEOUT_MS2 = 6e5;
@@ -26508,7 +26646,7 @@ async function provisionNeonInteractive(runner, cwd, options) {
26508
26646
  termsResolved = true;
26509
26647
  quietSpinner.clear();
26510
26648
  eraseRows(termsNotice.rows);
26511
- p23.log.step(termsNotice.text);
26649
+ p24.log.step(termsNotice.text);
26512
26650
  };
26513
26651
  const quiet = await runVercel(runner, neonAddArgs(options), {
26514
26652
  cwd,
@@ -26527,7 +26665,7 @@ ${pc8.dim(termsUrl)}`,
26527
26665
  rows: clackLogRows(message) + clackLogRows(termsUrl) - 1
26528
26666
  };
26529
26667
  quietSpinner.clear();
26530
- p23.log.info(termsNotice.text);
26668
+ p24.log.info(termsNotice.text);
26531
26669
  quietSpinner.start("Waiting for the terms to be accepted");
26532
26670
  return;
26533
26671
  }
@@ -26543,7 +26681,7 @@ ${pc8.dim(termsUrl)}`,
26543
26681
  return readNeonProvisionInfo(quiet.stdout);
26544
26682
  }
26545
26683
  quietSpinner.clear();
26546
- p23.log.info(
26684
+ p24.log.info(
26547
26685
  `Create your Neon database in the Vercel prompts below ${pc8.dim(
26548
26686
  "(the Free plan is recommended)."
26549
26687
  )}`
@@ -26620,14 +26758,14 @@ async function runVercelNeonFlow(options) {
26620
26758
  allowLogin: options.interactive
26621
26759
  });
26622
26760
  if (!auth.authed) {
26623
- p24.log.warn(authFailureMessage(auth.reason));
26761
+ p25.log.warn(authFailureMessage(auth.reason));
26624
26762
  return { ok: false };
26625
26763
  }
26626
26764
  await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
26627
26765
  const neon = await provisionNeonForMode(runner, options);
26628
26766
  if (neon.failure) {
26629
- p24.log.warn(neonFailureMessage(neon.failure));
26630
- if (neon.detail) p24.log.message(pc9.dim(redactSecrets(neon.detail)));
26767
+ p25.log.warn(neonFailureMessage(neon.failure));
26768
+ if (neon.detail) p25.log.message(pc9.dim(redactSecrets(neon.detail)));
26631
26769
  return { ok: false };
26632
26770
  }
26633
26771
  const databaseUrl = await pullNeonDatabaseUrl(runner, options.cwd, env);
@@ -26640,7 +26778,7 @@ async function runVercelNeonFlow(options) {
26640
26778
  dismissSignedInNote
26641
26779
  };
26642
26780
  } catch (error) {
26643
- p24.log.warn(
26781
+ p25.log.warn(
26644
26782
  `Vercel provisioning failed: ${error instanceof Error ? error.message : String(error)}`
26645
26783
  );
26646
26784
  return { ok: false };
@@ -26662,14 +26800,14 @@ async function runVercelBlobFlow(options) {
26662
26800
  allowLogin: options.interactive
26663
26801
  });
26664
26802
  if (!auth.authed) {
26665
- p24.log.warn(authFailureMessage(auth.reason));
26803
+ p25.log.warn(authFailureMessage(auth.reason));
26666
26804
  return { ok: false };
26667
26805
  }
26668
26806
  await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
26669
26807
  const blob = await provisionBlobForMode(runner, options);
26670
26808
  if (blob.failure || !blob.token) {
26671
- p24.log.warn(blobFailureMessage(blob.failure));
26672
- if (blob.detail) p24.log.message(pc9.dim(redactSecrets(blob.detail)));
26809
+ p25.log.warn(blobFailureMessage(blob.failure));
26810
+ if (blob.detail) p25.log.message(pc9.dim(redactSecrets(blob.detail)));
26673
26811
  return { ok: false };
26674
26812
  }
26675
26813
  return {
@@ -26678,7 +26816,7 @@ async function runVercelBlobFlow(options) {
26678
26816
  blobStoreName: blob.storeName
26679
26817
  };
26680
26818
  } catch (error) {
26681
- p24.log.warn(
26819
+ p25.log.warn(
26682
26820
  `Vercel provisioning failed: ${error instanceof Error ? error.message : String(error)}`
26683
26821
  );
26684
26822
  return { ok: false };
@@ -26700,7 +26838,7 @@ async function runVercelDeployFlow(options) {
26700
26838
  allowLogin: options.interactive ?? true
26701
26839
  });
26702
26840
  if (!auth.authed) {
26703
- p24.log.warn(authFailureMessage(auth.reason));
26841
+ p25.log.warn(authFailureMessage(auth.reason));
26704
26842
  printManualDeployHint();
26705
26843
  return { ok: false };
26706
26844
  }
@@ -26710,7 +26848,7 @@ async function runVercelDeployFlow(options) {
26710
26848
  const sync = await syncVercelProductionEnv(runner, options.cwd, env);
26711
26849
  envSpinner.clear();
26712
26850
  for (const key of sync.failed) {
26713
- p24.log.warn(
26851
+ p25.log.warn(
26714
26852
  `Could not set ${pc9.cyan(key)} on Vercel \u2014 add it in the project's environment settings.`
26715
26853
  );
26716
26854
  }
@@ -26720,12 +26858,12 @@ async function runVercelDeployFlow(options) {
26720
26858
  const packageGuard = await guardProjectForDeploy(options.cwd);
26721
26859
  guardSpinner.clear();
26722
26860
  if (packageGuard.lockfile === "failed") {
26723
- p24.log.warn(
26861
+ p25.log.warn(
26724
26862
  "Could not refresh pnpm-lock.yaml after removing betterstart-cli \u2014 the remote install may fail."
26725
26863
  );
26726
26864
  }
26727
26865
  for (const dep of packageGuard.localSpecDeps) {
26728
- p24.log.warn(
26866
+ p25.log.warn(
26729
26867
  `Dependency ${pc9.cyan(dep)} uses a local spec that cannot install on Vercel \u2014 the remote build may fail.`
26730
26868
  );
26731
26869
  }
@@ -26742,7 +26880,7 @@ async function runVercelDeployFlow(options) {
26742
26880
  }
26743
26881
  if (deploy.failure) {
26744
26882
  deploySpinner.stop(`${pc9.yellow("\u25B2")} ${deployFailureMessage(deploy.failure)}`);
26745
- if (deploy.detail) p24.log.message(pc9.dim(redactSecrets(deploy.detail)));
26883
+ if (deploy.detail) p25.log.message(pc9.dim(redactSecrets(deploy.detail)));
26746
26884
  printManualDeployHint();
26747
26885
  return { ok: false };
26748
26886
  }
@@ -26750,7 +26888,7 @@ async function runVercelDeployFlow(options) {
26750
26888
  deploySpinner.stop(url ? `Deployed ${pc9.cyan(url)}` : "Deployed to Vercel");
26751
26889
  return { ok: true, url, syncedEnvKeys: sync.synced };
26752
26890
  } catch (error) {
26753
- p24.log.warn(`Vercel deploy failed: ${error instanceof Error ? error.message : String(error)}`);
26891
+ p25.log.warn(`Vercel deploy failed: ${error instanceof Error ? error.message : String(error)}`);
26754
26892
  printManualDeployHint();
26755
26893
  return { ok: false };
26756
26894
  } finally {
@@ -26758,7 +26896,7 @@ async function runVercelDeployFlow(options) {
26758
26896
  }
26759
26897
  }
26760
26898
  function printManualDeployHint() {
26761
- p24.log.info(`You can deploy manually: ${pc9.cyan("vercel deploy --prod")}`);
26899
+ p25.log.info(`You can deploy manually: ${pc9.cyan("vercel deploy --prod")}`);
26762
26900
  }
26763
26901
  async function ensureLinkedProject(runner, cwd, projectName, env, scope) {
26764
26902
  if (readLinkedProjectId(cwd)) return;
@@ -26841,13 +26979,6 @@ import pc10 from "picocolors";
26841
26979
  import fs40 from "fs";
26842
26980
  import path51 from "path";
26843
26981
  import * as clack2 from "@clack/prompts";
26844
-
26845
- // core-engine/utils/interactive.ts
26846
- function isInteractiveSession4() {
26847
- return Boolean(process.stdin.isTTY) && process.env.CI !== "true";
26848
- }
26849
-
26850
- // adapters/next/commands/seed.ts
26851
26982
  function buildSeedScript(authBasePath = "/api/admin/auth") {
26852
26983
  return `/**
26853
26984
  * BetterStart Admin \u2014 Seed Script
@@ -27029,7 +27160,7 @@ async function runSeedCommand(options) {
27029
27160
  process.exit(1);
27030
27161
  }
27031
27162
  const adminDir = config.paths?.admin ?? "./admin";
27032
- const interactive = isInteractiveSession4();
27163
+ const interactive = isInteractiveSession();
27033
27164
  let email;
27034
27165
  if (options.email) {
27035
27166
  if (!options.email.includes("@")) {
@@ -27102,10 +27233,10 @@ async function runSeedCommand(options) {
27102
27233
  }
27103
27234
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
27104
27235
  fs40.writeFileSync(seedPath, buildSeedScript(`${namespace.apiPath}/auth`), "utf-8");
27105
- const { execFile } = await import("child_process");
27236
+ const { execFile: execFile2 } = await import("child_process");
27106
27237
  const tsxBin = path51.join(cwd, "node_modules", ".bin", "tsx");
27107
27238
  const runSeed2 = (overwrite) => new Promise((resolve, reject) => {
27108
- execFile(
27239
+ execFile2(
27109
27240
  tsxBin,
27110
27241
  [seedPath],
27111
27242
  {
@@ -27194,16 +27325,16 @@ function addVersionToBoxBottomBorder(box2, version2) {
27194
27325
  if (!bottomLine) {
27195
27326
  return box2;
27196
27327
  }
27197
- const leftCornerIndex = bottomLine.indexOf(p25.S_CORNER_BOTTOM_LEFT);
27198
- const rightCornerIndex = bottomLine.lastIndexOf(p25.S_CORNER_BOTTOM_RIGHT);
27328
+ const leftCornerIndex = bottomLine.indexOf(p26.S_CORNER_BOTTOM_LEFT);
27329
+ const rightCornerIndex = bottomLine.lastIndexOf(p26.S_CORNER_BOTTOM_RIGHT);
27199
27330
  const label = ` v${version2} `;
27200
- const borderWidth = rightCornerIndex - leftCornerIndex - p25.S_CORNER_BOTTOM_LEFT.length;
27331
+ const borderWidth = rightCornerIndex - leftCornerIndex - p26.S_CORNER_BOTTOM_LEFT.length;
27201
27332
  if (leftCornerIndex === -1 || rightCornerIndex === -1 || borderWidth < label.length) {
27202
27333
  return box2;
27203
27334
  }
27204
27335
  const leftBorderWidth = Math.floor((borderWidth - label.length) / 2);
27205
27336
  const rightBorderWidth = borderWidth - label.length - leftBorderWidth;
27206
- lines[bottomLineIndex] = `${bottomLine.slice(0, leftCornerIndex + p25.S_CORNER_BOTTOM_LEFT.length)}${p25.S_BAR_H.repeat(leftBorderWidth)}${label}${p25.S_BAR_H.repeat(rightBorderWidth)}${bottomLine.slice(rightCornerIndex)}`;
27337
+ lines[bottomLineIndex] = `${bottomLine.slice(0, leftCornerIndex + p26.S_CORNER_BOTTOM_LEFT.length)}${p26.S_BAR_H.repeat(leftBorderWidth)}${label}${p26.S_BAR_H.repeat(rightBorderWidth)}${bottomLine.slice(rightCornerIndex)}`;
27207
27338
  return lines.join("\n");
27208
27339
  }
27209
27340
  function renderInitBanner() {
@@ -27213,7 +27344,7 @@ function renderInitBanner() {
27213
27344
  output.on("data", (chunk) => {
27214
27345
  box2 += chunk.toString();
27215
27346
  });
27216
- p25.box(
27347
+ p26.box(
27217
27348
  `
27218
27349
  \u2584 \u2597 \u2597 \u2584\u2596\u2597 \u2597
27219
27350
  \u2599\u2598\u2588\u258C\u259C\u2598\u259C\u2598\u2588\u258C\u259B\u2598\u259A \u259C\u2598\u2580\u258C\u259B\u2598\u259C\u2598
@@ -27309,7 +27440,7 @@ async function runInitCommand(name, options) {
27309
27440
  let restoreStdout;
27310
27441
  if (options.json) {
27311
27442
  if (!options.yes) {
27312
- p25.log.error("--json requires --yes.");
27443
+ p26.log.error("--json requires --yes.");
27313
27444
  process.exit(1);
27314
27445
  }
27315
27446
  restoreStdout = redirectStdoutToStderr();
@@ -27330,7 +27461,7 @@ async function runInitCommand(name, options) {
27330
27461
  }
27331
27462
  } catch (error) {
27332
27463
  disposeCancelGuard();
27333
- p25.log.error(error instanceof Error ? error.message : String(error));
27464
+ p26.log.error(error instanceof Error ? error.message : String(error));
27334
27465
  process.exit(1);
27335
27466
  }
27336
27467
  let cwd = process.cwd();
@@ -27341,7 +27472,7 @@ async function runInitCommand(name, options) {
27341
27472
  try {
27342
27473
  namespace = validateAdminNamespace(options.namespace);
27343
27474
  } catch (error) {
27344
- p25.log.error(error instanceof Error ? error.message : String(error));
27475
+ p26.log.error(error instanceof Error ? error.message : String(error));
27345
27476
  process.exit(1);
27346
27477
  }
27347
27478
  }
@@ -27350,13 +27481,13 @@ async function runInitCommand(name, options) {
27350
27481
  try {
27351
27482
  projectPrompt = options.yes ? resolveNonInteractiveProject(name) : await promptProject(name);
27352
27483
  } catch (error) {
27353
- p25.log.error(error instanceof Error ? error.message : String(error));
27484
+ p26.log.error(error instanceof Error ? error.message : String(error));
27354
27485
  process.exit(1);
27355
27486
  }
27356
27487
  }
27357
27488
  if (!options.yes && !options.namespace) {
27358
27489
  const defaultDashboardPath = resolveAdminNamespace(DEFAULT_ADMIN_NAMESPACE).routePath;
27359
- const namespaceInput = await p25.text({
27490
+ const namespaceInput = await p26.text({
27360
27491
  message: "Enter the dashboard path",
27361
27492
  placeholder: `eg. ${defaultDashboardPath}`,
27362
27493
  defaultValue: defaultDashboardPath,
@@ -27369,8 +27500,8 @@ async function runInitCommand(name, options) {
27369
27500
  }
27370
27501
  }
27371
27502
  });
27372
- if (p25.isCancel(namespaceInput)) {
27373
- p25.cancel("Setup cancelled.");
27503
+ if (p26.isCancel(namespaceInput)) {
27504
+ p26.cancel("Setup cancelled.");
27374
27505
  process.exit(0);
27375
27506
  }
27376
27507
  namespace = validateAdminDashboardPath(namespaceInput);
@@ -27382,13 +27513,13 @@ async function runInitCommand(name, options) {
27382
27513
  if (project2.isExisting) {
27383
27514
  srcDir = project2.hasSrcDir;
27384
27515
  if (!project2.hasTypeScript) {
27385
- p25.log.error("TypeScript is required. Please add a tsconfig.json first.");
27516
+ p26.log.error("TypeScript is required. Please add a tsconfig.json first.");
27386
27517
  process.exit(1);
27387
27518
  }
27388
27519
  if (forceMode) {
27389
27520
  const nuked = removeExistingAdminPaths(cwd, await resolveForceInitNamespaces(cwd, namespace));
27390
27521
  if (nuked > 0) {
27391
- p25.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27522
+ p26.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27392
27523
  }
27393
27524
  project2 = detectProject(cwd, namespace);
27394
27525
  } else if (project2.conflicts.length > 0) {
@@ -27397,14 +27528,14 @@ async function runInitCommand(name, options) {
27397
27528
  "",
27398
27529
  pc10.dim(`Use ${pc10.bold("--force")} to remove existing admin files before scaffolding.`)
27399
27530
  );
27400
- p25.note(conflictLines.join("\n"), pc10.yellow("Conflicts"));
27531
+ p26.note(conflictLines.join("\n"), pc10.yellow("Conflicts"));
27401
27532
  if (options.yes) {
27402
- p25.log.error(
27533
+ p26.log.error(
27403
27534
  "Can't continue with --yes while admin files conflict. Re-run with --force to remove them first."
27404
27535
  );
27405
27536
  process.exit(1);
27406
27537
  }
27407
- const proceed = await p25.confirm({
27538
+ const proceed = await p26.confirm({
27408
27539
  message: [
27409
27540
  `Continue with ${pc10.bold(pc10.cyan("--force"))}?`,
27410
27541
  `${pc10.cyan("\u2502")} ${pc10.dim("This will force overwrite the existing admin code.")}`,
@@ -27412,14 +27543,14 @@ async function runInitCommand(name, options) {
27412
27543
  ].join("\n"),
27413
27544
  initialValue: true
27414
27545
  });
27415
- if (p25.isCancel(proceed) || !proceed) {
27416
- p25.cancel("Setup cancelled.");
27546
+ if (p26.isCancel(proceed) || !proceed) {
27547
+ p26.cancel("Setup cancelled.");
27417
27548
  process.exit(0);
27418
27549
  }
27419
27550
  forceMode = true;
27420
27551
  const nuked = removeExistingAdminPaths(cwd, await resolveForceInitNamespaces(cwd, namespace));
27421
27552
  if (nuked > 0) {
27422
- p25.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27553
+ p26.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27423
27554
  }
27424
27555
  project2 = detectProject(cwd, namespace);
27425
27556
  }
@@ -27427,7 +27558,7 @@ async function runInitCommand(name, options) {
27427
27558
  const freshProject = projectPrompt;
27428
27559
  srcDir = false;
27429
27560
  if (!options.yes) {
27430
- const pmChoice = await p25.select({
27561
+ const pmChoice = await p26.select({
27431
27562
  message: "Which package manager do you want to use?",
27432
27563
  options: [
27433
27564
  { value: "pnpm", label: "pnpm", hint: "recommended" },
@@ -27435,8 +27566,8 @@ async function runInitCommand(name, options) {
27435
27566
  { value: "bun", label: "bun" }
27436
27567
  ]
27437
27568
  });
27438
- if (p25.isCancel(pmChoice)) {
27439
- p25.cancel("Setup cancelled.");
27569
+ if (p26.isCancel(pmChoice)) {
27570
+ p26.cancel("Setup cancelled.");
27440
27571
  process.exit(0);
27441
27572
  }
27442
27573
  pm = pmChoice;
@@ -27471,8 +27602,8 @@ async function runInitCommand(name, options) {
27471
27602
  process.stderr.write(`${createNextAppResult.output.trimEnd()}
27472
27603
  `);
27473
27604
  }
27474
- p25.log.error(createNextAppResult.error);
27475
- p25.log.info(
27605
+ p26.log.error(createNextAppResult.error);
27606
+ p26.log.info(
27476
27607
  `You can create the project manually:
27477
27608
  ${pc10.cyan(`npx create-next-app@latest ${freshProject.projectName} --typescript --tailwind --app`)}
27478
27609
  Then run ${pc10.cyan("betterstart init")} inside it.`
@@ -27486,11 +27617,11 @@ async function runInitCommand(name, options) {
27486
27617
  );
27487
27618
  if (!hasPackageJson || !hasNextConfig) {
27488
27619
  createNextAppSpinner.stop(`Failed to create Next.js app: ${displayName}`);
27489
- p25.log.error(
27620
+ p26.log.error(
27490
27621
  "create-next-app completed but the project was not created. This can happen with nested npx calls."
27491
27622
  );
27492
27623
  const manualCmd = `npx create-next-app@latest ${freshProject.projectName} --typescript --tailwind --app`;
27493
- p25.log.info(
27624
+ p26.log.info(
27494
27625
  `Create the project manually:
27495
27626
  ${pc10.cyan(manualCmd)}
27496
27627
  Then run ${pc10.cyan("betterstart init")} inside it.`
@@ -27539,13 +27670,13 @@ async function runInitCommand(name, options) {
27539
27670
  try {
27540
27671
  validateResolvedDatabaseProvider(databaseProvider, options);
27541
27672
  } catch (error) {
27542
- p25.log.error(error instanceof Error ? error.message : String(error));
27673
+ p26.log.error(error instanceof Error ? error.message : String(error));
27543
27674
  process.exit(1);
27544
27675
  }
27545
27676
  if (databaseProvider === "manual") {
27546
27677
  const candidate = options.databaseUrl ?? existingDbUrl ?? promptedManualUrl;
27547
27678
  if (candidate && !isValidDbUrl(candidate)) {
27548
- p25.log.error(
27679
+ p26.log.error(
27549
27680
  `Invalid database URL. Must start with ${pc10.cyan("postgres://")} or ${pc10.cyan("postgresql://")}`
27550
27681
  );
27551
27682
  process.exit(1);
@@ -27553,7 +27684,7 @@ async function runInitCommand(name, options) {
27553
27684
  if (candidate) {
27554
27685
  databaseUrl = candidate;
27555
27686
  if (existingDbUrl === candidate && !options.databaseUrl) {
27556
- p25.log.info(
27687
+ p26.log.info(
27557
27688
  `Using the existing DATABASE_URL from .env.local ${pc10.dim(`(${maskDbUrl(candidate)})`)}`
27558
27689
  );
27559
27690
  }
@@ -27573,7 +27704,7 @@ async function runInitCommand(name, options) {
27573
27704
  persistDatabaseUrl(cwd, databaseUrl);
27574
27705
  dismissVercelSignedInNote = flow.dismissSignedInNote;
27575
27706
  } else if (options.yes) {
27576
- p25.log.error(
27707
+ p26.log.error(
27577
27708
  flow.ok ? "Created a Neon database, but DATABASE_URL could not be retrieved from Vercel." : "Vercel database provisioning did not complete."
27578
27709
  );
27579
27710
  process.exit(1);
@@ -27582,7 +27713,7 @@ async function runInitCommand(name, options) {
27582
27713
  databaseUrl = await promptConnectionString();
27583
27714
  persistDatabaseUrl(cwd, databaseUrl);
27584
27715
  } else {
27585
- p25.log.info("Falling back to a manual database connection string.");
27716
+ p26.log.info("Falling back to a manual database connection string.");
27586
27717
  openBrowserVercelNeon();
27587
27718
  databaseUrl = await promptConnectionString();
27588
27719
  }
@@ -27596,11 +27727,11 @@ async function runInitCommand(name, options) {
27596
27727
  } catch (error) {
27597
27728
  const message = error instanceof Error ? error.message : String(error);
27598
27729
  if (options.yes) {
27599
- p25.log.error(`Railway database provisioning failed: ${message}`);
27730
+ p26.log.error(`Railway database provisioning failed: ${message}`);
27600
27731
  process.exit(1);
27601
27732
  }
27602
- p25.log.warn(`Railway database provisioning failed: ${message}`);
27603
- p25.log.info("Falling back to a manual database connection string.");
27733
+ p26.log.warn(`Railway database provisioning failed: ${message}`);
27734
+ p26.log.info("Falling back to a manual database connection string.");
27604
27735
  databaseUrl = await promptConnectionString();
27605
27736
  }
27606
27737
  }
@@ -27630,7 +27761,7 @@ async function runInitCommand(name, options) {
27630
27761
  return { ok: true, config: config2 };
27631
27762
  } catch (error) {
27632
27763
  const message = error instanceof Error ? error.message : String(error);
27633
- p25.log.warn(`Railway bucket provisioning failed: ${message}`);
27764
+ p26.log.warn(`Railway bucket provisioning failed: ${message}`);
27634
27765
  return { ok: false };
27635
27766
  }
27636
27767
  };
@@ -27644,7 +27775,7 @@ async function runInitCommand(name, options) {
27644
27775
  if (storage === "r2") {
27645
27776
  const missingR2Keys = R2_ENV_KEYS.filter((key) => !readEnvVar(cwd, key)?.trim());
27646
27777
  if (options.yes && missingR2Keys.length > 0) {
27647
- p25.log.error(
27778
+ p26.log.error(
27648
27779
  `Cloudflare R2 is missing required environment variables: ${missingR2Keys.join(", ")}.`
27649
27780
  );
27650
27781
  process.exit(1);
@@ -27658,7 +27789,7 @@ async function runInitCommand(name, options) {
27658
27789
  if (flow.ok && flow.config) {
27659
27790
  mergeCollectedIntegrationConfig(flow.config);
27660
27791
  } else if (options.yes) {
27661
- p25.log.error("Railway bucket provisioning did not complete.");
27792
+ p26.log.error("Railway bucket provisioning did not complete.");
27662
27793
  process.exit(1);
27663
27794
  }
27664
27795
  }
@@ -27677,10 +27808,10 @@ async function runInitCommand(name, options) {
27677
27808
  });
27678
27809
  collectedIntegrationConfig.overwriteKeys.add("BLOB_READ_WRITE_TOKEN");
27679
27810
  } else if (options.yes) {
27680
- p25.log.error("Vercel Blob provisioning did not complete.");
27811
+ p26.log.error("Vercel Blob provisioning did not complete.");
27681
27812
  process.exit(1);
27682
27813
  } else {
27683
- p25.log.warn(
27814
+ p26.log.warn(
27684
27815
  "Continuing without a Blob token \u2014 add BLOB_READ_WRITE_TOKEN to .env.local from the store on vercel.com/dashboard/stores."
27685
27816
  );
27686
27817
  collectedIntegrationConfig.sections.push({
@@ -27754,7 +27885,7 @@ async function runInitCommand(name, options) {
27754
27885
  const nextConfigResult = scaffoldNextConfig({ cwd, nextMajorVersion });
27755
27886
  s.clear();
27756
27887
  if (nextConfigResult.status === "unsupported") {
27757
- p25.log.warn("The Next.js config could not be updated automatically \u2014 review it manually.");
27888
+ p26.log.warn("The Next.js config could not be updated automatically \u2014 review it manually.");
27758
27889
  }
27759
27890
  const drizzleConfigPath = path52.join(cwd, "drizzle.config.ts");
27760
27891
  if (!dbFiles.includes("drizzle.config.ts") && fs41.existsSync(drizzleConfigPath)) {
@@ -27765,20 +27896,20 @@ async function runInitCommand(name, options) {
27765
27896
  readNamespacedTemplate("drizzle.config.ts", namespace),
27766
27897
  "utf-8"
27767
27898
  );
27768
- p25.log.success("Updated drizzle.config.ts");
27899
+ p26.log.success("Updated drizzle.config.ts");
27769
27900
  } else if (!options.yes) {
27770
- const overwrite = await p25.confirm({
27901
+ const overwrite = await p26.confirm({
27771
27902
  message: "drizzle.config.ts already exists. Overwrite with latest version?",
27772
27903
  initialValue: true
27773
27904
  });
27774
- if (!p25.isCancel(overwrite) && overwrite) {
27905
+ if (!p26.isCancel(overwrite) && overwrite) {
27775
27906
  const { readNamespacedTemplate } = await import("./template-reader-PVN53GS7.js");
27776
27907
  fs41.writeFileSync(
27777
27908
  drizzleConfigPath,
27778
27909
  readNamespacedTemplate("drizzle.config.ts", namespace),
27779
27910
  "utf-8"
27780
27911
  );
27781
- p25.log.success("Updated drizzle.config.ts");
27912
+ p26.log.success("Updated drizzle.config.ts");
27782
27913
  }
27783
27914
  }
27784
27915
  }
@@ -27803,8 +27934,8 @@ async function runInitCommand(name, options) {
27803
27934
  s.stop("");
27804
27935
  } else {
27805
27936
  s.stop("Failed to install dependencies");
27806
- p25.log.warn(depsResult.error ?? "Unknown error");
27807
- p25.log.info(
27937
+ p26.log.warn(depsResult.error ?? "Unknown error");
27938
+ p26.log.info(
27808
27939
  `You can install them manually:
27809
27940
  ${pc10.cyan(`${pm} add ${depsResult.dependencies.join(" ")}`)}
27810
27941
  ${pc10.cyan(`${pm} add -D ${depsResult.devDeps.join(" ")}`)}`
@@ -27860,22 +27991,22 @@ async function runInitCommand(name, options) {
27860
27991
  writeConfigFile(cwd, resolvedIntegrationInstallResult.config);
27861
27992
  const usesLocalStorage = resolvedIntegrationInstallResult.config.storage.provider === "local";
27862
27993
  for (const err of coreSchemasResult.errors) {
27863
- p25.log.warn(`Core schemas: ${err}`);
27994
+ p26.log.warn(`Core schemas: ${err}`);
27864
27995
  }
27865
27996
  for (const warning of resolvedPresetInstallResult.warnings) {
27866
- p25.log.warn(warning);
27997
+ p26.log.warn(warning);
27867
27998
  }
27868
27999
  for (const warning of resolvedIntegrationInstallResult.warnings) {
27869
- p25.log.warn(warning);
28000
+ p26.log.warn(warning);
27870
28001
  }
27871
28002
  if (usesLocalStorage) {
27872
- p25.log.warn(
28003
+ p26.log.warn(
27873
28004
  "Local filesystem storage is only for development or self-hosted persistent-disk deployments. Use Vercel Blob, Railway Bucket, or Cloudflare R2 for hosted production."
27874
28005
  );
27875
28006
  }
27876
28007
  let dbPushed = false;
27877
28008
  if (depsResult.success && options.skipMigration && hasDbUrl(cwd)) {
27878
- p25.log.info(`Skipping database schema push ${pc10.dim("(--skip-migration)")}`);
28009
+ p26.log.info(`Skipping database schema push ${pc10.dim("(--skip-migration)")}`);
27879
28010
  } else if (depsResult.success && hasDbUrl(cwd)) {
27880
28011
  let driverReady = hasDrizzleKitPostgresDriverDependency(cwd);
27881
28012
  if (!driverReady) {
@@ -27890,8 +28021,8 @@ async function runInitCommand(name, options) {
27890
28021
  });
27891
28022
  if (!driverResult.success) {
27892
28023
  s.stop("Database push failed");
27893
- p25.log.warn(driverResult.error ?? `Failed to install ${DRIZZLE_KIT_POSTGRES_DRIVER_DEP}`);
27894
- p25.log.info(
28024
+ p26.log.warn(driverResult.error ?? `Failed to install ${DRIZZLE_KIT_POSTGRES_DRIVER_DEP}`);
28025
+ p26.log.info(
27895
28026
  `Install ${DRIZZLE_KIT_POSTGRES_DRIVER_DEP} manually, then run: ${pc10.cyan(drizzlePushCommand(pm))}`
27896
28027
  );
27897
28028
  } else {
@@ -27919,8 +28050,8 @@ async function runInitCommand(name, options) {
27919
28050
  const verification = await verifyDatabaseReachable(cwd);
27920
28051
  clearDbSpinner();
27921
28052
  if (!verification.success) {
27922
- p25.log.warn(verification.error);
27923
- p25.log.error("Database was not reachable. Aborting setup.");
28053
+ p26.log.warn(verification.error);
28054
+ p26.log.error("Database was not reachable. Aborting setup.");
27924
28055
  process.exit(1);
27925
28056
  }
27926
28057
  } else {
@@ -27933,12 +28064,12 @@ async function runInitCommand(name, options) {
27933
28064
  s.stop("Database push failed");
27934
28065
  }
27935
28066
  const pushError = pushResult.error ?? "Unknown error";
27936
- p25.log.warn(pushError);
28067
+ p26.log.warn(pushError);
27937
28068
  if (isDatabaseReachabilityError(pushError)) {
27938
- p25.log.error("Database was not reachable. Aborting setup.");
28069
+ p26.log.error("Database was not reachable. Aborting setup.");
27939
28070
  process.exit(1);
27940
28071
  }
27941
- p25.log.info(`You can run it manually: ${pc10.cyan(drizzlePushCommand(pm))}`);
28072
+ p26.log.info(`You can run it manually: ${pc10.cyan(drizzlePushCommand(pm))}`);
27942
28073
  }
27943
28074
  }
27944
28075
  }
@@ -27947,7 +28078,7 @@ async function runInitCommand(name, options) {
27947
28078
  let seedSuccess = false;
27948
28079
  let adminAccountReady = false;
27949
28080
  if (dbPushed && options.skipAdminCreation) {
27950
- p25.log.info(
28081
+ p26.log.info(
27951
28082
  `Skipping admin user creation ${pc10.dim(`(use ${betterstartExecCommand(pm, "seed")} later)`)}`
27952
28083
  );
27953
28084
  }
@@ -27959,14 +28090,14 @@ async function runInitCommand(name, options) {
27959
28090
  const adminCheck = await checkExistingAdmin(cwd, adminDir, authBasePath);
27960
28091
  s.clear();
27961
28092
  if (adminCheck.error) {
27962
- p25.log.warn(`Could not verify existing admin account ${pc10.dim(`(${adminCheck.error})`)}`);
28093
+ p26.log.warn(`Could not verify existing admin account ${pc10.dim(`(${adminCheck.error})`)}`);
27963
28094
  if (isDatabaseReachabilityError(adminCheck.error)) {
27964
- p25.log.error("Database was not reachable. Aborting setup.");
28095
+ p26.log.error("Database was not reachable. Aborting setup.");
27965
28096
  process.exit(1);
27966
28097
  }
27967
28098
  } else if (adminCheck.existingAdmin) {
27968
28099
  const existingAdminLabel = formatAdminIdentity(adminCheck.existingAdmin);
27969
- const adminAction = await p25.select({
28100
+ const adminAction = await p26.select({
27970
28101
  message: "Found an already existing admin account. Do you want to replace it or skip?",
27971
28102
  options: [
27972
28103
  {
@@ -27980,28 +28111,28 @@ async function runInitCommand(name, options) {
27980
28111
  }
27981
28112
  ]
27982
28113
  });
27983
- if (p25.isCancel(adminAction)) {
27984
- p25.cancel("Setup cancelled.");
28114
+ if (p26.isCancel(adminAction)) {
28115
+ p26.cancel("Setup cancelled.");
27985
28116
  process.exit(0);
27986
28117
  }
27987
28118
  if (adminAction === "skip") {
27988
28119
  adminAccountReady = true;
27989
- p25.log.info(`Keeping existing admin account ${pc10.dim(`(${existingAdminLabel})`)}`);
28120
+ p26.log.info(`Keeping existing admin account ${pc10.dim(`(${existingAdminLabel})`)}`);
27990
28121
  } else {
27991
28122
  replaceExistingAdmin = true;
27992
28123
  }
27993
28124
  }
27994
28125
  if (!adminAccountReady) {
27995
- const credentials = await p25.group(
28126
+ const credentials = await p26.group(
27996
28127
  {
27997
- email: () => p25.text({
28128
+ email: () => p26.text({
27998
28129
  message: "Admin email",
27999
28130
  placeholder: "admin@example.com",
28000
28131
  validate: (v) => {
28001
28132
  if (!v || !v.includes("@")) return "Please enter a valid email";
28002
28133
  }
28003
28134
  }),
28004
- password: () => p25.password({
28135
+ password: () => p26.password({
28005
28136
  message: "Admin password",
28006
28137
  validate: (v) => {
28007
28138
  if (!v || v.length < 8) return "Password must be at least 8 characters";
@@ -28010,14 +28141,14 @@ async function runInitCommand(name, options) {
28010
28141
  },
28011
28142
  {
28012
28143
  onCancel: () => {
28013
- p25.cancel("Setup cancelled.");
28144
+ p26.cancel("Setup cancelled.");
28014
28145
  process.exit(0);
28015
28146
  }
28016
28147
  }
28017
28148
  );
28018
28149
  seedEmail = credentials.email;
28019
28150
  seedPassword = credentials.password;
28020
- const credentialPromptRows = clackPromptRows("Admin email", credentials.email) + clackPromptRows("Admin password", p25.S_PASSWORD_MASK.repeat(credentials.password.length));
28151
+ const credentialPromptRows = clackPromptRows("Admin email", credentials.email) + clackPromptRows("Admin password", p26.S_PASSWORD_MASK.repeat(credentials.password.length));
28021
28152
  let rowsBelowCredentialPrompts = 0;
28022
28153
  let seedOverwriteMode = replaceExistingAdmin ? "admin" : void 0;
28023
28154
  s.start(replaceExistingAdmin ? "Replacing admin user" : "Creating admin user");
@@ -28034,7 +28165,7 @@ async function runInitCommand(name, options) {
28034
28165
  s.stop(existingAccountMessage);
28035
28166
  rowsBelowCredentialPrompts += clackLogRows(existingAccountMessage);
28036
28167
  const replaceAccountMessage = "Replace the existing account with this email?";
28037
- const replace = await p25.confirm({
28168
+ const replace = await p26.confirm({
28038
28169
  message: replaceAccountMessage,
28039
28170
  initialValue: false
28040
28171
  });
@@ -28042,7 +28173,7 @@ async function runInitCommand(name, options) {
28042
28173
  replaceAccountMessage,
28043
28174
  replace === true ? "Yes" : "No"
28044
28175
  );
28045
- if (!p25.isCancel(replace) && replace) {
28176
+ if (!p26.isCancel(replace) && replace) {
28046
28177
  seedOverwriteMode = "email";
28047
28178
  s.start("Replacing admin user");
28048
28179
  seedResult = await runSeed(
@@ -28064,14 +28195,14 @@ async function runInitCommand(name, options) {
28064
28195
  adminAccountReady = true;
28065
28196
  } else if (seedResult.error) {
28066
28197
  s.stop(`Failed to create admin user`);
28067
- p25.note(
28198
+ p26.note(
28068
28199
  `${pc10.red(seedResult.error)}
28069
28200
 
28070
28201
  Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28071
28202
  pc10.red("Seed failed")
28072
28203
  );
28073
28204
  if (isDatabaseReachabilityError(seedResult.error)) {
28074
- p25.log.error("Database was not reachable. Aborting setup.");
28205
+ p26.log.error("Database was not reachable. Aborting setup.");
28075
28206
  process.exit(1);
28076
28207
  }
28077
28208
  }
@@ -28080,9 +28211,9 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28080
28211
  if (isFreshProject) {
28081
28212
  s.start("Creating initial git commit");
28082
28213
  try {
28083
- execFileSync5("git", ["init"], { cwd, stdio: "pipe" });
28084
- execFileSync5("git", ["add", "."], { cwd, stdio: "pipe" });
28085
- 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"], {
28086
28217
  cwd,
28087
28218
  stdio: "pipe"
28088
28219
  });
@@ -28113,10 +28244,10 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28113
28244
  deployedUrl = deployFlow.url;
28114
28245
  if (!deployFlow.ok) {
28115
28246
  if (options.yes) {
28116
- p25.log.error("Vercel deploy did not complete.");
28247
+ p26.log.error("Vercel deploy did not complete.");
28117
28248
  process.exit(1);
28118
28249
  }
28119
- p25.log.warn("Vercel deploy did not complete; continuing.");
28250
+ p26.log.warn("Vercel deploy did not complete; continuing.");
28120
28251
  }
28121
28252
  } else if (deployProvider === "railway") {
28122
28253
  try {
@@ -28134,29 +28265,29 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28134
28265
  });
28135
28266
  deployedUrl = deployFlow.url;
28136
28267
  if (!deployFlow.ok) {
28137
- if (deployFlow.detail) p25.log.message(pc10.dim(redactSecrets(deployFlow.detail)));
28268
+ if (deployFlow.detail) p26.log.message(pc10.dim(redactSecrets(deployFlow.detail)));
28138
28269
  if (options.yes) {
28139
- p25.log.error("Railway deploy did not complete.");
28270
+ p26.log.error("Railway deploy did not complete.");
28140
28271
  process.exit(1);
28141
28272
  }
28142
- p25.log.warn("Railway deploy did not complete; continuing.");
28273
+ p26.log.warn("Railway deploy did not complete; continuing.");
28143
28274
  }
28144
28275
  } catch (error) {
28145
28276
  const message = error instanceof Error ? error.message : String(error);
28146
28277
  if (options.yes) {
28147
- p25.log.error(`Railway deploy failed: ${message}`);
28278
+ p26.log.error(`Railway deploy failed: ${message}`);
28148
28279
  process.exit(1);
28149
28280
  }
28150
- p25.log.warn(`Railway deploy failed: ${message}`);
28281
+ p26.log.warn(`Railway deploy failed: ${message}`);
28151
28282
  }
28152
28283
  }
28153
28284
  if (!options.yes && !options.skipDevServerStart) {
28154
28285
  const devCmd = runCommand(pm, "dev");
28155
- const startDev = await p25.confirm({
28286
+ const startDev = await p26.confirm({
28156
28287
  message: "Start the development server?",
28157
28288
  initialValue: true
28158
28289
  });
28159
- if (!p25.isCancel(startDev) && startDev) {
28290
+ if (!p26.isCancel(startDev) && startDev) {
28160
28291
  disposeCancelGuard();
28161
28292
  await startManagedDevServer(cwd, devCmd, adminLoginUrl, {
28162
28293
  email: seedSuccess && seedEmail ? seedEmail : void 0,
@@ -28188,7 +28319,7 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28188
28319
  );
28189
28320
  return;
28190
28321
  }
28191
- p25.outro(`Admin ready at ${adminNamespace.routePath}`);
28322
+ p26.outro(`Admin ready at ${adminNamespace.routePath}`);
28192
28323
  }
28193
28324
  function isValidDbUrl(url) {
28194
28325
  return url.startsWith("postgres://") || url.startsWith("postgresql://");
@@ -28581,7 +28712,7 @@ function printAdminReadyNote(state) {
28581
28712
  } else if (state.adminEmail) {
28582
28713
  lines.unshift(`Admin user: ${pc10.cyan(state.adminEmail)}`);
28583
28714
  }
28584
- p25.note(lines.join("\n"), "Admin ready");
28715
+ p26.note(lines.join("\n"), "Admin ready");
28585
28716
  }
28586
28717
  function shouldSuppressDevServerStartupLine(line) {
28587
28718
  const plain = stripAnsi2(line).trim();
@@ -28693,7 +28824,7 @@ function startManagedDevServer(cwd, devCmd, adminLoginUrl, adminCredentials) {
28693
28824
 
28694
28825
  // adapters/next/commands/list-integrations.ts
28695
28826
  import path53 from "path";
28696
- import * as p26 from "@clack/prompts";
28827
+ import * as p27 from "@clack/prompts";
28697
28828
 
28698
28829
  // core-engine/utils/table.ts
28699
28830
  function renderTableRows(rows) {
@@ -28740,15 +28871,15 @@ async function runListIntegrationsCommand(options) {
28740
28871
  integration.kind,
28741
28872
  integration.description
28742
28873
  ]);
28743
- p26.note(renderTableRows(rows).join("\n"), "BetterStart integrations");
28744
- p26.outro(
28874
+ p27.note(renderTableRows(rows).join("\n"), "BetterStart integrations");
28875
+ p27.outro(
28745
28876
  `${installedIntegrations.size} installed, ${rows.length - installedIntegrations.size} available`
28746
28877
  );
28747
28878
  }
28748
28879
 
28749
28880
  // adapters/next/commands/list-presets.ts
28750
28881
  import path54 from "path";
28751
- import * as p27 from "@clack/prompts";
28882
+ import * as p28 from "@clack/prompts";
28752
28883
  async function runListPresetsCommand(options) {
28753
28884
  const cwd = options.cwd ? path54.resolve(options.cwd) : process.cwd();
28754
28885
  if (options.json) {
@@ -28778,48 +28909,73 @@ async function runListPresetsCommand(options) {
28778
28909
  preset.kind,
28779
28910
  preset.description
28780
28911
  ]);
28781
- p27.note(renderTableRows(rows).join("\n"), "BetterStart presets");
28782
- p27.outro(`${installedPresets.size} installed, ${rows.length - installedPresets.size} available`);
28912
+ p28.note(renderTableRows(rows).join("\n"), "BetterStart presets");
28913
+ p28.outro(`${installedPresets.size} installed, ${rows.length - installedPresets.size} available`);
28783
28914
  }
28784
28915
 
28785
- // adapters/next/commands/remove.ts
28916
+ // adapters/next/commands/menu-choices.ts
28786
28917
  import path55 from "path";
28787
- import * as p28 from "@clack/prompts";
28918
+ async function listInstallableChoices(cwd) {
28919
+ const config = await resolveConfigOrExit(cwd);
28920
+ const installedPresets = new Set(config.presets.installed);
28921
+ const installedIntegrations = new Set(config.integrations.installed);
28922
+ return {
28923
+ presets: listAvailablePresets().map((preset) => ({
28924
+ id: preset.id,
28925
+ description: preset.description,
28926
+ installed: installedPresets.has(preset.id)
28927
+ })),
28928
+ integrations: listAvailableIntegrations().map((integration) => ({
28929
+ id: integration.id,
28930
+ description: integration.description,
28931
+ installed: installedIntegrations.has(integration.id)
28932
+ }))
28933
+ };
28934
+ }
28935
+ async function listSchemaChoices(cwd) {
28936
+ const config = await resolveConfigOrExit(cwd);
28937
+ const paths = resolveProjectPaths(config);
28938
+ return listSchemaNames(path55.join(cwd, ...paths.schemasDir.split("/")));
28939
+ }
28940
+
28941
+ // adapters/next/commands/remove.ts
28942
+ import path56 from "path";
28943
+ import * as p29 from "@clack/prompts";
28788
28944
  async function runRemoveCommand(items, options) {
28789
28945
  const removeIntegrationsMode = Boolean(options.integration);
28790
28946
  if (!removeIntegrationsMode && items.includes("core")) {
28791
- p28.log.error("The core Admin cannot be removed.");
28947
+ p29.log.error("The core Admin cannot be removed.");
28792
28948
  process.exit(1);
28793
28949
  }
28794
28950
  const presetIds = items.filter(isPresetId);
28795
28951
  const integrationIds = items.filter(isIntegrationId);
28796
28952
  if (!removeIntegrationsMode && integrationIds.length > 0) {
28797
- p28.log.error(
28953
+ p29.log.error(
28798
28954
  `Integration IDs require --integration. Run \`betterstart remove --integration ${integrationIds.join(" ")}\`.`
28799
28955
  );
28800
28956
  process.exit(1);
28801
28957
  }
28802
28958
  if (removeIntegrationsMode && presetIds.length > 0) {
28803
- p28.log.error(`Preset IDs cannot be removed with --integration: ${presetIds.join(", ")}`);
28959
+ p29.log.error(`Preset IDs cannot be removed with --integration: ${presetIds.join(", ")}`);
28804
28960
  process.exit(1);
28805
28961
  }
28806
28962
  const invalidItems = removeIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
28807
28963
  if (invalidItems.length > 0) {
28808
- p28.log.error(
28964
+ p29.log.error(
28809
28965
  removeIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
28810
28966
  );
28811
28967
  process.exit(1);
28812
28968
  }
28813
- const cwd = options.cwd ? path55.resolve(options.cwd) : process.cwd();
28969
+ const cwd = options.cwd ? path56.resolve(options.cwd) : process.cwd();
28814
28970
  const config = await resolveConfigOrExit(cwd);
28815
28971
  const pm = detectPackageManager(cwd);
28816
28972
  if (!options.force) {
28817
- const confirmed = await p28.confirm({
28973
+ const confirmed = await p29.confirm({
28818
28974
  message: `Remove ${removeIntegrationsMode ? "integration" : "preset"}${items.length === 1 ? "" : "s"} ${items.join(", ")}?`,
28819
28975
  initialValue: false
28820
28976
  });
28821
- if (p28.isCancel(confirmed) || !confirmed) {
28822
- p28.cancel(`${removeIntegrationsMode ? "Integration" : "Preset"} removal cancelled.`);
28977
+ if (p29.isCancel(confirmed) || !confirmed) {
28978
+ p29.cancel(`${removeIntegrationsMode ? "Integration" : "Preset"} removal cancelled.`);
28823
28979
  process.exit(0);
28824
28980
  }
28825
28981
  }
@@ -28832,13 +28988,13 @@ async function runRemoveCommand(items, options) {
28832
28988
  });
28833
28989
  writeConfigFile(cwd, result2.config);
28834
28990
  if (result2.removed.length === 0) {
28835
- p28.outro("No integrations were removed.");
28991
+ p29.outro("No integrations were removed.");
28836
28992
  return;
28837
28993
  }
28838
28994
  if (result2.warnings.length > 0) {
28839
- p28.note(result2.warnings.join("\n"), "Warnings");
28995
+ p29.note(result2.warnings.join("\n"), "Warnings");
28840
28996
  }
28841
- p28.outro(
28997
+ p29.outro(
28842
28998
  `Removed integration${result2.removed.length === 1 ? "" : "s"}: ${result2.removed.join(", ")}`
28843
28999
  );
28844
29000
  return;
@@ -28851,37 +29007,37 @@ async function runRemoveCommand(items, options) {
28851
29007
  });
28852
29008
  writeConfigFile(cwd, result.config);
28853
29009
  if (result.removed.length === 0) {
28854
- p28.outro("No presets were removed.");
29010
+ p29.outro("No presets were removed.");
28855
29011
  return;
28856
29012
  }
28857
29013
  if (result.warnings.length > 0) {
28858
- p28.note(result.warnings.join("\n"), "Warnings");
29014
+ p29.note(result.warnings.join("\n"), "Warnings");
28859
29015
  }
28860
- p28.outro(`Removed preset${result.removed.length === 1 ? "" : "s"}: ${result.removed.join(", ")}`);
29016
+ p29.outro(`Removed preset${result.removed.length === 1 ? "" : "s"}: ${result.removed.join(", ")}`);
28861
29017
  }
28862
29018
 
28863
29019
  // adapters/next/commands/remove-schema.ts
28864
29020
  import fs42 from "fs";
28865
- import path56 from "path";
29021
+ import path57 from "path";
28866
29022
  import * as clack3 from "@clack/prompts";
28867
29023
  function removePath2(cwd, filePath) {
28868
- const fullPath = path56.join(cwd, ...filePath.split("/"));
29024
+ const fullPath = path57.join(cwd, ...filePath.split("/"));
28869
29025
  const existed = fs42.existsSync(fullPath);
28870
29026
  fs42.rmSync(fullPath, { recursive: true, force: true });
28871
29027
  return existed;
28872
29028
  }
28873
29029
  function cleanupEmptyDirs3(cwd, deletedPaths, configPaths) {
28874
29030
  const stopRoots = /* @__PURE__ */ new Set([
28875
- path56.join(cwd, ...configPaths.adminDir.split("/")),
28876
- path56.join(cwd, ...configPaths.adminNavigationDir.split("/")),
28877
- path56.join(cwd, ...configPaths.adminWebhookEventsDir.split("/")),
28878
- path56.join(cwd, ...configPaths.pagesDir.split("/"))
29031
+ path57.join(cwd, ...configPaths.adminDir.split("/")),
29032
+ path57.join(cwd, ...configPaths.adminNavigationDir.split("/")),
29033
+ path57.join(cwd, ...configPaths.adminWebhookEventsDir.split("/")),
29034
+ path57.join(cwd, ...configPaths.pagesDir.split("/"))
28879
29035
  ]);
28880
29036
  for (const deletedPath of deletedPaths) {
28881
- let current = path56.dirname(path56.join(cwd, ...deletedPath.split("/")));
29037
+ let current = path57.dirname(path57.join(cwd, ...deletedPath.split("/")));
28882
29038
  while (!stopRoots.has(current)) {
28883
29039
  if (!fs42.existsSync(current)) {
28884
- current = path56.dirname(current);
29040
+ current = path57.dirname(current);
28885
29041
  continue;
28886
29042
  }
28887
29043
  const entries = fs42.readdirSync(current);
@@ -28889,7 +29045,7 @@ function cleanupEmptyDirs3(cwd, deletedPaths, configPaths) {
28889
29045
  break;
28890
29046
  }
28891
29047
  fs42.rmdirSync(current);
28892
- current = path56.dirname(current);
29048
+ current = path57.dirname(current);
28893
29049
  }
28894
29050
  }
28895
29051
  }
@@ -28905,7 +29061,7 @@ function resolveSchemaOwnerForRemoval(cwd, schemaName) {
28905
29061
  }
28906
29062
  async function runRemoveSchemaCommand(schemaName, options) {
28907
29063
  const owner = resolveSchemaOwnerForRemoval(
28908
- options.cwd ? path56.resolve(options.cwd) : process.cwd(),
29064
+ options.cwd ? path57.resolve(options.cwd) : process.cwd(),
28909
29065
  schemaName
28910
29066
  );
28911
29067
  if (owner === "core") {
@@ -28918,7 +29074,7 @@ async function runRemoveSchemaCommand(schemaName, options) {
28918
29074
  clack3.log.error(`"${schemaName}" is owned by ${owner}. Remove the owning preset instead.`);
28919
29075
  process.exit(1);
28920
29076
  }
28921
- const cwd = options.cwd ? path56.resolve(options.cwd) : process.cwd();
29077
+ const cwd = options.cwd ? path57.resolve(options.cwd) : process.cwd();
28922
29078
  const config = await resolveConfigOrExit(cwd);
28923
29079
  const paths = resolveProjectPaths(config);
28924
29080
  const manifest = loadManifest(cwd, schemaName);
@@ -28931,7 +29087,7 @@ async function runRemoveSchemaCommand(schemaName, options) {
28931
29087
  process.exit(1);
28932
29088
  }
28933
29089
  if (!options.force) {
28934
- if (!isInteractiveSession4()) {
29090
+ if (!isInteractiveSession()) {
28935
29091
  clack3.log.error(
28936
29092
  `Removing generated files for ${schemaName} needs confirmation. Re-run with --force.`
28937
29093
  );
@@ -28954,7 +29110,7 @@ async function runRemoveSchemaCommand(schemaName, options) {
28954
29110
  }
28955
29111
  const loaded = (() => {
28956
29112
  try {
28957
- return loadSchema(path56.join(cwd, ...paths.schemasDir.split("/")), schemaName);
29113
+ return loadSchema(path57.join(cwd, ...paths.schemasDir.split("/")), schemaName);
28958
29114
  } catch {
28959
29115
  return null;
28960
29116
  }
@@ -28999,8 +29155,8 @@ Schema JSON preserved.`
28999
29155
 
29000
29156
  // adapters/next/commands/uninstall.ts
29001
29157
  import fs44 from "fs";
29002
- import path57 from "path";
29003
- import * as p29 from "@clack/prompts";
29158
+ import path58 from "path";
29159
+ import * as p30 from "@clack/prompts";
29004
29160
  import pc11 from "picocolors";
29005
29161
 
29006
29162
  // adapters/next/commands/uninstall-cleaners.ts
@@ -29149,7 +29305,7 @@ function findMainCss2(cwd) {
29149
29305
  "globals.css"
29150
29306
  ];
29151
29307
  for (const candidate of candidates) {
29152
- const filePath = path57.join(cwd, candidate);
29308
+ const filePath = path58.join(cwd, candidate);
29153
29309
  if (fs44.existsSync(filePath)) return filePath;
29154
29310
  }
29155
29311
  return void 0;
@@ -29166,13 +29322,13 @@ function isCLICreatedBiome(biomePath) {
29166
29322
  function buildUninstallPlan(cwd, namespaceValue) {
29167
29323
  const steps = [];
29168
29324
  const namespace = resolveAdminNamespace(namespaceValue);
29169
- const hasSrc = fs44.existsSync(path57.join(cwd, "src"));
29325
+ const hasSrc = fs44.existsSync(path58.join(cwd, "src"));
29170
29326
  const appBase = hasSrc ? "src/app" : "app";
29171
29327
  const dirs = [];
29172
- const adminDir = path57.join(cwd, namespace.segment);
29173
- const legacyAdminDir = path57.join(cwd, "admin");
29174
- const adminRouteGroup = path57.join(cwd, appBase, namespace.routeGroup);
29175
- const legacyAdminRouteGroup = path57.join(cwd, appBase, "(admin)");
29328
+ const adminDir = path58.join(cwd, namespace.segment);
29329
+ const legacyAdminDir = path58.join(cwd, "admin");
29330
+ const adminRouteGroup = path58.join(cwd, appBase, namespace.routeGroup);
29331
+ const legacyAdminRouteGroup = path58.join(cwd, appBase, "(admin)");
29176
29332
  if (fs44.existsSync(adminDir)) dirs.push(`${namespace.segment}/`);
29177
29333
  if (namespace.segment !== "admin" && fs44.existsSync(legacyAdminDir)) dirs.push("admin/");
29178
29334
  if (fs44.existsSync(adminRouteGroup)) dirs.push(`${appBase}/${namespace.routeGroup}/`);
@@ -29200,9 +29356,9 @@ function buildUninstallPlan(cwd, namespaceValue) {
29200
29356
  const configFiles = [];
29201
29357
  const configPaths = [];
29202
29358
  const candidates = [
29203
- [CONFIG_FILE_NAME, path57.join(cwd, CONFIG_FILE_NAME)],
29204
- ["drizzle.config.ts", path57.join(cwd, "drizzle.config.ts")],
29205
- ["ADMIN.md", path57.join(cwd, "ADMIN.md")]
29359
+ [CONFIG_FILE_NAME, path58.join(cwd, CONFIG_FILE_NAME)],
29360
+ ["drizzle.config.ts", path58.join(cwd, "drizzle.config.ts")],
29361
+ ["ADMIN.md", path58.join(cwd, "ADMIN.md")]
29206
29362
  ];
29207
29363
  for (const [label, fullPath] of candidates) {
29208
29364
  if (fs44.existsSync(fullPath)) {
@@ -29210,7 +29366,7 @@ function buildUninstallPlan(cwd, namespaceValue) {
29210
29366
  configPaths.push(fullPath);
29211
29367
  }
29212
29368
  }
29213
- const biomePath = path57.join(cwd, "biome.json");
29369
+ const biomePath = path58.join(cwd, "biome.json");
29214
29370
  if (isCLICreatedBiome(biomePath)) {
29215
29371
  configFiles.push("biome.json (CLI-created)");
29216
29372
  configPaths.push(biomePath);
@@ -29222,13 +29378,13 @@ function buildUninstallPlan(cwd, namespaceValue) {
29222
29378
  count: configFiles.length,
29223
29379
  unit: configFiles.length === 1 ? "file" : "files",
29224
29380
  execute() {
29225
- for (const p31 of configPaths) {
29226
- if (fs44.existsSync(p31)) fs44.unlinkSync(p31);
29381
+ for (const p32 of configPaths) {
29382
+ if (fs44.existsSync(p32)) fs44.unlinkSync(p32);
29227
29383
  }
29228
29384
  }
29229
29385
  });
29230
29386
  }
29231
- const tsconfigPath = path57.join(cwd, "tsconfig.json");
29387
+ const tsconfigPath = path58.join(cwd, "tsconfig.json");
29232
29388
  if (fs44.existsSync(tsconfigPath)) {
29233
29389
  const content = fs44.readFileSync(tsconfigPath, "utf-8");
29234
29390
  const aliasMatches = [
@@ -29255,7 +29411,7 @@ function buildUninstallPlan(cwd, namespaceValue) {
29255
29411
  (l) => new RegExp(`^@source\\s+"[^"]*(?:admin|${namespace.segment})[^"]*";\\s*$`).test(l)
29256
29412
  );
29257
29413
  if (sourceLines.length > 0) {
29258
- const relCss = path57.relative(cwd, cssFile);
29414
+ const relCss = path58.relative(cwd, cssFile);
29259
29415
  steps.push({
29260
29416
  label: `CSS @source lines (${relCss})`,
29261
29417
  items: [`@source lines in ${relCss}`],
@@ -29267,7 +29423,7 @@ function buildUninstallPlan(cwd, namespaceValue) {
29267
29423
  });
29268
29424
  }
29269
29425
  }
29270
- const envPath = path57.join(cwd, ".env.local");
29426
+ const envPath = path58.join(cwd, ".env.local");
29271
29427
  if (fs44.existsSync(envPath)) {
29272
29428
  const envContent = fs44.readFileSync(envPath, "utf-8");
29273
29429
  const bsVars = envContent.split("\n").filter((l) => l.trim().match(/^BETTERSTART_\w+=/)).map((l) => l.split("=")[0]);
@@ -29286,8 +29442,8 @@ function buildUninstallPlan(cwd, namespaceValue) {
29286
29442
  return steps;
29287
29443
  }
29288
29444
  async function runUninstallCommand(options) {
29289
- const cwd = options.cwd ? path57.resolve(options.cwd) : process.cwd();
29290
- p29.intro(pc11.bgRed(pc11.white(" BetterStart Uninstall ")));
29445
+ const cwd = options.cwd ? path58.resolve(options.cwd) : process.cwd();
29446
+ p30.intro(pc11.bgRed(pc11.white(" BetterStart Uninstall ")));
29291
29447
  let namespace = DEFAULT_ADMIN_NAMESPACE;
29292
29448
  try {
29293
29449
  const config = await resolveConfig(cwd);
@@ -29296,8 +29452,8 @@ async function runUninstallCommand(options) {
29296
29452
  }
29297
29453
  const steps = buildUninstallPlan(cwd, namespace);
29298
29454
  if (steps.length === 0) {
29299
- p29.log.success(`${pc11.green("\u2713")} Nothing to remove \u2014 project is already clean.`);
29300
- p29.outro("Project already clean");
29455
+ p30.log.success(`${pc11.green("\u2713")} Nothing to remove \u2014 project is already clean.`);
29456
+ p30.outro("Project already clean");
29301
29457
  return;
29302
29458
  }
29303
29459
  const planLines = steps.map((step) => {
@@ -29305,14 +29461,14 @@ async function runUninstallCommand(options) {
29305
29461
  const countLabel = pc11.dim(`${step.count} ${step.unit}`);
29306
29462
  return `${pc11.red("\u2717")} ${names} ${countLabel}`;
29307
29463
  });
29308
- p29.note(planLines.join("\n"), "Uninstall plan");
29464
+ p30.note(planLines.join("\n"), "Uninstall plan");
29309
29465
  if (!options.force) {
29310
- const confirmed = await p29.confirm({
29466
+ const confirmed = await p30.confirm({
29311
29467
  message: "Proceed with uninstall?",
29312
29468
  initialValue: false
29313
29469
  });
29314
- if (p29.isCancel(confirmed) || !confirmed) {
29315
- p29.cancel("Uninstall cancelled.");
29470
+ if (p30.isCancel(confirmed) || !confirmed) {
29471
+ p30.cancel("Uninstall cancelled.");
29316
29472
  process.exit(0);
29317
29473
  }
29318
29474
  }
@@ -29324,14 +29480,14 @@ async function runUninstallCommand(options) {
29324
29480
  }
29325
29481
  const parts = steps.map((step) => `${step.count} ${step.unit}`);
29326
29482
  s.stop(`Removed ${parts.join(", ")}`);
29327
- p29.note(pc11.dim("Database tables were NOT dropped \u2014 drop them manually if needed."), "Next steps");
29328
- p29.outro("Uninstall complete");
29483
+ p30.note(pc11.dim("Database tables were NOT dropped \u2014 drop them manually if needed."), "Next steps");
29484
+ p30.outro("Uninstall complete");
29329
29485
  }
29330
29486
 
29331
29487
  // adapters/next/commands/update-component.ts
29332
- import { execFileSync as execFileSync6 } from "child_process";
29488
+ import { execFileSync as execFileSync5 } from "child_process";
29333
29489
  import fs45 from "fs";
29334
- import path58 from "path";
29490
+ import path59 from "path";
29335
29491
  import * as clack4 from "@clack/prompts";
29336
29492
  import fsExtra from "fs-extra";
29337
29493
  var STATIC_CUSTOM_DEPENDENCIES = {
@@ -29592,14 +29748,14 @@ function copyNamespacedDirectory(srcDir, destDir, namespace) {
29592
29748
  const entries = fs45.readdirSync(srcDir, { withFileTypes: true });
29593
29749
  for (const entry of entries) {
29594
29750
  const namespacedName = applyAdminNamespaceToPath(entry.name, namespace);
29595
- const srcPath = path58.join(srcDir, entry.name);
29596
- const destPath = path58.join(destDir, namespacedName);
29751
+ const srcPath = path59.join(srcDir, entry.name);
29752
+ const destPath = path59.join(destDir, namespacedName);
29597
29753
  if (entry.isDirectory()) {
29598
29754
  fsExtra.ensureDirSync(destPath);
29599
29755
  copyNamespacedDirectory(srcPath, destPath, namespace);
29600
29756
  continue;
29601
29757
  }
29602
- fsExtra.ensureDirSync(path58.dirname(destPath));
29758
+ fsExtra.ensureDirSync(path59.dirname(destPath));
29603
29759
  writeNamespacedFile(srcPath, destPath, namespace);
29604
29760
  }
29605
29761
  }
@@ -29610,7 +29766,7 @@ function hasIntegration(config, integrationId) {
29610
29766
  return config.integrations.installed.includes(integrationId);
29611
29767
  }
29612
29768
  function readProjectPackageJson2(cwd) {
29613
- const pkgPath = path58.join(cwd, "package.json");
29769
+ const pkgPath = path59.join(cwd, "package.json");
29614
29770
  if (!fs45.existsSync(pkgPath)) return null;
29615
29771
  try {
29616
29772
  return JSON.parse(fs45.readFileSync(pkgPath, "utf-8"));
@@ -31146,12 +31302,12 @@ function getStaticAssetComponentEntries(assetDirectory) {
31146
31302
  continue;
31147
31303
  }
31148
31304
  const indexFile = ["index.tsx", "index.ts"].find(
31149
- (file) => fs45.existsSync(path58.join(assetDir, entry.name, file))
31305
+ (file) => fs45.existsSync(path59.join(assetDir, entry.name, file))
31150
31306
  );
31151
31307
  if (indexFile) {
31152
31308
  components.push({
31153
31309
  name: entry.name,
31154
- file: path58.join(entry.name, indexFile)
31310
+ file: path59.join(entry.name, indexFile)
31155
31311
  });
31156
31312
  }
31157
31313
  }
@@ -31160,20 +31316,20 @@ function getStaticAssetComponentEntries(assetDirectory) {
31160
31316
  function findStaticAssetFile(assetDir, componentName) {
31161
31317
  if (!fs45.existsSync(assetDir)) return void 0;
31162
31318
  const isNestedComponentName = /[\\/]/.test(componentName);
31163
- const nestedComponentName = componentName.split(/[\\/]/).filter(Boolean).join(path58.sep);
31164
- if (isNestedComponentName && nestedComponentName && !path58.isAbsolute(componentName) && !nestedComponentName.split(path58.sep).includes("..")) {
31319
+ const nestedComponentName = componentName.split(/[\\/]/).filter(Boolean).join(path59.sep);
31320
+ if (isNestedComponentName && nestedComponentName && !path59.isAbsolute(componentName) && !nestedComponentName.split(path59.sep).includes("..")) {
31165
31321
  for (const extension of [".tsx", ".ts"]) {
31166
31322
  const relPath = `${nestedComponentName}${extension}`;
31167
- const filePath = path58.join(assetDir, relPath);
31323
+ const filePath = path59.join(assetDir, relPath);
31168
31324
  if (fs45.existsSync(filePath) && fs45.statSync(filePath).isFile()) {
31169
31325
  return relPath;
31170
31326
  }
31171
31327
  }
31172
31328
  }
31173
- if (!isNestedComponentName && !componentName.includes("..") && !path58.isAbsolute(componentName)) {
31329
+ if (!isNestedComponentName && !componentName.includes("..") && !path59.isAbsolute(componentName)) {
31174
31330
  for (const extension of [".tsx", ".ts"]) {
31175
- const relPath = path58.join(componentName, `index${extension}`);
31176
- const filePath = path58.join(assetDir, relPath);
31331
+ const relPath = path59.join(componentName, `index${extension}`);
31332
+ const filePath = path59.join(assetDir, relPath);
31177
31333
  if (fs45.existsSync(filePath) && fs45.statSync(filePath).isFile()) {
31178
31334
  return relPath;
31179
31335
  }
@@ -31198,7 +31354,7 @@ function getAllComponentNamesForConfig(config) {
31198
31354
  return [.../* @__PURE__ */ new Set([...staticUi, ...staticCustom, ...templateKeys, "tiptap"])].sort();
31199
31355
  }
31200
31356
  async function runUpdateCommand(components, options) {
31201
- const cwd = options.cwd ? path58.resolve(options.cwd) : process.cwd();
31357
+ const cwd = options.cwd ? path59.resolve(options.cwd) : process.cwd();
31202
31358
  const normalizedOnly = normalizeShadcnPresetOnly(options.only);
31203
31359
  validateShadcnPresetOptions(components, options);
31204
31360
  if (options.json && !options.list) {
@@ -31259,7 +31415,7 @@ async function runUpdateCommand(components, options) {
31259
31415
  return;
31260
31416
  }
31261
31417
  const config = await resolveConfigOrExit(cwd);
31262
- const admin = path58.resolve(cwd, config.paths.admin);
31418
+ const admin = path59.resolve(cwd, config.paths.admin);
31263
31419
  if (!fs45.existsSync(admin)) {
31264
31420
  clack4.cancel(
31265
31421
  `Admin directory not found at ${config.paths.admin}. Run 'betterstart init' first.`
@@ -31314,7 +31470,7 @@ async function runUpdateCommand(components, options) {
31314
31470
  }
31315
31471
  const { relPath, content } = applyNamespaceToTemplateEntry(entry, config, cwd);
31316
31472
  const baseDir = entry.base === "cwd" ? cwd : admin;
31317
- const destPath = path58.join(baseDir, relPath);
31473
+ const destPath = path59.join(baseDir, relPath);
31318
31474
  if (entry.preserveExisting && fs45.existsSync(destPath)) {
31319
31475
  clack4.log.info(`Preserved ${relPath}`);
31320
31476
  updatedTemplateNames.add(name);
@@ -31324,7 +31480,7 @@ async function runUpdateCommand(components, options) {
31324
31480
  pendingWrites.push({
31325
31481
  displayPath: relPath,
31326
31482
  write: () => {
31327
- fsExtra.ensureDirSync(path58.dirname(destPath));
31483
+ fsExtra.ensureDirSync(path59.dirname(destPath));
31328
31484
  fs45.writeFileSync(destPath, content, "utf-8");
31329
31485
  clack4.log.success(`Updated ${relPath}`);
31330
31486
  }
@@ -31356,20 +31512,20 @@ async function runUpdateCommand(components, options) {
31356
31512
  }
31357
31513
  const namespace = config.frameworkConfig.next.namespace;
31358
31514
  const namespacedAssetFile = applyAdminNamespaceToPath(assetFile, namespace);
31359
- const destPath = path58.join(admin, "components", assetDirectory, namespacedAssetFile);
31515
+ const destPath = path59.join(admin, "components", assetDirectory, namespacedAssetFile);
31360
31516
  pendingWrites.push({
31361
31517
  displayPath: `components/${assetDirectory}/${namespacedAssetFile}`,
31362
31518
  write: () => {
31363
- fsExtra.ensureDirSync(path58.dirname(destPath));
31364
- writeNamespacedFile(path58.join(assetDir, assetFile), destPath, namespace);
31519
+ fsExtra.ensureDirSync(path59.dirname(destPath));
31520
+ writeNamespacedFile(path59.join(assetDir, assetFile), destPath, namespace);
31365
31521
  clack4.log.success(`Updated components/${assetDirectory}/${namespacedAssetFile}`);
31366
31522
  }
31367
31523
  });
31368
31524
  if (assetDirectory === "custom") {
31369
- const assetSubdir = path58.join(assetDir, name);
31525
+ const assetSubdir = path59.join(assetDir, name);
31370
31526
  if (fs45.existsSync(assetSubdir) && fs45.statSync(assetSubdir).isDirectory()) {
31371
31527
  const namespacedName = applyAdminNamespaceToPath(name, namespace);
31372
- const destSubdir = path58.join(admin, "components", assetDirectory, namespacedName);
31528
+ const destSubdir = path59.join(admin, "components", assetDirectory, namespacedName);
31373
31529
  pendingWrites.push({
31374
31530
  displayPath: `components/${assetDirectory}/${namespacedName}/ (template files)`,
31375
31531
  write: () => {
@@ -31404,19 +31560,19 @@ async function runUpdateCommand(components, options) {
31404
31560
  "content-editor"
31405
31561
  );
31406
31562
  const namespace = config.frameworkConfig.next.namespace;
31407
- const destBaseDir = path58.join(admin, "components", "custom", "content-editor");
31563
+ const destBaseDir = path59.join(admin, "components", "custom", "content-editor");
31408
31564
  if (!fs45.existsSync(srcBaseDir)) {
31409
31565
  return false;
31410
31566
  }
31411
31567
  const dirsToCopy = [];
31412
31568
  for (const directory of TIPTAP_CONTENT_EDITOR_DIRECTORIES) {
31413
- const srcDir = path58.join(srcBaseDir, directory);
31569
+ const srcDir = path59.join(srcBaseDir, directory);
31414
31570
  if (!fs45.existsSync(srcDir)) {
31415
31571
  continue;
31416
31572
  }
31417
31573
  dirsToCopy.push({
31418
31574
  srcDir,
31419
- destDir: path58.join(destBaseDir, applyAdminNamespaceToPath(directory, namespace))
31575
+ destDir: path59.join(destBaseDir, applyAdminNamespaceToPath(directory, namespace))
31420
31576
  });
31421
31577
  }
31422
31578
  if (dirsToCopy.length === 0) {
@@ -31430,7 +31586,7 @@ async function runUpdateCommand(components, options) {
31430
31586
  copyNamespacedDirectory(srcDir, destDir, namespace);
31431
31587
  }
31432
31588
  clack4.log.success("Updated components/custom/content-editor/tiptap-*/ (template files)");
31433
- removeLegacyDirectory(path58.join(admin, "components", "custom", "tiptap"));
31589
+ removeLegacyDirectory(path59.join(admin, "components", "custom", "tiptap"));
31434
31590
  }
31435
31591
  });
31436
31592
  updatedStaticNames.add(key);
@@ -31490,7 +31646,7 @@ async function runUpdateCommand(components, options) {
31490
31646
  `Overwriting ${displayPaths.length} file${displayPaths.length === 1 ? "" : "s"}`
31491
31647
  );
31492
31648
  if (!options.yes) {
31493
- if (!isInteractiveSession4()) {
31649
+ if (!isInteractiveSession()) {
31494
31650
  clack4.log.error(
31495
31651
  `Overwriting ${displayPaths.length} file${displayPaths.length === 1 ? "" : "s"} needs confirmation. Re-run with --yes.`
31496
31652
  );
@@ -31570,13 +31726,13 @@ function runShadcnPresetUpdate({
31570
31726
  only
31571
31727
  }) {
31572
31728
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
31573
- const adminGlobalsPath = path58.join(cwd, config.paths.admin, namespace.globalsFile);
31574
- const componentsJsonPath = path58.join(cwd, "components.json");
31729
+ const adminGlobalsPath = path59.join(cwd, config.paths.admin, namespace.globalsFile);
31730
+ const componentsJsonPath = path59.join(cwd, "components.json");
31575
31731
  const shadcnBackupPath = `${componentsJsonPath}.bak`;
31576
31732
  const restoreAfterApplyPaths = [
31577
31733
  componentsJsonPath,
31578
31734
  shadcnBackupPath,
31579
- path58.join(cwd, config.paths.admin, "lib", "utils.ts"),
31735
+ path59.join(cwd, config.paths.admin, "lib", "utils.ts"),
31580
31736
  ...getHostProjectFilesToRestore(cwd)
31581
31737
  ];
31582
31738
  if (!preset) {
@@ -31585,7 +31741,7 @@ function runShadcnPresetUpdate({
31585
31741
  }
31586
31742
  if (!fs45.existsSync(adminGlobalsPath)) {
31587
31743
  clack4.cancel(
31588
- `Admin globals file not found at ${path58.relative(cwd, adminGlobalsPath)}. Run 'betterstart update admin-globals' first.`
31744
+ `Admin globals file not found at ${path59.relative(cwd, adminGlobalsPath)}. Run 'betterstart update admin-globals' first.`
31589
31745
  );
31590
31746
  process.exit(1);
31591
31747
  }
@@ -31595,7 +31751,7 @@ function runShadcnPresetUpdate({
31595
31751
  snapshot: snapshotFile(filePath)
31596
31752
  }));
31597
31753
  clack4.intro("BetterStart Shadcn Preset");
31598
- clack4.log.info(`Applying preset to ${path58.join(config.paths.admin, "components/ui")}`);
31754
+ clack4.log.info(`Applying preset to ${path59.join(config.paths.admin, "components/ui")}`);
31599
31755
  let failed = false;
31600
31756
  try {
31601
31757
  fs45.writeFileSync(
@@ -31608,7 +31764,7 @@ function runShadcnPresetUpdate({
31608
31764
  if (only) {
31609
31765
  args.push("--only", only);
31610
31766
  }
31611
- execFileSync6(shadcnBin, args, { cwd, stdio: "inherit" });
31767
+ execFileSync5(shadcnBin, args, { cwd, stdio: "inherit" });
31612
31768
  } catch {
31613
31769
  failed = true;
31614
31770
  } finally {
@@ -31654,7 +31810,7 @@ function toPosixPath(value) {
31654
31810
  }
31655
31811
  function resolveLocalShadcnBin(cwd) {
31656
31812
  const binName = process.platform === "win32" ? "shadcn.cmd" : "shadcn";
31657
- const shadcnBin = path58.join(cwd, "node_modules", ".bin", binName);
31813
+ const shadcnBin = path59.join(cwd, "node_modules", ".bin", binName);
31658
31814
  if (!fs45.existsSync(shadcnBin)) {
31659
31815
  clack4.cancel(
31660
31816
  `shadcn is not installed in this project. Run 'betterstart update-deps' and try again.`
@@ -31676,7 +31832,7 @@ function getHostProjectFilesToRestore(cwd) {
31676
31832
  "app/globals.css",
31677
31833
  "src/app/globals.css"
31678
31834
  ];
31679
- return hostRelativePaths.map((relativePath) => path58.join(cwd, relativePath));
31835
+ return hostRelativePaths.map((relativePath) => path59.join(cwd, relativePath));
31680
31836
  }
31681
31837
  function snapshotFile(filePath) {
31682
31838
  if (!fs45.existsSync(filePath)) {
@@ -31695,10 +31851,10 @@ function restoreFile(filePath, snapshot) {
31695
31851
  }
31696
31852
 
31697
31853
  // adapters/next/commands/update-deps.ts
31698
- import path59 from "path";
31854
+ import path60 from "path";
31699
31855
  import * as clack5 from "@clack/prompts";
31700
31856
  async function runUpdateDepsCommand(options) {
31701
- const cwd = options.cwd ? path59.resolve(options.cwd) : process.cwd();
31857
+ const cwd = options.cwd ? path60.resolve(options.cwd) : process.cwd();
31702
31858
  clack5.intro("BetterStart Update Dependencies");
31703
31859
  const pm = detectPackageManager(cwd);
31704
31860
  clack5.log.info(`Package manager: ${pm}`);
@@ -31733,17 +31889,17 @@ async function runUpdateDepsCommand(options) {
31733
31889
 
31734
31890
  // adapters/next/commands/update-styles.ts
31735
31891
  import fs46 from "fs";
31736
- import path60 from "path";
31892
+ import path61 from "path";
31737
31893
  import * as clack6 from "@clack/prompts";
31738
31894
  async function runUpdateStylesCommand(options) {
31739
- const cwd = options.cwd ? path60.resolve(options.cwd) : process.cwd();
31895
+ const cwd = options.cwd ? path61.resolve(options.cwd) : process.cwd();
31740
31896
  clack6.intro("BetterStart Update Styles");
31741
31897
  const config = await resolveConfigOrExit(cwd);
31742
31898
  const adminDir = config.paths.admin;
31743
31899
  const namespace = resolveAdminNamespace(config.frameworkConfig.next.namespace);
31744
- const targetPath = path60.join(cwd, adminDir, namespace.globalsFile);
31900
+ const targetPath = path61.join(cwd, adminDir, namespace.globalsFile);
31745
31901
  if (!fs46.existsSync(targetPath)) {
31746
- clack6.cancel(`${namespace.globalsFile} not found at ${path60.relative(cwd, targetPath)}`);
31902
+ clack6.cancel(`${namespace.globalsFile} not found at ${path61.relative(cwd, targetPath)}`);
31747
31903
  process.exit(1);
31748
31904
  }
31749
31905
  fs46.writeFileSync(
@@ -31751,12 +31907,14 @@ async function runUpdateStylesCommand(options) {
31751
31907
  applyAdminNamespaceToContent(readTemplate("admin-globals.css"), namespace.segment),
31752
31908
  "utf-8"
31753
31909
  );
31754
- clack6.log.success(`Updated ${path60.relative(cwd, targetPath)}`);
31910
+ clack6.log.success(`Updated ${path61.relative(cwd, targetPath)}`);
31755
31911
  clack6.outro("Styles updated");
31756
31912
  }
31757
31913
 
31758
31914
  // adapters/next/commands-runtime.ts
31759
31915
  var nextCommandRuntime = {
31916
+ listInstallableChoices,
31917
+ listSchemaChoices,
31760
31918
  runAdd: runAddCommand,
31761
31919
  runAddField: runAddFieldCommand,
31762
31920
  runCreate: runCreateCommand,
@@ -31780,7 +31938,7 @@ var { version } = JSON.parse(
31780
31938
  readFileSync(new URL("../package.json", import.meta.url), "utf-8")
31781
31939
  );
31782
31940
  var program = new Command2();
31783
- program.name("betterstart").description("Scaffold a preset- and integration-based Admin into any Next.js 16 application").version(version);
31941
+ program.name("betterstart").description("A production ready dashboard, tailored for you in 5 Minutes.").version(version);
31784
31942
  program.hook("preAction", (_command, actionCommand) => {
31785
31943
  requireInitializedProject(actionCommand);
31786
31944
  });
@@ -31799,14 +31957,18 @@ program.addCommand(createUpdateCommand(nextCommandRuntime));
31799
31957
  program.addCommand(createUpdateDepsCommand(nextCommandRuntime));
31800
31958
  program.addCommand(createUpdateStylesCommand(nextCommandRuntime));
31801
31959
  try {
31802
- await program.parseAsync();
31960
+ if (process.argv.slice(2).length === 0) {
31961
+ await runDefaultAction(program, nextCommandRuntime);
31962
+ } else {
31963
+ await program.parseAsync();
31964
+ }
31803
31965
  } catch (error) {
31804
31966
  if (process.env.BETTERSTART_DEBUG) {
31805
31967
  console.error(error);
31806
31968
  } else {
31807
31969
  const message = error instanceof Error && error.message ? error.message : String(error);
31808
- p30.log.error(message);
31809
- p30.log.message(pc12.dim("Re-run with BETTERSTART_DEBUG=1 for the full stack trace."));
31970
+ p31.log.error(message);
31971
+ p31.log.message(pc12.dim("Re-run with BETTERSTART_DEBUG=1 for the full stack trace."));
31810
31972
  }
31811
31973
  process.exit(1);
31812
31974
  }