@nextsparkjs/cli 0.1.0-beta.100 → 0.1.0-beta.101

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
@@ -1,65 +1,473 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
- buildCommand,
4
- devCommand,
5
- generateCommand,
6
- getAIWorkflowDir,
7
- getCoreDir,
8
- getProjectRoot,
9
- registryBuildCommand,
10
- registryWatchCommand
11
- } from "./chunk-QXD4PBX6.js";
12
- import {
3
+ __require,
13
4
  addPlugin,
14
5
  addPluginCommand,
15
6
  fetchPackage,
16
7
  installTheme,
17
8
  runPostinstall,
18
9
  validateTheme
19
- } from "./chunk-5GBCARGX.js";
20
- import {
21
- __require
22
- } from "./chunk-DGUM43GV.js";
10
+ } from "./chunk-DXL5CEZD.js";
23
11
 
24
12
  // src/cli.ts
25
13
  import { config } from "dotenv";
26
14
  import { Command } from "commander";
27
- import chalk16 from "chalk";
28
- import { readFileSync as readFileSync8 } from "fs";
15
+ import chalk20 from "chalk";
16
+ import { readFileSync as readFileSync11 } from "fs";
29
17
 
30
- // src/commands/init.ts
31
- import { existsSync as existsSync4, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync4 } from "fs";
32
- import { join as join5 } from "path";
33
- import chalk8 from "chalk";
18
+ // src/commands/dev.ts
19
+ import { spawn } from "child_process";
20
+ import chalk from "chalk";
21
+ import ora from "ora";
22
+
23
+ // src/utils/paths.ts
24
+ import { existsSync } from "fs";
25
+ import { resolve, join, dirname } from "path";
26
+ import { fileURLToPath } from "url";
27
+ var __filename = fileURLToPath(import.meta.url);
28
+ var __dirname = dirname(__filename);
29
+ function getCoreDir() {
30
+ const cwd = process.cwd();
31
+ const npmCorePath = resolve(cwd, "node_modules", "@nextsparkjs", "core");
32
+ if (existsSync(npmCorePath)) {
33
+ return npmCorePath;
34
+ }
35
+ const monorepoCorePath = resolve(__dirname, "..", "..", "..", "..", "core");
36
+ if (existsSync(monorepoCorePath)) {
37
+ return monorepoCorePath;
38
+ }
39
+ const cwdMonorepoCorePath = resolve(cwd, "..", "..", "packages", "core");
40
+ if (existsSync(cwdMonorepoCorePath)) {
41
+ return cwdMonorepoCorePath;
42
+ }
43
+ throw new Error(
44
+ "Could not find @nextsparkjs/core. Make sure it is installed as a dependency or you are running from within the monorepo."
45
+ );
46
+ }
47
+ function getProjectRoot() {
48
+ return process.cwd();
49
+ }
50
+ function isMonorepoMode() {
51
+ const cwd = process.cwd();
52
+ const npmCorePath = resolve(cwd, "node_modules", "@nextsparkjs", "core");
53
+ return !existsSync(npmCorePath);
54
+ }
55
+ function getAIWorkflowDir() {
56
+ const cwd = process.cwd();
57
+ const nmPath = join(cwd, "node_modules", "@nextsparkjs", "ai-workflow");
58
+ if (existsSync(nmPath)) return nmPath;
59
+ const webNmPath = join(cwd, "web", "node_modules", "@nextsparkjs", "ai-workflow");
60
+ if (existsSync(webNmPath)) return webNmPath;
61
+ const monoPath = join(cwd, "packages", "ai-workflow");
62
+ if (existsSync(monoPath)) return monoPath;
63
+ return null;
64
+ }
65
+
66
+ // src/commands/dev.ts
67
+ async function devCommand(options) {
68
+ const spinner = ora("Starting development environment...").start();
69
+ try {
70
+ const coreDir = getCoreDir();
71
+ const projectRoot = getProjectRoot();
72
+ const mode = isMonorepoMode() ? "monorepo" : "npm";
73
+ spinner.succeed(`Core found at: ${coreDir} (${mode} mode)`);
74
+ const processes = [];
75
+ if (options.registry) {
76
+ console.log(chalk.blue("\n[Registry] Starting registry builder with watch mode..."));
77
+ const registryProcess = spawn("node", ["scripts/build/registry.mjs", "--watch"], {
78
+ cwd: coreDir,
79
+ stdio: "inherit",
80
+ env: {
81
+ ...process.env,
82
+ NEXTSPARK_PROJECT_ROOT: projectRoot
83
+ }
84
+ });
85
+ processes.push(registryProcess);
86
+ registryProcess.on("error", (err) => {
87
+ console.error(chalk.red(`[Registry] Error: ${err.message}`));
88
+ });
89
+ }
90
+ console.log(chalk.green(`
91
+ [Dev] Starting Next.js dev server on port ${options.port}...`));
92
+ const devProcess = spawn("npx", ["next", "dev", "-p", options.port], {
93
+ cwd: projectRoot,
94
+ stdio: "inherit",
95
+ shell: true,
96
+ env: {
97
+ ...process.env,
98
+ NEXTSPARK_CORE_DIR: coreDir
99
+ }
100
+ });
101
+ processes.push(devProcess);
102
+ devProcess.on("error", (err) => {
103
+ console.error(chalk.red(`[Dev] Error: ${err.message}`));
104
+ process.exit(1);
105
+ });
106
+ const cleanup = () => {
107
+ console.log(chalk.yellow("\nShutting down..."));
108
+ processes.forEach((p) => {
109
+ if (!p.killed) {
110
+ p.kill("SIGTERM");
111
+ }
112
+ });
113
+ process.exit(0);
114
+ };
115
+ process.on("SIGINT", cleanup);
116
+ process.on("SIGTERM", cleanup);
117
+ devProcess.on("exit", (code) => {
118
+ cleanup();
119
+ process.exit(code ?? 0);
120
+ });
121
+ } catch (error) {
122
+ spinner.fail("Failed to start development environment");
123
+ if (error instanceof Error) {
124
+ console.error(chalk.red(error.message));
125
+ }
126
+ process.exit(1);
127
+ }
128
+ }
129
+
130
+ // src/commands/build.ts
131
+ import { spawn as spawn2 } from "child_process";
132
+ import { existsSync as existsSync2, readFileSync } from "fs";
133
+ import { join as join2 } from "path";
134
+ import chalk2 from "chalk";
135
+ import ora2 from "ora";
136
+ function loadProjectEnv(projectRoot) {
137
+ const envPath = join2(projectRoot, ".env");
138
+ const envVars = {};
139
+ if (existsSync2(envPath)) {
140
+ const content = readFileSync(envPath, "utf-8");
141
+ for (const line of content.split("\n")) {
142
+ const trimmed = line.trim();
143
+ if (trimmed && !trimmed.startsWith("#")) {
144
+ const [key, ...valueParts] = trimmed.split("=");
145
+ if (key && valueParts.length > 0) {
146
+ let value = valueParts.join("=");
147
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
148
+ value = value.slice(1, -1);
149
+ }
150
+ envVars[key] = value;
151
+ }
152
+ }
153
+ }
154
+ }
155
+ return envVars;
156
+ }
157
+ async function buildCommand(options) {
158
+ const spinner = ora2("Preparing production build...").start();
159
+ try {
160
+ const coreDir = getCoreDir();
161
+ const projectRoot = getProjectRoot();
162
+ spinner.succeed("Core package found");
163
+ const projectEnv = loadProjectEnv(projectRoot);
164
+ if (options.registry) {
165
+ spinner.start("Generating registries...");
166
+ await new Promise((resolve4, reject) => {
167
+ const registryProcess = spawn2("node", ["scripts/build/registry.mjs"], {
168
+ cwd: coreDir,
169
+ stdio: "pipe",
170
+ env: {
171
+ ...projectEnv,
172
+ ...process.env,
173
+ NEXTSPARK_PROJECT_ROOT: projectRoot
174
+ }
175
+ });
176
+ let stderr = "";
177
+ registryProcess.stderr?.on("data", (data) => {
178
+ stderr += data.toString();
179
+ });
180
+ registryProcess.on("close", (code) => {
181
+ if (code === 0) {
182
+ resolve4();
183
+ } else {
184
+ reject(new Error(`Registry generation failed: ${stderr}`));
185
+ }
186
+ });
187
+ registryProcess.on("error", reject);
188
+ });
189
+ spinner.succeed("Registries generated");
190
+ }
191
+ spinner.start("Building for production...");
192
+ const buildProcess = spawn2("npx", ["next", "build"], {
193
+ cwd: projectRoot,
194
+ stdio: "inherit",
195
+ shell: true,
196
+ env: {
197
+ ...projectEnv,
198
+ ...process.env,
199
+ NEXTSPARK_CORE_DIR: coreDir,
200
+ NODE_ENV: "production"
201
+ }
202
+ });
203
+ buildProcess.on("error", (err) => {
204
+ spinner.fail("Build failed");
205
+ console.error(chalk2.red(err.message));
206
+ process.exit(1);
207
+ });
208
+ buildProcess.on("close", (code) => {
209
+ if (code === 0) {
210
+ console.log(chalk2.green("\nBuild completed successfully!"));
211
+ process.exit(0);
212
+ } else {
213
+ console.error(chalk2.red(`
214
+ Build failed with exit code ${code}`));
215
+ process.exit(code ?? 1);
216
+ }
217
+ });
218
+ } catch (error) {
219
+ spinner.fail("Build preparation failed");
220
+ if (error instanceof Error) {
221
+ console.error(chalk2.red(error.message));
222
+ }
223
+ process.exit(1);
224
+ }
225
+ }
226
+
227
+ // src/commands/generate.ts
228
+ import { spawn as spawn3 } from "child_process";
229
+ import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
230
+ import { join as join3 } from "path";
231
+ import chalk3 from "chalk";
232
+ import ora3 from "ora";
233
+ function loadProjectEnv2(projectRoot) {
234
+ const envPath = join3(projectRoot, ".env");
235
+ const envVars = {};
236
+ if (existsSync3(envPath)) {
237
+ const content = readFileSync2(envPath, "utf-8");
238
+ for (const line of content.split("\n")) {
239
+ const trimmed = line.trim();
240
+ if (trimmed && !trimmed.startsWith("#")) {
241
+ const [key, ...valueParts] = trimmed.split("=");
242
+ if (key && valueParts.length > 0) {
243
+ let value = valueParts.join("=");
244
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
245
+ value = value.slice(1, -1);
246
+ }
247
+ envVars[key] = value;
248
+ }
249
+ }
250
+ }
251
+ }
252
+ return envVars;
253
+ }
254
+ async function generateCommand(options) {
255
+ const spinner = ora3("Preparing registry generation...").start();
256
+ try {
257
+ const coreDir = getCoreDir();
258
+ const projectRoot = getProjectRoot();
259
+ const mode = isMonorepoMode() ? "monorepo" : "npm";
260
+ spinner.succeed(`Core found at: ${coreDir} (${mode} mode)`);
261
+ const projectEnv = loadProjectEnv2(projectRoot);
262
+ const watchArg = options.watch ? ["--watch"] : [];
263
+ const action = options.watch ? "Watching" : "Generating";
264
+ console.log(chalk3.blue(`
265
+ ${action} registries...`));
266
+ const generateProcess = spawn3("node", ["scripts/build/registry.mjs", ...watchArg], {
267
+ cwd: coreDir,
268
+ stdio: "inherit",
269
+ env: {
270
+ ...projectEnv,
271
+ ...process.env,
272
+ NEXTSPARK_PROJECT_ROOT: projectRoot
273
+ }
274
+ });
275
+ generateProcess.on("error", (err) => {
276
+ console.error(chalk3.red(`Error: ${err.message}`));
277
+ process.exit(1);
278
+ });
279
+ generateProcess.on("close", (code) => {
280
+ if (code === 0) {
281
+ if (!options.watch) {
282
+ console.log(chalk3.green("\nRegistry generation completed!"));
283
+ }
284
+ process.exit(0);
285
+ } else {
286
+ console.error(chalk3.red(`
287
+ Registry generation failed with exit code ${code}`));
288
+ process.exit(code ?? 1);
289
+ }
290
+ });
291
+ if (options.watch) {
292
+ const cleanup = () => {
293
+ console.log(chalk3.yellow("\nStopping watcher..."));
294
+ if (!generateProcess.killed) {
295
+ generateProcess.kill("SIGTERM");
296
+ }
297
+ process.exit(0);
298
+ };
299
+ process.on("SIGINT", cleanup);
300
+ process.on("SIGTERM", cleanup);
301
+ }
302
+ } catch (error) {
303
+ spinner.fail("Registry generation failed");
304
+ if (error instanceof Error) {
305
+ console.error(chalk3.red(error.message));
306
+ }
307
+ process.exit(1);
308
+ }
309
+ }
310
+
311
+ // src/commands/registry.ts
312
+ import { spawn as spawn4 } from "child_process";
313
+ import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
314
+ import { join as join4 } from "path";
315
+ import chalk4 from "chalk";
34
316
  import ora4 from "ora";
317
+ function loadProjectEnv3(projectRoot) {
318
+ const envPath = join4(projectRoot, ".env");
319
+ const envVars = {};
320
+ if (existsSync4(envPath)) {
321
+ const content = readFileSync3(envPath, "utf-8");
322
+ for (const line of content.split("\n")) {
323
+ const trimmed = line.trim();
324
+ if (trimmed && !trimmed.startsWith("#")) {
325
+ const [key, ...valueParts] = trimmed.split("=");
326
+ if (key && valueParts.length > 0) {
327
+ let value = valueParts.join("=");
328
+ if (value.startsWith('"') && value.endsWith('"') || value.startsWith("'") && value.endsWith("'")) {
329
+ value = value.slice(1, -1);
330
+ }
331
+ envVars[key] = value;
332
+ }
333
+ }
334
+ }
335
+ }
336
+ return envVars;
337
+ }
338
+ async function registryBuildCommand() {
339
+ const spinner = ora4("Building registries...").start();
340
+ try {
341
+ const coreDir = getCoreDir();
342
+ const projectRoot = getProjectRoot();
343
+ const mode = isMonorepoMode() ? "monorepo" : "npm";
344
+ const projectEnv = loadProjectEnv3(projectRoot);
345
+ spinner.text = `Building registries (${mode} mode)...`;
346
+ const buildProcess = spawn4("node", ["scripts/build/registry.mjs"], {
347
+ cwd: coreDir,
348
+ stdio: "pipe",
349
+ env: {
350
+ ...projectEnv,
351
+ ...process.env,
352
+ NEXTSPARK_PROJECT_ROOT: projectRoot
353
+ }
354
+ });
355
+ let stdout = "";
356
+ let stderr = "";
357
+ buildProcess.stdout?.on("data", (data) => {
358
+ stdout += data.toString();
359
+ });
360
+ buildProcess.stderr?.on("data", (data) => {
361
+ stderr += data.toString();
362
+ });
363
+ buildProcess.on("close", (code) => {
364
+ if (code === 0) {
365
+ spinner.succeed("Registries built successfully");
366
+ if (stdout.trim()) {
367
+ console.log(chalk4.gray(stdout.trim()));
368
+ }
369
+ process.exit(0);
370
+ } else {
371
+ spinner.fail("Registry build failed");
372
+ if (stderr.trim()) {
373
+ console.error(chalk4.red(stderr.trim()));
374
+ }
375
+ process.exit(code ?? 1);
376
+ }
377
+ });
378
+ buildProcess.on("error", (err) => {
379
+ spinner.fail("Registry build failed");
380
+ console.error(chalk4.red(err.message));
381
+ process.exit(1);
382
+ });
383
+ } catch (error) {
384
+ spinner.fail("Registry build failed");
385
+ if (error instanceof Error) {
386
+ console.error(chalk4.red(error.message));
387
+ }
388
+ process.exit(1);
389
+ }
390
+ }
391
+ async function registryWatchCommand() {
392
+ const spinner = ora4("Starting registry watcher...").start();
393
+ try {
394
+ const coreDir = getCoreDir();
395
+ const projectRoot = getProjectRoot();
396
+ const mode = isMonorepoMode() ? "monorepo" : "npm";
397
+ spinner.succeed(`Registry watcher started (${mode} mode)`);
398
+ console.log(chalk4.blue("\nWatching for changes... Press Ctrl+C to stop.\n"));
399
+ const projectEnv = loadProjectEnv3(projectRoot);
400
+ const watchProcess = spawn4("node", ["scripts/build/registry.mjs", "--watch"], {
401
+ cwd: coreDir,
402
+ stdio: "inherit",
403
+ env: {
404
+ ...projectEnv,
405
+ ...process.env,
406
+ NEXTSPARK_PROJECT_ROOT: projectRoot
407
+ }
408
+ });
409
+ watchProcess.on("error", (err) => {
410
+ console.error(chalk4.red(`Watcher error: ${err.message}`));
411
+ process.exit(1);
412
+ });
413
+ const cleanup = () => {
414
+ console.log(chalk4.yellow("\nStopping registry watcher..."));
415
+ if (!watchProcess.killed) {
416
+ watchProcess.kill("SIGTERM");
417
+ }
418
+ process.exit(0);
419
+ };
420
+ process.on("SIGINT", cleanup);
421
+ process.on("SIGTERM", cleanup);
422
+ watchProcess.on("close", (code) => {
423
+ if (code !== 0) {
424
+ console.error(chalk4.red(`
425
+ Watcher exited with code ${code}`));
426
+ }
427
+ process.exit(code ?? 0);
428
+ });
429
+ } catch (error) {
430
+ spinner.fail("Failed to start registry watcher");
431
+ if (error instanceof Error) {
432
+ console.error(chalk4.red(error.message));
433
+ }
434
+ process.exit(1);
435
+ }
436
+ }
437
+
438
+ // src/commands/init.ts
439
+ import { existsSync as existsSync8, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync7 } from "fs";
440
+ import { join as join9 } from "path";
441
+ import chalk12 from "chalk";
442
+ import ora8 from "ora";
35
443
 
