@mnci/cli 1.9.0 → 1.10.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/cli.js CHANGED
@@ -38,7 +38,7 @@ module.exports = __toCommonJS(cli_exports);
38
38
  var import_commander = require("commander");
39
39
 
40
40
  // src/commands/add.ts
41
- var import_node_path8 = require("path");
41
+ var import_node_path9 = require("path");
42
42
  var import_prompts4 = require("@inquirer/prompts");
43
43
 
44
44
  // src/nx.ts
@@ -164,11 +164,11 @@ function assertValidProjectName(name, label) {
164
164
  }
165
165
  }
166
166
 
167
- // src/commands/add/go.ts
168
- var import_node_fs2 = require("fs");
167
+ // src/commands/add/flutter.ts
169
168
  var import_node_path3 = require("path");
170
169
 
171
170
  // src/commands/add/shared.ts
171
+ var import_node_fs2 = require("fs");
172
172
  var import_node_path2 = require("path");
173
173
  function hasPlugin(workspaceRoot, packageName) {
174
174
  const manifest = readJson((0, import_node_path2.join)(workspaceRoot, "package.json"));
@@ -202,8 +202,126 @@ function addNxTargets(manifestPath, newTargets) {
202
202
  toJson({ ...manifest, nx: { ...nx, targets: { ...targets, ...newTargets } } })
203
203
  );
204
204
  }
205
+ function findCodeWorkspaceFile(workspaceRoot) {
206
+ try {
207
+ const entry = (0, import_node_fs2.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
208
+ return entry ? (0, import_node_path2.join)(workspaceRoot, entry) : void 0;
209
+ } catch {
210
+ return void 0;
211
+ }
212
+ }
213
+ function readCodeWorkspaceFile(path) {
214
+ const contents = (0, import_node_fs2.readFileSync)(path, "utf8").replaceAll(/,(\s*[}\]])/g, "$1");
215
+ return JSON.parse(contents);
216
+ }
217
+ function projectTask(name, kind) {
218
+ const script = `${name}:${kind}`;
219
+ const base = { label: `${name}: ${kind}`, type: "npm", script, problemMatcher: [] };
220
+ return kind === "start" ? { ...base, isBackground: true } : { ...base, group: kind };
221
+ }
222
+ function registerProjectCommands(workspaceRoot, name, commands) {
223
+ const scripts = {
224
+ [`${name}:qa`]: `nx run ${name}:lint && nx run ${name}:test`
225
+ };
226
+ if (commands.build) {
227
+ scripts[`${name}:build`] = `nx run ${name}:build`;
228
+ }
229
+ if (commands.start) {
230
+ scripts[`${name}:start`] = commands.start;
231
+ }
232
+ const manifestPath = (0, import_node_path2.join)(workspaceRoot, "package.json");
233
+ const manifest = readJson(manifestPath);
234
+ const existingScripts = manifest.scripts ?? {};
235
+ writeFileEnsured(
236
+ manifestPath,
237
+ toJson({ ...manifest, scripts: { ...existingScripts, ...scripts } })
238
+ );
239
+ const codeWorkspacePath = findCodeWorkspaceFile(workspaceRoot);
240
+ if (!codeWorkspacePath) {
241
+ return;
242
+ }
243
+ const workspaceFile = readCodeWorkspaceFile(codeWorkspacePath);
244
+ const label = (task) => task.label ?? "";
245
+ const existingTasks = (workspaceFile.tasks?.tasks ?? []).filter(
246
+ (task) => !label(task).startsWith(`${name}: `)
247
+ );
248
+ const newTasks = [
249
+ projectTask(name, "qa"),
250
+ ...commands.build ? [projectTask(name, "build")] : [],
251
+ ...commands.start ? [projectTask(name, "start")] : []
252
+ ];
253
+ writeFileEnsured(
254
+ codeWorkspacePath,
255
+ toJson({
256
+ ...workspaceFile,
257
+ tasks: {
258
+ version: workspaceFile.tasks?.version ?? "2.0.0",
259
+ tasks: [...existingTasks, ...newTasks]
260
+ }
261
+ })
262
+ );
263
+ }
264
+
265
+ // src/commands/add/flutter.ts
266
+ function addProjectJsonTargets(projectJsonPath, newTargets) {
267
+ const project = readJson(projectJsonPath);
268
+ const targets = project.targets ?? {};
269
+ writeFileEnsured(projectJsonPath, toJson({ ...project, targets: { ...targets, ...newTargets } }));
270
+ }
271
+ function flutterAppStartTarget(name) {
272
+ return {
273
+ executor: "nx:run-commands",
274
+ continuous: true,
275
+ options: { command: "flutter run -d chrome", cwd: `apps/${name}` }
276
+ };
277
+ }
278
+ function ensureFlutter(workspaceRoot) {
279
+ if (runShell("flutter", ["--version"], workspaceRoot) !== 0) {
280
+ throw new Error(
281
+ "Flutter not found. Install the Flutter SDK first (3.27+, for Dart 3.6+ pub workspaces): https://docs.flutter.dev/get-started/install"
282
+ );
283
+ }
284
+ }
285
+ function nxFlutterPluginSpec() {
286
+ return process.env.MNCI_NX_FLUTTER_SPEC ?? "@mnci/nx-flutter";
287
+ }
288
+ function ensureNxFlutterPlugin(workspaceRoot) {
289
+ if (hasPlugin(workspaceRoot, "@mnci/nx-flutter")) {
290
+ return;
291
+ }
292
+ const spec = nxFlutterPluginSpec();
293
+ logger.step(`Installing the Flutter toolchain plugin (${spec})`);
294
+ if (runShell("npm", ["install", "--save-dev", spec, "--no-audit", "--no-fund"], workspaceRoot) !== 0) {
295
+ throw new Error("npm install of @mnci/nx-flutter failed");
296
+ }
297
+ }
298
+ function prepareFlutter(workspaceRoot) {
299
+ ensureFlutter(workspaceRoot);
300
+ ensureNxFlutterPlugin(workspaceRoot);
301
+ }
302
+ function addFlutterApp(workspaceRoot, name) {
303
+ prepareFlutter(workspaceRoot);
304
+ ensureAdmZip(workspaceRoot);
305
+ runNx(["g", "@mnci/nx-flutter:application", name, "--no-interactive"], workspaceRoot);
306
+ addProjectJsonTargets((0, import_node_path3.join)(workspaceRoot, "apps", name, "project.json"), {
307
+ start: flutterAppStartTarget(name)
308
+ });
309
+ registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
310
+ }
311
+ function addFlutterLib(workspaceRoot, name) {
312
+ prepareFlutter(workspaceRoot);
313
+ runNx(["g", "@mnci/nx-flutter:library", name, "--no-interactive"], workspaceRoot);
314
+ registerProjectCommands(workspaceRoot, name, { build: false });
315
+ }
316
+ function addFlutterInternalLib(workspaceRoot, name) {
317
+ prepareFlutter(workspaceRoot);
318
+ runNx(["g", "@mnci/nx-flutter:internal-library", name, "--no-interactive"], workspaceRoot);
319
+ registerProjectCommands(workspaceRoot, name, { build: false });
320
+ }
205
321
 
