betterstart-cli 0.0.87 → 0.0.89

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,7 +22,7 @@ import {
22
22
 
23
23
  // cli.ts
24
24
  import { readFileSync } from "fs";
25
- import * as p29 from "@clack/prompts";
25
+ import * as p30 from "@clack/prompts";
26
26
 
27
27
  // core-engine/commands/require-init.ts
28
28
  import path2 from "path";
@@ -198,7 +198,7 @@ function createUpdateStylesCommand(runtime) {
198
198
 
199
199
  // adapters/next/commands/add.ts
200
200
  import path27 from "path";
201
- import * as p6 from "@clack/prompts";
201
+ import * as p7 from "@clack/prompts";
202
202
 
203
203
  // core-engine/config/serialize.ts
204
204
  import fs3 from "fs";
@@ -750,7 +750,7 @@ async function resolveConfigOrExit(cwd) {
750
750
  import { execFileSync as execFileSync2 } from "child_process";
751
751
  import fs8 from "fs";
752
752
  import path10 from "path";
753
- import * as p3 from "@clack/prompts";
753
+ import * as p4 from "@clack/prompts";
754
754
 
755
755
  // adapters/next/init/scaffolders/dependencies.ts
756
756
  import { spawn } from "child_process";
@@ -1633,6 +1633,7 @@ async function syncProjectCliDependency(cwd, pm) {
1633
1633
  // adapters/next/utils/drizzle-push.ts
1634
1634
  import { spawn as spawn2 } from "child_process";
1635
1635
  import path9 from "path";
1636
+ import * as p2 from "@clack/prompts";
1636
1637
  var PG_SSL_WARNING_START = "Warning: SECURITY WARNING: The SSL modes 'prefer', 'require', and 'verify-ca' are treated as aliases for 'verify-full'.";
1637
1638
  var PG_SSL_WARNING_END = "See https://www.postgresql.org/docs/current/libpq-ssl.html for libpq SSL mode definitions.";
1638
1639
  var NODE_TRACE_WARNING_HINT = "(Use `node --trace-warnings";
@@ -1654,6 +1655,36 @@ var ANSI_ESCAPE_PATTERN = /\u001B\[[0-9;]*[A-Za-z]/g;
1654
1655
  function resolveDrizzlePushStdio(interactive) {
1655
1656
  return interactive ? ["inherit", "pipe", "pipe"] : "pipe";
1656
1657
  }
1658
+ var DRIZZLE_TTY_PROMPT_ERROR = "Interactive prompts require a TTY terminal";
1659
+ function createTtyPromptErrorSuppressor(forward) {
1660
+ let inStack = false;
1661
+ let saw = false;
1662
+ return {
1663
+ write(chunk) {
1664
+ const lines = chunk.match(/[^\n]*\n|[^\n]+/g) ?? [];
1665
+ const kept = [];
1666
+ for (const line of lines) {
1667
+ const text7 = stripAnsi(line).trim();
1668
+ if (text7.includes(DRIZZLE_TTY_PROMPT_ERROR)) {
1669
+ saw = true;
1670
+ inStack = true;
1671
+ continue;
1672
+ }
1673
+ if (inStack) {
1674
+ if (text7.startsWith("at ") || text7 === "") {
1675
+ continue;
1676
+ }
1677
+ inStack = false;
1678
+ }
1679
+ kept.push(line);
1680
+ }
1681
+ if (kept.length > 0) {
1682
+ forward(kept.join(""));
1683
+ }
1684
+ },
1685
+ sawError: () => saw
1686
+ };
1687
+ }
1657
1688
  function stripAnsi(text7) {
1658
1689
  return text7.replace(ANSI_ESCAPE_PATTERN, "").replaceAll("\r", "");
1659
1690
  }
@@ -1740,18 +1771,24 @@ function runDrizzlePush(cwd, options = {}) {
1740
1771
  outputNotified = true;
1741
1772
  options.onOutput?.();
1742
1773
  };
1774
+ const stderrTtySuppressor = createTtyPromptErrorSuppressor((chunk) => {
1775
+ notifyOutput();
1776
+ process.stderr.write(chunk);
1777
+ });
1778
+ const stdoutTtySuppressor = createTtyPromptErrorSuppressor((chunk) => {
1779
+ notifyOutput();
1780
+ process.stdout.write(chunk);
1781
+ });
1743
1782
  const stderrFilter = createDrizzleNoiseFilter((chunk) => {
1744
1783
  if (options.interactive) {
1745
- notifyOutput();
1746
- process.stderr.write(chunk);
1784
+ stderrTtySuppressor.write(chunk);
1747
1785
  return;
1748
1786
  }
1749
1787
  stderr += chunk;
1750
1788
  });
1751
1789
  const stdoutFilter = createDrizzleNoiseFilter((chunk) => {
1752
1790
  if (options.interactive) {
1753
- notifyOutput();
1754
- process.stdout.write(chunk);
1791
+ stdoutTtySuppressor.write(chunk);
1755
1792
  return;
1756
1793
  }
1757
1794
  stdout += chunk;
@@ -1770,6 +1807,29 @@ function runDrizzlePush(cwd, options = {}) {
1770
1807
  resolve({ success: true, error: null });
1771
1808
  return;
1772
1809
  }
1810
+ if (stdoutTtySuppressor.sawError() || stderrTtySuppressor.sawError()) {
1811
+ notifyOutput();
1812
+ p2.log.info("Database changes need your input \u2014 continuing in drizzle-kit.");
1813
+ const attached = spawn2(drizzleBin, ["push", "--force"], {
1814
+ cwd,
1815
+ stdio: "inherit",
1816
+ env: { ...process.env }
1817
+ });
1818
+ attached.on("close", (attachedCode, attachedSignal) => {
1819
+ if (attachedCode === 0) {
1820
+ resolve({ success: true, error: null });
1821
+ return;
1822
+ }
1823
+ resolve({
1824
+ success: false,
1825
+ error: attachedSignal ? `drizzle-kit push exited with signal ${attachedSignal}` : `drizzle-kit push exited with code ${attachedCode}`
1826
+ });
1827
+ });
1828
+ attached.on("error", (err) => {
1829
+ resolve({ success: false, error: err.message });
1830
+ });
1831
+ return;
1832
+ }
1773
1833
  resolve({
1774
1834
  success: false,
1775
1835
  error: signal ? `drizzle-kit push exited with signal ${signal}` : `drizzle-kit push exited with code ${code}`
@@ -1795,7 +1855,7 @@ ${stderr}`.trim();
1795
1855
  }
1796
1856
 
1797
1857
  // adapters/next/utils/next-steps.ts
1798
- import * as p2 from "@clack/prompts";
1858
+ import * as p3 from "@clack/prompts";
1799
1859
  function printNextSteps(options) {
1800
1860
  const steps = [`1. Review ${options.reviewLabel}`];
1801
1861
  if (options.needsMigration) {
@@ -1804,7 +1864,7 @@ function printNextSteps(options) {
1804
1864
  } else {
1805
1865
  steps.push(`2. Start the dev server and visit ${options.route}`);
1806
1866
  }
1807
- p2.note(steps.join("\n"), "Next steps");
1867
+ p3.note(steps.join("\n"), "Next steps");
1808
1868
  }
1809
1869
 
1810
1870
  // adapters/next/generators/post-generate.ts
@@ -1906,25 +1966,25 @@ function ensureDatabasePushDependencies(cwd, pm) {
1906
1966
  if (missing.length === 0) {
1907
1967
  return true;
1908
1968
  }
1909
- p3.log.info(
1969
+ p4.log.info(
1910
1970
  `Installing database push dependencies (${missing.map((dependency) => dependency.name).join(", ")})...`
1911
1971
  );
1912
1972
  for (const dependency of missing) {
1913
1973
  const installed2 = installDependency(cwd, pm, dependency.name, dependency.dev);
1914
1974
  if (!installed2) {
1915
- p3.log.warn(`Failed to install ${dependency.name}`);
1975
+ p4.log.warn(`Failed to install ${dependency.name}`);
1916
1976
  return false;
1917
1977
  }
1918
1978
  }
1919
1979
  const ready = hasPostgresRuntimeDependency(cwd) && hasDrizzleKitPostgresDriverDependency(cwd);
1920
1980
  if (ready) {
1921
- p3.log.success("Database push dependencies installed");
1981
+ p4.log.success("Database push dependencies installed");
1922
1982
  } else {
1923
1983
  const unresolved = [
1924
1984
  !hasPostgresRuntimeDependency(cwd) ? POSTGRES_RUNTIME_DEP : null,
1925
1985
  !hasDrizzleKitPostgresDriverDependency(cwd) ? DRIZZLE_KIT_POSTGRES_DRIVER_DEP : null
1926
1986
  ].filter((dependency) => Boolean(dependency));
1927
- p3.log.warn(`Installed dependencies but could not resolve ${unresolved.join(", ")}`);
1987
+ p4.log.warn(`Installed dependencies but could not resolve ${unresolved.join(", ")}`);
1928
1988
  }
1929
1989
  return ready;
1930
1990
  }
@@ -1967,8 +2027,8 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
1967
2027
  "Formatting: skipped (biome refuses files with conflict markers)",
1968
2028
  ...(options.conflictPaths ?? []).map((conflictPath) => ` - ${conflictPath}`)
1969
2029
  ];
1970
- p3.log.warn(lines.join("\n"));
1971
- p3.log.message(
2030
+ p4.log.warn(lines.join("\n"));
2031
+ p4.log.message(
1972
2032
  "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."
1973
2033
  );
1974
2034
  return result;
@@ -1978,7 +2038,7 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
1978
2038
  const dbUrl = process.env.DATABASE_URL;
1979
2039
  if (!dbUrl) {
1980
2040
  result.dbPush = "no-db-url";
1981
- p3.log.warn(
2041
+ p4.log.warn(
1982
2042
  [
1983
2043
  "Database: skipped (no DATABASE_URL configured)",
1984
2044
  " To sync later: run db:push after setting DATABASE_URL"
@@ -1986,43 +2046,43 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
1986
2046
  );
1987
2047
  } else if (!ensureDatabasePushDependencies(cwd, pm)) {
1988
2048
  result.dbPush = "failed";
1989
- p3.log.warn(
2049
+ p4.log.warn(
1990
2050
  "Database push failed (install database dependencies and run drizzle-kit push manually)"
1991
2051
  );
1992
2052
  } else if (hasPkgScript(cwd, "db:push")) {
1993
- p3.log.info("Running db:push...");
2053
+ p4.log.info("Running db:push...");
1994
2054
  const ok = runPmScript(pm, "db:push", cwd);
1995
2055
  result.dbPush = ok ? "success" : "failed";
1996
2056
  if (ok) {
1997
- p3.log.success("Database schema synced");
2057
+ p4.log.success("Database schema synced");
1998
2058
  } else {
1999
- p3.log.warn("Database push failed (run db:push manually)");
2059
+ p4.log.warn("Database push failed (run db:push manually)");
2000
2060
  }
2001
2061
  } else {
2002
- p3.log.info("Running drizzle-kit push...");
2062
+ p4.log.info("Running drizzle-kit push...");
2003
2063
  try {
2004
2064
  const pushResult = await runDrizzlePush(cwd, { interactive: true });
2005
2065
  if (!pushResult.success) {
2006
2066
  throw new Error(pushResult.error ?? "drizzle-kit push failed");
2007
2067
  }
2008
2068
  result.dbPush = "success";
2009
- p3.log.success("Database schema synced");
2069
+ p4.log.success("Database schema synced");
2010
2070
  } catch {
2011
2071
  result.dbPush = "failed";
2012
- p3.log.warn("Database push failed (run drizzle-kit push manually)");
2072
+ p4.log.warn("Database push failed (run drizzle-kit push manually)");
2013
2073
  }
2014
2074
  }
2015
2075
  } else {
2016
- p3.log.info(`Database: skipped (${options.skipMigrationMessage ?? "--skip-migration"})`);
2076
+ p4.log.info(`Database: skipped (${options.skipMigrationMessage ?? "--skip-migration"})`);
2017
2077
  }
2018
2078
  if (hasPkgScript(cwd, "lint:fix")) {
2019
- p3.log.info("Running lint:fix...");
2079
+ p4.log.info("Running lint:fix...");
2020
2080
  const ok = runPmScript(pm, "lint:fix", cwd, BIOME_FORMAT_TIMEOUT_MS);
2021
2081
  result.lintFix = ok ? "success" : "failed";
2022
2082
  if (ok) {
2023
- p3.log.success("Code formatted");
2083
+ p4.log.success("Code formatted");
2024
2084
  } else {
2025
- p3.log.warn("Lint fix had issues (run lint:fix manually)");
2085
+ p4.log.warn("Lint fix had issues (run lint:fix manually)");
2026
2086
  }
2027
2087
  } else {
2028
2088
  try {
@@ -2030,10 +2090,10 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2030
2090
  throw new Error("Biome binary not found");
2031
2091
  }
2032
2092
  result.lintFix = "success";
2033
- p3.log.success("Code formatted with Biome");
2093
+ p4.log.success("Code formatted with Biome");
2034
2094
  } catch {
2035
2095
  result.lintFix = "failed";
2036
- p3.log.warn("Biome formatting had issues (run biome check --write manually)");
2096
+ p4.log.warn("Biome formatting had issues (run biome check --write manually)");
2037
2097
  }
2038
2098
  }
2039
2099
  if (options.showNextSteps !== false) {
@@ -2050,7 +2110,7 @@ async function runPostGenerate(cwd, schemaName, options = {}) {
2050
2110
  // adapters/next/integration-runtime.ts
2051
2111
  import fs14 from "fs";
2052
2112
  import path17 from "path";
2053
- import * as p4 from "@clack/prompts";
2113
+ import * as p5 from "@clack/prompts";
2054
2114
 
2055
2115
  // core-engine/schema/schema-reader.ts
2056
2116
  import fs9 from "fs";
@@ -3376,12 +3436,12 @@ async function resolveTextEnvValue(options) {
3376
3436
  if (existingValue) {
3377
3437
  return existingValue;
3378
3438
  }
3379
- const result = await p4.text({
3439
+ const result = await p5.text({
3380
3440
  message: options.message,
3381
3441
  defaultValue: options.defaultValue,
3382
3442
  validate: options.validate
3383
3443
  });
3384
- if (p4.isCancel(result)) {
3444
+ if (p5.isCancel(result)) {
3385
3445
  throw new Error(options.cancelMessage);
3386
3446
  }
3387
3447
  options.overwriteEnvKeys.add(options.key);
@@ -3392,11 +3452,11 @@ async function resolvePasswordEnvValue(options) {
3392
3452
  if (existingValue) {
3393
3453
  return existingValue;
3394
3454
  }
3395
- const result = await p4.password({
3455
+ const result = await p5.password({
3396
3456
  message: options.message,
3397
3457
  validate: options.validate
3398
3458
  });
3399
- if (p4.isCancel(result)) {
3459
+ if (p5.isCancel(result)) {
3400
3460
  throw new Error(options.cancelMessage);
3401
3461
  }
3402
3462
  options.overwriteEnvKeys.add(options.key);
@@ -5777,14 +5837,14 @@ function buildStepsConstant(steps) {
5777
5837
  ${entries.join(",\n")}
5778
5838
  ]`;
5779
5839
  }
5780
- function buildComponentSource(p30) {
5840
+ function buildComponentSource(p31) {
5781
5841
  const providerOpen = ` <NuqsAdapter>
5782
5842
  <React.Suspense fallback={null}>
5783
- <${p30.pascal}FormInner />
5843
+ <${p31.pascal}FormInner />
5784
5844
  </React.Suspense>
5785
5845
  </NuqsAdapter>`;
5786
5846
  const exportWrapper = `
5787
- export function ${p30.pascal}Form() {
5847
+ export function ${p31.pascal}Form() {
5788
5848
  return (
5789
5849
  ${providerOpen}
5790
5850
  )
@@ -5793,22 +5853,22 @@ ${providerOpen}
5793
5853
  return `'use client'
5794
5854
 
5795
5855
  import { standardSchemaResolver } from '@hookform/resolvers/standard-schema'
5796
- import { ChevronLeft, ChevronRight${p30.hasListFields ? ", Trash2" : ""} } from 'lucide-react'
5856
+ import { ChevronLeft, ChevronRight${p31.hasListFields ? ", Trash2" : ""} } from 'lucide-react'
5797
5857
  import { createParser, useQueryState } from 'nuqs'
5798
5858
  import { NuqsAdapter } from 'nuqs/adapters/next/app'
5799
5859
  import * as React from 'react'
5800
- ${p30.rhfImport}
5860
+ ${p31.rhfImport}
5801
5861
  import { z } from 'zod/v3'
5802
- import { create${p30.pascal}Submission } from '@admin/actions/${p30.actionImportPath}'
5862
+ import { create${p31.pascal}Submission } from '@admin/actions/${p31.actionImportPath}'
5803
5863
 
5804
5864
  const formSchema = z.object({
5805
- ${p30.zodFields}
5865
+ ${p31.zodFields}
5806
5866
  })
5807
5867
 
5808
5868
  type FormValues = z.infer<typeof formSchema>
5809
5869
  ${buildFieldErrorHelper()}
5810
5870
 
5811
- ${p30.stepsConst}
5871
+ ${p31.stepsConst}
5812
5872
 
5813
5873
  const stepParser = createParser({
5814
5874
  parse(value) {
@@ -5826,7 +5886,7 @@ const stepParser = createParser({
5826
5886
  }
5827
5887
  }).withDefault(0)
5828
5888
 
5829
- function ${p30.pascal}FormInner() {
5889
+ function ${p31.pascal}FormInner() {
5830
5890
  const [currentStep, setCurrentStep] = useQueryState('step', stepParser)
5831
5891
  const [submitted, setSubmitted] = React.useState(false)
5832
5892
  const [submitting, startSubmitTransition] = React.useTransition()
@@ -5834,11 +5894,11 @@ function ${p30.pascal}FormInner() {
5834
5894
  const form = useForm<FormValues>({
5835
5895
  resolver: standardSchemaResolver(formSchema),
5836
5896
  defaultValues: {
5837
- ${p30.defaults}
5897
+ ${p31.defaults}
5838
5898
  },
5839
5899
  })
5840
5900
 
5841
- ${p30.fieldArraySetup}${p30.watchSetup}
5901
+ ${p31.fieldArraySetup}${p31.watchSetup}
5842
5902
  async function handleNext() {
5843
5903
  const stepFields = STEPS[currentStep].fields as (keyof FormValues)[]
5844
5904
  const isValid = await form.trigger(stepFields, { shouldFocus: true })
@@ -5854,9 +5914,9 @@ ${p30.fieldArraySetup}${p30.watchSetup}
5854
5914
  function onSubmit(values: FormValues) {
5855
5915
  startSubmitTransition(async () => {
5856
5916
  try {
5857
- const result = await create${p30.pascal}Submission(values)
5917
+ const result = await create${p31.pascal}Submission(values)
5858
5918
  if (result.success) {
5859
- ${p30.successHandler}
5919
+ ${p31.successHandler}
5860
5920
  } else {
5861
5921
  form.setError('root', { message: result.error || 'Something went wrong' })
5862
5922
  }
@@ -5870,7 +5930,7 @@ ${p30.fieldArraySetup}${p30.watchSetup}
5870
5930
  return (
5871
5931
  <div className="rounded-sm border p-6 text-center">
5872
5932
  <h3 className="text-lg font-semibold">Thank you!</h3>
5873
- <p className="mt-2 text-muted-foreground">${p30.successMessage}</p>
5933
+ <p className="mt-2 text-muted-foreground">${p31.successMessage}</p>
5874
5934
  </div>
5875
5935
  )
5876
5936
  }
@@ -5887,7 +5947,7 @@ ${p30.fieldArraySetup}${p30.watchSetup}
5887
5947
 
5888
5948
  {/* Step content */}
5889
5949
  <div key={currentStep} className="animate-in fade-in duration-300 space-y-6">
5890
- ${p30.stepContentBlocks}
5950
+ ${p31.stepContentBlocks}
5891
5951
  </div>
5892
5952
 
5893
5953
  {form.formState.errors.root && (
@@ -5921,7 +5981,7 @@ ${p30.stepContentBlocks}
5921
5981
  onClick={() => form.handleSubmit(onSubmit)()}
5922
5982
  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"
5923
5983
  >
5924
- {submitting ? 'Submitting...' : ${p30.submitText}}
5984
+ {submitting ? 'Submitting...' : ${p31.submitText}}
5925
5985
  </button>
5926
5986
  )}
5927
5987
  </div>
@@ -17745,7 +17805,7 @@ function readPresetTemplate(presetId, relativePath) {
17745
17805
  // adapters/next/snapshots/apply.ts
17746
17806
  import fs20 from "fs";
17747
17807
  import path24 from "path";
17748
- import * as p5 from "@clack/prompts";
17808
+ import * as p6 from "@clack/prompts";
17749
17809
 
17750
17810
  // core-engine/snapshots/ast-substitution.ts
17751
17811
  import { Node, Project } from "ts-morph";
@@ -18412,7 +18472,7 @@ function isInteractiveSession(interactive) {
18412
18472
  return interactive && Boolean(process.stdin.isTTY) && process.env.CI !== "true";
18413
18473
  }
18414
18474
  async function promptNoBaseDecision(filePath) {
18415
- const answer = await p5.select({
18475
+ const answer = await p6.select({
18416
18476
  message: `File already exists without snapshot base: ${filePath}`,
18417
18477
  options: [
18418
18478
  { value: "backup", label: "Backup and overwrite", hint: "recommended" },
@@ -18421,7 +18481,7 @@ async function promptNoBaseDecision(filePath) {
18421
18481
  ],
18422
18482
  initialValue: "backup"
18423
18483
  });
18424
- if (p5.isCancel(answer)) {
18484
+ if (p6.isCancel(answer)) {
18425
18485
  throw new Error("Generation cancelled.");
18426
18486
  }
18427
18487
  return answer;
@@ -19302,18 +19362,18 @@ async function runAddCommand(items, options) {
19302
19362
  const presetIds = items.filter(isPresetId);
19303
19363
  const integrationIds = items.filter(isIntegrationId);
19304
19364
  if (!installIntegrationsMode && integrationIds.length > 0) {
19305
- p6.log.error(
19365
+ p7.log.error(
19306
19366
  `Integration IDs require --integration. Run \`betterstart add --integration ${integrationIds.join(" ")}\`.`
19307
19367
  );
19308
19368
  process.exit(1);
19309
19369
  }
19310
19370
  if (installIntegrationsMode && presetIds.length > 0) {
19311
- p6.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
19371
+ p7.log.error(`Preset IDs cannot be installed with --integration: ${presetIds.join(", ")}`);
19312
19372
  process.exit(1);
19313
19373
  }
19314
19374
  const invalidItems = installIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
19315
19375
  if (invalidItems.length > 0) {
19316
- p6.log.error(
19376
+ p7.log.error(
19317
19377
  installIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
19318
19378
  );
19319
19379
  process.exit(1);
@@ -19324,7 +19384,7 @@ async function runAddCommand(items, options) {
19324
19384
  const pm = detectPackageManager(cwd);
19325
19385
  const cliSyncResult = await syncProjectCliDependency(cwd, pm);
19326
19386
  if (cliSyncResult && !cliSyncResult.success) {
19327
- p6.log.error(cliSyncResult.error ?? "Failed to sync betterstart-cli");
19387
+ p7.log.error(cliSyncResult.error ?? "Failed to sync betterstart-cli");
19328
19388
  process.exit(1);
19329
19389
  }
19330
19390
  if (installIntegrationsMode) {
@@ -19338,10 +19398,10 @@ async function runAddCommand(items, options) {
19338
19398
  });
19339
19399
  writeConfigFile(cwd, result2.config);
19340
19400
  if (result2.warnings.length > 0) {
19341
- p6.note(result2.warnings.join("\n"), "Warnings");
19401
+ p7.note(result2.warnings.join("\n"), "Warnings");
19342
19402
  }
19343
19403
  if (result2.installed.length === 0 && result2.activated.length === 0 && result2.skipped.length > 0) {
19344
- p6.outro(`No changes made. Already installed: ${result2.skipped.join(", ")}`);
19404
+ p7.outro(`No changes made. Already installed: ${result2.skipped.join(", ")}`);
19345
19405
  return;
19346
19406
  }
19347
19407
  const conflictPaths2 = scanConflictPaths(cwd);
@@ -19363,12 +19423,12 @@ async function runAddCommand(items, options) {
19363
19423
  result2.installed.length > 0 ? `Installed integration${result2.installed.length === 1 ? "" : "s"}: ${result2.installed.join(", ")}` : null,
19364
19424
  result2.activated.length > 0 ? `Activated integration${result2.activated.length === 1 ? "" : "s"}: ${result2.activated.join(", ")}` : null
19365
19425
  ].filter(Boolean);
19366
- p6.outro(messages.join("\n"));
19426
+ p7.outro(messages.join("\n"));
19367
19427
  return;
19368
19428
  }
19369
19429
  const invalidPresets = items.filter((presetId) => !isPresetId(presetId));
19370
19430
  if (invalidPresets.length > 0) {
19371
- p6.log.error(formatUnknownPresetMessage(invalidPresets));
19431
+ p7.log.error(formatUnknownPresetMessage(invalidPresets));
19372
19432
  process.exit(1);
19373
19433
  }
19374
19434
  const result = await installPresets({
@@ -19381,11 +19441,11 @@ async function runAddCommand(items, options) {
19381
19441
  });
19382
19442
  writeConfigFile(cwd, result.config);
19383
19443
  if (result.installed.length === 0 && result.skipped.length > 0) {
19384
- p6.outro(`No changes made. Already installed: ${result.skipped.join(", ")}`);
19444
+ p7.outro(`No changes made. Already installed: ${result.skipped.join(", ")}`);
19385
19445
  return;
19386
19446
  }
19387
19447
  if (result.warnings.length > 0) {
19388
- p6.note(result.warnings.join("\n"), "Warnings");
19448
+ p7.note(result.warnings.join("\n"), "Warnings");
19389
19449
  }
19390
19450
  const installedSchemaNames = result.installed.flatMap(
19391
19451
  (presetId) => getPresetDefinition(presetId).schemaFiles.map((schemaFile) => schemaFile.replace(/\.json$/, ""))
@@ -19402,14 +19462,14 @@ async function runAddCommand(items, options) {
19402
19462
  if (conflictPaths.length === 0) {
19403
19463
  printAddNextSteps("preset", hasSchemaChanges, postGenerateResult, adminRoutePath);
19404
19464
  }
19405
- p6.outro(
19465
+ p7.outro(
19406
19466
  `Installed preset${result.installed.length === 1 ? "" : "s"}: ${result.installed.join(", ")}`
19407
19467
  );
19408
19468
  }
19409
19469
 
19410
19470
  // adapters/next/commands/add-field.ts
19411
19471
  import path30 from "path";
19412
- import * as p10 from "@clack/prompts";
19472
+ import * as p11 from "@clack/prompts";
19413
19473
 
19414
19474
  // core-engine/schema/add-field.ts
19415
19475
  import fs23 from "fs";
@@ -20061,7 +20121,7 @@ function getTabFields(tab) {
20061
20121
  // adapters/next/commands/generate.ts
20062
20122
  import fs24 from "fs";
20063
20123
  import path29 from "path";
20064
- import * as p8 from "@clack/prompts";
20124
+ import * as p9 from "@clack/prompts";
20065
20125
 
20066
20126
  // core-engine/snapshots/rename-detector.ts
20067
20127
  function levenshtein(a, b) {
@@ -20155,7 +20215,7 @@ function diffSchemas(before, after) {
20155
20215
 
20156
20216
  // core-engine/utils/spinner.ts
20157
20217
  import { stripVTControlCharacters } from "util";
20158
- import * as p7 from "@clack/prompts";
20218
+ import * as p8 from "@clack/prompts";
20159
20219
  var RENDER_OVERHEAD = 7;
20160
20220
  var MIN_MESSAGE_WIDTH = 8;
20161
20221
  function fitSpinnerMessage(message) {
@@ -20202,7 +20262,7 @@ function hasActiveSpinner() {
20202
20262
  return activeSpinners > 0;
20203
20263
  }
20204
20264
  function spinner2(options) {
20205
- const inner = p7.spinner({ ...options, cancelMessage: "Setup cancelled." });
20265
+ const inner = p8.spinner({ ...options, cancelMessage: "Setup cancelled." });
20206
20266
  const guided = options?.withGuide !== false;
20207
20267
  let started = false;
20208
20268
  const setStarted = (next) => {
@@ -20321,7 +20381,7 @@ function assertSnapshotStateOrExit(cwd) {
20321
20381
  if (snapshotRootExists(cwd)) {
20322
20382
  return;
20323
20383
  }
20324
- p8.log.error(UNSUPPORTED_PROJECT_STATE_MESSAGE);
20384
+ p9.log.error(UNSUPPORTED_PROJECT_STATE_MESSAGE);
20325
20385
  process.exit(1);
20326
20386
  }
20327
20387
  function printSchemaDiff(scope, loaded, cwd) {
@@ -20356,14 +20416,14 @@ function printSchemaDiff(scope, loaded, cwd) {
20356
20416
  ` custom cells: +[${diff.customComponents.added.join(", ")}] -[${diff.customComponents.removed.join(", ")}]`
20357
20417
  );
20358
20418
  }
20359
- p8.log.message(lines.join("\n"));
20419
+ p9.log.message(lines.join("\n"));
20360
20420
  }
20361
20421
  async function promptConfirm(message) {
20362
- const result = await p8.confirm({
20422
+ const result = await p9.confirm({
20363
20423
  message,
20364
20424
  initialValue: true
20365
20425
  });
20366
- if (p8.isCancel(result)) {
20426
+ if (p9.isCancel(result)) {
20367
20427
  throw new Error("Generation cancelled.");
20368
20428
  }
20369
20429
  return Boolean(result);
@@ -20493,7 +20553,7 @@ async function maybeBuildRenamePlan(loaded, cwd, config, generatedFiles, options
20493
20553
  };
20494
20554
  if (finalPlan.fields.length === 0 && finalPlan.customCells.length === 0) {
20495
20555
  if (validatedCustomCells.warnings.length > 0) {
20496
- p8.log.warn(validatedCustomCells.warnings.join("\n"));
20556
+ p9.log.warn(validatedCustomCells.warnings.join("\n"));
20497
20557
  }
20498
20558
  return void 0;
20499
20559
  }
@@ -20511,10 +20571,10 @@ async function maybeBuildRenamePlan(loaded, cwd, config, generatedFiles, options
20511
20571
  if (preview.previewLines.length > previewLines.length) {
20512
20572
  renameLines.push(` ... ${preview.previewLines.length - previewLines.length} more change(s)`);
20513
20573
  }
20514
- p8.log.message(renameLines.join("\n"));
20574
+ p9.log.message(renameLines.join("\n"));
20515
20575
  const warnings = [...validatedCustomCells.warnings, ...preview.warnings];
20516
20576
  if (warnings.length > 0) {
20517
- p8.log.warn(warnings.join("\n"));
20577
+ p9.log.warn(warnings.join("\n"));
20518
20578
  }
20519
20579
  const confirmed = await promptConfirm("Apply these rename substitutions before merge?");
20520
20580
  return confirmed ? finalPlan : void 0;
@@ -20625,7 +20685,7 @@ function printApplySummary(schemaName, summary) {
20625
20685
  if (summary.skippedCleared.length > 0) {
20626
20686
  lines.push(` skip entries cleared: ${summary.skippedCleared.join(", ")}`);
20627
20687
  }
20628
- p8.log.message(lines.join("\n"));
20688
+ p9.log.message(lines.join("\n"));
20629
20689
  }
20630
20690
  async function runGenerateCommand(schemaName, options) {
20631
20691
  const cwd = options.cwd ? path29.resolve(options.cwd) : process.cwd();
@@ -20634,7 +20694,7 @@ async function runGenerateCommand(schemaName, options) {
20634
20694
  try {
20635
20695
  config = await resolveConfig(cwd);
20636
20696
  } catch (error) {
20637
- p8.log.error(`Error loading config: ${error instanceof Error ? error.message : String(error)}`);
20697
+ p9.log.error(`Error loading config: ${error instanceof Error ? error.message : String(error)}`);
20638
20698
  process.exit(1);
20639
20699
  }
20640
20700
  assertSnapshotStateOrExit(cwd);
@@ -20644,7 +20704,7 @@ async function runGenerateCommand(schemaName, options) {
20644
20704
  if (options.all) {
20645
20705
  const schemaNames = listSchemaNames(schemasDir);
20646
20706
  if (schemaNames.length === 0) {
20647
- p8.log.error(`No schemas found in ${schemasDir}`);
20707
+ p9.log.error(`No schemas found in ${schemasDir}`);
20648
20708
  process.exit(1);
20649
20709
  }
20650
20710
  const failed = [];
@@ -20652,14 +20712,14 @@ async function runGenerateCommand(schemaName, options) {
20652
20712
  const processedRoutes = [];
20653
20713
  let markdownDepsChecked = false;
20654
20714
  const adminRoutePath2 = resolveAdminNamespace(config.frameworkConfig.next.namespace).routePath;
20655
- p8.intro(`BetterStart Generator \u2014 regenerating ${schemaNames.length} schema(s)`);
20715
+ p9.intro(`BetterStart Generator \u2014 regenerating ${schemaNames.length} schema(s)`);
20656
20716
  for (const name of schemaNames) {
20657
20717
  if (hasTombstone(cwd, name)) {
20658
20718
  if (loadManifest(cwd, name)) {
20659
20719
  clearTombstone(cwd, name);
20660
- p8.log.warn(`${name}: tombstone cleared (manifest present)`);
20720
+ p9.log.warn(`${name}: tombstone cleared (manifest present)`);
20661
20721
  } else {
20662
- p8.log.message(`${name}: skipped (tombstoned)`);
20722
+ p9.log.message(`${name}: skipped (tombstoned)`);
20663
20723
  continue;
20664
20724
  }
20665
20725
  }
@@ -20685,7 +20745,7 @@ async function runGenerateCommand(schemaName, options) {
20685
20745
  processed.push(name);
20686
20746
  processedRoutes.push(getGeneratedSchemaRoutePath(loaded2, adminRoutePath2));
20687
20747
  } catch (error) {
20688
- p8.log.error(`${name}: ${error instanceof Error ? error.message : String(error)}`);
20748
+ p9.log.error(`${name}: ${error instanceof Error ? error.message : String(error)}`);
20689
20749
  failed.push(name);
20690
20750
  }
20691
20751
  }
@@ -20708,14 +20768,14 @@ async function runGenerateCommand(schemaName, options) {
20708
20768
  });
20709
20769
  }
20710
20770
  if (failed.length > 0) {
20711
- p8.log.error(`Failed: ${failed.join(", ")}`);
20771
+ p9.log.error(`Failed: ${failed.join(", ")}`);
20712
20772
  process.exit(1);
20713
20773
  }
20714
- p8.outro(`Regenerated ${processed.length}/${schemaNames.length} schema(s)`);
20774
+ p9.outro(`Regenerated ${processed.length}/${schemaNames.length} schema(s)`);
20715
20775
  return;
20716
20776
  }
20717
20777
  if (!schemaName) {
20718
- p8.log.error("Error: schema name is required (or use --all)");
20778
+ p9.log.error("Error: schema name is required (or use --all)");
20719
20779
  process.exit(1);
20720
20780
  }
20721
20781
  let loaded;
@@ -20723,20 +20783,20 @@ async function runGenerateCommand(schemaName, options) {
20723
20783
  loaded = loadSchema(schemasDir, schemaName);
20724
20784
  } catch (error) {
20725
20785
  if (error instanceof SchemaNotFoundError) {
20726
- p8.log.error(error.message);
20786
+ p9.log.error(error.message);
20727
20787
  } else {
20728
- p8.log.error(`Error loading schema: ${error instanceof Error ? error.message : String(error)}`);
20788
+ p9.log.error(`Error loading schema: ${error instanceof Error ? error.message : String(error)}`);
20729
20789
  }
20730
20790
  process.exit(1);
20731
20791
  }
20732
20792
  const validationErrors = validateLoadedSchema(loaded);
20733
20793
  if (validationErrors.length > 0) {
20734
- p8.log.error(
20794
+ p9.log.error(
20735
20795
  ["Schema validation failed:", ...validationErrors.map((error) => ` - ${error}`)].join("\n")
20736
20796
  );
20737
20797
  process.exit(1);
20738
20798
  }
20739
- p8.intro(`BetterStart Generator \u2014 ${loaded.schema.name}`);
20799
+ p9.intro(`BetterStart Generator \u2014 ${loaded.schema.name}`);
20740
20800
  const needsMarkdownRenderer = schemaNeedsMarkdownRenderer(loaded);
20741
20801
  await ensureMarkdownRendererDependencies(cwd, needsMarkdownRenderer);
20742
20802
  const result = await applySchemaGeneration(loaded, cwd, config, {
@@ -20761,38 +20821,38 @@ async function runGenerateCommand(schemaName, options) {
20761
20821
  adminRoutePath,
20762
20822
  schemaRoutePath: getGeneratedSchemaRoutePath(loaded, adminRoutePath)
20763
20823
  });
20764
- p8.outro(`Generated ${loaded.schema.name}`);
20824
+ p9.outro(`Generated ${loaded.schema.name}`);
20765
20825
  }
20766
20826
 
20767
20827
  // adapters/next/commands/schema-prompts.ts
20768
- import * as p9 from "@clack/prompts";
20828
+ import * as p10 from "@clack/prompts";
20769
20829
  function isInteractiveSession3() {
20770
20830
  return Boolean(process.stdin.isTTY) && process.env.CI !== "true";
20771
20831
  }
20772
20832
  function fail(message) {
20773
- p9.log.error(message);
20833
+ p10.log.error(message);
20774
20834
  process.exit(1);
20775
20835
  }
20776
20836
  function cancel2(context) {
20777
- p9.cancel(context.cancelMessage);
20837
+ p10.cancel(context.cancelMessage);
20778
20838
  process.exit(0);
20779
20839
  }
20780
20840
  function cancelIfNeeded(context, value) {
20781
- if (p9.isCancel(value)) {
20841
+ if (p10.isCancel(value)) {
20782
20842
  cancel2(context);
20783
20843
  }
20784
20844
  return value;
20785
20845
  }
20786
20846
  async function promptConfirm2(context, message, initialValue = true) {
20787
- const confirmed = await p9.confirm({ message, initialValue });
20788
- if (p9.isCancel(confirmed)) {
20847
+ const confirmed = await p10.confirm({ message, initialValue });
20848
+ if (p10.isCancel(confirmed)) {
20789
20849
  cancel2(context);
20790
20850
  }
20791
20851
  return Boolean(confirmed);
20792
20852
  }
20793
20853
  async function promptText(context, message, optionsOrDefaultValue) {
20794
20854
  const options = typeof optionsOrDefaultValue === "string" ? { defaultValue: optionsOrDefaultValue } : optionsOrDefaultValue ?? {};
20795
- const value = await p9.text({
20855
+ const value = await p10.text({
20796
20856
  message,
20797
20857
  defaultValue: options.defaultValue,
20798
20858
  placeholder: options.placeholder,
@@ -20809,7 +20869,7 @@ async function promptText(context, message, optionsOrDefaultValue) {
20809
20869
  return String(cancelIfNeeded(context, value)).trim();
20810
20870
  }
20811
20871
  async function promptOptionalText(context, message) {
20812
- const value = await p9.text({
20872
+ const value = await p10.text({
20813
20873
  message,
20814
20874
  placeholder: "Leave blank to skip"
20815
20875
  });
@@ -20817,7 +20877,7 @@ async function promptOptionalText(context, message) {
20817
20877
  return result || void 0;
20818
20878
  }
20819
20879
  async function promptSelectValue(context, message, options, initialValue) {
20820
- const value = await p9.select({
20880
+ const value = await p10.select({
20821
20881
  message,
20822
20882
  options,
20823
20883
  initialValue
@@ -21036,7 +21096,7 @@ async function shouldPromptRequired(type) {
21036
21096
  return !["group", "section", "tabs", "separator"].includes(type);
21037
21097
  }
21038
21098
  async function promptFormFileOptions(context) {
21039
- const selected = await p9.multiselect({
21099
+ const selected = await p10.multiselect({
21040
21100
  message: "Field options",
21041
21101
  options: [
21042
21102
  { value: "required", label: "Required field?" },
@@ -21075,7 +21135,7 @@ async function promptFieldOptions(context, kind, type, creatable) {
21075
21135
  try {
21076
21136
  return parseInteractiveOptionsList(value);
21077
21137
  } catch (error) {
21078
- p9.log.error(error instanceof Error ? error.message : String(error));
21138
+ p10.log.error(error instanceof Error ? error.message : String(error));
21079
21139
  }
21080
21140
  }
21081
21141
  }
@@ -21193,7 +21253,7 @@ async function promptChildFields(context, kind, schemasDir, scope, fields, depth
21193
21253
  const addChild = fields.length === 0 ? await promptConfirm2(context, "Add a child field?", true) : await promptConfirm2(context, "Add another child field?", false);
21194
21254
  if (!addChild) {
21195
21255
  if (fields.length === 0) {
21196
- p9.log.warn("Containers need at least one child field.");
21256
+ p10.log.warn("Containers need at least one child field.");
21197
21257
  continue;
21198
21258
  }
21199
21259
  return;
@@ -21218,7 +21278,7 @@ async function promptTabsField(context, kind, schemasDir, scope, name, label, de
21218
21278
  const addTab = field.tabs.length === 0 ? await promptConfirm2(context, "Add a tab?", true) : await promptConfirm2(context, "Add another tab?", false);
21219
21279
  if (!addTab) {
21220
21280
  if (field.tabs.length === 0) {
21221
- p9.log.warn("Tabs need at least one tab.");
21281
+ p10.log.warn("Tabs need at least one tab.");
21222
21282
  continue;
21223
21283
  }
21224
21284
  return field;
@@ -21243,7 +21303,7 @@ async function promptTabsField(context, kind, schemasDir, scope, name, label, de
21243
21303
  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);
21244
21304
  if (!addChild) {
21245
21305
  if (mainFields.length + sidebarFields.length === 0) {
21246
- p9.log.warn("Tabs need at least one child field.");
21306
+ p10.log.warn("Tabs need at least one child field.");
21247
21307
  continue;
21248
21308
  }
21249
21309
  break;
@@ -21314,7 +21374,7 @@ async function applyAdvancedOptions(context, field, kind, type, options) {
21314
21374
  if (Number.isInteger(parsed) && parsed > 0) {
21315
21375
  record.length = parsed;
21316
21376
  } else {
21317
- p9.log.warn("Skipped invalid length.");
21377
+ p10.log.warn("Skipped invalid length.");
21318
21378
  }
21319
21379
  }
21320
21380
  }
@@ -21472,11 +21532,11 @@ function hasNonInteractiveFieldOptions(options) {
21472
21532
  );
21473
21533
  }
21474
21534
  function fail2(message) {
21475
- p10.log.error(message);
21535
+ p11.log.error(message);
21476
21536
  process.exit(1);
21477
21537
  }
21478
21538
  function cancel4(message = "Add field cancelled.") {
21479
- p10.cancel(message);
21539
+ p11.cancel(message);
21480
21540
  process.exit(0);
21481
21541
  }
21482
21542
  function schemaNameFromLoaded(loaded) {
@@ -21581,7 +21641,7 @@ function printPreview(loaded, owner, firstTimeGeneration, insertion, options) {
21581
21641
  } else {
21582
21642
  lines.push("schema integration: none");
21583
21643
  }
21584
- p10.note(
21644
+ p11.note(
21585
21645
  `${lines.join("\n")}
21586
21646
 
21587
21647
  ${stringifyProjectJson(insertion.field).trim()}`,
@@ -21614,7 +21674,7 @@ Re-run with --yes to confirm these warning cases.`);
21614
21674
  }
21615
21675
  return;
21616
21676
  }
21617
- p10.note(warnings.join("\n"), "Warnings");
21677
+ p11.note(warnings.join("\n"), "Warnings");
21618
21678
  const confirmed = await promptConfirm3("Continue with these warnings?", true);
21619
21679
  if (!confirmed) {
21620
21680
  cancel4();
@@ -21731,7 +21791,7 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21731
21791
  }
21732
21792
  }
21733
21793
  writeAuthoredGeneratedSchema(loaded);
21734
- p10.log.success(`Updated ${path30.relative(cwd, loaded.filePath)}`);
21794
+ p11.log.success(`Updated ${path30.relative(cwd, loaded.filePath)}`);
21735
21795
  try {
21736
21796
  await runGenerateCommand(selectedSchemaName, {
21737
21797
  force: false,
@@ -21742,8 +21802,8 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21742
21802
  cwd
21743
21803
  });
21744
21804
  } catch (error) {
21745
- p10.log.error(error instanceof Error ? error.message : String(error));
21746
- p10.log.info(
21805
+ p11.log.error(error instanceof Error ? error.message : String(error));
21806
+ p11.log.info(
21747
21807
  `Schema JSON was kept. Re-run \`betterstart generate ${selectedSchemaName}${options.skipMigration ? " --skip-migration" : ""}\` after resolving the issue.`
21748
21808
  );
21749
21809
  process.exit(1);
@@ -21753,7 +21813,7 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
21753
21813
  // adapters/next/commands/create.ts
21754
21814
  import fs25 from "fs";
21755
21815
  import path31 from "path";
21756
- import * as p11 from "@clack/prompts";
21816
+ import * as p12 from "@clack/prompts";
21757
21817
  var CREATE_PROMPT_CONTEXT = {
21758
21818
  cancelMessage: "Create schema cancelled."
21759
21819
  };
@@ -21944,7 +22004,7 @@ async function promptTabSlotFields(kind, schemasDir, titleField) {
21944
22004
  );
21945
22005
  if (!addField) {
21946
22006
  if (!hasFields) {
21947
- p11.log.warn("Tabs need at least one child field.");
22007
+ p12.log.warn("Tabs need at least one child field.");
21948
22008
  continue;
21949
22009
  }
21950
22010
  return { main, sidebar };
@@ -21992,7 +22052,7 @@ async function promptSchemaTab(kind, schemasDir, titleField, existingTabs) {
21992
22052
  while (fields.length === 0) {
21993
22053
  await promptAdditionalSchemaFields(kind, schemasDir, fields);
21994
22054
  if (fields.length === 0) {
21995
- p11.log.warn("Tabs need at least one child field.");
22055
+ p12.log.warn("Tabs need at least one child field.");
21996
22056
  }
21997
22057
  }
21998
22058
  }
@@ -22082,7 +22142,7 @@ async function promptFormSubmissionColumns(schema) {
22082
22142
  }
22083
22143
  const existingColumnNames = schema.columns ? new Set(schema.columns.map((column) => column.accessorKey)) : void 0;
22084
22144
  const initialValues = existingColumnNames ? fields.filter((field) => existingColumnNames.has(field.name)).map((field) => field.name) : fields.map((field) => field.name);
22085
- const selected = await p11.multiselect({
22145
+ const selected = await p12.multiselect({
22086
22146
  message: "Submission table columns",
22087
22147
  options: fields.map((field) => ({
22088
22148
  value: field.name,
@@ -22091,7 +22151,7 @@ async function promptFormSubmissionColumns(schema) {
22091
22151
  initialValues,
22092
22152
  required: false
22093
22153
  });
22094
- if (p11.isCancel(selected)) {
22154
+ if (p12.isCancel(selected)) {
22095
22155
  cancel2(CREATE_PROMPT_CONTEXT);
22096
22156
  }
22097
22157
  const selectedNames = new Set(selected);
@@ -22151,7 +22211,7 @@ function schemaFilePath(kind, schemasDir, schemaName) {
22151
22211
  return kind === "form" ? path31.join(schemasDir, "forms", `${schemaName}.json`) : path31.join(schemasDir, `${schemaName}.json`);
22152
22212
  }
22153
22213
  function printPreview2(loaded, cwd) {
22154
- p11.note(
22214
+ p12.note(
22155
22215
  `schema: ${loaded.name} (${loaded.kind})
22156
22216
  path: ${path31.relative(cwd, loaded.filePath)}
22157
22217
  owner: user
@@ -22204,7 +22264,7 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
22204
22264
  }
22205
22265
  fs25.mkdirSync(path31.dirname(filePath), { recursive: true });
22206
22266
  writeAuthoredGeneratedSchema(loaded);
22207
- p11.log.success(`Created ${path31.relative(cwd, filePath)}`);
22267
+ p12.log.success(`Created ${path31.relative(cwd, filePath)}`);
22208
22268
  try {
22209
22269
  await runGenerateCommand(metadata.name, {
22210
22270
  force: false,
@@ -22215,8 +22275,8 @@ ${validationErrors.map((error) => ` - ${error}`).join("\n")}`
22215
22275
  cwd
22216
22276
  });
22217
22277
  } catch (error) {
22218
- p11.log.error(error instanceof Error ? error.message : String(error));
22219
- p11.log.info(
22278
+ p12.log.error(error instanceof Error ? error.message : String(error));
22279
+ p12.log.info(
22220
22280
  `Schema JSON was kept. Re-run \`betterstart generate ${metadata.name}${options.skipMigration ? " --skip-migration" : ""}\` after resolving the issue.`
22221
22281
  );
22222
22282
  process.exit(1);
@@ -22228,14 +22288,14 @@ import { execFileSync as execFileSync5, spawn as spawn6 } from "child_process";
22228
22288
  import fs41 from "fs";
22229
22289
  import path52 from "path";
22230
22290
  import { PassThrough } from "stream";
22231
- import * as p24 from "@clack/prompts";
22291
+ import * as p25 from "@clack/prompts";
22232
22292
 
22233
22293
  // core-engine/utils/cancel-guard.ts
22234
- import * as p12 from "@clack/prompts";
22294
+ import * as p13 from "@clack/prompts";
22235
22295
  function installSetupCancelGuard() {
22236
22296
  const onSignal = () => {
22237
22297
  if (!hasActiveSpinner()) {
22238
- p12.cancel("Setup cancelled.");
22298
+ p13.cancel("Setup cancelled.");
22239
22299
  }
22240
22300
  process.exit(0);
22241
22301
  };
@@ -22290,11 +22350,11 @@ function redactSecrets(text7) {
22290
22350
 
22291
22351
  // adapters/next/init/prompts/database.ts
22292
22352
  import { execFileSync as execFileSync4 } from "child_process";
22293
- import * as p13 from "@clack/prompts";
22353
+ import * as p14 from "@clack/prompts";
22294
22354
  import pc from "picocolors";
22295
22355
  var VERCEL_NEON_URL = "https://vercel.com/dashboard/integrations/checkout/neon";
22296
22356
  async function promptServices() {
22297
- const choice = await p13.select({
22357
+ const choice = await p14.select({
22298
22358
  message: "Connect a PostgreSQL Database",
22299
22359
  options: [
22300
22360
  {
@@ -22315,8 +22375,8 @@ async function promptServices() {
22315
22375
  ],
22316
22376
  initialValue: "vercel"
22317
22377
  });
22318
- if (p13.isCancel(choice)) {
22319
- p13.cancel("Setup cancelled.");
22378
+ if (p14.isCancel(choice)) {
22379
+ p14.cancel("Setup cancelled.");
22320
22380
  process.exit(0);
22321
22381
  }
22322
22382
  if (choice === "vercel") {
@@ -22330,7 +22390,7 @@ async function promptServices() {
22330
22390
  }
22331
22391
  function openBrowserVercelNeon() {
22332
22392
  openBrowser(VERCEL_NEON_URL);
22333
- p13.log.info(
22393
+ p14.log.info(
22334
22394
  `Opening Vercel... Create a Neon Postgres database, then copy the ${pc.cyan("DATABASE_URL")} from the dashboard.`
22335
22395
  );
22336
22396
  }
@@ -22340,12 +22400,12 @@ function openBrowserVercelNeonResource(url) {
22340
22400
  return;
22341
22401
  }
22342
22402
  openBrowser(url);
22343
- p13.log.info(
22403
+ p14.log.info(
22344
22404
  `Opening Vercel... Copy the Neon ${pc.cyan("DATABASE_URL")} from the database dashboard, then paste it below.`
22345
22405
  );
22346
22406
  }
22347
22407
  async function promptConnectionString() {
22348
- const input = await p13.text({
22408
+ const input = await p14.text({
22349
22409
  message: "Paste your PostgreSQL connection string",
22350
22410
  placeholder: "postgres://user:pass@host/db",
22351
22411
  validate(val) {
@@ -22359,8 +22419,8 @@ async function promptConnectionString() {
22359
22419
  }
22360
22420
  }
22361
22421
  });
22362
- if (p13.isCancel(input)) {
22363
- p13.cancel("Setup cancelled.");
22422
+ if (p14.isCancel(input)) {
22423
+ p14.cancel("Setup cancelled.");
22364
22424
  process.exit(0);
22365
22425
  }
22366
22426
  return input.replace(/^['"]|['"]$/g, "").trim();
@@ -22380,7 +22440,7 @@ function openBrowser(url) {
22380
22440
  }
22381
22441
 
22382
22442
  // adapters/next/init/prompts/presets.ts
22383
- import * as p14 from "@clack/prompts";
22443
+ import * as p15 from "@clack/prompts";
22384
22444
 
22385
22445
  // adapters/next/init/scaffolders/env.ts
22386
22446
  import crypto2 from "crypto";
@@ -22545,7 +22605,7 @@ async function promptPresets(cwd, options = {}) {
22545
22605
  overwriteKeys.add(key);
22546
22606
  }
22547
22607
  };
22548
- const storage = await p14.select({
22608
+ const storage = await p15.select({
22549
22609
  message: "Choose a file storage",
22550
22610
  options: [
22551
22611
  {
@@ -22569,8 +22629,8 @@ async function promptPresets(cwd, options = {}) {
22569
22629
  ],
22570
22630
  initialValue: "vercel-blob"
22571
22631
  });
22572
- if (p14.isCancel(storage)) {
22573
- p14.cancel("Setup cancelled.");
22632
+ if (p15.isCancel(storage)) {
22633
+ p15.cancel("Setup cancelled.");
22574
22634
  process.exit(0);
22575
22635
  }
22576
22636
  if (storage === "r2") {
@@ -22580,7 +22640,7 @@ async function promptPresets(cwd, options = {}) {
22580
22640
  if (flow?.ok && flow.config) {
22581
22641
  mergeIntegrationConfig(flow.config);
22582
22642
  } else if (flow) {
22583
- p14.log.warn(
22643
+ p15.log.warn(
22584
22644
  "Continuing without Railway bucket credentials \u2014 rerun betterstart add --integration railway-bucket after fixing Railway access."
22585
22645
  );
22586
22646
  } else {
@@ -22597,7 +22657,7 @@ async function promptPresets(cwd, options = {}) {
22597
22657
  });
22598
22658
  overwriteKeys.add("BLOB_READ_WRITE_TOKEN");
22599
22659
  } else if (flow) {
22600
- p14.log.warn(
22660
+ p15.log.warn(
22601
22661
  "Continuing without a Blob token \u2014 add BLOB_READ_WRITE_TOKEN to .env.local from the store on vercel.com/dashboard/stores."
22602
22662
  );
22603
22663
  sections.push({
@@ -22606,7 +22666,7 @@ async function promptPresets(cwd, options = {}) {
22606
22666
  });
22607
22667
  } else {
22608
22668
  if (existingToken) {
22609
- p14.log.info(
22669
+ p15.log.info(
22610
22670
  `Using the existing BLOB_READ_WRITE_TOKEN from .env.local ${pc2.dim(
22611
22671
  `(${maskBlobToken(existingToken)})`
22612
22672
  )}`
@@ -22615,7 +22675,7 @@ async function promptPresets(cwd, options = {}) {
22615
22675
  mergeIntegrationConfig(await collectIntegrationConfig(cwd, ["vercel-blob"]));
22616
22676
  }
22617
22677
  }
22618
- const selectedPresets = await p14.multiselect({
22678
+ const selectedPresets = await p15.multiselect({
22619
22679
  message: "Select presets",
22620
22680
  options: [
22621
22681
  {
@@ -22627,8 +22687,8 @@ async function promptPresets(cwd, options = {}) {
22627
22687
  required: false,
22628
22688
  initialValues: ["blog"]
22629
22689
  });
22630
- if (p14.isCancel(selectedPresets)) {
22631
- p14.cancel("Setup cancelled.");
22690
+ if (p15.isCancel(selectedPresets)) {
22691
+ p15.cancel("Setup cancelled.");
22632
22692
  process.exit(0);
22633
22693
  }
22634
22694
  const integrations = [];
@@ -22655,9 +22715,9 @@ async function promptPresets(cwd, options = {}) {
22655
22715
  }
22656
22716
 
22657
22717
  // adapters/next/init/prompts/project.ts
22658
- import * as p15 from "@clack/prompts";
22718
+ import * as p16 from "@clack/prompts";
22659
22719
  async function promptProject(defaultName) {
22660
- const projectName = await p15.text({
22720
+ const projectName = await p16.text({
22661
22721
  message: "What is your project named?",
22662
22722
  placeholder: defaultName ?? "(Press Enter to use default)",
22663
22723
  defaultValue: defaultName ?? ".",
@@ -22670,15 +22730,15 @@ async function promptProject(defaultName) {
22670
22730
  return void 0;
22671
22731
  }
22672
22732
  });
22673
- if (p15.isCancel(projectName)) {
22674
- p15.cancel("Setup cancelled.");
22733
+ if (p16.isCancel(projectName)) {
22734
+ p16.cancel("Setup cancelled.");
22675
22735
  process.exit(0);
22676
22736
  }
22677
22737
  return { projectName: projectName.trim() || "." };
22678
22738
  }
22679
22739
 
22680
22740
  // adapters/next/init/providers.ts
22681
- import * as p16 from "@clack/prompts";
22741
+ import * as p17 from "@clack/prompts";
22682
22742
  var DATABASE_PROVIDERS = ["vercel", "railway", "manual"];
22683
22743
  var STORAGE_PROVIDERS = ["vercel-blob", "railway-bucket", "r2", "local"];
22684
22744
  var DEPLOY_PROVIDERS = ["vercel", "railway", "none"];
@@ -22735,7 +22795,7 @@ function validateResolvedDatabaseProvider(provider, options) {
22735
22795
  }
22736
22796
  }
22737
22797
  async function promptDeployProvider(initialValue = "none") {
22738
- const provider = await p16.select({
22798
+ const provider = await p17.select({
22739
22799
  message: "Deploy this project",
22740
22800
  options: [
22741
22801
  {
@@ -22753,8 +22813,8 @@ async function promptDeployProvider(initialValue = "none") {
22753
22813
  ],
22754
22814
  initialValue
22755
22815
  });
22756
- if (p16.isCancel(provider)) {
22757
- p16.cancel("Setup cancelled.");
22816
+ if (p17.isCancel(provider)) {
22817
+ p17.cancel("Setup cancelled.");
22758
22818
  process.exit(0);
22759
22819
  }
22760
22820
  return provider;
@@ -22763,7 +22823,7 @@ async function promptDeployProvider(initialValue = "none") {
22763
22823
  // adapters/next/init/railway/deploy.ts
22764
22824
  import fs28 from "fs";
22765
22825
  import path34 from "path";
22766
- import * as p18 from "@clack/prompts";
22826
+ import * as p19 from "@clack/prompts";
22767
22827
 
22768
22828
  // adapters/next/init/deploy/guard.ts
22769
22829
  import { spawn as spawn3 } from "child_process";
@@ -22860,7 +22920,7 @@ function guardBetterstartConfig(cwd, restores) {
22860
22920
  }
22861
22921
 
22862
22922
  // adapters/next/init/railway/project.ts
22863
- import * as p17 from "@clack/prompts";
22923
+ import * as p18 from "@clack/prompts";
22864
22924
 
22865
22925
  // adapters/next/init/railway/runner.ts
22866
22926
  import { spawn as spawn4 } from "child_process";
@@ -23144,15 +23204,15 @@ async function ensureRailwayProject(runner, options) {
23144
23204
  createWorkspace = options.workspaces[0]?.id;
23145
23205
  } else if (!createWorkspace && options.interactive && options.workspaces?.length) {
23146
23206
  projectSpinner.clear();
23147
- const workspace = await p17.select({
23207
+ const workspace = await p18.select({
23148
23208
  message: "Choose a Railway workspace",
23149
23209
  options: options.workspaces.map((candidate) => ({
23150
23210
  value: candidate.id,
23151
23211
  label: candidate.name
23152
23212
  }))
23153
23213
  });
23154
- if (p17.isCancel(workspace)) {
23155
- p17.cancel("Setup cancelled.");
23214
+ if (p18.isCancel(workspace)) {
23215
+ p18.cancel("Setup cancelled.");
23156
23216
  process.exit(0);
23157
23217
  }
23158
23218
  createWorkspace = workspace;
@@ -23678,7 +23738,7 @@ async function runRailwayDeployFlow(options) {
23678
23738
  );
23679
23739
  envSpinner.clear();
23680
23740
  for (const key of sync.failed) {
23681
- p18.log.warn(`Could not set ${pc4.cyan(key)} on Railway.`);
23741
+ p19.log.warn(`Could not set ${pc4.cyan(key)} on Railway.`);
23682
23742
  }
23683
23743
  if (sync.failed.length > 0) {
23684
23744
  return {
@@ -23693,12 +23753,12 @@ async function runRailwayDeployFlow(options) {
23693
23753
  const packageGuard = await guardProjectForDeploy(options.cwd);
23694
23754
  guardSpinner.clear();
23695
23755
  if (packageGuard.lockfile === "failed") {
23696
- p18.log.warn(
23756
+ p19.log.warn(
23697
23757
  "Could not refresh pnpm-lock.yaml after removing betterstart-cli \u2014 the remote install may fail."
23698
23758
  );
23699
23759
  }
23700
23760
  for (const dependency of packageGuard.localSpecDeps) {
23701
- p18.log.warn(
23761
+ p19.log.warn(
23702
23762
  `Dependency ${pc4.cyan(dependency)} uses a local spec that cannot install on Railway.`
23703
23763
  );
23704
23764
  }
@@ -23751,7 +23811,7 @@ ${deploy.stderr}`) ?? deploy.errorMessage
23751
23811
  }
23752
23812
 
23753
23813
  // adapters/next/init/railway/auth.ts
23754
- import * as p19 from "@clack/prompts";
23814
+ import * as p20 from "@clack/prompts";
23755
23815
  import pc5 from "picocolors";
23756
23816
  var WHOAMI_TIMEOUT_MS = 3e4;
23757
23817
  var LOGIN_TIMEOUT_MS = 3e5;
@@ -23821,7 +23881,7 @@ async function ensureRailwayAuth(runner, cwd, options) {
23821
23881
  return { authed: false, reason: existing.reason };
23822
23882
  }
23823
23883
  checkSpinner.clear();
23824
- p19.log.info(
23884
+ p20.log.info(
23825
23885
  "Sign in to Railway to continue. Railway will open your browser or show a device code."
23826
23886
  );
23827
23887
  const login = await runRailway(runner, ["login"], {
@@ -25708,11 +25768,11 @@ function scaffoldTsconfig(cwd, config) {
25708
25768
  }
25709
25769
 
25710
25770
  // adapters/next/init/vercel/flow.ts
25711
- import * as p23 from "@clack/prompts";
25771
+ import * as p24 from "@clack/prompts";
25712
25772
  import pc9 from "picocolors";
25713
25773
 
25714
25774
  // adapters/next/init/vercel/auth.ts
25715
- import * as p20 from "@clack/prompts";
25775
+ import * as p21 from "@clack/prompts";
25716
25776
  import pc6 from "picocolors";
25717
25777
 
25718
25778
  // adapters/next/init/vercel/runner.ts
@@ -25956,7 +26016,7 @@ async function ensureVercelAuth(runner, cwd, options) {
25956
26016
  checkSpinner.clear();
25957
26017
  const signInMessage = `Sign in to Vercel to continue ${pc6.dim("(or press Ctrl-C to enter a connection string manually)")}`;
25958
26018
  const signInRows = clackLogRows(signInMessage);
25959
- p20.log.info(signInMessage);
26019
+ p21.log.info(signInMessage);
25960
26020
  let streamedRows = 0;
25961
26021
  const login = await runVercel(runner, ["login"], {
25962
26022
  cwd,
@@ -25988,7 +26048,7 @@ function signedInMessage(username) {
25988
26048
  }
25989
26049
 
25990
26050
  // adapters/next/init/vercel/blob.ts
25991
- import * as p21 from "@clack/prompts";
26051
+ import * as p22 from "@clack/prompts";
25992
26052
  import pc7 from "picocolors";
25993
26053
 
25994
26054
  // adapters/next/init/vercel/env-pull.ts
@@ -26230,7 +26290,7 @@ async function provisionBlobStoreInteractive(runner, cwd, options) {
26230
26290
  if (terminalFallbackRan) break;
26231
26291
  terminalFallbackRan = true;
26232
26292
  quietSpinner.clear();
26233
- p21.log.info(
26293
+ p22.log.info(
26234
26294
  `Create your Blob store in the Vercel prompts below ${pc7.dim(
26235
26295
  "(connect it to all environments)."
26236
26296
  )}`
@@ -26429,7 +26489,7 @@ function guardEnvLocal(cwd) {
26429
26489
  }
26430
26490
 
26431
26491
  // adapters/next/init/vercel/neon.ts
26432
- import * as p22 from "@clack/prompts";
26492
+ import * as p23 from "@clack/prompts";
26433
26493
  import pc8 from "picocolors";
26434
26494
  var PROVISION_TIMEOUT_MS2 = 18e4;
26435
26495
  var INTERACTIVE_PROVISION_TIMEOUT_MS2 = 6e5;
@@ -26448,7 +26508,7 @@ async function provisionNeonInteractive(runner, cwd, options) {
26448
26508
  termsResolved = true;
26449
26509
  quietSpinner.clear();
26450
26510
  eraseRows(termsNotice.rows);
26451
- p22.log.step(termsNotice.text);
26511
+ p23.log.step(termsNotice.text);
26452
26512
  };
26453
26513
  const quiet = await runVercel(runner, neonAddArgs(options), {
26454
26514
  cwd,
@@ -26467,7 +26527,7 @@ ${pc8.dim(termsUrl)}`,
26467
26527
  rows: clackLogRows(message) + clackLogRows(termsUrl) - 1
26468
26528
  };
26469
26529
  quietSpinner.clear();
26470
- p22.log.info(termsNotice.text);
26530
+ p23.log.info(termsNotice.text);
26471
26531
  quietSpinner.start("Waiting for the terms to be accepted");
26472
26532
  return;
26473
26533
  }
@@ -26483,7 +26543,7 @@ ${pc8.dim(termsUrl)}`,
26483
26543
  return readNeonProvisionInfo(quiet.stdout);
26484
26544
  }
26485
26545
  quietSpinner.clear();
26486
- p22.log.info(
26546
+ p23.log.info(
26487
26547
  `Create your Neon database in the Vercel prompts below ${pc8.dim(
26488
26548
  "(the Free plan is recommended)."
26489
26549
  )}`
@@ -26560,14 +26620,14 @@ async function runVercelNeonFlow(options) {
26560
26620
  allowLogin: options.interactive
26561
26621
  });
26562
26622
  if (!auth.authed) {
26563
- p23.log.warn(authFailureMessage(auth.reason));
26623
+ p24.log.warn(authFailureMessage(auth.reason));
26564
26624
  return { ok: false };
26565
26625
  }
26566
26626
  await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
26567
26627
  const neon = await provisionNeonForMode(runner, options);
26568
26628
  if (neon.failure) {
26569
- p23.log.warn(neonFailureMessage(neon.failure));
26570
- if (neon.detail) p23.log.message(pc9.dim(redactSecrets(neon.detail)));
26629
+ p24.log.warn(neonFailureMessage(neon.failure));
26630
+ if (neon.detail) p24.log.message(pc9.dim(redactSecrets(neon.detail)));
26571
26631
  return { ok: false };
26572
26632
  }
26573
26633
  const databaseUrl = await pullNeonDatabaseUrl(runner, options.cwd, env);
@@ -26580,7 +26640,7 @@ async function runVercelNeonFlow(options) {
26580
26640
  dismissSignedInNote
26581
26641
  };
26582
26642
  } catch (error) {
26583
- p23.log.warn(
26643
+ p24.log.warn(
26584
26644
  `Vercel provisioning failed: ${error instanceof Error ? error.message : String(error)}`
26585
26645
  );
26586
26646
  return { ok: false };
@@ -26602,14 +26662,14 @@ async function runVercelBlobFlow(options) {
26602
26662
  allowLogin: options.interactive
26603
26663
  });
26604
26664
  if (!auth.authed) {
26605
- p23.log.warn(authFailureMessage(auth.reason));
26665
+ p24.log.warn(authFailureMessage(auth.reason));
26606
26666
  return { ok: false };
26607
26667
  }
26608
26668
  await ensureLinkedProject(runner, options.cwd, options.projectName, env, auth.username);
26609
26669
  const blob = await provisionBlobForMode(runner, options);
26610
26670
  if (blob.failure || !blob.token) {
26611
- p23.log.warn(blobFailureMessage(blob.failure));
26612
- if (blob.detail) p23.log.message(pc9.dim(redactSecrets(blob.detail)));
26671
+ p24.log.warn(blobFailureMessage(blob.failure));
26672
+ if (blob.detail) p24.log.message(pc9.dim(redactSecrets(blob.detail)));
26613
26673
  return { ok: false };
26614
26674
  }
26615
26675
  return {
@@ -26618,7 +26678,7 @@ async function runVercelBlobFlow(options) {
26618
26678
  blobStoreName: blob.storeName
26619
26679
  };
26620
26680
  } catch (error) {
26621
- p23.log.warn(
26681
+ p24.log.warn(
26622
26682
  `Vercel provisioning failed: ${error instanceof Error ? error.message : String(error)}`
26623
26683
  );
26624
26684
  return { ok: false };
@@ -26640,7 +26700,7 @@ async function runVercelDeployFlow(options) {
26640
26700
  allowLogin: options.interactive ?? true
26641
26701
  });
26642
26702
  if (!auth.authed) {
26643
- p23.log.warn(authFailureMessage(auth.reason));
26703
+ p24.log.warn(authFailureMessage(auth.reason));
26644
26704
  printManualDeployHint();
26645
26705
  return { ok: false };
26646
26706
  }
@@ -26650,7 +26710,7 @@ async function runVercelDeployFlow(options) {
26650
26710
  const sync = await syncVercelProductionEnv(runner, options.cwd, env);
26651
26711
  envSpinner.clear();
26652
26712
  for (const key of sync.failed) {
26653
- p23.log.warn(
26713
+ p24.log.warn(
26654
26714
  `Could not set ${pc9.cyan(key)} on Vercel \u2014 add it in the project's environment settings.`
26655
26715
  );
26656
26716
  }
@@ -26660,12 +26720,12 @@ async function runVercelDeployFlow(options) {
26660
26720
  const packageGuard = await guardProjectForDeploy(options.cwd);
26661
26721
  guardSpinner.clear();
26662
26722
  if (packageGuard.lockfile === "failed") {
26663
- p23.log.warn(
26723
+ p24.log.warn(
26664
26724
  "Could not refresh pnpm-lock.yaml after removing betterstart-cli \u2014 the remote install may fail."
26665
26725
  );
26666
26726
  }
26667
26727
  for (const dep of packageGuard.localSpecDeps) {
26668
- p23.log.warn(
26728
+ p24.log.warn(
26669
26729
  `Dependency ${pc9.cyan(dep)} uses a local spec that cannot install on Vercel \u2014 the remote build may fail.`
26670
26730
  );
26671
26731
  }
@@ -26682,7 +26742,7 @@ async function runVercelDeployFlow(options) {
26682
26742
  }
26683
26743
  if (deploy.failure) {
26684
26744
  deploySpinner.stop(`${pc9.yellow("\u25B2")} ${deployFailureMessage(deploy.failure)}`);
26685
- if (deploy.detail) p23.log.message(pc9.dim(redactSecrets(deploy.detail)));
26745
+ if (deploy.detail) p24.log.message(pc9.dim(redactSecrets(deploy.detail)));
26686
26746
  printManualDeployHint();
26687
26747
  return { ok: false };
26688
26748
  }
@@ -26690,7 +26750,7 @@ async function runVercelDeployFlow(options) {
26690
26750
  deploySpinner.stop(url ? `Deployed ${pc9.cyan(url)}` : "Deployed to Vercel");
26691
26751
  return { ok: true, url, syncedEnvKeys: sync.synced };
26692
26752
  } catch (error) {
26693
- p23.log.warn(`Vercel deploy failed: ${error instanceof Error ? error.message : String(error)}`);
26753
+ p24.log.warn(`Vercel deploy failed: ${error instanceof Error ? error.message : String(error)}`);
26694
26754
  printManualDeployHint();
26695
26755
  return { ok: false };
26696
26756
  } finally {
@@ -26698,7 +26758,7 @@ async function runVercelDeployFlow(options) {
26698
26758
  }
26699
26759
  }
26700
26760
  function printManualDeployHint() {
26701
- p23.log.info(`You can deploy manually: ${pc9.cyan("vercel deploy --prod")}`);
26761
+ p24.log.info(`You can deploy manually: ${pc9.cyan("vercel deploy --prod")}`);
26702
26762
  }
26703
26763
  async function ensureLinkedProject(runner, cwd, projectName, env, scope) {
26704
26764
  if (readLinkedProjectId(cwd)) return;
@@ -27134,16 +27194,16 @@ function addVersionToBoxBottomBorder(box2, version2) {
27134
27194
  if (!bottomLine) {
27135
27195
  return box2;
27136
27196
  }
27137
- const leftCornerIndex = bottomLine.indexOf(p24.S_CORNER_BOTTOM_LEFT);
27138
- const rightCornerIndex = bottomLine.lastIndexOf(p24.S_CORNER_BOTTOM_RIGHT);
27197
+ const leftCornerIndex = bottomLine.indexOf(p25.S_CORNER_BOTTOM_LEFT);
27198
+ const rightCornerIndex = bottomLine.lastIndexOf(p25.S_CORNER_BOTTOM_RIGHT);
27139
27199
  const label = ` v${version2} `;
27140
- const borderWidth = rightCornerIndex - leftCornerIndex - p24.S_CORNER_BOTTOM_LEFT.length;
27200
+ const borderWidth = rightCornerIndex - leftCornerIndex - p25.S_CORNER_BOTTOM_LEFT.length;
27141
27201
  if (leftCornerIndex === -1 || rightCornerIndex === -1 || borderWidth < label.length) {
27142
27202
  return box2;
27143
27203
  }
27144
27204
  const leftBorderWidth = Math.floor((borderWidth - label.length) / 2);
27145
27205
  const rightBorderWidth = borderWidth - label.length - leftBorderWidth;
27146
- lines[bottomLineIndex] = `${bottomLine.slice(0, leftCornerIndex + p24.S_CORNER_BOTTOM_LEFT.length)}${p24.S_BAR_H.repeat(leftBorderWidth)}${label}${p24.S_BAR_H.repeat(rightBorderWidth)}${bottomLine.slice(rightCornerIndex)}`;
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)}`;
27147
27207
  return lines.join("\n");
27148
27208
  }
27149
27209
  function renderInitBanner() {
@@ -27153,7 +27213,7 @@ function renderInitBanner() {
27153
27213
  output.on("data", (chunk) => {
27154
27214
  box2 += chunk.toString();
27155
27215
  });
27156
- p24.box(
27216
+ p25.box(
27157
27217
  `
27158
27218
  \u2584 \u2597 \u2597 \u2584\u2596\u2597 \u2597
27159
27219
  \u2599\u2598\u2588\u258C\u259C\u2598\u259C\u2598\u2588\u258C\u259B\u2598\u259A \u259C\u2598\u2580\u258C\u259B\u2598\u259C\u2598
@@ -27249,7 +27309,7 @@ async function runInitCommand(name, options) {
27249
27309
  let restoreStdout;
27250
27310
  if (options.json) {
27251
27311
  if (!options.yes) {
27252
- p24.log.error("--json requires --yes.");
27312
+ p25.log.error("--json requires --yes.");
27253
27313
  process.exit(1);
27254
27314
  }
27255
27315
  restoreStdout = redirectStdoutToStderr();
@@ -27270,7 +27330,7 @@ async function runInitCommand(name, options) {
27270
27330
  }
27271
27331
  } catch (error) {
27272
27332
  disposeCancelGuard();
27273
- p24.log.error(error instanceof Error ? error.message : String(error));
27333
+ p25.log.error(error instanceof Error ? error.message : String(error));
27274
27334
  process.exit(1);
27275
27335
  }
27276
27336
  let cwd = process.cwd();
@@ -27281,7 +27341,7 @@ async function runInitCommand(name, options) {
27281
27341
  try {
27282
27342
  namespace = validateAdminNamespace(options.namespace);
27283
27343
  } catch (error) {
27284
- p24.log.error(error instanceof Error ? error.message : String(error));
27344
+ p25.log.error(error instanceof Error ? error.message : String(error));
27285
27345
  process.exit(1);
27286
27346
  }
27287
27347
  }
@@ -27290,13 +27350,13 @@ async function runInitCommand(name, options) {
27290
27350
  try {
27291
27351
  projectPrompt = options.yes ? resolveNonInteractiveProject(name) : await promptProject(name);
27292
27352
  } catch (error) {
27293
- p24.log.error(error instanceof Error ? error.message : String(error));
27353
+ p25.log.error(error instanceof Error ? error.message : String(error));
27294
27354
  process.exit(1);
27295
27355
  }
27296
27356
  }
27297
27357
  if (!options.yes && !options.namespace) {
27298
27358
  const defaultDashboardPath = resolveAdminNamespace(DEFAULT_ADMIN_NAMESPACE).routePath;
27299
- const namespaceInput = await p24.text({
27359
+ const namespaceInput = await p25.text({
27300
27360
  message: "Enter the dashboard path",
27301
27361
  placeholder: `eg. ${defaultDashboardPath}`,
27302
27362
  defaultValue: defaultDashboardPath,
@@ -27309,8 +27369,8 @@ async function runInitCommand(name, options) {
27309
27369
  }
27310
27370
  }
27311
27371
  });
27312
- if (p24.isCancel(namespaceInput)) {
27313
- p24.cancel("Setup cancelled.");
27372
+ if (p25.isCancel(namespaceInput)) {
27373
+ p25.cancel("Setup cancelled.");
27314
27374
  process.exit(0);
27315
27375
  }
27316
27376
  namespace = validateAdminDashboardPath(namespaceInput);
@@ -27322,13 +27382,13 @@ async function runInitCommand(name, options) {
27322
27382
  if (project2.isExisting) {
27323
27383
  srcDir = project2.hasSrcDir;
27324
27384
  if (!project2.hasTypeScript) {
27325
- p24.log.error("TypeScript is required. Please add a tsconfig.json first.");
27385
+ p25.log.error("TypeScript is required. Please add a tsconfig.json first.");
27326
27386
  process.exit(1);
27327
27387
  }
27328
27388
  if (forceMode) {
27329
27389
  const nuked = removeExistingAdminPaths(cwd, await resolveForceInitNamespaces(cwd, namespace));
27330
27390
  if (nuked > 0) {
27331
- p24.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27391
+ p25.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27332
27392
  }
27333
27393
  project2 = detectProject(cwd, namespace);
27334
27394
  } else if (project2.conflicts.length > 0) {
@@ -27337,14 +27397,14 @@ async function runInitCommand(name, options) {
27337
27397
  "",
27338
27398
  pc10.dim(`Use ${pc10.bold("--force")} to remove existing admin files before scaffolding.`)
27339
27399
  );
27340
- p24.note(conflictLines.join("\n"), pc10.yellow("Conflicts"));
27400
+ p25.note(conflictLines.join("\n"), pc10.yellow("Conflicts"));
27341
27401
  if (options.yes) {
27342
- p24.log.error(
27402
+ p25.log.error(
27343
27403
  "Can't continue with --yes while admin files conflict. Re-run with --force to remove them first."
27344
27404
  );
27345
27405
  process.exit(1);
27346
27406
  }
27347
- const proceed = await p24.confirm({
27407
+ const proceed = await p25.confirm({
27348
27408
  message: [
27349
27409
  `Continue with ${pc10.bold(pc10.cyan("--force"))}?`,
27350
27410
  `${pc10.cyan("\u2502")} ${pc10.dim("This will force overwrite the existing admin code.")}`,
@@ -27352,14 +27412,14 @@ async function runInitCommand(name, options) {
27352
27412
  ].join("\n"),
27353
27413
  initialValue: true
27354
27414
  });
27355
- if (p24.isCancel(proceed) || !proceed) {
27356
- p24.cancel("Setup cancelled.");
27415
+ if (p25.isCancel(proceed) || !proceed) {
27416
+ p25.cancel("Setup cancelled.");
27357
27417
  process.exit(0);
27358
27418
  }
27359
27419
  forceMode = true;
27360
27420
  const nuked = removeExistingAdminPaths(cwd, await resolveForceInitNamespaces(cwd, namespace));
27361
27421
  if (nuked > 0) {
27362
- p24.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27422
+ p25.log.warn(`${pc10.yellow("Force mode:")} removed ${nuked} existing admin paths`);
27363
27423
  }
27364
27424
  project2 = detectProject(cwd, namespace);
27365
27425
  }
@@ -27367,7 +27427,7 @@ async function runInitCommand(name, options) {
27367
27427
  const freshProject = projectPrompt;
27368
27428
  srcDir = false;
27369
27429
  if (!options.yes) {
27370
- const pmChoice = await p24.select({
27430
+ const pmChoice = await p25.select({
27371
27431
  message: "Which package manager do you want to use?",
27372
27432
  options: [
27373
27433
  { value: "pnpm", label: "pnpm", hint: "recommended" },
@@ -27375,8 +27435,8 @@ async function runInitCommand(name, options) {
27375
27435
  { value: "bun", label: "bun" }
27376
27436
  ]
27377
27437
  });
27378
- if (p24.isCancel(pmChoice)) {
27379
- p24.cancel("Setup cancelled.");
27438
+ if (p25.isCancel(pmChoice)) {
27439
+ p25.cancel("Setup cancelled.");
27380
27440
  process.exit(0);
27381
27441
  }
27382
27442
  pm = pmChoice;
@@ -27411,8 +27471,8 @@ async function runInitCommand(name, options) {
27411
27471
  process.stderr.write(`${createNextAppResult.output.trimEnd()}
27412
27472
  `);
27413
27473
  }
27414
- p24.log.error(createNextAppResult.error);
27415
- p24.log.info(
27474
+ p25.log.error(createNextAppResult.error);
27475
+ p25.log.info(
27416
27476
  `You can create the project manually:
27417
27477
  ${pc10.cyan(`npx create-next-app@latest ${freshProject.projectName} --typescript --tailwind --app`)}
27418
27478
  Then run ${pc10.cyan("betterstart init")} inside it.`
@@ -27426,11 +27486,11 @@ async function runInitCommand(name, options) {
27426
27486
  );
27427
27487
  if (!hasPackageJson || !hasNextConfig) {
27428
27488
  createNextAppSpinner.stop(`Failed to create Next.js app: ${displayName}`);
27429
- p24.log.error(
27489
+ p25.log.error(
27430
27490
  "create-next-app completed but the project was not created. This can happen with nested npx calls."
27431
27491
  );
27432
27492
  const manualCmd = `npx create-next-app@latest ${freshProject.projectName} --typescript --tailwind --app`;
27433
- p24.log.info(
27493
+ p25.log.info(
27434
27494
  `Create the project manually:
27435
27495
  ${pc10.cyan(manualCmd)}
27436
27496
  Then run ${pc10.cyan("betterstart init")} inside it.`
@@ -27479,13 +27539,13 @@ async function runInitCommand(name, options) {
27479
27539
  try {
27480
27540
  validateResolvedDatabaseProvider(databaseProvider, options);
27481
27541
  } catch (error) {
27482
- p24.log.error(error instanceof Error ? error.message : String(error));
27542
+ p25.log.error(error instanceof Error ? error.message : String(error));
27483
27543
  process.exit(1);
27484
27544
  }
27485
27545
  if (databaseProvider === "manual") {
27486
27546
  const candidate = options.databaseUrl ?? existingDbUrl ?? promptedManualUrl;
27487
27547
  if (candidate && !isValidDbUrl(candidate)) {
27488
- p24.log.error(
27548
+ p25.log.error(
27489
27549
  `Invalid database URL. Must start with ${pc10.cyan("postgres://")} or ${pc10.cyan("postgresql://")}`
27490
27550
  );
27491
27551
  process.exit(1);
@@ -27493,7 +27553,7 @@ async function runInitCommand(name, options) {
27493
27553
  if (candidate) {
27494
27554
  databaseUrl = candidate;
27495
27555
  if (existingDbUrl === candidate && !options.databaseUrl) {
27496
- p24.log.info(
27556
+ p25.log.info(
27497
27557
  `Using the existing DATABASE_URL from .env.local ${pc10.dim(`(${maskDbUrl(candidate)})`)}`
27498
27558
  );
27499
27559
  }
@@ -27513,7 +27573,7 @@ async function runInitCommand(name, options) {
27513
27573
  persistDatabaseUrl(cwd, databaseUrl);
27514
27574
  dismissVercelSignedInNote = flow.dismissSignedInNote;
27515
27575
  } else if (options.yes) {
27516
- p24.log.error(
27576
+ p25.log.error(
27517
27577
  flow.ok ? "Created a Neon database, but DATABASE_URL could not be retrieved from Vercel." : "Vercel database provisioning did not complete."
27518
27578
  );
27519
27579
  process.exit(1);
@@ -27522,7 +27582,7 @@ async function runInitCommand(name, options) {
27522
27582
  databaseUrl = await promptConnectionString();
27523
27583
  persistDatabaseUrl(cwd, databaseUrl);
27524
27584
  } else {
27525
- p24.log.info("Falling back to a manual database connection string.");
27585
+ p25.log.info("Falling back to a manual database connection string.");
27526
27586
  openBrowserVercelNeon();
27527
27587
  databaseUrl = await promptConnectionString();
27528
27588
  }
@@ -27536,11 +27596,11 @@ async function runInitCommand(name, options) {
27536
27596
  } catch (error) {
27537
27597
  const message = error instanceof Error ? error.message : String(error);
27538
27598
  if (options.yes) {
27539
- p24.log.error(`Railway database provisioning failed: ${message}`);
27599
+ p25.log.error(`Railway database provisioning failed: ${message}`);
27540
27600
  process.exit(1);
27541
27601
  }
27542
- p24.log.warn(`Railway database provisioning failed: ${message}`);
27543
- p24.log.info("Falling back to a manual database connection string.");
27602
+ p25.log.warn(`Railway database provisioning failed: ${message}`);
27603
+ p25.log.info("Falling back to a manual database connection string.");
27544
27604
  databaseUrl = await promptConnectionString();
27545
27605
  }
27546
27606
  }
@@ -27570,7 +27630,7 @@ async function runInitCommand(name, options) {
27570
27630
  return { ok: true, config: config2 };
27571
27631
  } catch (error) {
27572
27632
  const message = error instanceof Error ? error.message : String(error);
27573
- p24.log.warn(`Railway bucket provisioning failed: ${message}`);
27633
+ p25.log.warn(`Railway bucket provisioning failed: ${message}`);
27574
27634
  return { ok: false };
27575
27635
  }
27576
27636
  };
@@ -27584,7 +27644,7 @@ async function runInitCommand(name, options) {
27584
27644
  if (storage === "r2") {
27585
27645
  const missingR2Keys = R2_ENV_KEYS.filter((key) => !readEnvVar(cwd, key)?.trim());
27586
27646
  if (options.yes && missingR2Keys.length > 0) {
27587
- p24.log.error(
27647
+ p25.log.error(
27588
27648
  `Cloudflare R2 is missing required environment variables: ${missingR2Keys.join(", ")}.`
27589
27649
  );
27590
27650
  process.exit(1);
@@ -27598,7 +27658,7 @@ async function runInitCommand(name, options) {
27598
27658
  if (flow.ok && flow.config) {
27599
27659
  mergeCollectedIntegrationConfig(flow.config);
27600
27660
  } else if (options.yes) {
27601
- p24.log.error("Railway bucket provisioning did not complete.");
27661
+ p25.log.error("Railway bucket provisioning did not complete.");
27602
27662
  process.exit(1);
27603
27663
  }
27604
27664
  }
@@ -27617,10 +27677,10 @@ async function runInitCommand(name, options) {
27617
27677
  });
27618
27678
  collectedIntegrationConfig.overwriteKeys.add("BLOB_READ_WRITE_TOKEN");
27619
27679
  } else if (options.yes) {
27620
- p24.log.error("Vercel Blob provisioning did not complete.");
27680
+ p25.log.error("Vercel Blob provisioning did not complete.");
27621
27681
  process.exit(1);
27622
27682
  } else {
27623
- p24.log.warn(
27683
+ p25.log.warn(
27624
27684
  "Continuing without a Blob token \u2014 add BLOB_READ_WRITE_TOKEN to .env.local from the store on vercel.com/dashboard/stores."
27625
27685
  );
27626
27686
  collectedIntegrationConfig.sections.push({
@@ -27694,7 +27754,7 @@ async function runInitCommand(name, options) {
27694
27754
  const nextConfigResult = scaffoldNextConfig({ cwd, nextMajorVersion });
27695
27755
  s.clear();
27696
27756
  if (nextConfigResult.status === "unsupported") {
27697
- p24.log.warn("The Next.js config could not be updated automatically \u2014 review it manually.");
27757
+ p25.log.warn("The Next.js config could not be updated automatically \u2014 review it manually.");
27698
27758
  }
27699
27759
  const drizzleConfigPath = path52.join(cwd, "drizzle.config.ts");
27700
27760
  if (!dbFiles.includes("drizzle.config.ts") && fs41.existsSync(drizzleConfigPath)) {
@@ -27705,20 +27765,20 @@ async function runInitCommand(name, options) {
27705
27765
  readNamespacedTemplate("drizzle.config.ts", namespace),
27706
27766
  "utf-8"
27707
27767
  );
27708
- p24.log.success("Updated drizzle.config.ts");
27768
+ p25.log.success("Updated drizzle.config.ts");
27709
27769
  } else if (!options.yes) {
27710
- const overwrite = await p24.confirm({
27770
+ const overwrite = await p25.confirm({
27711
27771
  message: "drizzle.config.ts already exists. Overwrite with latest version?",
27712
27772
  initialValue: true
27713
27773
  });
27714
- if (!p24.isCancel(overwrite) && overwrite) {
27774
+ if (!p25.isCancel(overwrite) && overwrite) {
27715
27775
  const { readNamespacedTemplate } = await import("./template-reader-X6KFP7B3.js");
27716
27776
  fs41.writeFileSync(
27717
27777
  drizzleConfigPath,
27718
27778
  readNamespacedTemplate("drizzle.config.ts", namespace),
27719
27779
  "utf-8"
27720
27780
  );
27721
- p24.log.success("Updated drizzle.config.ts");
27781
+ p25.log.success("Updated drizzle.config.ts");
27722
27782
  }
27723
27783
  }
27724
27784
  }
@@ -27743,8 +27803,8 @@ async function runInitCommand(name, options) {
27743
27803
  s.stop("");
27744
27804
  } else {
27745
27805
  s.stop("Failed to install dependencies");
27746
- p24.log.warn(depsResult.error ?? "Unknown error");
27747
- p24.log.info(
27806
+ p25.log.warn(depsResult.error ?? "Unknown error");
27807
+ p25.log.info(
27748
27808
  `You can install them manually:
27749
27809
  ${pc10.cyan(`${pm} add ${depsResult.dependencies.join(" ")}`)}
27750
27810
  ${pc10.cyan(`${pm} add -D ${depsResult.devDeps.join(" ")}`)}`
@@ -27800,22 +27860,22 @@ async function runInitCommand(name, options) {
27800
27860
  writeConfigFile(cwd, resolvedIntegrationInstallResult.config);
27801
27861
  const usesLocalStorage = resolvedIntegrationInstallResult.config.storage.provider === "local";
27802
27862
  for (const err of coreSchemasResult.errors) {
27803
- p24.log.warn(`Core schemas: ${err}`);
27863
+ p25.log.warn(`Core schemas: ${err}`);
27804
27864
  }
27805
27865
  for (const warning of resolvedPresetInstallResult.warnings) {
27806
- p24.log.warn(warning);
27866
+ p25.log.warn(warning);
27807
27867
  }
27808
27868
  for (const warning of resolvedIntegrationInstallResult.warnings) {
27809
- p24.log.warn(warning);
27869
+ p25.log.warn(warning);
27810
27870
  }
27811
27871
  if (usesLocalStorage) {
27812
- p24.log.warn(
27872
+ p25.log.warn(
27813
27873
  "Local filesystem storage is only for development or self-hosted persistent-disk deployments. Use Vercel Blob, Railway Bucket, or Cloudflare R2 for hosted production."
27814
27874
  );
27815
27875
  }
27816
27876
  let dbPushed = false;
27817
27877
  if (depsResult.success && options.skipMigration && hasDbUrl(cwd)) {
27818
- p24.log.info(`Skipping database schema push ${pc10.dim("(--skip-migration)")}`);
27878
+ p25.log.info(`Skipping database schema push ${pc10.dim("(--skip-migration)")}`);
27819
27879
  } else if (depsResult.success && hasDbUrl(cwd)) {
27820
27880
  let driverReady = hasDrizzleKitPostgresDriverDependency(cwd);
27821
27881
  if (!driverReady) {
@@ -27830,8 +27890,8 @@ async function runInitCommand(name, options) {
27830
27890
  });
27831
27891
  if (!driverResult.success) {
27832
27892
  s.stop("Database push failed");
27833
- p24.log.warn(driverResult.error ?? `Failed to install ${DRIZZLE_KIT_POSTGRES_DRIVER_DEP}`);
27834
- p24.log.info(
27893
+ p25.log.warn(driverResult.error ?? `Failed to install ${DRIZZLE_KIT_POSTGRES_DRIVER_DEP}`);
27894
+ p25.log.info(
27835
27895
  `Install ${DRIZZLE_KIT_POSTGRES_DRIVER_DEP} manually, then run: ${pc10.cyan(drizzlePushCommand(pm))}`
27836
27896
  );
27837
27897
  } else {
@@ -27859,8 +27919,8 @@ async function runInitCommand(name, options) {
27859
27919
  const verification = await verifyDatabaseReachable(cwd);
27860
27920
  clearDbSpinner();
27861
27921
  if (!verification.success) {
27862
- p24.log.warn(verification.error);
27863
- p24.log.error("Database was not reachable. Aborting setup.");
27922
+ p25.log.warn(verification.error);
27923
+ p25.log.error("Database was not reachable. Aborting setup.");
27864
27924
  process.exit(1);
27865
27925
  }
27866
27926
  } else {
@@ -27873,20 +27933,21 @@ async function runInitCommand(name, options) {
27873
27933
  s.stop("Database push failed");
27874
27934
  }
27875
27935
  const pushError = pushResult.error ?? "Unknown error";
27876
- p24.log.warn(pushError);
27936
+ p25.log.warn(pushError);
27877
27937
  if (isDatabaseReachabilityError(pushError)) {
27878
- p24.log.error("Database was not reachable. Aborting setup.");
27938
+ p25.log.error("Database was not reachable. Aborting setup.");
27879
27939
  process.exit(1);
27880
27940
  }
27881
- p24.log.info(`You can run it manually: ${pc10.cyan(drizzlePushCommand(pm))}`);
27941
+ p25.log.info(`You can run it manually: ${pc10.cyan(drizzlePushCommand(pm))}`);
27882
27942
  }
27883
27943
  }
27884
27944
  }
27885
27945
  let seedEmail;
27946
+ let seedPassword;
27886
27947
  let seedSuccess = false;
27887
27948
  let adminAccountReady = false;
27888
27949
  if (dbPushed && options.skipAdminCreation) {
27889
- p24.log.info(
27950
+ p25.log.info(
27890
27951
  `Skipping admin user creation ${pc10.dim(`(use ${betterstartExecCommand(pm, "seed")} later)`)}`
27891
27952
  );
27892
27953
  }
@@ -27898,14 +27959,14 @@ async function runInitCommand(name, options) {
27898
27959
  const adminCheck = await checkExistingAdmin(cwd, adminDir, authBasePath);
27899
27960
  s.clear();
27900
27961
  if (adminCheck.error) {
27901
- p24.log.warn(`Could not verify existing admin account ${pc10.dim(`(${adminCheck.error})`)}`);
27962
+ p25.log.warn(`Could not verify existing admin account ${pc10.dim(`(${adminCheck.error})`)}`);
27902
27963
  if (isDatabaseReachabilityError(adminCheck.error)) {
27903
- p24.log.error("Database was not reachable. Aborting setup.");
27964
+ p25.log.error("Database was not reachable. Aborting setup.");
27904
27965
  process.exit(1);
27905
27966
  }
27906
27967
  } else if (adminCheck.existingAdmin) {
27907
27968
  const existingAdminLabel = formatAdminIdentity(adminCheck.existingAdmin);
27908
- const adminAction = await p24.select({
27969
+ const adminAction = await p25.select({
27909
27970
  message: "Found an already existing admin account. Do you want to replace it or skip?",
27910
27971
  options: [
27911
27972
  {
@@ -27919,28 +27980,28 @@ async function runInitCommand(name, options) {
27919
27980
  }
27920
27981
  ]
27921
27982
  });
27922
- if (p24.isCancel(adminAction)) {
27923
- p24.cancel("Setup cancelled.");
27983
+ if (p25.isCancel(adminAction)) {
27984
+ p25.cancel("Setup cancelled.");
27924
27985
  process.exit(0);
27925
27986
  }
27926
27987
  if (adminAction === "skip") {
27927
27988
  adminAccountReady = true;
27928
- p24.log.info(`Keeping existing admin account ${pc10.dim(`(${existingAdminLabel})`)}`);
27989
+ p25.log.info(`Keeping existing admin account ${pc10.dim(`(${existingAdminLabel})`)}`);
27929
27990
  } else {
27930
27991
  replaceExistingAdmin = true;
27931
27992
  }
27932
27993
  }
27933
27994
  if (!adminAccountReady) {
27934
- const credentials = await p24.group(
27995
+ const credentials = await p25.group(
27935
27996
  {
27936
- email: () => p24.text({
27997
+ email: () => p25.text({
27937
27998
  message: "Admin email",
27938
27999
  placeholder: "admin@example.com",
27939
28000
  validate: (v) => {
27940
28001
  if (!v || !v.includes("@")) return "Please enter a valid email";
27941
28002
  }
27942
28003
  }),
27943
- password: () => p24.password({
28004
+ password: () => p25.password({
27944
28005
  message: "Admin password",
27945
28006
  validate: (v) => {
27946
28007
  if (!v || v.length < 8) return "Password must be at least 8 characters";
@@ -27949,13 +28010,14 @@ async function runInitCommand(name, options) {
27949
28010
  },
27950
28011
  {
27951
28012
  onCancel: () => {
27952
- p24.cancel("Setup cancelled.");
28013
+ p25.cancel("Setup cancelled.");
27953
28014
  process.exit(0);
27954
28015
  }
27955
28016
  }
27956
28017
  );
27957
28018
  seedEmail = credentials.email;
27958
- const credentialPromptRows = clackPromptRows("Admin email", credentials.email) + clackPromptRows("Admin password", p24.S_PASSWORD_MASK.repeat(credentials.password.length));
28019
+ seedPassword = credentials.password;
28020
+ const credentialPromptRows = clackPromptRows("Admin email", credentials.email) + clackPromptRows("Admin password", p25.S_PASSWORD_MASK.repeat(credentials.password.length));
27959
28021
  let rowsBelowCredentialPrompts = 0;
27960
28022
  let seedOverwriteMode = replaceExistingAdmin ? "admin" : void 0;
27961
28023
  s.start(replaceExistingAdmin ? "Replacing admin user" : "Creating admin user");
@@ -27972,7 +28034,7 @@ async function runInitCommand(name, options) {
27972
28034
  s.stop(existingAccountMessage);
27973
28035
  rowsBelowCredentialPrompts += clackLogRows(existingAccountMessage);
27974
28036
  const replaceAccountMessage = "Replace the existing account with this email?";
27975
- const replace = await p24.confirm({
28037
+ const replace = await p25.confirm({
27976
28038
  message: replaceAccountMessage,
27977
28039
  initialValue: false
27978
28040
  });
@@ -27980,7 +28042,7 @@ async function runInitCommand(name, options) {
27980
28042
  replaceAccountMessage,
27981
28043
  replace === true ? "Yes" : "No"
27982
28044
  );
27983
- if (!p24.isCancel(replace) && replace) {
28045
+ if (!p25.isCancel(replace) && replace) {
27984
28046
  seedOverwriteMode = "email";
27985
28047
  s.start("Replacing admin user");
27986
28048
  seedResult = await runSeed(
@@ -28002,14 +28064,14 @@ async function runInitCommand(name, options) {
28002
28064
  adminAccountReady = true;
28003
28065
  } else if (seedResult.error) {
28004
28066
  s.stop(`Failed to create admin user`);
28005
- p24.note(
28067
+ p25.note(
28006
28068
  `${pc10.red(seedResult.error)}
28007
28069
 
28008
28070
  Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28009
28071
  pc10.red("Seed failed")
28010
28072
  );
28011
28073
  if (isDatabaseReachabilityError(seedResult.error)) {
28012
- p24.log.error("Database was not reachable. Aborting setup.");
28074
+ p25.log.error("Database was not reachable. Aborting setup.");
28013
28075
  process.exit(1);
28014
28076
  }
28015
28077
  }
@@ -28051,10 +28113,10 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28051
28113
  deployedUrl = deployFlow.url;
28052
28114
  if (!deployFlow.ok) {
28053
28115
  if (options.yes) {
28054
- p24.log.error("Vercel deploy did not complete.");
28116
+ p25.log.error("Vercel deploy did not complete.");
28055
28117
  process.exit(1);
28056
28118
  }
28057
- p24.log.warn("Vercel deploy did not complete; continuing.");
28119
+ p25.log.warn("Vercel deploy did not complete; continuing.");
28058
28120
  }
28059
28121
  } else if (deployProvider === "railway") {
28060
28122
  try {
@@ -28072,36 +28134,34 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28072
28134
  });
28073
28135
  deployedUrl = deployFlow.url;
28074
28136
  if (!deployFlow.ok) {
28075
- if (deployFlow.detail) p24.log.message(pc10.dim(redactSecrets(deployFlow.detail)));
28137
+ if (deployFlow.detail) p25.log.message(pc10.dim(redactSecrets(deployFlow.detail)));
28076
28138
  if (options.yes) {
28077
- p24.log.error("Railway deploy did not complete.");
28139
+ p25.log.error("Railway deploy did not complete.");
28078
28140
  process.exit(1);
28079
28141
  }
28080
- p24.log.warn("Railway deploy did not complete; continuing.");
28142
+ p25.log.warn("Railway deploy did not complete; continuing.");
28081
28143
  }
28082
28144
  } catch (error) {
28083
28145
  const message = error instanceof Error ? error.message : String(error);
28084
28146
  if (options.yes) {
28085
- p24.log.error(`Railway deploy failed: ${message}`);
28147
+ p25.log.error(`Railway deploy failed: ${message}`);
28086
28148
  process.exit(1);
28087
28149
  }
28088
- p24.log.warn(`Railway deploy failed: ${message}`);
28150
+ p25.log.warn(`Railway deploy failed: ${message}`);
28089
28151
  }
28090
28152
  }
28091
28153
  if (!options.yes && !options.skipDevServerStart) {
28092
28154
  const devCmd = runCommand(pm, "dev");
28093
- const startDev = await p24.confirm({
28155
+ const startDev = await p25.confirm({
28094
28156
  message: "Start the development server?",
28095
28157
  initialValue: true
28096
28158
  });
28097
- if (!p24.isCancel(startDev) && startDev) {
28159
+ if (!p25.isCancel(startDev) && startDev) {
28098
28160
  disposeCancelGuard();
28099
- await startManagedDevServer(
28100
- cwd,
28101
- devCmd,
28102
- adminLoginUrl,
28103
- seedSuccess && seedEmail ? seedEmail : void 0
28104
- );
28161
+ await startManagedDevServer(cwd, devCmd, adminLoginUrl, {
28162
+ email: seedSuccess && seedEmail ? seedEmail : void 0,
28163
+ password: seedSuccess && seedPassword ? seedPassword : void 0
28164
+ });
28105
28165
  return;
28106
28166
  }
28107
28167
  }
@@ -28128,7 +28188,7 @@ Run manually: ${pc10.cyan(betterstartExecCommand(pm, "seed"))}`,
28128
28188
  );
28129
28189
  return;
28130
28190
  }
28131
- p24.outro(`Admin ready at ${adminNamespace.routePath}`);
28191
+ p25.outro(`Admin ready at ${adminNamespace.routePath}`);
28132
28192
  }
28133
28193
  function isValidDbUrl(url) {
28134
28194
  return url.startsWith("postgres://") || url.startsWith("postgresql://");
@@ -28515,10 +28575,13 @@ function stripAnsi2(value) {
28515
28575
  }
28516
28576
  function printAdminReadyNote(state) {
28517
28577
  const lines = [`Admin: ${pc10.cyan(state.adminLoginUrl)}`];
28518
- if (state.adminEmail) {
28578
+ if (state.adminEmail && state.adminPassword) {
28579
+ lines.unshift(`Password: ${pc10.cyan(state.adminPassword)}`);
28580
+ lines.unshift(`Admin user: ${pc10.cyan(state.adminEmail)}`);
28581
+ } else if (state.adminEmail) {
28519
28582
  lines.unshift(`Admin user: ${pc10.cyan(state.adminEmail)}`);
28520
28583
  }
28521
- p24.note(lines.join("\n"), "Admin ready");
28584
+ p25.note(lines.join("\n"), "Admin ready");
28522
28585
  }
28523
28586
  function shouldSuppressDevServerStartupLine(line) {
28524
28587
  const plain = stripAnsi2(line).trim();
@@ -28581,7 +28644,7 @@ function pipeManagedDevServerStream(stream, target, state) {
28581
28644
  flushBuffer(true);
28582
28645
  });
28583
28646
  }
28584
- function startManagedDevServer(cwd, devCmd, adminLoginUrl, adminEmail) {
28647
+ function startManagedDevServer(cwd, devCmd, adminLoginUrl, adminCredentials) {
28585
28648
  return new Promise((resolve, reject) => {
28586
28649
  const [bin, ...args] = devCmd.split(" ");
28587
28650
  const child = spawn6(bin, args, {
@@ -28592,7 +28655,8 @@ function startManagedDevServer(cwd, devCmd, adminLoginUrl, adminEmail) {
28592
28655
  suppressStartup: true,
28593
28656
  readyLogged: false,
28594
28657
  adminLoginUrl,
28595
- adminEmail
28658
+ adminEmail: adminCredentials?.email,
28659
+ adminPassword: adminCredentials?.password
28596
28660
  };
28597
28661
  const forwardSignal = (signal) => {
28598
28662
  if (!child.killed) {
@@ -28629,7 +28693,7 @@ function startManagedDevServer(cwd, devCmd, adminLoginUrl, adminEmail) {
28629
28693
 
28630
28694
  // adapters/next/commands/list-integrations.ts
28631
28695
  import path53 from "path";
28632
- import * as p25 from "@clack/prompts";
28696
+ import * as p26 from "@clack/prompts";
28633
28697
 
28634
28698
  // core-engine/utils/table.ts
28635
28699
  function renderTableRows(rows) {
@@ -28676,15 +28740,15 @@ async function runListIntegrationsCommand(options) {
28676
28740
  integration.kind,
28677
28741
  integration.description
28678
28742
  ]);
28679
- p25.note(renderTableRows(rows).join("\n"), "BetterStart integrations");
28680
- p25.outro(
28743
+ p26.note(renderTableRows(rows).join("\n"), "BetterStart integrations");
28744
+ p26.outro(
28681
28745
  `${installedIntegrations.size} installed, ${rows.length - installedIntegrations.size} available`
28682
28746
  );
28683
28747
  }
28684
28748
 
28685
28749
  // adapters/next/commands/list-presets.ts
28686
28750
  import path54 from "path";
28687
- import * as p26 from "@clack/prompts";
28751
+ import * as p27 from "@clack/prompts";
28688
28752
  async function runListPresetsCommand(options) {
28689
28753
  const cwd = options.cwd ? path54.resolve(options.cwd) : process.cwd();
28690
28754
  if (options.json) {
@@ -28714,34 +28778,34 @@ async function runListPresetsCommand(options) {
28714
28778
  preset.kind,
28715
28779
  preset.description
28716
28780
  ]);
28717
- p26.note(renderTableRows(rows).join("\n"), "BetterStart presets");
28718
- p26.outro(`${installedPresets.size} installed, ${rows.length - installedPresets.size} available`);
28781
+ p27.note(renderTableRows(rows).join("\n"), "BetterStart presets");
28782
+ p27.outro(`${installedPresets.size} installed, ${rows.length - installedPresets.size} available`);
28719
28783
  }
28720
28784
 
28721
28785
  // adapters/next/commands/remove.ts
28722
28786
  import path55 from "path";
28723
- import * as p27 from "@clack/prompts";
28787
+ import * as p28 from "@clack/prompts";
28724
28788
  async function runRemoveCommand(items, options) {
28725
28789
  const removeIntegrationsMode = Boolean(options.integration);
28726
28790
  if (!removeIntegrationsMode && items.includes("core")) {
28727
- p27.log.error("The core Admin cannot be removed.");
28791
+ p28.log.error("The core Admin cannot be removed.");
28728
28792
  process.exit(1);
28729
28793
  }
28730
28794
  const presetIds = items.filter(isPresetId);
28731
28795
  const integrationIds = items.filter(isIntegrationId);
28732
28796
  if (!removeIntegrationsMode && integrationIds.length > 0) {
28733
- p27.log.error(
28797
+ p28.log.error(
28734
28798
  `Integration IDs require --integration. Run \`betterstart remove --integration ${integrationIds.join(" ")}\`.`
28735
28799
  );
28736
28800
  process.exit(1);
28737
28801
  }
28738
28802
  if (removeIntegrationsMode && presetIds.length > 0) {
28739
- p27.log.error(`Preset IDs cannot be removed with --integration: ${presetIds.join(", ")}`);
28803
+ p28.log.error(`Preset IDs cannot be removed with --integration: ${presetIds.join(", ")}`);
28740
28804
  process.exit(1);
28741
28805
  }
28742
28806
  const invalidItems = removeIntegrationsMode ? items.filter((integrationId) => !isIntegrationId(integrationId)) : items.filter((presetId) => !isPresetId(presetId));
28743
28807
  if (invalidItems.length > 0) {
28744
- p27.log.error(
28808
+ p28.log.error(
28745
28809
  removeIntegrationsMode ? formatUnknownIntegrationMessage(invalidItems) : formatUnknownPresetMessage(invalidItems)
28746
28810
  );
28747
28811
  process.exit(1);
@@ -28750,12 +28814,12 @@ async function runRemoveCommand(items, options) {
28750
28814
  const config = await resolveConfigOrExit(cwd);
28751
28815
  const pm = detectPackageManager(cwd);
28752
28816
  if (!options.force) {
28753
- const confirmed = await p27.confirm({
28817
+ const confirmed = await p28.confirm({
28754
28818
  message: `Remove ${removeIntegrationsMode ? "integration" : "preset"}${items.length === 1 ? "" : "s"} ${items.join(", ")}?`,
28755
28819
  initialValue: false
28756
28820
  });
28757
- if (p27.isCancel(confirmed) || !confirmed) {
28758
- p27.cancel(`${removeIntegrationsMode ? "Integration" : "Preset"} removal cancelled.`);
28821
+ if (p28.isCancel(confirmed) || !confirmed) {
28822
+ p28.cancel(`${removeIntegrationsMode ? "Integration" : "Preset"} removal cancelled.`);
28759
28823
  process.exit(0);
28760
28824
  }
28761
28825
  }
@@ -28768,13 +28832,13 @@ async function runRemoveCommand(items, options) {
28768
28832
  });
28769
28833
  writeConfigFile(cwd, result2.config);
28770
28834
  if (result2.removed.length === 0) {
28771
- p27.outro("No integrations were removed.");
28835
+ p28.outro("No integrations were removed.");
28772
28836
  return;
28773
28837
  }
28774
28838
  if (result2.warnings.length > 0) {
28775
- p27.note(result2.warnings.join("\n"), "Warnings");
28839
+ p28.note(result2.warnings.join("\n"), "Warnings");
28776
28840
  }
28777
- p27.outro(
28841
+ p28.outro(
28778
28842
  `Removed integration${result2.removed.length === 1 ? "" : "s"}: ${result2.removed.join(", ")}`
28779
28843
  );
28780
28844
  return;
@@ -28787,13 +28851,13 @@ async function runRemoveCommand(items, options) {
28787
28851
  });
28788
28852
  writeConfigFile(cwd, result.config);
28789
28853
  if (result.removed.length === 0) {
28790
- p27.outro("No presets were removed.");
28854
+ p28.outro("No presets were removed.");
28791
28855
  return;
28792
28856
  }
28793
28857
  if (result.warnings.length > 0) {
28794
- p27.note(result.warnings.join("\n"), "Warnings");
28858
+ p28.note(result.warnings.join("\n"), "Warnings");
28795
28859
  }
28796
- p27.outro(`Removed preset${result.removed.length === 1 ? "" : "s"}: ${result.removed.join(", ")}`);
28860
+ p28.outro(`Removed preset${result.removed.length === 1 ? "" : "s"}: ${result.removed.join(", ")}`);
28797
28861
  }
28798
28862
 
28799
28863
  // adapters/next/commands/remove-schema.ts
@@ -28936,7 +29000,7 @@ Schema JSON preserved.`
28936
29000
  // adapters/next/commands/uninstall.ts
28937
29001
  import fs44 from "fs";
28938
29002
  import path57 from "path";
28939
- import * as p28 from "@clack/prompts";
29003
+ import * as p29 from "@clack/prompts";
28940
29004
  import pc11 from "picocolors";
28941
29005
 
28942
29006
  // adapters/next/commands/uninstall-cleaners.ts
@@ -29158,8 +29222,8 @@ function buildUninstallPlan(cwd, namespaceValue) {
29158
29222
  count: configFiles.length,
29159
29223
  unit: configFiles.length === 1 ? "file" : "files",
29160
29224
  execute() {
29161
- for (const p30 of configPaths) {
29162
- if (fs44.existsSync(p30)) fs44.unlinkSync(p30);
29225
+ for (const p31 of configPaths) {
29226
+ if (fs44.existsSync(p31)) fs44.unlinkSync(p31);
29163
29227
  }
29164
29228
  }
29165
29229
  });
@@ -29223,7 +29287,7 @@ function buildUninstallPlan(cwd, namespaceValue) {
29223
29287
  }
29224
29288
  async function runUninstallCommand(options) {
29225
29289
  const cwd = options.cwd ? path57.resolve(options.cwd) : process.cwd();
29226
- p28.intro(pc11.bgRed(pc11.white(" BetterStart Uninstall ")));
29290
+ p29.intro(pc11.bgRed(pc11.white(" BetterStart Uninstall ")));
29227
29291
  let namespace = DEFAULT_ADMIN_NAMESPACE;
29228
29292
  try {
29229
29293
  const config = await resolveConfig(cwd);
@@ -29232,8 +29296,8 @@ async function runUninstallCommand(options) {
29232
29296
  }
29233
29297
  const steps = buildUninstallPlan(cwd, namespace);
29234
29298
  if (steps.length === 0) {
29235
- p28.log.success(`${pc11.green("\u2713")} Nothing to remove \u2014 project is already clean.`);
29236
- p28.outro("Project already clean");
29299
+ p29.log.success(`${pc11.green("\u2713")} Nothing to remove \u2014 project is already clean.`);
29300
+ p29.outro("Project already clean");
29237
29301
  return;
29238
29302
  }
29239
29303
  const planLines = steps.map((step) => {
@@ -29241,14 +29305,14 @@ async function runUninstallCommand(options) {
29241
29305
  const countLabel = pc11.dim(`${step.count} ${step.unit}`);
29242
29306
  return `${pc11.red("\u2717")} ${names} ${countLabel}`;
29243
29307
  });
29244
- p28.note(planLines.join("\n"), "Uninstall plan");
29308
+ p29.note(planLines.join("\n"), "Uninstall plan");
29245
29309
  if (!options.force) {
29246
- const confirmed = await p28.confirm({
29310
+ const confirmed = await p29.confirm({
29247
29311
  message: "Proceed with uninstall?",
29248
29312
  initialValue: false
29249
29313
  });
29250
- if (p28.isCancel(confirmed) || !confirmed) {
29251
- p28.cancel("Uninstall cancelled.");
29314
+ if (p29.isCancel(confirmed) || !confirmed) {
29315
+ p29.cancel("Uninstall cancelled.");
29252
29316
  process.exit(0);
29253
29317
  }
29254
29318
  }
@@ -29260,8 +29324,8 @@ async function runUninstallCommand(options) {
29260
29324
  }
29261
29325
  const parts = steps.map((step) => `${step.count} ${step.unit}`);
29262
29326
  s.stop(`Removed ${parts.join(", ")}`);
29263
- p28.note(pc11.dim("Database tables were NOT dropped \u2014 drop them manually if needed."), "Next steps");
29264
- p28.outro("Uninstall complete");
29327
+ p29.note(pc11.dim("Database tables were NOT dropped \u2014 drop them manually if needed."), "Next steps");
29328
+ p29.outro("Uninstall complete");
29265
29329
  }
29266
29330
 
29267
29331
  // adapters/next/commands/update-component.ts
@@ -31741,8 +31805,8 @@ try {
31741
31805
  console.error(error);
31742
31806
  } else {
31743
31807
  const message = error instanceof Error && error.message ? error.message : String(error);
31744
- p29.log.error(message);
31745
- p29.log.message(pc12.dim("Re-run with BETTERSTART_DEBUG=1 for the full stack trace."));
31808
+ p30.log.error(message);
31809
+ p30.log.message(pc12.dim("Re-run with BETTERSTART_DEBUG=1 for the full stack trace."));
31746
31810
  }
31747
31811
  process.exit(1);
31748
31812
  }