@h3ravel/musket 0.1.9 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -262,11 +262,11 @@ var Signature = class Signature {
262
262
  /**
263
263
  * Check for nested options after '|'
264
264
  */
265
- let description$1 = rest;
265
+ let description = rest;
266
266
  let nestedOptions;
267
267
  const pipeIndex = rest.indexOf("|");
268
268
  if (pipeIndex !== -1) {
269
- description$1 = rest.substring(0, pipeIndex).trim();
269
+ description = rest.substring(0, pipeIndex).trim();
270
270
  /**
271
271
  * nestedText should start with '{' and end with ')', clean it
272
272
  * Also Remove trailing ')' if present
@@ -280,20 +280,20 @@ var Signature = class Signature {
280
280
  /**
281
281
  * Trim the string
282
282
  */
283
- description$1 = description$1.trim();
284
- let name$1 = namePart;
283
+ description = description.trim();
284
+ let name = namePart;
285
285
  let flags;
286
286
  let choices = [];
287
- let required = /[^a-zA-Z0-9_|-]/.test(name$1);
287
+ let required = /[^a-zA-Z0-9_|-]/.test(name);
288
288
  let multiple = false;
289
289
  let placeholder;
290
290
  let defaultValue;
291
291
  /**
292
292
  * Parse the command name
293
293
  */
294
- if (name$1.includes("=")) {
295
- const [rawName, rawDefault] = name$1.split("=");
296
- name$1 = rawName.trim();
294
+ if (name.includes("=")) {
295
+ const [rawName, rawDefault] = name.split("=");
296
+ name = rawName.trim();
297
297
  const hold = rawName.trim().split("|");
298
298
  const holder = (hold.at(1) ?? hold.at(0)).replace("--", "");
299
299
  defaultValue = rawDefault.trim();
@@ -303,27 +303,27 @@ var Signature = class Signature {
303
303
  /**
304
304
  * Parse name modifiers (?, *, ?*)
305
305
  */
306
- if (name$1.endsWith("?*")) {
306
+ if (name.endsWith("?*")) {
307
307
  required = false;
308
308
  multiple = true;
309
- name$1 = name$1.slice(0, -2);
310
- } else if (name$1.endsWith("*")) {
309
+ name = name.slice(0, -2);
310
+ } else if (name.endsWith("*")) {
311
311
  multiple = true;
312
- name$1 = name$1.slice(0, -1);
313
- } else if (name$1.endsWith("?")) {
312
+ name = name.slice(0, -1);
313
+ } else if (name.endsWith("?")) {
314
314
  required = false;
315
- name$1 = name$1.slice(0, -1);
316
- placeholder = `[${name$1.split("--").at(1)?.split("|").at(1) ?? name$1}]`;
315
+ name = name.slice(0, -1);
316
+ placeholder = `[${name.split("--").at(1)?.split("|").at(1) ?? name}]`;
317
317
  }
318
318
  /**
319
319
  * Check if it's a flag option (starts with --)
320
320
  */
321
- const isFlag = name$1.startsWith("--");
321
+ const isFlag = name.startsWith("--");
322
322
  if (isFlag) {
323
323
  /**
324
324
  * Parse flags and default values
325
325
  */
326
- const flagParts = name$1.split("|").map((s) => s.trim());
326
+ const flagParts = name.split("|").map((s) => s.trim());
327
327
  flags = [];
328
328
  for (let part of flagParts) {
329
329
  if (part.startsWith("--") && part.slice(2).length === 1) part = "-" + part.slice(2);
@@ -340,17 +340,17 @@ var Signature = class Signature {
340
340
  } else flags.push(part);
341
341
  }
342
342
  }
343
- const desc = description$1.match(/^([^:]+?)\s*:\s*\[?([\w\s,]+)\]?$/);
343
+ const desc = description.match(/^([^:]+?)\s*:\s*\[?([\w\s,]+)\]?$/);
344
344
  if (match) {
345
- description$1 = desc?.[1].trim() ?? description$1;
345
+ description = desc?.[1].trim() ?? description;
346
346
  choices = desc?.[2].split(",").map((s) => s.trim()).filter(Boolean) ?? choices;
347
347
  }
348
348
  options.push({
349
- name: isFlag ? flags[flags.length - 1] : name$1,
349
+ name: isFlag ? flags[flags.length - 1] : name,
350
350
  choices,
351
351
  required,
352
352
  multiple,
353
- description: description$1,
353
+ description,
354
354
  flags,
355
355
  shared,
356
356
  isFlag,
@@ -373,7 +373,7 @@ var Signature = class Signature {
373
373
  const lines = signature.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
374
374
  const isHidden = ["#", "^"].includes(lines[0][0]) || /:[#^]/.test(lines[0]);
375
375
  const baseCommand = lines[0].split("{")[0].trim().replace(/[^\w:-]/g, "");
376
- const description$1 = commandClass.getDescription();
376
+ const description = commandClass.getDescription();
377
377
  const isNamespaceCommand = baseCommand.endsWith(":");
378
378
  /**
379
379
  * Join the rest lines to a single string for parsing
@@ -396,7 +396,7 @@ var Signature = class Signature {
396
396
  baseCommand: baseCommand.slice(0, -1),
397
397
  isNamespaceCommand,
398
398
  subCommands: allOptions.filter((e) => !e.flags && !e.isHidden),
399
- description: description$1,
399
+ description,
400
400
  commandClass,
401
401
  options: allOptions.filter((e) => !!e.flags),
402
402
  isHidden
@@ -405,7 +405,7 @@ var Signature = class Signature {
405
405
  baseCommand,
406
406
  isNamespaceCommand,
407
407
  options: allOptions,
408
- description: description$1,
408
+ description,
409
409
  commandClass,
410
410
  isHidden
411
411
  };
@@ -508,11 +508,11 @@ var ListCommand = class ListCommand extends Command {
508
508
  });
509
509
  const list = ListCommand.groupItems(commands);
510
510
  /** Output the modules version */
511
- const version$1 = this.kernel.modules.map((e) => {
511
+ const version = this.kernel.modules.map((e) => {
512
512
  return __h3ravel_shared.Logger.log([[`${__h3ravel_support.Str.of(e.alias ?? e.name).afterLast("/").ucfirst().replace(["-", "_"], " ").replace("cli", "CLI", false)}:`, "white"], [e.version, "green"]], " ", false);
513
513
  }).join(" | ");
514
514
  this.newLine();
515
- console.log(version$1);
515
+ console.log(version);
516
516
  this.newLine();
517
517
  console.log(this.kernel.config.logo ?? altLogo);
518
518
  this.newLine();
@@ -610,9 +610,9 @@ var Musket = class Musket {
610
610
  * CLI Commands auto registration
611
611
  */
612
612
  for await (const pth of glob.glob.stream(paths)) {
613
- const name$1 = node_path.default.basename(pth).replace(".js", "").replace(".ts", "");
613
+ const name = node_path.default.basename(pth).replace(".js", "").replace(".ts", "");
614
614
  try {
615
- const cmdClass = (await import(pth))[name$1];
615
+ const cmdClass = (await import(pth))[name];
616
616
  commands.push(new cmdClass(this.app, this.kernel));
617
617
  } catch {}
618
618
  }
@@ -635,8 +635,9 @@ var Musket = class Musket {
635
635
  verbose: ["-v, --verbose [level]", "Increase the verbosity of messages: 1 for normal output, 2 and v for more verbose output and 3 and vv for debug"],
636
636
  noInteraction: ["-n, --no-interaction", "Do not ask any interactive question"]
637
637
  };
638
- /**
639
- * Init Commander
638
+ if (!this.config.rootCommand)
639
+ /**
640
+ * Run the base Command if a root command was not defined
640
641
  */
641
642
  commander.program.name(this.cliName).version(moduleVersions).description(this.config.logo ?? altLogo).configureHelp({ showGlobalOptions: true }).addOption(new commander.Option(additional.quiet[0], additional.quiet[1])).addOption(new commander.Option(additional.silent[0], additional.silent[1]).implies({ quiet: true })).addOption(new commander.Option(additional.verbose[0], additional.verbose[1]).choices([
642
643
  "1",
@@ -649,6 +650,20 @@ var Musket = class Musket {
649
650
  instance.setInput(commander.program.opts(), commander.program.args, commander.program.registeredArguments, {}, commander.program);
650
651
  await this.handle(instance);
651
652
  });
653
+ else {
654
+ /**
655
+ * Load the root command here
656
+ */
657
+ const root = new this.config.rootCommand(this.app, this.kernel);
658
+ const sign = Signature.parseSignature(root.getSignature(), root);
659
+ const cmd = commander.program.name(sign.baseCommand).description(sign.description ?? sign.baseCommand).configureHelp({ showGlobalOptions: true }).action(async () => {
660
+ root.setInput(commander.program.opts(), commander.program.args, commander.program.registeredArguments, {}, commander.program);
661
+ await this.handle(root);
662
+ });
663
+ if ((sign.options?.length ?? 0) > 0) sign.options?.filter((v, i, a) => a.findIndex((t) => t.name === v.name) === i).forEach((opt) => {
664
+ this.makeOption(opt, cmd);
665
+ });
666
+ }
652
667
  /**
653
668
  * Format the help command display
654
669
  */
@@ -739,8 +754,8 @@ var Musket = class Musket {
739
754
  });
740
755
  return commander.program;
741
756
  }
742
- async rebuild(name$1) {
743
- if (name$1 !== "fire" && name$1 !== "build") await (0, tsdown.build)({
757
+ async rebuild(name) {
758
+ if (name !== "fire" && name !== "build" && this.config.allowRebuilds) await (0, tsdown.build)({
744
759
  ...this.tsDownConfig,
745
760
  logLevel: "silent",
746
761
  watch: false,
@@ -748,27 +763,27 @@ var Musket = class Musket {
748
763
  });
749
764
  }
750
765
  makeOption(opt, cmd, parse, parent) {
751
- const description$1 = opt.description?.replace(/\[(\w+)\]/g, (_, k) => parent?.[k] ?? `[${k}]`) ?? "";
752
- const type$1 = opt.name.replaceAll("-", "");
766
+ const description = opt.description?.replace(/\[(\w+)\]/g, (_, k) => parent?.[k] ?? `[${k}]`) ?? "";
767
+ const type = opt.name.replaceAll("-", "");
753
768
  if (opt.isFlag) if (parse) {
754
769
  let flags = opt.flags?.map((f) => f.length === 1 ? `-${f}` : `--${f.replace(/^-+/, "")}`).join(", ") ?? void 0;
755
- if (opt.required && !opt.placeholder) flags += ` <${type$1}>`;
770
+ if (opt.required && !opt.placeholder) flags += ` <${type}>`;
756
771
  else if (opt.placeholder) flags += " " + opt.placeholder;
757
- let optn = new commander.Option(flags || "", description$1).default(opt.defaultValue);
772
+ let optn = new commander.Option(flags || "", description).default(opt.defaultValue);
758
773
  if (opt.choices && opt.choices.length) optn = optn.choices(opt.choices ?? []);
759
774
  cmd.addOption(optn);
760
775
  } else {
761
776
  let flags = opt.flags?.join(", ") ?? "";
762
- if (opt.required && !opt.placeholder) flags += ` <${type$1}>`;
777
+ if (opt.required && !opt.placeholder) flags += ` <${type}>`;
763
778
  else if (opt.placeholder) flags += " " + opt.placeholder;
764
- let optn = new commander.Option(flags, description$1).default(opt.defaultValue);
779
+ let optn = new commander.Option(flags, description).default(opt.defaultValue);
765
780
  if (opt.choices && opt.choices.length) optn = optn.choices(opt.choices ?? []);
766
781
  cmd.addOption(optn);
767
782
  }
768
783
  else {
769
- let name$1 = opt.placeholder;
770
- if (!name$1) name$1 = opt.required ? `<${opt.name}>` : `[${opt.name}]`;
771
- let arg = new commander.Argument(name$1, description$1);
784
+ let name = opt.placeholder;
785
+ if (!name) name = opt.required ? `<${opt.name}>` : `[${opt.name}]`;
786
+ let arg = new commander.Argument(name, description);
772
787
  if (opt.choices && opt.choices.length) arg = arg.choices(opt.choices ?? []);
773
788
  if (opt.defaultValue) arg.default(opt.defaultValue);
774
789
  cmd.addArgument(arg);
@@ -797,109 +812,6 @@ var Musket = class Musket {
797
812
  }
798
813
  };
799
814
 
800
- //#endregion
801
- //#region package.json
802
- var name = "@h3ravel/musket";
803
- var version = "0.1.8";
804
- var description = "Musket CLI is a framework-agnostic CLI framework designed to allow you build artisan-like CLI apps and for use in the H3ravel framework.";
805
- var type = "module";
806
- var exports$1 = {
807
- ".": {
808
- "import": "./dist/index.js",
809
- "require": "./dist/index.cjs"
810
- },
811
- "./Utils": {
812
- "import": "./dist/Utils.js",
813
- "require": "./dist/Utils.cjs"
814
- }
815
- };
816
- var typesVersions = { "*": {
817
- "Utils": ["dist/Utils.d.ts"],
818
- "*": ["dist/index.d.ts"]
819
- } };
820
- var files = ["dist"];
821
- var publishConfig = { "access": "public" };
822
- var homepage = "https://h3ravel.toneflix.net/guide/deeper/musket";
823
- var repository = {
824
- "type": "git",
825
- "url": "git+https://github.com/h3ravel/musket.git"
826
- };
827
- var keywords = [
828
- "h3ravel",
829
- "modern",
830
- "web",
831
- "H3",
832
- "framework",
833
- "nodejs",
834
- "typescript",
835
- "laravel",
836
- "artisan",
837
- "musket",
838
- "commander",
839
- "command",
840
- "CLI",
841
- "build",
842
- "console"
843
- ];
844
- var scripts = {
845
- "build": "tsdown --config-loader unconfig",
846
- "lint": "eslint . --ext .ts",
847
- "barrel": "barrelize >/dev/null",
848
- "test": "vitest",
849
- "coverage": "vitest --coverage",
850
- "cmd": "tsx --experimental-specifier-resolution=node tests/run",
851
- "release:patch": "pnpm build && pnpm version patch && git add . && git commit -m \"version: bump console package version\" && pnpm publish --tag latest",
852
- "version-patch": "pnpm version patch",
853
- "postinstall": "pnpm barrel"
854
- };
855
- var peerDependencies = { "@h3ravel/support": "^0.14.1" };
856
- var devDependencies = {
857
- "@types/node": "^24.7.2",
858
- "@typescript-eslint/eslint-plugin": "^8.44.0",
859
- "@typescript-eslint/parser": "^8.44.0",
860
- "@vitest/coverage-v8": "^3.2.4",
861
- "barrelize": "^1.6.4",
862
- "eslint": "^9.36.0",
863
- "husky": "^9.1.7",
864
- "tsdown": "^0.15.7",
865
- "typescript": "^5.9.2",
866
- "vite-tsconfig-paths": "^5.1.4",
867
- "vitest": "^3.2.4"
868
- };
869
- var dependencies = {
870
- "@h3ravel/shared": "^0.22.2",
871
- "chalk": "^5.6.2",
872
- "commander": "^14.0.1",
873
- "dayjs": "^1.11.18",
874
- "execa": "^9.6.0",
875
- "glob": "^11.0.3",
876
- "preferred-pm": "^4.1.1",
877
- "radashi": "^12.6.2",
878
- "resolve-from": "^5.0.0",
879
- "tsx": "^4.20.5"
880
- };
881
- var packageManager = "pnpm@10.18.2";
882
- var engines = { "node": "^20.19.0 || >=22.12.0" };
883
- var package_default = {
884
- name,
885
- version,
886
- description,
887
- type,
888
- exports: exports$1,
889
- typesVersions,
890
- files,
891
- publishConfig,
892
- homepage,
893
- repository,
894
- keywords,
895
- scripts,
896
- peerDependencies,
897
- devDependencies,
898
- dependencies,
899
- packageManager,
900
- engines
901
- };
902
-
903
815
  //#endregion
904
816
  //#region src/Core/Kernel.ts
905
817
  var Kernel = class Kernel {
@@ -927,14 +839,15 @@ var Kernel = class Kernel {
927
839
  async loadRequirements() {
928
840
  this.cwd = node_path.default.join(process.cwd(), this.basePath);
929
841
  if (!this.config.hideMusketInfo) try {
930
- package_default.name = this.config.cliName ?? package_default.name;
931
- this.modules.push(package_default);
842
+ const pkg = (await import(node_path.default.join(process.cwd(), "package.json"))).default;
843
+ pkg.name = this.config.cliName ?? pkg.name;
844
+ this.modules.push(pkg);
932
845
  } catch {}
933
846
  for (let i = 0; i < this.packages.length; i++) try {
934
847
  const item = this.packages[i];
935
- const name$1 = typeof item === "string" ? item : item.name;
848
+ const name = typeof item === "string" ? item : item.name;
936
849
  const alias = typeof item === "string" ? item : item.alias;
937
- const modulePath = __h3ravel_shared.FileSystem.findModulePkg(name$1, this.cwd) ?? "";
850
+ const modulePath = __h3ravel_shared.FileSystem.findModulePkg(name, this.cwd) ?? "";
938
851
  const pkg = (await import(node_path.default.join(modulePath, "package.json"))).default;
939
852
  pkg.alias = alias;
940
853
  this.modules.push(pkg);
package/dist/index.d.cts CHANGED
@@ -91,10 +91,18 @@ interface InitConfig {
91
91
  * version info will not be unexpectedly shown in console
92
92
  */
93
93
  hideMusketInfo?: boolean;
94
+ /**
95
+ * If enabled rebuilds will be triggered when code changes happen
96
+ */
97
+ allowRebuilds?: boolean;
94
98
  /**
95
99
  * Commands that should be autoloaded by default
96
100
  */
97
101
  baseCommands?: typeof Command[];
102
+ /**
103
+ * A command that will be run when the script is run without arguments
104
+ */
105
+ rootCommand?: typeof Command;
98
106
  /**
99
107
  * Paths where musket can search and auto discover commands
100
108
  *
package/dist/index.d.ts CHANGED
@@ -91,10 +91,18 @@ interface InitConfig {
91
91
  * version info will not be unexpectedly shown in console
92
92
  */
93
93
  hideMusketInfo?: boolean;
94
+ /**
95
+ * If enabled rebuilds will be triggered when code changes happen
96
+ */
97
+ allowRebuilds?: boolean;
94
98
  /**
95
99
  * Commands that should be autoloaded by default
96
100
  */
97
101
  baseCommands?: typeof Command[];
102
+ /**
103
+ * A command that will be run when the script is run without arguments
104
+ */
105
+ rootCommand?: typeof Command;
98
106
  /**
99
107
  * Paths where musket can search and auto discover commands
100
108
  *
package/dist/index.js CHANGED
@@ -232,11 +232,11 @@ var Signature = class Signature {
232
232
  /**
233
233
  * Check for nested options after '|'
234
234
  */
235
- let description$1 = rest;
235
+ let description = rest;
236
236
  let nestedOptions;
237
237
  const pipeIndex = rest.indexOf("|");
238
238
  if (pipeIndex !== -1) {
239
- description$1 = rest.substring(0, pipeIndex).trim();
239
+ description = rest.substring(0, pipeIndex).trim();
240
240
  /**
241
241
  * nestedText should start with '{' and end with ')', clean it
242
242
  * Also Remove trailing ')' if present
@@ -250,20 +250,20 @@ var Signature = class Signature {
250
250
  /**
251
251
  * Trim the string
252
252
  */
253
- description$1 = description$1.trim();
254
- let name$1 = namePart;
253
+ description = description.trim();
254
+ let name = namePart;
255
255
  let flags;
256
256
  let choices = [];
257
- let required = /[^a-zA-Z0-9_|-]/.test(name$1);
257
+ let required = /[^a-zA-Z0-9_|-]/.test(name);
258
258
  let multiple = false;
259
259
  let placeholder;
260
260
  let defaultValue;
261
261
  /**
262
262
  * Parse the command name
263
263
  */
264
- if (name$1.includes("=")) {
265
- const [rawName, rawDefault] = name$1.split("=");
266
- name$1 = rawName.trim();
264
+ if (name.includes("=")) {
265
+ const [rawName, rawDefault] = name.split("=");
266
+ name = rawName.trim();
267
267
  const hold = rawName.trim().split("|");
268
268
  const holder = (hold.at(1) ?? hold.at(0)).replace("--", "");
269
269
  defaultValue = rawDefault.trim();
@@ -273,27 +273,27 @@ var Signature = class Signature {
273
273
  /**
274
274
  * Parse name modifiers (?, *, ?*)
275
275
  */
276
- if (name$1.endsWith("?*")) {
276
+ if (name.endsWith("?*")) {
277
277
  required = false;
278
278
  multiple = true;
279
- name$1 = name$1.slice(0, -2);
280
- } else if (name$1.endsWith("*")) {
279
+ name = name.slice(0, -2);
280
+ } else if (name.endsWith("*")) {
281
281
  multiple = true;
282
- name$1 = name$1.slice(0, -1);
283
- } else if (name$1.endsWith("?")) {
282
+ name = name.slice(0, -1);
283
+ } else if (name.endsWith("?")) {
284
284
  required = false;
285
- name$1 = name$1.slice(0, -1);
286
- placeholder = `[${name$1.split("--").at(1)?.split("|").at(1) ?? name$1}]`;
285
+ name = name.slice(0, -1);
286
+ placeholder = `[${name.split("--").at(1)?.split("|").at(1) ?? name}]`;
287
287
  }
288
288
  /**
289
289
  * Check if it's a flag option (starts with --)
290
290
  */
291
- const isFlag = name$1.startsWith("--");
291
+ const isFlag = name.startsWith("--");
292
292
  if (isFlag) {
293
293
  /**
294
294
  * Parse flags and default values
295
295
  */
296
- const flagParts = name$1.split("|").map((s) => s.trim());
296
+ const flagParts = name.split("|").map((s) => s.trim());
297
297
  flags = [];
298
298
  for (let part of flagParts) {
299
299
  if (part.startsWith("--") && part.slice(2).length === 1) part = "-" + part.slice(2);
@@ -310,17 +310,17 @@ var Signature = class Signature {
310
310
  } else flags.push(part);
311
311
  }
312
312
  }
313
- const desc = description$1.match(/^([^:]+?)\s*:\s*\[?([\w\s,]+)\]?$/);
313
+ const desc = description.match(/^([^:]+?)\s*:\s*\[?([\w\s,]+)\]?$/);
314
314
  if (match) {
315
- description$1 = desc?.[1].trim() ?? description$1;
315
+ description = desc?.[1].trim() ?? description;
316
316
  choices = desc?.[2].split(",").map((s) => s.trim()).filter(Boolean) ?? choices;
317
317
  }
318
318
  options.push({
319
- name: isFlag ? flags[flags.length - 1] : name$1,
319
+ name: isFlag ? flags[flags.length - 1] : name,
320
320
  choices,
321
321
  required,
322
322
  multiple,
323
- description: description$1,
323
+ description,
324
324
  flags,
325
325
  shared,
326
326
  isFlag,
@@ -343,7 +343,7 @@ var Signature = class Signature {
343
343
  const lines = signature.split("\n").map((l) => l.trim()).filter((l) => l.length > 0);
344
344
  const isHidden = ["#", "^"].includes(lines[0][0]) || /:[#^]/.test(lines[0]);
345
345
  const baseCommand = lines[0].split("{")[0].trim().replace(/[^\w:-]/g, "");
346
- const description$1 = commandClass.getDescription();
346
+ const description = commandClass.getDescription();
347
347
  const isNamespaceCommand = baseCommand.endsWith(":");
348
348
  /**
349
349
  * Join the rest lines to a single string for parsing
@@ -366,7 +366,7 @@ var Signature = class Signature {
366
366
  baseCommand: baseCommand.slice(0, -1),
367
367
  isNamespaceCommand,
368
368
  subCommands: allOptions.filter((e) => !e.flags && !e.isHidden),
369
- description: description$1,
369
+ description,
370
370
  commandClass,
371
371
  options: allOptions.filter((e) => !!e.flags),
372
372
  isHidden
@@ -375,7 +375,7 @@ var Signature = class Signature {
375
375
  baseCommand,
376
376
  isNamespaceCommand,
377
377
  options: allOptions,
378
- description: description$1,
378
+ description,
379
379
  commandClass,
380
380
  isHidden
381
381
  };
@@ -478,11 +478,11 @@ var ListCommand = class ListCommand extends Command {
478
478
  });
479
479
  const list = ListCommand.groupItems(commands);
480
480
  /** Output the modules version */
481
- const version$1 = this.kernel.modules.map((e) => {
481
+ const version = this.kernel.modules.map((e) => {
482
482
  return Logger.log([[`${Str.of(e.alias ?? e.name).afterLast("/").ucfirst().replace(["-", "_"], " ").replace("cli", "CLI", false)}:`, "white"], [e.version, "green"]], " ", false);
483
483
  }).join(" | ");
484
484
  this.newLine();
485
- console.log(version$1);
485
+ console.log(version);
486
486
  this.newLine();
487
487
  console.log(this.kernel.config.logo ?? altLogo);
488
488
  this.newLine();
@@ -580,9 +580,9 @@ var Musket = class Musket {
580
580
  * CLI Commands auto registration
581
581
  */
582
582
  for await (const pth of glob.stream(paths)) {
583
- const name$1 = path.basename(pth).replace(".js", "").replace(".ts", "");
583
+ const name = path.basename(pth).replace(".js", "").replace(".ts", "");
584
584
  try {
585
- const cmdClass = (await import(pth))[name$1];
585
+ const cmdClass = (await import(pth))[name];
586
586
  commands.push(new cmdClass(this.app, this.kernel));
587
587
  } catch {}
588
588
  }
@@ -605,8 +605,9 @@ var Musket = class Musket {
605
605
  verbose: ["-v, --verbose [level]", "Increase the verbosity of messages: 1 for normal output, 2 and v for more verbose output and 3 and vv for debug"],
606
606
  noInteraction: ["-n, --no-interaction", "Do not ask any interactive question"]
607
607
  };
608
- /**
609
- * Init Commander
608
+ if (!this.config.rootCommand)
609
+ /**
610
+ * Run the base Command if a root command was not defined
610
611
  */
611
612
  program.name(this.cliName).version(moduleVersions).description(this.config.logo ?? altLogo).configureHelp({ showGlobalOptions: true }).addOption(new Option(additional.quiet[0], additional.quiet[1])).addOption(new Option(additional.silent[0], additional.silent[1]).implies({ quiet: true })).addOption(new Option(additional.verbose[0], additional.verbose[1]).choices([
612
613
  "1",
@@ -619,6 +620,20 @@ var Musket = class Musket {
619
620
  instance.setInput(program.opts(), program.args, program.registeredArguments, {}, program);
620
621
  await this.handle(instance);
621
622
  });
623
+ else {
624
+ /**
625
+ * Load the root command here
626
+ */
627
+ const root = new this.config.rootCommand(this.app, this.kernel);
628
+ const sign = Signature.parseSignature(root.getSignature(), root);
629
+ const cmd = program.name(sign.baseCommand).description(sign.description ?? sign.baseCommand).configureHelp({ showGlobalOptions: true }).action(async () => {
630
+ root.setInput(program.opts(), program.args, program.registeredArguments, {}, program);
631
+ await this.handle(root);
632
+ });
633
+ if ((sign.options?.length ?? 0) > 0) sign.options?.filter((v, i, a) => a.findIndex((t) => t.name === v.name) === i).forEach((opt) => {
634
+ this.makeOption(opt, cmd);
635
+ });
636
+ }
622
637
  /**
623
638
  * Format the help command display
624
639
  */
@@ -709,8 +724,8 @@ var Musket = class Musket {
709
724
  });
710
725
  return program;
711
726
  }
712
- async rebuild(name$1) {
713
- if (name$1 !== "fire" && name$1 !== "build") await build({
727
+ async rebuild(name) {
728
+ if (name !== "fire" && name !== "build" && this.config.allowRebuilds) await build({
714
729
  ...this.tsDownConfig,
715
730
  logLevel: "silent",
716
731
  watch: false,
@@ -718,27 +733,27 @@ var Musket = class Musket {
718
733
  });
719
734
  }
720
735
  makeOption(opt, cmd, parse, parent) {
721
- const description$1 = opt.description?.replace(/\[(\w+)\]/g, (_, k) => parent?.[k] ?? `[${k}]`) ?? "";
722
- const type$1 = opt.name.replaceAll("-", "");
736
+ const description = opt.description?.replace(/\[(\w+)\]/g, (_, k) => parent?.[k] ?? `[${k}]`) ?? "";
737
+ const type = opt.name.replaceAll("-", "");
723
738
  if (opt.isFlag) if (parse) {
724
739
  let flags = opt.flags?.map((f) => f.length === 1 ? `-${f}` : `--${f.replace(/^-+/, "")}`).join(", ") ?? void 0;
725
- if (opt.required && !opt.placeholder) flags += ` <${type$1}>`;
740
+ if (opt.required && !opt.placeholder) flags += ` <${type}>`;
726
741
  else if (opt.placeholder) flags += " " + opt.placeholder;
727
- let optn = new Option(flags || "", description$1).default(opt.defaultValue);
742
+ let optn = new Option(flags || "", description).default(opt.defaultValue);
728
743
  if (opt.choices && opt.choices.length) optn = optn.choices(opt.choices ?? []);
729
744
  cmd.addOption(optn);
730
745
  } else {
731
746
  let flags = opt.flags?.join(", ") ?? "";
732
- if (opt.required && !opt.placeholder) flags += ` <${type$1}>`;
747
+ if (opt.required && !opt.placeholder) flags += ` <${type}>`;
733
748
  else if (opt.placeholder) flags += " " + opt.placeholder;
734
- let optn = new Option(flags, description$1).default(opt.defaultValue);
749
+ let optn = new Option(flags, description).default(opt.defaultValue);
735
750
  if (opt.choices && opt.choices.length) optn = optn.choices(opt.choices ?? []);
736
751
  cmd.addOption(optn);
737
752
  }
738
753
  else {
739
- let name$1 = opt.placeholder;
740
- if (!name$1) name$1 = opt.required ? `<${opt.name}>` : `[${opt.name}]`;
741
- let arg = new Argument(name$1, description$1);
754
+ let name = opt.placeholder;
755
+ if (!name) name = opt.required ? `<${opt.name}>` : `[${opt.name}]`;
756
+ let arg = new Argument(name, description);
742
757
  if (opt.choices && opt.choices.length) arg = arg.choices(opt.choices ?? []);
743
758
  if (opt.defaultValue) arg.default(opt.defaultValue);
744
759
  cmd.addArgument(arg);
@@ -767,109 +782,6 @@ var Musket = class Musket {
767
782
  }
768
783
  };
769
784
 
770
- //#endregion
771
- //#region package.json
772
- var name = "@h3ravel/musket";
773
- var version = "0.1.8";
774
- var description = "Musket CLI is a framework-agnostic CLI framework designed to allow you build artisan-like CLI apps and for use in the H3ravel framework.";
775
- var type = "module";
776
- var exports = {
777
- ".": {
778
- "import": "./dist/index.js",
779
- "require": "./dist/index.cjs"
780
- },
781
- "./Utils": {
782
- "import": "./dist/Utils.js",
783
- "require": "./dist/Utils.cjs"
784
- }
785
- };
786
- var typesVersions = { "*": {
787
- "Utils": ["dist/Utils.d.ts"],
788
- "*": ["dist/index.d.ts"]
789
- } };
790
- var files = ["dist"];
791
- var publishConfig = { "access": "public" };
792
- var homepage = "https://h3ravel.toneflix.net/guide/deeper/musket";
793
- var repository = {
794
- "type": "git",
795
- "url": "git+https://github.com/h3ravel/musket.git"
796
- };
797
- var keywords = [
798
- "h3ravel",
799
- "modern",
800
- "web",
801
- "H3",
802
- "framework",
803
- "nodejs",
804
- "typescript",
805
- "laravel",
806
- "artisan",
807
- "musket",
808
- "commander",
809
- "command",
810
- "CLI",
811
- "build",
812
- "console"
813
- ];
814
- var scripts = {
815
- "build": "tsdown --config-loader unconfig",
816
- "lint": "eslint . --ext .ts",
817
- "barrel": "barrelize >/dev/null",
818
- "test": "vitest",
819
- "coverage": "vitest --coverage",
820
- "cmd": "tsx --experimental-specifier-resolution=node tests/run",
821
- "release:patch": "pnpm build && pnpm version patch && git add . && git commit -m \"version: bump console package version\" && pnpm publish --tag latest",
822
- "version-patch": "pnpm version patch",
823
- "postinstall": "pnpm barrel"
824
- };
825
- var peerDependencies = { "@h3ravel/support": "^0.14.1" };
826
- var devDependencies = {
827
- "@types/node": "^24.7.2",
828
- "@typescript-eslint/eslint-plugin": "^8.44.0",
829
- "@typescript-eslint/parser": "^8.44.0",
830
- "@vitest/coverage-v8": "^3.2.4",
831
- "barrelize": "^1.6.4",
832
- "eslint": "^9.36.0",
833
- "husky": "^9.1.7",
834
- "tsdown": "^0.15.7",
835
- "typescript": "^5.9.2",
836
- "vite-tsconfig-paths": "^5.1.4",
837
- "vitest": "^3.2.4"
838
- };
839
- var dependencies = {
840
- "@h3ravel/shared": "^0.22.2",
841
- "chalk": "^5.6.2",
842
- "commander": "^14.0.1",
843
- "dayjs": "^1.11.18",
844
- "execa": "^9.6.0",
845
- "glob": "^11.0.3",
846
- "preferred-pm": "^4.1.1",
847
- "radashi": "^12.6.2",
848
- "resolve-from": "^5.0.0",
849
- "tsx": "^4.20.5"
850
- };
851
- var packageManager = "pnpm@10.18.2";
852
- var engines = { "node": "^20.19.0 || >=22.12.0" };
853
- var package_default = {
854
- name,
855
- version,
856
- description,
857
- type,
858
- exports,
859
- typesVersions,
860
- files,
861
- publishConfig,
862
- homepage,
863
- repository,
864
- keywords,
865
- scripts,
866
- peerDependencies,
867
- devDependencies,
868
- dependencies,
869
- packageManager,
870
- engines
871
- };
872
-
873
785
  //#endregion
874
786
  //#region src/Core/Kernel.ts
875
787
  var Kernel = class Kernel {
@@ -897,14 +809,15 @@ var Kernel = class Kernel {
897
809
  async loadRequirements() {
898
810
  this.cwd = path.join(process.cwd(), this.basePath);
899
811
  if (!this.config.hideMusketInfo) try {
900
- package_default.name = this.config.cliName ?? package_default.name;
901
- this.modules.push(package_default);
812
+ const pkg = (await import(path.join(process.cwd(), "package.json"))).default;
813
+ pkg.name = this.config.cliName ?? pkg.name;
814
+ this.modules.push(pkg);
902
815
  } catch {}
903
816
  for (let i = 0; i < this.packages.length; i++) try {
904
817
  const item = this.packages[i];
905
- const name$1 = typeof item === "string" ? item : item.name;
818
+ const name = typeof item === "string" ? item : item.name;
906
819
  const alias = typeof item === "string" ? item : item.alias;
907
- const modulePath = FileSystem.findModulePkg(name$1, this.cwd) ?? "";
820
+ const modulePath = FileSystem.findModulePkg(name, this.cwd) ?? "";
908
821
  const pkg = (await import(path.join(modulePath, "package.json"))).default;
909
822
  pkg.alias = alias;
910
823
  this.modules.push(pkg);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@h3ravel/musket",
3
- "version": "0.1.9",
3
+ "version": "0.2.0",
4
4
  "description": "Musket CLI is a framework-agnostic CLI framework designed to allow you build artisan-like CLI apps and for use in the H3ravel framework.",
5
5
  "type": "module",
6
6
  "exports": {