@nanoforge-dev/cli 1.0.0 → 1.1.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.
package/dist/nf.js CHANGED
@@ -40,7 +40,7 @@ var require_package = __commonJS({
40
40
  module2.exports = {
41
41
  $schema: "https://json.schemastore.org/package.json",
42
42
  name: "@nanoforge-dev/cli",
43
- version: "1.0.0",
43
+ version: "1.1.1",
44
44
  description: "NanoForge CLI",
45
45
  keywords: [
46
46
  "nanoforge",
@@ -79,58 +79,60 @@ var require_package = __commonJS({
79
79
  prepack: "pnpm run build && pnpm run lint",
80
80
  changelog: "git cliff --prepend ./CHANGELOG.md -u -c ./cliff.toml -r . --include-path '.'",
81
81
  release: "cliff-jumper",
82
+ test: "pnpm run test:unit && pnpm run test:e2e",
83
+ "test:unit": "vitest run -c vitest.config.ts",
84
+ "test:unit:watch": "vitest -c vitest.config.ts",
85
+ "test:e2e": "vitest run -c vitest.config.e2e.ts",
86
+ "test:e2e:watch": "vitest -c vitest.config.e2e.ts",
87
+ "test:coverage": "pnpm run test:unit --coverage && pnpm run test:e2e",
82
88
  prepare: "husky"
83
89
  },
84
90
  dependencies: {
85
- "@angular-devkit/schematics": "^21.0.1",
86
- "@angular-devkit/schematics-cli": "^21.0.1",
87
- "@inquirer/prompts": "^7.9.0",
88
- "@nanoforge-dev/loader-client": "^1.0.1",
89
- "@nanoforge-dev/loader-server": "^1.0.1",
90
- "@nanoforge-dev/schematics": "^1.0.2",
91
- ansis: "^4.2.0",
92
- chokidar: "^4.0.3",
93
- "class-transformer": "^0.5.1",
94
- "class-validator": "^0.14.2",
95
- "cli-table3": "^0.6.5",
96
- commander: "^14.0.2",
97
- "node-emoji": "^2.2.0",
98
- ora: "^9.0.0",
99
- "reflect-metadata": "^0.2.2"
91
+ "@angular-devkit/schematics": "catalog:schematics",
92
+ "@angular-devkit/schematics-cli": "catalog:schematics",
93
+ "@inquirer/prompts": "catalog:cli",
94
+ "@nanoforge-dev/loader-client": "catalog:loader",
95
+ "@nanoforge-dev/loader-server": "catalog:loader",
96
+ "@nanoforge-dev/schematics": "catalog:schematics",
97
+ ansis: "catalog:cli",
98
+ bun: "catalog:core",
99
+ chokidar: "catalog:libs",
100
+ "class-transformer": "catalog:libs",
101
+ "class-validator": "catalog:libs",
102
+ commander: "catalog:cli",
103
+ "node-emoji": "catalog:cli",
104
+ ora: "catalog:cli",
105
+ "reflect-metadata": "catalog:libs"
100
106
  },
101
107
  devDependencies: {
102
- "@commitlint/cli": "^20.1.0",
103
- "@commitlint/config-conventional": "^20.0.0",
104
- "@eslint/js": "^9.39.0",
105
- "@favware/cliff-jumper": "^6.0.0",
106
- "@trivago/prettier-plugin-sort-imports": "^5.2.2",
107
- "@types/inquirer": "^9.0.9",
108
- "@types/node": "^24.10.1",
109
- "@typescript-eslint/eslint-plugin": "^8.46.2",
110
- "@typescript-eslint/parser": "^8.46.2",
111
- eslint: "^9.39.0",
112
- "eslint-config-prettier": "^10.1.8",
113
- "eslint-formatter-pretty": "^7.0.0",
114
- "eslint-plugin-prettier": "^5.5.4",
115
- globals: "^16.5.0",
116
- husky: "^9.1.7",
117
- "lint-staged": "^16.2.6",
118
- prettier: "^3.6.2",
119
- taze: "^19.9.0",
120
- tsup: "^8.5.1",
121
- typescript: "^5.9.3",
122
- "typescript-eslint": "^8.46.2"
108
+ "@commitlint/cli": "catalog:ci",
109
+ "@commitlint/config-conventional": "catalog:ci",
110
+ "@favware/cliff-jumper": "catalog:ci",
111
+ "@nanoforge-dev/actions": "catalog:ci",
112
+ "@nanoforge-dev/utils-eslint-config": "catalog:lint",
113
+ "@nanoforge-dev/utils-prettier-config": "catalog:lint",
114
+ "@trivago/prettier-plugin-sort-imports": "catalog:lint",
115
+ "@types/inquirer": "catalog:cli",
116
+ "@types/node": "catalog:core",
117
+ "@vitest/coverage-v8": "catalog:tests",
118
+ eslint: "catalog:lint",
119
+ husky: "catalog:ci",
120
+ "lint-staged": "catalog:ci",
121
+ prettier: "catalog:lint",
122
+ tsup: "catalog:build",
123
+ typescript: "catalog:build",
124
+ vitest: "catalog:tests"
123
125
  },
124
- packageManager: "pnpm@10.24.0",
126
+ packageManager: "pnpm@10.28.1",
125
127
  engines: {
126
- node: "24.11.1"
128
+ node: "25"
127
129
  },
128
130
  publishConfig: {
129
131
  access: "public"
130
132
  },
131
133
  "lint-staged": {
132
- "**/*.ts": [
133
- "prettier --write"
134
+ "**": [
135
+ "prettier --ignore-unknown --write"
134
136
  ],
135
137
  "src/**/*.ts": [
136
138
  "eslint --fix"
@@ -157,7 +159,7 @@ var loadLocalBinCommandLoader = /* @__PURE__ */ __name(async () => {
157
159
  }, "loadLocalBinCommandLoader");
158
160
 
159
161
  // src/command/command.loader.ts
160
- import { red as red6 } from "ansis";
162
+ import { red as red8 } from "ansis";
161
163
 
162
164
  // src/lib/ui/messages.ts
163
165
  import { green } from "ansis";
@@ -187,7 +189,9 @@ var Emojis = {
187
189
  // src/lib/ui/messages.ts
188
190
  var Messages = {
189
191
  BUILD_START: "NanoForge Build",
190
- BUILD_PART_IN_PROGRESS: /* @__PURE__ */ __name((part) => `Building ${part}...`, "BUILD_PART_IN_PROGRESS"),
192
+ BUILD_WATCH_START: "Start watching mode",
193
+ BUILD_PART_IN_PROGRESS: /* @__PURE__ */ __name((part) => `Building ${part}`, "BUILD_PART_IN_PROGRESS"),
194
+ BUILD_PART_WATCH_IN_PROGRESS: /* @__PURE__ */ __name((part) => `${part} updated. Rebuilding`, "BUILD_PART_WATCH_IN_PROGRESS"),
191
195
  BUILD_NOTHING: "Nothing to build, terminated.",
192
196
  BUILD_SUCCESS: `${Emojis.ROCKET} Build succeeded !`,
193
197
  BUILD_PART_FAILED: /* @__PURE__ */ __name((part, commandToRunManually) => `${Emojis.SCREAM} Build of ${part} failed !
@@ -204,8 +208,16 @@ In case you don't see any errors above, consider manually running the failed com
204
208
  NEW_STRICT_QUESTION: "Do you want to use types strict mode ?",
205
209
  NEW_SERVER_QUESTION: "Do you want generate a server to create a multiplayer game ?",
206
210
  NEW_SKIP_INSTALL_QUESTION: "Do you want to skip installation ?",
211
+ GENERATE_START: "NanoForge Generate",
212
+ GENERATE_WATCH_START: "Start watching mode",
213
+ GENERATE_SUCCESS: `${Emojis.ROCKET} Generate succeeded !`,
214
+ GENERATE_FAILED: `${Emojis.SCREAM} Generate failed !`,
215
+ DEV_START: "NanoForge Dev mode",
216
+ DEV_SUCCESS: "Dev mode ended",
217
+ DEV_FAILED: `${Emojis.SCREAM} Dev failed !`,
207
218
  SCHEMATICS_START: "Schematics execution",
208
219
  SCHEMATIC_IN_PROGRESS: /* @__PURE__ */ __name((name) => `Executing schematic ${name}...`, "SCHEMATIC_IN_PROGRESS"),
220
+ SCHEMATIC_WATCH_IN_PROGRESS: /* @__PURE__ */ __name((name) => `Update watched. Executing schematic ${name}...`, "SCHEMATIC_WATCH_IN_PROGRESS"),
209
221
  SCHEMATIC_SUCCESS: /* @__PURE__ */ __name((name) => `${Emojis.ROCKET} Schematic ${name} executed successfully !`, "SCHEMATIC_SUCCESS"),
210
222
  SCHEMATIC_FAILED: /* @__PURE__ */ __name((name) => `${Emojis.SCREAM} Schematic ${name} execution failed. See error below for more details.`, "SCHEMATIC_FAILED"),
211
223
  PACKAGE_MANAGER_INSTALLATION_IN_PROGRESS: `Installation in progress... ${Emojis.COFFEE}`,
@@ -230,7 +242,9 @@ var Prefixes = {
230
242
 
231
243
  // src/action/actions/build.action.ts
232
244
  import * as ansis from "ansis";
233
- import * as process3 from "process";
245
+ import { watch } from "chokidar";
246
+ import * as console2 from "console";
247
+ import { dirname, join as join4 } from "path";
234
248
 
235
249
  // src/lib/input/base-inputs.ts
236
250
  var getStringInput = /* @__PURE__ */ __name((input2, field) => {
@@ -279,6 +293,16 @@ var getConfigInput = /* @__PURE__ */ __name((inputs) => {
279
293
  return getStringInputWithDefault(inputs, "config", ".");
280
294
  }, "getConfigInput");
281
295
 
296
+ // src/lib/input/inputs/watch.input.ts
297
+ var getWatchInput = /* @__PURE__ */ __name((inputs) => {
298
+ return getBooleanInputWithDefault(inputs, "watch", false);
299
+ }, "getWatchInput");
300
+
301
+ // src/lib/input/inputs/dev/generate.input.ts
302
+ var getDevGenerateInput = /* @__PURE__ */ __name((inputs) => {
303
+ return getBooleanInputWithDefault(inputs, "generate", false);
304
+ }, "getDevGenerateInput");
305
+
282
306
  // src/lib/question/questions/confirm.question.ts
283
307
  import { confirm } from "@inquirer/prompts";
284
308
 
@@ -360,6 +384,10 @@ var getInstallNamesInputOrAsk = /* @__PURE__ */ __name((inputs) => {
360
384
  );
361
385
  }, "getInstallNamesInputOrAsk");
362
386
 
387
+ // src/lib/package-manager/package-manager.factory.ts
388
+ import fs2 from "fs";
389
+ import { resolve as resolve2 } from "path";
390
+
363
391
  // src/lib/runner/runner.factory.ts
364
392
  import { yellow } from "ansis";
365
393
 
@@ -382,7 +410,7 @@ var AbstractRunner = class {
382
410
  shell: true,
383
411
  env: { ...process2.env, ...env2 }
384
412
  };
385
- return new Promise((resolve, reject) => {
413
+ return new Promise((resolve3, reject) => {
386
414
  const child = spawn(
387
415
  `${this.binary} ${[...this.args, ...args].join(" ")}`,
388
416
  options
@@ -398,7 +426,7 @@ var AbstractRunner = class {
398
426
  );
399
427
  child.on("close", (code) => {
400
428
  if (code === 0) {
401
- resolve(collect && res.length ? res.join("\n") : null);
429
+ resolve3(collect && res.length ? res.join("\n") : null);
402
430
  } else {
403
431
  if (failSpinner) failSpinner();
404
432
  console.error(
@@ -431,15 +459,59 @@ var BunRunner = class extends AbstractRunner {
431
459
  };
432
460
 
433
461
  // src/lib/utils/path.ts
434
- import { join as join2 } from "path";
462
+ import fs from "fs";
463
+ import { join as join2, resolve } from "path";
435
464
  var getCwd = /* @__PURE__ */ __name((directory) => {
436
- return directory.startsWith("/") ? directory : join2(process.cwd(), directory);
465
+ return resolve(directory);
437
466
  }, "getCwd");
438
467
  var getModulePath = /* @__PURE__ */ __name((name, removeLast = false) => {
439
468
  const path = import.meta.resolve(name).replace(/^file:\/\//, "");
440
469
  if (removeLast) return path.split("/").slice(0, -1).join("/");
441
470
  return path;
442
471
  }, "getModulePath");
472
+ var resolveCLINodeBinaryPath = /* @__PURE__ */ __name((name) => {
473
+ let base = join2(getModulePath(".", true), "..");
474
+ while (base.length >= 1) {
475
+ const path = join2(base, "node_modules", ".bin", name);
476
+ try {
477
+ fs.accessSync(path);
478
+ return path;
479
+ } catch {
480
+ base = join2(base, "..");
481
+ }
482
+ }
483
+ throw new Error("Could not find module path");
484
+ }, "resolveCLINodeBinaryPath");
485
+
486
+ // src/lib/runner/runners/local-bun.runner.ts
487
+ var LocalBunRunner = class extends AbstractRunner {
488
+ static {
489
+ __name(this, "LocalBunRunner");
490
+ }
491
+ constructor() {
492
+ super(resolveCLINodeBinaryPath("bun"));
493
+ }
494
+ };
495
+
496
+ // src/lib/runner/runners/npm.runner.ts
497
+ var NpmRunner = class extends AbstractRunner {
498
+ static {
499
+ __name(this, "NpmRunner");
500
+ }
501
+ constructor() {
502
+ super("npm");
503
+ }
504
+ };
505
+
506
+ // src/lib/runner/runners/pnpm.runner.ts
507
+ var PnpmRunner = class extends AbstractRunner {
508
+ static {
509
+ __name(this, "PnpmRunner");
510
+ }
511
+ constructor() {
512
+ super("pnpm");
513
+ }
514
+ };
443
515
 
444
516
  // src/lib/runner/runners/schematic.runner.ts
445
517
  var SchematicRunner = class _SchematicRunner extends AbstractRunner {
@@ -462,6 +534,16 @@ var SchematicRunner = class _SchematicRunner extends AbstractRunner {
462
534
  }
463
535
  };
464
536
 
537
+ // src/lib/runner/runners/yarn.runner.ts
538
+ var YarnRunner = class extends AbstractRunner {
539
+ static {
540
+ __name(this, "YarnRunner");
541
+ }
542
+ constructor() {
543
+ super("yarn");
544
+ }
545
+ };
546
+
465
547
  // src/lib/runner/runner.factory.ts
466
548
  var RunnerFactory = class {
467
549
  static {
@@ -471,8 +553,16 @@ var RunnerFactory = class {
471
553
  switch (runner) {
472
554
  case 0 /* BUN */:
473
555
  return new BunRunner();
474
- case 1 /* SCHEMATIC */:
556
+ case 1 /* LOCAL_BUN */:
557
+ return new LocalBunRunner();
558
+ case 2 /* NPM */:
559
+ return new NpmRunner();
560
+ case 3 /* PNPM */:
561
+ return new PnpmRunner();
562
+ case 4 /* SCHEMATIC */:
475
563
  return new SchematicRunner();
564
+ case 5 /* YARN */:
565
+ return new YarnRunner();
476
566
  default:
477
567
  console.info(yellow`[WARN] Unsupported runner: ${runner}`);
478
568
  throw Error(`Unsupported runner: ${runner}`);
@@ -529,9 +619,11 @@ var AbstractPackageManager = class {
529
619
  const command = [this.cli.add, this.cli.saveDevFlag];
530
620
  return this.add(command, directory, dependencies);
531
621
  }
532
- async build(name, directory, entry, output, flags) {
622
+ async build(name, directory, entry, output, flags, watch3) {
533
623
  if (!this.cli.build) throw new Error(`Package manager ${this.name} does not support building`);
534
- const spinner = SPINNER(Messages.BUILD_PART_IN_PROGRESS(name));
624
+ const spinner = SPINNER(
625
+ (watch3 ? Messages.BUILD_PART_WATCH_IN_PROGRESS : Messages.BUILD_PART_IN_PROGRESS)(name)
626
+ );
535
627
  spinner.start();
536
628
  try {
537
629
  const commandArgs = [
@@ -561,7 +653,6 @@ var AbstractPackageManager = class {
561
653
  }
562
654
  }
563
655
  async run(name, directory, file, env2 = {}, flags = [], silent = false) {
564
- if (!this.cli.run) throw new Error(`Package manager ${this.name} does not support running`);
565
656
  try {
566
657
  console.info(Messages.RUN_PART_IN_PROGRESS(name));
567
658
  const commandArgs = [...flags, this.cli.run];
@@ -578,6 +669,15 @@ var AbstractPackageManager = class {
578
669
  return false;
579
670
  }
580
671
  }
672
+ async runDev(directory, command, env2 = {}, flags = [], collect = true) {
673
+ try {
674
+ const commandArgs = [this.cli.exec, command, ...flags];
675
+ await this.runner.run(commandArgs, collect, getCwd(directory), env2);
676
+ return true;
677
+ } catch {
678
+ return false;
679
+ }
680
+ }
581
681
  async add(args, directory, dependencies) {
582
682
  if (!dependencies.length) {
583
683
  console.info();
@@ -649,8 +749,36 @@ var BunPackageManager = class extends AbstractPackageManager {
649
749
  add: "add",
650
750
  update: "update",
651
751
  remove: "remove",
652
- build: "build",
752
+ exec: "exec",
753
+ run: "run",
754
+ saveFlag: "--save",
755
+ saveDevFlag: "--dev",
756
+ silentFlag: "--silent"
757
+ };
758
+ }
759
+ };
760
+
761
+ // src/lib/package-manager/package-managers/local-bun.package-manager.ts
762
+ var LocalBunPackageManager = class extends AbstractPackageManager {
763
+ static {
764
+ __name(this, "LocalBunPackageManager");
765
+ }
766
+ constructor() {
767
+ super(RunnerFactory.create(1 /* LOCAL_BUN */));
768
+ }
769
+ get name() {
770
+ return "local_bun" /* LOCAL_BUN */.toUpperCase();
771
+ }
772
+ get cli() {
773
+ return {
774
+ install: "install",
775
+ add: "add",
776
+ update: "update",
777
+ remove: "remove",
778
+ exec: "exec",
653
779
  run: "run",
780
+ build: "build",
781
+ runFile: "run",
654
782
  saveFlag: "--save",
655
783
  saveDevFlag: "--dev",
656
784
  silentFlag: "--silent"
@@ -658,6 +786,84 @@ var BunPackageManager = class extends AbstractPackageManager {
658
786
  }
659
787
  };
660
788
 
789
+ // src/lib/package-manager/package-managers/npm.package-manager.ts
790
+ var NpmPackageManager = class extends AbstractPackageManager {
791
+ static {
792
+ __name(this, "NpmPackageManager");
793
+ }
794
+ constructor() {
795
+ super(RunnerFactory.create(2 /* NPM */));
796
+ }
797
+ get name() {
798
+ return "npm" /* NPM */.toUpperCase();
799
+ }
800
+ get cli() {
801
+ return {
802
+ install: "install",
803
+ add: "install",
804
+ update: "update",
805
+ remove: "uninstall",
806
+ exec: "exec",
807
+ run: "run",
808
+ saveFlag: "--save",
809
+ saveDevFlag: "--save-dev",
810
+ silentFlag: "--silent"
811
+ };
812
+ }
813
+ };
814
+
815
+ // src/lib/package-manager/package-managers/pnpm.package-manager.ts
816
+ var PnpmPackageManager = class extends AbstractPackageManager {
817
+ static {
818
+ __name(this, "PnpmPackageManager");
819
+ }
820
+ constructor() {
821
+ super(RunnerFactory.create(3 /* PNPM */));
822
+ }
823
+ get name() {
824
+ return "pnpm" /* PNPM */.toUpperCase();
825
+ }
826
+ get cli() {
827
+ return {
828
+ install: "install",
829
+ add: "add",
830
+ update: "update",
831
+ remove: "remove",
832
+ exec: "exec",
833
+ run: "run",
834
+ saveFlag: "-P",
835
+ saveDevFlag: "-D",
836
+ silentFlag: "--silent"
837
+ };
838
+ }
839
+ };
840
+
841
+ // src/lib/package-manager/package-managers/yarn.package-manager.ts
842
+ var YarnPackageManager = class extends AbstractPackageManager {
843
+ static {
844
+ __name(this, "YarnPackageManager");
845
+ }
846
+ constructor() {
847
+ super(RunnerFactory.create(5 /* YARN */));
848
+ }
849
+ get name() {
850
+ return "yarn" /* YARN */.toUpperCase();
851
+ }
852
+ get cli() {
853
+ return {
854
+ install: "install",
855
+ add: "add",
856
+ update: "update",
857
+ remove: "remove",
858
+ exec: "exec",
859
+ run: "run",
860
+ saveFlag: "",
861
+ saveDevFlag: "-D",
862
+ silentFlag: "--silent"
863
+ };
864
+ }
865
+ };
866
+
661
867
  // src/lib/package-manager/package-manager.factory.ts
662
868
  var PackageManagerFactory = class {
663
869
  static {
@@ -667,10 +873,39 @@ var PackageManagerFactory = class {
667
873
  switch (name) {
668
874
  case "bun" /* BUN */:
669
875
  return new BunPackageManager();
876
+ case "local_bun" /* LOCAL_BUN */:
877
+ return new LocalBunPackageManager();
878
+ case "npm" /* NPM */:
879
+ return new NpmPackageManager();
880
+ case "pnpm" /* PNPM */:
881
+ return new PnpmPackageManager();
882
+ case "yarn" /* YARN */:
883
+ return new YarnPackageManager();
670
884
  default:
671
885
  throw new Error(`Package manager ${name} is not managed.`);
672
886
  }
673
887
  }
888
+ static async find(directory = ".") {
889
+ const DEFAULT_PACKAGE_MANAGER = "npm" /* NPM */;
890
+ try {
891
+ const files = await fs2.promises.readdir(resolve2(directory));
892
+ if (files.includes("bun.lock")) {
893
+ return this.create("bun" /* BUN */);
894
+ }
895
+ if (files.includes("package-lock.json")) {
896
+ return this.create("npm" /* NPM */);
897
+ }
898
+ if (files.includes("pnpm-lock.yaml")) {
899
+ return this.create("pnpm" /* PNPM */);
900
+ }
901
+ if (files.includes("yarn.lock")) {
902
+ return this.create("yarn" /* YARN */);
903
+ }
904
+ return this.create(DEFAULT_PACKAGE_MANAGER);
905
+ } catch {
906
+ return this.create(DEFAULT_PACKAGE_MANAGER);
907
+ }
908
+ }
674
909
  };
675
910
 
676
911
  // src/lib/config/config.type.ts
@@ -900,32 +1135,41 @@ var BuildAction = class extends AbstractAction {
900
1135
  __name(this, "BuildAction");
901
1136
  }
902
1137
  async handle(_args, options) {
903
- console.info(Messages.BUILD_START);
904
- console.info();
1138
+ console2.info(Messages.BUILD_START);
1139
+ console2.info();
905
1140
  try {
906
1141
  const directory = getDirectoryInput(options);
907
1142
  const config2 = await getConfig(options, directory);
1143
+ const watch3 = getWatchInput(options);
908
1144
  const client = getPart(
909
1145
  config2.client.build,
910
1146
  options.get("clientDirectory")?.value,
911
1147
  "client"
912
1148
  );
913
- let res = await buildPart("Client", client, directory);
1149
+ let res = await buildPart("Client", client, directory, { watch: watch3 });
914
1150
  if (config2.server.enable) {
915
1151
  const server = getPart(
916
1152
  config2.server.build,
917
1153
  options.get("serverDirectory")?.value,
918
1154
  "server"
919
1155
  );
920
- res = await buildPart("Server", server, directory) ? res : false;
1156
+ res = await buildPart("Server", server, directory, { watch: watch3 }) ? res : false;
921
1157
  }
922
- console.info();
923
- if (!res) console.info(Messages.BUILD_FAILED);
924
- else console.info(Messages.BUILD_SUCCESS);
925
- process3.exit(0);
1158
+ console2.info();
1159
+ if (watch3) {
1160
+ console2.info(Messages.BUILD_WATCH_START);
1161
+ console2.info();
1162
+ return;
1163
+ }
1164
+ if (!res) {
1165
+ console2.info(Messages.BUILD_FAILED);
1166
+ process.exit(1);
1167
+ }
1168
+ console2.info(Messages.BUILD_SUCCESS);
1169
+ process.exit(0);
926
1170
  } catch (e) {
927
- console.error(e);
928
- process3.exit(1);
1171
+ console2.error(e);
1172
+ process.exit(1);
929
1173
  }
930
1174
  }
931
1175
  };
@@ -936,26 +1180,76 @@ var getPart = /* @__PURE__ */ __name((config2, directoryOption, target) => {
936
1180
  target
937
1181
  };
938
1182
  }, "getPart");
939
- var buildPart = /* @__PURE__ */ __name(async (name, part, directory) => {
940
- const packageManagerName = "bun" /* BUN */;
1183
+ var buildPart = /* @__PURE__ */ __name(async (name, part, directory, options) => {
1184
+ const packageManagerName = "local_bun" /* LOCAL_BUN */;
1185
+ const packageManager = PackageManagerFactory.create(packageManagerName);
1186
+ const build = /* @__PURE__ */ __name(async (watch3 = false) => {
1187
+ try {
1188
+ return await packageManager.build(
1189
+ name,
1190
+ directory,
1191
+ part.entry,
1192
+ part.output,
1193
+ [
1194
+ "--asset-naming",
1195
+ "[name].[ext]",
1196
+ "--target",
1197
+ part.target === "client" ? "browser" : "node"
1198
+ ],
1199
+ watch3
1200
+ );
1201
+ } catch (error4) {
1202
+ if (error4 && error4.message) {
1203
+ console2.error(ansis.red(error4.message));
1204
+ }
1205
+ return false;
1206
+ }
1207
+ }, "build");
1208
+ if (options?.watch)
1209
+ watch(dirname(join4(getCwd(directory), part.entry))).on("change", () => build(true));
1210
+ return await build();
1211
+ }, "buildPart");
1212
+
1213
+ // src/action/actions/dev.action.ts
1214
+ import * as ansis2 from "ansis";
1215
+ var DevAction = class extends AbstractAction {
1216
+ static {
1217
+ __name(this, "DevAction");
1218
+ }
1219
+ async handle(_args, options) {
1220
+ console.info(Messages.DEV_START);
1221
+ console.info();
1222
+ try {
1223
+ const directory = getDirectoryInput(options);
1224
+ const generate = getDevGenerateInput(options);
1225
+ await Promise.all([
1226
+ generate ? runAction("generate", [], directory, false) : void 0,
1227
+ runAction("build", [], directory, false),
1228
+ runAction("start", [], directory, true)
1229
+ ]);
1230
+ console.info(Messages.DEV_SUCCESS);
1231
+ process.exit(0);
1232
+ } catch (e) {
1233
+ console.error(Messages.DEV_FAILED);
1234
+ console.error(e);
1235
+ process.exit(1);
1236
+ }
1237
+ }
1238
+ };
1239
+ var runAction = /* @__PURE__ */ __name(async (command, params, directory, stdout = false) => {
941
1240
  try {
942
- const packageManager = PackageManagerFactory.create(packageManagerName);
943
- return await packageManager.build(name, directory, part.entry, part.output, [
944
- "--asset-naming",
945
- "[name].[ext]",
946
- "--target",
947
- part.target === "client" ? "browser" : "node"
948
- ]);
949
- } catch (error3) {
950
- if (error3 && error3.message) {
951
- console.error(ansis.red(error3.message));
1241
+ const packageManager = await PackageManagerFactory.find(directory);
1242
+ await packageManager.runDev(directory, "nf", {}, [command, ...params, "--watch"], !stdout);
1243
+ } catch (error4) {
1244
+ if (error4 && error4.message) {
1245
+ console.error(ansis2.red(error4.message));
952
1246
  }
953
- return false;
954
1247
  }
955
- }, "buildPart");
1248
+ }, "runAction");
956
1249
 
957
1250
  // src/action/actions/generate.action.ts
958
- import * as console2 from "console";
1251
+ import * as console3 from "console";
1252
+ import { join as join5 } from "path";
959
1253
 
960
1254
  // src/lib/schematics/abstract.collection.ts
961
1255
  var AbstractCollection = class {
@@ -1045,7 +1339,7 @@ var CollectionFactory = class {
1045
1339
  __name(this, "CollectionFactory");
1046
1340
  }
1047
1341
  static create(collection, directory) {
1048
- const schematicRunner = RunnerFactory.create(1 /* SCHEMATIC */);
1342
+ const schematicRunner = RunnerFactory.create(4 /* SCHEMATIC */);
1049
1343
  if (collection === "@nanoforge-dev/schematics" /* NANOFORGE */) {
1050
1344
  return new NanoforgeCollection(schematicRunner, directory);
1051
1345
  } else {
@@ -1083,7 +1377,7 @@ var SchematicOption = class {
1083
1377
  }
1084
1378
  } else if (typeof this.value === "boolean") {
1085
1379
  const str = normalizedName;
1086
- return this.value ? [`--${str}`] : [`--no-${str}`];
1380
+ return this.value ? [`--${str}=true`] : [`--${str}=false`];
1087
1381
  } else if (Array.isArray(this.value)) {
1088
1382
  return this.value.reduce(
1089
1383
  (old, option) => [
@@ -1106,6 +1400,9 @@ var SchematicOption = class {
1106
1400
  }
1107
1401
  };
1108
1402
 
1403
+ // src/action/common/schematics.ts
1404
+ import { watch as watch2 } from "chokidar";
1405
+
1109
1406
  // src/action/common/spinner.ts
1110
1407
  import ora2 from "ora";
1111
1408
  var getSpinner = /* @__PURE__ */ __name((message) => ora2({
@@ -1113,16 +1410,22 @@ var getSpinner = /* @__PURE__ */ __name((message) => ora2({
1113
1410
  }), "getSpinner");
1114
1411
 
1115
1412
  // src/action/common/schematics.ts
1116
- var executeSchematic = /* @__PURE__ */ __name(async (name, collection, schematicName, options) => {
1117
- const spinner = getSpinner(Messages.SCHEMATIC_IN_PROGRESS(name));
1118
- spinner.start();
1119
- await collection.execute(
1120
- schematicName,
1121
- mapSchematicOptions(options),
1122
- void 0,
1123
- () => spinner.fail(Messages.SCHEMATIC_FAILED(name))
1124
- );
1125
- spinner.succeed(Messages.SCHEMATIC_SUCCESS(name));
1413
+ var executeSchematic = /* @__PURE__ */ __name(async (name, collection, schematicName, options, fileToWatch) => {
1414
+ const execute = /* @__PURE__ */ __name(async (watch3 = false) => {
1415
+ const spinner = getSpinner(
1416
+ (watch3 ? Messages.SCHEMATIC_WATCH_IN_PROGRESS : Messages.SCHEMATIC_IN_PROGRESS)(name)
1417
+ );
1418
+ spinner.start();
1419
+ await collection.execute(
1420
+ schematicName,
1421
+ mapSchematicOptions(options),
1422
+ void 0,
1423
+ () => spinner.fail(Messages.SCHEMATIC_FAILED(name))
1424
+ );
1425
+ spinner.succeed(Messages.SCHEMATIC_SUCCESS(name));
1426
+ }, "execute");
1427
+ if (fileToWatch) watch2(fileToWatch).on("change", () => execute(true));
1428
+ return await execute();
1126
1429
  }, "executeSchematic");
1127
1430
  var mapSchematicOptions = /* @__PURE__ */ __name((inputs) => {
1128
1431
  return Object.entries(inputs).reduce((old, [key, value]) => {
@@ -1140,18 +1443,25 @@ var GenerateAction = class extends AbstractAction {
1140
1443
  __name(this, "GenerateAction");
1141
1444
  }
1142
1445
  async handle(_args, options) {
1143
- console2.info(Messages.NEW_START);
1446
+ console3.info(Messages.GENERATE_START);
1447
+ console3.info();
1144
1448
  try {
1145
1449
  const directory = getDirectoryInput(options);
1146
1450
  const config2 = await getConfig(options, directory);
1451
+ const watch3 = getWatchInput(options);
1147
1452
  const values = await getSchemaValues(config2);
1148
- await generateFiles(values, directory);
1149
- console2.info();
1150
- console2.info(Messages.NEW_SUCCESS);
1453
+ await generateFiles(values, directory, watch3);
1454
+ console3.info();
1455
+ if (watch3) {
1456
+ console3.info(Messages.GENERATE_WATCH_START);
1457
+ console3.info();
1458
+ return;
1459
+ }
1460
+ console3.info(Messages.GENERATE_SUCCESS);
1151
1461
  process.exit(0);
1152
1462
  } catch (e) {
1153
- console2.error(Messages.NEW_FAILED);
1154
- console2.error(e);
1463
+ console3.error(Messages.GENERATE_FAILED);
1464
+ console3.error(e);
1155
1465
  process.exit(1);
1156
1466
  }
1157
1467
  }
@@ -1165,33 +1475,43 @@ var getSchemaValues = /* @__PURE__ */ __name(async (config2) => {
1165
1475
  initFunctions: config2.initFunctions
1166
1476
  };
1167
1477
  }, "getSchemaValues");
1168
- var generateFiles = /* @__PURE__ */ __name(async (values, directory) => {
1169
- console2.info();
1478
+ var generateFiles = /* @__PURE__ */ __name(async (values, directory, watch3) => {
1170
1479
  const collection = CollectionFactory.create("@nanoforge-dev/schematics" /* NANOFORGE */, directory);
1171
- console2.info();
1172
- console2.info(Messages.SCHEMATICS_START);
1173
- console2.info();
1174
- await executeSchematic("Client main file", collection, "part-main", {
1175
- name: values.name,
1176
- part: "client",
1177
- directory: values.directory,
1178
- language: values.language,
1179
- initFunctions: values.initFunctions
1180
- });
1181
- if (values.server) {
1182
- await executeSchematic("Server main file", collection, "part-main", {
1480
+ console3.info(Messages.SCHEMATICS_START);
1481
+ console3.info();
1482
+ await executeSchematic(
1483
+ "Client main file",
1484
+ collection,
1485
+ "part-main",
1486
+ {
1183
1487
  name: values.name,
1184
- part: "server",
1488
+ part: "client",
1185
1489
  directory: values.directory,
1186
1490
  language: values.language,
1187
1491
  initFunctions: values.initFunctions
1188
- });
1492
+ },
1493
+ watch3 ? join5(getCwd(directory), values.directory, ".nanoforge", "client.save.json") : void 0
1494
+ );
1495
+ if (values.server) {
1496
+ await executeSchematic(
1497
+ "Server main file",
1498
+ collection,
1499
+ "part-main",
1500
+ {
1501
+ name: values.name,
1502
+ part: "server",
1503
+ directory: values.directory,
1504
+ language: values.language,
1505
+ initFunctions: values.initFunctions
1506
+ },
1507
+ join5(getCwd(directory), values.directory, ".nanoforge", "server.save.json")
1508
+ );
1189
1509
  }
1190
1510
  }, "generateFiles");
1191
1511
 
1192
1512
  // src/action/actions/install.action.ts
1193
- import * as ansis2 from "ansis";
1194
- import * as process4 from "process";
1513
+ import * as ansis3 from "ansis";
1514
+ import * as process3 from "process";
1195
1515
  var InstallAction = class extends AbstractAction {
1196
1516
  static {
1197
1517
  __name(this, "InstallAction");
@@ -1203,25 +1523,31 @@ var InstallAction = class extends AbstractAction {
1203
1523
  const names = await getInstallNamesInputOrAsk(args);
1204
1524
  const directory = getDirectoryInput(options);
1205
1525
  await installPackages(names, directory);
1206
- process4.exit(0);
1526
+ process3.exit(0);
1207
1527
  } catch (e) {
1208
1528
  console.error(e);
1209
- process4.exit(1);
1529
+ process3.exit(1);
1210
1530
  }
1211
1531
  }
1212
1532
  };
1213
1533
  var installPackages = /* @__PURE__ */ __name(async (names, directory) => {
1214
- const packageManagerName = "bun" /* BUN */;
1215
1534
  try {
1216
- const packageManager = PackageManagerFactory.create(packageManagerName);
1217
- await packageManager.addProduction(directory, names);
1218
- } catch (error3) {
1219
- if (error3 && error3.message) {
1220
- console.error(ansis2.red(error3.message));
1535
+ const packageManager = await PackageManagerFactory.find(directory);
1536
+ const res = await packageManager.addProduction(directory, names);
1537
+ if (!res) process3.exit(1);
1538
+ } catch (error4) {
1539
+ if (error4 && error4.message) {
1540
+ console.error(ansis3.red(error4.message));
1221
1541
  }
1542
+ process3.exit(1);
1222
1543
  }
1223
1544
  }, "installPackages");
1224
1545
 
1546
+ // src/action/actions/new.action.ts
1547
+ import * as ansis4 from "ansis";
1548
+ import console4 from "console";
1549
+ import * as process4 from "process";
1550
+
1225
1551
  // src/lib/input/inputs/new/init-functions.input.ts
1226
1552
  var getNewInitFunctionsWithDefault = /* @__PURE__ */ __name((inputs) => {
1227
1553
  return getBooleanInputWithDefault(inputs, "initFunctions", false);
@@ -1315,17 +1641,18 @@ var NewAction = class extends AbstractAction {
1315
1641
  __name(this, "NewAction");
1316
1642
  }
1317
1643
  async handle(_args, options) {
1318
- console.info(Messages.NEW_START);
1644
+ console4.info(Messages.NEW_START);
1319
1645
  try {
1320
1646
  const directory = getDirectoryInput(options);
1321
1647
  const values = await getSchemaValues2(options);
1322
1648
  await generateApplicationFiles(values, directory);
1323
- console.info();
1324
- console.info(Messages.NEW_SUCCESS);
1325
- process.exit(0);
1649
+ if (!values.skipInstall) await runInstall(directory, values.packageManager);
1650
+ console4.info();
1651
+ console4.info(Messages.NEW_SUCCESS);
1652
+ process4.exit(0);
1326
1653
  } catch {
1327
- console.error(Messages.NEW_FAILED);
1328
- process.exit(1);
1654
+ console4.error(Messages.NEW_FAILED);
1655
+ process4.exit(1);
1329
1656
  }
1330
1657
  }
1331
1658
  };
@@ -1342,11 +1669,11 @@ var getSchemaValues2 = /* @__PURE__ */ __name(async (inputs) => {
1342
1669
  };
1343
1670
  }, "getSchemaValues");
1344
1671
  var generateApplicationFiles = /* @__PURE__ */ __name(async (values, directory) => {
1345
- console.info();
1672
+ console4.info();
1346
1673
  const collection = CollectionFactory.create("@nanoforge-dev/schematics" /* NANOFORGE */, directory);
1347
- console.info();
1348
- console.info(Messages.SCHEMATICS_START);
1349
- console.info();
1674
+ console4.info();
1675
+ console4.info(Messages.SCHEMATICS_START);
1676
+ console4.info();
1350
1677
  await executeSchematic("Application", collection, "application", {
1351
1678
  name: values.name,
1352
1679
  directory: values.directory,
@@ -1391,56 +1718,91 @@ var generateApplicationFiles = /* @__PURE__ */ __name(async (values, directory)
1391
1718
  });
1392
1719
  }
1393
1720
  }, "generateApplicationFiles");
1721
+ var runInstall = /* @__PURE__ */ __name(async (directory, pkgManagerName) => {
1722
+ try {
1723
+ const packageManager = PackageManagerFactory.create(pkgManagerName);
1724
+ await packageManager.install(directory);
1725
+ } catch (error4) {
1726
+ if (error4 && error4.message) {
1727
+ console4.error(ansis4.red(error4.message));
1728
+ }
1729
+ process4.exit(1);
1730
+ }
1731
+ }, "runInstall");
1394
1732
 
1395
1733
  // src/action/actions/start.action.ts
1396
- import * as ansis3 from "ansis";
1397
- import * as console3 from "console";
1398
- import { join as join4 } from "path";
1734
+ import * as ansis5 from "ansis";
1735
+ import * as console5 from "console";
1736
+ import * as process5 from "process";
1737
+ import { join as join6 } from "path";
1399
1738
  var StartAction = class extends AbstractAction {
1400
1739
  static {
1401
1740
  __name(this, "StartAction");
1402
1741
  }
1403
1742
  async handle(_args, options) {
1404
- console3.info(Messages.RUN_START);
1405
- console3.info();
1743
+ console5.info(Messages.RUN_START);
1744
+ console5.info();
1406
1745
  try {
1407
1746
  const directory = getDirectoryInput(options);
1408
1747
  const config2 = await getConfig(options, directory);
1409
1748
  const clientDir = config2.client.runtime.dir;
1410
1749
  const serverDir = config2.server.runtime.dir;
1411
1750
  const clientPort = getStringInputWithDefault(options, "clientPort", config2.client.port);
1751
+ const cert = getStringInput(options, "cert");
1752
+ const key = getStringInput(options, "key");
1753
+ const watch3 = getWatchInput(options);
1412
1754
  await Promise.all([
1413
- config2.server.enable ? this.startServer(directory, serverDir) : void 0,
1414
- this.startClient(clientPort, directory, clientDir)
1755
+ config2.server.enable ? this.startServer(directory, serverDir, watch3) : void 0,
1756
+ this.startClient(
1757
+ clientPort,
1758
+ directory,
1759
+ clientDir,
1760
+ {
1761
+ watch: watch3,
1762
+ serverGameDir: config2.server.enable ? serverDir : void 0
1763
+ },
1764
+ cert,
1765
+ key
1766
+ )
1415
1767
  ]);
1416
- process.exit(0);
1768
+ process5.exit(0);
1417
1769
  } catch (e) {
1418
- console3.error(e);
1419
- process.exit(1);
1770
+ console5.error(e);
1771
+ process5.exit(1);
1420
1772
  }
1421
1773
  }
1422
- async startClient(port, directory, gameDir) {
1774
+ async startClient(port, directory, gameDir, options, cert, key) {
1423
1775
  const path = getModulePath("@nanoforge-dev/loader-client/package.json", true);
1424
- return runPart("Client", path, {
1776
+ const params = {
1425
1777
  PORT: port,
1426
- GAME_DIR: getCwd(join4(directory, gameDir))
1427
- });
1778
+ GAME_DIR: getCwd(join6(directory, gameDir)),
1779
+ CERT: cert ? join6(getCwd(directory), cert) : void 0,
1780
+ KEY: key ? join6(getCwd(directory), key) : void 0
1781
+ };
1782
+ if (options?.watch) {
1783
+ params["WATCH"] = "true";
1784
+ if (options?.serverGameDir) {
1785
+ params["WATCH_SERVER_GAME_DIR"] = getCwd(join6(directory, options.serverGameDir));
1786
+ }
1787
+ }
1788
+ return runPart("Client", path, params);
1428
1789
  }
1429
- startServer(directory, gameDir) {
1790
+ startServer(directory, gameDir, watch3) {
1430
1791
  const path = getModulePath("@nanoforge-dev/loader-server/package.json", true);
1431
- return runPart("Server", path, {
1432
- GAME_DIR: getCwd(join4(directory, gameDir))
1433
- });
1792
+ const params = {
1793
+ GAME_DIR: getCwd(join6(directory, gameDir))
1794
+ };
1795
+ if (watch3) params["WATCH"] = "true";
1796
+ return runPart("Server", path, params);
1434
1797
  }
1435
1798
  };
1436
1799
  var runPart = /* @__PURE__ */ __name(async (part, directory, env2, flags) => {
1437
- const packageManagerName = "bun" /* BUN */;
1438
1800
  try {
1439
- const packageManager = PackageManagerFactory.create(packageManagerName);
1801
+ const packageManager = await PackageManagerFactory.find(directory);
1440
1802
  await packageManager.run(part, directory, "start", env2, flags, true);
1441
- } catch (error3) {
1442
- if (error3 && error3.message) {
1443
- console3.error(ansis3.red(error3.message));
1803
+ } catch (error4) {
1804
+ if (error4 && error4.message) {
1805
+ console5.error(ansis5.red(error4.message));
1444
1806
  }
1445
1807
  }
1446
1808
  }, "runPart");
@@ -1461,12 +1823,30 @@ var BuildCommand = class extends AbstractCommand {
1461
1823
  __name(this, "BuildCommand");
1462
1824
  }
1463
1825
  load(program2) {
1464
- program2.command("build").description("build your game").option("-d, --directory [directory]", "specify the directory of your project").option("-c, --config [config]", "path to the config file", "nanoforge.config.json").option("--client-outDir [clientDirectory]", "specify the output directory of the client").option("--server-outDir [serverDirectory]", "specify the output directory of the server").action(async (rawOptions) => {
1826
+ program2.command("build").description("build your game").option("-d, --directory [directory]", "specify the directory of your project").option("-c, --config [config]", "path to the config file", "nanoforge.config.json").option("--client-outDir [clientDirectory]", "specify the output directory of the client").option("--server-outDir [serverDirectory]", "specify the output directory of the server").option("--watch", "build app in watching mode", false).action(async (rawOptions) => {
1465
1827
  const options = /* @__PURE__ */ new Map();
1466
1828
  options.set("directory", { value: rawOptions.directory });
1467
1829
  options.set("config", { value: rawOptions.config });
1468
1830
  options.set("clientDirectory", { value: rawOptions.clientOutDir });
1469
1831
  options.set("serverDirectory", { value: rawOptions.serverOutDir });
1832
+ options.set("watch", { value: rawOptions.watch });
1833
+ const args = /* @__PURE__ */ new Map();
1834
+ await this.action.handle(args, options);
1835
+ });
1836
+ }
1837
+ };
1838
+
1839
+ // src/command/commands/dev.command.ts
1840
+ var DevCommand = class extends AbstractCommand {
1841
+ static {
1842
+ __name(this, "DevCommand");
1843
+ }
1844
+ load(program2) {
1845
+ program2.command("dev").description("run your game in dev mode").option("-d, --directory [directory]", "specify the directory of your project").option("--generate", "generate app from config", false).action(async (rawOptions) => {
1846
+ const options = /* @__PURE__ */ new Map();
1847
+ options.set("directory", { value: rawOptions.directory });
1848
+ options.set("config", { value: rawOptions.config });
1849
+ options.set("generate", { value: rawOptions.generate });
1470
1850
  const args = /* @__PURE__ */ new Map();
1471
1851
  await this.action.handle(args, options);
1472
1852
  });
@@ -1479,10 +1859,11 @@ var GenerateCommand = class extends AbstractCommand {
1479
1859
  __name(this, "GenerateCommand");
1480
1860
  }
1481
1861
  load(program2) {
1482
- program2.command("generate").description("generate nanoforge files from config").option("-d, --directory [directory]", "specify the directory of your project").option("-c, --config [config]", "path to the config file", "nanoforge.config.json").action(async (rawOptions) => {
1862
+ program2.command("generate").description("generate nanoforge files from config").option("-d, --directory [directory]", "specify the directory of your project").option("-c, --config [config]", "path to the config file", "nanoforge.config.json").option("--watch", "generate app in watching mode", false).action(async (rawOptions) => {
1483
1863
  const options = /* @__PURE__ */ new Map();
1484
1864
  options.set("directory", { value: rawOptions.directory });
1485
1865
  options.set("config", { value: rawOptions.config });
1866
+ options.set("watch", { value: rawOptions.watch });
1486
1867
  const args = /* @__PURE__ */ new Map();
1487
1868
  await this.action.handle(args, options);
1488
1869
  });
@@ -1537,7 +1918,7 @@ var StartCommand = class extends AbstractCommand {
1537
1918
  program2.command("start").description("start your game").option("-d, --directory [directory]", "specify the directory of your project").option("-c, --config [config]", "path to the config file", "nanoforge.config.json").option(
1538
1919
  "-p, --client-port [clientPort]",
1539
1920
  "specify the port of the loader (the website to load the game)"
1540
- ).option("--game-exposure-port [gameExposurePort]", "specify the port of the game exposure").option("--server-port [serverPort]", "specify the port of the server").action(async (rawOptions) => {
1921
+ ).option("--game-exposure-port [gameExposurePort]", "specify the port of the game exposure").option("--server-port [serverPort]", "specify the port of the server").option("--watch", "run app in watching mode", false).option("--cert [cert]", "path to the SSL certificate for HTTPS").option("--key [key]", "path to the SSL key for HTTPS").action(async (rawOptions) => {
1541
1922
  const options = /* @__PURE__ */ new Map();
1542
1923
  options.set("directory", { value: rawOptions.directory });
1543
1924
  options.set("config", { value: rawOptions.config });
@@ -1546,6 +1927,9 @@ var StartCommand = class extends AbstractCommand {
1546
1927
  value: rawOptions.gameExposurePort
1547
1928
  });
1548
1929
  options.set("serverPort", { value: rawOptions.serverPort });
1930
+ options.set("watch", { value: rawOptions.watch });
1931
+ options.set("cert", { value: rawOptions.cert });
1932
+ options.set("key", { value: rawOptions.key });
1549
1933
  const args = /* @__PURE__ */ new Map();
1550
1934
  await this.action.handle(args, options);
1551
1935
  });
@@ -1559,6 +1943,7 @@ var CommandLoader = class {
1559
1943
  }
1560
1944
  static async load(program2) {
1561
1945
  new BuildCommand(new BuildAction()).load(program2);
1946
+ new DevCommand(new DevAction()).load(program2);
1562
1947
  new GenerateCommand(new GenerateAction()).load(program2);
1563
1948
  new InstallCommand(new InstallAction()).load(program2);
1564
1949
  new NewCommand(new NewAction()).load(program2);
@@ -1568,8 +1953,8 @@ var CommandLoader = class {
1568
1953
  static handleInvalidCommand(program2) {
1569
1954
  program2.on("command:*", () => {
1570
1955
  console.error(`
1571
- ${Prefixes.ERROR} Invalid command: ${red6`%s`}`, program2.args.join(" "));
1572
- console.log(`See ${red6`--help`} for a list of available commands.
1956
+ ${Prefixes.ERROR} Invalid command: ${red8`%s`}`, program2.args.join(" "));
1957
+ console.log(`See ${red8`--help`} for a list of available commands.
1573
1958
  `);
1574
1959
  process.exit(1);
1575
1960
  });