@nextsparkjs/cli 0.1.0-beta.87 → 0.1.0-beta.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/dist/cli.js +208 -118
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -12,7 +12,7 @@ import {
12
12
  // src/cli.ts
13
13
  import { config } from "dotenv";
14
14
  import { Command } from "commander";
15
- import chalk19 from "chalk";
15
+ import chalk20 from "chalk";
16
16
  import { readFileSync as readFileSync11 } from "fs";
17
17
 
18
18
  // src/commands/dev.ts
@@ -22,7 +22,7 @@ import ora from "ora";
22
22
 
23
23
  // src/utils/paths.ts
24
24
  import { existsSync } from "fs";
25
- import { resolve, dirname } from "path";
25
+ import { resolve, join, dirname } from "path";
26
26
  import { fileURLToPath } from "url";
27
27
  var __filename = fileURLToPath(import.meta.url);
28
28
  var __dirname = dirname(__filename);
@@ -52,6 +52,16 @@ function isMonorepoMode() {
52
52
  const npmCorePath = resolve(cwd, "node_modules", "@nextsparkjs", "core");
53
53
  return !existsSync(npmCorePath);
54
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
+ }
55
65
 
56
66
  // src/commands/dev.ts
57
67
  async function devCommand(options) {
@@ -120,11 +130,11 @@ async function devCommand(options) {
120
130
  // src/commands/build.ts
121
131
  import { spawn as spawn2 } from "child_process";
122
132
  import { existsSync as existsSync2, readFileSync } from "fs";
123
- import { join } from "path";
133
+ import { join as join2 } from "path";
124
134
  import chalk2 from "chalk";
125
135
  import ora2 from "ora";
126
136
  function loadProjectEnv(projectRoot) {
127
- const envPath = join(projectRoot, ".env");
137
+ const envPath = join2(projectRoot, ".env");
128
138
  const envVars = {};
129
139
  if (existsSync2(envPath)) {
130
140
  const content = readFileSync(envPath, "utf-8");
@@ -217,11 +227,11 @@ Build failed with exit code ${code}`));
217
227
  // src/commands/generate.ts
218
228
  import { spawn as spawn3 } from "child_process";
219
229
  import { existsSync as existsSync3, readFileSync as readFileSync2 } from "fs";
220
- import { join as join2 } from "path";
230
+ import { join as join3 } from "path";
221
231
  import chalk3 from "chalk";
222
232
  import ora3 from "ora";
223
233
  function loadProjectEnv2(projectRoot) {
224
- const envPath = join2(projectRoot, ".env");
234
+ const envPath = join3(projectRoot, ".env");
225
235
  const envVars = {};
226
236
  if (existsSync3(envPath)) {
227
237
  const content = readFileSync2(envPath, "utf-8");
@@ -301,11 +311,11 @@ Registry generation failed with exit code ${code}`));
301
311
  // src/commands/registry.ts
302
312
  import { spawn as spawn4 } from "child_process";
303
313
  import { existsSync as existsSync4, readFileSync as readFileSync3 } from "fs";
304
- import { join as join3 } from "path";
314
+ import { join as join4 } from "path";
305
315
  import chalk4 from "chalk";
306
316
  import ora4 from "ora";
307
317
  function loadProjectEnv3(projectRoot) {
308
- const envPath = join3(projectRoot, ".env");
318
+ const envPath = join4(projectRoot, ".env");
309
319
  const envVars = {};
310
320
  if (existsSync4(envPath)) {
311
321
  const content = readFileSync3(envPath, "utf-8");
@@ -427,7 +437,7 @@ Watcher exited with code ${code}`));
427
437
 
428
438
  // src/commands/init.ts
429
439
  import { existsSync as existsSync8, mkdirSync as mkdirSync2, writeFileSync as writeFileSync2, readFileSync as readFileSync7 } from "fs";
430
- import { join as join8 } from "path";
440
+ import { join as join9 } from "path";
431
441
  import chalk12 from "chalk";
432
442
  import ora8 from "ora";
433
443
 
@@ -437,22 +447,22 @@ import ora7 from "ora";
437
447
  import { confirm as confirm5, select as select6 } from "@inquirer/prompts";
438
448
  import { execSync } from "child_process";
439
449
  import { existsSync as existsSync7, readdirSync } from "fs";
440
- import { join as join7 } from "path";
450
+ import { join as join8 } from "path";
441
451
 
442
452
  // src/wizard/banner.ts
443
453
  import chalk5 from "chalk";
444
454
  import { readFileSync as readFileSync4 } from "fs";
445
455
  import { fileURLToPath as fileURLToPath2 } from "url";
446
- import { dirname as dirname2, join as join4 } from "path";
456
+ import { dirname as dirname2, join as join5 } from "path";
447
457
  var __filename2 = fileURLToPath2(import.meta.url);
448
458
  var __dirname2 = dirname2(__filename2);
449
459
  function getCliVersion() {
450
460
  const possiblePaths = [
451
- join4(__dirname2, "../package.json"),
461
+ join5(__dirname2, "../package.json"),
452
462
  // from dist/
453
- join4(__dirname2, "../../package.json"),
463
+ join5(__dirname2, "../../package.json"),
454
464
  // from dist/wizard/ or src/wizard/
455
- join4(__dirname2, "../../../package.json")
465
+ join5(__dirname2, "../../../package.json")
456
466
  // fallback
457
467
  ];
458
468
  for (const packageJsonPath of possiblePaths) {
@@ -2019,7 +2029,7 @@ async function copyContentFeatures(config2) {
2019
2029
 
2020
2030
  // src/wizard/generators/theme-plugins-installer.ts
2021
2031
  import { existsSync as existsSync6, cpSync, mkdirSync, readFileSync as readFileSync6, writeFileSync } from "fs";
2022
- import { join as join6, resolve as resolve2 } from "path";
2032
+ import { join as join7, resolve as resolve2 } from "path";
2023
2033
  import chalk9 from "chalk";
2024
2034
  import ora6 from "ora";
2025
2035
 
@@ -2027,12 +2037,12 @@ import ora6 from "ora";
2027
2037
  import chalk8 from "chalk";
2028
2038
  import ora5 from "ora";
2029
2039
  import { existsSync as existsSync5, readFileSync as readFileSync5 } from "fs";
2030
- import { join as join5 } from "path";
2040
+ import { join as join6 } from "path";
2031
2041
  async function addTheme(packageSpec, options = {}) {
2032
2042
  const spinner = ora5(`Adding theme ${packageSpec}`).start();
2033
2043
  let cleanup = null;
2034
2044
  try {
2035
- const contentsDir = join5(process.cwd(), "contents");
2045
+ const contentsDir = join6(process.cwd(), "contents");
2036
2046
  if (!existsSync5(contentsDir)) {
2037
2047
  spinner.fail('contents/ directory not found. Run "nextspark init" first.');
2038
2048
  return;
@@ -2095,10 +2105,10 @@ async function addTheme(packageSpec, options = {}) {
2095
2105
  }
2096
2106
  function checkPluginExists(pluginName) {
2097
2107
  const name = pluginName.replace(/^@[^/]+\//, "").replace(/^nextspark-plugin-/, "").replace(/^plugin-/, "");
2098
- return existsSync5(join5(process.cwd(), "contents", "plugins", name));
2108
+ return existsSync5(join6(process.cwd(), "contents", "plugins", name));
2099
2109
  }
2100
2110
  function getCoreVersion() {
2101
- const pkgPath = join5(process.cwd(), "node_modules", "@nextsparkjs", "core", "package.json");
2111
+ const pkgPath = join6(process.cwd(), "node_modules", "@nextsparkjs", "core", "package.json");
2102
2112
  if (existsSync5(pkgPath)) {
2103
2113
  try {
2104
2114
  const pkg2 = JSON.parse(readFileSync5(pkgPath, "utf-8"));
@@ -2139,20 +2149,20 @@ var THEME_REQUIRED_PLUGINS2 = {
2139
2149
  };
2140
2150
  function isMonorepoMode2() {
2141
2151
  const possiblePaths = [
2142
- join6(process.cwd(), "pnpm-workspace.yaml"),
2143
- join6(process.cwd(), "..", "pnpm-workspace.yaml"),
2144
- join6(process.cwd(), "..", "..", "pnpm-workspace.yaml")
2152
+ join7(process.cwd(), "pnpm-workspace.yaml"),
2153
+ join7(process.cwd(), "..", "pnpm-workspace.yaml"),
2154
+ join7(process.cwd(), "..", "..", "pnpm-workspace.yaml")
2145
2155
  ];
2146
2156
  return possiblePaths.some((p) => existsSync6(p));
2147
2157
  }
2148
2158
  function getMonorepoRoot() {
2149
2159
  const possibleRoots = [
2150
2160
  process.cwd(),
2151
- join6(process.cwd(), ".."),
2152
- join6(process.cwd(), "..", "..")
2161
+ join7(process.cwd(), ".."),
2162
+ join7(process.cwd(), "..", "..")
2153
2163
  ];
2154
2164
  for (const root of possibleRoots) {
2155
- if (existsSync6(join6(root, "pnpm-workspace.yaml"))) {
2165
+ if (existsSync6(join7(root, "pnpm-workspace.yaml"))) {
2156
2166
  return resolve2(root);
2157
2167
  }
2158
2168
  }
@@ -2162,15 +2172,15 @@ function getLocalPackageDir(type, name) {
2162
2172
  const monorepoRoot = getMonorepoRoot();
2163
2173
  if (!monorepoRoot) return null;
2164
2174
  const baseDir = type === "theme" ? "themes" : "plugins";
2165
- const packageDir = join6(monorepoRoot, baseDir, name);
2166
- if (existsSync6(packageDir) && existsSync6(join6(packageDir, "package.json"))) {
2175
+ const packageDir = join7(monorepoRoot, baseDir, name);
2176
+ if (existsSync6(packageDir) && existsSync6(join7(packageDir, "package.json"))) {
2167
2177
  return packageDir;
2168
2178
  }
2169
2179
  return null;
2170
2180
  }
2171
2181
  async function copyLocalTheme(name, sourceDir) {
2172
- const targetDir = join6(process.cwd(), "contents", "themes", name);
2173
- const themesDir = join6(process.cwd(), "contents", "themes");
2182
+ const targetDir = join7(process.cwd(), "contents", "themes", name);
2183
+ const themesDir = join7(process.cwd(), "contents", "themes");
2174
2184
  if (!existsSync6(themesDir)) {
2175
2185
  mkdirSync(themesDir, { recursive: true });
2176
2186
  }
@@ -2183,8 +2193,8 @@ async function copyLocalTheme(name, sourceDir) {
2183
2193
  return true;
2184
2194
  }
2185
2195
  async function copyLocalPlugin(name, sourceDir) {
2186
- const targetDir = join6(process.cwd(), "contents", "plugins", name);
2187
- const pluginsDir = join6(process.cwd(), "contents", "plugins");
2196
+ const targetDir = join7(process.cwd(), "contents", "plugins", name);
2197
+ const pluginsDir = join7(process.cwd(), "contents", "plugins");
2188
2198
  if (!existsSync6(pluginsDir)) {
2189
2199
  mkdirSync(pluginsDir, { recursive: true });
2190
2200
  }
@@ -2197,7 +2207,7 @@ async function copyLocalPlugin(name, sourceDir) {
2197
2207
  return true;
2198
2208
  }
2199
2209
  async function updateTsConfigPaths(name, type) {
2200
- const tsconfigPath = join6(process.cwd(), "tsconfig.json");
2210
+ const tsconfigPath = join7(process.cwd(), "tsconfig.json");
2201
2211
  if (!existsSync6(tsconfigPath)) {
2202
2212
  return;
2203
2213
  }
@@ -2242,7 +2252,7 @@ async function installTheme2(theme) {
2242
2252
  prefixText: " "
2243
2253
  }).start();
2244
2254
  try {
2245
- const targetDir = join6(process.cwd(), "contents", "themes", theme);
2255
+ const targetDir = join7(process.cwd(), "contents", "themes", theme);
2246
2256
  if (existsSync6(targetDir)) {
2247
2257
  spinner.info(chalk9.gray(`Reference theme ${theme} already exists`));
2248
2258
  return true;
@@ -2295,7 +2305,7 @@ async function installPlugins(plugins) {
2295
2305
  prefixText: " "
2296
2306
  }).start();
2297
2307
  try {
2298
- const pluginDir = join6(process.cwd(), "contents", "plugins", plugin);
2308
+ const pluginDir = join7(process.cwd(), "contents", "plugins", plugin);
2299
2309
  if (existsSync6(pluginDir)) {
2300
2310
  spinner.info(chalk9.gray(`Plugin ${plugin} already installed`));
2301
2311
  continue;
@@ -3116,6 +3126,7 @@ async function generateProject(config2) {
3116
3126
  await copyProjectFiles();
3117
3127
  await updateGlobalsCss(config2);
3118
3128
  await copyStarterTheme(config2);
3129
+ await fs8.ensureDir(path7.join(process.cwd(), "contents", "plugins"));
3119
3130
  await copyContentFeatures(config2);
3120
3131
  await updateThemeConfig(config2);
3121
3132
  await updateDevConfig(config2);
@@ -3572,7 +3583,7 @@ async function runWizard(options = { mode: "interactive" }) {
3572
3583
  prefixText: " "
3573
3584
  }).start();
3574
3585
  try {
3575
- const registryScript = join7(webDir, "node_modules/@nextsparkjs/core/scripts/build/registry.mjs");
3586
+ const registryScript = join8(webDir, "node_modules/@nextsparkjs/core/scripts/build/registry.mjs");
3576
3587
  registrySpinner.stop();
3577
3588
  execSync(`node "${registryScript}" --build`, {
3578
3589
  cwd: webDir,
@@ -3589,8 +3600,8 @@ async function runWizard(options = { mode: "interactive" }) {
3589
3600
  const devCmd = isMonorepo ? "pnpm dev" : "pnpm dev";
3590
3601
  console.log(chalk11.yellow(` Registries will be built automatically when you run "${devCmd}"`));
3591
3602
  }
3592
- await promptAIWorkflowSetup(config2);
3593
- showNextSteps(config2, selectedTheme);
3603
+ const aiChoice = await promptAIWorkflowSetup(config2);
3604
+ showNextSteps(config2, selectedTheme, aiChoice);
3594
3605
  } catch (error) {
3595
3606
  if (error instanceof Error) {
3596
3607
  if (error.message.includes("User force closed")) {
@@ -3697,8 +3708,9 @@ function formatDevTool(tool) {
3697
3708
  };
3698
3709
  return mapping[tool] || tool;
3699
3710
  }
3700
- function showNextSteps(config2, referenceTheme = null) {
3711
+ function showNextSteps(config2, referenceTheme = null, aiChoice = "skip") {
3701
3712
  const isMonorepo = config2.projectType === "web-mobile";
3713
+ const aiSetupDone = aiChoice === "claude";
3702
3714
  console.log("");
3703
3715
  console.log(chalk11.cyan(" " + "=".repeat(60)));
3704
3716
  console.log(chalk11.bold.green(" \u2728 NextSpark project ready!"));
@@ -3707,12 +3719,12 @@ function showNextSteps(config2, referenceTheme = null) {
3707
3719
  console.log(chalk11.bold.white(" Next steps:"));
3708
3720
  console.log("");
3709
3721
  const envPath = isMonorepo ? "web/.env" : ".env";
3710
- console.log(chalk11.white(" 1. Configure your .env file:"));
3711
- console.log(chalk11.gray(` Edit these values in ${envPath}:`));
3722
+ console.log(chalk11.white(" 1. Configure your environment:"));
3723
+ console.log(chalk11.gray(` Edit ${envPath} with your credentials:`));
3712
3724
  console.log("");
3713
3725
  console.log(chalk11.yellow(" DATABASE_URL"));
3714
3726
  console.log(chalk11.gray(" PostgreSQL connection string"));
3715
- console.log(chalk11.dim(" Example: postgresql://user:pass@localhost:5432/mydb"));
3727
+ console.log(chalk11.gray(` Recommended: ${chalk11.cyan("https://supabase.com")} | ${chalk11.cyan("https://neon.com")}`));
3716
3728
  console.log("");
3717
3729
  console.log(chalk11.yellow(" BETTER_AUTH_SECRET"));
3718
3730
  console.log(chalk11.gray(" Generate with:"));
@@ -3724,11 +3736,23 @@ function showNextSteps(config2, referenceTheme = null) {
3724
3736
  console.log(chalk11.white(" 3. Start the development server:"));
3725
3737
  console.log(chalk11.cyan(" pnpm dev"));
3726
3738
  console.log("");
3739
+ let nextStep = 4;
3727
3740
  if (isMonorepo) {
3728
- console.log(chalk11.white(" 4. (Optional) Start the mobile app:"));
3741
+ console.log(chalk11.white(` ${nextStep}. (Optional) Start the mobile app:`));
3729
3742
  console.log(chalk11.cyan(" pnpm dev:mobile"));
3730
3743
  console.log(chalk11.gray(" Or: cd mobile && pnpm start"));
3731
3744
  console.log("");
3745
+ nextStep++;
3746
+ }
3747
+ if (aiSetupDone) {
3748
+ console.log(chalk11.white(` ${nextStep}. Start building with AI:`));
3749
+ console.log(chalk11.gray(" Open Claude Code in your project and run:"));
3750
+ console.log(chalk11.cyan(" /how-to:start"));
3751
+ console.log("");
3752
+ } else {
3753
+ console.log(chalk11.white(` ${nextStep}. (Optional) Setup AI workflows:`));
3754
+ console.log(chalk11.cyan(" nextspark setup:ai"));
3755
+ console.log("");
3732
3756
  }
3733
3757
  console.log(chalk11.gray(" " + "-".repeat(60)));
3734
3758
  if (isMonorepo) {
@@ -3744,18 +3768,10 @@ function showNextSteps(config2, referenceTheme = null) {
3744
3768
  const refPath = isMonorepo ? `web/contents/themes/${referenceTheme}/` : `contents/themes/${referenceTheme}/`;
3745
3769
  console.log(chalk11.gray(` Reference: ${chalk11.white(refPath)}`));
3746
3770
  }
3747
- console.log("");
3748
- console.log(chalk11.white(` ${isMonorepo ? "5" : "4"}. (Optional) Setup AI workflows:`));
3749
- console.log(chalk11.cyan(" nextspark setup:ai"));
3750
- console.log("");
3751
- console.log(chalk11.gray(" Docs: https://nextspark.dev/docs"));
3771
+ console.log(chalk11.gray(` Docs: ${chalk11.cyan("https://nextspark.dev/docs")}`));
3752
3772
  console.log("");
3753
3773
  }
3754
3774
  async function promptAIWorkflowSetup(config2) {
3755
- console.log("");
3756
- console.log(chalk11.cyan(" " + "=".repeat(60)));
3757
- console.log(chalk11.bold.white(" AI Workflow Setup (Optional)"));
3758
- console.log(chalk11.cyan(" " + "=".repeat(60)));
3759
3775
  console.log("");
3760
3776
  const choice = await select6({
3761
3777
  message: "Setup AI-assisted development workflows?",
@@ -3767,12 +3783,11 @@ async function promptAIWorkflowSetup(config2) {
3767
3783
  ]
3768
3784
  });
3769
3785
  if (choice === "skip") {
3770
- showInfo('Skipped AI workflow setup. Run "nextspark setup:ai" later to set up.');
3771
- return;
3786
+ return "skip";
3772
3787
  }
3773
3788
  if (choice === "cursor" || choice === "antigravity") {
3774
3789
  showInfo(`${choice} support is coming soon. For now, use Claude Code.`);
3775
- return;
3790
+ return "skip";
3776
3791
  }
3777
3792
  const projectRoot = process.cwd();
3778
3793
  const isMonorepo = isMonorepoProject(config2);
@@ -3781,9 +3796,9 @@ async function promptAIWorkflowSetup(config2) {
3781
3796
  cwd: projectRoot,
3782
3797
  stdio: "inherit"
3783
3798
  });
3784
- let setupScript = join7(projectRoot, "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3799
+ let setupScript = join8(projectRoot, "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3785
3800
  if (!existsSync7(setupScript) && isMonorepo) {
3786
- setupScript = join7(projectRoot, "web", "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3801
+ setupScript = join8(projectRoot, "web", "node_modules", "@nextsparkjs", "ai-workflow", "scripts", "setup.mjs");
3787
3802
  }
3788
3803
  if (existsSync7(setupScript)) {
3789
3804
  execSync(`node "${setupScript}" ${choice}`, {
@@ -3796,7 +3811,9 @@ async function promptAIWorkflowSetup(config2) {
3796
3811
  }
3797
3812
  } catch (error) {
3798
3813
  showError('Failed to install AI workflow package. Run "nextspark setup:ai" later.');
3814
+ return "skip";
3799
3815
  }
3816
+ return choice;
3800
3817
  }
3801
3818
  function findLocalCoreTarball() {
3802
3819
  const cwd = process.cwd();
@@ -3806,14 +3823,14 @@ function findLocalCoreTarball() {
3806
3823
  (f) => f.includes("nextsparkjs-core") && f.endsWith(".tgz")
3807
3824
  );
3808
3825
  if (coreTarball) {
3809
- return join7(cwd, coreTarball);
3826
+ return join8(cwd, coreTarball);
3810
3827
  }
3811
3828
  } catch {
3812
3829
  }
3813
3830
  return null;
3814
3831
  }
3815
3832
  function isCoreInstalled() {
3816
- const corePath = join7(process.cwd(), "node_modules", "@nextsparkjs", "core");
3833
+ const corePath = join8(process.cwd(), "node_modules", "@nextsparkjs", "core");
3817
3834
  return existsSync7(corePath);
3818
3835
  }
3819
3836
  async function installCore() {
@@ -3831,8 +3848,8 @@ async function installCore() {
3831
3848
  packageSpec = localTarball;
3832
3849
  spinner.text = "Installing @nextsparkjs/core from local tarball...";
3833
3850
  }
3834
- const useYarn = existsSync7(join7(process.cwd(), "yarn.lock"));
3835
- const usePnpm = existsSync7(join7(process.cwd(), "pnpm-lock.yaml"));
3851
+ const useYarn = existsSync7(join8(process.cwd(), "yarn.lock"));
3852
+ const usePnpm = existsSync7(join8(process.cwd(), "pnpm-lock.yaml"));
3836
3853
  let installCmd;
3837
3854
  if (usePnpm) {
3838
3855
  installCmd = `pnpm add ${packageSpec}`;
@@ -3858,7 +3875,7 @@ async function installCore() {
3858
3875
  }
3859
3876
  }
3860
3877
  function isMobileInstalled() {
3861
- const mobilePath = join7(process.cwd(), "node_modules", "@nextsparkjs", "mobile");
3878
+ const mobilePath = join8(process.cwd(), "node_modules", "@nextsparkjs", "mobile");
3862
3879
  return existsSync7(mobilePath);
3863
3880
  }
3864
3881
  function findLocalMobileTarball() {
@@ -3869,7 +3886,7 @@ function findLocalMobileTarball() {
3869
3886
  (f) => f.includes("nextsparkjs-mobile") && f.endsWith(".tgz")
3870
3887
  );
3871
3888
  if (mobileTarball) {
3872
- return join7(cwd, mobileTarball);
3889
+ return join8(cwd, mobileTarball);
3873
3890
  }
3874
3891
  } catch {
3875
3892
  }
@@ -3890,8 +3907,8 @@ async function installMobile() {
3890
3907
  packageSpec = localTarball;
3891
3908
  spinner.text = "Installing @nextsparkjs/mobile from local tarball...";
3892
3909
  }
3893
- const useYarn = existsSync7(join7(process.cwd(), "yarn.lock"));
3894
- const usePnpm = existsSync7(join7(process.cwd(), "pnpm-lock.yaml"));
3910
+ const useYarn = existsSync7(join8(process.cwd(), "yarn.lock"));
3911
+ const usePnpm = existsSync7(join8(process.cwd(), "pnpm-lock.yaml"));
3895
3912
  let installCmd;
3896
3913
  if (usePnpm) {
3897
3914
  installCmd = `pnpm add ${packageSpec}`;
@@ -3929,10 +3946,10 @@ function parsePlugins(pluginsStr) {
3929
3946
  }
3930
3947
  function hasExistingProject() {
3931
3948
  const projectRoot = process.cwd();
3932
- return existsSync8(join8(projectRoot, "contents")) || existsSync8(join8(projectRoot, ".nextspark"));
3949
+ return existsSync8(join9(projectRoot, "contents")) || existsSync8(join9(projectRoot, ".nextspark"));
3933
3950
  }
3934
3951
  function generateInitialRegistries(registriesDir) {
3935
- writeFileSync2(join8(registriesDir, "block-registry.ts"), `// Auto-generated by nextspark init
3952
+ writeFileSync2(join9(registriesDir, "block-registry.ts"), `// Auto-generated by nextspark init
3936
3953
  import type { ComponentType } from 'react'
3937
3954
 
3938
3955
  export const BLOCK_REGISTRY: Record<string, {
@@ -3945,26 +3962,26 @@ export const BLOCK_REGISTRY: Record<string, {
3945
3962
 
3946
3963
  export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<ComponentType<any>>> = {}
3947
3964
  `);
3948
- writeFileSync2(join8(registriesDir, "theme-registry.ts"), `// Auto-generated by nextspark init
3965
+ writeFileSync2(join9(registriesDir, "theme-registry.ts"), `// Auto-generated by nextspark init
3949
3966
  export const THEME_REGISTRY: Record<string, unknown> = {}
3950
3967
  `);
3951
- writeFileSync2(join8(registriesDir, "entity-registry.ts"), `// Auto-generated by nextspark init
3968
+ writeFileSync2(join9(registriesDir, "entity-registry.ts"), `// Auto-generated by nextspark init
3952
3969
  export const ENTITY_REGISTRY: Record<string, unknown> = {}
3953
3970
  `);
3954
- writeFileSync2(join8(registriesDir, "entity-registry.client.ts"), `// Auto-generated by nextspark init
3971
+ writeFileSync2(join9(registriesDir, "entity-registry.client.ts"), `// Auto-generated by nextspark init
3955
3972
  export const CLIENT_ENTITY_REGISTRY: Record<string, unknown> = {}
3956
3973
  export function parseChildEntity(path: string) { return null }
3957
3974
  export function getEntityApiPath(entity: string) { return \`/api/\${entity}\` }
3958
3975
  export function clientMetaSystemAdapter() { return {} }
3959
3976
  export type ClientEntityConfig = Record<string, unknown>
3960
3977
  `);
3961
- writeFileSync2(join8(registriesDir, "billing-registry.ts"), `// Auto-generated by nextspark init
3978
+ writeFileSync2(join9(registriesDir, "billing-registry.ts"), `// Auto-generated by nextspark init
3962
3979
  export const BILLING_REGISTRY = { plans: [], features: [] }
3963
3980
  `);
3964
- writeFileSync2(join8(registriesDir, "plugin-registry.ts"), `// Auto-generated by nextspark init
3981
+ writeFileSync2(join9(registriesDir, "plugin-registry.ts"), `// Auto-generated by nextspark init
3965
3982
  export const PLUGIN_REGISTRY: Record<string, unknown> = {}
3966
3983
  `);
3967
- writeFileSync2(join8(registriesDir, "testing-registry.ts"), `// Auto-generated by nextspark init
3984
+ writeFileSync2(join9(registriesDir, "testing-registry.ts"), `// Auto-generated by nextspark init
3968
3985
  export const FLOW_REGISTRY: Record<string, unknown> = {}
3969
3986
  export const FEATURE_REGISTRY: Record<string, unknown> = {}
3970
3987
  export const TAGS_REGISTRY: Record<string, unknown> = {}
@@ -3972,11 +3989,11 @@ export const COVERAGE_SUMMARY = { total: 0, covered: 0 }
3972
3989
  export type FlowEntry = unknown
3973
3990
  export type FeatureEntry = unknown
3974
3991
  `);
3975
- writeFileSync2(join8(registriesDir, "docs-registry.ts"), `// Auto-generated by nextspark init
3992
+ writeFileSync2(join9(registriesDir, "docs-registry.ts"), `// Auto-generated by nextspark init
3976
3993
  export const DOCS_REGISTRY = { sections: [], pages: [] }
3977
3994
  export type DocSectionMeta = { title: string; slug: string }
3978
3995
  `);
3979
- writeFileSync2(join8(registriesDir, "index.ts"), `// Auto-generated by nextspark init
3996
+ writeFileSync2(join9(registriesDir, "index.ts"), `// Auto-generated by nextspark init
3980
3997
  export * from './block-registry'
3981
3998
  export * from './theme-registry'
3982
3999
  export * from './entity-registry'
@@ -3991,15 +4008,15 @@ async function simpleInit(options) {
3991
4008
  const spinner = ora8("Initializing NextSpark project...").start();
3992
4009
  const projectRoot = process.cwd();
3993
4010
  try {
3994
- const nextspark = join8(projectRoot, ".nextspark");
3995
- const registriesDir = join8(nextspark, "registries");
4011
+ const nextspark = join9(projectRoot, ".nextspark");
4012
+ const registriesDir = join9(nextspark, "registries");
3996
4013
  if (!existsSync8(registriesDir) || options.force) {
3997
4014
  mkdirSync2(registriesDir, { recursive: true });
3998
4015
  spinner.text = "Creating .nextspark/registries/";
3999
4016
  generateInitialRegistries(registriesDir);
4000
4017
  spinner.text = "Generated initial registries";
4001
4018
  }
4002
- const tsconfigPath = join8(projectRoot, "tsconfig.json");
4019
+ const tsconfigPath = join9(projectRoot, "tsconfig.json");
4003
4020
  if (existsSync8(tsconfigPath)) {
4004
4021
  spinner.text = "Updating tsconfig.json paths...";
4005
4022
  const tsconfig = JSON.parse(readFileSync7(tsconfigPath, "utf-8"));
@@ -4011,7 +4028,7 @@ async function simpleInit(options) {
4011
4028
  };
4012
4029
  writeFileSync2(tsconfigPath, JSON.stringify(tsconfig, null, 2));
4013
4030
  }
4014
- const envExample = join8(projectRoot, ".env.example");
4031
+ const envExample = join9(projectRoot, ".env.example");
4015
4032
  if (!existsSync8(envExample)) {
4016
4033
  const envContent = `# NextSpark Configuration
4017
4034
  DATABASE_URL="postgresql://user:password@localhost:5432/db"
@@ -4062,21 +4079,21 @@ async function initCommand(options) {
4062
4079
 
4063
4080
  // src/commands/add-mobile.ts
4064
4081
  import { existsSync as existsSync9, cpSync as cpSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync3 } from "fs";
4065
- import { join as join9 } from "path";
4082
+ import { join as join10 } from "path";
4066
4083
  import chalk13 from "chalk";
4067
4084
  import ora9 from "ora";
4068
4085
  import { execSync as execSync2 } from "child_process";
4069
4086
  function findMobileCoreDir() {
4070
4087
  const projectRoot = process.cwd();
4071
- const npmPath = join9(projectRoot, "node_modules", "@nextsparkjs", "mobile");
4088
+ const npmPath = join10(projectRoot, "node_modules", "@nextsparkjs", "mobile");
4072
4089
  if (existsSync9(npmPath)) {
4073
4090
  return npmPath;
4074
4091
  }
4075
- const monoPath = join9(projectRoot, "packages", "mobile");
4092
+ const monoPath = join10(projectRoot, "packages", "mobile");
4076
4093
  if (existsSync9(monoPath)) {
4077
4094
  return monoPath;
4078
4095
  }
4079
- const parentNpmPath = join9(projectRoot, "..", "node_modules", "@nextsparkjs", "mobile");
4096
+ const parentNpmPath = join10(projectRoot, "..", "node_modules", "@nextsparkjs", "mobile");
4080
4097
  if (existsSync9(parentNpmPath)) {
4081
4098
  return parentNpmPath;
4082
4099
  }
@@ -4086,7 +4103,7 @@ function findMobileCoreDir() {
4086
4103
  }
4087
4104
  async function addMobileCommand(options = {}) {
4088
4105
  const projectRoot = process.cwd();
4089
- const mobileDir = join9(projectRoot, "mobile");
4106
+ const mobileDir = join10(projectRoot, "mobile");
4090
4107
  console.log();
4091
4108
  console.log(chalk13.bold("Adding NextSpark Mobile App"));
4092
4109
  console.log();
@@ -4102,7 +4119,7 @@ async function addMobileCommand(options = {}) {
4102
4119
  console.log(chalk13.red(error.message));
4103
4120
  process.exit(1);
4104
4121
  }
4105
- const templatesDir = join9(mobileCoreDir, "templates");
4122
+ const templatesDir = join10(mobileCoreDir, "templates");
4106
4123
  if (!existsSync9(templatesDir)) {
4107
4124
  console.log(chalk13.red("Error: Could not find mobile templates"));
4108
4125
  console.log(chalk13.gray(`Expected at: ${templatesDir}`));
@@ -4112,12 +4129,12 @@ async function addMobileCommand(options = {}) {
4112
4129
  try {
4113
4130
  mkdirSync3(mobileDir, { recursive: true });
4114
4131
  cpSync2(templatesDir, mobileDir, { recursive: true });
4115
- const pkgTemplatePath = join9(mobileDir, "package.json.template");
4116
- const pkgPath = join9(mobileDir, "package.json");
4132
+ const pkgTemplatePath = join10(mobileDir, "package.json.template");
4133
+ const pkgPath = join10(mobileDir, "package.json");
4117
4134
  if (existsSync9(pkgTemplatePath)) {
4118
4135
  renameSync(pkgTemplatePath, pkgPath);
4119
4136
  const pkg2 = JSON.parse(readFileSync8(pkgPath, "utf-8"));
4120
- const rootPkgPath = join9(projectRoot, "package.json");
4137
+ const rootPkgPath = join10(projectRoot, "package.json");
4121
4138
  if (existsSync9(rootPkgPath)) {
4122
4139
  const rootPkg = JSON.parse(readFileSync8(rootPkgPath, "utf-8"));
4123
4140
  const rawName = rootPkg.name || "my-project";
@@ -4631,11 +4648,11 @@ async function doctorCommand() {
4631
4648
  // src/commands/db.ts
4632
4649
  import { spawn as spawn5 } from "child_process";
4633
4650
  import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
4634
- import { join as join10 } from "path";
4651
+ import { join as join11 } from "path";
4635
4652
  import chalk16 from "chalk";
4636
4653
  import ora10 from "ora";
4637
4654
  function loadProjectEnv4(projectRoot) {
4638
- const envPath = join10(projectRoot, ".env");
4655
+ const envPath = join11(projectRoot, ".env");
4639
4656
  const envVars = {};
4640
4657
  if (existsSync10(envPath)) {
4641
4658
  const content = readFileSync9(envPath, "utf-8");
@@ -4660,7 +4677,7 @@ async function dbMigrateCommand() {
4660
4677
  try {
4661
4678
  const coreDir = getCoreDir();
4662
4679
  const projectRoot = getProjectRoot();
4663
- const migrationsScript = join10(coreDir, "scripts", "db", "run-migrations.mjs");
4680
+ const migrationsScript = join11(coreDir, "scripts", "db", "run-migrations.mjs");
4664
4681
  if (!existsSync10(migrationsScript)) {
4665
4682
  spinner.fail("Migrations script not found");
4666
4683
  console.error(chalk16.red(`Expected script at: ${migrationsScript}`));
@@ -4720,7 +4737,7 @@ async function dbSeedCommand() {
4720
4737
 
4721
4738
  // src/commands/sync-app.ts
4722
4739
  import { existsSync as existsSync11, readdirSync as readdirSync2, mkdirSync as mkdirSync4, copyFileSync, readFileSync as readFileSync10 } from "fs";
4723
- import { join as join11, dirname as dirname4, relative } from "path";
4740
+ import { join as join12, dirname as dirname4, relative } from "path";
4724
4741
  import chalk17 from "chalk";
4725
4742
  import ora11 from "ora";
4726
4743
  var EXCLUDED_TEMPLATE_PATTERNS = ["(templates)"];
@@ -4743,7 +4760,7 @@ function getAllFiles(dir, baseDir = dir) {
4743
4760
  }
4744
4761
  const entries = readdirSync2(dir, { withFileTypes: true });
4745
4762
  for (const entry of entries) {
4746
- const fullPath = join11(dir, entry.name);
4763
+ const fullPath = join12(dir, entry.name);
4747
4764
  const relativePath = relative(baseDir, fullPath);
4748
4765
  if (entry.isDirectory()) {
4749
4766
  files.push(...getAllFiles(fullPath, baseDir));
@@ -4768,14 +4785,14 @@ function backupDirectory(source, target) {
4768
4785
  }
4769
4786
  const files = getAllFiles(source);
4770
4787
  for (const file of files) {
4771
- const sourcePath = join11(source, file);
4772
- const targetPath = join11(target, file);
4788
+ const sourcePath = join12(source, file);
4789
+ const targetPath = join12(target, file);
4773
4790
  copyFile(sourcePath, targetPath);
4774
4791
  }
4775
4792
  }
4776
4793
  function getCoreVersion2(coreDir) {
4777
4794
  try {
4778
- const pkgPath = join11(coreDir, "package.json");
4795
+ const pkgPath = join12(coreDir, "package.json");
4779
4796
  const pkg2 = JSON.parse(readFileSync10(pkgPath, "utf-8"));
4780
4797
  return pkg2.version || "unknown";
4781
4798
  } catch {
@@ -4788,8 +4805,8 @@ async function syncAppCommand(options) {
4788
4805
  const coreDir = getCoreDir();
4789
4806
  const projectRoot = getProjectRoot();
4790
4807
  const coreVersion = getCoreVersion2(coreDir);
4791
- const templatesDir = join11(coreDir, "templates", "app");
4792
- const appDir = join11(projectRoot, "app");
4808
+ const templatesDir = join12(coreDir, "templates", "app");
4809
+ const appDir = join12(projectRoot, "app");
4793
4810
  if (!existsSync11(templatesDir)) {
4794
4811
  spinner.fail("Templates directory not found in @nextsparkjs/core");
4795
4812
  console.error(chalk17.red(`
@@ -4817,7 +4834,7 @@ async function syncAppCommand(options) {
4817
4834
  if (options.verbose) {
4818
4835
  console.log(chalk17.gray(" Files to sync:"));
4819
4836
  for (const file of filesToUpdate) {
4820
- const targetPath = join11(appDir, file);
4837
+ const targetPath = join12(appDir, file);
4821
4838
  const status = existsSync11(targetPath) ? chalk17.yellow("update") : chalk17.green("create");
4822
4839
  console.log(chalk17.gray(` ${status} ${file}`));
4823
4840
  }
@@ -4854,7 +4871,7 @@ async function syncAppCommand(options) {
4854
4871
  }
4855
4872
  }
4856
4873
  if (options.backup && !options.dryRun) {
4857
- const backupDir = join11(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);
4874
+ const backupDir = join12(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);
4858
4875
  spinner.start("Creating backup...");
4859
4876
  backupDirectory(appDir, backupDir);
4860
4877
  spinner.succeed(`Backup created: ${relative(projectRoot, backupDir)}`);
@@ -4864,8 +4881,8 @@ async function syncAppCommand(options) {
4864
4881
  let updated = 0;
4865
4882
  let created = 0;
4866
4883
  for (const file of filesToUpdate) {
4867
- const sourcePath = join11(templatesDir, file);
4868
- const targetPath = join11(appDir, file);
4884
+ const sourcePath = join12(templatesDir, file);
4885
+ const targetPath = join12(appDir, file);
4869
4886
  const isNew = !existsSync11(targetPath);
4870
4887
  copyFile(sourcePath, targetPath);
4871
4888
  if (isNew) {
@@ -4878,12 +4895,12 @@ async function syncAppCommand(options) {
4878
4895
  }
4879
4896
  }
4880
4897
  spinner.succeed(`Synced ${filesToUpdate.length} files (${updated} updated, ${created} created)`);
4881
- const rootTemplatesDir = join11(coreDir, "templates");
4898
+ const rootTemplatesDir = join12(coreDir, "templates");
4882
4899
  let rootUpdated = 0;
4883
4900
  let rootCreated = 0;
4884
4901
  for (const file of ROOT_TEMPLATE_FILES) {
4885
- const sourcePath = join11(rootTemplatesDir, file);
4886
- const targetPath = join11(projectRoot, file);
4902
+ const sourcePath = join12(rootTemplatesDir, file);
4903
+ const targetPath = join12(projectRoot, file);
4887
4904
  if (existsSync11(sourcePath)) {
4888
4905
  const isNew = !existsSync11(targetPath);
4889
4906
  copyFile(sourcePath, targetPath);
@@ -4935,20 +4952,10 @@ ${error.stack}
4935
4952
 
4936
4953
  // src/commands/setup-ai.ts
4937
4954
  import { existsSync as existsSync12 } from "fs";
4938
- import { join as join12 } from "path";
4955
+ import { join as join13 } from "path";
4939
4956
  import { execSync as execSync3 } from "child_process";
4940
4957
  import chalk18 from "chalk";
4941
4958
  import ora12 from "ora";
4942
- function resolveAIWorkflowPath() {
4943
- const cwd = process.cwd();
4944
- const nmPath = join12(cwd, "node_modules", "@nextsparkjs", "ai-workflow");
4945
- if (existsSync12(nmPath)) return nmPath;
4946
- const webNmPath = join12(cwd, "web", "node_modules", "@nextsparkjs", "ai-workflow");
4947
- if (existsSync12(webNmPath)) return webNmPath;
4948
- const monoPath = join12(cwd, "packages", "ai-workflow");
4949
- if (existsSync12(monoPath)) return monoPath;
4950
- return null;
4951
- }
4952
4959
  var VALID_EDITORS = ["claude", "cursor", "antigravity", "all"];
4953
4960
  async function setupAICommand(options) {
4954
4961
  const editor = options.editor || "claude";
@@ -4961,7 +4968,7 @@ async function setupAICommand(options) {
4961
4968
  console.log(chalk18.cyan(" AI Workflow Setup"));
4962
4969
  console.log(chalk18.gray(" " + "-".repeat(40)));
4963
4970
  console.log("");
4964
- const pkgPath = resolveAIWorkflowPath();
4971
+ const pkgPath = getAIWorkflowDir();
4965
4972
  if (!pkgPath) {
4966
4973
  console.log(chalk18.red(" @nextsparkjs/ai-workflow package not found."));
4967
4974
  console.log("");
@@ -4970,7 +4977,7 @@ async function setupAICommand(options) {
4970
4977
  console.log("");
4971
4978
  process.exit(1);
4972
4979
  }
4973
- const setupScript = join12(pkgPath, "scripts", "setup.mjs");
4980
+ const setupScript = join13(pkgPath, "scripts", "setup.mjs");
4974
4981
  if (!existsSync12(setupScript)) {
4975
4982
  console.log(chalk18.red(" Setup script not found in ai-workflow package."));
4976
4983
  console.log(chalk18.gray(` Expected: ${setupScript}`));
@@ -4996,6 +5003,88 @@ async function setupAICommand(options) {
4996
5003
  }
4997
5004
  }
4998
5005
 
5006
+ // src/commands/sync-ai.ts
5007
+ import { existsSync as existsSync13 } from "fs";
5008
+ import { join as join14 } from "path";
5009
+ import { execSync as execSync4 } from "child_process";
5010
+ import chalk19 from "chalk";
5011
+ import ora13 from "ora";
5012
+ var VALID_EDITORS2 = ["claude", "cursor", "antigravity", "all"];
5013
+ async function syncAICommand(options) {
5014
+ const editor = options.editor || "claude";
5015
+ if (!VALID_EDITORS2.includes(editor)) {
5016
+ console.log(chalk19.red(` Unknown editor: ${editor}`));
5017
+ console.log(chalk19.gray(` Available: ${VALID_EDITORS2.join(", ")}`));
5018
+ process.exit(1);
5019
+ }
5020
+ console.log("");
5021
+ console.log(chalk19.cyan(" AI Workflow Sync"));
5022
+ console.log(chalk19.gray(" " + "-".repeat(40)));
5023
+ console.log("");
5024
+ const editorDir = editor === "cursor" ? ".cursor" : ".claude";
5025
+ const editorDirPath = join14(process.cwd(), editorDir);
5026
+ if (!existsSync13(editorDirPath)) {
5027
+ console.log(chalk19.red(` No ${editorDir}/ directory found.`));
5028
+ console.log("");
5029
+ console.log(chalk19.gray(" AI workflow must be set up first. Run:"));
5030
+ console.log(chalk19.cyan(" nextspark setup:ai --editor " + editor));
5031
+ console.log("");
5032
+ process.exit(1);
5033
+ }
5034
+ const pkgPath = getAIWorkflowDir();
5035
+ if (!pkgPath) {
5036
+ console.log(chalk19.red(" @nextsparkjs/ai-workflow package not found."));
5037
+ console.log("");
5038
+ console.log(chalk19.gray(" Install it first:"));
5039
+ console.log(chalk19.cyan(" pnpm add -D -w @nextsparkjs/ai-workflow"));
5040
+ console.log("");
5041
+ process.exit(1);
5042
+ }
5043
+ const setupScript = join14(pkgPath, "scripts", "setup.mjs");
5044
+ if (!existsSync13(setupScript)) {
5045
+ console.log(chalk19.red(" Setup script not found in ai-workflow package."));
5046
+ console.log(chalk19.gray(` Expected: ${setupScript}`));
5047
+ process.exit(1);
5048
+ }
5049
+ if (!options.force) {
5050
+ console.log(chalk19.yellow(" This will sync AI workflow files from @nextsparkjs/ai-workflow."));
5051
+ console.log(chalk19.gray(" Framework files will be overwritten. Custom files will be preserved."));
5052
+ console.log(chalk19.gray(" Config JSON files will never be overwritten.\n"));
5053
+ try {
5054
+ const { confirm: confirm6 } = await import("@inquirer/prompts");
5055
+ const confirmed = await confirm6({
5056
+ message: "Proceed with sync?",
5057
+ default: true
5058
+ });
5059
+ if (!confirmed) {
5060
+ console.log(chalk19.yellow("\n Sync cancelled.\n"));
5061
+ process.exit(0);
5062
+ }
5063
+ } catch {
5064
+ console.error(chalk19.red("\n Failed to load confirmation prompt. Use --force to skip.\n"));
5065
+ process.exit(1);
5066
+ }
5067
+ }
5068
+ const spinner = ora13({
5069
+ text: `Syncing AI workflow for ${editor}...`,
5070
+ prefixText: " "
5071
+ }).start();
5072
+ try {
5073
+ spinner.stop();
5074
+ execSync4(`node "${setupScript}" ${editor}`, {
5075
+ cwd: process.cwd(),
5076
+ stdio: "inherit"
5077
+ });
5078
+ } catch (error) {
5079
+ console.log("");
5080
+ console.log(chalk19.red(" AI workflow sync failed."));
5081
+ if (error instanceof Error) {
5082
+ console.log(chalk19.gray(` ${error.message}`));
5083
+ }
5084
+ process.exit(1);
5085
+ }
5086
+ }
5087
+
4999
5088
  // src/cli.ts
5000
5089
  config();
5001
5090
  var pkg = JSON.parse(readFileSync11(new URL("../package.json", import.meta.url), "utf-8"));
@@ -5021,8 +5110,9 @@ program.command("db:migrate").description("Run database migrations (alias)").act
5021
5110
  program.command("db:seed").description("Seed database with sample data (alias)").action(dbSeedCommand);
5022
5111
  program.command("sync:app").description("Sync /app folder with @nextsparkjs/core templates").option("--dry-run", "Preview changes without applying").option("-f, --force", "Skip confirmation prompt").option("--backup", "Backup existing files before overwriting").option("-v, --verbose", "Show detailed file operations").action(syncAppCommand);
5023
5112
  program.command("setup:ai").description("Setup AI workflow for your editor (Claude Code, Cursor, Antigravity)").option("-e, --editor <editor>", "Editor to setup (claude, cursor, antigravity, all)", "claude").action(setupAICommand);
5113
+ 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);
5024
5114
  program.showHelpAfterError();
5025
5115
  program.configureOutput({
5026
- writeErr: (str) => process.stderr.write(chalk19.red(str))
5116
+ writeErr: (str) => process.stderr.write(chalk20.red(str))
5027
5117
  });
5028
5118
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/cli",
3
- "version": "0.1.0-beta.87",
3
+ "version": "0.1.0-beta.89",
4
4
  "description": "NextSpark CLI - Complete development toolkit",
5
5
  "type": "module",
6
6
  "bin": {