@nexical/cli 0.10.0 → 0.11.1

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 (76) hide show
  1. package/.github/workflows/deploy.yml +1 -1
  2. package/.husky/pre-commit +1 -0
  3. package/.prettierignore +8 -0
  4. package/.prettierrc +7 -0
  5. package/GEMINI.md +199 -0
  6. package/README.md +85 -56
  7. package/dist/chunk-AC4B3HPJ.js +93 -0
  8. package/dist/chunk-AC4B3HPJ.js.map +1 -0
  9. package/dist/{chunk-JYASTIIW.js → chunk-PJIOCW2A.js} +1 -1
  10. package/dist/chunk-PJIOCW2A.js.map +1 -0
  11. package/dist/{chunk-WKERTCM6.js → chunk-Q7YLW5HJ.js} +5 -2
  12. package/dist/chunk-Q7YLW5HJ.js.map +1 -0
  13. package/dist/index.js +41 -12
  14. package/dist/index.js.map +1 -1
  15. package/dist/src/commands/init.d.ts +4 -1
  16. package/dist/src/commands/init.js +15 -10
  17. package/dist/src/commands/init.js.map +1 -1
  18. package/dist/src/commands/module/add.d.ts +3 -1
  19. package/dist/src/commands/module/add.js +27 -16
  20. package/dist/src/commands/module/add.js.map +1 -1
  21. package/dist/src/commands/module/list.js +9 -5
  22. package/dist/src/commands/module/list.js.map +1 -1
  23. package/dist/src/commands/module/remove.d.ts +3 -1
  24. package/dist/src/commands/module/remove.js +13 -7
  25. package/dist/src/commands/module/remove.js.map +1 -1
  26. package/dist/src/commands/module/update.d.ts +3 -1
  27. package/dist/src/commands/module/update.js +7 -5
  28. package/dist/src/commands/module/update.js.map +1 -1
  29. package/dist/src/commands/run.d.ts +4 -1
  30. package/dist/src/commands/run.js +10 -2
  31. package/dist/src/commands/run.js.map +1 -1
  32. package/dist/src/commands/setup.d.ts +8 -0
  33. package/dist/src/commands/setup.js +75 -0
  34. package/dist/src/commands/setup.js.map +1 -0
  35. package/dist/src/utils/discovery.js +1 -1
  36. package/dist/src/utils/git.js +1 -1
  37. package/dist/src/utils/url-resolver.js +1 -1
  38. package/eslint.config.mjs +67 -0
  39. package/index.ts +34 -20
  40. package/package.json +57 -33
  41. package/src/commands/init.ts +79 -75
  42. package/src/commands/module/add.ts +158 -148
  43. package/src/commands/module/list.ts +61 -50
  44. package/src/commands/module/remove.ts +59 -54
  45. package/src/commands/module/update.ts +44 -42
  46. package/src/commands/run.ts +89 -81
  47. package/src/commands/setup.ts +92 -0
  48. package/src/utils/discovery.ts +98 -113
  49. package/src/utils/git.ts +35 -28
  50. package/src/utils/url-resolver.ts +50 -45
  51. package/test/e2e/lifecycle.e2e.test.ts +139 -130
  52. package/test/integration/commands/init.integration.test.ts +64 -61
  53. package/test/integration/commands/module.integration.test.ts +122 -122
  54. package/test/integration/commands/run.integration.test.ts +70 -63
  55. package/test/integration/utils/command-loading.integration.test.ts +40 -53
  56. package/test/unit/commands/init.test.ts +163 -128
  57. package/test/unit/commands/module/add.test.ts +312 -245
  58. package/test/unit/commands/module/list.test.ts +108 -91
  59. package/test/unit/commands/module/remove.test.ts +74 -67
  60. package/test/unit/commands/module/update.test.ts +74 -70
  61. package/test/unit/commands/run.test.ts +253 -201
  62. package/test/unit/commands/setup.test.ts +187 -0
  63. package/test/unit/utils/command-discovery.test.ts +138 -125
  64. package/test/unit/utils/git.test.ts +135 -117
  65. package/test/unit/utils/integration-helpers.test.ts +59 -49
  66. package/test/unit/utils/url-resolver.test.ts +46 -34
  67. package/test/utils/integration-helpers.ts +36 -29
  68. package/tsconfig.json +15 -25
  69. package/tsup.config.ts +14 -14
  70. package/vitest.config.ts +10 -10
  71. package/vitest.e2e.config.ts +6 -6
  72. package/vitest.integration.config.ts +17 -17
  73. package/dist/chunk-JYASTIIW.js.map +0 -1
  74. package/dist/chunk-OKXOCNXP.js +0 -105
  75. package/dist/chunk-OKXOCNXP.js.map +0 -1
  76. package/dist/chunk-WKERTCM6.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/module/remove.ts"],"sourcesContent":["import { type CommandDefinition, BaseCommand, logger, runCommand } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport YAML from 'yaml';\n\nexport default class ModuleRemoveCommand extends BaseCommand {\n static usage = 'module remove <name>';\n static description = 'Remove an installed module.';\n static requiresProject = true;\n\n static args: CommandDefinition = {\n args: [\n { name: 'name', required: true, description: 'Name of the module to remove' }\n ]\n };\n\n async run(options: any) {\n const projectRoot = this.projectRoot as string;\n let { name } = options;\n\n const relativePath = `modules/${name}`;\n const fullPath = path.resolve(projectRoot, relativePath);\n\n logger.debug('Removing module at:', fullPath);\n\n if (!(await fs.pathExists(fullPath))) {\n this.error(`Module ${name} not found at ${relativePath}.`);\n return;\n }\n\n this.info(`Removing module ${name}...`);\n\n try {\n await runCommand(`git submodule deinit -f ${relativePath}`, projectRoot);\n await runCommand(`git rm -f ${relativePath}`, projectRoot);\n\n // Clean up .git/modules\n const gitModulesDir = path.resolve(projectRoot, '.git', 'modules', 'modules', name);\n if (await fs.pathExists(gitModulesDir)) {\n await fs.remove(gitModulesDir);\n }\n\n this.info('Syncing workspace dependencies...');\n await runCommand('npm install', projectRoot);\n\n\n await this.removeFromConfig(name);\n\n this.success(`Module ${name} removed successfully.`);\n } catch (e: any) {\n this.error(`Failed to remove module: ${e.message}`);\n }\n }\n\n private async removeFromConfig(moduleName: string) {\n const projectRoot = this.projectRoot as string;\n const configPath = path.join(projectRoot, 'nexical.yaml');\n\n if (!await fs.pathExists(configPath)) return;\n\n try {\n const content = await fs.readFile(configPath, 'utf8');\n let config = YAML.parse(content) || {};\n\n if (config.modules && config.modules.includes(moduleName)) {\n config.modules = config.modules.filter((m: string) => m !== moduleName);\n await fs.writeFile(configPath, YAML.stringify(config));\n logger.debug(`Removed ${moduleName} from nexical.yaml modules list.`);\n }\n } catch (e: any) {\n logger.warn(`Failed to update nexical.yaml: ${e.message}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAiC,aAAa,QAAQ,kBAAkB;AAExE,OAAO,UAAU;AACjB,OAAO,UAAU;AAEjB,IAAqB,sBAArB,cAAiD,YAAY;AAAA,EACzD,OAAO,QAAQ;AAAA,EACf,OAAO,cAAc;AAAA,EACrB,OAAO,kBAAkB;AAAA,EAEzB,OAAO,OAA0B;AAAA,IAC7B,MAAM;AAAA,MACF,EAAE,MAAM,QAAQ,UAAU,MAAM,aAAa,+BAA+B;AAAA,IAChF;AAAA,EACJ;AAAA,EAEA,MAAM,IAAI,SAAc;AACpB,UAAM,cAAc,KAAK;AACzB,QAAI,EAAE,KAAK,IAAI;AAEf,UAAM,eAAe,WAAW,IAAI;AACpC,UAAM,WAAW,KAAK,QAAQ,aAAa,YAAY;AAEvD,WAAO,MAAM,uBAAuB,QAAQ;AAE5C,QAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,QAAQ,GAAI;AAClC,WAAK,MAAM,UAAU,IAAI,iBAAiB,YAAY,GAAG;AACzD;AAAA,IACJ;AAEA,SAAK,KAAK,mBAAmB,IAAI,KAAK;AAEtC,QAAI;AACA,YAAM,WAAW,2BAA2B,YAAY,IAAI,WAAW;AACvE,YAAM,WAAW,aAAa,YAAY,IAAI,WAAW;AAGzD,YAAM,gBAAgB,KAAK,QAAQ,aAAa,QAAQ,WAAW,WAAW,IAAI;AAClF,UAAI,MAAM,gBAAAA,QAAG,WAAW,aAAa,GAAG;AACpC,cAAM,gBAAAA,QAAG,OAAO,aAAa;AAAA,MACjC;AAEA,WAAK,KAAK,mCAAmC;AAC7C,YAAM,WAAW,eAAe,WAAW;AAG3C,YAAM,KAAK,iBAAiB,IAAI;AAEhC,WAAK,QAAQ,UAAU,IAAI,wBAAwB;AAAA,IACvD,SAAS,GAAQ;AACb,WAAK,MAAM,4BAA4B,EAAE,OAAO,EAAE;AAAA,IACtD;AAAA,EACJ;AAAA,EAEA,MAAc,iBAAiB,YAAoB;AAC/C,UAAM,cAAc,KAAK;AACzB,UAAM,aAAa,KAAK,KAAK,aAAa,cAAc;AAExD,QAAI,CAAC,MAAM,gBAAAA,QAAG,WAAW,UAAU,EAAG;AAEtC,QAAI;AACA,YAAM,UAAU,MAAM,gBAAAA,QAAG,SAAS,YAAY,MAAM;AACpD,UAAI,SAAS,KAAK,MAAM,OAAO,KAAK,CAAC;AAErC,UAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,UAAU,GAAG;AACvD,eAAO,UAAU,OAAO,QAAQ,OAAO,CAAC,MAAc,MAAM,UAAU;AACtE,cAAM,gBAAAA,QAAG,UAAU,YAAY,KAAK,UAAU,MAAM,CAAC;AACrD,eAAO,MAAM,WAAW,UAAU,kCAAkC;AAAA,MACxE;AAAA,IACJ,SAAS,GAAQ;AACb,aAAO,KAAK,kCAAkC,EAAE,OAAO,EAAE;AAAA,IAC7D;AAAA,EACJ;AACJ;","names":["fs"]}
1
+ {"version":3,"sources":["../../../../src/commands/module/remove.ts"],"sourcesContent":["import { type CommandDefinition, BaseCommand, logger, runCommand } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport YAML from 'yaml';\n\nexport default class ModuleRemoveCommand extends BaseCommand {\n static usage = 'module remove <name>';\n static description = 'Remove an installed module.';\n static requiresProject = true;\n\n static args: CommandDefinition = {\n args: [{ name: 'name', required: true, description: 'Name of the module to remove' }],\n };\n\n async run(options: { name: string }) {\n const projectRoot = this.projectRoot as string;\n const { name } = options;\n\n const relativePath = `modules/${name}`;\n const fullPath = path.resolve(projectRoot, relativePath);\n\n logger.debug('Removing module at:', fullPath);\n\n if (!(await fs.pathExists(fullPath))) {\n this.error(`Module ${name} not found at ${relativePath}.`);\n return;\n }\n\n this.info(`Removing module ${name}...`);\n\n try {\n await runCommand(`git submodule deinit -f ${relativePath}`, projectRoot);\n await runCommand(`git rm -f ${relativePath}`, projectRoot);\n\n // Clean up .git/modules\n const gitModulesDir = path.resolve(projectRoot, '.git', 'modules', 'modules', name);\n if (await fs.pathExists(gitModulesDir)) {\n await fs.remove(gitModulesDir);\n }\n\n this.info('Syncing workspace dependencies...');\n await runCommand('npm install', projectRoot);\n\n await this.removeFromConfig(name);\n\n this.success(`Module ${name} removed successfully.`);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.error(`Failed to remove module: ${e.message}`);\n } else {\n this.error(`Failed to remove module: ${String(e)}`);\n }\n }\n }\n\n private async removeFromConfig(moduleName: string) {\n const projectRoot = this.projectRoot as string;\n const configPath = path.join(projectRoot, 'nexical.yaml');\n\n if (!(await fs.pathExists(configPath))) return;\n\n try {\n const content = await fs.readFile(configPath, 'utf8');\n const config = YAML.parse(content) || {};\n\n if (config.modules && config.modules.includes(moduleName)) {\n config.modules = config.modules.filter((m: string) => m !== moduleName);\n await fs.writeFile(configPath, YAML.stringify(config));\n logger.debug(`Removed ${moduleName} from nexical.yaml modules list.`);\n }\n } catch (e: unknown) {\n if (e instanceof Error) {\n logger.warn(`Failed to update nexical.yaml: ${e.message}`);\n } else {\n logger.warn(`Failed to update nexical.yaml: ${String(e)}`);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAiC,aAAa,QAAQ,kBAAkB;AAExE,OAAO,UAAU;AACjB,OAAO,UAAU;AAEjB,IAAqB,sBAArB,cAAiD,YAAY;AAAA,EAC3D,OAAO,QAAQ;AAAA,EACf,OAAO,cAAc;AAAA,EACrB,OAAO,kBAAkB;AAAA,EAEzB,OAAO,OAA0B;AAAA,IAC/B,MAAM,CAAC,EAAE,MAAM,QAAQ,UAAU,MAAM,aAAa,+BAA+B,CAAC;AAAA,EACtF;AAAA,EAEA,MAAM,IAAI,SAA2B;AACnC,UAAM,cAAc,KAAK;AACzB,UAAM,EAAE,KAAK,IAAI;AAEjB,UAAM,eAAe,WAAW,IAAI;AACpC,UAAM,WAAW,KAAK,QAAQ,aAAa,YAAY;AAEvD,WAAO,MAAM,uBAAuB,QAAQ;AAE5C,QAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,QAAQ,GAAI;AACpC,WAAK,MAAM,UAAU,IAAI,iBAAiB,YAAY,GAAG;AACzD;AAAA,IACF;AAEA,SAAK,KAAK,mBAAmB,IAAI,KAAK;AAEtC,QAAI;AACF,YAAM,WAAW,2BAA2B,YAAY,IAAI,WAAW;AACvE,YAAM,WAAW,aAAa,YAAY,IAAI,WAAW;AAGzD,YAAM,gBAAgB,KAAK,QAAQ,aAAa,QAAQ,WAAW,WAAW,IAAI;AAClF,UAAI,MAAM,gBAAAA,QAAG,WAAW,aAAa,GAAG;AACtC,cAAM,gBAAAA,QAAG,OAAO,aAAa;AAAA,MAC/B;AAEA,WAAK,KAAK,mCAAmC;AAC7C,YAAM,WAAW,eAAe,WAAW;AAE3C,YAAM,KAAK,iBAAiB,IAAI;AAEhC,WAAK,QAAQ,UAAU,IAAI,wBAAwB;AAAA,IACrD,SAAS,GAAY;AACnB,UAAI,aAAa,OAAO;AACtB,aAAK,MAAM,4BAA4B,EAAE,OAAO,EAAE;AAAA,MACpD,OAAO;AACL,aAAK,MAAM,4BAA4B,OAAO,CAAC,CAAC,EAAE;AAAA,MACpD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,iBAAiB,YAAoB;AACjD,UAAM,cAAc,KAAK;AACzB,UAAM,aAAa,KAAK,KAAK,aAAa,cAAc;AAExD,QAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,UAAU,EAAI;AAExC,QAAI;AACF,YAAM,UAAU,MAAM,gBAAAA,QAAG,SAAS,YAAY,MAAM;AACpD,YAAM,SAAS,KAAK,MAAM,OAAO,KAAK,CAAC;AAEvC,UAAI,OAAO,WAAW,OAAO,QAAQ,SAAS,UAAU,GAAG;AACzD,eAAO,UAAU,OAAO,QAAQ,OAAO,CAAC,MAAc,MAAM,UAAU;AACtE,cAAM,gBAAAA,QAAG,UAAU,YAAY,KAAK,UAAU,MAAM,CAAC;AACrD,eAAO,MAAM,WAAW,UAAU,kCAAkC;AAAA,MACtE;AAAA,IACF,SAAS,GAAY;AACnB,UAAI,aAAa,OAAO;AACtB,eAAO,KAAK,kCAAkC,EAAE,OAAO,EAAE;AAAA,MAC3D,OAAO;AACL,eAAO,KAAK,kCAAkC,OAAO,CAAC,CAAC,EAAE;AAAA,MAC3D;AAAA,IACF;AAAA,EACF;AACF;","names":["fs"]}
@@ -5,7 +5,9 @@ declare class ModuleUpdateCommand extends BaseCommand {
5
5
  static description: string;
6
6
  static requiresProject: boolean;
7
7
  static args: CommandDefinition;
8
- run(options: any): Promise<void>;
8
+ run(options: {
9
+ name?: string;
10
+ }): Promise<void>;
9
11
  }
10
12
 
11
13
  export { ModuleUpdateCommand as default };
@@ -17,13 +17,11 @@ var ModuleUpdateCommand = class extends BaseCommand {
17
17
  static description = "Update a specific module or all modules.";
18
18
  static requiresProject = true;
19
19
  static args = {
20
- args: [
21
- { name: "name", required: false, description: "Name of the module to update" }
22
- ]
20
+ args: [{ name: "name", required: false, description: "Name of the module to update" }]
23
21
  };
24
22
  async run(options) {
25
23
  const projectRoot = this.projectRoot;
26
- let { name } = options;
24
+ const { name } = options;
27
25
  this.info(name ? `Updating module ${name}...` : "Updating all modules...");
28
26
  logger.debug("Update context:", { name, projectRoot });
29
27
  try {
@@ -42,7 +40,11 @@ var ModuleUpdateCommand = class extends BaseCommand {
42
40
  await runCommand("npm install", projectRoot);
43
41
  this.success("Modules updated successfully.");
44
42
  } catch (e) {
45
- this.error(`Failed to update modules: ${e.message}`);
43
+ if (e instanceof Error) {
44
+ this.error(`Failed to update modules: ${e.message}`);
45
+ } else {
46
+ this.error(`Failed to update modules: ${String(e)}`);
47
+ }
46
48
  }
47
49
  }
48
50
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/commands/module/update.ts"],"sourcesContent":["import { type CommandDefinition, BaseCommand, logger, runCommand } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nexport default class ModuleUpdateCommand extends BaseCommand {\n static usage = 'module update [name]';\n static description = 'Update a specific module or all modules.';\n static requiresProject = true;\n\n static args: CommandDefinition = {\n args: [\n { name: 'name', required: false, description: 'Name of the module to update' }\n ]\n };\n\n async run(options: any) {\n const projectRoot = this.projectRoot as string;\n let { name } = options;\n\n this.info(name ? `Updating module ${name}...` : 'Updating all modules...');\n logger.debug('Update context:', { name, projectRoot: projectRoot });\n\n try {\n if (name) {\n const relativePath = `modules/${name}`;\n const fullPath = path.resolve(projectRoot, relativePath);\n\n if (!(await fs.pathExists(fullPath))) {\n this.error(`Module ${name} not found.`);\n return;\n }\n\n // Update specific module\n // We enter the directory and pull? Or generic submodule update?\n // Generic submodule update --remote src/modules/name\n await runCommand(`git submodule update --remote --merge ${relativePath}`, projectRoot);\n } else {\n // Update all\n await runCommand('git submodule update --remote --merge', projectRoot);\n }\n\n this.info('Syncing workspace dependencies...');\n await runCommand('npm install', projectRoot);\n\n this.success('Modules updated successfully.');\n } catch (e: any) {\n this.error(`Failed to update modules: ${e.message}`);\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAiC,aAAa,QAAQ,kBAAkB;AAExE,OAAO,UAAU;AAEjB,IAAqB,sBAArB,cAAiD,YAAY;AAAA,EACzD,OAAO,QAAQ;AAAA,EACf,OAAO,cAAc;AAAA,EACrB,OAAO,kBAAkB;AAAA,EAEzB,OAAO,OAA0B;AAAA,IAC7B,MAAM;AAAA,MACF,EAAE,MAAM,QAAQ,UAAU,OAAO,aAAa,+BAA+B;AAAA,IACjF;AAAA,EACJ;AAAA,EAEA,MAAM,IAAI,SAAc;AACpB,UAAM,cAAc,KAAK;AACzB,QAAI,EAAE,KAAK,IAAI;AAEf,SAAK,KAAK,OAAO,mBAAmB,IAAI,QAAQ,yBAAyB;AACzE,WAAO,MAAM,mBAAmB,EAAE,MAAM,YAAyB,CAAC;AAElE,QAAI;AACA,UAAI,MAAM;AACN,cAAM,eAAe,WAAW,IAAI;AACpC,cAAM,WAAW,KAAK,QAAQ,aAAa,YAAY;AAEvD,YAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,QAAQ,GAAI;AAClC,eAAK,MAAM,UAAU,IAAI,aAAa;AACtC;AAAA,QACJ;AAKA,cAAM,WAAW,yCAAyC,YAAY,IAAI,WAAW;AAAA,MACzF,OAAO;AAEH,cAAM,WAAW,yCAAyC,WAAW;AAAA,MACzE;AAEA,WAAK,KAAK,mCAAmC;AAC7C,YAAM,WAAW,eAAe,WAAW;AAE3C,WAAK,QAAQ,+BAA+B;AAAA,IAChD,SAAS,GAAQ;AACb,WAAK,MAAM,6BAA6B,EAAE,OAAO,EAAE;AAAA,IACvD;AAAA,EACJ;AACJ;","names":["fs"]}
1
+ {"version":3,"sources":["../../../../src/commands/module/update.ts"],"sourcesContent":["import { type CommandDefinition, BaseCommand, logger, runCommand } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nexport default class ModuleUpdateCommand extends BaseCommand {\n static usage = 'module update [name]';\n static description = 'Update a specific module or all modules.';\n static requiresProject = true;\n\n static args: CommandDefinition = {\n args: [{ name: 'name', required: false, description: 'Name of the module to update' }],\n };\n\n async run(options: { name?: string }) {\n const projectRoot = this.projectRoot as string;\n const { name } = options;\n\n this.info(name ? `Updating module ${name}...` : 'Updating all modules...');\n logger.debug('Update context:', { name, projectRoot: projectRoot });\n\n try {\n if (name) {\n const relativePath = `modules/${name}`;\n const fullPath = path.resolve(projectRoot, relativePath);\n\n if (!(await fs.pathExists(fullPath))) {\n this.error(`Module ${name} not found.`);\n return;\n }\n\n // Update specific module\n // We enter the directory and pull? Or generic submodule update?\n // Generic submodule update --remote src/modules/name\n await runCommand(`git submodule update --remote --merge ${relativePath}`, projectRoot);\n } else {\n // Update all\n await runCommand('git submodule update --remote --merge', projectRoot);\n }\n\n this.info('Syncing workspace dependencies...');\n await runCommand('npm install', projectRoot);\n\n this.success('Modules updated successfully.');\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.error(`Failed to update modules: ${e.message}`);\n } else {\n this.error(`Failed to update modules: ${String(e)}`);\n }\n }\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAiC,aAAa,QAAQ,kBAAkB;AAExE,OAAO,UAAU;AAEjB,IAAqB,sBAArB,cAAiD,YAAY;AAAA,EAC3D,OAAO,QAAQ;AAAA,EACf,OAAO,cAAc;AAAA,EACrB,OAAO,kBAAkB;AAAA,EAEzB,OAAO,OAA0B;AAAA,IAC/B,MAAM,CAAC,EAAE,MAAM,QAAQ,UAAU,OAAO,aAAa,+BAA+B,CAAC;AAAA,EACvF;AAAA,EAEA,MAAM,IAAI,SAA4B;AACpC,UAAM,cAAc,KAAK;AACzB,UAAM,EAAE,KAAK,IAAI;AAEjB,SAAK,KAAK,OAAO,mBAAmB,IAAI,QAAQ,yBAAyB;AACzE,WAAO,MAAM,mBAAmB,EAAE,MAAM,YAAyB,CAAC;AAElE,QAAI;AACF,UAAI,MAAM;AACR,cAAM,eAAe,WAAW,IAAI;AACpC,cAAM,WAAW,KAAK,QAAQ,aAAa,YAAY;AAEvD,YAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,QAAQ,GAAI;AACpC,eAAK,MAAM,UAAU,IAAI,aAAa;AACtC;AAAA,QACF;AAKA,cAAM,WAAW,yCAAyC,YAAY,IAAI,WAAW;AAAA,MACvF,OAAO;AAEL,cAAM,WAAW,yCAAyC,WAAW;AAAA,MACvE;AAEA,WAAK,KAAK,mCAAmC;AAC7C,YAAM,WAAW,eAAe,WAAW;AAE3C,WAAK,QAAQ,+BAA+B;AAAA,IAC9C,SAAS,GAAY;AACnB,UAAI,aAAa,OAAO;AACtB,aAAK,MAAM,6BAA6B,EAAE,OAAO,EAAE;AAAA,MACrD,OAAO;AACL,aAAK,MAAM,6BAA6B,OAAO,CAAC,CAAC,EAAE;AAAA,MACrD;AAAA,IACF;AAAA,EACF;AACF;","names":["fs"]}
@@ -5,7 +5,10 @@ declare class RunCommand extends BaseCommand {
5
5
  static description: string;
6
6
  static requiresProject: boolean;
7
7
  static args: CommandDefinition;
8
- run(options: any): Promise<void>;
8
+ run(options: {
9
+ script: string;
10
+ args?: string[];
11
+ }): Promise<void>;
9
12
  }
10
13
 
11
14
  export { RunCommand as default };
@@ -20,7 +20,11 @@ var RunCommand = class extends BaseCommand {
20
20
  static requiresProject = true;
21
21
  static args = {
22
22
  args: [
23
- { name: "script", required: true, description: "The script to run (script-name OR module:script-name)" },
23
+ {
24
+ name: "script",
25
+ required: true,
26
+ description: "The script to run (script-name OR module:script-name)"
27
+ },
24
28
  { name: "args...", required: false, description: "Arguments for the script" }
25
29
  ]
26
30
  };
@@ -56,7 +60,11 @@ var RunCommand = class extends BaseCommand {
56
60
  return;
57
61
  }
58
62
  } catch (e) {
59
- this.error(`Failed to read package.json at ${execPath}: ${e.message}`);
63
+ if (e instanceof Error) {
64
+ this.error(`Failed to read package.json at ${execPath}: ${e.message}`);
65
+ } else {
66
+ this.error(`Failed to read package.json at ${execPath}: ${String(e)}`);
67
+ }
60
68
  return;
61
69
  }
62
70
  const finalArgs = ["run", scriptName, "--", ...scriptArgs];
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/commands/run.ts"],"sourcesContent":["import { type CommandDefinition, BaseCommand, logger } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport process from 'node:process';\n\nexport default class RunCommand extends BaseCommand {\n static usage = 'run <script> [args...]';\n static description = 'Run a script inside the Nexical environment.';\n static requiresProject = true;\n\n static args: CommandDefinition = {\n args: [\n { name: 'script', required: true, description: 'The script to run (script-name OR module:script-name)' },\n { name: 'args...', required: false, description: 'Arguments for the script' }\n ]\n };\n\n async run(options: any) {\n const projectRoot = this.projectRoot as string;\n const script = options.script;\n const scriptArgs = options.args || [];\n\n if (!script) {\n this.error('Please specify a script to run.');\n return;\n }\n\n logger.debug('Run command context:', { script, args: scriptArgs, projectRoot });\n\n let execPath = projectRoot;\n let scriptName = script;\n\n // Handle module:script syntax\n if (script.includes(':')) {\n const [moduleName, name] = script.split(':');\n execPath = path.resolve(projectRoot, 'modules', moduleName);\n scriptName = name;\n\n logger.debug(`Resolving module script: ${moduleName}:${scriptName} at ${execPath}`);\n } else {\n logger.debug(`Resolving core script: ${scriptName} at ${execPath}`);\n }\n\n // Validate script existence\n const pkgJsonPath = path.join(execPath, 'package.json');\n if (!(await fs.pathExists(pkgJsonPath))) {\n this.error(`Failed to find package.json at ${execPath}`);\n return;\n }\n\n try {\n const pkg = await fs.readJson(pkgJsonPath);\n if (!pkg.scripts || !pkg.scripts[scriptName]) {\n const type = script.includes(':') ? `module ${script.split(':')[0]}` : 'Nexical core';\n this.error(`Script \"${scriptName}\" does not exist in ${type}`);\n return;\n }\n } catch (e: any) {\n this.error(`Failed to read package.json at ${execPath}: ${e.message}`);\n return;\n }\n\n const finalArgs = ['run', scriptName, '--', ...scriptArgs];\n logger.debug(`Executing: npm ${finalArgs.join(' ')} in ${execPath}`);\n\n const child = spawn('npm', finalArgs, {\n cwd: execPath,\n stdio: 'inherit',\n env: {\n ...process.env,\n FORCE_COLOR: '1'\n }\n });\n\n // Handle process termination to kill child\n const cleanup = () => {\n child.kill();\n process.exit();\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n\n await new Promise<void>((resolve) => {\n child.on('close', (code) => {\n // Remove listeners to prevent memory leaks if this command is run multiple times in-process (e.g. tests)\n process.off('SIGINT', cleanup);\n process.off('SIGTERM', cleanup);\n\n if (code !== 0) {\n process.exit(code || 1);\n }\n resolve();\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAiC,aAAa,cAAc;AAE5D,OAAO,UAAU;AACjB,SAAS,aAAa;AACtB,OAAO,aAAa;AAEpB,IAAqB,aAArB,cAAwC,YAAY;AAAA,EAChD,OAAO,QAAQ;AAAA,EACf,OAAO,cAAc;AAAA,EACrB,OAAO,kBAAkB;AAAA,EAEzB,OAAO,OAA0B;AAAA,IAC7B,MAAM;AAAA,MACF,EAAE,MAAM,UAAU,UAAU,MAAM,aAAa,wDAAwD;AAAA,MACvG,EAAE,MAAM,WAAW,UAAU,OAAO,aAAa,2BAA2B;AAAA,IAChF;AAAA,EACJ;AAAA,EAEA,MAAM,IAAI,SAAc;AACpB,UAAM,cAAc,KAAK;AACzB,UAAM,SAAS,QAAQ;AACvB,UAAM,aAAa,QAAQ,QAAQ,CAAC;AAEpC,QAAI,CAAC,QAAQ;AACT,WAAK,MAAM,iCAAiC;AAC5C;AAAA,IACJ;AAEA,WAAO,MAAM,wBAAwB,EAAE,QAAQ,MAAM,YAAY,YAAY,CAAC;AAE9E,QAAI,WAAW;AACf,QAAI,aAAa;AAGjB,QAAI,OAAO,SAAS,GAAG,GAAG;AACtB,YAAM,CAAC,YAAY,IAAI,IAAI,OAAO,MAAM,GAAG;AAC3C,iBAAW,KAAK,QAAQ,aAAa,WAAW,UAAU;AAC1D,mBAAa;AAEb,aAAO,MAAM,4BAA4B,UAAU,IAAI,UAAU,OAAO,QAAQ,EAAE;AAAA,IACtF,OAAO;AACH,aAAO,MAAM,0BAA0B,UAAU,OAAO,QAAQ,EAAE;AAAA,IACtE;AAGA,UAAM,cAAc,KAAK,KAAK,UAAU,cAAc;AACtD,QAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,WAAW,GAAI;AACrC,WAAK,MAAM,kCAAkC,QAAQ,EAAE;AACvD;AAAA,IACJ;AAEA,QAAI;AACA,YAAM,MAAM,MAAM,gBAAAA,QAAG,SAAS,WAAW;AACzC,UAAI,CAAC,IAAI,WAAW,CAAC,IAAI,QAAQ,UAAU,GAAG;AAC1C,cAAM,OAAO,OAAO,SAAS,GAAG,IAAI,UAAU,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;AACvE,aAAK,MAAM,WAAW,UAAU,uBAAuB,IAAI,EAAE;AAC7D;AAAA,MACJ;AAAA,IACJ,SAAS,GAAQ;AACb,WAAK,MAAM,kCAAkC,QAAQ,KAAK,EAAE,OAAO,EAAE;AACrE;AAAA,IACJ;AAEA,UAAM,YAAY,CAAC,OAAO,YAAY,MAAM,GAAG,UAAU;AACzD,WAAO,MAAM,kBAAkB,UAAU,KAAK,GAAG,CAAC,OAAO,QAAQ,EAAE;AAEnE,UAAM,QAAQ,MAAM,OAAO,WAAW;AAAA,MAClC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA,QACD,GAAG,QAAQ;AAAA,QACX,aAAa;AAAA,MACjB;AAAA,IACJ,CAAC;AAGD,UAAM,UAAU,MAAM;AAClB,YAAM,KAAK;AACX,cAAQ,KAAK;AAAA,IACjB;AAEA,YAAQ,GAAG,UAAU,OAAO;AAC5B,YAAQ,GAAG,WAAW,OAAO;AAE7B,UAAM,IAAI,QAAc,CAAC,YAAY;AACjC,YAAM,GAAG,SAAS,CAAC,SAAS;AAExB,gBAAQ,IAAI,UAAU,OAAO;AAC7B,gBAAQ,IAAI,WAAW,OAAO;AAE9B,YAAI,SAAS,GAAG;AACZ,kBAAQ,KAAK,QAAQ,CAAC;AAAA,QAC1B;AACA,gBAAQ;AAAA,MACZ,CAAC;AAAA,IACL,CAAC;AAAA,EACL;AACJ;","names":["fs"]}
1
+ {"version":3,"sources":["../../../src/commands/run.ts"],"sourcesContent":["import { type CommandDefinition, BaseCommand, logger } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\nimport { spawn } from 'child_process';\nimport process from 'node:process';\n\nexport default class RunCommand extends BaseCommand {\n static usage = 'run <script> [args...]';\n static description = 'Run a script inside the Nexical environment.';\n static requiresProject = true;\n\n static args: CommandDefinition = {\n args: [\n {\n name: 'script',\n required: true,\n description: 'The script to run (script-name OR module:script-name)',\n },\n { name: 'args...', required: false, description: 'Arguments for the script' },\n ],\n };\n\n async run(options: { script: string; args?: string[] }) {\n const projectRoot = this.projectRoot as string;\n const script = options.script;\n const scriptArgs = options.args || [];\n\n if (!script) {\n this.error('Please specify a script to run.');\n return;\n }\n\n logger.debug('Run command context:', { script, args: scriptArgs, projectRoot });\n\n let execPath = projectRoot;\n let scriptName = script;\n\n // Handle module:script syntax\n if (script.includes(':')) {\n const [moduleName, name] = script.split(':');\n execPath = path.resolve(projectRoot, 'modules', moduleName);\n scriptName = name;\n\n logger.debug(`Resolving module script: ${moduleName}:${scriptName} at ${execPath}`);\n } else {\n logger.debug(`Resolving core script: ${scriptName} at ${execPath}`);\n }\n\n // Validate script existence\n const pkgJsonPath = path.join(execPath, 'package.json');\n if (!(await fs.pathExists(pkgJsonPath))) {\n this.error(`Failed to find package.json at ${execPath}`);\n return;\n }\n\n try {\n const pkg = await fs.readJson(pkgJsonPath);\n if (!pkg.scripts || !pkg.scripts[scriptName]) {\n const type = script.includes(':') ? `module ${script.split(':')[0]}` : 'Nexical core';\n this.error(`Script \"${scriptName}\" does not exist in ${type}`);\n return;\n }\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.error(`Failed to read package.json at ${execPath}: ${e.message}`);\n } else {\n this.error(`Failed to read package.json at ${execPath}: ${String(e)}`);\n }\n return;\n }\n\n const finalArgs = ['run', scriptName, '--', ...scriptArgs];\n logger.debug(`Executing: npm ${finalArgs.join(' ')} in ${execPath}`);\n\n const child = spawn('npm', finalArgs, {\n cwd: execPath,\n stdio: 'inherit',\n env: {\n ...process.env,\n FORCE_COLOR: '1',\n },\n });\n\n // Handle process termination to kill child\n const cleanup = () => {\n child.kill();\n process.exit();\n };\n\n process.on('SIGINT', cleanup);\n process.on('SIGTERM', cleanup);\n\n await new Promise<void>((resolve) => {\n child.on('close', (code) => {\n // Remove listeners to prevent memory leaks if this command is run multiple times in-process (e.g. tests)\n process.off('SIGINT', cleanup);\n process.off('SIGTERM', cleanup);\n\n if (code !== 0) {\n process.exit(code || 1);\n }\n resolve();\n });\n });\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAiC,aAAa,cAAc;AAE5D,OAAO,UAAU;AACjB,SAAS,aAAa;AACtB,OAAO,aAAa;AAEpB,IAAqB,aAArB,cAAwC,YAAY;AAAA,EAClD,OAAO,QAAQ;AAAA,EACf,OAAO,cAAc;AAAA,EACrB,OAAO,kBAAkB;AAAA,EAEzB,OAAO,OAA0B;AAAA,IAC/B,MAAM;AAAA,MACJ;AAAA,QACE,MAAM;AAAA,QACN,UAAU;AAAA,QACV,aAAa;AAAA,MACf;AAAA,MACA,EAAE,MAAM,WAAW,UAAU,OAAO,aAAa,2BAA2B;AAAA,IAC9E;AAAA,EACF;AAAA,EAEA,MAAM,IAAI,SAA8C;AACtD,UAAM,cAAc,KAAK;AACzB,UAAM,SAAS,QAAQ;AACvB,UAAM,aAAa,QAAQ,QAAQ,CAAC;AAEpC,QAAI,CAAC,QAAQ;AACX,WAAK,MAAM,iCAAiC;AAC5C;AAAA,IACF;AAEA,WAAO,MAAM,wBAAwB,EAAE,QAAQ,MAAM,YAAY,YAAY,CAAC;AAE9E,QAAI,WAAW;AACf,QAAI,aAAa;AAGjB,QAAI,OAAO,SAAS,GAAG,GAAG;AACxB,YAAM,CAAC,YAAY,IAAI,IAAI,OAAO,MAAM,GAAG;AAC3C,iBAAW,KAAK,QAAQ,aAAa,WAAW,UAAU;AAC1D,mBAAa;AAEb,aAAO,MAAM,4BAA4B,UAAU,IAAI,UAAU,OAAO,QAAQ,EAAE;AAAA,IACpF,OAAO;AACL,aAAO,MAAM,0BAA0B,UAAU,OAAO,QAAQ,EAAE;AAAA,IACpE;AAGA,UAAM,cAAc,KAAK,KAAK,UAAU,cAAc;AACtD,QAAI,CAAE,MAAM,gBAAAA,QAAG,WAAW,WAAW,GAAI;AACvC,WAAK,MAAM,kCAAkC,QAAQ,EAAE;AACvD;AAAA,IACF;AAEA,QAAI;AACF,YAAM,MAAM,MAAM,gBAAAA,QAAG,SAAS,WAAW;AACzC,UAAI,CAAC,IAAI,WAAW,CAAC,IAAI,QAAQ,UAAU,GAAG;AAC5C,cAAM,OAAO,OAAO,SAAS,GAAG,IAAI,UAAU,OAAO,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;AACvE,aAAK,MAAM,WAAW,UAAU,uBAAuB,IAAI,EAAE;AAC7D;AAAA,MACF;AAAA,IACF,SAAS,GAAY;AACnB,UAAI,aAAa,OAAO;AACtB,aAAK,MAAM,kCAAkC,QAAQ,KAAK,EAAE,OAAO,EAAE;AAAA,MACvE,OAAO;AACL,aAAK,MAAM,kCAAkC,QAAQ,KAAK,OAAO,CAAC,CAAC,EAAE;AAAA,MACvE;AACA;AAAA,IACF;AAEA,UAAM,YAAY,CAAC,OAAO,YAAY,MAAM,GAAG,UAAU;AACzD,WAAO,MAAM,kBAAkB,UAAU,KAAK,GAAG,CAAC,OAAO,QAAQ,EAAE;AAEnE,UAAM,QAAQ,MAAM,OAAO,WAAW;AAAA,MACpC,KAAK;AAAA,MACL,OAAO;AAAA,MACP,KAAK;AAAA,QACH,GAAG,QAAQ;AAAA,QACX,aAAa;AAAA,MACf;AAAA,IACF,CAAC;AAGD,UAAM,UAAU,MAAM;AACpB,YAAM,KAAK;AACX,cAAQ,KAAK;AAAA,IACf;AAEA,YAAQ,GAAG,UAAU,OAAO;AAC5B,YAAQ,GAAG,WAAW,OAAO;AAE7B,UAAM,IAAI,QAAc,CAAC,YAAY;AACnC,YAAM,GAAG,SAAS,CAAC,SAAS;AAE1B,gBAAQ,IAAI,UAAU,OAAO;AAC7B,gBAAQ,IAAI,WAAW,OAAO;AAE9B,YAAI,SAAS,GAAG;AACd,kBAAQ,KAAK,QAAQ,CAAC;AAAA,QACxB;AACA,gBAAQ;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;","names":["fs"]}
@@ -0,0 +1,8 @@
1
+ import { BaseCommand } from '@nexical/cli-core';
2
+
3
+ declare class SetupCommand extends BaseCommand {
4
+ static description: string;
5
+ run(): Promise<void>;
6
+ }
7
+
8
+ export { SetupCommand as default };
@@ -0,0 +1,75 @@
1
+ import { createRequire } from "module"; const require = createRequire(import.meta.url);
2
+ import {
3
+ require_lib
4
+ } from "../../chunk-LZ3YQWAR.js";
5
+ import {
6
+ __toESM,
7
+ init_esm_shims
8
+ } from "../../chunk-OYFWMYPG.js";
9
+
10
+ // src/commands/setup.ts
11
+ init_esm_shims();
12
+ var import_fs_extra = __toESM(require_lib(), 1);
13
+ import { BaseCommand, logger } from "@nexical/cli-core";
14
+ import path from "path";
15
+ var SetupCommand = class extends BaseCommand {
16
+ static description = "Setup the application environment by symlinking core assets.";
17
+ async run() {
18
+ const rootDir = process.cwd();
19
+ if (!import_fs_extra.default.existsSync(path.join(rootDir, "core"))) {
20
+ this.error('Could not find "core" directory. Are you in the project root?');
21
+ process.exit(1);
22
+ }
23
+ const apps = ["frontend", "backend"];
24
+ const sharedAssets = [
25
+ "prisma",
26
+ "src",
27
+ "public",
28
+ "locales",
29
+ "scripts",
30
+ "astro.config.mjs",
31
+ "tsconfig.json"
32
+ ];
33
+ for (const app of apps) {
34
+ const appDir = path.join(rootDir, "apps", app);
35
+ if (!import_fs_extra.default.existsSync(appDir)) {
36
+ this.warn(`App directory ${app} not found. Skipping.`);
37
+ continue;
38
+ }
39
+ this.info(`Setting up ${app}...`);
40
+ for (const asset of sharedAssets) {
41
+ const source = path.join(rootDir, "core", asset);
42
+ const dest = path.join(appDir, asset);
43
+ if (!import_fs_extra.default.existsSync(source)) {
44
+ this.warn(`Source asset ${asset} not found in core.`);
45
+ continue;
46
+ }
47
+ try {
48
+ const destDir = path.dirname(dest);
49
+ await import_fs_extra.default.ensureDir(destDir);
50
+ try {
51
+ import_fs_extra.default.lstatSync(dest);
52
+ import_fs_extra.default.removeSync(dest);
53
+ } catch (e) {
54
+ if (e && typeof e === "object" && "code" in e && e.code !== "ENOENT")
55
+ throw e;
56
+ }
57
+ const relSource = path.relative(destDir, source);
58
+ await import_fs_extra.default.symlink(relSource, dest);
59
+ logger.debug(`Symlinked ${asset} to ${app}`);
60
+ } catch (e) {
61
+ if (e instanceof Error) {
62
+ this.error(`Failed to symlink ${asset} to ${app}: ${e.message}`);
63
+ } else {
64
+ this.error(`Failed to symlink ${asset} to ${app}: ${String(e)}`);
65
+ }
66
+ }
67
+ }
68
+ }
69
+ this.success("Application setup complete.");
70
+ }
71
+ };
72
+ export {
73
+ SetupCommand as default
74
+ };
75
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/commands/setup.ts"],"sourcesContent":["import { BaseCommand, logger } from '@nexical/cli-core';\nimport fs from 'fs-extra';\nimport path from 'path';\n\nexport default class SetupCommand extends BaseCommand {\n static description = 'Setup the application environment by symlinking core assets.';\n\n async run() {\n // We assume we are in the project root\n // But the CLI might be run from anywhere?\n // findProjectRoot in index.ts handles finding the root.\n // BaseCommand has this.projectRoot?\n\n // BaseCommand doesn't expose projectRoot directly in current implementation seen in memory, checking source if possible?\n // InitCommand used process.cwd().\n\n // Let's assume process.cwd() is project root if run via `npm run setup` from root.\n const rootDir = process.cwd();\n\n // Verify we are in the right place\n if (!fs.existsSync(path.join(rootDir, 'core'))) {\n this.error('Could not find \"core\" directory. Are you in the project root?');\n process.exit(1);\n }\n\n const apps = ['frontend', 'backend'];\n const sharedAssets = [\n 'prisma',\n 'src',\n 'public',\n 'locales',\n 'scripts',\n 'astro.config.mjs',\n 'tsconfig.json',\n ]; // tsconfig might be needed if extended\n\n for (const app of apps) {\n const appDir = path.join(rootDir, 'apps', app);\n if (!fs.existsSync(appDir)) {\n this.warn(`App directory ${app} not found. Skipping.`);\n continue;\n }\n\n this.info(`Setting up ${app}...`);\n\n for (const asset of sharedAssets) {\n const source = path.join(rootDir, 'core', asset);\n const dest = path.join(appDir, asset);\n\n if (!fs.existsSync(source)) {\n this.warn(`Source asset ${asset} not found in core.`);\n continue;\n }\n\n try {\n // Remove existing destination if it exists (to ensure clean symlink)\n // Be careful not to delete real files if they aren't symlinks?\n // For now, we assume setup controls these.\n\n const destDir = path.dirname(dest);\n await fs.ensureDir(destDir);\n\n try {\n fs.lstatSync(dest);\n fs.removeSync(dest);\n } catch (e: unknown) {\n if (\n e &&\n typeof e === 'object' &&\n 'code' in e &&\n (e as { code: string }).code !== 'ENOENT'\n )\n throw e;\n }\n\n const relSource = path.relative(destDir, source);\n await fs.symlink(relSource, dest);\n\n logger.debug(`Symlinked ${asset} to ${app}`);\n } catch (e: unknown) {\n if (e instanceof Error) {\n this.error(`Failed to symlink ${asset} to ${app}: ${e.message}`);\n } else {\n this.error(`Failed to symlink ${asset} to ${app}: ${String(e)}`);\n }\n }\n }\n }\n\n this.success('Application setup complete.');\n }\n}\n"],"mappings":";;;;;;;;;;AAAA;AACA,sBAAe;AADf,SAAS,aAAa,cAAc;AAEpC,OAAO,UAAU;AAEjB,IAAqB,eAArB,cAA0C,YAAY;AAAA,EACpD,OAAO,cAAc;AAAA,EAErB,MAAM,MAAM;AAUV,UAAM,UAAU,QAAQ,IAAI;AAG5B,QAAI,CAAC,gBAAAA,QAAG,WAAW,KAAK,KAAK,SAAS,MAAM,CAAC,GAAG;AAC9C,WAAK,MAAM,+DAA+D;AAC1E,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,OAAO,CAAC,YAAY,SAAS;AACnC,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF;AAEA,eAAW,OAAO,MAAM;AACtB,YAAM,SAAS,KAAK,KAAK,SAAS,QAAQ,GAAG;AAC7C,UAAI,CAAC,gBAAAA,QAAG,WAAW,MAAM,GAAG;AAC1B,aAAK,KAAK,iBAAiB,GAAG,uBAAuB;AACrD;AAAA,MACF;AAEA,WAAK,KAAK,cAAc,GAAG,KAAK;AAEhC,iBAAW,SAAS,cAAc;AAChC,cAAM,SAAS,KAAK,KAAK,SAAS,QAAQ,KAAK;AAC/C,cAAM,OAAO,KAAK,KAAK,QAAQ,KAAK;AAEpC,YAAI,CAAC,gBAAAA,QAAG,WAAW,MAAM,GAAG;AAC1B,eAAK,KAAK,gBAAgB,KAAK,qBAAqB;AACpD;AAAA,QACF;AAEA,YAAI;AAKF,gBAAM,UAAU,KAAK,QAAQ,IAAI;AACjC,gBAAM,gBAAAA,QAAG,UAAU,OAAO;AAE1B,cAAI;AACF,4BAAAA,QAAG,UAAU,IAAI;AACjB,4BAAAA,QAAG,WAAW,IAAI;AAAA,UACpB,SAAS,GAAY;AACnB,gBACE,KACA,OAAO,MAAM,YACb,UAAU,KACT,EAAuB,SAAS;AAEjC,oBAAM;AAAA,UACV;AAEA,gBAAM,YAAY,KAAK,SAAS,SAAS,MAAM;AAC/C,gBAAM,gBAAAA,QAAG,QAAQ,WAAW,IAAI;AAEhC,iBAAO,MAAM,aAAa,KAAK,OAAO,GAAG,EAAE;AAAA,QAC7C,SAAS,GAAY;AACnB,cAAI,aAAa,OAAO;AACtB,iBAAK,MAAM,qBAAqB,KAAK,OAAO,GAAG,KAAK,EAAE,OAAO,EAAE;AAAA,UACjE,OAAO;AACL,iBAAK,MAAM,qBAAqB,KAAK,OAAO,GAAG,KAAK,OAAO,CAAC,CAAC,EAAE;AAAA,UACjE;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,SAAK,QAAQ,6BAA6B;AAAA,EAC5C;AACF;","names":["fs"]}
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "module"; const require = createRequire(import.meta.url);
2
2
  import {
3
3
  discoverCommandDirectories
4
- } from "../../chunk-OKXOCNXP.js";
4
+ } from "../../chunk-AC4B3HPJ.js";
5
5
  import "../../chunk-OYFWMYPG.js";
6
6
  export {
7
7
  discoverCommandDirectories
@@ -11,7 +11,7 @@ import {
11
11
  renameBranch,
12
12
  renameRemote,
13
13
  updateSubmodules
14
- } from "../../chunk-WKERTCM6.js";
14
+ } from "../../chunk-Q7YLW5HJ.js";
15
15
  import "../../chunk-OYFWMYPG.js";
16
16
  export {
17
17
  addAll,
@@ -1,7 +1,7 @@
1
1
  import { createRequire } from "module"; const require = createRequire(import.meta.url);
2
2
  import {
3
3
  resolveGitUrl
4
- } from "../../chunk-JYASTIIW.js";
4
+ } from "../../chunk-PJIOCW2A.js";
5
5
  import "../../chunk-OYFWMYPG.js";
6
6
  export {
7
7
  resolveGitUrl
@@ -0,0 +1,67 @@
1
+ import eslintPluginAstro from 'eslint-plugin-astro';
2
+ import eslintPluginReact from 'eslint-plugin-react';
3
+ import eslintPluginReactHooks from 'eslint-plugin-react-hooks';
4
+ import eslintPluginJsxA11y from 'eslint-plugin-jsx-a11y';
5
+ import eslintConfigPrettier from 'eslint-config-prettier';
6
+ import tseslint from 'typescript-eslint';
7
+ import globals from 'globals';
8
+ import js from '@eslint/js';
9
+
10
+ export default tseslint.config(
11
+ // Global ignore
12
+ {
13
+ ignores: ['**/dist/**', '**/node_modules/**', '**/coverage/**', '**/.astro/**', '**/.agent/**'],
14
+ },
15
+
16
+ // Base JS/TS configuration
17
+ js.configs.recommended,
18
+ ...tseslint.configs.recommended,
19
+
20
+ // React configuration
21
+ {
22
+ files: ['**/*.{js,jsx,mjs,cjs,ts,tsx}'],
23
+ plugins: {
24
+ react: eslintPluginReact,
25
+ 'react-hooks': eslintPluginReactHooks,
26
+ 'jsx-a11y': eslintPluginJsxA11y,
27
+ },
28
+ languageOptions: {
29
+ parserOptions: {
30
+ ecmaFeatures: {
31
+ jsx: true,
32
+ },
33
+ },
34
+ globals: {
35
+ ...globals.browser,
36
+ ...globals.node,
37
+ },
38
+ },
39
+ settings: {
40
+ react: {
41
+ version: 'detect',
42
+ },
43
+ },
44
+ rules: {
45
+ ...eslintPluginReact.configs.recommended.rules,
46
+ ...eslintPluginReactHooks.configs.recommended.rules,
47
+ ...eslintPluginJsxA11y.configs.recommended.rules,
48
+ 'react/react-in-jsx-scope': 'off', // Not needed in React 17+ or Astro
49
+ 'react/no-unknown-property': 'off', // Conflicts with some Astro/Web Component patterns
50
+ },
51
+ },
52
+
53
+ // Astro configuration
54
+ ...eslintPluginAstro.configs.recommended,
55
+
56
+ // Custom rules override
57
+ {
58
+ rules: {
59
+ '@typescript-eslint/no-unused-vars': ['error', { args: 'none', varsIgnorePattern: '^_' }],
60
+ '@typescript-eslint/no-explicit-any': 'warn', // Downgrade to warning for now as codebase has some anys
61
+ 'no-console': ['warn', { allow: ['warn', 'error', 'info'] }],
62
+ },
63
+ },
64
+
65
+ // Prettier must be last to override conflicting rules
66
+ eslintConfigPrettier,
67
+ );
package/index.ts CHANGED
@@ -8,31 +8,45 @@ import path from 'node:path';
8
8
  const __dirname = path.dirname(fileURLToPath(import.meta.url));
9
9
 
10
10
  const commandName = 'nexical';
11
- const projectRoot = await findProjectRoot(commandName, process.cwd()) || process.cwd();
11
+ const projectRoot = (await findProjectRoot(commandName, process.cwd())) || process.cwd();
12
12
  const coreCommandsDir = path.resolve(__dirname, './src/commands');
13
13
  const additionalCommands = discoverCommandDirectories(projectRoot);
14
14
 
15
- // Filter out the source version of core commands if we are running from dist
16
- const filteredAdditional = additionalCommands.filter(dir => {
17
- if (dir === coreCommandsDir) return false;
18
-
19
- // Handle the case where we are running from dist/ and it finds src/commands in projectRoot
20
- if (coreCommandsDir.includes(path.join(path.sep, 'dist', 'src', 'commands'))) {
21
- const srcVersion = coreCommandsDir.replace(
22
- path.join(path.sep, 'dist', 'src', 'commands'),
23
- path.join(path.sep, 'src', 'commands')
24
- );
25
- if (dir === srcVersion) return false;
26
- }
27
- return true;
15
+ // Filter out duplicate core commands and source versions
16
+ const filteredAdditional = additionalCommands.filter((dir) => {
17
+ const resolvedDir = path.resolve(dir);
18
+ const resolvedCore = path.resolve(coreCommandsDir);
19
+
20
+ if (resolvedDir === resolvedCore) return false;
21
+
22
+ // Check if this is another instance of the core CLI commands (by checking path suffix)
23
+ const coreSuffix = path.join('@nexical', 'cli', 'dist', 'src', 'commands');
24
+ const coreSuffixSrc = path.join('packages', 'cli', 'dist', 'src', 'commands');
25
+ const coreSuffixRawSrc = path.join('packages', 'cli', 'src', 'commands');
26
+
27
+ if (
28
+ resolvedDir.endsWith(coreSuffix) ||
29
+ resolvedDir.endsWith(coreSuffixSrc) ||
30
+ resolvedDir.endsWith(coreSuffixRawSrc)
31
+ ) {
32
+ return false;
33
+ }
34
+
35
+ // Handle mismatch between dist/src and src/
36
+ if (resolvedCore.includes(path.join(path.sep, 'dist', 'src', 'commands'))) {
37
+ const srcVersion = resolvedCore.replace(
38
+ path.join(path.sep, 'dist', 'src', 'commands'),
39
+ path.join(path.sep, 'src', 'commands'),
40
+ );
41
+ if (resolvedDir === srcVersion) return false;
42
+ }
43
+
44
+ return true;
28
45
  });
29
46
 
30
47
  const app = new CLI({
31
- version: pkg.version,
32
- commandName: commandName,
33
- searchDirectories: [...new Set([
34
- coreCommandsDir,
35
- ...filteredAdditional
36
- ])]
48
+ version: pkg.version,
49
+ commandName: commandName,
50
+ searchDirectories: [...new Set([coreCommandsDir, ...filteredAdditional])],
37
51
  });
38
52
  app.start();
package/package.json CHANGED
@@ -1,34 +1,58 @@
1
1
  {
2
- "name": "@nexical/cli",
3
- "version": "0.10.0",
4
- "type": "module",
5
- "bin": {
6
- "nexical": "./dist/index.js"
7
- },
8
- "scripts": {
9
- "build": "tsup",
10
- "dev": "tsup --watch",
11
- "start": "node dist/index.js",
12
- "test": "npm run test:unit && npm run test:integration && npm run test:e2e",
13
- "test:unit": "vitest run --config vitest.config.ts --coverage",
14
- "test:integration": "vitest run --config vitest.integration.config.ts",
15
- "test:e2e": "npm run build && vitest run --config vitest.e2e.config.ts",
16
- "test:watch": "vitest"
17
- },
18
- "dependencies": {
19
- "@nexical/cli-core": "^0.1.12",
20
- "yaml": "^2.3.4",
21
- "fast-glob": "^3.3.3"
22
- },
23
- "devDependencies": {
24
- "@types/fs-extra": "^11.0.4",
25
- "@types/node": "^20.10.0",
26
- "@vitest/coverage-v8": "^4.0.15",
27
- "execa": "^9.6.1",
28
- "fs-extra": "^11.3.2",
29
- "tsup": "^8.0.1",
30
- "tsx": "^4.21.0",
31
- "typescript": "^5.3.3",
32
- "vitest": "^4.0.15"
33
- }
34
- }
2
+ "name": "@nexical/cli",
3
+ "version": "0.11.1",
4
+ "type": "module",
5
+ "bin": {
6
+ "nexical": "./dist/index.js"
7
+ },
8
+ "scripts": {
9
+ "build": "tsup",
10
+ "dev": "tsup --watch",
11
+ "start": "node dist/index.js",
12
+ "test": "npm run test:unit && npm run test:integration && npm run test:e2e",
13
+ "test:unit": "vitest run --config vitest.config.ts --coverage",
14
+ "test:integration": "vitest run --config vitest.integration.config.ts",
15
+ "test:e2e": "npm run build && vitest run --config vitest.e2e.config.ts",
16
+ "test:watch": "vitest",
17
+ "format": "prettier --write .",
18
+ "lint": "eslint .",
19
+ "lint:fix": "eslint . --fix",
20
+ "prepare": "husky"
21
+ },
22
+ "lint-staged": {
23
+ "**/*": [
24
+ "prettier --write --ignore-unknown"
25
+ ],
26
+ "**/*.{js,jsx,ts,tsx,astro}": [
27
+ "eslint --fix"
28
+ ]
29
+ },
30
+ "dependencies": {
31
+ "@nexical/cli-core": "^0.1.12",
32
+ "yaml": "^2.3.4",
33
+ "fast-glob": "^3.3.3"
34
+ },
35
+ "devDependencies": {
36
+ "@types/fs-extra": "^11.0.4",
37
+ "@types/node": "^20.10.0",
38
+ "@vitest/coverage-v8": "^4.0.15",
39
+ "execa": "^9.6.1",
40
+ "fs-extra": "^11.3.2",
41
+ "tsup": "^8.0.1",
42
+ "tsx": "^4.21.0",
43
+ "typescript": "^5.3.3",
44
+ "vitest": "^4.0.15",
45
+ "@eslint/js": "^9.39.2",
46
+ "eslint": "^9.39.2",
47
+ "eslint-config-prettier": "^10.1.8",
48
+ "eslint-plugin-astro": "^1.5.0",
49
+ "eslint-plugin-jsx-a11y": "^6.10.2",
50
+ "eslint-plugin-react": "^7.37.5",
51
+ "eslint-plugin-react-hooks": "^7.0.1",
52
+ "globals": "^17.2.0",
53
+ "husky": "^9.1.7",
54
+ "lint-staged": "^16.2.7",
55
+ "prettier": "^3.8.1",
56
+ "typescript-eslint": "^8.54.0"
57
+ }
58
+ }