36
444
  // src/wizard/index.ts
37
- import chalk7 from "chalk";
38
- import ora3 from "ora";
39
- import { confirm as confirm5, select as select6 } from "@inquirer/prompts";
445
+ import chalk11 from "chalk";
446
+ import ora7 from "ora";
447
+ import { confirm as confirm5, select as select7 } from "@inquirer/prompts";
40
448
  import { execSync } from "child_process";
41
- import { existsSync as existsSync3, readdirSync } from "fs";
42
- import { join as join4 } from "path";
449
+ import { existsSync as existsSync7, readdirSync } from "fs";
450
+ import { join as join8 } from "path";
43
451
 
44
452
  // src/wizard/banner.ts
45
- import chalk from "chalk";
46
- import { readFileSync } from "fs";
47
- import { fileURLToPath } from "url";
48
- import { dirname, join } from "path";
49
- var __filename = fileURLToPath(import.meta.url);
50
- var __dirname = dirname(__filename);
453
+ import chalk5 from "chalk";
454
+ import { readFileSync as readFileSync4 } from "fs";
455
+ import { fileURLToPath as fileURLToPath2 } from "url";
456
+ import { dirname as dirname2, join as join5 } from "path";
457
+ var __filename2 = fileURLToPath2(import.meta.url);
458
+ var __dirname2 = dirname2(__filename2);
51
459
  function getCliVersion() {
52
460
  const possiblePaths = [
53
- join(__dirname, "../package.json"),
461
+ join5(__dirname2, "../package.json"),
54
462
  // from dist/
55
- join(__dirname, "../../package.json"),
463
+ join5(__dirname2, "../../package.json"),
56
464
  // from dist/wizard/ or src/wizard/
57
- join(__dirname, "../../../package.json")
465
+ join5(__dirname2, "../../../package.json")
58
466
  // fallback
59
467
  ];
60
468
  for (const packageJsonPath of possiblePaths) {
61
469
  try {
62
- const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf-8"));
470
+ const packageJson = JSON.parse(readFileSync4(packageJsonPath, "utf-8"));
63
471
  if (packageJson.name === "@nextsparkjs/cli" && packageJson.version) {
64
472
  return packageJson.version;
65
473
  }
@@ -78,29 +486,29 @@ var BANNER = `
78
486
  `;
79
487
  function showBanner() {
80
488
  const version = getCliVersion();
81
- console.log(chalk.cyan(BANNER));
82
- console.log(chalk.bold.white(" Welcome to NextSpark - The Complete SaaS Framework for Next.js"));
83
- console.log(chalk.gray(` Version ${version} - Create production-ready SaaS applications in minutes
489
+ console.log(chalk5.cyan(BANNER));
490
+ console.log(chalk5.bold.white(" Welcome to NextSpark - The Complete SaaS Framework for Next.js"));
491
+ console.log(chalk5.gray(` Version ${version} - Create production-ready SaaS applications in minutes
84
492
  `));
85
- console.log(chalk.gray(" " + "=".repeat(60) + "\n"));
493
+ console.log(chalk5.gray(" " + "=".repeat(60) + "\n"));
86
494
  }
87
495
  function showSection(title, step, totalSteps) {
88
496
  console.log("");
89
- console.log(chalk.cyan(` Step ${step}/${totalSteps}: ${title}`));
90
- console.log(chalk.gray(" " + "-".repeat(40)));
497
+ console.log(chalk5.cyan(` Step ${step}/${totalSteps}: ${title}`));
498
+ console.log(chalk5.gray(" " + "-".repeat(40)));
91
499
  console.log("");
92
500
  }
93
501
  function showSuccess(message) {
94
- console.log(chalk.green(` \u2713 ${message}`));
502
+ console.log(chalk5.green(` \u2713 ${message}`));
95
503
  }
96
504
  function showWarning(message) {
97
- console.log(chalk.yellow(` \u26A0 ${message}`));
505
+ console.log(chalk5.yellow(` \u26A0 ${message}`));
98
506
  }
99
507
  function showError(message) {
100
- console.log(chalk.red(` \u2717 ${message}`));
508
+ console.log(chalk5.red(` \u2717 ${message}`));
101
509
  }
102
510
  function showInfo(message) {
103
- console.log(chalk.blue(` \u2139 ${message}`));
511
+ console.log(chalk5.blue(` \u2139 ${message}`));
104
512
  }
105
513
 
106
514
  // src/wizard/prompts/project-info.ts
@@ -456,7 +864,24 @@ async function promptContentFeaturesConfig(mode = "interactive", totalSteps = 9)
456
864
  }
457
865
 
458
866
  // src/wizard/prompts/auth-config.ts
459
- import { checkbox as checkbox5 } from "@inquirer/prompts";
867
+ import { checkbox as checkbox5, input as input2, select as select5 } from "@inquirer/prompts";
868
+ var REGISTRATION_MODE_OPTIONS = [
869
+ {
870
+ name: "Open (anyone can register)",
871
+ value: "open",
872
+ description: "Email+password and Google OAuth signup available to everyone"
873
+ },
874
+ {
875
+ name: "Domain-Restricted (Google OAuth only for specific domains)",
876
+ value: "domain-restricted",
877
+ description: "Only Google OAuth for allowed email domains (e.g., @yourcompany.com)"
878
+ },
879
+ {
880
+ name: "Invitation-Only (registration via invite link)",
881
+ value: "invitation-only",
882
+ description: "Users can only register when invited by an existing user"
883
+ }
884
+ ];
460
885
  var AUTH_METHOD_OPTIONS = [
461
886
  {
462
887
  name: "Email & Password",
@@ -481,6 +906,7 @@ var SECURITY_OPTIONS = [
481
906
  ];
482
907
  function getDefaultAuthConfig() {
483
908
  return {
909
+ registrationMode: "open",
484
910
  emailPassword: true,
485
911
  googleOAuth: false,
486
912
  emailVerification: true
@@ -490,10 +916,40 @@ async function promptAuthConfig(mode = "interactive", totalSteps = 8) {
490
916
  showSection("Authentication", 8, totalSteps);
491
917
  showInfo("Configure how users will authenticate to your application.");
492
918
  console.log("");
493
- const selectedMethods = await checkbox5({
494
- message: "Which authentication methods do you want to enable?",
495
- choices: AUTH_METHOD_OPTIONS
919
+ const registrationMode = await select5({
920
+ message: "How should new users register?",
921
+ choices: REGISTRATION_MODE_OPTIONS,
922
+ default: "open"
496
923
  });
924
+ console.log("");
925
+ let emailPassword = true;
926
+ let googleOAuth = false;
927
+ let allowedDomains;
928
+ if (registrationMode === "domain-restricted") {
929
+ googleOAuth = true;
930
+ emailPassword = false;
931
+ showInfo("Domain-restricted mode: Google OAuth enabled, email login hidden on login page.");
932
+ console.log("");
933
+ const domainsInput = await input2({
934
+ message: "Allowed email domains (comma-separated, e.g. yourcompany.com, partner.org):",
935
+ validate: (value) => {
936
+ if (!value.trim()) return "At least one domain is required for domain-restricted mode";
937
+ const domains = value.split(",").map((d) => d.trim()).filter(Boolean);
938
+ const invalid = domains.find((d) => !d.includes("."));
939
+ if (invalid) return `Invalid domain: "${invalid}" (must contain a dot)`;
940
+ return true;
941
+ }
942
+ });
943
+ allowedDomains = domainsInput.split(",").map((d) => d.trim().toLowerCase()).filter(Boolean);
944
+ console.log("");
945
+ } else {
946
+ const selectedMethods = await checkbox5({
947
+ message: "Which authentication methods do you want to enable?",
948
+ choices: AUTH_METHOD_OPTIONS
949
+ });
950
+ emailPassword = selectedMethods.includes("emailPassword");
951
+ googleOAuth = selectedMethods.includes("googleOAuth");
952
+ }
497
953
  let selectedSecurity = ["emailVerification"];
498
954
  if (mode === "expert") {
499
955
  console.log("");
@@ -505,9 +961,11 @@ async function promptAuthConfig(mode = "interactive", totalSteps = 8) {
505
961
  });
506
962
  }
507
963
  const auth = {
508
- emailPassword: selectedMethods.includes("emailPassword"),
509
- googleOAuth: selectedMethods.includes("googleOAuth"),
510
- emailVerification: selectedSecurity.includes("emailVerification")
964
+ registrationMode,
965
+ emailPassword,
966
+ googleOAuth,
967
+ emailVerification: selectedSecurity.includes("emailVerification"),
968
+ allowedDomains
511
969
  };
512
970
  return { auth };
513
971
  }
@@ -650,17 +1108,17 @@ async function promptDevConfig(mode = "interactive", totalSteps = 8) {
650
1108
  }
651
1109
 
652
1110
  // src/wizard/prompts/theme-selection.ts
653
- import { select as select5 } from "@inquirer/prompts";
654
- import chalk2 from "chalk";
1111
+ import { select as select6 } from "@inquirer/prompts";
1112
+ import chalk6 from "chalk";
655
1113
  async function promptThemeSelection() {
656
1114
  console.log("");
657
- console.log(chalk2.cyan(" Reference Theme Installation"));
658
- console.log(chalk2.gray(" " + "-".repeat(40)));
1115
+ console.log(chalk6.cyan(" Reference Theme Installation"));
1116
+ console.log(chalk6.gray(" " + "-".repeat(40)));
659
1117
  console.log("");
660
- console.log(chalk2.gray(" A reference theme provides a complete example to learn from."));
661
- console.log(chalk2.gray(" Your custom theme (based on starter) will be your active theme."));
1118
+ console.log(chalk6.gray(" A reference theme provides a complete example to learn from."));
1119
+ console.log(chalk6.gray(" Your custom theme (based on starter) will be your active theme."));
662
1120
  console.log("");
663
- const theme = await select5({
1121
+ const theme = await select6({
664
1122
  message: "Which reference theme would you like to install?",
665
1123
  choices: [
666
1124
  {
@@ -696,7 +1154,7 @@ async function promptThemeSelection() {
696
1154
 
697
1155
  // src/wizard/prompts/plugins-selection.ts
698
1156
  import { checkbox as checkbox8 } from "@inquirer/prompts";
699
- import chalk3 from "chalk";
1157
+ import chalk7 from "chalk";
700
1158
  var THEME_REQUIRED_PLUGINS = {
701
1159
  "default": ["langchain"],
702
1160
  "blog": [],
@@ -706,11 +1164,11 @@ var THEME_REQUIRED_PLUGINS = {
706
1164
  async function promptPluginsSelection(selectedTheme) {
707
1165
  const requiredPlugins = selectedTheme ? THEME_REQUIRED_PLUGINS[selectedTheme] || [] : [];
708
1166
  console.log("");
709
- console.log(chalk3.cyan(" Plugin Selection"));
710
- console.log(chalk3.gray(" " + "-".repeat(40)));
1167
+ console.log(chalk7.cyan(" Plugin Selection"));
1168
+ console.log(chalk7.gray(" " + "-".repeat(40)));
711
1169
  if (requiredPlugins.length > 0) {
712
1170
  console.log("");
713
- console.log(chalk3.gray(` Note: ${requiredPlugins.join(", ")} will be installed (required by theme)`));
1171
+ console.log(chalk7.gray(` Note: ${requiredPlugins.join(", ")} will be installed (required by theme)`));
714
1172
  }
715
1173
  console.log("");
716
1174
  const plugins = await checkbox8({
@@ -746,10 +1204,10 @@ function getRequiredPlugins(theme) {
746
1204
  }
747
1205
 
748
1206
  // src/wizard/prompts/env-config.ts
749
- import { confirm as confirm3, input as input2 } from "@inquirer/prompts";
1207
+ import { confirm as confirm3, input as input3 } from "@inquirer/prompts";
750
1208
 
751
1209
  // src/wizard/prompts/git-config.ts
752
- import { confirm as confirm4, input as input3 } from "@inquirer/prompts";
1210
+ import { confirm as confirm4, input as input4 } from "@inquirer/prompts";
753
1211
 
754
1212
  // src/wizard/prompts/index.ts
755
1213
  async function runAllPrompts() {
@@ -828,24 +1286,24 @@ async function runExpertPrompts() {
828
1286
  // src/wizard/generators/index.ts
829
1287
  import fs8 from "fs-extra";
830
1288
  import path7 from "path";
831
- import { fileURLToPath as fileURLToPath6 } from "url";
1289
+ import { fileURLToPath as fileURLToPath7 } from "url";
832
1290
 
833
1291
  // src/wizard/generators/theme-renamer.ts
834
1292
  import fs from "fs-extra";
835
1293
  import path from "path";
836
- import { fileURLToPath as fileURLToPath2 } from "url";
837
- var __filename2 = fileURLToPath2(import.meta.url);
838
- var __dirname2 = path.dirname(__filename2);
1294
+ import { fileURLToPath as fileURLToPath3 } from "url";
1295
+ var __filename3 = fileURLToPath3(import.meta.url);
1296
+ var __dirname3 = path.dirname(__filename3);
839
1297
  function getTemplatesDir() {
840
1298
  const rootDir = process.cwd();
841
1299
  const possiblePaths = [
842
1300
  // From project root node_modules (most common for installed packages)
843
1301
  path.resolve(rootDir, "node_modules/@nextsparkjs/core/templates"),
844
1302
  // From CLI dist folder for development
845
- path.resolve(__dirname2, "../../core/templates"),
1303
+ path.resolve(__dirname3, "../../core/templates"),
846
1304
  // Legacy paths for different build structures
847
- path.resolve(__dirname2, "../../../../../core/templates"),
848
- path.resolve(__dirname2, "../../../../core/templates")
1305
+ path.resolve(__dirname3, "../../../../../core/templates"),
1306
+ path.resolve(__dirname3, "../../../../core/templates")
849
1307
  ];
850
1308
  for (const p of possiblePaths) {
851
1309
  if (fs.existsSync(p)) {
@@ -1170,29 +1628,32 @@ function getTargetThemesDir2() {
1170
1628
  return path2.resolve(process.cwd(), "contents", "themes");
1171
1629
  }
1172
1630
  async function updateAuthConfig(config2) {
1173
- const authConfigPath = path2.join(
1631
+ const appConfigPath = path2.join(
1174
1632
  getTargetThemesDir2(),
1175
1633
  config2.projectSlug,
1176
1634
  "config",
1177
- "auth.config.ts"
1635
+ "app.config.ts"
1178
1636
  );
1179
- if (!await fs2.pathExists(authConfigPath)) {
1637
+ if (!await fs2.pathExists(appConfigPath)) {
1180
1638
  return;
1181
1639
  }
1182
- let content = await fs2.readFile(authConfigPath, "utf-8");
1640
+ let content = await fs2.readFile(appConfigPath, "utf-8");
1183
1641
  content = content.replace(
1184
- /(emailPassword:\s*{[^}]*enabled:\s*)(?:true|false)/gs,
1185
- `$1${config2.auth.emailPassword}`
1642
+ /(mode:\s*)'open'(\s*as\s*const)/,
1643
+ `$1'${config2.auth.registrationMode}'$2`
1186
1644
  );
1187
1645
  content = content.replace(
1188
- /(google:\s*{[^}]*enabled:\s*)(?:true|false)/gs,
1646
+ /(google:\s*{\s*enabled:\s*)(?:true|false)/s,
1189
1647
  `$1${config2.auth.googleOAuth}`
1190
1648
  );
1191
- content = content.replace(
1192
- /(emailVerification:\s*)(?:true|false)/g,
1193
- `$1${config2.auth.emailVerification}`
1194
- );
1195
- await fs2.writeFile(authConfigPath, content, "utf-8");
1649
+ if (config2.auth.registrationMode === "domain-restricted") {
1650
+ const domains = config2.auth.allowedDomains?.length ? config2.auth.allowedDomains.map((d) => `'${d}'`).join(", ") : "'yourcompany.com'";
1651
+ content = content.replace(
1652
+ /\/\/\s*allowedDomains:\s*\['yourcompany\.com'\],\s*\/\/\s*Only for 'domain-restricted' mode/,
1653
+ `allowedDomains: [${domains}],`
1654
+ );
1655
+ }
1656
+ await fs2.writeFile(appConfigPath, content, "utf-8");
1196
1657
  }
1197
1658
  async function updateDashboardUIConfig(config2) {
1198
1659
  const dashboardConfigPath = path2.join(
@@ -1544,19 +2005,19 @@ async function processI18n(config2) {
1544
2005
  // src/wizard/generators/content-features-generator.ts
1545
2006
  import fs4 from "fs-extra";
1546
2007
  import path4 from "path";
1547
- import { fileURLToPath as fileURLToPath3 } from "url";
1548
- var __filename3 = fileURLToPath3(import.meta.url);
1549
- var __dirname3 = path4.dirname(__filename3);
2008
+ import { fileURLToPath as fileURLToPath4 } from "url";
2009
+ var __filename4 = fileURLToPath4(import.meta.url);
2010
+ var __dirname4 = path4.dirname(__filename4);
1550
2011
  function getTemplatesDir2() {
1551
2012
  const rootDir = process.cwd();
1552
2013
  const possiblePaths = [
1553
2014
  // From project root node_modules (most common for installed packages)
1554
2015
  path4.resolve(rootDir, "node_modules/@nextsparkjs/core/templates"),
1555
2016
  // From CLI dist folder for development
1556
- path4.resolve(__dirname3, "../../core/templates"),
2017
+ path4.resolve(__dirname4, "../../core/templates"),
1557
2018
  // Legacy paths for different build structures
1558
- path4.resolve(__dirname3, "../../../../../core/templates"),
1559
- path4.resolve(__dirname3, "../../../../core/templates")
2019
+ path4.resolve(__dirname4, "../../../../../core/templates"),
2020
+ path4.resolve(__dirname4, "../../../../core/templates")
1560
2021
  ];
1561
2022
  for (const p of possiblePaths) {
1562
2023
  if (fs4.existsSync(p)) {
@@ -1620,22 +2081,22 @@ async function copyContentFeatures(config2) {
1620
2081
  }
1621
2082
 
1622
2083
  // src/wizard/generators/theme-plugins-installer.ts
1623
- import { existsSync as existsSync2, cpSync, mkdirSync, readFileSync as readFileSync3, writeFileSync } from "fs";
1624
- import { join as join3, resolve } from "path";
1625
- import chalk5 from "chalk";
1626
- import ora2 from "ora";
2084
+ import { existsSync as existsSync6, cpSync, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
2085
+ import { join as join7, resolve as resolve2 } from "path";
2086
+ import chalk9 from "chalk";
2087
+ import ora6 from "ora";
1627
2088
 
1628
2089
  // src/commands/add-theme.ts
1629
- import chalk4 from "chalk";
1630
- import ora from "ora";
1631
- import { existsSync, readFileSync as readFileSync2 } from "fs";
1632
- import { join as join2 } from "path";
2090
+ import chalk8 from "chalk";
2091
+ import ora5 from "ora";
2092
+ import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
2093
+ import { join as join6 } from "path";
1633
2094
  async function addTheme(packageSpec, options = {}) {
1634
- const spinner = ora(`Adding theme ${packageSpec}`).start();
2095
+ const spinner = ora5(`Adding theme ${packageSpec}`).start();
1635
2096
  let cleanup = null;
1636
2097
  try {
1637
- const contentsDir = join2(process.cwd(), "contents");
1638
- if (!existsSync(contentsDir)) {
2098
+ const contentsDir = join6(process.cwd(), "contents");
2099
+ if (!existsSync5(contentsDir)) {
1639
2100
  spinner.fail('contents/ directory not found. Run "nextspark init" first.');
1640
2101
  return;
1641
2102
  }
@@ -1649,15 +2110,15 @@ async function addTheme(packageSpec, options = {}) {
1649
2110
  const validation = validateTheme(packageJson, extractedPath);
1650
2111
  if (!validation.valid) {
1651
2112
  spinner.fail("Invalid theme");
1652
- validation.errors.forEach((e) => console.log(chalk4.red(` \u2717 ${e}`)));
2113
+ validation.errors.forEach((e) => console.log(chalk8.red(` \u2717 ${e}`)));
1653
2114
  return;
1654
2115
  }
1655
2116
  if (validation.warnings.length > 0) {
1656
- validation.warnings.forEach((w) => console.log(chalk4.yellow(` \u26A0 ${w}`)));
2117
+ validation.warnings.forEach((w) => console.log(chalk8.yellow(` \u26A0 ${w}`)));
1657
2118
  }
1658
2119
  if (packageJson.requiredPlugins?.length && !options.skipPostinstall) {
1659
2120
  spinner.stop();
1660
- console.log(chalk4.blue("\n Installing required plugins..."));
2121
+ console.log(chalk8.blue("\n Installing required plugins..."));
1661
2122
  const installingPlugins = /* @__PURE__ */ new Set();
1662
2123
  for (const plugin of packageJson.requiredPlugins) {
1663
2124
  if (!checkPluginExists(plugin)) {
@@ -1681,14 +2142,14 @@ async function addTheme(packageSpec, options = {}) {
1681
2142
  };
1682
2143
  await runPostinstall(packageJson, result.installedPath, context);
1683
2144
  }
1684
- console.log(chalk4.green(`
2145
+ console.log(chalk8.green(`
1685
2146
  \u2713 Theme ${result.name} installed successfully!`));
1686
- console.log(chalk4.gray(` Location: contents/themes/${result.name}/`));
1687
- console.log(chalk4.gray(` Set NEXT_PUBLIC_ACTIVE_THEME=${result.name} to activate`));
2147
+ console.log(chalk8.gray(` Location: contents/themes/${result.name}/`));
2148
+ console.log(chalk8.gray(` Set NEXT_PUBLIC_ACTIVE_THEME=${result.name} to activate`));
1688
2149
  } catch (error) {
1689
2150
  spinner.fail("Failed to add theme");
1690
2151
  if (error instanceof Error) {
1691
- console.log(chalk4.red(` ${error.message}`));
2152
+ console.log(chalk8.red(` ${error.message}`));
1692
2153
  }
1693
2154
  throw error;
1694
2155
  } finally {
@@ -1697,13 +2158,13 @@ async function addTheme(packageSpec, options = {}) {
1697
2158
  }
1698
2159
  function checkPluginExists(pluginName) {
1699
2160
  const name = pluginName.replace(/^@[^/]+\//, "").replace(/^nextspark-plugin-/, "").replace(/^plugin-/, "");
1700
- return existsSync(join2(process.cwd(), "contents", "plugins", name));
2161
+ return existsSync5(join6(process.cwd(), "contents", "plugins", name));
1701
2162
  }
1702
2163
  function getCoreVersion() {
1703
- const pkgPath = join2(process.cwd(), "node_modules", "@nextsparkjs", "core", "package.json");
1704
- if (existsSync(pkgPath)) {
2164
+ const pkgPath = join6(process.cwd(), "node_modules", "@nextsparkjs", "core", "package.json");
2165
+ if (existsSync5(pkgPath)) {
1705
2166
  try {
1706
- const pkg2 = JSON.parse(readFileSync2(pkgPath, "utf-8"));
2167
+ const pkg2 = JSON.parse(readFileSync5(pkgPath, "utf-8"));
1707
2168
  return pkg2.version || "0.0.0";
1708
2169
  } catch {
1709
2170
  return "0.0.0";
@@ -1739,23 +2200,23 @@ var THEME_REQUIRED_PLUGINS2 = {
1739
2200
  "crm": [],
1740
2201
  "productivity": []
1741
2202
  };
1742
- function isMonorepoMode() {
2203
+ function isMonorepoMode2() {
1743
2204
  const possiblePaths = [
1744
- join3(process.cwd(), "pnpm-workspace.yaml"),
1745
- join3(process.cwd(), "..", "pnpm-workspace.yaml"),
1746
- join3(process.cwd(), "..", "..", "pnpm-workspace.yaml")
2205
+ join7(process.cwd(), "pnpm-workspace.yaml"),
2206
+ join7(process.cwd(), "..", "pnpm-workspace.yaml"),
2207
+ join7(process.cwd(), "..", "..", "pnpm-workspace.yaml")
1747
2208
  ];
1748
- return possiblePaths.some((p) => existsSync2(p));
2209
+ return possiblePaths.some((p) => existsSync6(p));
1749
2210
  }
1750
2211
  function getMonorepoRoot() {
1751
2212
  const possibleRoots = [
1752
2213
  process.cwd(),
1753
- join3(process.cwd(), ".."),
1754
- join3(process.cwd(), "..", "..")
2214
+ join7(process.cwd(), ".."),
2215
+ join7(process.cwd(), "..", "..")
1755
2216
  ];
1756
2217
  for (const root of possibleRoots) {
1757
- if (existsSync2(join3(root, "pnpm-workspace.yaml"))) {
1758
- return resolve(root);
2218
+ if (existsSync6(join7(root, "pnpm-workspace.yaml"))) {
2219
+ return resolve2(root);
1759
2220
  }
1760
2221
  }
1761
2222
  return null;
@@ -1764,20 +2225,20 @@ function getLocalPackageDir(type, name) {
1764
2225
  const monorepoRoot = getMonorepoRoot();
1765
2226
  if (!monorepoRoot) return null;
1766
2227
  const baseDir = type === "theme" ? "themes" : "plugins";
1767
- const packageDir = join3(monorepoRoot, baseDir, name);
1768
- if (existsSync2(packageDir) && existsSync2(join3(packageDir, "package.json"))) {
2228
+ const packageDir = join7(monorepoRoot, baseDir, name);
2229
+ if (existsSync6(packageDir) && existsSync6(join7(packageDir, "package.json"))) {
1769
2230
  return packageDir;
1770
2231
  }
1771
2232
  return null;
1772
2233
  }
1773
2234
  async function copyLocalTheme(name, sourceDir) {
1774
- const targetDir = join3(process.cwd(), "contents", "themes", name);
1775
- const themesDir = join3(process.cwd(), "contents", "themes");
1776
- if (!existsSync2(themesDir)) {
2235
+ const targetDir = join7(process.cwd(), "contents", "themes", name);
2236
+ const themesDir = join7(process.cwd(), "contents", "themes");
2237
+ if (!existsSync6(themesDir)) {
1777
2238
  mkdirSync(themesDir, { recursive: true });
1778
2239
  }
1779
- if (existsSync2(targetDir)) {
1780
- console.log(chalk5.gray(` Theme ${name} already exists, skipping...`));
2240
+ if (existsSync6(targetDir)) {
2241
+ console.log(chalk9.gray(` Theme ${name} already exists, skipping...`));
1781
2242
  return true;
1782
2243
  }
1783
2244
  cpSync(sourceDir, targetDir, { recursive: true });
@@ -1785,13 +2246,13 @@ async function copyLocalTheme(name, sourceDir) {
1785
2246
  return true;
1786
2247
  }
1787
2248
  async function copyLocalPlugin(name, sourceDir) {
1788
- const targetDir = join3(process.cwd(), "contents", "plugins", name);
1789
- const pluginsDir = join3(process.cwd(), "contents", "plugins");
1790
- if (!existsSync2(pluginsDir)) {
2249
+ const targetDir = join7(process.cwd(), "contents", "plugins", name);
2250
+ const pluginsDir = join7(process.cwd(), "contents", "plugins");
2251
+ if (!existsSync6(pluginsDir)) {
1791
2252
  mkdirSync(pluginsDir, { recursive: true });
1792
2253
  }
1793
- if (existsSync2(targetDir)) {
1794
- console.log(chalk5.gray(` Plugin ${name} already exists, skipping...`));
2254
+ if (existsSync6(targetDir)) {
2255
+ console.log(chalk9.gray(` Plugin ${name} already exists, skipping...`));
1795
2256
  return true;
1796
2257
  }
1797
2258
  cpSync(sourceDir, targetDir, { recursive: true });
@@ -1799,12 +2260,12 @@ async function copyLocalPlugin(name, sourceDir) {
1799
2260
  return true;
1800
2261
  }
1801
2262
  async function updateTsConfigPaths(name, type) {
1802
- const tsconfigPath = join3(process.cwd(), "tsconfig.json");
1803
- if (!existsSync2(tsconfigPath)) {
2263
+ const tsconfigPath = join7(process.cwd(), "tsconfig.json");
2264
+ if (!existsSync6(tsconfigPath)) {
1804
2265
  return;
1805
2266
  }
1806
2267
  try {
1807
- const content = readFileSync3(tsconfigPath, "utf-8");
2268
+ const content = readFileSync6(tsconfigPath, "utf-8");
1808
2269
  const tsconfig = JSON.parse(content);
1809
2270
  if (!tsconfig.compilerOptions) {
1810
2271
  tsconfig.compilerOptions = {};
@@ -1839,17 +2300,17 @@ async function installTheme2(theme) {
1839
2300
  if (!theme) {
1840
2301
  return true;
1841
2302
  }
1842
- const spinner = ora2({
2303
+ const spinner = ora6({
1843
2304
  text: `Installing reference theme: ${theme}...`,
1844
2305
  prefixText: " "
1845
2306
  }).start();
1846
2307
  try {
1847
- const targetDir = join3(process.cwd(), "contents", "themes", theme);
1848
- if (existsSync2(targetDir)) {
1849
- spinner.info(chalk5.gray(`Reference theme ${theme} already exists`));
2308
+ const targetDir = join7(process.cwd(), "contents", "themes", theme);
2309
+ if (existsSync6(targetDir)) {
2310
+ spinner.info(chalk9.gray(`Reference theme ${theme} already exists`));
1850
2311
  return true;
1851
2312
  }
1852
- if (isMonorepoMode()) {
2313
+ if (isMonorepoMode2()) {
1853
2314
  const localDir = getLocalPackageDir("theme", theme);
1854
2315
  if (localDir) {
1855
2316
  spinner.text = `Copying reference theme from local: ${theme}...`;
@@ -1862,7 +2323,7 @@ async function installTheme2(theme) {
1862
2323
  await copyLocalPlugin(plugin, pluginDir);
1863
2324
  }
1864
2325
  }
1865
- spinner.succeed(chalk5.green(`Reference theme ${theme} installed!`));
2326
+ spinner.succeed(chalk9.green(`Reference theme ${theme} installed!`));
1866
2327
  return true;
1867
2328
  }
1868
2329
  }
@@ -1871,17 +2332,17 @@ async function installTheme2(theme) {
1871
2332
  const packageSpec = THEME_PACKAGES[theme];
1872
2333
  const success = await installThemeViaCli(packageSpec);
1873
2334
  if (success) {
1874
- spinner.succeed(chalk5.green(`Reference theme ${theme} installed!`));
2335
+ spinner.succeed(chalk9.green(`Reference theme ${theme} installed!`));
1875
2336
  return true;
1876
2337
  } else {
1877
- spinner.fail(chalk5.red(`Failed to install theme: ${theme}`));
1878
- console.log(chalk5.gray(" Hint: Make sure @nextsparkjs/cli is installed or the theme package is published"));
2338
+ spinner.fail(chalk9.red(`Failed to install theme: ${theme}`));
2339
+ console.log(chalk9.gray(" Hint: Make sure @nextsparkjs/cli is installed or the theme package is published"));
1879
2340
  return false;
1880
2341
  }
1881
2342
  } catch (error) {
1882
- spinner.fail(chalk5.red(`Failed to install theme: ${theme}`));
2343
+ spinner.fail(chalk9.red(`Failed to install theme: ${theme}`));
1883
2344
  if (error instanceof Error) {
1884
- console.log(chalk5.red(` Error: ${error.message}`));
2345
+ console.log(chalk9.red(` Error: ${error.message}`));
1885
2346
  }
1886
2347
  return false;
1887
2348
  }
@@ -1892,23 +2353,23 @@ async function installPlugins(plugins) {
1892
2353
  }
1893
2354
  let allSuccess = true;
1894
2355
  for (const plugin of plugins) {
1895
- const spinner = ora2({
2356
+ const spinner = ora6({
1896
2357
  text: `Installing plugin: ${plugin}...`,
1897
2358
  prefixText: " "
1898
2359
  }).start();
1899
2360
  try {
1900
- const pluginDir = join3(process.cwd(), "contents", "plugins", plugin);
1901
- if (existsSync2(pluginDir)) {
1902
- spinner.info(chalk5.gray(`Plugin ${plugin} already installed`));
2361
+ const pluginDir = join7(process.cwd(), "contents", "plugins", plugin);
2362
+ if (existsSync6(pluginDir)) {
2363
+ spinner.info(chalk9.gray(`Plugin ${plugin} already installed`));
1903
2364
  continue;
1904
2365
  }
1905
- if (isMonorepoMode()) {
2366
+ if (isMonorepoMode2()) {
1906
2367
  const localDir = getLocalPackageDir("plugin", plugin);
1907
2368
  if (localDir) {
1908
2369
  spinner.text = `Copying plugin from local: ${plugin}...`;
1909
2370
  const success2 = await copyLocalPlugin(plugin, localDir);
1910
2371
  if (success2) {
1911
- spinner.succeed(chalk5.green(`Plugin ${plugin} installed!`));
2372
+ spinner.succeed(chalk9.green(`Plugin ${plugin} installed!`));
1912
2373
  continue;
1913
2374
  }
1914
2375
  }
@@ -1917,16 +2378,16 @@ async function installPlugins(plugins) {
1917
2378
  const packageSpec = PLUGIN_PACKAGES[plugin];
1918
2379
  const success = await installPluginViaCli(packageSpec);
1919
2380
  if (success) {
1920
- spinner.succeed(chalk5.green(`Plugin ${plugin} installed!`));
2381
+ spinner.succeed(chalk9.green(`Plugin ${plugin} installed!`));
1921
2382
  } else {
1922
- spinner.fail(chalk5.red(`Failed to install plugin: ${plugin}`));
1923
- console.log(chalk5.gray(" Hint: Make sure @nextsparkjs/cli is installed or the plugin package is published"));
2383
+ spinner.fail(chalk9.red(`Failed to install plugin: ${plugin}`));
2384
+ console.log(chalk9.gray(" Hint: Make sure @nextsparkjs/cli is installed or the plugin package is published"));
1924
2385
  allSuccess = false;
1925
2386
  }
1926
2387
  } catch (error) {
1927
- spinner.fail(chalk5.red(`Failed to install plugin: ${plugin}`));
2388
+ spinner.fail(chalk9.red(`Failed to install plugin: ${plugin}`));
1928
2389
  if (error instanceof Error) {
1929
- console.log(chalk5.red(` Error: ${error.message}`));
2390
+ console.log(chalk9.red(` Error: ${error.message}`));
1930
2391
  }
1931
2392
  allSuccess = false;
1932
2393
  }
@@ -1938,19 +2399,19 @@ async function installThemeAndPlugins(theme, plugins) {
1938
2399
  return true;
1939
2400
  }
1940
2401
  console.log("");
1941
- console.log(chalk5.cyan(" Installing Reference Theme & Plugins"));
1942
- console.log(chalk5.gray(" " + "-".repeat(40)));
2402
+ console.log(chalk9.cyan(" Installing Reference Theme & Plugins"));
2403
+ console.log(chalk9.gray(" " + "-".repeat(40)));
1943
2404
  console.log("");
1944
2405
  const themeSuccess = await installTheme2(theme);
1945
2406
  if (!themeSuccess && theme) {
1946
- console.log(chalk5.yellow(" Warning: Theme installation failed, continuing with plugins..."));
2407
+ console.log(chalk9.yellow(" Warning: Theme installation failed, continuing with plugins..."));
1947
2408
  }
1948
2409
  const pluginsSuccess = await installPlugins(plugins);
1949
2410
  console.log("");
1950
2411
  if (themeSuccess && pluginsSuccess) {
1951
- console.log(chalk5.green(" All installations completed successfully!"));
2412
+ console.log(chalk9.green(" All installations completed successfully!"));
1952
2413
  } else {
1953
- console.log(chalk5.yellow(" Some installations had issues. Check the messages above."));
2414
+ console.log(chalk9.yellow(" Some installations had issues. Check the messages above."));
1954
2415
  }
1955
2416
  return themeSuccess && pluginsSuccess;
1956
2417
  }
@@ -1958,10 +2419,10 @@ async function installThemeAndPlugins(theme, plugins) {
1958
2419
  // src/wizard/generators/env-setup.ts
1959
2420
  import fs5 from "fs-extra";
1960
2421
  import path5 from "path";
1961
- import { fileURLToPath as fileURLToPath4 } from "url";
1962
- var __filename4 = fileURLToPath4(import.meta.url);
1963
- var __dirname4 = path5.dirname(__filename4);
1964
- var ENV_TEMPLATE_PATH = path5.resolve(__dirname4, "../../../templates/env.template");
2422
+ import { fileURLToPath as fileURLToPath5 } from "url";
2423
+ var __filename5 = fileURLToPath5(import.meta.url);
2424
+ var __dirname5 = path5.dirname(__filename5);
2425
+ var ENV_TEMPLATE_PATH = path5.resolve(__dirname5, "../../../templates/env.template");
1965
2426
 
1966
2427
  // src/wizard/generators/git-init.ts
1967
2428
  import fs6 from "fs-extra";
@@ -1969,9 +2430,9 @@ import fs6 from "fs-extra";
1969
2430
  // src/wizard/generators/monorepo-generator.ts
1970
2431
  import fs7 from "fs-extra";
1971
2432
  import path6 from "path";
1972
- import { fileURLToPath as fileURLToPath5 } from "url";
1973
- var __filename5 = fileURLToPath5(import.meta.url);
1974
- var __dirname5 = path6.dirname(__filename5);
2433
+ import { fileURLToPath as fileURLToPath6 } from "url";
2434
+ var __filename6 = fileURLToPath6(import.meta.url);
2435
+ var __dirname6 = path6.dirname(__filename6);
1975
2436
  var DIRS = {
1976
2437
  WEB: "web",
1977
2438
  MOBILE: "mobile",
@@ -2043,10 +2504,10 @@ function getMobileTemplatesDir() {
2043
2504
  // From CWD node_modules (installed package)
2044
2505
  path6.resolve(process.cwd(), "node_modules/@nextsparkjs/mobile/templates"),
2045
2506
  // From CLI dist folder: ../../mobile/templates (development)
2046
- path6.resolve(__dirname5, "../../mobile/templates"),
2507
+ path6.resolve(__dirname6, "../../mobile/templates"),
2047
2508
  // Legacy paths for different build structures
2048
- path6.resolve(__dirname5, "../../../../../mobile/templates"),
2049
- path6.resolve(__dirname5, "../../../../mobile/templates")
2509
+ path6.resolve(__dirname6, "../../../../../mobile/templates"),
2510
+ path6.resolve(__dirname6, "../../../../mobile/templates")
2050
2511
  ];
2051
2512
  for (const p of possiblePaths) {
2052
2513
  if (fs7.existsSync(p)) {
@@ -2498,18 +2959,18 @@ function getWebDir(targetDir, config2) {
2498
2959
  }
2499
2960
 
2500
2961
  // src/wizard/generators/index.ts
2501
- var __filename6 = fileURLToPath6(import.meta.url);
2502
- var __dirname6 = path7.dirname(__filename6);
2962
+ var __filename7 = fileURLToPath7(import.meta.url);
2963
+ var __dirname7 = path7.dirname(__filename7);
2503
2964
  function getTemplatesDir3(projectRoot) {
2504
2965
  const rootDir = projectRoot || process.cwd();
2505
2966
  const possiblePaths = [
2506
2967
  // From project root node_modules (most common for installed packages)
2507
2968
  path7.resolve(rootDir, "node_modules/@nextsparkjs/core/templates"),
2508
2969
  // From CLI dist folder for development
2509
- path7.resolve(__dirname6, "../../core/templates"),
2970
+ path7.resolve(__dirname7, "../../core/templates"),
2510
2971
  // Legacy paths for different build structures
2511
- path7.resolve(__dirname6, "../../../../../core/templates"),
2512
- path7.resolve(__dirname6, "../../../../core/templates")
2972
+ path7.resolve(__dirname7, "../../../../../core/templates"),
2973
+ path7.resolve(__dirname7, "../../../../core/templates")
2513
2974
  ];
2514
2975
  for (const p of possiblePaths) {
2515
2976
  if (fs8.existsSync(p)) {
@@ -2772,6 +3233,7 @@ var SAAS_PRESET = {
2772
3233
  blog: false
2773
3234
  },
2774
3235
  auth: {
3236
+ registrationMode: "open",
2775
3237
  emailPassword: true,
2776
3238
  googleOAuth: true,
2777
3239
  emailVerification: true
@@ -2811,6 +3273,7 @@ var BLOG_PRESET = {
2811
3273
  blog: true
2812
3274
  },
2813
3275
  auth: {
3276
+ registrationMode: "invitation-only",
2814
3277
  emailPassword: true,
2815
3278
  googleOAuth: false,
2816
3279
  emailVerification: false
@@ -2850,6 +3313,7 @@ var CRM_PRESET = {
2850
3313
  blog: false
2851
3314
  },
2852
3315
  auth: {
3316
+ registrationMode: "invitation-only",
2853
3317
  emailPassword: true,
2854
3318
  googleOAuth: true,
2855
3319
  emailVerification: true
@@ -2897,7 +3361,7 @@ function applyPreset(projectInfo, presetName, typeOverride) {
2897
3361
  }
2898
3362
 
2899
3363
  // src/wizard/preview.ts
2900
- import chalk6 from "chalk";
3364
+ import chalk10 from "chalk";
2901
3365
  var BOX = {
2902
3366
  vertical: "\u2502",
2903
3367
  // |
@@ -2990,12 +3454,12 @@ function showConfigPreview(config2) {
2990
3454
  const groups = groupFilesByCategory(files);
2991
3455
  const themeDir = `contents/themes/${config2.projectSlug}`;
2992
3456
  console.log("");
2993
- console.log(chalk6.cyan.bold(" Theme Preview"));
2994
- console.log(chalk6.gray(" " + "=".repeat(50)));
3457
+ console.log(chalk10.cyan.bold(" Theme Preview"));
3458
+ console.log(chalk10.gray(" " + "=".repeat(50)));
2995
3459
  console.log("");
2996
- console.log(chalk6.white.bold(` ${BOX.topLeft}${"\u2500".repeat(48)}${BOX.topRight}`));
2997
- console.log(chalk6.white.bold(` ${BOX.vertical}`) + chalk6.cyan(` ${themeDir}/`) + " ".repeat(48 - themeDir.length - 2) + chalk6.white.bold(BOX.vertical));
2998
- console.log(chalk6.white.bold(` ${BOX.vertical}${"\u2500".repeat(48)}${BOX.vertical}`));
3460
+ console.log(chalk10.white.bold(` ${BOX.topLeft}${"\u2500".repeat(48)}${BOX.topRight}`));
3461
+ console.log(chalk10.white.bold(` ${BOX.vertical}`) + chalk10.cyan(` ${themeDir}/`) + " ".repeat(48 - themeDir.length - 2) + chalk10.white.bold(BOX.vertical));
3462
+ console.log(chalk10.white.bold(` ${BOX.vertical}${"\u2500".repeat(48)}${BOX.vertical}`));
2999
3463
  const categoryLabels = {
3000
3464
  config: "Configuration",
3001
3465
  entities: "Entities",
@@ -3020,40 +3484,40 @@ function showConfigPreview(config2) {
3020
3484
  if (categoryFiles.length === 0) continue;
3021
3485
  const label = categoryLabels[category];
3022
3486
  const icon = categoryIcons[category];
3023
- console.log(chalk6.white.bold(` ${BOX.vertical} `) + chalk6.yellow(`[${icon}] ${label}`) + chalk6.gray(` (${categoryFiles.length} files)`));
3487
+ console.log(chalk10.white.bold(` ${BOX.vertical} `) + chalk10.yellow(`[${icon}] ${label}`) + chalk10.gray(` (${categoryFiles.length} files)`));
3024
3488
  for (let i = 0; i < categoryFiles.length; i++) {
3025
3489
  const file = categoryFiles[i];
3026
3490
  const isLast = i === categoryFiles.length - 1;
3027
3491
  const prefix = isLast ? BOX.corner : BOX.tee;
3028
3492
  const formattedPath = formatFilePath(file, themeDir);
3029
- console.log(chalk6.white.bold(` ${BOX.vertical} `) + chalk6.gray(` ${prefix}${BOX.horizontal} `) + chalk6.white(formattedPath));
3493
+ console.log(chalk10.white.bold(` ${BOX.vertical} `) + chalk10.gray(` ${prefix}${BOX.horizontal} `) + chalk10.white(formattedPath));
3030
3494
  }
3031
- console.log(chalk6.white.bold(` ${BOX.vertical}`));
3495
+ console.log(chalk10.white.bold(` ${BOX.vertical}`));
3032
3496
  }
3033
- console.log(chalk6.white.bold(` ${BOX.bottomLeft}${"\u2500".repeat(48)}${BOX.bottomRight}`));
3497
+ console.log(chalk10.white.bold(` ${BOX.bottomLeft}${"\u2500".repeat(48)}${BOX.bottomRight}`));
3034
3498
  console.log("");
3035
- console.log(chalk6.cyan.bold(" Summary"));
3036
- console.log(chalk6.gray(" " + "-".repeat(30)));
3499
+ console.log(chalk10.cyan.bold(" Summary"));
3500
+ console.log(chalk10.gray(" " + "-".repeat(30)));
3037
3501
  console.log("");
3038
3502
  const totalFiles = files.length;
3039
3503
  const estimatedSize = "~350KB";
3040
- console.log(chalk6.white(` Total files: `) + chalk6.green.bold(totalFiles.toString()));
3041
- console.log(chalk6.white(` Estimated size: `) + chalk6.green.bold(estimatedSize));
3504
+ console.log(chalk10.white(` Total files: `) + chalk10.green.bold(totalFiles.toString()));
3505
+ console.log(chalk10.white(` Estimated size: `) + chalk10.green.bold(estimatedSize));
3042
3506
  console.log("");
3043
- console.log(chalk6.gray(" By category:"));
3507
+ console.log(chalk10.gray(" By category:"));
3044
3508
  for (const category of categoryOrder) {
3045
3509
  const count = groups[category].length;
3046
3510
  if (count > 0) {
3047
3511
  const label = categoryLabels[category].padEnd(16);
3048
- console.log(chalk6.gray(` ${label}`) + chalk6.white(count.toString().padStart(3)) + chalk6.gray(" files"));
3512
+ console.log(chalk10.gray(` ${label}`) + chalk10.white(count.toString().padStart(3)) + chalk10.gray(" files"));
3049
3513
  }
3050
3514
  }
3051
3515
  console.log("");
3052
- console.log(chalk6.gray(" Locales configured:"));
3516
+ console.log(chalk10.gray(" Locales configured:"));
3053
3517
  for (const locale of config2.supportedLocales) {
3054
3518
  const isDefault = locale === config2.defaultLocale;
3055
- const suffix = isDefault ? chalk6.cyan(" (default)") : "";
3056
- console.log(chalk6.gray(` - `) + chalk6.white(locale) + suffix);
3519
+ const suffix = isDefault ? chalk10.cyan(" (default)") : "";
3520
+ console.log(chalk10.gray(` - `) + chalk10.white(locale) + suffix);
3057
3521
  }
3058
3522
  console.log("");
3059
3523
  }
@@ -3137,7 +3601,7 @@ async function runWizard(options = { mode: "interactive" }) {
3137
3601
  }
3138
3602
  }
3139
3603
  console.log("");
3140
- const spinner = ora3({
3604
+ const spinner = ora7({
3141
3605
  text: "Generating your NextSpark project...",
3142
3606
  prefixText: " "
3143
3607
  }).start();
@@ -3154,7 +3618,7 @@ async function runWizard(options = { mode: "interactive" }) {
3154
3618
  const projectRoot = process.cwd();
3155
3619
  const webDir = getWebDir(projectRoot, config2);
3156
3620
  const isMonorepo = isMonorepoProject(config2);
3157
- const installSpinner = ora3({
3621
+ const installSpinner = ora7({
3158
3622
  text: isMonorepo ? "Installing dependencies (monorepo)..." : "Installing dependencies...",
3159
3623
  prefixText: " "
3160
3624
  }).start();
@@ -3168,14 +3632,14 @@ async function runWizard(options = { mode: "interactive" }) {
3168
3632
  installSpinner.succeed("Dependencies installed!");
3169
3633
  } catch (error) {
3170
3634
  installSpinner.fail("Failed to install dependencies");
3171
- console.log(chalk7.yellow(' Run "pnpm install" manually to install dependencies'));
3635
+ console.log(chalk11.yellow(' Run "pnpm install" manually to install dependencies'));
3172
3636
  }
3173
- const registrySpinner = ora3({
3637
+ const registrySpinner = ora7({
3174
3638
  text: "Building registries...",
3175
3639
  prefixText: " "
3176
3640
  }).start();
3177
3641
  try {
3178
- const registryScript = join4(webDir, "node_modules/@nextsparkjs/core/scripts/build/registry.mjs");
3642
+ const registryScript = join8(webDir, "node_modules/@nextsparkjs/core/scripts/build/registry.mjs");
3179
3643
  registrySpinner.stop();
3180
3644
  execSync(`node "${registryScript}" --build`, {
3181
3645
  cwd: webDir,
@@ -3190,7 +3654,7 @@ async function runWizard(options = { mode: "interactive" }) {
3190
3654
  } catch (error) {
3191
3655
  registrySpinner.fail("Failed to build registries");
3192
3656
  const devCmd = isMonorepo ? "pnpm dev" : "pnpm dev";
3193
- console.log(chalk7.yellow(` Registries will be built automatically when you run "${devCmd}"`));
3657
+ console.log(chalk11.yellow(` Registries will be built automatically when you run "${devCmd}"`));
3194
3658
  }
3195
3659
  const aiChoice = await promptAIWorkflowSetup(config2);
3196
3660
  showNextSteps(config2, selectedTheme, aiChoice);
@@ -3208,7 +3672,7 @@ async function runWizard(options = { mode: "interactive" }) {
3208
3672
  }
3209
3673
  function showModeIndicator(options) {
3210
3674
  if (options.preset) {
3211
- showInfo(`Using preset: ${chalk7.cyan(options.preset)} - ${PRESET_DESCRIPTIONS[options.preset]}`);
3675
+ showInfo(`Using preset: ${chalk11.cyan(options.preset)} - ${PRESET_DESCRIPTIONS[options.preset]}`);
3212
3676
  console.log("");
3213
3677
  } else if (options.mode === "quick") {
3214
3678
  showInfo("Quick mode: Running essential prompts only (steps 1-5)");
@@ -3238,43 +3702,52 @@ async function runPresetMode(presetName, options) {
3238
3702
  }
3239
3703
  function showConfigSummary(config2) {
3240
3704
  console.log("");
3241
- console.log(chalk7.cyan(" " + "=".repeat(60)));
3242
- console.log(chalk7.bold.white(" Configuration Summary"));
3243
- console.log(chalk7.cyan(" " + "=".repeat(60)));
3705
+ console.log(chalk11.cyan(" " + "=".repeat(60)));
3706
+ console.log(chalk11.bold.white(" Configuration Summary"));
3707
+ console.log(chalk11.cyan(" " + "=".repeat(60)));
3244
3708
  console.log("");
3245
- console.log(chalk7.white(" Project:"));
3246
- console.log(chalk7.gray(` Name: ${chalk7.white(config2.projectName)}`));
3247
- console.log(chalk7.gray(` Slug: ${chalk7.white(config2.projectSlug)}`));
3248
- console.log(chalk7.gray(` Description: ${chalk7.white(config2.projectDescription)}`));
3249
- console.log(chalk7.gray(` Type: ${chalk7.white(config2.projectType === "web-mobile" ? "Web + Mobile (Monorepo)" : "Web only")}`));
3709
+ console.log(chalk11.white(" Project:"));
3710
+ console.log(chalk11.gray(` Name: ${chalk11.white(config2.projectName)}`));
3711
+ console.log(chalk11.gray(` Slug: ${chalk11.white(config2.projectSlug)}`));
3712
+ console.log(chalk11.gray(` Description: ${chalk11.white(config2.projectDescription)}`));
3713
+ console.log(chalk11.gray(` Type: ${chalk11.white(config2.projectType === "web-mobile" ? "Web + Mobile (Monorepo)" : "Web only")}`));
3250
3714
  console.log("");
3251
- console.log(chalk7.white(" Team Mode:"));
3252
- console.log(chalk7.gray(` Mode: ${chalk7.white(config2.teamMode)}`));
3253
- console.log(chalk7.gray(` Roles: ${chalk7.white(config2.teamRoles.join(", "))}`));
3715
+ console.log(chalk11.white(" Team Mode:"));
3716
+ console.log(chalk11.gray(` Mode: ${chalk11.white(config2.teamMode)}`));
3717
+ console.log(chalk11.gray(` Roles: ${chalk11.white(config2.teamRoles.join(", "))}`));
3254
3718
  console.log("");
3255
- console.log(chalk7.white(" Internationalization:"));
3256
- console.log(chalk7.gray(` Default: ${chalk7.white(config2.defaultLocale)}`));
3257
- console.log(chalk7.gray(` Languages: ${chalk7.white(config2.supportedLocales.join(", "))}`));
3719
+ console.log(chalk11.white(" Internationalization:"));
3720
+ console.log(chalk11.gray(` Default: ${chalk11.white(config2.defaultLocale)}`));
3721
+ console.log(chalk11.gray(` Languages: ${chalk11.white(config2.supportedLocales.join(", "))}`));
3258
3722
  console.log("");
3259
- console.log(chalk7.white(" Billing:"));
3260
- console.log(chalk7.gray(` Model: ${chalk7.white(config2.billingModel)}`));
3261
- console.log(chalk7.gray(` Currency: ${chalk7.white(config2.currency.toUpperCase())}`));
3723
+ console.log(chalk11.white(" Billing:"));
3724
+ console.log(chalk11.gray(` Model: ${chalk11.white(config2.billingModel)}`));
3725
+ console.log(chalk11.gray(` Currency: ${chalk11.white(config2.currency.toUpperCase())}`));
3262
3726
  console.log("");
3263
- console.log(chalk7.white(" Features:"));
3727
+ console.log(chalk11.white(" Features:"));
3264
3728
  const enabledFeatures = Object.entries(config2.features).filter(([_, enabled]) => enabled).map(([feature]) => feature);
3265
- console.log(chalk7.gray(` Enabled: ${chalk7.white(enabledFeatures.join(", ") || "None")}`));
3729
+ console.log(chalk11.gray(` Enabled: ${chalk11.white(enabledFeatures.join(", ") || "None")}`));
3266
3730
  console.log("");
3267
- console.log(chalk7.white(" Authentication:"));
3268
- const enabledAuth = Object.entries(config2.auth).filter(([_, enabled]) => enabled).map(([method]) => formatAuthMethod(method));
3269
- console.log(chalk7.gray(` Methods: ${chalk7.white(enabledAuth.join(", ") || "None")}`));
3731
+ console.log(chalk11.white(" Authentication:"));
3732
+ console.log(chalk11.gray(` Registration: ${chalk11.white(formatRegistrationMode(config2.auth.registrationMode))}`));
3733
+ const enabledAuth = Object.entries(config2.auth).filter(([key, enabled]) => key !== "registrationMode" && enabled).map(([method]) => formatAuthMethod(method));
3734
+ console.log(chalk11.gray(` Methods: ${chalk11.white(enabledAuth.join(", ") || "None")}`));
3270
3735
  console.log("");
3271
- console.log(chalk7.white(" Dashboard:"));
3736
+ console.log(chalk11.white(" Dashboard:"));
3272
3737
  const enabledDashboard = Object.entries(config2.dashboard).filter(([_, enabled]) => enabled).map(([feature]) => formatDashboardFeature(feature));
3273
- console.log(chalk7.gray(` Features: ${chalk7.white(enabledDashboard.join(", ") || "None")}`));
3738
+ console.log(chalk11.gray(` Features: ${chalk11.white(enabledDashboard.join(", ") || "None")}`));
3274
3739
  console.log("");
3275
- console.log(chalk7.white(" Dev Tools:"));
3740
+ console.log(chalk11.white(" Dev Tools:"));
3276
3741
  const enabledDevTools = Object.entries(config2.dev).filter(([_, enabled]) => enabled).map(([tool]) => formatDevTool(tool));
3277
- console.log(chalk7.gray(` Enabled: ${chalk7.white(enabledDevTools.join(", ") || "None")}`));
3742
+ console.log(chalk11.gray(` Enabled: ${chalk11.white(enabledDevTools.join(", ") || "None")}`));
3743
+ }
3744
+ function formatRegistrationMode(mode) {
3745
+ const mapping = {
3746
+ "open": "Open (anyone can register)",
3747
+ "domain-restricted": "Domain-Restricted (Google OAuth only)",
3748
+ "invitation-only": "Invitation-Only"
3749
+ };
3750
+ return mapping[mode] || mode;
3278
3751
  }
3279
3752
  function formatAuthMethod(method) {
3280
3753
  const mapping = {
@@ -3304,68 +3777,68 @@ function showNextSteps(config2, referenceTheme = null, aiChoice = "skip") {
3304
3777
  const isMonorepo = config2.projectType === "web-mobile";
3305
3778
  const aiSetupDone = aiChoice === "claude";
3306
3779
  console.log("");
3307
- console.log(chalk7.cyan(" " + "=".repeat(60)));
3308
- console.log(chalk7.bold.green(" \u2728 NextSpark project ready!"));
3309
- console.log(chalk7.cyan(" " + "=".repeat(60)));
3780
+ console.log(chalk11.cyan(" " + "=".repeat(60)));
3781
+ console.log(chalk11.bold.green(" \u2728 NextSpark project ready!"));
3782
+ console.log(chalk11.cyan(" " + "=".repeat(60)));
3310
3783
  console.log("");
3311
- console.log(chalk7.bold.white(" Next steps:"));
3784
+ console.log(chalk11.bold.white(" Next steps:"));
3312
3785
  console.log("");
3313
3786
  const envPath = isMonorepo ? "web/.env" : ".env";
3314
- console.log(chalk7.white(" 1. Configure your environment:"));
3315
- console.log(chalk7.gray(` Edit ${envPath} with your credentials:`));
3787
+ console.log(chalk11.white(" 1. Configure your environment:"));
3788
+ console.log(chalk11.gray(` Edit ${envPath} with your credentials:`));
3316
3789
  console.log("");
3317
- console.log(chalk7.yellow(" DATABASE_URL"));
3318
- console.log(chalk7.gray(" PostgreSQL connection string"));
3319
- console.log(chalk7.gray(` Recommended: ${chalk7.cyan("https://supabase.com")} | ${chalk7.cyan("https://neon.com")}`));
3790
+ console.log(chalk11.yellow(" DATABASE_URL"));
3791
+ console.log(chalk11.gray(" PostgreSQL connection string"));
3792
+ console.log(chalk11.gray(` Recommended: ${chalk11.cyan("https://supabase.com")} | ${chalk11.cyan("https://neon.com")}`));
3320
3793
  console.log("");
3321
- console.log(chalk7.yellow(" BETTER_AUTH_SECRET"));
3322
- console.log(chalk7.gray(" Generate with:"));
3323
- console.log(chalk7.cyan(" openssl rand -base64 32"));
3794
+ console.log(chalk11.yellow(" BETTER_AUTH_SECRET"));
3795
+ console.log(chalk11.gray(" Generate with:"));
3796
+ console.log(chalk11.cyan(" openssl rand -base64 32"));
3324
3797
  console.log("");
3325
- console.log(chalk7.white(" 2. Run database migrations:"));
3326
- console.log(chalk7.cyan(" pnpm db:migrate"));
3798
+ console.log(chalk11.white(" 2. Run database migrations:"));
3799
+ console.log(chalk11.cyan(" pnpm db:migrate"));
3327
3800
  console.log("");
3328
- console.log(chalk7.white(" 3. Start the development server:"));
3329
- console.log(chalk7.cyan(" pnpm dev"));
3801
+ console.log(chalk11.white(" 3. Start the development server:"));
3802
+ console.log(chalk11.cyan(" pnpm dev"));
3330
3803
  console.log("");
3331
3804
  let nextStep = 4;
3332
3805
  if (isMonorepo) {
3333
- console.log(chalk7.white(` ${nextStep}. (Optional) Start the mobile app:`));
3334
- console.log(chalk7.cyan(" pnpm dev:mobile"));
3335
- console.log(chalk7.gray(" Or: cd mobile && pnpm start"));
3806
+ console.log(chalk11.white(` ${nextStep}. (Optional) Start the mobile app:`));
3807
+ console.log(chalk11.cyan(" pnpm dev:mobile"));
3808
+ console.log(chalk11.gray(" Or: cd mobile && pnpm start"));
3336
3809
  console.log("");
3337
3810
  nextStep++;
3338
3811
  }
3339
3812
  if (aiSetupDone) {
3340
- console.log(chalk7.white(` ${nextStep}. Start building with AI:`));
3341
- console.log(chalk7.gray(" Open Claude Code in your project and run:"));
3342
- console.log(chalk7.cyan(" /how-to:start"));
3813
+ console.log(chalk11.white(` ${nextStep}. Start building with AI:`));
3814
+ console.log(chalk11.gray(" Open Claude Code in your project and run:"));
3815
+ console.log(chalk11.cyan(" /how-to:start"));
3343
3816
  console.log("");
3344
3817
  } else {
3345
- console.log(chalk7.white(` ${nextStep}. (Optional) Setup AI workflows:`));
3346
- console.log(chalk7.cyan(" nextspark setup:ai"));
3818
+ console.log(chalk11.white(` ${nextStep}. (Optional) Setup AI workflows:`));
3819
+ console.log(chalk11.cyan(" nextspark setup:ai"));
3347
3820
  console.log("");
3348
3821
  }
3349
- console.log(chalk7.gray(" " + "-".repeat(60)));
3822
+ console.log(chalk11.gray(" " + "-".repeat(60)));
3350
3823
  if (isMonorepo) {
3351
- console.log(chalk7.gray(` Structure: ${chalk7.white("Monorepo (web/ + mobile/)")}`));
3352
- console.log(chalk7.gray(` Web theme: ${chalk7.white(`web/contents/themes/${config2.projectSlug}/`)}`));
3353
- console.log(chalk7.gray(` Mobile app: ${chalk7.white("mobile/")}`));
3354
- console.log(chalk7.gray(` Active theme: ${chalk7.green(`NEXT_PUBLIC_ACTIVE_THEME=${config2.projectSlug}`)}`));
3824
+ console.log(chalk11.gray(` Structure: ${chalk11.white("Monorepo (web/ + mobile/)")}`));
3825
+ console.log(chalk11.gray(` Web theme: ${chalk11.white(`web/contents/themes/${config2.projectSlug}/`)}`));
3826
+ console.log(chalk11.gray(` Mobile app: ${chalk11.white("mobile/")}`));
3827
+ console.log(chalk11.gray(` Active theme: ${chalk11.green(`NEXT_PUBLIC_ACTIVE_THEME=${config2.projectSlug}`)}`));
3355
3828
  } else {
3356
- console.log(chalk7.gray(` Theme: ${chalk7.white(`contents/themes/${config2.projectSlug}/`)}`));
3357
- console.log(chalk7.gray(` Active theme: ${chalk7.green(`NEXT_PUBLIC_ACTIVE_THEME=${config2.projectSlug}`)}`));
3829
+ console.log(chalk11.gray(` Theme: ${chalk11.white(`contents/themes/${config2.projectSlug}/`)}`));
3830
+ console.log(chalk11.gray(` Active theme: ${chalk11.green(`NEXT_PUBLIC_ACTIVE_THEME=${config2.projectSlug}`)}`));
3358
3831
  }
3359
3832
  if (referenceTheme) {
3360
3833
  const refPath = isMonorepo ? `web/contents/themes/${referenceTheme}/` : `contents/themes/${referenceTheme}/`;
3361
- console.log(chalk7.gray(` Reference: ${chalk7.white(refPath)}`));
3834
+ console.log(chalk11.gray(` Reference: ${chalk11.white(refPath)}`));
3362
3835
  }
3363
- console.log(chalk7.gray(` Docs: ${chalk7.cyan("https://nextspark.dev/docs")}`));
3836
+ console.log(chalk11.gray(` Docs: ${chalk11.cyan("https://nextspark.dev/docs")}`));
3364
3837
  console.log("");
3365
3838
  }
3366
3839
  async function promptAIWorkflowSetup(config2) {
3367
3840
  console.log("");
3368
- const choice = await select6({
3841
+ const choice = await select7({
3369
3842
  message: "Setup AI-assisted development workflows?",
3370
3843
  choices: [
3371
3844
  { name: "Claude Code (Recommended)", value: "claude" },
@@ -3388,11 +3861,11 @@ async function promptAIWorkflowSetup(config2) {
3388
3861
  cwd: projectRoot,
3389
3862
  stdio: "inherit"
3390
3863
  });
3391
- let setupScript = join4(projectRoot, "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3392
- if (!existsSync3(setupScript) && isMonorepo) {
3393
- setupScript = join4(projectRoot, "web", "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3864
+ let setupScript = join8(projectRoot, "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3865
+ if (!existsSync7(setupScript) && isMonorepo) {
3866
+ setupScript = join8(projectRoot, "web", "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3394
3867
  }
3395
- if (existsSync3(setupScript)) {
3868
+ if (existsSync7(setupScript)) {
3396
3869
  execSync(`node "${setupScript}" ${choice}`, {
3397
3870
  cwd: projectRoot,
3398
3871
  stdio: "inherit"
@@ -3415,21 +3888,21 @@ function findLocalCoreTarball() {
3415
3888
  (f) => f.includes("nextsparkjs-core") && f.endsWith(".tgz")
3416
3889
  );
3417
3890
  if (coreTarball) {
3418
- return join4(cwd, coreTarball);
3891
+ return join8(cwd, coreTarball);
3419
3892
  }
3420
3893
  } catch {
3421
3894
  }
3422
3895
  return null;
3423
3896
  }
3424
3897
  function isCoreInstalled() {
3425
- const corePath = join4(process.cwd(), "node_modules", "@nextsparkjs", "core");
3426
- return existsSync3(corePath);
3898
+ const corePath = join8(process.cwd(), "node_modules", "@nextsparkjs", "core");
3899
+ return existsSync7(corePath);
3427
3900
  }
3428
3901
  async function installCore() {
3429
3902
  if (isCoreInstalled()) {
3430
3903
  return true;
3431
3904
  }
3432
- const spinner = ora3({
3905
+ const spinner = ora7({
3433
3906
  text: "Installing @nextsparkjs/core...",
3434
3907
  prefixText: " "
3435
3908
  }).start();
@@ -3440,8 +3913,8 @@ async function installCore() {
3440
3913
  packageSpec = localTarball;
3441
3914
  spinner.text = "Installing @nextsparkjs/core from local tarball...";
3442
3915
  }
3443
- const useYarn = existsSync3(join4(process.cwd(), "yarn.lock"));
3444
- const usePnpm = existsSync3(join4(process.cwd(), "pnpm-lock.yaml"));
3916
+ const useYarn = existsSync7(join8(process.cwd(), "yarn.lock"));
3917
+ const usePnpm = existsSync7(join8(process.cwd(), "pnpm-lock.yaml"));
3445
3918
  let installCmd;
3446
3919
  if (usePnpm) {
3447
3920
  installCmd = `pnpm add ${packageSpec}`;
@@ -3455,20 +3928,20 @@ async function installCore() {
3455
3928
  stdio: "inherit",
3456
3929
  cwd: process.cwd()
3457
3930
  });
3458
- spinner.succeed(chalk7.green("@nextsparkjs/core installed successfully!"));
3931
+ spinner.succeed(chalk11.green("@nextsparkjs/core installed successfully!"));
3459
3932
  return true;
3460
3933
  } catch (error) {
3461
- spinner.fail(chalk7.red("Failed to install @nextsparkjs/core"));
3934
+ spinner.fail(chalk11.red("Failed to install @nextsparkjs/core"));
3462
3935
  if (error instanceof Error) {
3463
- console.log(chalk7.red(` Error: ${error.message}`));
3936
+ console.log(chalk11.red(` Error: ${error.message}`));
3464
3937
  }
3465
- console.log(chalk7.gray(" Hint: Make sure the package is available (npm registry or local tarball)"));
3938
+ console.log(chalk11.gray(" Hint: Make sure the package is available (npm registry or local tarball)"));
3466
3939
  return false;
3467
3940
  }
3468
3941
  }
3469
3942
  function isMobileInstalled() {
3470
- const mobilePath = join4(process.cwd(), "node_modules", "@nextsparkjs", "mobile");
3471
- return existsSync3(mobilePath);
3943
+ const mobilePath = join8(process.cwd(), "node_modules", "@nextsparkjs", "mobile");
3944
+ return existsSync7(mobilePath);
3472
3945
  }
3473
3946
  function findLocalMobileTarball() {
3474
3947
  const cwd = process.cwd();
@@ -3478,7 +3951,7 @@ function findLocalMobileTarball() {
3478
3951
  (f) => f.includes("nextsparkjs-mobile") && f.endsWith(".tgz")
3479
3952
  );
3480
3953
  if (mobileTarball) {
3481
- return join4(cwd, mobileTarball);
3954
+ return join8(cwd, mobileTarball);
3482
3955
  }
3483
3956
  } catch {
3484
3957
  }
@@ -3488,7 +3961,7 @@ async function installMobile() {
3488
3961
  if (isMobileInstalled()) {
3489
3962
  return true;
3490
3963
  }
3491
- const spinner = ora3({
3964
+ const spinner = ora7({
3492
3965
  text: "Installing @nextsparkjs/mobile...",
3493
3966
  prefixText: " "
3494
3967
  }).start();
@@ -3499,8 +3972,8 @@ async function installMobile() {
3499
3972
  packageSpec = localTarball;
3500
3973
  spinner.text = "Installing @nextsparkjs/mobile from local tarball...";
3501
3974
  }
3502
- const useYarn = existsSync3(join4(process.cwd(), "yarn.lock"));
3503
- const usePnpm = existsSync3(join4(process.cwd(), "pnpm-lock.yaml"));
3975
+ const useYarn = existsSync7(join8(process.cwd(), "yarn.lock"));
3976
+ const usePnpm = existsSync7(join8(process.cwd(), "pnpm-lock.yaml"));
3504
3977
  let installCmd;
3505
3978
  if (usePnpm) {
3506
3979
  installCmd = `pnpm add ${packageSpec}`;
@@ -3514,14 +3987,14 @@ async function installMobile() {
3514
3987
  stdio: "inherit",
3515
3988
  cwd: process.cwd()
3516
3989
  });
3517
- spinner.succeed(chalk7.green("@nextsparkjs/mobile installed successfully!"));
3990
+ spinner.succeed(chalk11.green("@nextsparkjs/mobile installed successfully!"));
3518
3991
  return true;
3519
3992
  } catch (error) {
3520
- spinner.fail(chalk7.red("Failed to install @nextsparkjs/mobile"));
3993
+ spinner.fail(chalk11.red("Failed to install @nextsparkjs/mobile"));
3521
3994
  if (error instanceof Error) {
3522
- console.log(chalk7.red(` Error: ${error.message}`));
3995
+ console.log(chalk11.red(` Error: ${error.message}`));
3523
3996
  }
3524
- console.log(chalk7.gray(" Hint: Make sure the package is available (npm registry or local tarball)"));
3997
+ console.log(chalk11.gray(" Hint: Make sure the package is available (npm registry or local tarball)"));
3525
3998
  return false;
3526
3999
  }
3527
4000
  }
@@ -3538,10 +4011,10 @@ function parsePlugins(pluginsStr) {
3538
4011
  }
3539
4012
  function hasExistingProject() {
3540
4013
  const projectRoot = process.cwd();
3541
- return existsSync4(join5(projectRoot, "contents")) || existsSync4(join5(projectRoot, ".nextspark"));
4014
+ return existsSync8(join9(projectRoot, "contents")) || existsSync8(join9(projectRoot, ".nextspark"));
3542
4015
  }
3543
4016
  function generateInitialRegistries(registriesDir) {
3544
- writeFileSync2(join5(registriesDir, "block-registry.ts"), `// Auto-generated by nextspark init
4017
+ writeFileSync2(join9(registriesDir, "block-registry.ts"), `// Auto-generated by nextspark init
3545
4018
  import type { ComponentType } from 'react'
3546
4019
 
3547
4020
  export const BLOCK_REGISTRY: Record<string, {
@@ -3554,26 +4027,26 @@ export const BLOCK_REGISTRY: Record<string, {
3554
4027
 
3555
4028
  export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<ComponentType<any>>> = {}
3556
4029
  `);
3557
- writeFileSync2(join5(registriesDir, "theme-registry.ts"), `// Auto-generated by nextspark init
4030
+ writeFileSync2(join9(registriesDir, "theme-registry.ts"), `// Auto-generated by nextspark init
3558
4031
  export const THEME_REGISTRY: Record<string, unknown> = {}
3559
4032
  `);
3560
- writeFileSync2(join5(registriesDir, "entity-registry.ts"), `// Auto-generated by nextspark init
4033
+ writeFileSync2(join9(registriesDir, "entity-registry.ts"), `// Auto-generated by nextspark init
3561
4034
  export const ENTITY_REGISTRY: Record<string, unknown> = {}
3562
4035
  `);
3563
- writeFileSync2(join5(registriesDir, "entity-registry.client.ts"), `// Auto-generated by nextspark init
4036
+ writeFileSync2(join9(registriesDir, "entity-registry.client.ts"), `// Auto-generated by nextspark init
3564
4037
  export const CLIENT_ENTITY_REGISTRY: Record<string, unknown> = {}
3565
4038
  export function parseChildEntity(path: string) { return null }
3566
4039
  export function getEntityApiPath(entity: string) { return \`/api/\${entity}\` }
3567
4040
  export function clientMetaSystemAdapter() { return {} }
3568
4041
  export type ClientEntityConfig = Record<string, unknown>
3569
4042
  `);
3570
- writeFileSync2(join5(registriesDir, "billing-registry.ts"), `// Auto-generated by nextspark init
4043
+ writeFileSync2(join9(registriesDir, "billing-registry.ts"), `// Auto-generated by nextspark init
3571
4044
  export const BILLING_REGISTRY = { plans: [], features: [] }
3572
4045
  `);
3573
- writeFileSync2(join5(registriesDir, "plugin-registry.ts"), `// Auto-generated by nextspark init
4046
+ writeFileSync2(join9(registriesDir, "plugin-registry.ts"), `// Auto-generated by nextspark init
3574
4047
  export const PLUGIN_REGISTRY: Record<string, unknown> = {}
3575
4048
  `);
3576
- writeFileSync2(join5(registriesDir, "testing-registry.ts"), `// Auto-generated by nextspark init
4049
+ writeFileSync2(join9(registriesDir, "testing-registry.ts"), `// Auto-generated by nextspark init
3577
4050
  export const FLOW_REGISTRY: Record<string, unknown> = {}
3578
4051
  export const FEATURE_REGISTRY: Record<string, unknown> = {}
3579
4052
  export const TAGS_REGISTRY: Record<string, unknown> = {}
@@ -3581,11 +4054,11 @@ export const COVERAGE_SUMMARY = { total: 0, covered: 0 }
3581
4054
  export type FlowEntry = unknown
3582
4055
  export type FeatureEntry = unknown
3583
4056
  `);
3584
- writeFileSync2(join5(registriesDir, "docs-registry.ts"), `// Auto-generated by nextspark init
4057
+ writeFileSync2(join9(registriesDir, "docs-registry.ts"), `// Auto-generated by nextspark init
3585
4058
  export const DOCS_REGISTRY = { sections: [], pages: [] }
3586
4059
  export type DocSectionMeta = { title: string; slug: string }
3587
4060
  `);
3588
- writeFileSync2(join5(registriesDir, "index.ts"), `// Auto-generated by nextspark init
4061
+ writeFileSync2(join9(registriesDir, "index.ts"), `// Auto-generated by nextspark init
3589
4062
  export * from './block-registry'
3590
4063
  export * from './theme-registry'
3591
4064
  export * from './entity-registry'
@@ -3597,21 +4070,21 @@ export * from './docs-registry'
3597
4070
  `);
3598
4071
  }
3599
4072
  async function simpleInit(options) {
3600
- const spinner = ora4("Initializing NextSpark project...").start();
4073
+ const spinner = ora8("Initializing NextSpark project...").start();
3601
4074
  const projectRoot = process.cwd();
3602
4075
  try {
3603
- const nextspark = join5(projectRoot, ".nextspark");
3604
- const registriesDir = join5(nextspark, "registries");
3605
- if (!existsSync4(registriesDir) || options.force) {
4076
+ const nextspark = join9(projectRoot, ".nextspark");
4077
+ const registriesDir = join9(nextspark, "registries");
4078
+ if (!existsSync8(registriesDir) || options.force) {
3606
4079
  mkdirSync2(registriesDir, { recursive: true });
3607
4080
  spinner.text = "Creating .nextspark/registries/";
3608
4081
  generateInitialRegistries(registriesDir);
3609
4082
  spinner.text = "Generated initial registries";
3610
4083
  }
3611
- const tsconfigPath = join5(projectRoot, "tsconfig.json");
3612
- if (existsSync4(tsconfigPath)) {
4084
+ const tsconfigPath = join9(projectRoot, "tsconfig.json");
4085
+ if (existsSync8(tsconfigPath)) {
3613
4086
  spinner.text = "Updating tsconfig.json paths...";
3614
- const tsconfig = JSON.parse(readFileSync4(tsconfigPath, "utf-8"));
4087
+ const tsconfig = JSON.parse(readFileSync7(tsconfigPath, "utf-8"));
3615
4088
  tsconfig.compilerOptions = tsconfig.compilerOptions || {};
3616
4089
  tsconfig.compilerOptions.paths = {
3617
4090
  ...tsconfig.compilerOptions.paths,
@@ -3620,8 +4093,8 @@ async function simpleInit(options) {
3620
4093
  };
3621
4094
  writeFileSync2(tsconfigPath, JSON.stringify(tsconfig, null, 2));
3622
4095
  }
3623
- const envExample = join5(projectRoot, ".env.example");
3624
- if (!existsSync4(envExample)) {
4096
+ const envExample = join9(projectRoot, ".env.example");
4097
+ if (!existsSync8(envExample)) {
3625
4098
  const envContent = `# NextSpark Configuration
3626
4099
  DATABASE_URL="postgresql://user:password@localhost:5432/db"
3627
4100
  BETTER_AUTH_SECRET="your-secret-here-min-32-chars"
@@ -3632,14 +4105,14 @@ NEXT_PUBLIC_APP_URL=http://localhost:3000
3632
4105
  spinner.text = "Created .env.example";
3633
4106
  }
3634
4107
  spinner.succeed("NextSpark initialized successfully!");
3635
- console.log(chalk8.blue("\nNext steps:"));
4108
+ console.log(chalk12.blue("\nNext steps:"));
3636
4109
  console.log(" 1. Copy .env.example to .env and configure");
3637
4110
  console.log(" 2. Run: nextspark generate");
3638
4111
  console.log(" 3. Run: nextspark dev");
3639
4112
  } catch (error) {
3640
4113
  spinner.fail("Initialization failed");
3641
4114
  if (error instanceof Error) {
3642
- console.error(chalk8.red(error.message));
4115
+ console.error(chalk12.red(error.message));
3643
4116
  }
3644
4117
  process.exit(1);
3645
4118
  }
@@ -3650,8 +4123,8 @@ async function initCommand(options) {
3650
4123
  return;
3651
4124
  }
3652
4125
  if (hasExistingProject() && !options.wizard && !options.preset && !options.theme) {
3653
- console.log(chalk8.yellow("Existing NextSpark project detected."));
3654
- console.log(chalk8.gray("Use --wizard to run the full wizard, or --registries-only for just registries."));
4126
+ console.log(chalk12.yellow("Existing NextSpark project detected."));
4127
+ console.log(chalk12.gray("Use --wizard to run the full wizard, or --registries-only for just registries."));
3655
4128
  await simpleInit(options);
3656
4129
  return;
3657
4130
  }
@@ -3670,23 +4143,23 @@ async function initCommand(options) {
3670
4143
  }
3671
4144
 
3672
4145
  // src/commands/add-mobile.ts
3673
- import { existsSync as existsSync5, cpSync as cpSync2, readFileSync as readFileSync5, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync3 } from "fs";
3674
- import { join as join6 } from "path";
3675
- import chalk9 from "chalk";
3676
- import ora5 from "ora";
4146
+ import { existsSync as existsSync9, cpSync as cpSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync3 } from "fs";
4147
+ import { join as join10 } from "path";
4148
+ import chalk13 from "chalk";
4149
+ import ora9 from "ora";
3677
4150
  import { execSync as execSync2 } from "child_process";
3678
4151
  function findMobileCoreDir() {
3679
4152
  const projectRoot = process.cwd();
3680
- const npmPath = join6(projectRoot, "node_modules", "@nextsparkjs", "mobile");
3681
- if (existsSync5(npmPath)) {
4153
+ const npmPath = join10(projectRoot, "node_modules", "@nextsparkjs", "mobile");
4154
+ if (existsSync9(npmPath)) {
3682
4155
  return npmPath;
3683
4156
  }
3684
- const monoPath = join6(projectRoot, "packages", "mobile");
3685
- if (existsSync5(monoPath)) {
4157
+ const monoPath = join10(projectRoot, "packages", "mobile");
4158
+ if (existsSync9(monoPath)) {
3686
4159
  return monoPath;
3687
4160
  }
3688
- const parentNpmPath = join6(projectRoot, "..", "node_modules", "@nextsparkjs", "mobile");
3689
- if (existsSync5(parentNpmPath)) {
4161
+ const parentNpmPath = join10(projectRoot, "..", "node_modules", "@nextsparkjs", "mobile");
4162
+ if (existsSync9(parentNpmPath)) {
3690
4163
  return parentNpmPath;
3691
4164
  }
3692
4165
  throw new Error(
@@ -3695,40 +4168,40 @@ function findMobileCoreDir() {
3695
4168
  }
3696
4169
  async function addMobileCommand(options = {}) {
3697
4170
  const projectRoot = process.cwd();
3698
- const mobileDir = join6(projectRoot, "mobile");
4171
+ const mobileDir = join10(projectRoot, "mobile");
3699
4172
  console.log();
3700
- console.log(chalk9.bold("Adding NextSpark Mobile App"));
4173
+ console.log(chalk13.bold("Adding NextSpark Mobile App"));
3701
4174
  console.log();
3702
- if (existsSync5(mobileDir) && !options.force) {
3703
- console.log(chalk9.red("Error: Mobile app already exists at mobile/"));
3704
- console.log(chalk9.gray("Use --force to overwrite"));
4175
+ if (existsSync9(mobileDir) && !options.force) {
4176
+ console.log(chalk13.red("Error: Mobile app already exists at mobile/"));
4177
+ console.log(chalk13.gray("Use --force to overwrite"));
3705
4178
  process.exit(1);
3706
4179
  }
3707
4180
  let mobileCoreDir;
3708
4181
  try {
3709
4182
  mobileCoreDir = findMobileCoreDir();
3710
4183
  } catch (error) {
3711
- console.log(chalk9.red(error.message));
4184
+ console.log(chalk13.red(error.message));
3712
4185
  process.exit(1);
3713
4186
  }
3714
- const templatesDir = join6(mobileCoreDir, "templates");
3715
- if (!existsSync5(templatesDir)) {
3716
- console.log(chalk9.red("Error: Could not find mobile templates"));
3717
- console.log(chalk9.gray(`Expected at: ${templatesDir}`));
4187
+ const templatesDir = join10(mobileCoreDir, "templates");
4188
+ if (!existsSync9(templatesDir)) {
4189
+ console.log(chalk13.red("Error: Could not find mobile templates"));
4190
+ console.log(chalk13.gray(`Expected at: ${templatesDir}`));
3718
4191
  process.exit(1);
3719
4192
  }
3720
- const copySpinner = ora5("Copying mobile app template...").start();
4193
+ const copySpinner = ora9("Copying mobile app template...").start();
3721
4194
  try {
3722
4195
  mkdirSync3(mobileDir, { recursive: true });
3723
4196
  cpSync2(templatesDir, mobileDir, { recursive: true });
3724
- const pkgTemplatePath = join6(mobileDir, "package.json.template");
3725
- const pkgPath = join6(mobileDir, "package.json");
3726
- if (existsSync5(pkgTemplatePath)) {
4197
+ const pkgTemplatePath = join10(mobileDir, "package.json.template");
4198
+ const pkgPath = join10(mobileDir, "package.json");
4199
+ if (existsSync9(pkgTemplatePath)) {
3727
4200
  renameSync(pkgTemplatePath, pkgPath);
3728
- const pkg2 = JSON.parse(readFileSync5(pkgPath, "utf-8"));
3729
- const rootPkgPath = join6(projectRoot, "package.json");
3730
- if (existsSync5(rootPkgPath)) {
3731
- const rootPkg = JSON.parse(readFileSync5(rootPkgPath, "utf-8"));
4201
+ const pkg2 = JSON.parse(readFileSync8(pkgPath, "utf-8"));
4202
+ const rootPkgPath = join10(projectRoot, "package.json");
4203
+ if (existsSync9(rootPkgPath)) {
4204
+ const rootPkg = JSON.parse(readFileSync8(rootPkgPath, "utf-8"));
3732
4205
  const rawName = rootPkg.name || "my-project";
3733
4206
  if (rawName.startsWith("@")) {
3734
4207
  const scopeMatch = rawName.match(/^@[\w-]+/);
@@ -3744,11 +4217,11 @@ async function addMobileCommand(options = {}) {
3744
4217
  copySpinner.succeed("Mobile app template copied");
3745
4218
  } catch (error) {
3746
4219
  copySpinner.fail("Failed to copy templates");
3747
- console.log(chalk9.red(error.message));
4220
+ console.log(chalk13.red(error.message));
3748
4221
  process.exit(1);
3749
4222
  }
3750
4223
  if (!options.skipInstall) {
3751
- const installSpinner = ora5("Installing dependencies...").start();
4224
+ const installSpinner = ora9("Installing dependencies...").start();
3752
4225
  try {
3753
4226
  execSync2("npm install", {
3754
4227
  cwd: mobileDir,
@@ -3759,28 +4232,28 @@ async function addMobileCommand(options = {}) {
3759
4232
  installSpinner.succeed("Dependencies installed");
3760
4233
  } catch (error) {
3761
4234
  installSpinner.fail("Failed to install dependencies");
3762
- console.log(chalk9.yellow(" Run `npm install` in mobile/ manually"));
4235
+ console.log(chalk13.yellow(" Run `npm install` in mobile/ manually"));
3763
4236
  }
3764
4237
  }
3765
4238
  console.log();
3766
- console.log(chalk9.green.bold(" Mobile app created successfully!"));
4239
+ console.log(chalk13.green.bold(" Mobile app created successfully!"));
3767
4240
  console.log();
3768
- console.log(chalk9.bold(" Next steps:"));
4241
+ console.log(chalk13.bold(" Next steps:"));
3769
4242
  console.log();
3770
- console.log(` ${chalk9.cyan("1.")} cd mobile`);
3771
- console.log(` ${chalk9.cyan("2.")} Update ${chalk9.bold("app.config.ts")} with your app name and bundle ID`);
3772
- console.log(` ${chalk9.cyan("3.")} Add your entities in ${chalk9.bold("src/entities/")}`);
3773
- console.log(` ${chalk9.cyan("4.")} npm start`);
4243
+ console.log(` ${chalk13.cyan("1.")} cd mobile`);
4244
+ console.log(` ${chalk13.cyan("2.")} Update ${chalk13.bold("app.config.ts")} with your app name and bundle ID`);
4245
+ console.log(` ${chalk13.cyan("3.")} Add your entities in ${chalk13.bold("src/entities/")}`);
4246
+ console.log(` ${chalk13.cyan("4.")} npm start`);
3774
4247
  console.log();
3775
- console.log(chalk9.gray(" Documentation: https://nextspark.dev/docs/mobile"));
4248
+ console.log(chalk13.gray(" Documentation: https://nextspark.dev/docs/mobile"));
3776
4249
  console.log();
3777
4250
  }
3778
4251
 
3779
4252
  // src/commands/doctor.ts
3780
- import chalk11 from "chalk";
4253
+ import chalk15 from "chalk";
3781
4254
 
3782
4255
  // src/doctor/index.ts
3783
- import chalk10 from "chalk";
4256
+ import chalk14 from "chalk";
3784
4257
 
3785
4258
  // src/doctor/checks/dependencies.ts
3786
4259
  import fs9 from "fs-extra";
@@ -4148,25 +4621,25 @@ async function checkImports() {
4148
4621
 
4149
4622
  // src/doctor/index.ts
4150
4623
  var STATUS_ICONS = {
4151
- pass: chalk10.green("\u2713"),
4152
- warn: chalk10.yellow("\u26A0"),
4153
- fail: chalk10.red("\u2717")
4624
+ pass: chalk14.green("\u2713"),
4625
+ warn: chalk14.yellow("\u26A0"),
4626
+ fail: chalk14.red("\u2717")
4154
4627
  };
4155
4628
  function formatResult(result) {
4156
4629
  const icon = STATUS_ICONS[result.status];
4157
- const nameColor = result.status === "fail" ? chalk10.red : result.status === "warn" ? chalk10.yellow : chalk10.white;
4630
+ const nameColor = result.status === "fail" ? chalk14.red : result.status === "warn" ? chalk14.yellow : chalk14.white;
4158
4631
  const name = nameColor(result.name.padEnd(18));
4159
- const message = chalk10.gray(result.message);
4632
+ const message = chalk14.gray(result.message);
4160
4633
  let output = `${icon} ${name} ${message}`;
4161
4634
  if (result.fix && result.status !== "pass") {
4162
4635
  output += `
4163
- ${" ".repeat(22)}${chalk10.cyan("\u2192")} ${chalk10.cyan(result.fix)}`;
4636
+ ${" ".repeat(22)}${chalk14.cyan("\u2192")} ${chalk14.cyan(result.fix)}`;
4164
4637
  }
4165
4638
  return output;
4166
4639
  }
4167
4640
  function showHeader() {
4168
4641
  console.log("");
4169
- console.log(chalk10.cyan("\u{1FA7A} NextSpark Health Check"));
4642
+ console.log(chalk14.cyan("\u{1FA7A} NextSpark Health Check"));
4170
4643
  console.log("");
4171
4644
  }
4172
4645
  function showSummary(results) {
@@ -4174,11 +4647,11 @@ function showSummary(results) {
4174
4647
  const warnings = results.filter((r) => r.status === "warn").length;
4175
4648
  const failed = results.filter((r) => r.status === "fail").length;
4176
4649
  console.log("");
4177
- console.log(chalk10.gray("-".repeat(50)));
4650
+ console.log(chalk14.gray("-".repeat(50)));
4178
4651
  const summary = [
4179
- chalk10.green(`${passed} passed`),
4180
- warnings > 0 ? chalk10.yellow(`${warnings} warning${warnings > 1 ? "s" : ""}`) : null,
4181
- failed > 0 ? chalk10.red(`${failed} failed`) : null
4652
+ chalk14.green(`${passed} passed`),
4653
+ warnings > 0 ? chalk14.yellow(`${warnings} warning${warnings > 1 ? "s" : ""}`) : null,
4654
+ failed > 0 ? chalk14.red(`${failed} failed`) : null
4182
4655
  ].filter(Boolean).join(", ");
4183
4656
  console.log(`Summary: ${summary}`);
4184
4657
  console.log("");
@@ -4220,7 +4693,7 @@ async function runDoctorCommand() {
4220
4693
  var isDirectExecution = process.argv[1]?.includes("doctor") || process.argv.includes("doctor");
4221
4694
  if (isDirectExecution && typeof __require !== "undefined") {
4222
4695
  runDoctorCommand().catch((error) => {
4223
- console.error(chalk10.red("An unexpected error occurred:"), error.message);
4696
+ console.error(chalk14.red("An unexpected error occurred:"), error.message);
4224
4697
  process.exit(1);
4225
4698
  });
4226
4699
  }
@@ -4231,23 +4704,23 @@ async function doctorCommand() {
4231
4704
  await runDoctorCommand();
4232
4705
  } catch (error) {
4233
4706
  if (error instanceof Error) {
4234
- console.error(chalk11.red(`Error: ${error.message}`));
4707
+ console.error(chalk15.red(`Error: ${error.message}`));
4235
4708
  }
4236
4709
  process.exit(1);
4237
4710
  }
4238
4711
  }
4239
4712
 
4240
4713
  // src/commands/db.ts
4241
- import { spawn } from "child_process";
4242
- import { existsSync as existsSync6, readFileSync as readFileSync6 } from "fs";
4243
- import { join as join7 } from "path";
4244
- import chalk12 from "chalk";
4245
- import ora6 from "ora";
4246
- function loadProjectEnv(projectRoot) {
4247
- const envPath = join7(projectRoot, ".env");
4714
+ import { spawn as spawn5 } from "child_process";
4715
+ import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
4716
+ import { join as join11 } from "path";
4717
+ import chalk16 from "chalk";
4718
+ import ora10 from "ora";
4719
+ function loadProjectEnv4(projectRoot) {
4720
+ const envPath = join11(projectRoot, ".env");
4248
4721
  const envVars = {};
4249
- if (existsSync6(envPath)) {
4250
- const content = readFileSync6(envPath, "utf-8");
4722
+ if (existsSync10(envPath)) {
4723
+ const content = readFileSync9(envPath, "utf-8");
4251
4724
  for (const line of content.split("\n")) {
4252
4725
  const trimmed = line.trim();
4253
4726
  if (trimmed && !trimmed.startsWith("#")) {
@@ -4265,30 +4738,30 @@ function loadProjectEnv(projectRoot) {
4265
4738
  return envVars;
4266
4739
  }
4267
4740
  async function dbMigrateCommand() {
4268
- const spinner = ora6("Preparing to run migrations...").start();
4741
+ const spinner = ora10("Preparing to run migrations...").start();
4269
4742
  try {
4270
4743
  const coreDir = getCoreDir();
4271
4744
  const projectRoot = getProjectRoot();
4272
- const migrationsScript = join7(coreDir, "scripts", "db", "run-migrations.mjs");
4273
- if (!existsSync6(migrationsScript)) {
4745
+ const migrationsScript = join11(coreDir, "scripts", "db", "run-migrations.mjs");
4746
+ if (!existsSync10(migrationsScript)) {
4274
4747
  spinner.fail("Migrations script not found");
4275
- console.error(chalk12.red(`Expected script at: ${migrationsScript}`));
4748
+ console.error(chalk16.red(`Expected script at: ${migrationsScript}`));
4276
4749
  process.exit(1);
4277
4750
  }
4278
4751
  spinner.succeed("Core package found");
4279
- const projectEnv = loadProjectEnv(projectRoot);
4752
+ const projectEnv = loadProjectEnv4(projectRoot);
4280
4753
  if (!projectEnv.DATABASE_URL) {
4281
4754
  spinner.fail("DATABASE_URL not found in .env file");
4282
- console.error(chalk12.red("Please configure DATABASE_URL in your .env file"));
4755
+ console.error(chalk16.red("Please configure DATABASE_URL in your .env file"));
4283
4756
  process.exit(1);
4284
4757
  }
4285
4758
  if (!projectEnv.NEXT_PUBLIC_ACTIVE_THEME) {
4286
4759
  spinner.fail("NEXT_PUBLIC_ACTIVE_THEME not found in .env file");
4287
- console.error(chalk12.red("Please configure NEXT_PUBLIC_ACTIVE_THEME in your .env file"));
4760
+ console.error(chalk16.red("Please configure NEXT_PUBLIC_ACTIVE_THEME in your .env file"));
4288
4761
  process.exit(1);
4289
4762
  }
4290
4763
  spinner.start("Running database migrations...");
4291
- const migrateProcess = spawn("node", [migrationsScript], {
4764
+ const migrateProcess = spawn5("node", [migrationsScript], {
4292
4765
  cwd: projectRoot,
4293
4766
  stdio: "inherit",
4294
4767
  env: {
@@ -4300,15 +4773,15 @@ async function dbMigrateCommand() {
4300
4773
  });
4301
4774
  migrateProcess.on("error", (err) => {
4302
4775
  spinner.fail("Migration failed");
4303
- console.error(chalk12.red(err.message));
4776
+ console.error(chalk16.red(err.message));
4304
4777
  process.exit(1);
4305
4778
  });
4306
4779
  migrateProcess.on("close", (code) => {
4307
4780
  if (code === 0) {
4308
- console.log(chalk12.green("\n\u2705 Migrations completed successfully!"));
4781
+ console.log(chalk16.green("\n\u2705 Migrations completed successfully!"));
4309
4782
  process.exit(0);
4310
4783
  } else {
4311
- console.error(chalk12.red(`
4784
+ console.error(chalk16.red(`
4312
4785
  \u274C Migrations failed with exit code ${code}`));
4313
4786
  process.exit(code ?? 1);
4314
4787
  }
@@ -4316,22 +4789,22 @@ async function dbMigrateCommand() {
4316
4789
  } catch (error) {
4317
4790
  spinner.fail("Migration preparation failed");
4318
4791
  if (error instanceof Error) {
4319
- console.error(chalk12.red(error.message));
4792
+ console.error(chalk16.red(error.message));
4320
4793
  }
4321
4794
  process.exit(1);
4322
4795
  }
4323
4796
  }
4324
4797
  async function dbSeedCommand() {
4325
- console.log(chalk12.cyan("\u2139\uFE0F Sample data is included as part of the migration process."));
4326
- console.log(chalk12.cyan(" Running db:migrate to apply all migrations including sample data...\n"));
4798
+ console.log(chalk16.cyan("\u2139\uFE0F Sample data is included as part of the migration process."));
4799
+ console.log(chalk16.cyan(" Running db:migrate to apply all migrations including sample data...\n"));
4327
4800
  await dbMigrateCommand();
4328
4801
  }
4329
4802
 
4330
4803
  // src/commands/sync-app.ts
4331
- import { existsSync as existsSync7, readdirSync as readdirSync2, mkdirSync as mkdirSync4, copyFileSync, readFileSync as readFileSync7 } from "fs";
4332
- import { join as join8, dirname as dirname3, relative } from "path";
4333
- import chalk13 from "chalk";
4334
- import ora7 from "ora";
4804
+ import { existsSync as existsSync11, readdirSync as readdirSync2, mkdirSync as mkdirSync4, copyFileSync, readFileSync as readFileSync10 } from "fs";
4805
+ import { join as join12, dirname as dirname4, relative } from "path";
4806
+ import chalk17 from "chalk";
4807
+ import ora11 from "ora";
4335
4808
  var EXCLUDED_TEMPLATE_PATTERNS = ["(templates)"];
4336
4809
  var ROOT_TEMPLATE_FILES = [
4337
4810
  "proxy.ts",
@@ -4347,12 +4820,12 @@ var MAX_VERBOSE_FILES = 10;
4347
4820
  var MAX_SUMMARY_FILES = 5;
4348
4821
  function getAllFiles(dir, baseDir = dir) {
4349
4822
  const files = [];
4350
- if (!existsSync7(dir)) {
4823
+ if (!existsSync11(dir)) {
4351
4824
  return files;
4352
4825
  }
4353
4826
  const entries = readdirSync2(dir, { withFileTypes: true });
4354
4827
  for (const entry of entries) {
4355
- const fullPath = join8(dir, entry.name);
4828
+ const fullPath = join12(dir, entry.name);
4356
4829
  const relativePath = relative(baseDir, fullPath);
4357
4830
  if (entry.isDirectory()) {
4358
4831
  files.push(...getAllFiles(fullPath, baseDir));
@@ -4365,50 +4838,50 @@ function getAllFiles(dir, baseDir = dir) {
4365
4838
  return files;
4366
4839
  }
4367
4840
  function copyFile(source, target) {
4368
- const targetDir = dirname3(target);
4369
- if (!existsSync7(targetDir)) {
4841
+ const targetDir = dirname4(target);
4842
+ if (!existsSync11(targetDir)) {
4370
4843
  mkdirSync4(targetDir, { recursive: true });
4371
4844
  }
4372
4845
  copyFileSync(source, target);
4373
4846
  }
4374
4847
  function backupDirectory(source, target) {
4375
- if (!existsSync7(source)) {
4848
+ if (!existsSync11(source)) {
4376
4849
  return;
4377
4850
  }
4378
4851
  const files = getAllFiles(source);
4379
4852
  for (const file of files) {
4380
- const sourcePath = join8(source, file);
4381
- const targetPath = join8(target, file);
4853
+ const sourcePath = join12(source, file);
4854
+ const targetPath = join12(target, file);
4382
4855
  copyFile(sourcePath, targetPath);
4383
4856
  }
4384
4857
  }
4385
4858
  function getCoreVersion2(coreDir) {
4386
4859
  try {
4387
- const pkgPath = join8(coreDir, "package.json");
4388
- const pkg2 = JSON.parse(readFileSync7(pkgPath, "utf-8"));
4860
+ const pkgPath = join12(coreDir, "package.json");
4861
+ const pkg2 = JSON.parse(readFileSync10(pkgPath, "utf-8"));
4389
4862
  return pkg2.version || "unknown";
4390
4863
  } catch {
4391
4864
  return "unknown";
4392
4865
  }
4393
4866
  }
4394
4867
  async function syncAppCommand(options) {
4395
- const spinner = ora7({ text: "Preparing sync...", isSilent: options.dryRun }).start();
4868
+ const spinner = ora11({ text: "Preparing sync...", isSilent: options.dryRun }).start();
4396
4869
  try {
4397
4870
  const coreDir = getCoreDir();
4398
4871
  const projectRoot = getProjectRoot();
4399
4872
  const coreVersion = getCoreVersion2(coreDir);
4400
- const templatesDir = join8(coreDir, "templates", "app");
4401
- const appDir = join8(projectRoot, "app");
4402
- if (!existsSync7(templatesDir)) {
4873
+ const templatesDir = join12(coreDir, "templates", "app");
4874
+ const appDir = join12(projectRoot, "app");
4875
+ if (!existsSync11(templatesDir)) {
4403
4876
  spinner.fail("Templates directory not found in @nextsparkjs/core");
4404
- console.error(chalk13.red(`
4877
+ console.error(chalk17.red(`
4405
4878
  Expected path: ${templatesDir}`));
4406
4879
  process.exit(1);
4407
4880
  }
4408
- if (!existsSync7(appDir)) {
4881
+ if (!existsSync11(appDir)) {
4409
4882
  spinner.fail("No /app directory found");
4410
- console.error(chalk13.red("\n This project does not have an /app folder."));
4411
- console.error(chalk13.yellow(' Run "nextspark init" first to initialize your project.\n'));
4883
+ console.error(chalk17.red("\n This project does not have an /app folder."));
4884
+ console.error(chalk17.yellow(' Run "nextspark init" first to initialize your project.\n'));
4412
4885
  process.exit(1);
4413
4886
  }
4414
4887
  spinner.text = "Scanning template files...";
@@ -4417,36 +4890,36 @@ async function syncAppCommand(options) {
4417
4890
  const customFiles = existingAppFiles.filter((f) => !templateFiles.includes(f));
4418
4891
  const filesToUpdate = templateFiles;
4419
4892
  spinner.succeed("Scan complete");
4420
- console.log(chalk13.cyan(`
4893
+ console.log(chalk17.cyan(`
4421
4894
  Syncing /app with @nextsparkjs/core@${coreVersion}...
4422
4895
  `));
4423
4896
  if (options.dryRun) {
4424
- console.log(chalk13.yellow(" [DRY RUN] No changes will be made\n"));
4897
+ console.log(chalk17.yellow(" [DRY RUN] No changes will be made\n"));
4425
4898
  }
4426
4899
  if (options.verbose) {
4427
- console.log(chalk13.gray(" Files to sync:"));
4900
+ console.log(chalk17.gray(" Files to sync:"));
4428
4901
  for (const file of filesToUpdate) {
4429
- const targetPath = join8(appDir, file);
4430
- const status = existsSync7(targetPath) ? chalk13.yellow("update") : chalk13.green("create");
4431
- console.log(chalk13.gray(` ${status} ${file}`));
4902
+ const targetPath = join12(appDir, file);
4903
+ const status = existsSync11(targetPath) ? chalk17.yellow("update") : chalk17.green("create");
4904
+ console.log(chalk17.gray(` ${status} ${file}`));
4432
4905
  }
4433
4906
  console.log();
4434
4907
  }
4435
- console.log(chalk13.white(` Template files: ${filesToUpdate.length}`));
4436
- console.log(chalk13.white(` Custom files preserved: ${customFiles.length}`));
4908
+ console.log(chalk17.white(` Template files: ${filesToUpdate.length}`));
4909
+ console.log(chalk17.white(` Custom files preserved: ${customFiles.length}`));
4437
4910
  if (customFiles.length > 0 && options.verbose) {
4438
- console.log(chalk13.gray("\n Custom files (will be preserved):"));
4911
+ console.log(chalk17.gray("\n Custom files (will be preserved):"));
4439
4912
  for (const file of customFiles.slice(0, MAX_VERBOSE_FILES)) {
4440
- console.log(chalk13.gray(` - ${file}`));
4913
+ console.log(chalk17.gray(` - ${file}`));
4441
4914
  }
4442
4915
  if (customFiles.length > MAX_VERBOSE_FILES) {
4443
- console.log(chalk13.gray(` ... and ${customFiles.length - MAX_VERBOSE_FILES} more`));
4916
+ console.log(chalk17.gray(` ... and ${customFiles.length - MAX_VERBOSE_FILES} more`));
4444
4917
  }
4445
4918
  }
4446
4919
  if (!options.force && !options.dryRun) {
4447
- console.log(chalk13.yellow(`
4920
+ console.log(chalk17.yellow(`
4448
4921
  This will overwrite ${filesToUpdate.length} core template files.`));
4449
- console.log(chalk13.gray(" Run with --dry-run to preview changes, or --force to skip this prompt.\n"));
4922
+ console.log(chalk17.gray(" Run with --dry-run to preview changes, or --force to skip this prompt.\n"));
4450
4923
  try {
4451
4924
  const { confirm: confirm6 } = await import("@inquirer/prompts");
4452
4925
  const confirmed = await confirm6({
@@ -4454,16 +4927,16 @@ async function syncAppCommand(options) {
4454
4927
  default: true
4455
4928
  });
4456
4929
  if (!confirmed) {
4457
- console.log(chalk13.yellow("\n Sync cancelled.\n"));
4930
+ console.log(chalk17.yellow("\n Sync cancelled.\n"));
4458
4931
  process.exit(0);
4459
4932
  }
4460
4933
  } catch (promptError) {
4461
- console.error(chalk13.red("\n Failed to load confirmation prompt. Use --force to skip.\n"));
4934
+ console.error(chalk17.red("\n Failed to load confirmation prompt. Use --force to skip.\n"));
4462
4935
  process.exit(1);
4463
4936
  }
4464
4937
  }
4465
4938
  if (options.backup && !options.dryRun) {
4466
- const backupDir = join8(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);
4939
+ const backupDir = join12(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);
4467
4940
  spinner.start("Creating backup...");
4468
4941
  backupDirectory(appDir, backupDir);
4469
4942
  spinner.succeed(`Backup created: ${relative(projectRoot, backupDir)}`);
@@ -4473,9 +4946,9 @@ async function syncAppCommand(options) {
4473
4946
  let updated = 0;
4474
4947
  let created = 0;
4475
4948
  for (const file of filesToUpdate) {
4476
- const sourcePath = join8(templatesDir, file);
4477
- const targetPath = join8(appDir, file);
4478
- const isNew = !existsSync7(targetPath);
4949
+ const sourcePath = join12(templatesDir, file);
4950
+ const targetPath = join12(appDir, file);
4951
+ const isNew = !existsSync11(targetPath);
4479
4952
  copyFile(sourcePath, targetPath);
4480
4953
  if (isNew) {
4481
4954
  created++;
@@ -4487,40 +4960,40 @@ async function syncAppCommand(options) {
4487
4960
  }
4488
4961
  }
4489
4962
  spinner.succeed(`Synced ${filesToUpdate.length} files (${updated} updated, ${created} created)`);
4490
- const rootTemplatesDir = join8(coreDir, "templates");
4963
+ const rootTemplatesDir = join12(coreDir, "templates");
4491
4964
  let rootUpdated = 0;
4492
4965
  let rootCreated = 0;
4493
4966
  for (const file of ROOT_TEMPLATE_FILES) {
4494
- const sourcePath = join8(rootTemplatesDir, file);
4495
- const targetPath = join8(projectRoot, file);
4496
- if (existsSync7(sourcePath)) {
4497
- const isNew = !existsSync7(targetPath);
4967
+ const sourcePath = join12(rootTemplatesDir, file);
4968
+ const targetPath = join12(projectRoot, file);
4969
+ if (existsSync11(sourcePath)) {
4970
+ const isNew = !existsSync11(targetPath);
4498
4971
  copyFile(sourcePath, targetPath);
4499
4972
  if (isNew) {
4500
4973
  rootCreated++;
4501
4974
  if (options.verbose) {
4502
- console.log(chalk13.green(` + Created: ${file}`));
4975
+ console.log(chalk17.green(` + Created: ${file}`));
4503
4976
  }
4504
4977
  } else {
4505
4978
  rootUpdated++;
4506
4979
  if (options.verbose) {
4507
- console.log(chalk13.yellow(` ~ Updated: ${file}`));
4980
+ console.log(chalk17.yellow(` ~ Updated: ${file}`));
4508
4981
  }
4509
4982
  }
4510
4983
  }
4511
4984
  }
4512
4985
  if (rootUpdated + rootCreated > 0) {
4513
- console.log(chalk13.gray(` Root files: ${rootUpdated} updated, ${rootCreated} created`));
4986
+ console.log(chalk17.gray(` Root files: ${rootUpdated} updated, ${rootCreated} created`));
4514
4987
  }
4515
4988
  }
4516
- console.log(chalk13.green("\n \u2705 Sync complete!\n"));
4989
+ console.log(chalk17.green("\n \u2705 Sync complete!\n"));
4517
4990
  if (customFiles.length > 0) {
4518
- console.log(chalk13.gray(` Preserved ${customFiles.length} custom file(s):`));
4991
+ console.log(chalk17.gray(` Preserved ${customFiles.length} custom file(s):`));
4519
4992
  for (const file of customFiles.slice(0, MAX_SUMMARY_FILES)) {
4520
- console.log(chalk13.gray(` - app/${file}`));
4993
+ console.log(chalk17.gray(` - app/${file}`));
4521
4994
  }
4522
4995
  if (customFiles.length > MAX_SUMMARY_FILES) {
4523
- console.log(chalk13.gray(` ... and ${customFiles.length - MAX_SUMMARY_FILES} more
4996
+ console.log(chalk17.gray(` ... and ${customFiles.length - MAX_SUMMARY_FILES} more
4524
4997
  `));
4525
4998
  } else {
4526
4999
  console.log();
@@ -4529,11 +5002,11 @@ async function syncAppCommand(options) {
4529
5002
  } catch (error) {
4530
5003
  spinner.fail("Sync failed");
4531
5004
  if (error instanceof Error) {
4532
- console.error(chalk13.red(`
5005
+ console.error(chalk17.red(`
4533
5006
  Error: ${error.message}
4534
5007
  `));
4535
5008
  if (options.verbose && error.stack) {
4536
- console.error(chalk13.gray(` Stack trace:
5009
+ console.error(chalk17.gray(` Stack trace:
4537
5010
  ${error.stack}
4538
5011
  `));
4539
5012
  }
@@ -4543,39 +5016,39 @@ ${error.stack}
4543
5016
  }
4544
5017
 
4545
5018
  // src/commands/setup-ai.ts
4546
- import { existsSync as existsSync8 } from "fs";
4547
- import { join as join9 } from "path";
5019
+ import { existsSync as existsSync12 } from "fs";
5020
+ import { join as join13 } from "path";
4548
5021
  import { execSync as execSync3 } from "child_process";
4549
- import chalk14 from "chalk";
4550
- import ora8 from "ora";
5022
+ import chalk18 from "chalk";
5023
+ import ora12 from "ora";
4551
5024
  var VALID_EDITORS = ["claude", "cursor", "antigravity", "all"];
4552
5025
  async function setupAICommand(options) {
4553
5026
  const editor = options.editor || "claude";
4554
5027
  if (!VALID_EDITORS.includes(editor)) {
4555
- console.log(chalk14.red(` Unknown editor: ${editor}`));
4556
- console.log(chalk14.gray(` Available: ${VALID_EDITORS.join(", ")}`));
5028
+ console.log(chalk18.red(` Unknown editor: ${editor}`));
5029
+ console.log(chalk18.gray(` Available: ${VALID_EDITORS.join(", ")}`));
4557
5030
  process.exit(1);
4558
5031
  }
4559
5032
  console.log("");
4560
- console.log(chalk14.cyan(" AI Workflow Setup"));
4561
- console.log(chalk14.gray(" " + "-".repeat(40)));
5033
+ console.log(chalk18.cyan(" AI Workflow Setup"));
5034
+ console.log(chalk18.gray(" " + "-".repeat(40)));
4562
5035
  console.log("");
4563
5036
  const pkgPath = getAIWorkflowDir();
4564
5037
  if (!pkgPath) {
4565
- console.log(chalk14.red(" @nextsparkjs/ai-workflow package not found."));
5038
+ console.log(chalk18.red(" @nextsparkjs/ai-workflow package not found."));
4566
5039
  console.log("");
4567
- console.log(chalk14.gray(" Install it first:"));
4568
- console.log(chalk14.cyan(" pnpm add -D -w @nextsparkjs/ai-workflow"));
5040
+ console.log(chalk18.gray(" Install it first:"));
5041
+ console.log(chalk18.cyan(" pnpm add -D -w @nextsparkjs/ai-workflow"));
4569
5042
  console.log("");
4570
5043
  process.exit(1);
4571
5044
  }
4572
- const setupScript = join9(pkgPath, "scripts", "setup.mjs");
4573
- if (!existsSync8(setupScript)) {
4574
- console.log(chalk14.red(" Setup script not found in ai-workflow package."));
4575
- console.log(chalk14.gray(` Expected: ${setupScript}`));
5045
+ const setupScript = join13(pkgPath, "scripts", "setup.mjs");
5046
+ if (!existsSync12(setupScript)) {
5047
+ console.log(chalk18.red(" Setup script not found in ai-workflow package."));
5048
+ console.log(chalk18.gray(` Expected: ${setupScript}`));
4576
5049
  process.exit(1);
4577
5050
  }
4578
- const spinner = ora8({
5051
+ const spinner = ora12({
4579
5052
  text: `Setting up AI workflow for ${editor}...`,
4580
5053
  prefixText: " "
4581
5054
  }).start();
@@ -4587,61 +5060,61 @@ async function setupAICommand(options) {
4587
5060
  });
4588
5061
  } catch (error) {
4589
5062
  console.log("");
4590
- console.log(chalk14.red(" AI workflow setup failed."));
5063
+ console.log(chalk18.red(" AI workflow setup failed."));
4591
5064
  if (error instanceof Error) {
4592
- console.log(chalk14.gray(` ${error.message}`));
5065
+ console.log(chalk18.gray(` ${error.message}`));
4593
5066
  }
4594
5067
  process.exit(1);
4595
5068
  }
4596
5069
  }
4597
5070
 
4598
5071
  // src/commands/sync-ai.ts
4599
- import { existsSync as existsSync9 } from "fs";
4600
- import { join as join10 } from "path";
5072
+ import { existsSync as existsSync13 } from "fs";
5073
+ import { join as join14 } from "path";
4601
5074
  import { execSync as execSync4 } from "child_process";
4602
- import chalk15 from "chalk";
4603
- import ora9 from "ora";
5075
+ import chalk19 from "chalk";
5076
+ import ora13 from "ora";
4604
5077
  var VALID_EDITORS2 = ["claude", "cursor", "antigravity", "all"];
4605
5078
  async function syncAICommand(options) {
4606
5079
  const editor = options.editor || "claude";
4607
5080
  if (!VALID_EDITORS2.includes(editor)) {
4608
- console.log(chalk15.red(` Unknown editor: ${editor}`));
4609
- console.log(chalk15.gray(` Available: ${VALID_EDITORS2.join(", ")}`));
5081
+ console.log(chalk19.red(` Unknown editor: ${editor}`));
5082
+ console.log(chalk19.gray(` Available: ${VALID_EDITORS2.join(", ")}`));
4610
5083
  process.exit(1);
4611
5084
  }
4612
5085
  console.log("");
4613
- console.log(chalk15.cyan(" AI Workflow Sync"));
4614
- console.log(chalk15.gray(" " + "-".repeat(40)));
5086
+ console.log(chalk19.cyan(" AI Workflow Sync"));
5087
+ console.log(chalk19.gray(" " + "-".repeat(40)));
4615
5088
  console.log("");
4616
5089
  const editorDir = editor === "cursor" ? ".cursor" : ".claude";
4617
- const editorDirPath = join10(process.cwd(), editorDir);
4618
- if (!existsSync9(editorDirPath)) {
4619
- console.log(chalk15.red(` No ${editorDir}/ directory found.`));
5090
+ const editorDirPath = join14(process.cwd(), editorDir);
5091
+ if (!existsSync13(editorDirPath)) {
5092
+ console.log(chalk19.red(` No ${editorDir}/ directory found.`));
4620
5093
  console.log("");
4621
- console.log(chalk15.gray(" AI workflow must be set up first. Run:"));
4622
- console.log(chalk15.cyan(" nextspark setup:ai --editor " + editor));
5094
+ console.log(chalk19.gray(" AI workflow must be set up first. Run:"));
5095
+ console.log(chalk19.cyan(" nextspark setup:ai --editor " + editor));
4623
5096
  console.log("");
4624
5097
  process.exit(1);
4625
5098
  }
4626
5099
  const pkgPath = getAIWorkflowDir();
4627
5100
  if (!pkgPath) {
4628
- console.log(chalk15.red(" @nextsparkjs/ai-workflow package not found."));
5101
+ console.log(chalk19.red(" @nextsparkjs/ai-workflow package not found."));
4629
5102
  console.log("");
4630
- console.log(chalk15.gray(" Install it first:"));
4631
- console.log(chalk15.cyan(" pnpm add -D -w @nextsparkjs/ai-workflow"));
5103
+ console.log(chalk19.gray(" Install it first:"));
5104
+ console.log(chalk19.cyan(" pnpm add -D -w @nextsparkjs/ai-workflow"));
4632
5105
  console.log("");
4633
5106
  process.exit(1);
4634
5107
  }
4635
- const setupScript = join10(pkgPath, "scripts", "setup.mjs");
4636
- if (!existsSync9(setupScript)) {
4637
- console.log(chalk15.red(" Setup script not found in ai-workflow package."));
4638
- console.log(chalk15.gray(` Expected: ${setupScript}`));
5108
+ const setupScript = join14(pkgPath, "scripts", "setup.mjs");
5109
+ if (!existsSync13(setupScript)) {
5110
+ console.log(chalk19.red(" Setup script not found in ai-workflow package."));
5111
+ console.log(chalk19.gray(` Expected: ${setupScript}`));
4639
5112
  process.exit(1);
4640
5113
  }
4641
5114
  if (!options.force) {
4642
- console.log(chalk15.yellow(" This will sync AI workflow files from @nextsparkjs/ai-workflow."));
4643
- console.log(chalk15.gray(" Framework files will be overwritten. Custom files will be preserved."));
4644
- console.log(chalk15.gray(" Config JSON files will never be overwritten.\n"));
5115
+ console.log(chalk19.yellow(" This will sync AI workflow files from @nextsparkjs/ai-workflow."));
5116
+ console.log(chalk19.gray(" Framework files will be overwritten. Custom files will be preserved."));
5117
+ console.log(chalk19.gray(" Config JSON files will never be overwritten.\n"));
4645
5118
  try {
4646
5119
  const { confirm: confirm6 } = await import("@inquirer/prompts");
4647
5120
  const confirmed = await confirm6({
@@ -4649,15 +5122,15 @@ async function syncAICommand(options) {
4649
5122
  default: true
4650
5123
  });
4651
5124
  if (!confirmed) {
4652
- console.log(chalk15.yellow("\n Sync cancelled.\n"));
5125
+ console.log(chalk19.yellow("\n Sync cancelled.\n"));
4653
5126
  process.exit(0);
4654
5127
  }
4655
5128
  } catch {
4656
- console.error(chalk15.red("\n Failed to load confirmation prompt. Use --force to skip.\n"));
5129
+ console.error(chalk19.red("\n Failed to load confirmation prompt. Use --force to skip.\n"));
4657
5130
  process.exit(1);
4658
5131
  }
4659
5132
  }
4660
- const spinner = ora9({
5133
+ const spinner = ora13({
4661
5134
  text: `Syncing AI workflow for ${editor}...`,
4662
5135
  prefixText: " "
4663
5136
  }).start();
@@ -4669,9 +5142,9 @@ async function syncAICommand(options) {
4669
5142
  });
4670
5143
  } catch (error) {
4671
5144
  console.log("");
4672
- console.log(chalk15.red(" AI workflow sync failed."));
5145
+ console.log(chalk19.red(" AI workflow sync failed."));
4673
5146
  if (error instanceof Error) {
4674
- console.log(chalk15.gray(` ${error.message}`));
5147
+ console.log(chalk19.gray(` ${error.message}`));
4675
5148
  }
4676
5149
  process.exit(1);
4677
5150
  }
@@ -4679,7 +5152,7 @@ async function syncAICommand(options) {
4679
5152
 
4680
5153
  // src/cli.ts
4681
5154
  config();
4682
- var pkg = JSON.parse(readFileSync8(new URL("../package.json", import.meta.url), "utf-8"));
5155
+ var pkg = JSON.parse(readFileSync11(new URL("../package.json", import.meta.url), "utf-8"));
4683
5156
  var program = new Command();
4684
5157
  program.name("nextspark").description("NextSpark CLI - Professional SaaS Boilerplate").version(pkg.version);
4685
5158
  program.command("dev").description("Start development server with registry watcher").option("-p, --port <port>", "Port to run the dev server on", process.env.PORT || "3000").option("--no-registry", "Disable registry watcher").action(devCommand);
@@ -4705,7 +5178,6 @@ program.command("setup:ai").description("Setup AI workflow for your editor (Clau
4705
5178
  program.command("sync:ai").description("Sync AI workflow files from @nextsparkjs/ai-workflow").option("-e, --editor <editor>", "Editor to sync (claude, cursor, antigravity, all)", "claude").option("-f, --force", "Skip confirmation prompt").action(syncAICommand);
4706
5179
  program.showHelpAfterError();
4707
5180
  program.configureOutput({
4708
- writeErr: (str) => process.stderr.write(chalk16.red(str))
5181
+ writeErr: (str) => process.stderr.write(chalk20.red(str))
4709
5182
  });
4710
5183
  program.parse();
4711
- //# sourceMappingURL=cli.js.map