@nextsparkjs/cli 0.1.0-beta.88 → 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 +182 -99
  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;
@@ -3573,7 +3583,7 @@ async function runWizard(options = { mode: "interactive" }) {
3573
3583
  prefixText: " "
3574
3584
  }).start();
3575
3585
  try {
3576
- 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");
3577
3587
  registrySpinner.stop();
3578
3588
  execSync(`node "${registryScript}" --build`, {
3579
3589
  cwd: webDir,
@@ -3786,9 +3796,9 @@ async function promptAIWorkflowSetup(config2) {
3786
3796
  cwd: projectRoot,
3787
3797
  stdio: "inherit"
3788
3798
  });
3789
- 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");
3790
3800
  if (!existsSync7(setupScript) && isMonorepo) {
3791
- 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");
3792
3802
  }
3793
3803
  if (existsSync7(setupScript)) {
3794
3804
  execSync(`node "${setupScript}" ${choice}`, {
@@ -3813,14 +3823,14 @@ function findLocalCoreTarball() {
3813
3823
  (f) => f.includes("nextsparkjs-core") && f.endsWith(".tgz")
3814
3824
  );
3815
3825
  if (coreTarball) {
3816
- return join7(cwd, coreTarball);
3826
+ return join8(cwd, coreTarball);
3817
3827
  }
3818
3828
  } catch {
3819
3829
  }
3820
3830
  return null;
3821
3831
  }
3822
3832
  function isCoreInstalled() {
3823
- const corePath = join7(process.cwd(), "node_modules", "@nextsparkjs", "core");
3833
+ const corePath = join8(process.cwd(), "node_modules", "@nextsparkjs", "core");
3824
3834
  return existsSync7(corePath);
3825
3835
  }
3826
3836
  async function installCore() {
@@ -3838,8 +3848,8 @@ async function installCore() {
3838
3848
  packageSpec = localTarball;
3839
3849
  spinner.text = "Installing @nextsparkjs/core from local tarball...";
3840
3850
  }
3841
- const useYarn = existsSync7(join7(process.cwd(), "yarn.lock"));
3842
- 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"));
3843
3853
  let installCmd;
3844
3854
  if (usePnpm) {
3845
3855
  installCmd = `pnpm add ${packageSpec}`;
@@ -3865,7 +3875,7 @@ async function installCore() {
3865
3875
  }
3866
3876
  }
3867
3877
  function isMobileInstalled() {
3868
- const mobilePath = join7(process.cwd(), "node_modules", "@nextsparkjs", "mobile");
3878
+ const mobilePath = join8(process.cwd(), "node_modules", "@nextsparkjs", "mobile");
3869
3879
  return existsSync7(mobilePath);
3870
3880
  }
3871
3881
  function findLocalMobileTarball() {
@@ -3876,7 +3886,7 @@ function findLocalMobileTarball() {
3876
3886
  (f) => f.includes("nextsparkjs-mobile") && f.endsWith(".tgz")
3877
3887
  );
3878
3888
  if (mobileTarball) {
3879
- return join7(cwd, mobileTarball);
3889
+ return join8(cwd, mobileTarball);
3880
3890
  }
3881
3891
  } catch {
3882
3892
  }
@@ -3897,8 +3907,8 @@ async function installMobile() {
3897
3907
  packageSpec = localTarball;
3898
3908
  spinner.text = "Installing @nextsparkjs/mobile from local tarball...";
3899
3909
  }
3900
- const useYarn = existsSync7(join7(process.cwd(), "yarn.lock"));
3901
- 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"));
3902
3912
  let installCmd;
3903
3913
  if (usePnpm) {
3904
3914
  installCmd = `pnpm add ${packageSpec}`;
@@ -3936,10 +3946,10 @@ function parsePlugins(pluginsStr) {
3936
3946
  }
3937
3947
  function hasExistingProject() {
3938
3948
  const projectRoot = process.cwd();
3939
- return existsSync8(join8(projectRoot, "contents")) || existsSync8(join8(projectRoot, ".nextspark"));
3949
+ return existsSync8(join9(projectRoot, "contents")) || existsSync8(join9(projectRoot, ".nextspark"));
3940
3950
  }
3941
3951
  function generateInitialRegistries(registriesDir) {
3942
- writeFileSync2(join8(registriesDir, "block-registry.ts"), `// Auto-generated by nextspark init
3952
+ writeFileSync2(join9(registriesDir, "block-registry.ts"), `// Auto-generated by nextspark init
3943
3953
  import type { ComponentType } from 'react'
3944
3954
 
3945
3955
  export const BLOCK_REGISTRY: Record<string, {
@@ -3952,26 +3962,26 @@ export const BLOCK_REGISTRY: Record<string, {
3952
3962
 
3953
3963
  export const BLOCK_COMPONENTS: Record<string, React.LazyExoticComponent<ComponentType<any>>> = {}
3954
3964
  `);
3955
- writeFileSync2(join8(registriesDir, "theme-registry.ts"), `// Auto-generated by nextspark init
3965
+ writeFileSync2(join9(registriesDir, "theme-registry.ts"), `// Auto-generated by nextspark init
3956
3966
  export const THEME_REGISTRY: Record<string, unknown> = {}
3957
3967
  `);
3958
- writeFileSync2(join8(registriesDir, "entity-registry.ts"), `// Auto-generated by nextspark init
3968
+ writeFileSync2(join9(registriesDir, "entity-registry.ts"), `// Auto-generated by nextspark init
3959
3969
  export const ENTITY_REGISTRY: Record<string, unknown> = {}
3960
3970
  `);
3961
- 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
3962
3972
  export const CLIENT_ENTITY_REGISTRY: Record<string, unknown> = {}
3963
3973
  export function parseChildEntity(path: string) { return null }
3964
3974
  export function getEntityApiPath(entity: string) { return \`/api/\${entity}\` }
3965
3975
  export function clientMetaSystemAdapter() { return {} }
3966
3976
  export type ClientEntityConfig = Record<string, unknown>
3967
3977
  `);
3968
- writeFileSync2(join8(registriesDir, "billing-registry.ts"), `// Auto-generated by nextspark init
3978
+ writeFileSync2(join9(registriesDir, "billing-registry.ts"), `// Auto-generated by nextspark init
3969
3979
  export const BILLING_REGISTRY = { plans: [], features: [] }
3970
3980
  `);
3971
- writeFileSync2(join8(registriesDir, "plugin-registry.ts"), `// Auto-generated by nextspark init
3981
+ writeFileSync2(join9(registriesDir, "plugin-registry.ts"), `// Auto-generated by nextspark init
3972
3982
  export const PLUGIN_REGISTRY: Record<string, unknown> = {}
3973
3983
  `);
3974
- writeFileSync2(join8(registriesDir, "testing-registry.ts"), `// Auto-generated by nextspark init
3984
+ writeFileSync2(join9(registriesDir, "testing-registry.ts"), `// Auto-generated by nextspark init
3975
3985
  export const FLOW_REGISTRY: Record<string, unknown> = {}
3976
3986
  export const FEATURE_REGISTRY: Record<string, unknown> = {}
3977
3987
  export const TAGS_REGISTRY: Record<string, unknown> = {}
@@ -3979,11 +3989,11 @@ export const COVERAGE_SUMMARY = { total: 0, covered: 0 }
3979
3989
  export type FlowEntry = unknown
3980
3990
  export type FeatureEntry = unknown
3981
3991
  `);
3982
- writeFileSync2(join8(registriesDir, "docs-registry.ts"), `// Auto-generated by nextspark init
3992
+ writeFileSync2(join9(registriesDir, "docs-registry.ts"), `// Auto-generated by nextspark init
3983
3993
  export const DOCS_REGISTRY = { sections: [], pages: [] }
3984
3994
  export type DocSectionMeta = { title: string; slug: string }
3985
3995
  `);
3986
- writeFileSync2(join8(registriesDir, "index.ts"), `// Auto-generated by nextspark init
3996
+ writeFileSync2(join9(registriesDir, "index.ts"), `// Auto-generated by nextspark init
3987
3997
  export * from './block-registry'
3988
3998
  export * from './theme-registry'
3989
3999
  export * from './entity-registry'
@@ -3998,15 +4008,15 @@ async function simpleInit(options) {
3998
4008
  const spinner = ora8("Initializing NextSpark project...").start();
3999
4009
  const projectRoot = process.cwd();
4000
4010
  try {
4001
- const nextspark = join8(projectRoot, ".nextspark");
4002
- const registriesDir = join8(nextspark, "registries");
4011
+ const nextspark = join9(projectRoot, ".nextspark");
4012
+ const registriesDir = join9(nextspark, "registries");
4003
4013
  if (!existsSync8(registriesDir) || options.force) {
4004
4014
  mkdirSync2(registriesDir, { recursive: true });
4005
4015
  spinner.text = "Creating .nextspark/registries/";
4006
4016
  generateInitialRegistries(registriesDir);
4007
4017
  spinner.text = "Generated initial registries";
4008
4018
  }
4009
- const tsconfigPath = join8(projectRoot, "tsconfig.json");
4019
+ const tsconfigPath = join9(projectRoot, "tsconfig.json");
4010
4020
  if (existsSync8(tsconfigPath)) {
4011
4021
  spinner.text = "Updating tsconfig.json paths...";
4012
4022
  const tsconfig = JSON.parse(readFileSync7(tsconfigPath, "utf-8"));
@@ -4018,7 +4028,7 @@ async function simpleInit(options) {
4018
4028
  };
4019
4029
  writeFileSync2(tsconfigPath, JSON.stringify(tsconfig, null, 2));
4020
4030
  }
4021
- const envExample = join8(projectRoot, ".env.example");
4031
+ const envExample = join9(projectRoot, ".env.example");
4022
4032
  if (!existsSync8(envExample)) {
4023
4033
  const envContent = `# NextSpark Configuration
4024
4034
  DATABASE_URL="postgresql://user:password@localhost:5432/db"
@@ -4069,21 +4079,21 @@ async function initCommand(options) {
4069
4079
 
4070
4080
  // src/commands/add-mobile.ts
4071
4081
  import { existsSync as existsSync9, cpSync as cpSync2, readFileSync as readFileSync8, writeFileSync as writeFileSync3, renameSync, mkdirSync as mkdirSync3 } from "fs";
4072
- import { join as join9 } from "path";
4082
+ import { join as join10 } from "path";
4073
4083
  import chalk13 from "chalk";
4074
4084
  import ora9 from "ora";
4075
4085
  import { execSync as execSync2 } from "child_process";
4076
4086
  function findMobileCoreDir() {
4077
4087
  const projectRoot = process.cwd();
4078
- const npmPath = join9(projectRoot, "node_modules", "@nextsparkjs", "mobile");
4088
+ const npmPath = join10(projectRoot, "node_modules", "@nextsparkjs", "mobile");
4079
4089
  if (existsSync9(npmPath)) {
4080
4090
  return npmPath;
4081
4091
  }
4082
- const monoPath = join9(projectRoot, "packages", "mobile");
4092
+ const monoPath = join10(projectRoot, "packages", "mobile");
4083
4093
  if (existsSync9(monoPath)) {
4084
4094
  return monoPath;
4085
4095
  }
4086
- const parentNpmPath = join9(projectRoot, "..", "node_modules", "@nextsparkjs", "mobile");
4096
+ const parentNpmPath = join10(projectRoot, "..", "node_modules", "@nextsparkjs", "mobile");
4087
4097
  if (existsSync9(parentNpmPath)) {
4088
4098
  return parentNpmPath;
4089
4099
  }
@@ -4093,7 +4103,7 @@ function findMobileCoreDir() {
4093
4103
  }
4094
4104
  async function addMobileCommand(options = {}) {
4095
4105
  const projectRoot = process.cwd();
4096
- const mobileDir = join9(projectRoot, "mobile");
4106
+ const mobileDir = join10(projectRoot, "mobile");
4097
4107
  console.log();
4098
4108
  console.log(chalk13.bold("Adding NextSpark Mobile App"));
4099
4109
  console.log();
@@ -4109,7 +4119,7 @@ async function addMobileCommand(options = {}) {
4109
4119
  console.log(chalk13.red(error.message));
4110
4120
  process.exit(1);
4111
4121
  }
4112
- const templatesDir = join9(mobileCoreDir, "templates");
4122
+ const templatesDir = join10(mobileCoreDir, "templates");
4113
4123
  if (!existsSync9(templatesDir)) {
4114
4124
  console.log(chalk13.red("Error: Could not find mobile templates"));
4115
4125
  console.log(chalk13.gray(`Expected at: ${templatesDir}`));
@@ -4119,12 +4129,12 @@ async function addMobileCommand(options = {}) {
4119
4129
  try {
4120
4130
  mkdirSync3(mobileDir, { recursive: true });
4121
4131
  cpSync2(templatesDir, mobileDir, { recursive: true });
4122
- const pkgTemplatePath = join9(mobileDir, "package.json.template");
4123
- const pkgPath = join9(mobileDir, "package.json");
4132
+ const pkgTemplatePath = join10(mobileDir, "package.json.template");
4133
+ const pkgPath = join10(mobileDir, "package.json");
4124
4134
  if (existsSync9(pkgTemplatePath)) {
4125
4135
  renameSync(pkgTemplatePath, pkgPath);
4126
4136
  const pkg2 = JSON.parse(readFileSync8(pkgPath, "utf-8"));
4127
- const rootPkgPath = join9(projectRoot, "package.json");
4137
+ const rootPkgPath = join10(projectRoot, "package.json");
4128
4138
  if (existsSync9(rootPkgPath)) {
4129
4139
  const rootPkg = JSON.parse(readFileSync8(rootPkgPath, "utf-8"));
4130
4140
  const rawName = rootPkg.name || "my-project";
@@ -4638,11 +4648,11 @@ async function doctorCommand() {
4638
4648
  // src/commands/db.ts
4639
4649
  import { spawn as spawn5 } from "child_process";
4640
4650
  import { existsSync as existsSync10, readFileSync as readFileSync9 } from "fs";
4641
- import { join as join10 } from "path";
4651
+ import { join as join11 } from "path";
4642
4652
  import chalk16 from "chalk";
4643
4653
  import ora10 from "ora";
4644
4654
  function loadProjectEnv4(projectRoot) {
4645
- const envPath = join10(projectRoot, ".env");
4655
+ const envPath = join11(projectRoot, ".env");
4646
4656
  const envVars = {};
4647
4657
  if (existsSync10(envPath)) {
4648
4658
  const content = readFileSync9(envPath, "utf-8");
@@ -4667,7 +4677,7 @@ async function dbMigrateCommand() {
4667
4677
  try {
4668
4678
  const coreDir = getCoreDir();
4669
4679
  const projectRoot = getProjectRoot();
4670
- const migrationsScript = join10(coreDir, "scripts", "db", "run-migrations.mjs");
4680
+ const migrationsScript = join11(coreDir, "scripts", "db", "run-migrations.mjs");
4671
4681
  if (!existsSync10(migrationsScript)) {
4672
4682
  spinner.fail("Migrations script not found");
4673
4683
  console.error(chalk16.red(`Expected script at: ${migrationsScript}`));
@@ -4727,7 +4737,7 @@ async function dbSeedCommand() {
4727
4737
 
4728
4738
  // src/commands/sync-app.ts
4729
4739
  import { existsSync as existsSync11, readdirSync as readdirSync2, mkdirSync as mkdirSync4, copyFileSync, readFileSync as readFileSync10 } from "fs";
4730
- import { join as join11, dirname as dirname4, relative } from "path";
4740
+ import { join as join12, dirname as dirname4, relative } from "path";
4731
4741
  import chalk17 from "chalk";
4732
4742
  import ora11 from "ora";
4733
4743
  var EXCLUDED_TEMPLATE_PATTERNS = ["(templates)"];
@@ -4750,7 +4760,7 @@ function getAllFiles(dir, baseDir = dir) {
4750
4760
  }
4751
4761
  const entries = readdirSync2(dir, { withFileTypes: true });
4752
4762
  for (const entry of entries) {
4753
- const fullPath = join11(dir, entry.name);
4763
+ const fullPath = join12(dir, entry.name);
4754
4764
  const relativePath = relative(baseDir, fullPath);
4755
4765
  if (entry.isDirectory()) {
4756
4766
  files.push(...getAllFiles(fullPath, baseDir));
@@ -4775,14 +4785,14 @@ function backupDirectory(source, target) {
4775
4785
  }
4776
4786
  const files = getAllFiles(source);
4777
4787
  for (const file of files) {
4778
- const sourcePath = join11(source, file);
4779
- const targetPath = join11(target, file);
4788
+ const sourcePath = join12(source, file);
4789
+ const targetPath = join12(target, file);
4780
4790
  copyFile(sourcePath, targetPath);
4781
4791
  }
4782
4792
  }
4783
4793
  function getCoreVersion2(coreDir) {
4784
4794
  try {
4785
- const pkgPath = join11(coreDir, "package.json");
4795
+ const pkgPath = join12(coreDir, "package.json");
4786
4796
  const pkg2 = JSON.parse(readFileSync10(pkgPath, "utf-8"));
4787
4797
  return pkg2.version || "unknown";
4788
4798
  } catch {
@@ -4795,8 +4805,8 @@ async function syncAppCommand(options) {
4795
4805
  const coreDir = getCoreDir();
4796
4806
  const projectRoot = getProjectRoot();
4797
4807
  const coreVersion = getCoreVersion2(coreDir);
4798
- const templatesDir = join11(coreDir, "templates", "app");
4799
- const appDir = join11(projectRoot, "app");
4808
+ const templatesDir = join12(coreDir, "templates", "app");
4809
+ const appDir = join12(projectRoot, "app");
4800
4810
  if (!existsSync11(templatesDir)) {
4801
4811
  spinner.fail("Templates directory not found in @nextsparkjs/core");
4802
4812
  console.error(chalk17.red(`
@@ -4824,7 +4834,7 @@ async function syncAppCommand(options) {
4824
4834
  if (options.verbose) {
4825
4835
  console.log(chalk17.gray(" Files to sync:"));
4826
4836
  for (const file of filesToUpdate) {
4827
- const targetPath = join11(appDir, file);
4837
+ const targetPath = join12(appDir, file);
4828
4838
  const status = existsSync11(targetPath) ? chalk17.yellow("update") : chalk17.green("create");
4829
4839
  console.log(chalk17.gray(` ${status} ${file}`));
4830
4840
  }
@@ -4861,7 +4871,7 @@ async function syncAppCommand(options) {
4861
4871
  }
4862
4872
  }
4863
4873
  if (options.backup && !options.dryRun) {
4864
- const backupDir = join11(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);
4874
+ const backupDir = join12(projectRoot, `app.backup.v${coreVersion}.${Date.now()}`);
4865
4875
  spinner.start("Creating backup...");
4866
4876
  backupDirectory(appDir, backupDir);
4867
4877
  spinner.succeed(`Backup created: ${relative(projectRoot, backupDir)}`);
@@ -4871,8 +4881,8 @@ async function syncAppCommand(options) {
4871
4881
  let updated = 0;
4872
4882
  let created = 0;
4873
4883
  for (const file of filesToUpdate) {
4874
- const sourcePath = join11(templatesDir, file);
4875
- const targetPath = join11(appDir, file);
4884
+ const sourcePath = join12(templatesDir, file);
4885
+ const targetPath = join12(appDir, file);
4876
4886
  const isNew = !existsSync11(targetPath);
4877
4887
  copyFile(sourcePath, targetPath);
4878
4888
  if (isNew) {
@@ -4885,12 +4895,12 @@ async function syncAppCommand(options) {
4885
4895
  }
4886
4896
  }
4887
4897
  spinner.succeed(`Synced ${filesToUpdate.length} files (${updated} updated, ${created} created)`);
4888
- const rootTemplatesDir = join11(coreDir, "templates");
4898
+ const rootTemplatesDir = join12(coreDir, "templates");
4889
4899
  let rootUpdated = 0;
4890
4900
  let rootCreated = 0;
4891
4901
  for (const file of ROOT_TEMPLATE_FILES) {
4892
- const sourcePath = join11(rootTemplatesDir, file);
4893
- const targetPath = join11(projectRoot, file);
4902
+ const sourcePath = join12(rootTemplatesDir, file);
4903
+ const targetPath = join12(projectRoot, file);
4894
4904
  if (existsSync11(sourcePath)) {
4895
4905
  const isNew = !existsSync11(targetPath);
4896
4906
  copyFile(sourcePath, targetPath);
@@ -4942,20 +4952,10 @@ ${error.stack}
4942
4952
 
4943
4953
  // src/commands/setup-ai.ts
4944
4954
  import { existsSync as existsSync12 } from "fs";
4945
- import { join as join12 } from "path";
4955
+ import { join as join13 } from "path";
4946
4956
  import { execSync as execSync3 } from "child_process";
4947
4957
  import chalk18 from "chalk";
4948
4958
  import ora12 from "ora";
4949
- function resolveAIWorkflowPath() {
4950
- const cwd = process.cwd();
4951
- const nmPath = join12(cwd, "node_modules", "@nextsparkjs", "ai-workflow");
4952
- if (existsSync12(nmPath)) return nmPath;
4953
- const webNmPath = join12(cwd, "web", "node_modules", "@nextsparkjs", "ai-workflow");
4954
- if (existsSync12(webNmPath)) return webNmPath;
4955
- const monoPath = join12(cwd, "packages", "ai-workflow");
4956
- if (existsSync12(monoPath)) return monoPath;
4957
- return null;
4958
- }
4959
4959
  var VALID_EDITORS = ["claude", "cursor", "antigravity", "all"];
4960
4960
  async function setupAICommand(options) {
4961
4961
  const editor = options.editor || "claude";
@@ -4968,7 +4968,7 @@ async function setupAICommand(options) {
4968
4968
  console.log(chalk18.cyan(" AI Workflow Setup"));
4969
4969
  console.log(chalk18.gray(" " + "-".repeat(40)));
4970
4970
  console.log("");
4971
- const pkgPath = resolveAIWorkflowPath();
4971
+ const pkgPath = getAIWorkflowDir();
4972
4972
  if (!pkgPath) {
4973
4973
  console.log(chalk18.red(" @nextsparkjs/ai-workflow package not found."));
4974
4974
  console.log("");
@@ -4977,7 +4977,7 @@ async function setupAICommand(options) {
4977
4977
  console.log("");
4978
4978
  process.exit(1);
4979
4979
  }
4980
- const setupScript = join12(pkgPath, "scripts", "setup.mjs");
4980
+ const setupScript = join13(pkgPath, "scripts", "setup.mjs");
4981
4981
  if (!existsSync12(setupScript)) {
4982
4982
  console.log(chalk18.red(" Setup script not found in ai-workflow package."));
4983
4983
  console.log(chalk18.gray(` Expected: ${setupScript}`));
@@ -5003,6 +5003,88 @@ async function setupAICommand(options) {
5003
5003
  }
5004
5004
  }
5005
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
+
5006
5088
  // src/cli.ts
5007
5089
  config();
5008
5090
  var pkg = JSON.parse(readFileSync11(new URL("../package.json", import.meta.url), "utf-8"));
@@ -5028,8 +5110,9 @@ program.command("db:migrate").description("Run database migrations (alias)").act
5028
5110
  program.command("db:seed").description("Seed database with sample data (alias)").action(dbSeedCommand);
5029
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);
5030
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);
5031
5114
  program.showHelpAfterError();
5032
5115
  program.configureOutput({
5033
- writeErr: (str) => process.stderr.write(chalk19.red(str))
5116
+ writeErr: (str) => process.stderr.write(chalk20.red(str))
5034
5117
  });
5035
5118
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nextsparkjs/cli",
3
- "version": "0.1.0-beta.88",
3
+ "version": "0.1.0-beta.89",
4
4
  "description": "NextSpark CLI - Complete development toolkit",
5
5
  "type": "module",
6
6
  "bin": {