206
322
  // src/commands/add/go.ts
323
+ var import_node_fs3 = require("fs");
324
+ var import_node_path4 = require("path");
207
325
  function ensureGo(workspaceRoot) {
208
326
  if (runShell("go", ["version"], workspaceRoot) !== 0) {
209
327
  throw new Error("Go not found. Install Go 1.21+ first: https://go.dev/dl/");
@@ -230,7 +348,7 @@ function ensureNxGoPlugin(workspaceRoot) {
230
348
  }
231
349
  }
232
350
  function ensureGoModule(workspaceRoot) {
233
- if (fileExists((0, import_node_path3.join)(workspaceRoot, "go.mod"))) {
351
+ if (fileExists((0, import_node_path4.join)(workspaceRoot, "go.mod"))) {
234
352
  return;
235
353
  }
236
354
  logger.step("Bootstrapping the workspace Go module (single root go.mod)");
@@ -239,13 +357,13 @@ function ensureGoModule(workspaceRoot) {
239
357
  }
240
358
  function goModulePath(workspaceRoot) {
241
359
  try {
242
- const contents = (0, import_node_fs2.readFileSync)((0, import_node_path3.join)(workspaceRoot, "go.mod"), "utf8");
360
+ const contents = (0, import_node_fs3.readFileSync)((0, import_node_path4.join)(workspaceRoot, "go.mod"), "utf8");
243
361
  return /^module\s+(\S+)/m.exec(contents)?.[1];
244
362
  } catch {
245
363
  return void 0;
246
364
  }
247
365
  }
248
- function addProjectJsonTargets(projectJsonPath, newTargets) {
366
+ function addProjectJsonTargets2(projectJsonPath, newTargets) {
249
367
  const project = readJson(projectJsonPath);
250
368
  const targets = project.targets ?? {};
251
369
  writeFileEnsured(projectJsonPath, toJson({ ...project, targets: { ...targets, ...newTargets } }));
@@ -275,6 +393,13 @@ function goPackageTarget(tag, name) {
275
393
  options: { command }
276
394
  };
277
395
  }
396
+ function goStartTarget(name) {
397
+ return {
398
+ executor: "nx:run-commands",
399
+ continuous: true,
400
+ options: { command: "go run .", cwd: `apps/${name}` }
401
+ };
402
+ }
278
403
  function prepareGo(workspaceRoot) {
279
404
  ensureGo(workspaceRoot);
280
405
  warnIfNoGolangciLint(workspaceRoot);
@@ -295,12 +420,14 @@ function addGoApp(workspaceRoot, name) {
295
420
  ],
296
421
  workspaceRoot
297
422
  );
298
- addProjectJsonTargets((0, import_node_path3.join)(workspaceRoot, "apps", name, "project.json"), {
423
+ addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "apps", name, "project.json"), {
299
424
  build: goBuildTarget(name),
300
425
  test: goTestTarget(),
301
426
  lint: goLintTarget(),
302
- package: goPackageTarget("go-app", name)
427
+ package: goPackageTarget("go-app", name),
428
+ start: goStartTarget(name)
303
429
  });
430
+ registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
304
431
  }
305
432
  function addGoFunctionApp(workspaceRoot, name) {
306
433
  prepareGo(workspaceRoot);
@@ -316,12 +443,13 @@ function addGoFunctionApp(workspaceRoot, name) {
316
443
  ],
317
444
  workspaceRoot
318
445
  );
319
- addProjectJsonTargets((0, import_node_path3.join)(workspaceRoot, "apps", name, "project.json"), {
446
+ addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "apps", name, "project.json"), {
320
447
  build: goBuildTarget(name),
321
448
  test: goTestTarget(),
322
449
  lint: goLintTarget(),
323
450
  package: goPackageTarget("go-function-app", name)
324
451
  });
452
+ registerProjectCommands(workspaceRoot, name, { build: true });
325
453
  }
326
454
  function addGoLib(workspaceRoot, name) {
327
455
  prepareGo(workspaceRoot);
@@ -336,10 +464,11 @@ function addGoLib(workspaceRoot, name) {
336
464
  ],
337
465
  workspaceRoot
338
466
  );
339
- addProjectJsonTargets((0, import_node_path3.join)(workspaceRoot, "packages", name, "project.json"), {
467
+ addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "packages", name, "project.json"), {
340
468
  test: goTestTarget(),
341
469
  lint: goLintTarget()
342
470
  });
471
+ registerProjectCommands(workspaceRoot, name, { build: false });
343
472
  const module2 = goModulePath(workspaceRoot);
344
473
  if (module2) {
345
474
  logger.step(`Import it as ${module2}/packages/${name}`);
@@ -358,10 +487,11 @@ function addGoInternalLib(workspaceRoot, name) {
358
487
  ],
359
488
  workspaceRoot
360
489
  );
361
- addProjectJsonTargets((0, import_node_path3.join)(workspaceRoot, "libs", name, "project.json"), {
490
+ addProjectJsonTargets2((0, import_node_path4.join)(workspaceRoot, "libs", name, "project.json"), {
362
491
  test: goTestTarget(),
363
492
  lint: goLintTarget()
364
493
  });
494
+ registerProjectCommands(workspaceRoot, name, { build: false });
365
495
  const module2 = goModulePath(workspaceRoot);
366
496
  if (module2) {
367
497
  logger.step(`Import it as ${module2}/libs/${name}`);
@@ -369,7 +499,7 @@ function addGoInternalLib(workspaceRoot, name) {
369
499
  }
370
500
 
371
501
  // src/commands/add/node.ts
372
- var import_node_path4 = require("path");
502
+ var import_node_path5 = require("path");
373
503
  function ensurePlugin(workspaceRoot, packageName) {
374
504
  if (hasPlugin(workspaceRoot, packageName)) {
375
505
  return;
@@ -408,9 +538,10 @@ function nodeAppPackageTarget(name) {
408
538
  function addNodeApp(workspaceRoot, name, stack, framework = "none") {
409
539
  runNodeApp(workspaceRoot, name, stack, framework);
410
540
  ensureAdmZip(workspaceRoot);
411
- addNxTargets((0, import_node_path4.join)(workspaceRoot, "apps", name, "package.json"), {
541
+ addNxTargets((0, import_node_path5.join)(workspaceRoot, "apps", name, "package.json"), {
412
542
  package: nodeAppPackageTarget(name)
413
543
  });
544
+ registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
414
545
  }
415
546
  function ensureAzureFunctionsPackage(workspaceRoot) {
416
547
  if (hasPlugin(workspaceRoot, "@azure/functions")) {
@@ -461,17 +592,17 @@ describe('buildGreeting', () => {
461
592
  })
462
593
  `;
463
594
  function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
464
- const manifestPath = (0, import_node_path4.join)(nodeFunctionAppRoot, "package.json");
595
+ const manifestPath = (0, import_node_path5.join)(nodeFunctionAppRoot, "package.json");
465
596
  const manifest = readJson(manifestPath);
466
597
  const azureFunctionsVersion = readJson(
467
- (0, import_node_path4.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
598
+ (0, import_node_path5.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
468
599
  ).version;
469
600
  const dependencies = manifest.dependencies ?? {};
470
601
  writeFileEnsured(
471
602
  manifestPath,
472
603
  toJson({
473
604
  ...manifest,
474
- main: "main.js",
605
+ main: "dist/main.js",
475
606
  dependencies: { ...dependencies, "@azure/functions": `^${azureFunctionsVersion}` }
476
607
  })
477
608
  );
@@ -479,7 +610,7 @@ function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
479
610
  function nodeFunctionAppPackageTarget(name) {
480
611
  const zip = `dist/drop/node-function-app-${name}.zip`;
481
612
  const root = `apps/${name}`;
482
- const command = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const A=require('adm-zip');const z=new A();z.addLocalFolder('${root}/dist');z.addLocalFile('${root}/host.json');z.addLocalFile('${root}/package.json');z.writeZip('${zip}')"`;
613
+ const command = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const A=require('adm-zip');const z=new A();z.addLocalFolder('${root}/dist','dist');z.addLocalFile('${root}/host.json');z.addLocalFile('${root}/package.json');z.writeZip('${zip}')"`;
483
614
  return {
484
615
  executor: "nx:run-commands",
485
616
  dependsOn: ["build"],
@@ -488,30 +619,40 @@ function nodeFunctionAppPackageTarget(name) {
488
619
  options: { command }
489
620
  };
490
621
  }
622
+ function nodeFunctionAppStartTarget(name) {
623
+ return {
624
+ executor: "nx:run-commands",
625
+ dependsOn: ["build"],
626
+ continuous: true,
627
+ options: { command: "func start", cwd: `apps/${name}` }
628
+ };
629
+ }
491
630
  function addNodeFunctionApp(workspaceRoot, name, stack) {
492
631
  runNodeApp(workspaceRoot, name, stack, "none");
493
632
  ensureAzureFunctionsPackage(workspaceRoot);
494
- const nodeFunctionAppRoot = (0, import_node_path4.join)(workspaceRoot, "apps", name);
495
- writeFileEnsured((0, import_node_path4.join)(nodeFunctionAppRoot, "src/main.ts"), NODE_FUNCTION_APP_MAIN);
496
- writeFileEnsured((0, import_node_path4.join)(nodeFunctionAppRoot, "src/functions/hello.ts"), NODE_FUNCTION_APP_HELLO);
633
+ const nodeFunctionAppRoot = (0, import_node_path5.join)(workspaceRoot, "apps", name);
634
+ writeFileEnsured((0, import_node_path5.join)(nodeFunctionAppRoot, "src/main.ts"), NODE_FUNCTION_APP_MAIN);
635
+ writeFileEnsured((0, import_node_path5.join)(nodeFunctionAppRoot, "src/functions/hello.ts"), NODE_FUNCTION_APP_HELLO);
497
636
  writeFileEnsured(
498
- (0, import_node_path4.join)(nodeFunctionAppRoot, "src/functions/greeting.ts"),
637
+ (0, import_node_path5.join)(nodeFunctionAppRoot, "src/functions/greeting.ts"),
499
638
  NODE_FUNCTION_APP_GREETING
500
639
  );
501
640
  writeFileEnsured(
502
- (0, import_node_path4.join)(nodeFunctionAppRoot, "src/functions/greeting.spec.ts"),
641
+ (0, import_node_path5.join)(nodeFunctionAppRoot, "src/functions/greeting.spec.ts"),
503
642
  NODE_FUNCTION_APP_GREETING_SPEC
504
643
  );
505
- writeFileEnsured((0, import_node_path4.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
644
+ writeFileEnsured((0, import_node_path5.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
506
645
  repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
507
646
  ensureAdmZip(workspaceRoot);
508
- addNxTargets((0, import_node_path4.join)(nodeFunctionAppRoot, "package.json"), {
509
- package: nodeFunctionAppPackageTarget(name)
647
+ addNxTargets((0, import_node_path5.join)(nodeFunctionAppRoot, "package.json"), {
648
+ package: nodeFunctionAppPackageTarget(name),
649
+ start: nodeFunctionAppStartTarget(name)
510
650
  });
651
+ registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
511
652
  }
512
653
 
513
654
  // src/commands/add/npmLib.ts
514
- var import_node_path5 = require("path");
655
+ var import_node_path6 = require("path");
515
656
  var NPM_LIB_ESLINT_CONFIG = `import { globSync, readFileSync } from 'node:fs';
516
657
  import { dirname, join } from 'node:path';
517
658
  import { fileURLToPath } from 'node:url';
@@ -539,6 +680,17 @@ export default [
539
680
  ignoredFiles: [
540
681
  '{projectRoot}/eslint.config.{js,cjs,mjs,ts,cts,mts}',
541
682
  '{projectRoot}/rollup.config.{js,ts,mjs,mts,cjs,cts}',
683
+ // Same reasoning as the two config files above, extended to the test
684
+ // toolchain: rollup bundles from the entry point only, so neither the
685
+ // Vitest config nor the spec files reach the published package \u2014 their
686
+ // imports must not drive the published manifest.
687
+ //
688
+ // Without this, a vitest-stack workspace fails \`npm run lint\` on a
689
+ // freshly generated npm-lib: Nx's own spec imports \`vitest\`, and
690
+ // @nx/dependency-checks then demands it be declared as a runtime
691
+ // dependency of a package that never uses it at runtime.
692
+ '{projectRoot}/vitest.config.{js,ts,mjs,mts,cjs,cts}',
693
+ '{projectRoot}/**/*.spec.{js,ts,jsx,tsx}',
542
694
  ],
543
695
  },
544
696
  ],
@@ -568,11 +720,12 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
568
720
  ],
569
721
  workspaceRoot
570
722
  );
571
- markPublic((0, import_node_path5.join)(workspaceRoot, "packages", name, "package.json"));
723
+ markPublic((0, import_node_path6.join)(workspaceRoot, "packages", name, "package.json"));
572
724
  writeFileEnsured(
573
- (0, import_node_path5.join)(workspaceRoot, "packages", name, "eslint.config.mjs"),
725
+ (0, import_node_path6.join)(workspaceRoot, "packages", name, "eslint.config.mjs"),
574
726
  NPM_LIB_ESLINT_CONFIG
575
727
  );
728
+ registerProjectCommands(workspaceRoot, name, { build: true });
576
729
  }
577
730
  function markPublic(manifestPath) {
578
731
  const manifest = readJson(manifestPath);
@@ -580,8 +733,8 @@ function markPublic(manifestPath) {
580
733
  }
581
734
 
582
735
  // src/commands/add/python.ts
583
- var import_node_fs3 = require("fs");
584
- var import_node_path6 = require("path");
736
+ var import_node_fs4 = require("fs");
737
+ var import_node_path7 = require("path");
585
738
  function ensurePython(workspaceRoot) {
586
739
  const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
587
740
  if (!hasPython) {
@@ -610,7 +763,7 @@ pytest
610
763
  pip-audit
611
764
  `;
612
765
  function ensureRequirementsDev(workspaceRoot) {
613
- const requirementsDevPath = (0, import_node_path6.join)(workspaceRoot, "requirements-dev.txt");
766
+ const requirementsDevPath = (0, import_node_path7.join)(workspaceRoot, "requirements-dev.txt");
614
767
  if (!fileExists(requirementsDevPath)) {
615
768
  writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
616
769
  }
@@ -618,11 +771,34 @@ function ensureRequirementsDev(workspaceRoot) {
618
771
  function pythonModuleDirectory(name) {
619
772
  return name.replaceAll("-", "_");
620
773
  }
621
- function addProjectJsonTargets2(projectJsonPath, newTargets) {
774
+ function addProjectJsonTargets3(projectJsonPath, newTargets) {
622
775
  const project = readJson(projectJsonPath);
623
776
  const targets = project.targets ?? {};
624
777
  writeFileEnsured(projectJsonPath, toJson({ ...project, targets: { ...targets, ...newTargets } }));
625
778
  }
779
+ function pythonAppMain(name) {
780
+ return `def main() -> None:
781
+ print('${name} is running')
782
+
783
+
784
+ if __name__ == '__main__':
785
+ main()
786
+ `;
787
+ }
788
+ function pythonAppStartTarget(name) {
789
+ return {
790
+ executor: "nx:run-commands",
791
+ continuous: true,
792
+ options: { command: "python3 main.py", cwd: `apps/${name}` }
793
+ };
794
+ }
795
+ function pythonFunctionAppStartTarget(name) {
796
+ return {
797
+ executor: "nx:run-commands",
798
+ continuous: true,
799
+ options: { command: "func start", cwd: `apps/${name}` }
800
+ };
801
+ }
626
802
  function pythonAppPackageTarget(name) {
627
803
  const zip = `dist/drop/python-app-${name}.zip`;
628
804
  const command = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});const A=require('adm-zip');const z=new A();z.addLocalFolder('apps/${name}/dist');z.writeZip('${zip}')"`;
@@ -654,9 +830,12 @@ function addPythonApp(workspaceRoot, name) {
654
830
  ["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
655
831
  workspaceRoot
656
832
  );
657
- addProjectJsonTargets2((0, import_node_path6.join)(workspaceRoot, "apps", name, "project.json"), {
658
- package: pythonAppPackageTarget(name)
833
+ writeFileEnsured((0, import_node_path7.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
834
+ addProjectJsonTargets3((0, import_node_path7.join)(workspaceRoot, "apps", name, "project.json"), {
835
+ package: pythonAppPackageTarget(name),
836
+ start: pythonAppStartTarget(name)
659
837
  });
838
+ registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
660
839
  }
661
840
  function addPythonFunctionApp(workspaceRoot, name) {
662
841
  ensurePython(workspaceRoot);
@@ -674,9 +853,11 @@ function addPythonFunctionApp(workspaceRoot, name) {
674
853
  workspaceRoot
675
854
  );
676
855
  const moduleDirectory = pythonModuleDirectory(name);
677
- addProjectJsonTargets2((0, import_node_path6.join)(workspaceRoot, "apps", name, "project.json"), {
678
- package: pythonFunctionAppPackageTarget(name, moduleDirectory)
856
+ addProjectJsonTargets3((0, import_node_path7.join)(workspaceRoot, "apps", name, "project.json"), {
857
+ package: pythonFunctionAppPackageTarget(name, moduleDirectory),
858
+ start: pythonFunctionAppStartTarget(name)
679
859
  });
860
+ registerProjectCommands(workspaceRoot, name, { build: false, start: `nx run ${name}:start` });
680
861
  }
681
862
  function addPythonLib(workspaceRoot, name) {
682
863
  ensurePython(workspaceRoot);
@@ -692,6 +873,7 @@ function addPythonLib(workspaceRoot, name) {
692
873
  ],
693
874
  workspaceRoot
694
875
  );
876
+ registerProjectCommands(workspaceRoot, name, { build: true });
695
877
  }
696
878
  function addPythonInternalLib(workspaceRoot, name) {
697
879
  ensurePython(workspaceRoot);
@@ -707,11 +889,12 @@ function addPythonInternalLib(workspaceRoot, name) {
707
889
  ],
708
890
  workspaceRoot
709
891
  );
892
+ registerProjectCommands(workspaceRoot, name, { build: false });
710
893
  }
711
894
  var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
712
895
  function findPythonProjectDirectory(workspaceRoot, name) {
713
896
  return PYTHON_PROJECT_DIRS.find(
714
- (directory) => fileExists((0, import_node_path6.join)(workspaceRoot, directory, name, "pyproject.toml"))
897
+ (directory) => fileExists((0, import_node_path7.join)(workspaceRoot, directory, name, "pyproject.toml"))
715
898
  );
716
899
  }
717
900
  function parseVendorEntries(pyprojectToml) {
@@ -750,7 +933,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
750
933
  `No Python project named '${consumer}' with a pyproject.toml found (checked apps/, python-packages/, libs/). A Python function app has no pyproject.toml \u2014 there is nothing to vendor into.`
751
934
  );
752
935
  }
753
- if (!fileExists((0, import_node_path6.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
936
+ if (!fileExists((0, import_node_path7.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
754
937
  throw new Error(
755
938
  `No internal Python library named '${lib}' found at libs/${lib}/pyproject.toml. Only an internal library (added via 'mnci add python-internal-lib') can be vendored.`
756
939
  );
@@ -758,8 +941,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
758
941
  if (consumerDirectory === "libs" && consumer === lib) {
759
942
  throw new Error(`'${consumer}' cannot vendor itself.`);
760
943
  }
761
- const pyprojectPath = (0, import_node_path6.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
762
- const pyprojectToml = (0, import_node_fs3.readFileSync)(pyprojectPath, "utf8");
944
+ const pyprojectPath = (0, import_node_path7.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
945
+ const pyprojectToml = (0, import_node_fs4.readFileSync)(pyprojectPath, "utf8");
763
946
  if (parseVendorEntries(pyprojectToml).includes(lib)) {
764
947
  logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
765
948
  return;
@@ -771,8 +954,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
771
954
  }
772
955
 
773
956
  // src/commands/add/reactApp.ts
774
- var import_node_fs4 = require("fs");
775
- var import_node_path7 = require("path");
957
+ var import_node_fs5 = require("fs");
958
+ var import_node_path8 = require("path");
776
959
  function ensurePlugin2(workspaceRoot, packageName) {
777
960
  if (hasPlugin(workspaceRoot, packageName)) {
778
961
  return;
@@ -818,12 +1001,12 @@ function reactAppTargets(name) {
818
1001
  return targets;
819
1002
  }
820
1003
  function allowEnvFiles(workspaceRoot) {
821
- const gitignorePath = (0, import_node_path7.join)(workspaceRoot, ".gitignore");
1004
+ const gitignorePath = (0, import_node_path8.join)(workspaceRoot, ".gitignore");
822
1005
  if (!fileExists(gitignorePath)) {
823
1006
  return;
824
1007
  }
825
1008
  const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
826
- const current = (0, import_node_fs4.readFileSync)(gitignorePath, "utf8");
1009
+ const current = (0, import_node_fs5.readFileSync)(gitignorePath, "utf8");
827
1010
  if (current.includes(marker)) {
828
1011
  return;
829
1012
  }
@@ -850,12 +1033,13 @@ function addReactApp(workspaceRoot, name, stack) {
850
1033
  workspaceRoot
851
1034
  );
852
1035
  ensureAdmZip(workspaceRoot);
853
- const reactAppRoot = (0, import_node_path7.join)(workspaceRoot, "apps", name);
1036
+ const reactAppRoot = (0, import_node_path8.join)(workspaceRoot, "apps", name);
854
1037
  for (const environment of REACT_ENVIRONMENTS) {
855
- writeFileEnsured((0, import_node_path7.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
1038
+ writeFileEnsured((0, import_node_path8.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
856
1039
  }
857
1040
  allowEnvFiles(workspaceRoot);
858
- addNxTargets((0, import_node_path7.join)(reactAppRoot, "package.json"), reactAppTargets(name));
1041
+ addNxTargets((0, import_node_path8.join)(reactAppRoot, "package.json"), reactAppTargets(name));
1042
+ registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
859
1043
  }
860
1044
 
861
1045
  // src/commands/add.ts
@@ -873,11 +1057,14 @@ var PROJECT_KINDS = [
873
1057
  "go-app",
874
1058
  "go-function-app",
875
1059
  "go-lib",
876
- "go-internal-lib"
1060
+ "go-internal-lib",
1061
+ "flutter-app",
1062
+ "flutter-lib",
1063
+ "flutter-internal-lib"
877
1064
  ];
878
1065
  async function runAdd(kind, name, options) {
879
1066
  const workspaceRoot = process.cwd();
880
- if (!fileExists((0, import_node_path8.join)(workspaceRoot, "nx.json"))) {
1067
+ if (!fileExists((0, import_node_path9.join)(workspaceRoot, "nx.json"))) {
881
1068
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
882
1069
  }
883
1070
  const stack = readWorkspaceStack(workspaceRoot);
@@ -918,7 +1105,8 @@ async function runAdd(kind, name, options) {
918
1105
  ],
919
1106
  workspaceRoot
920
1107
  );
921
- markPrivate((0, import_node_path8.join)(workspaceRoot, "libs", resolvedName, "package.json"));
1108
+ markPrivate((0, import_node_path9.join)(workspaceRoot, "libs", resolvedName, "package.json"));
1109
+ registerProjectCommands(workspaceRoot, resolvedName, { build: true });
922
1110
  break;
923
1111
  }
924
1112
  case "python-app": {
@@ -953,6 +1141,18 @@ async function runAdd(kind, name, options) {
953
1141
  addGoInternalLib(workspaceRoot, resolvedName);
954
1142
  break;
955
1143
  }
1144
+ case "flutter-app": {
1145
+ addFlutterApp(workspaceRoot, resolvedName);
1146
+ break;
1147
+ }
1148
+ case "flutter-lib": {
1149
+ addFlutterLib(workspaceRoot, resolvedName);
1150
+ break;
1151
+ }
1152
+ case "flutter-internal-lib": {
1153
+ addFlutterInternalLib(workspaceRoot, resolvedName);
1154
+ break;
1155
+ }
956
1156
  case "python-vendor": {
957
1157
  await addPythonVendor(workspaceRoot, resolvedName, options, kindProvided);
958
1158
  syncProjectReferences(workspaceRoot);
@@ -978,7 +1178,7 @@ function syncProjectReferences(workspaceRoot) {
978
1178
  }
979
1179
  function readWorkspaceStack(workspaceRoot) {
980
1180
  const nxJson = readJson(
981
- (0, import_node_path8.join)(workspaceRoot, "nx.json")
1181
+ (0, import_node_path9.join)(workspaceRoot, "nx.json")
982
1182
  );
983
1183
  const stack = nxJson.mnci?.stack;
984
1184
  return {
@@ -991,14 +1191,14 @@ function markPrivate(manifestPath) {
991
1191
  }
992
1192
 
993
1193
  // src/commands/interactive.ts
994
- var import_node_path12 = require("path");
1194
+ var import_node_path13 = require("path");
995
1195
  var import_prompts7 = require("@inquirer/prompts");
996
1196
 
997
1197
  // src/commands/new.ts
998
- var import_node_path10 = require("path");
1198
+ var import_node_path11 = require("path");
999
1199
 
1000
1200
  // src/overlay.ts
1001
- var import_node_path9 = require("path");
1201
+ var import_node_path10 = require("path");
1002
1202
  var DEFAULT_STACK = { testRunner: "jest" };
1003
1203
  var PRETTIER_VERSION = "^3.8.1";
1004
1204
  var TS_COMPILER_DEPENDENCIES = {
@@ -1038,7 +1238,7 @@ function releaseConfig(ci) {
1038
1238
  const githubReleases = ci === "github";
1039
1239
  return {
1040
1240
  projectsRelationship: "independent",
1041
- projects: ["packages/*", "python-packages/*"],
1241
+ projects: ["packages/*", "python-packages/*", "!tag:type:go-lib"],
1042
1242
  releaseTag: { pattern: "{projectName}@{version}" },
1043
1243
  git: { commit: false, tag: true, push: githubReleases },
1044
1244
  version: {
@@ -1092,12 +1292,7 @@ package-lock.json
1092
1292
  function vscodeWorkspace(workspaceName) {
1093
1293
  return JSON.stringify(
1094
1294
  {
1095
- folders: [
1096
- { path: ".", name: workspaceName },
1097
- { path: "packages/cli", name: "@mnci/cli" },
1098
- { path: "packages/nx-python-pip", name: "@mnci/nx-python-pip" },
1099
- { path: "libs/monecromanci-v2", name: "@mnci/monecromanci" }
1100
- ],
1295
+ folders: [{ path: ".", name: workspaceName }],
1101
1296
  settings: {
1102
1297
  "eslint.validate": [
1103
1298
  "javascript",
@@ -1131,7 +1326,8 @@ function vscodeWorkspace(workspaceName) {
1131
1326
  "nrwl.angular-console",
1132
1327
  "firsttris.vscode-jest-runner"
1133
1328
  ]
1134
- }
1329
+ },
1330
+ tasks: { version: "2.0.0", tasks: [] }
1135
1331
  },
1136
1332
  null,
1137
1333
  2
@@ -1176,7 +1372,7 @@ function mnciConfig(options) {
1176
1372
  };
1177
1373
  }
1178
1374
  function readMnciConfig(workspaceRoot) {
1179
- const nxJson = readJson((0, import_node_path9.join)(workspaceRoot, "nx.json"));
1375
+ const nxJson = readJson((0, import_node_path10.join)(workspaceRoot, "nx.json"));
1180
1376
  return nxJson.mnci ?? {};
1181
1377
  }
1182
1378
  function pythonPublishUrl(registry) {
@@ -1193,6 +1389,13 @@ var GOLANGCI_LINT_INSTALL_GUARD = `node -e "const fs=require('node:fs'),cp=requi
1193
1389
  var GO_TOOL_PATH_PRELUDE = `const fs=require('node:fs'),cp=require('node:child_process');if(!fs.existsSync('go.mod')){console.log('No Go projects - skipping.');process.exit(0)}const r=cp.spawnSync('go',['env','GOPATH'],{encoding:'utf8'});if(r.status!==0){console.log('Could not resolve GOPATH - skipping.');process.exit(0)}const bin=require('node:path').join(r.stdout.trim(),'bin');`;
1194
1390
  var GO_TOOL_PATH_AZURE = `node -e "${GO_TOOL_PATH_PRELUDE}console.log('##vso[task.prependpath]'+bin)"`;
1195
1391
  var GO_TOOL_PATH_GITHUB = `node -e "${GO_TOOL_PATH_PRELUDE}if(!process.env.GITHUB_PATH){console.log('Not running in GitHub Actions - skipping.');process.exit(0)}fs.appendFileSync(process.env.GITHUB_PATH,bin+${String.raw`'\n'`})"`;
1392
+ var FLUTTER_SDK_VERSION = "3.44.8";
1393
+ var FLUTTER_SDK_DIRECTORY_EXPRESSION = `require('node:path').join(require('node:os').homedir(),'.mnci-flutter-${FLUTTER_SDK_VERSION}')`;
1394
+ var FLUTTER_SDK_INSTALL_GUARD = `node -e "const fs=require('node:fs'),cp=require('node:child_process');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}if(cp.spawnSync('flutter',['--version'],{stdio:'ignore',shell:process.platform==='win32'}).status===0){console.log('Flutter SDK already on PATH - skipping.');process.exit(0)}const sdk=${FLUTTER_SDK_DIRECTORY_EXPRESSION};if(fs.existsSync(sdk)){console.log('Flutter SDK already installed at '+sdk+' - skipping.');process.exit(0)}process.exit(cp.spawnSync('git',['clone','--depth','1','--branch','${FLUTTER_SDK_VERSION}','https://github.com/flutter/flutter.git',sdk],{stdio:'inherit'}).status ?? 1)"`;
1395
+ var FLUTTER_TOOL_PATH_PRELUDE = `const fs=require('node:fs'),path=require('node:path');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}const sdk=${FLUTTER_SDK_DIRECTORY_EXPRESSION};if(!fs.existsSync(sdk)){console.log('Flutter SDK was not installed by mnci (already on PATH) - skipping.');process.exit(0)}const bin=path.join(sdk,'bin');`;
1396
+ var FLUTTER_TOOL_PATH_AZURE = `node -e "${FLUTTER_TOOL_PATH_PRELUDE}console.log('##vso[task.prependpath]'+bin)"`;
1397
+ var FLUTTER_TOOL_PATH_GITHUB = `node -e "${FLUTTER_TOOL_PATH_PRELUDE}if(!process.env.GITHUB_PATH){console.log('Not running in GitHub Actions - skipping.');process.exit(0)}fs.appendFileSync(process.env.GITHUB_PATH,bin+${String.raw`'\n'`})"`;
1398
+ var FLUTTER_PUB_GET_GUARD = `node -e "const fs=require('node:fs');if(!fs.existsSync('pubspec.yaml')){console.log('No Flutter projects - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('flutter',['pub','get'],{stdio:'inherit',shell:process.platform==='win32'}).status ?? 1)"`;
1196
1399
  var NPM_AUDIT_STEP = "npm audit --audit-level=high || echo npm audit found vulnerabilities, see log above - non-blocking, run npm audit locally to inspect";
1197
1400
  var PACK_APPS_GUARD = `node -e "const fs=require('node:fs');fs.mkdirSync('dist/drop',{recursive:true});if(fs.globSync('apps/*/project.json').length===0){console.log('No apps to pack - skipping.');process.exit(0)}process.exit(require('node:child_process').spawnSync('npx nx run-many -t package',{stdio:'inherit',shell:true}).status ?? 1)"`;
1198
1401
  function releaseGuard(pythonPublishEnv) {
@@ -1308,6 +1511,23 @@ steps:
1308
1511
  - script: ${GO_TOOL_PATH_AZURE}
1309
1512
  displayName: Add Go tool bin to PATH
1310
1513
 
1514
+ # Flutter, if the workspace has any. Unlike Python and Go, hosted agents do
1515
+ # NOT ship the Flutter SDK, so this installs it (shallow git clone at a
1516
+ # pinned tag) and puts it on PATH. All three guards skip cleanly on a
1517
+ # workspace with no root pubspec.yaml, and the install also skips when an
1518
+ # SDK is already on PATH.
1519
+ - script: ${FLUTTER_SDK_INSTALL_GUARD}
1520
+ displayName: Install the Flutter SDK (${FLUTTER_SDK_VERSION})
1521
+
1522
+ - script: ${FLUTTER_TOOL_PATH_AZURE}
1523
+ displayName: Add the Flutter SDK to PATH
1524
+
1525
+ # One command resolves EVERY Dart dependency, internal and external, for the
1526
+ # whole workspace: the projects are pub workspace members, so this writes a
1527
+ # single root pubspec.lock they all share.
1528
+ - script: ${FLUTTER_PUB_GET_GUARD}
1529
+ displayName: Resolve Dart dependencies (one pub get for the whole workspace)
1530
+
1311
1531
  # Fails fast, with an unambiguous message, when a stale TypeScript project
1312
1532
  # reference (or another sync generator's drift) was never synced+committed
1313
1533
  # locally \u2014 sync.applyChanges (nx.json) only auto-applies interactively, so
@@ -1462,6 +1682,23 @@ jobs:
1462
1682
  - run: ${GO_TOOL_PATH_GITHUB}
1463
1683
  name: Add Go tool bin to PATH
1464
1684
 
1685
+ # Flutter, if the workspace has any. Unlike Python and Go, hosted runners
1686
+ # do NOT ship the Flutter SDK, so this installs it (shallow git clone at
1687
+ # a pinned tag) and puts it on PATH. All three guards skip cleanly on a
1688
+ # workspace with no root pubspec.yaml, and the install also skips when an
1689
+ # SDK is already on PATH.
1690
+ - run: ${FLUTTER_SDK_INSTALL_GUARD}
1691
+ name: Install the Flutter SDK (${FLUTTER_SDK_VERSION})
1692
+
1693
+ - run: ${FLUTTER_TOOL_PATH_GITHUB}
1694
+ name: Add the Flutter SDK to PATH
1695
+
1696
+ # One command resolves EVERY Dart dependency, internal and external, for
1697
+ # the whole workspace: the projects are pub workspace members, so this
1698
+ # writes a single root pubspec.lock they all share.
1699
+ - run: ${FLUTTER_PUB_GET_GUARD}
1700
+ name: Resolve Dart dependencies (one pub get for the whole workspace)
1701
+
1465
1702
  # Fails fast, with an unambiguous message, when a stale TypeScript project
1466
1703
  # reference (or another sync generator's drift) was never synced+committed
1467
1704
  # locally \u2014 sync.applyChanges (nx.json) only auto-applies interactively, so
@@ -1547,9 +1784,21 @@ updates:
1547
1784
  - "/libs/*"
1548
1785
  schedule:
1549
1786
  interval: weekly
1787
+
1788
+ # Same glob reasoning as pip above. Dart projects are pub workspace members,
1789
+ # so each one declares its own dependencies even though they all resolve
1790
+ # through the single root pubspec.lock \u2014 hence the per-project directories
1791
+ # rather than just "/".
1792
+ - package-ecosystem: pub
1793
+ directories:
1794
+ - "/apps/*"
1795
+ - "/packages/*"
1796
+ - "/libs/*"
1797
+ schedule:
1798
+ interval: weekly
1550
1799
  `;
1551
1800
  function applyOverlay(workspaceRoot, options) {
1552
- const nxJsonPath = (0, import_node_path9.join)(workspaceRoot, "nx.json");
1801
+ const nxJsonPath = (0, import_node_path10.join)(workspaceRoot, "nx.json");
1553
1802
  const nxJson = readJson(nxJsonPath);
1554
1803
  const generators = {
1555
1804
  ...nxJson.generators,
@@ -1561,7 +1810,7 @@ function applyOverlay(workspaceRoot, options) {
1561
1810
  nxJsonPath,
1562
1811
  toJson({ ...withReleaseConfig(nxJson, options.ci), generators, sync, mnci })
1563
1812
  );
1564
- const manifestPath = (0, import_node_path9.join)(workspaceRoot, "package.json");
1813
+ const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
1565
1814
  const manifest = readJson(manifestPath);
1566
1815
  const scripts = {
1567
1816
  ...manifest.scripts,
@@ -1576,30 +1825,30 @@ function applyOverlay(workspaceRoot, options) {
1576
1825
  manifestPath,
1577
1826
  toJson({ ...manifest, name: `${options.scope}/source`, scripts, devDependencies: devDeps })
1578
1827
  );
1579
- writeFileEnsured((0, import_node_path9.join)(workspaceRoot, ".npmrc"), npmrcContent(options.registry, options.scope));
1580
- writeFileEnsured((0, import_node_path9.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
1581
- const hookPath = (0, import_node_path9.join)(workspaceRoot, ".husky/commit-msg");
1828
+ writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".npmrc"), npmrcContent(options.registry, options.scope));
1829
+ writeFileEnsured((0, import_node_path10.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
1830
+ const hookPath = (0, import_node_path10.join)(workspaceRoot, ".husky/commit-msg");
1582
1831
  writeFileEnsured(hookPath, COMMIT_MSG_HOOK);
1583
1832
  markExecutable(hookPath);
1584
- writeFileEnsured((0, import_node_path9.join)(workspaceRoot, ".prettierrc.json"), PRETTIER_CONFIG);
1585
- writeFileEnsured((0, import_node_path9.join)(workspaceRoot, ".prettierignore"), PRETTIER_IGNORE);
1833
+ writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".prettierrc.json"), PRETTIER_CONFIG);
1834
+ writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".prettierignore"), PRETTIER_IGNORE);
1586
1835
  writeFileEnsured(
1587
- (0, import_node_path9.join)(workspaceRoot, `${options.workspaceName}.code-workspace`),
1836
+ (0, import_node_path10.join)(workspaceRoot, `${options.workspaceName}.code-workspace`),
1588
1837
  vscodeWorkspace(options.workspaceName)
1589
1838
  );
1590
1839
  const publishUrl = pythonPublishUrl(options.registry);
1591
1840
  if (options.ci === "azure" || options.ci === "both") {
1592
1841
  writeFileEnsured(
1593
- (0, import_node_path9.join)(workspaceRoot, "azure-pipelines.yml"),
1842
+ (0, import_node_path10.join)(workspaceRoot, "azure-pipelines.yml"),
1594
1843
  azurePipelinesYaml(options.agent, options.variableGroup, publishUrl, options.registry.kind)
1595
1844
  );
1596
1845
  }
1597
1846
  if (options.ci === "github" || options.ci === "both") {
1598
1847
  writeFileEnsured(
1599
- (0, import_node_path9.join)(workspaceRoot, ".github/workflows/ci.yml"),
1848
+ (0, import_node_path10.join)(workspaceRoot, ".github/workflows/ci.yml"),
1600
1849
  githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci)
1601
1850
  );
1602
- writeFileEnsured((0, import_node_path9.join)(workspaceRoot, ".github/dependabot.yml"), DEPENDABOT_CONFIG);
1851
+ writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".github/dependabot.yml"), DEPENDABOT_CONFIG);
1603
1852
  }
1604
1853
  }
1605
1854
 
@@ -1668,7 +1917,7 @@ async function runNew(name, options) {
1668
1917
  ],
1669
1918
  process.cwd()
1670
1919
  );
1671
- const workspaceRoot = (0, import_node_path10.join)(process.cwd(), workspaceName);
1920
+ const workspaceRoot = (0, import_node_path11.join)(process.cwd(), workspaceName);
1672
1921
  logger.step(
1673
1922
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
1674
1923
  );
@@ -1689,13 +1938,19 @@ async function runNew(name, options) {
1689
1938
  " mnci add react-app web # or: node-app, node-function-app, npm-lib, internal-lib,"
1690
1939
  );
1691
1940
  logger.info(
1692
- " # python-app, python-function-app, python-lib, python-internal-lib"
1941
+ " # python-app, python-function-app, python-lib, python-internal-lib,"
1942
+ );
1943
+ logger.info(
1944
+ " # go-app, go-function-app, go-lib, go-internal-lib,"
1945
+ );
1946
+ logger.info(
1947
+ " # flutter-app, flutter-lib, flutter-internal-lib"
1693
1948
  );
1694
1949
  logger.info(' git add -A && git commit -m "feat: initial workspace"');
1695
1950
  }
1696
1951
 
1697
1952
  // src/commands/upgrade.ts
1698
- var import_node_path11 = require("path");
1953
+ var import_node_path12 = require("path");
1699
1954
  function resolveRegistry2(options, persisted) {
1700
1955
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
1701
1956
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -1747,7 +2002,7 @@ function resolveOverlayOptions(options, persisted) {
1747
2002
  return { scope, registry, agent, variableGroup, ci, stack: { testRunner } };
1748
2003
  }
1749
2004
  function runUpgrade(workspaceRoot, options) {
1750
- if (!fileExists((0, import_node_path11.join)(workspaceRoot, "nx.json"))) {
2005
+ if (!fileExists((0, import_node_path12.join)(workspaceRoot, "nx.json"))) {
1751
2006
  throw new Error(
1752
2007
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
1753
2008
  );
@@ -1763,7 +2018,7 @@ function runUpgrade(workspaceRoot, options) {
1763
2018
 
1764
2019
  // src/commands/interactive.ts
1765
2020
  async function runInteractive() {
1766
- const inWorkspace = fileExists((0, import_node_path12.join)(process.cwd(), "nx.json"));
2021
+ const inWorkspace = fileExists((0, import_node_path13.join)(process.cwd(), "nx.json"));
1767
2022
  const newChoice = { name: "Create a new monorepo", value: "new" };
1768
2023
  const addChoice = { name: "Add a project to this workspace", value: "add" };
1769
2024
  const upgradeChoice = {
@@ -1784,8 +2039,8 @@ async function runInteractive() {
1784
2039
  }
1785
2040
 
1786
2041
  // src/util/versionChecker.ts
1787
- var import_node_fs5 = require("fs");
1788
- var import_node_path13 = require("path");
2042
+ var import_node_fs6 = require("fs");
2043
+ var import_node_path14 = require("path");
1789
2044
  var import_cross_spawn2 = __toESM(require("cross-spawn"));
1790
2045
  var PACKAGE_NAME = "@mnci/cli";
1791
2046
  var REGISTRY_TIMEOUT_MS = 2e3;
@@ -1841,8 +2096,8 @@ function releaseTriple(version) {
1841
2096
  }
1842
2097
  function readCliVersion(packageDirectory) {
1843
2098
  try {
1844
- const manifestPath = (0, import_node_path13.join)(packageDirectory, "..", "package.json");
1845
- const manifest = JSON.parse((0, import_node_fs5.readFileSync)(manifestPath, "utf8"));
2099
+ const manifestPath = (0, import_node_path14.join)(packageDirectory, "..", "package.json");
2100
+ const manifest = JSON.parse((0, import_node_fs6.readFileSync)(manifestPath, "utf8"));
1846
2101
  return manifest.version ?? "0.0.0";
1847
2102
  } catch {
1848
2103
  return "0.0.0";