@mnci/cli 4.36.0 → 4.38.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
@@ -340,18 +340,81 @@ function runAudit(workspaceRoot, dependencies = {}) {
340
340
  }
341
341
 
342
342
  // src/ci-pipeline/native.use-case.ts
343
+ var import_node_fs6 = require("fs");
344
+ var import_node_path5 = require("path");
345
+
346
+ // src/native-build-config/native-build.contract.ts
347
+ var DEFAULT_NATIVE_RUNNERS = ["windows-latest", "macos-latest", "ubuntu-latest"];
348
+
349
+ // src/native-build-config/read-native-build-config.use-case.ts
350
+ var import_node_fs3 = require("fs");
351
+ var import_node_path2 = require("path");
352
+ var PACKAGE_NAME = /^[a-z0-9][a-z0-9+.-]*$/;
353
+ var RUNNER_NAME = /^[A-Z0-9][\w.-]*$/i;
354
+ function readNativeBuildConfig(workspaceRoot) {
355
+ const settings = {
356
+ config: { linuxPackages: [], runners: [...DEFAULT_NATIVE_RUNNERS] },
357
+ problems: []
358
+ };
359
+ const raw = readNativeEntry(workspaceRoot);
360
+ if (raw === void 0) {
361
+ return settings;
362
+ }
363
+ if (typeof raw !== "object" || raw === null || Array.isArray(raw)) {
364
+ settings.problems.push("mnci.native must be an object");
365
+ return settings;
366
+ }
367
+ const entry = raw;
368
+ const packages = validList(entry.linuxPackages, "mnci.native.linuxPackages", PACKAGE_NAME, settings.problems);
369
+ const runners = validList(entry.runners, "mnci.native.runners", RUNNER_NAME, settings.problems);
370
+ if (packages !== void 0) {
371
+ settings.config.linuxPackages = packages;
372
+ }
373
+ if (runners !== void 0 && runners.length > 0) {
374
+ settings.config.runners = runners;
375
+ }
376
+ return settings;
377
+ }
378
+ function readNativeEntry(workspaceRoot) {
379
+ const path = (0, import_node_path2.join)(workspaceRoot, "nx.json");
380
+ if (!(0, import_node_fs3.existsSync)(path)) {
381
+ return void 0;
382
+ }
383
+ try {
384
+ const nxJson = JSON.parse((0, import_node_fs3.readFileSync)(path, "utf8"));
385
+ return nxJson.mnci?.native;
386
+ } catch {
387
+ return void 0;
388
+ }
389
+ }
390
+ function validList(value, label, pattern, problems) {
391
+ if (value === void 0) {
392
+ return void 0;
393
+ }
394
+ if (!Array.isArray(value)) {
395
+ problems.push(`${label} must be a list of strings`);
396
+ return void 0;
397
+ }
398
+ const valid = [];
399
+ for (const item of value) {
400
+ if (typeof item === "string" && pattern.test(item)) {
401
+ valid.push(item);
402
+ } else {
403
+ problems.push(`${label} has an invalid entry: ${JSON.stringify(item)}`);
404
+ }
405
+ }
406
+ return valid;
407
+ }
408
+
409
+ // src/workspace-overlay/overlay.use-case.ts
343
410
  var import_node_fs5 = require("fs");
344
411
  var import_node_path4 = require("path");
345
412
 
346
- // src/workspace-overlay/overlay.use-case.ts
413
+ // src/file-system/file-system.client.ts
347
414
  var import_node_fs4 = require("fs");
348
415
  var import_node_path3 = require("path");
349
-
350
- // src/file-system/file-system.client.ts
351
- var import_node_fs3 = require("fs");
352
- var import_node_path2 = require("path");
353
416
  function readJson(path) {
354
- return JSON.parse((0, import_node_fs3.readFileSync)(path, "utf8"));
417
+ return JSON.parse((0, import_node_fs4.readFileSync)(path, "utf8"));
355
418
  }
356
419
  function stripJsonComments(text) {
357
420
  let result = "";
@@ -408,7 +471,7 @@ function stripJsonComments(text) {
408
471
  }
409
472
  function readCodeWorkspace(path) {
410
473
  try {
411
- const withoutComments = stripJsonComments((0, import_node_fs3.readFileSync)(path, "utf8"));
474
+ const withoutComments = stripJsonComments((0, import_node_fs4.readFileSync)(path, "utf8"));
412
475
  return JSON.parse(withoutComments.replaceAll(/,(\s*[}\]])/g, "$1"));
413
476
  } catch {
414
477
  return void 0;
@@ -419,14 +482,139 @@ function toJson(value) {
419
482
  `;
420
483
  }
421
484
  function writeFileEnsured(path, content) {
422
- (0, import_node_fs3.mkdirSync)((0, import_node_path2.dirname)(path), { recursive: true });
423
- (0, import_node_fs3.writeFileSync)(path, content);
485
+ (0, import_node_fs4.mkdirSync)((0, import_node_path3.dirname)(path), { recursive: true });
486
+ (0, import_node_fs4.writeFileSync)(path, content);
424
487
  }
425
488
  function markExecutable(path) {
426
- (0, import_node_fs3.chmodSync)(path, 493);
489
+ (0, import_node_fs4.chmodSync)(path, 493);
427
490
  }
428
491
  function fileExists(path) {
429
- return (0, import_node_fs3.existsSync)(path);
492
+ return (0, import_node_fs4.existsSync)(path);
493
+ }
494
+
495
+ // src/pipeline-customization/pipeline-markers.algorithm.ts
496
+ var CHOOSABLE_PHASES = ["pack", "release"];
497
+ var SLOT_BEGIN = /^(\s*)# mnci:slot (\S+)/;
498
+ var SLOT_END = /^\s*# mnci:slot-end \S+/;
499
+ var PHASE_BEGIN = /^(\s*)# mnci:phase (\S+)/;
500
+ var PHASE_END = /^\s*# mnci:phase-end (\S+)/;
501
+ var SWITCHED_OFF_HINT = "# mnci: switched off. Uncomment the lines below to run it again (mnci doctor lists it).";
502
+ function slotMarkers(name, indent) {
503
+ return [
504
+ `${indent}# mnci:slot ${name} (your own steps go between these two lines; mnci upgrade keeps them)`,
505
+ `${indent}# mnci:slot-end ${name}`
506
+ ].join("\n");
507
+ }
508
+ function phaseStart(name, indent) {
509
+ return `${indent}# mnci:phase ${name} (delete or comment this block to switch it off; mnci upgrade keeps it off)`;
510
+ }
511
+ function phaseEnd(name, indent) {
512
+ return `${indent}# mnci:phase-end ${name}`;
513
+ }
514
+ function extractSlots(text) {
515
+ const slots = /* @__PURE__ */ new Map();
516
+ const lines = text.split("\n");
517
+ for (let index = 0; index < lines.length; index++) {
518
+ const begin = SLOT_BEGIN.exec(lines[index]);
519
+ if (!begin) {
520
+ continue;
521
+ }
522
+ const [, indent, name] = begin;
523
+ const content = [];
524
+ for (index++; index < lines.length && !SLOT_END.test(lines[index]); index++) {
525
+ content.push(lines[index].startsWith(indent) ? lines[index].slice(indent.length) : lines[index].trimStart());
526
+ }
527
+ slots.set(name, content);
528
+ index--;
529
+ }
530
+ return slots;
531
+ }
532
+ function injectSlots(generated, slots) {
533
+ const lines = generated.split("\n");
534
+ const result = [];
535
+ for (let index = 0; index < lines.length; index++) {
536
+ result.push(lines[index]);
537
+ const begin = SLOT_BEGIN.exec(lines[index]);
538
+ if (!begin) {
539
+ continue;
540
+ }
541
+ const [, indent, name] = begin;
542
+ const content = slots.get(name) ?? [];
543
+ for (const line of content) {
544
+ result.push(line === "" ? "" : `${indent}${line}`);
545
+ }
546
+ while (index + 1 < lines.length && !SLOT_END.test(lines[index + 1])) {
547
+ index++;
548
+ }
549
+ }
550
+ return result.join("\n");
551
+ }
552
+ function switchedOffPhases(text) {
553
+ const lines = text.split("\n");
554
+ if (lines.every((line) => !(PHASE_BEGIN.test(line) || SLOT_BEGIN.test(line)))) {
555
+ return [];
556
+ }
557
+ return CHOOSABLE_PHASES.filter((phase) => {
558
+ const begin = lines.findIndex((line) => PHASE_BEGIN.exec(line)?.[2] === phase);
559
+ if (begin === -1) {
560
+ return true;
561
+ }
562
+ for (let index = begin + 1; index < lines.length && PHASE_END.exec(lines[index])?.[1] !== phase; index++) {
563
+ const line = lines[index].trim();
564
+ if (line !== "" && !line.startsWith("#")) {
565
+ return false;
566
+ }
567
+ }
568
+ return true;
569
+ });
570
+ }
571
+ function commentOutPhases(generated, phases) {
572
+ if (phases.length === 0) {
573
+ return generated;
574
+ }
575
+ const lines = generated.split("\n");
576
+ const result = [];
577
+ for (let index = 0; index < lines.length; index++) {
578
+ result.push(lines[index]);
579
+ const begin = PHASE_BEGIN.exec(lines[index]);
580
+ if (!begin || !phases.includes(begin[2])) {
581
+ continue;
582
+ }
583
+ const [, indent, name] = begin;
584
+ result.push(`${indent}${SWITCHED_OFF_HINT}`);
585
+ for (index++; index < lines.length && PHASE_END.exec(lines[index])?.[1] !== name; index++) {
586
+ const line = lines[index];
587
+ result.push(line.trim() === "" || line.trimStart().startsWith("#") ? line : `${indent}# ${line.slice(indent.length)}`);
588
+ }
589
+ index--;
590
+ }
591
+ return result.join("\n");
592
+ }
593
+ function inspectPipeline(text) {
594
+ return {
595
+ verifyActive: text.split("\n").some((line) => !line.trimStart().startsWith("#") && /\bci verify\b/.test(line)),
596
+ switchedOff: switchedOffPhases(text)
597
+ };
598
+ }
599
+
600
+ // src/pipeline-customization/merge-pipeline.use-case.ts
601
+ function mergePipeline(existing, generated) {
602
+ if (existing === void 0) {
603
+ return { text: generated, notes: [] };
604
+ }
605
+ const normalized = existing.replaceAll("\r\n", "\n");
606
+ if (!/^\s*# mnci:(?:slot|phase) /m.test(normalized)) {
607
+ return {
608
+ text: generated,
609
+ notes: ['This pipeline was written before mnci kept user slots, so it was regenerated whole. Edits outside the generated steps are in git history: re-apply them inside the new "# mnci:slot" blocks.']
610
+ };
611
+ }
612
+ const off = switchedOffPhases(normalized);
613
+ const text = commentOutPhases(injectSlots(generated, extractSlots(normalized)), off);
614
+ return {
615
+ text,
616
+ notes: off.map((phase) => `The ${phase} phase is switched off in this pipeline and stays off.`)
617
+ };
430
618
  }
431
619
 
432
620
  // src/workspace-overlay/overlay.use-case.ts
@@ -569,9 +757,9 @@ var VSCODE_EXTENSION_TAG = "type:vscode-extension";
569
757
  var GO_RELEASE_TAG = "release:go";
570
758
  var GO_CGO_TAG = "build:cgo";
571
759
  function hasNativeGoApp(workspaceRoot) {
572
- return (0, import_node_fs4.globSync)("apps/*/project.json", { cwd: workspaceRoot }).some((projectJson) => {
760
+ return (0, import_node_fs5.globSync)("apps/*/project.json", { cwd: workspaceRoot }).some((projectJson) => {
573
761
  try {
574
- const { tags } = JSON.parse((0, import_node_fs4.readFileSync)((0, import_node_path3.join)(workspaceRoot, projectJson), "utf8"));
762
+ const { tags } = JSON.parse((0, import_node_fs5.readFileSync)((0, import_node_path4.join)(workspaceRoot, projectJson), "utf8"));
575
763
  return (tags ?? []).includes(GO_CGO_TAG);
576
764
  } catch {
577
765
  return false;
@@ -918,9 +1106,16 @@ function isUnmodifiedMnciEslintConfig(content) {
918
1106
  const code = content.split("\n").map((line) => line.trim()).filter((line) => line !== "" && !line.startsWith("//"));
919
1107
  return code.length === 2 && code[0] === "import mnci from '@mnci/eslint-config'" && code[1] === "export default mnci({ workspaceRoot: import.meta.dirname })";
920
1108
  }
1109
+ function writePipeline(path, onProgress, generated) {
1110
+ const { text, notes } = mergePipeline((0, import_node_fs5.existsSync)(path) ? (0, import_node_fs5.readFileSync)(path, "utf8") : void 0, generated);
1111
+ for (const note of notes) {
1112
+ onProgress(` ${note}`);
1113
+ }
1114
+ writeFileEnsured(path, text);
1115
+ }
921
1116
  function writeEslintEntryPoint(workspaceRoot, onProgress) {
922
- const path = (0, import_node_path3.join)(workspaceRoot, ESLINT_USER_FILENAME);
923
- if ((0, import_node_fs4.existsSync)(path) && !isUnmodifiedMnciEslintConfig((0, import_node_fs4.readFileSync)(path, "utf8"))) {
1117
+ const path = (0, import_node_path4.join)(workspaceRoot, ESLINT_USER_FILENAME);
1118
+ if ((0, import_node_fs5.existsSync)(path) && !isUnmodifiedMnciEslintConfig((0, import_node_fs5.readFileSync)(path, "utf8"))) {
924
1119
  onProgress(`${ESLINT_USER_FILENAME} \u2014 kept as it is, it is yours`);
925
1120
  return;
926
1121
  }
@@ -1088,7 +1283,7 @@ function mnciConfig(options) {
1088
1283
  };
1089
1284
  }
1090
1285
  function readMnciConfig(workspaceRoot) {
1091
- const nxJson = readJson((0, import_node_path3.join)(workspaceRoot, "nx.json"));
1286
+ const nxJson = readJson((0, import_node_path4.join)(workspaceRoot, "nx.json"));
1092
1287
  return nxJson.mnci ?? {};
1093
1288
  }
1094
1289
  function pythonPublishUrl(registry) {
@@ -1173,8 +1368,7 @@ var DOTNET_SDK_VERSION = "10.0.x";
1173
1368
  var DOTNET_DETECT_AZURE = `node -e "const fs=require('node:fs');const has=[...fs.globSync('apps/*/*.csproj'),...fs.globSync('packages/*/*.csproj'),...fs.globSync('libs/*/*.csproj')].length>0;console.log('##vso[task.setvariable variable=hasDotnetProjects]'+has)"`;
1174
1369
  var VERIFY_TARGETS = "lint,typecheck,test,build";
1175
1370
  var NATIVE_TARGETS = "lint,test,build-native,package-native";
1176
- var NATIVE_LINUX_PREREQUISITES = "sudo apt-get update && sudo apt-get install -y gcc pkg-config";
1177
- function githubNativeJob(npmAuthName, npmAuthValue) {
1371
+ function githubNativeJob(npmAuthName, npmAuthValue, runners) {
1178
1372
  return `
1179
1373
  # Apps that need a C toolchain (mnci add go-app --cgo) cannot be cross-compiled
1180
1374
  # from the job above, so each is linted, tested, built and packaged here, on a
@@ -1186,7 +1380,7 @@ function githubNativeJob(npmAuthName, npmAuthValue) {
1186
1380
  strategy:
1187
1381
  fail-fast: false
1188
1382
  matrix:
1189
- os: [windows-latest, macos-latest, ubuntu-latest]
1383
+ os: [${runners.join(", ")}]
1190
1384
  steps:
1191
1385
  - uses: actions/checkout@${ACTION_VERSIONS["actions/checkout"]}
1192
1386
  with:
@@ -1214,15 +1408,9 @@ function githubNativeJob(npmAuthName, npmAuthValue) {
1214
1408
  - run: npx mnci ci setup
1215
1409
  name: Set up the Go toolchain
1216
1410
 
1217
- # A C compiler and pkg-config, which is all mnci can know a cgo app needs.
1218
- # Add the -dev packages your app links to this line, for example
1219
- # libgtk-3-dev and libayatana-appindicator3-dev for a system-tray icon.
1220
- # macOS and Windows runners ship their toolchains.
1221
- - run: ${NATIVE_LINUX_PREREQUISITES}
1222
- name: Install native prerequisites (Linux)
1223
- if: \${{ runner.os == 'Linux' }}
1224
-
1225
- # Lints, tests, builds and packages the native apps on this OS. On a push to
1411
+ # Lints, tests, builds and packages the native apps on this OS. On a Linux leg it
1412
+ # first installs a C compiler, pkg-config and the packages of mnci.native.linuxPackages
1413
+ # in nx.json (for a tray icon: libgtk-3-dev, libayatana-appindicator3-dev). On a push to
1226
1414
  # main, a releasable native app (--cgo with --release) also gets this OS's zip
1227
1415
  # attached to the GitHub Release the ci job just created, stamped with the
1228
1416
  # tag's version.
@@ -1242,7 +1430,7 @@ function indentYaml(text, spaces) {
1242
1430
  const pad = " ".repeat(spaces);
1243
1431
  return text.split("\n").map((line) => line === "" ? line : pad + line).join("\n");
1244
1432
  }
1245
- function withAzureNativeJob(document, nativeSteps) {
1433
+ function withAzureNativeJob(document, nativeSteps, runners) {
1246
1434
  const poolAt = document.indexOf("\npool:\n");
1247
1435
  const variablesAt = document.indexOf("\nvariables:\n");
1248
1436
  const stepsAt = document.indexOf("\nsteps:\n");
@@ -1253,7 +1441,7 @@ function withAzureNativeJob(document, nativeSteps) {
1253
1441
  const pool2 = document.slice(poolAt + "\npool:\n".length, variablesAt).replace(/\n+$/, "");
1254
1442
  const variables = document.slice(variablesAt + 1, stepsAt).replace(/\n+$/, "");
1255
1443
  const steps = document.slice(stepsAt + "\nsteps:\n".length).replace(/\n+$/, "");
1256
- const matrix = Object.entries({ windows: "windows-latest", macos: "macos-latest", linux: "ubuntu-latest" }).map(([leg, image]) => ` ${leg}:
1444
+ const matrix = runners.map((image) => ({ leg: image.replaceAll(/\W/g, "_"), image })).map(({ leg, image }) => ` ${leg}:
1257
1445
  legName: ${leg}
1258
1446
  vmImage: ${image}`).join("\n");
1259
1447
  return `${head}${variables}
@@ -1292,7 +1480,7 @@ function npmAuthEnvVariable(registryKind, variableReference) {
1292
1480
  function poolBlock(agent) {
1293
1481
  return /^(?:ubuntu|windows|macos)-/i.test(agent) ? ` vmImage: ${agent}` : ` name: ${agent}`;
1294
1482
  }
1295
- function azurePipelinesYaml(agent, variableGroup, pythonPublishUrl2, registryKind = "azure-artifacts", nugetFeedUrl2, npmAuth = "pat", nativeApps = false) {
1483
+ function azurePipelinesYaml(agent, variableGroup, pythonPublishUrl2, registryKind = "azure-artifacts", nugetFeedUrl2, npmAuth = "pat", nativeApps = false, nativeRunners = DEFAULT_NATIVE_RUNNERS) {
1296
1484
  const onMain = "and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'), eq(variables['Build.SourceBranchName'], 'main'))";
1297
1485
  const [npmAuthName, npmAuthValue] = npmAuthEnvVariable(registryKind, (name) => `$(${name})`);
1298
1486
  const buildIdentity = npmAuth === "build-identity" && registryKind === "azure-artifacts";
@@ -1429,6 +1617,8 @@ steps:
1429
1617
  ${npmAuthenticateStep} - script: npm ci
1430
1618
  displayName: Install dependencies${npmCiEnv}
1431
1619
 
1620
+ ${slotMarkers("after-install", " ")}
1621
+
1432
1622
  # Everything from here to the release is a command of the mnci CLI, a
1433
1623
  # devDependency of this workspace, so the version is the lockfile's and a
1434
1624
  # developer reproduces CI by running the same line. The guards that used to be
@@ -1472,6 +1662,7 @@ ${npmAuthenticateStep} - script: npm ci
1472
1662
  - script: npx mnci ci verify
1473
1663
  displayName: Verify (sync check, then affected on a PR, every project on main)
1474
1664
 
1665
+ ${phaseStart("pack", " ")}
1475
1666
  # Pack every app into dist/drop/<type>-<name>.zip via each app's 'package'
1476
1667
  # target; skipped cleanly when the workspace has no apps yet.
1477
1668
  - script: npx mnci ci pack
@@ -1491,7 +1682,11 @@ ${npmAuthenticateStep} - script: npm ci
1491
1682
  - script: node -e "const fs=require('node:fs');const path=require('node:path');for(const f of fs.globSync('dist/drop/*.zip')){console.log('##vso[build.addbuildtag]'+path.basename(f,'.zip'))}"
1492
1683
  displayName: Tag the run per app (type-name)
1493
1684
  condition: ${onMain}
1685
+ ${phaseEnd("pack", " ")}
1686
+
1687
+ ${slotMarkers("before-release", " ")}
1494
1688
 
1689
+ ${phaseStart("release", " ")}
1495
1690
  # The release, in the order that keeps a failure safe: refuse a shallow
1496
1691
  # clone, prove the npm token and name the PyPI projects it would create (all
1497
1692
  # BEFORE anything is tagged), then version + tag + publish in one 'nx release'
@@ -1517,6 +1712,9 @@ ${npmAuthenticateStep} - script: npm ci
1517
1712
  # A VS Code extension publishes with it; tools/vscode-extension.cjs skips the
1518
1713
  # Marketplace when it is unset, including when Azure leaves it as '$(VSCE_PAT)'.
1519
1714
  VSCE_PAT: $(VSCE_PAT)
1715
+ ${phaseEnd("release", " ")}
1716
+
1717
+ ${slotMarkers("after-release", " ")}
1520
1718
  `;
1521
1719
  if (!nativeApps) {
1522
1720
  return document;
@@ -1544,14 +1742,9 @@ ${npmAuthenticateStep} - script: npm ci
1544
1742
  - script: npx mnci ci setup
1545
1743
  displayName: Set up the Go toolchain
1546
1744
 
1547
- # A C compiler and pkg-config, which is all mnci can know a cgo app needs. Add the
1548
- # -dev packages your app links to this line, for example libgtk-3-dev and
1549
- # libayatana-appindicator3-dev for a system-tray icon. macOS and Windows agents
1550
- # ship their toolchains.
1551
- - script: ${NATIVE_LINUX_PREREQUISITES}
1552
- displayName: Install native prerequisites (Linux)
1553
- condition: eq(variables['Agent.OS'], 'Linux')
1554
-
1745
+ # On a Linux leg this first installs a C compiler, pkg-config and the packages of
1746
+ # mnci.native.linuxPackages in nx.json (for a tray icon: libgtk-3-dev,
1747
+ # libayatana-appindicator3-dev). macOS and Windows agents ship their toolchains.
1555
1748
  - script: npx mnci ci native
1556
1749
  displayName: Lint, test, build and package the native apps
1557
1750
 
@@ -1561,9 +1754,9 @@ ${npmAuthenticateStep} - script: npm ci
1561
1754
  PathtoPublish: $(Build.SourcesDirectory)/dist/drop
1562
1755
  ArtifactName: native-$(legName)
1563
1756
  `;
1564
- return withAzureNativeJob(document, nativeSteps);
1757
+ return withAzureNativeJob(document, nativeSteps, nativeRunners);
1565
1758
  }
1566
- function githubActionsYaml(agent, pythonPublishUrl2, registryKind = "azure-artifacts", ci = "github", nugetFeedUrl2, nativeApps = false) {
1759
+ function githubActionsYaml(agent, pythonPublishUrl2, registryKind = "azure-artifacts", ci = "github", nugetFeedUrl2, nativeApps = false, nativeRunners = DEFAULT_NATIVE_RUNNERS) {
1567
1760
  const onMain = "github.event_name == 'push' && github.ref_name == 'main'";
1568
1761
  const [npmAuthName, npmAuthValue] = npmAuthEnvVariable(
1569
1762
  registryKind,
@@ -1643,6 +1836,8 @@ jobs:
1643
1836
  env:
1644
1837
  ${npmAuthName}: ${npmAuthValue}
1645
1838
 
1839
+ ${slotMarkers("after-install", " ".repeat(6))}
1840
+
1646
1841
  # Everything from here to the release is a command of the mnci CLI, a
1647
1842
  # devDependency of this workspace, so the version is the lockfile's and a
1648
1843
  # developer reproduces CI by running the same line. The guards that used to be
@@ -1682,6 +1877,7 @@ jobs:
1682
1877
  - run: npx mnci ci verify
1683
1878
  name: Verify (sync check, then affected on a PR, every project on main)
1684
1879
 
1880
+ ${phaseStart("pack", " ".repeat(6))}
1685
1881
  # Pack every app into dist/drop/<type>-<name>.zip via each app's 'package'
1686
1882
  # target; skipped cleanly when the workspace has no apps yet.
1687
1883
  - run: npx mnci ci pack
@@ -1694,7 +1890,11 @@ jobs:
1694
1890
  name: drop
1695
1891
  path: dist/drop
1696
1892
  if-no-files-found: ignore
1893
+ ${phaseEnd("pack", " ".repeat(6))}
1697
1894
 
1895
+ ${slotMarkers("before-release", " ".repeat(6))}
1896
+
1897
+ ${phaseStart("release", " ".repeat(6))}
1698
1898
  # Signs in to Microsoft Entra ID as the Marketplace publishing identity (an
1699
1899
  # app registration with a federated credential for this repository's main
1700
1900
  # branch), so the release step publishes VS Code extensions with
@@ -1739,7 +1939,10 @@ jobs:
1739
1939
  VSCE_PAT: \${{ secrets.VSCE_PAT }}${githubReleases ? `
1740
1940
  GITHUB_TOKEN: \${{ secrets.GITHUB_TOKEN }}
1741
1941
  GH_TOKEN: \${{ secrets.GITHUB_TOKEN }}` : ""}
1742
- ${nativeApps ? githubNativeJob(npmAuthName, npmAuthValue) : ""}`;
1942
+ ${phaseEnd("release", " ".repeat(6))}
1943
+
1944
+ ${slotMarkers("after-release", " ".repeat(6))}
1945
+ ${nativeApps ? githubNativeJob(npmAuthName, npmAuthValue, nativeRunners) : ""}`;
1743
1946
  }
1744
1947
  var PIP_PROJECT_GLOBS = ["apps", "python-packages", "libs"];
1745
1948
  var PUB_PROJECT_GLOBS = ["apps", "packages", "libs"];
@@ -1749,12 +1952,12 @@ var ECOSYSTEM_MANIFESTS = {
1749
1952
  };
1750
1953
  function hasEcosystemProject(workspaceRoot, roots, manifests) {
1751
1954
  return roots.some((root) => {
1752
- const base = (0, import_node_path3.join)(workspaceRoot, root);
1753
- if (!(0, import_node_fs4.existsSync)(base)) {
1955
+ const base = (0, import_node_path4.join)(workspaceRoot, root);
1956
+ if (!(0, import_node_fs5.existsSync)(base)) {
1754
1957
  return false;
1755
1958
  }
1756
- return (0, import_node_fs4.readdirSync)(base, { withFileTypes: true }).some(
1757
- (entry) => entry.isDirectory() && manifests.some((manifest) => (0, import_node_fs4.existsSync)((0, import_node_path3.join)(base, entry.name, manifest)))
1959
+ return (0, import_node_fs5.readdirSync)(base, { withFileTypes: true }).some(
1960
+ (entry) => entry.isDirectory() && manifests.some((manifest) => (0, import_node_fs5.existsSync)((0, import_node_path4.join)(base, entry.name, manifest)))
1758
1961
  );
1759
1962
  });
1760
1963
  }
@@ -1832,11 +2035,11 @@ var LOCAL_REGISTRY_SCAFFOLDING = {
1832
2035
  rootTarget: "local-registry"
1833
2036
  };
1834
2037
  function removeLocalRegistryScaffolding(workspaceRoot) {
1835
- (0, import_node_fs4.rmSync)((0, import_node_path3.join)(workspaceRoot, LOCAL_REGISTRY_SCAFFOLDING.directory), {
2038
+ (0, import_node_fs5.rmSync)((0, import_node_path4.join)(workspaceRoot, LOCAL_REGISTRY_SCAFFOLDING.directory), {
1836
2039
  recursive: true,
1837
2040
  force: true
1838
2041
  });
1839
- const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2042
+ const manifestPath = (0, import_node_path4.join)(workspaceRoot, "package.json");
1840
2043
  if (!fileExists(manifestPath)) return;
1841
2044
  const manifest = readJson(manifestPath);
1842
2045
  if (manifest.devDependencies?.[LOCAL_REGISTRY_SCAFFOLDING.devDependency] !== void 0) {
@@ -1852,23 +2055,23 @@ function removeLocalRegistryScaffolding(workspaceRoot) {
1852
2055
  }
1853
2056
  function removeNxScaffolding(workspaceRoot) {
1854
2057
  for (const entry of NX_SCAFFOLDING_TO_REMOVE) {
1855
- (0, import_node_fs4.rmSync)((0, import_node_path3.join)(workspaceRoot, entry), { recursive: true, force: true });
2058
+ (0, import_node_fs5.rmSync)((0, import_node_path4.join)(workspaceRoot, entry), { recursive: true, force: true });
1856
2059
  }
1857
2060
  removeNxAuthoredAgentFiles(workspaceRoot);
1858
2061
  removeProjectEslintConfigs(workspaceRoot);
1859
2062
  }
1860
2063
  function removeNxAuthoredAgentFiles(workspaceRoot) {
1861
- (0, import_node_fs4.rmSync)((0, import_node_path3.join)(workspaceRoot, NX_CLAUDE_SETTINGS), { force: true });
1862
- const claudeDirectory = (0, import_node_path3.join)(workspaceRoot, (0, import_node_path3.dirname)(NX_CLAUDE_SETTINGS));
1863
- if ((0, import_node_fs4.existsSync)(claudeDirectory) && (0, import_node_fs4.readdirSync)(claudeDirectory).length === 0) {
1864
- (0, import_node_fs4.rmSync)(claudeDirectory, { recursive: true, force: true });
2064
+ (0, import_node_fs5.rmSync)((0, import_node_path4.join)(workspaceRoot, NX_CLAUDE_SETTINGS), { force: true });
2065
+ const claudeDirectory = (0, import_node_path4.join)(workspaceRoot, (0, import_node_path4.dirname)(NX_CLAUDE_SETTINGS));
2066
+ if ((0, import_node_fs5.existsSync)(claudeDirectory) && (0, import_node_fs5.readdirSync)(claudeDirectory).length === 0) {
2067
+ (0, import_node_fs5.rmSync)(claudeDirectory, { recursive: true, force: true });
1865
2068
  }
1866
2069
  for (const name of NX_AUTHORED_AGENT_FILES) {
1867
- const path = (0, import_node_path3.join)(workspaceRoot, name);
1868
- if (!(0, import_node_fs4.existsSync)(path)) continue;
1869
- const kept = withoutNxAgentRules((0, import_node_fs4.readFileSync)(path, "utf8"));
2070
+ const path = (0, import_node_path4.join)(workspaceRoot, name);
2071
+ if (!(0, import_node_fs5.existsSync)(path)) continue;
2072
+ const kept = withoutNxAgentRules((0, import_node_fs5.readFileSync)(path, "utf8"));
1870
2073
  if (kept === void 0) continue;
1871
- if (kept.trim() === "") (0, import_node_fs4.rmSync)(path, { force: true });
2074
+ if (kept.trim() === "") (0, import_node_fs5.rmSync)(path, { force: true });
1872
2075
  else writeFileEnsured(path, kept);
1873
2076
  }
1874
2077
  }
@@ -1883,14 +2086,14 @@ function withoutNxAgentRules(content) {
1883
2086
  return `${content.slice(0, start)}${rest}`.replace(/^[\r\n]+/, "");
1884
2087
  }
1885
2088
  function removeIfPresent(path) {
1886
- (0, import_node_fs4.rmSync)(path, { recursive: true, force: true });
2089
+ (0, import_node_fs5.rmSync)(path, { recursive: true, force: true });
1887
2090
  }
1888
2091
  function ensureEslintCacheIgnored(workspaceRoot) {
1889
- const gitignorePath = (0, import_node_path3.join)(workspaceRoot, ".gitignore");
2092
+ const gitignorePath = (0, import_node_path4.join)(workspaceRoot, ".gitignore");
1890
2093
  if (!fileExists(gitignorePath)) {
1891
2094
  return;
1892
2095
  }
1893
- const current = (0, import_node_fs4.readFileSync)(gitignorePath, "utf8");
2096
+ const current = (0, import_node_fs5.readFileSync)(gitignorePath, "utf8");
1894
2097
  if (current.split("\n").some((line) => line.trim() === ".eslintcache")) {
1895
2098
  return;
1896
2099
  }
@@ -1905,18 +2108,18 @@ function ensureEslintCacheIgnored(workspaceRoot) {
1905
2108
  }
1906
2109
  var PYTHON_ARTEFACT_IGNORES = ["__pycache__/", "*.py[cod]"];
1907
2110
  function ensurePythonArtefactsIgnored(workspaceRoot) {
1908
- const gitignorePath = (0, import_node_path3.join)(workspaceRoot, ".gitignore");
2111
+ const gitignorePath = (0, import_node_path4.join)(workspaceRoot, ".gitignore");
1909
2112
  if (!fileExists(gitignorePath)) {
1910
2113
  return;
1911
2114
  }
1912
- const hasPython = (0, import_node_fs4.globSync)(
2115
+ const hasPython = (0, import_node_fs5.globSync)(
1913
2116
  ["python-packages/*/pyproject.toml", "apps/*/pyproject.toml", "libs/*/pyproject.toml"],
1914
2117
  { cwd: workspaceRoot }
1915
2118
  ).length > 0;
1916
2119
  if (!hasPython) {
1917
2120
  return;
1918
2121
  }
1919
- const current = (0, import_node_fs4.readFileSync)(gitignorePath, "utf8");
2122
+ const current = (0, import_node_fs5.readFileSync)(gitignorePath, "utf8");
1920
2123
  const present = new Set(current.split("\n").map((line) => line.trim()));
1921
2124
  const missing = PYTHON_ARTEFACT_IGNORES.filter((line) => !present.has(line));
1922
2125
  if (missing.length === 0) {
@@ -1936,16 +2139,16 @@ ${missing.join("\n")}
1936
2139
  );
1937
2140
  }
1938
2141
  function removeProjectEslintConfigs(workspaceRoot) {
1939
- const matches = (0, import_node_fs4.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
2142
+ const matches = (0, import_node_fs5.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
1940
2143
  cwd: workspaceRoot
1941
2144
  });
1942
2145
  for (const match of matches) {
1943
- (0, import_node_fs4.rmSync)((0, import_node_path3.join)(workspaceRoot, match), { force: true });
2146
+ (0, import_node_fs5.rmSync)((0, import_node_path4.join)(workspaceRoot, match), { force: true });
1944
2147
  }
1945
2148
  }
1946
2149
  function applyOverlay(workspaceRoot, options, onProgress = () => {
1947
2150
  }) {
1948
- const nxJsonPath = (0, import_node_path3.join)(workspaceRoot, "nx.json");
2151
+ const nxJsonPath = (0, import_node_path4.join)(workspaceRoot, "nx.json");
1949
2152
  const nxJson = readJson(nxJsonPath);
1950
2153
  const generators = {
1951
2154
  ...nxJson.generators,
@@ -1953,7 +2156,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
1953
2156
  };
1954
2157
  const sync = { ...nxJson.sync, ...SYNC_CONFIG };
1955
2158
  const mnci = { ...nxJson.mnci, ...mnciConfig(options) };
1956
- const rootManifest = readJson((0, import_node_path3.join)(workspaceRoot, "package.json"));
2159
+ const rootManifest = readJson((0, import_node_path4.join)(workspaceRoot, "package.json"));
1957
2160
  const hasPythonPlugin = (rootManifest.devDependencies ?? {})["@mnci/nx-python-pip"] !== void 0 || (rootManifest.dependencies ?? {})["@mnci/nx-python-pip"] !== void 0;
1958
2161
  const withRelease = withReleaseConfig(nxJson, options.ci);
1959
2162
  const patched = withPythonGraphPlugin(
@@ -1963,7 +2166,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
1963
2166
  onProgress("nx.json \u2014 release, sync, generators, shared inputs, mnci block");
1964
2167
  writeFileEnsured(nxJsonPath, toJson({ ...patched, generators, sync, mnci }));
1965
2168
  onProgress("package.json \u2014 root scripts, TS compilers, ESLint toolchain, overrides");
1966
- const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2169
+ const manifestPath = (0, import_node_path4.join)(workspaceRoot, "package.json");
1967
2170
  const manifest = readJson(manifestPath);
1968
2171
  const scripts = {
1969
2172
  ...manifest.scripts,
@@ -2015,32 +2218,32 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2015
2218
  `.npmrc \u2014 ${options.registry.kind === "azure-artifacts" ? "Azure Artifacts feed routing and credentials" : "public npm registry auth"}`
2016
2219
  );
2017
2220
  writeFileEnsured(
2018
- (0, import_node_path3.join)(workspaceRoot, ".npmrc"),
2221
+ (0, import_node_path4.join)(workspaceRoot, ".npmrc"),
2019
2222
  npmrcContent(options.registry, options.scope, options.npmAuth)
2020
2223
  );
2021
2224
  onProgress("commitlint.config.mjs and .husky/commit-msg \u2014 conventional commit enforcement");
2022
- writeFileEnsured((0, import_node_path3.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
2023
- const hookPath = (0, import_node_path3.join)(workspaceRoot, ".husky/commit-msg");
2225
+ writeFileEnsured((0, import_node_path4.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
2226
+ const hookPath = (0, import_node_path4.join)(workspaceRoot, ".husky/commit-msg");
2024
2227
  writeFileEnsured(hookPath, COMMIT_MSG_HOOK);
2025
2228
  markExecutable(hookPath);
2026
2229
  onProgress(`${ESLINT_MNCI_FILENAME} \u2014 the shared lint AND formatting opinion`);
2027
- writeFileEnsured((0, import_node_path3.join)(workspaceRoot, ESLINT_MNCI_FILENAME), ESLINT_MNCI_CONFIG);
2230
+ writeFileEnsured((0, import_node_path4.join)(workspaceRoot, ESLINT_MNCI_FILENAME), ESLINT_MNCI_CONFIG);
2028
2231
  writeEslintEntryPoint(workspaceRoot, onProgress);
2029
2232
  ensureEslintCacheIgnored(workspaceRoot);
2030
2233
  ensurePythonArtefactsIgnored(workspaceRoot);
2031
2234
  for (const retired of RETIRED_FORMATTER_FILES) {
2032
- removeIfPresent((0, import_node_path3.join)(workspaceRoot, retired));
2235
+ removeIfPresent((0, import_node_path4.join)(workspaceRoot, retired));
2033
2236
  }
2034
2237
  onProgress(".devcontainer/devcontainer.json \u2014 a local toolchain matching CI");
2035
2238
  writeFileEnsured(
2036
- (0, import_node_path3.join)(workspaceRoot, ".devcontainer/devcontainer.json"),
2239
+ (0, import_node_path4.join)(workspaceRoot, ".devcontainer/devcontainer.json"),
2037
2240
  devcontainerJson(options.workspaceName)
2038
2241
  );
2039
2242
  removeNxScaffolding(workspaceRoot);
2040
2243
  onProgress(
2041
2244
  `${options.workspaceName}.code-workspace \u2014 settings, extensions, launch configs`
2042
2245
  );
2043
- const codeWorkspacePath = (0, import_node_path3.join)(workspaceRoot, `${options.workspaceName}.code-workspace`);
2246
+ const codeWorkspacePath = (0, import_node_path4.join)(workspaceRoot, `${options.workspaceName}.code-workspace`);
2044
2247
  const existing = readCodeWorkspace(codeWorkspacePath);
2045
2248
  writeFileEnsured(
2046
2249
  codeWorkspacePath,
@@ -2052,15 +2255,17 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2052
2255
  )
2053
2256
  );
2054
2257
  if (options.workspaceName !== "undefined") {
2055
- (0, import_node_fs4.rmSync)((0, import_node_path3.join)(workspaceRoot, "undefined.code-workspace"), { force: true });
2258
+ (0, import_node_fs5.rmSync)((0, import_node_path4.join)(workspaceRoot, "undefined.code-workspace"), { force: true });
2056
2259
  }
2057
2260
  const publishUrl = pythonPublishUrl(options.registry);
2058
2261
  const nugetUrl = nugetFeedUrl(options.registry);
2059
2262
  const nativeApps = hasNativeGoApp(workspaceRoot);
2263
+ const nativeRunners = readNativeBuildConfig(workspaceRoot).config.runners;
2060
2264
  if (options.ci === "azure" || options.ci === "both") {
2061
2265
  onProgress("azure-pipelines.yml \u2014 build, verify, pack and release");
2062
- writeFileEnsured(
2063
- (0, import_node_path3.join)(workspaceRoot, "azure-pipelines.yml"),
2266
+ writePipeline(
2267
+ (0, import_node_path4.join)(workspaceRoot, "azure-pipelines.yml"),
2268
+ onProgress,
2064
2269
  azurePipelinesYaml(
2065
2270
  options.agent,
2066
2271
  options.variableGroup,
@@ -2068,17 +2273,19 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2068
2273
  options.registry.kind,
2069
2274
  nugetUrl,
2070
2275
  options.npmAuth,
2071
- nativeApps
2276
+ nativeApps,
2277
+ nativeRunners
2072
2278
  )
2073
2279
  );
2074
2280
  }
2075
2281
  if (options.ci === "github" || options.ci === "both") {
2076
2282
  onProgress(".github/workflows/ci.yml and dependabot.yml");
2077
- writeFileEnsured(
2078
- (0, import_node_path3.join)(workspaceRoot, ".github/workflows/ci.yml"),
2079
- githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci, nugetUrl, nativeApps)
2283
+ writePipeline(
2284
+ (0, import_node_path4.join)(workspaceRoot, ".github/workflows/ci.yml"),
2285
+ onProgress,
2286
+ githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci, nugetUrl, nativeApps, nativeRunners)
2080
2287
  );
2081
- writeFileEnsured((0, import_node_path3.join)(workspaceRoot, ".github/dependabot.yml"), dependabotConfig(workspaceRoot));
2288
+ writeFileEnsured((0, import_node_path4.join)(workspaceRoot, ".github/dependabot.yml"), dependabotConfig(workspaceRoot));
2082
2289
  }
2083
2290
  }
2084
2291
 
@@ -2102,30 +2309,47 @@ function runNative(workspaceRoot, dependencies = {}) {
2102
2309
  }
2103
2310
  return status;
2104
2311
  };
2312
+ if (isLinuxAgent(environment)) {
2313
+ const prerequisites = installLinuxPrerequisites(workspaceRoot, inGroup);
2314
+ if (prerequisites !== 0) {
2315
+ return prerequisites;
2316
+ }
2317
+ }
2105
2318
  const built = inGroup("Lint, test, build and package the native apps", "npx", ["nx", "run-many", "-t", NATIVE_TARGETS, `--projects=tag:${GO_CGO_TAG}`]);
2106
2319
  if (built !== 0) {
2107
2320
  return built;
2108
2321
  }
2109
- if (host !== "github" || !isMainPush(environment) || !(0, import_node_fs5.existsSync)((0, import_node_path4.join)(workspaceRoot, "tools", "go-app-release.cjs"))) {
2322
+ if (host !== "github" || !isMainPush(environment) || !(0, import_node_fs6.existsSync)((0, import_node_path5.join)(workspaceRoot, "tools", "go-app-release.cjs"))) {
2110
2323
  return 0;
2111
2324
  }
2112
2325
  return inGroup("Attach this OS's zip to the GitHub Release", "node", ["tools/go-app-release.cjs", "assets", "--native"]);
2113
2326
  }
2327
+ function isLinuxAgent(environment) {
2328
+ return environment.RUNNER_OS === "Linux" || environment.AGENT_OS === "Linux";
2329
+ }
2330
+ function installLinuxPrerequisites(workspaceRoot, inGroup) {
2331
+ const { linuxPackages } = readNativeBuildConfig(workspaceRoot).config;
2332
+ const updated = inGroup("Update the package index", "sudo", ["apt-get", "update"]);
2333
+ if (updated !== 0) {
2334
+ return updated;
2335
+ }
2336
+ return inGroup("Install the native prerequisites (Linux)", "sudo", ["apt-get", "install", "-y", "gcc", "pkg-config", ...linuxPackages]);
2337
+ }
2114
2338
 
2115
2339
  // src/ci-pipeline/pack.use-case.ts
2116
- var import_node_fs6 = require("fs");
2117
- var import_node_path5 = require("path");
2340
+ var import_node_fs7 = require("fs");
2341
+ var import_node_path6 = require("path");
2118
2342
  function hasAppToPack(workspaceRoot) {
2119
- const hasProjectJson = (0, import_node_fs6.globSync)("apps/*/project.json", { cwd: workspaceRoot }).length > 0;
2120
- const hasInlineNx = (0, import_node_fs6.globSync)("apps/*/package.json", { cwd: workspaceRoot }).some((manifest) => {
2343
+ const hasProjectJson = (0, import_node_fs7.globSync)("apps/*/project.json", { cwd: workspaceRoot }).length > 0;
2344
+ const hasInlineNx = (0, import_node_fs7.globSync)("apps/*/package.json", { cwd: workspaceRoot }).some((manifest) => {
2121
2345
  try {
2122
- const parsed = JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path5.join)(workspaceRoot, manifest), "utf8"));
2346
+ const parsed = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, manifest), "utf8"));
2123
2347
  return Boolean(parsed.nx);
2124
2348
  } catch {
2125
2349
  return false;
2126
2350
  }
2127
2351
  });
2128
- const hasCsproj = (0, import_node_fs6.globSync)("apps/*/*.csproj", { cwd: workspaceRoot }).length > 0;
2352
+ const hasCsproj = (0, import_node_fs7.globSync)("apps/*/*.csproj", { cwd: workspaceRoot }).length > 0;
2129
2353
  return hasProjectJson || hasInlineNx || hasCsproj;
2130
2354
  }
2131
2355
  function runPack(workspaceRoot, dependencies = {}) {
@@ -2138,7 +2362,7 @@ function runPack(workspaceRoot, dependencies = {}) {
2138
2362
  console.log(message);
2139
2363
  });
2140
2364
  const host = detectCiHost(environment);
2141
- (0, import_node_fs6.mkdirSync)((0, import_node_path5.join)(workspaceRoot, "dist", "drop"), { recursive: true });
2365
+ (0, import_node_fs7.mkdirSync)((0, import_node_path6.join)(workspaceRoot, "dist", "drop"), { recursive: true });
2142
2366
  if (!hasAppToPack(workspaceRoot)) {
2143
2367
  log("No apps to pack - skipping.");
2144
2368
  return 0;
@@ -2153,12 +2377,12 @@ function runPack(workspaceRoot, dependencies = {}) {
2153
2377
  }
2154
2378
 
2155
2379
  // src/ci-pipeline/release.use-case.ts
2156
- var import_node_fs7 = require("fs");
2157
- var import_node_path6 = require("path");
2380
+ var import_node_fs8 = require("fs");
2381
+ var import_node_path7 = require("path");
2158
2382
  var SPECIFIER = /^(?:major|minor|patch|\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/;
2159
2383
  function hasTag(workspaceRoot, relativePath, tag) {
2160
2384
  try {
2161
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, relativePath), "utf8"));
2385
+ const parsed = JSON.parse((0, import_node_fs8.readFileSync)((0, import_node_path7.join)(workspaceRoot, relativePath), "utf8"));
2162
2386
  const tags = relativePath.endsWith("project.json") ? parsed.tags : parsed.nx?.tags;
2163
2387
  return Array.isArray(tags) && tags.includes(tag);
2164
2388
  } catch {
@@ -2167,12 +2391,12 @@ function hasTag(workspaceRoot, relativePath, tag) {
2167
2391
  }
2168
2392
  function releasableCounts(workspaceRoot) {
2169
2393
  return {
2170
- npm: (0, import_node_fs7.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length,
2171
- csharp: (0, import_node_fs7.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }).length,
2172
- python: (0, import_node_fs7.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot }).length,
2173
- dart: (0, import_node_fs7.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }).length,
2174
- vscode: (0, import_node_fs7.globSync)("apps/*/package.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, VSCODE_EXTENSION_TAG)).length,
2175
- go: (0, import_node_fs7.globSync)("apps/*/project.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, GO_RELEASE_TAG)).length
2394
+ npm: (0, import_node_fs8.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length,
2395
+ csharp: (0, import_node_fs8.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }).length,
2396
+ python: (0, import_node_fs8.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot }).length,
2397
+ dart: (0, import_node_fs8.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }).length,
2398
+ vscode: (0, import_node_fs8.globSync)("apps/*/package.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, VSCODE_EXTENSION_TAG)).length,
2399
+ go: (0, import_node_fs8.globSync)("apps/*/project.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, GO_RELEASE_TAG)).length
2176
2400
  };
2177
2401
  }
2178
2402
  function shallowCloneGuard(processes, log) {
@@ -2188,7 +2412,7 @@ function shallowCloneGuard(processes, log) {
2188
2412
  return 0;
2189
2413
  }
2190
2414
  function npmPreflight(workspaceRoot, registryKind, environment, processes, log) {
2191
- if (registryKind !== "npm" || (0, import_node_fs7.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length === 0) {
2415
+ if (registryKind !== "npm" || (0, import_node_fs8.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length === 0) {
2192
2416
  return 0;
2193
2417
  }
2194
2418
  if (!environment.NODE_AUTH_TOKEN) {
@@ -2204,7 +2428,7 @@ function npmPreflight(workspaceRoot, registryKind, environment, processes, log)
2204
2428
  return 0;
2205
2429
  }
2206
2430
  async function pypiPreflight(workspaceRoot, registryKind, environment, log, fetchStatus) {
2207
- const files = (0, import_node_fs7.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot });
2431
+ const files = (0, import_node_fs8.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot });
2208
2432
  if (registryKind !== "npm" || files.length === 0) {
2209
2433
  return 0;
2210
2434
  }
@@ -2217,7 +2441,7 @@ async function pypiPreflight(workspaceRoot, registryKind, environment, log, fetc
2217
2441
  return 1;
2218
2442
  }
2219
2443
  const names = files.map((file) => {
2220
- const text = (0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, file), "utf8");
2444
+ const text = (0, import_node_fs8.readFileSync)((0, import_node_path7.join)(workspaceRoot, file), "utf8");
2221
2445
  const block = text.slice(text.indexOf("[project]"));
2222
2446
  const line = block.split("\n").find((entry) => entry.trimStart().startsWith("name"));
2223
2447
  return line ? line.split("=", 2)[1].replaceAll(/[^\w.-]/gi, "") : "";
@@ -2292,14 +2516,14 @@ function runReleaseCommand(workspaceRoot, registry, counts, environment, process
2292
2516
  }
2293
2517
  function nxPushesTags(workspaceRoot) {
2294
2518
  try {
2295
- const nx = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, "nx.json"), "utf8"));
2519
+ const nx = JSON.parse((0, import_node_fs8.readFileSync)((0, import_node_path7.join)(workspaceRoot, "nx.json"), "utf8"));
2296
2520
  return nx.release?.git?.push === true;
2297
2521
  } catch {
2298
2522
  return false;
2299
2523
  }
2300
2524
  }
2301
2525
  function afterRelease(workspaceRoot, processes, githubReleases) {
2302
- if (githubReleases && (0, import_node_fs7.existsSync)((0, import_node_path6.join)(workspaceRoot, "tools", "go-app-release.cjs"))) {
2526
+ if (githubReleases && (0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "tools", "go-app-release.cjs"))) {
2303
2527
  const assets = processes.run("node", ["tools/go-app-release.cjs", "assets"]);
2304
2528
  if (assets !== 0) {
2305
2529
  return assets;
@@ -2350,17 +2574,17 @@ async function runRelease(workspaceRoot, dependencies = {}) {
2350
2574
  }
2351
2575
 
2352
2576
  // src/ci-pipeline/setup.use-case.ts
2353
- var import_node_fs10 = require("fs");
2354
- var import_node_path9 = require("path");
2577
+ var import_node_fs11 = require("fs");
2578
+ var import_node_path10 = require("path");
2355
2579
 
2356
2580
  // src/ci-pipeline/flutter-sdk.use-case.ts
2357
- var import_node_fs8 = require("fs");
2358
- var import_node_path7 = require("path");
2581
+ var import_node_fs9 = require("fs");
2582
+ var import_node_path8 = require("path");
2359
2583
  function flutterSdkDirectory(machine) {
2360
- return (0, import_node_path7.join)(machine.home, `.mnci-flutter-${FLUTTER_SDK_VERSION}`);
2584
+ return (0, import_node_path8.join)(machine.home, `.mnci-flutter-${FLUTTER_SDK_VERSION}`);
2361
2585
  }
2362
2586
  function installFlutterSdk(workspaceRoot, processes, log, machine) {
2363
- if (!(0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "pubspec.yaml"))) {
2587
+ if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "pubspec.yaml"))) {
2364
2588
  log("No Flutter projects - skipping.");
2365
2589
  return 0;
2366
2590
  }
@@ -2369,26 +2593,26 @@ function installFlutterSdk(workspaceRoot, processes, log, machine) {
2369
2593
  return 0;
2370
2594
  }
2371
2595
  const sdk = flutterSdkDirectory(machine);
2372
- if ((0, import_node_fs8.existsSync)(sdk)) {
2596
+ if ((0, import_node_fs9.existsSync)(sdk)) {
2373
2597
  log(`Flutter SDK already installed at ${sdk} - skipping.`);
2374
2598
  return 0;
2375
2599
  }
2376
2600
  return processes.run("git", ["clone", "--depth", "1", "--branch", FLUTTER_SDK_VERSION, "https://github.com/flutter/flutter.git", sdk]);
2377
2601
  }
2378
2602
  function publishFlutterSdk(workspaceRoot, host, environment, log, machine) {
2379
- if (!(0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "pubspec.yaml"))) {
2603
+ if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "pubspec.yaml"))) {
2380
2604
  log("No Flutter projects - skipping.");
2381
2605
  return;
2382
2606
  }
2383
2607
  const sdk = flutterSdkDirectory(machine);
2384
- if (!(0, import_node_fs8.existsSync)(sdk)) {
2608
+ if (!(0, import_node_fs9.existsSync)(sdk)) {
2385
2609
  log("Flutter SDK was not installed by mnci (already on PATH) - skipping.");
2386
2610
  return;
2387
2611
  }
2388
- addToPath(host, environment, (0, import_node_path7.join)(sdk, "bin"), log);
2612
+ addToPath(host, environment, (0, import_node_path8.join)(sdk, "bin"), log);
2389
2613
  }
2390
2614
  function resolveDartDependencies(workspaceRoot, processes, log) {
2391
- if (!(0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "pubspec.yaml"))) {
2615
+ if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "pubspec.yaml"))) {
2392
2616
  log("No Flutter projects - skipping.");
2393
2617
  return 0;
2394
2618
  }
@@ -2397,15 +2621,15 @@ function resolveDartDependencies(workspaceRoot, processes, log) {
2397
2621
 
2398
2622
  // src/ci-pipeline/go-tools.use-case.ts
2399
2623
  var import_node_crypto = require("crypto");
2400
- var import_node_fs9 = require("fs");
2624
+ var import_node_fs10 = require("fs");
2401
2625
  var import_node_os = require("os");
2402
- var import_node_path8 = require("path");
2626
+ var import_node_path9 = require("path");
2403
2627
  function currentMachine() {
2404
2628
  return { platform: process.platform, architecture: process.arch, home: (0, import_node_os.homedir)() };
2405
2629
  }
2406
2630
  var GOLANGCI_LINT_MODULE = "github.com/golangci/golangci-lint/v2/cmd/golangci-lint";
2407
2631
  function downloadGoModules(workspaceRoot, processes, log) {
2408
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
2632
+ if (!(0, import_node_fs10.existsSync)((0, import_node_path9.join)(workspaceRoot, "go.mod"))) {
2409
2633
  log("No Go projects - skipping.");
2410
2634
  return 0;
2411
2635
  }
@@ -2413,7 +2637,7 @@ function downloadGoModules(workspaceRoot, processes, log) {
2413
2637
  }
2414
2638
  async function installGolangciLint(workspaceRoot, dependencies, machine) {
2415
2639
  const { processes, log, fetchBytes } = dependencies;
2416
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
2640
+ if (!(0, import_node_fs10.existsSync)((0, import_node_path9.join)(workspaceRoot, "go.mod"))) {
2417
2641
  log("No Go projects - skipping.");
2418
2642
  return 0;
2419
2643
  }
@@ -2450,30 +2674,30 @@ async function installGolangciLint(workspaceRoot, dependencies, machine) {
2450
2674
  if ((0, import_node_crypto.createHash)("sha256").update(archive).digest("hex") !== entry[0]) {
2451
2675
  throw new Error(`checksum mismatch for ${file}`);
2452
2676
  }
2453
- temporary = (0, import_node_fs9.mkdtempSync)((0, import_node_path8.join)((0, import_node_os.tmpdir)(), "golangci-lint-"));
2454
- const archivePath = (0, import_node_path8.join)(temporary, file);
2455
- (0, import_node_fs9.writeFileSync)(archivePath, archive);
2456
- const tar = platform === "windows" ? (0, import_node_path8.join)(process.env.SystemRoot ?? "", "System32", "tar.exe") : "tar";
2677
+ temporary = (0, import_node_fs10.mkdtempSync)((0, import_node_path9.join)((0, import_node_os.tmpdir)(), "golangci-lint-"));
2678
+ const archivePath = (0, import_node_path9.join)(temporary, file);
2679
+ (0, import_node_fs10.writeFileSync)(archivePath, archive);
2680
+ const tar = platform === "windows" ? (0, import_node_path9.join)(process.env.SystemRoot ?? "", "System32", "tar.exe") : "tar";
2457
2681
  if (processes.run(tar, ["-xf", archivePath, "-C", temporary]) !== 0) {
2458
2682
  throw new Error(`could not extract ${file}`);
2459
2683
  }
2460
2684
  const executable = `golangci-lint${platform === "windows" ? ".exe" : ""}`;
2461
- const bin = (0, import_node_path8.join)(gopath.stdout.trim(), "bin");
2462
- (0, import_node_fs9.mkdirSync)(bin, { recursive: true });
2463
- (0, import_node_fs9.copyFileSync)((0, import_node_path8.join)(temporary, name, executable), (0, import_node_path8.join)(bin, executable));
2464
- (0, import_node_fs9.chmodSync)((0, import_node_path8.join)(bin, executable), 493);
2685
+ const bin = (0, import_node_path9.join)(gopath.stdout.trim(), "bin");
2686
+ (0, import_node_fs10.mkdirSync)(bin, { recursive: true });
2687
+ (0, import_node_fs10.copyFileSync)((0, import_node_path9.join)(temporary, name, executable), (0, import_node_path9.join)(bin, executable));
2688
+ (0, import_node_fs10.chmodSync)((0, import_node_path9.join)(bin, executable), 493);
2465
2689
  log(`golangci-lint ${version} installed from its checksum-verified prebuilt release into ${bin}`);
2466
2690
  return 0;
2467
2691
  } catch (error) {
2468
2692
  return fallback(error instanceof Error ? error.message : String(error));
2469
2693
  } finally {
2470
2694
  if (temporary !== void 0) {
2471
- (0, import_node_fs9.rmSync)(temporary, { recursive: true, force: true });
2695
+ (0, import_node_fs10.rmSync)(temporary, { recursive: true, force: true });
2472
2696
  }
2473
2697
  }
2474
2698
  }
2475
2699
  function publishGoTools(workspaceRoot, host, environment, processes, log) {
2476
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
2700
+ if (!(0, import_node_fs10.existsSync)((0, import_node_path9.join)(workspaceRoot, "go.mod"))) {
2477
2701
  log("No Go projects - skipping.");
2478
2702
  return;
2479
2703
  }
@@ -2482,7 +2706,7 @@ function publishGoTools(workspaceRoot, host, environment, processes, log) {
2482
2706
  log("Could not resolve GOPATH - skipping.");
2483
2707
  return;
2484
2708
  }
2485
- addToPath(host, environment, (0, import_node_path8.join)(gopath.stdout.trim(), "bin"), log);
2709
+ addToPath(host, environment, (0, import_node_path9.join)(gopath.stdout.trim(), "bin"), log);
2486
2710
  }
2487
2711
 
2488
2712
  // src/ci-pipeline/setup.use-case.ts
@@ -2490,15 +2714,15 @@ function pythonCommand(machine) {
2490
2714
  return machine.platform === "win32" ? "python" : "python3";
2491
2715
  }
2492
2716
  function installPythonToolchain(workspaceRoot, processes, log, machine) {
2493
- if (!(0, import_node_fs10.existsSync)((0, import_node_path9.join)(workspaceRoot, "requirements-dev.txt"))) {
2717
+ if (!(0, import_node_fs11.existsSync)((0, import_node_path10.join)(workspaceRoot, "requirements-dev.txt"))) {
2494
2718
  log("No Python projects - skipping.");
2495
2719
  return 0;
2496
2720
  }
2497
2721
  return processes.run(pythonCommand(machine), ["-m", "pip", "install", "-r", "requirements-dev.txt"]);
2498
2722
  }
2499
2723
  function installPythonProjects(workspaceRoot, processes, log, machine) {
2500
- const editable = ["apps/*/pyproject.toml", "python-packages/*/pyproject.toml", "libs/*/pyproject.toml"].flatMap((pattern) => (0, import_node_fs10.globSync)(pattern, { cwd: workspaceRoot })).map((path) => (0, import_node_path9.dirname)(path));
2501
- const requirements = (0, import_node_fs10.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot });
2724
+ const editable = ["apps/*/pyproject.toml", "python-packages/*/pyproject.toml", "libs/*/pyproject.toml"].flatMap((pattern) => (0, import_node_fs11.globSync)(pattern, { cwd: workspaceRoot })).map((path) => (0, import_node_path10.dirname)(path));
2725
+ const requirements = (0, import_node_fs11.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot });
2502
2726
  if (editable.length === 0 && requirements.length === 0) {
2503
2727
  log("No Python projects - skipping.");
2504
2728
  return 0;
@@ -2640,7 +2864,7 @@ function runCiPhase(phase, workspaceRoot, dependencies = {}) {
2640
2864
  }
2641
2865
 
2642
2866
  // src/project-scaffolding/add-project.use-case.ts
2643
- var import_node_path30 = require("path");
2867
+ var import_node_path31 = require("path");
2644
2868
  var import_prompts3 = require("@inquirer/prompts");
2645
2869
 
2646
2870
  // src/project-name/project-name.validator.ts
@@ -2653,8 +2877,8 @@ function assertValidProjectName(name, label) {
2653
2877
  }
2654
2878
 
2655
2879
  // src/project-scaffolding/csharp.use-case.ts
2656
- var import_node_fs12 = require("fs");
2657
- var import_node_path11 = require("path");
2880
+ var import_node_fs13 = require("fs");
2881
+ var import_node_path12 = require("path");
2658
2882
 
2659
2883
  // src/project-scaffolding/csharp-example.algorithm.ts
2660
2884
  function csharpExampleFiles(identity) {
@@ -2695,10 +2919,10 @@ public class GreetUseCaseTests
2695
2919
  }
2696
2920
 
2697
2921
  // src/project-scaffolding/post-generation.use-case.ts
2698
- var import_node_fs11 = require("fs");
2699
- var import_node_path10 = require("path");
2922
+ var import_node_fs12 = require("fs");
2923
+ var import_node_path11 = require("path");
2700
2924
  function hasPlugin(workspaceRoot, packageName) {
2701
- const manifest = readJson((0, import_node_path10.join)(workspaceRoot, "package.json"));
2925
+ const manifest = readJson((0, import_node_path11.join)(workspaceRoot, "package.json"));
2702
2926
  const installed = { ...manifest.dependencies, ...manifest.devDependencies };
2703
2927
  return Object.hasOwn(installed, packageName);
2704
2928
  }
@@ -2737,7 +2961,7 @@ function markPublic(manifestPath) {
2737
2961
  function writeProjectReadme(projectRoot, projectName, testRunner) {
2738
2962
  const runner = testRunner === "vitest" ? "[Vitest](https://vitest.dev)" : "[Jest](https://jestjs.io)";
2739
2963
  writeFileEnsured(
2740
- (0, import_node_path10.join)(projectRoot, "README.md"),
2964
+ (0, import_node_path11.join)(projectRoot, "README.md"),
2741
2965
  [
2742
2966
  `# ${projectName}`,
2743
2967
  "",
@@ -2756,13 +2980,13 @@ function writeProjectReadme(projectRoot, projectName, testRunner) {
2756
2980
  }
2757
2981
  function removeStaleGitkeeps(workspaceRoot) {
2758
2982
  for (const scaffold of ["apps", "libs", "packages"]) {
2759
- const directory = (0, import_node_path10.join)(workspaceRoot, scaffold);
2983
+ const directory = (0, import_node_path11.join)(workspaceRoot, scaffold);
2760
2984
  try {
2761
- const holdsAProject = (0, import_node_fs11.readdirSync)(directory, { withFileTypes: true }).some(
2985
+ const holdsAProject = (0, import_node_fs12.readdirSync)(directory, { withFileTypes: true }).some(
2762
2986
  (entry) => entry.isDirectory()
2763
2987
  );
2764
2988
  if (holdsAProject) {
2765
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(directory, ".gitkeep"), { force: true });
2989
+ (0, import_node_fs12.rmSync)((0, import_node_path11.join)(directory, ".gitkeep"), { force: true });
2766
2990
  }
2767
2991
  } catch {
2768
2992
  }
@@ -2782,7 +3006,7 @@ function ensureAdmZip(workspaceRoot) {
2782
3006
  }
2783
3007
  }
2784
3008
  function defaultScope(workspaceRoot) {
2785
- const { name } = readJson((0, import_node_path10.join)(workspaceRoot, "package.json"));
3009
+ const { name } = readJson((0, import_node_path11.join)(workspaceRoot, "package.json"));
2786
3010
  const base = (name.startsWith("@") ? name.slice(1) : name).split("/", 1)[0];
2787
3011
  return `@${base}`;
2788
3012
  }
@@ -2810,14 +3034,14 @@ var ESLINT_CONFIG_FILENAMES = [
2810
3034
  ];
2811
3035
  function removeGeneratedEslintConfig(workspaceRoot, projectRoot) {
2812
3036
  for (const filename of ESLINT_CONFIG_FILENAMES) {
2813
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(workspaceRoot, projectRoot, filename), { force: true });
3037
+ (0, import_node_fs12.rmSync)((0, import_node_path11.join)(workspaceRoot, projectRoot, filename), { force: true });
2814
3038
  }
2815
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(workspaceRoot, ".vscode"), { recursive: true, force: true });
3039
+ (0, import_node_fs12.rmSync)((0, import_node_path11.join)(workspaceRoot, ".vscode"), { recursive: true, force: true });
2816
3040
  }
2817
3041
  function findCodeWorkspaceFile(workspaceRoot) {
2818
3042
  try {
2819
- const entry = (0, import_node_fs11.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
2820
- return entry ? (0, import_node_path10.join)(workspaceRoot, entry) : void 0;
3043
+ const entry = (0, import_node_fs12.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
3044
+ return entry ? (0, import_node_path11.join)(workspaceRoot, entry) : void 0;
2821
3045
  } catch {
2822
3046
  return void 0;
2823
3047
  }
@@ -2834,8 +3058,8 @@ function reshapeReactScaffold(projectRoot, name, empty = false) {
2834
3058
  reshapeScaffoldSlice(projectRoot, name, "tsx", "component", empty);
2835
3059
  }
2836
3060
  function reshapeReactAppScaffold(projectRoot) {
2837
- const appDir = (0, import_node_path10.join)(projectRoot, "src", "app");
2838
- if (!(0, import_node_fs11.existsSync)((0, import_node_path10.join)(appDir, "app.tsx"))) {
3061
+ const appDir = (0, import_node_path11.join)(projectRoot, "src", "app");
3062
+ if (!(0, import_node_fs12.existsSync)((0, import_node_path11.join)(appDir, "app.tsx"))) {
2839
3063
  return;
2840
3064
  }
2841
3065
  for (const [from, to] of [
@@ -2843,60 +3067,60 @@ function reshapeReactAppScaffold(projectRoot) {
2843
3067
  ["app.spec.tsx", "app.component.spec.tsx"],
2844
3068
  ["nx-welcome.tsx", "nx-welcome.component.tsx"]
2845
3069
  ]) {
2846
- if ((0, import_node_fs11.existsSync)((0, import_node_path10.join)(appDir, from))) {
2847
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(appDir, from), (0, import_node_path10.join)(appDir, to));
3070
+ if ((0, import_node_fs12.existsSync)((0, import_node_path11.join)(appDir, from))) {
3071
+ (0, import_node_fs12.renameSync)((0, import_node_path11.join)(appDir, from), (0, import_node_path11.join)(appDir, to));
2848
3072
  }
2849
3073
  }
2850
3074
  const rewrite = (file, from, to) => {
2851
- if ((0, import_node_fs11.existsSync)(file)) {
2852
- writeFileEnsured(file, repointSpecifier((0, import_node_fs11.readFileSync)(file, "utf8"), from, to));
3075
+ if ((0, import_node_fs12.existsSync)(file)) {
3076
+ writeFileEnsured(file, repointSpecifier((0, import_node_fs12.readFileSync)(file, "utf8"), from, to));
2853
3077
  }
2854
3078
  };
2855
- rewrite((0, import_node_path10.join)(appDir, "app.component.tsx"), "./nx-welcome", "./nx-welcome.component");
2856
- rewrite((0, import_node_path10.join)(appDir, "app.component.spec.tsx"), "./app", "./app.component");
2857
- rewrite((0, import_node_path10.join)(projectRoot, "src", "main.tsx"), "./app/app", "./app");
3079
+ rewrite((0, import_node_path11.join)(appDir, "app.component.tsx"), "./nx-welcome", "./nx-welcome.component");
3080
+ rewrite((0, import_node_path11.join)(appDir, "app.component.spec.tsx"), "./app", "./app.component");
3081
+ rewrite((0, import_node_path11.join)(projectRoot, "src", "main.tsx"), "./app/app", "./app");
2858
3082
  writeFileEnsured(
2859
- (0, import_node_path10.join)(appDir, "index.ts"),
3083
+ (0, import_node_path11.join)(appDir, "index.ts"),
2860
3084
  "export * from './app.component'\nexport { default } from './app.component'\n"
2861
3085
  );
2862
3086
  }
2863
3087
  function emptySlice(projectRoot, sliceDir) {
2864
- for (const entry of (0, import_node_fs11.readdirSync)(sliceDir)) {
2865
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(sliceDir, entry), { recursive: true, force: true });
3088
+ for (const entry of (0, import_node_fs12.readdirSync)(sliceDir)) {
3089
+ (0, import_node_fs12.rmSync)((0, import_node_path11.join)(sliceDir, entry), { recursive: true, force: true });
2866
3090
  }
2867
- writeFileEnsured((0, import_node_path10.join)(sliceDir, "index.ts"), "export {}\n");
2868
- addNxTargets((0, import_node_path10.join)(projectRoot, "package.json"), { test: { options: { passWithNoTests: true } } });
3091
+ writeFileEnsured((0, import_node_path11.join)(sliceDir, "index.ts"), "export {}\n");
3092
+ addNxTargets((0, import_node_path11.join)(projectRoot, "package.json"), { test: { options: { passWithNoTests: true } } });
2869
3093
  }
2870
3094
  function reshapeScaffoldSlice(projectRoot, name, extension, role, empty) {
2871
- const sourceDir = (0, import_node_path10.join)(projectRoot, "src");
2872
- const libDir = (0, import_node_path10.join)(sourceDir, "lib");
2873
- if (!(0, import_node_fs11.existsSync)((0, import_node_path10.join)(libDir, `${name}.${extension}`))) {
3095
+ const sourceDir = (0, import_node_path11.join)(projectRoot, "src");
3096
+ const libDir = (0, import_node_path11.join)(sourceDir, "lib");
3097
+ if (!(0, import_node_fs12.existsSync)((0, import_node_path11.join)(libDir, `${name}.${extension}`))) {
2874
3098
  return;
2875
3099
  }
2876
- const sliceDir = (0, import_node_path10.join)(sourceDir, name);
2877
- (0, import_node_fs11.mkdirSync)(sliceDir, { recursive: true });
2878
- for (const entry of (0, import_node_fs11.readdirSync)(libDir)) {
3100
+ const sliceDir = (0, import_node_path11.join)(sourceDir, name);
3101
+ (0, import_node_fs12.mkdirSync)(sliceDir, { recursive: true });
3102
+ for (const entry of (0, import_node_fs12.readdirSync)(libDir)) {
2879
3103
  if (entry === `${name}.${extension}`) {
2880
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(libDir, entry), (0, import_node_path10.join)(sliceDir, `${name}.${role}.${extension}`));
3104
+ (0, import_node_fs12.renameSync)((0, import_node_path11.join)(libDir, entry), (0, import_node_path11.join)(sliceDir, `${name}.${role}.${extension}`));
2881
3105
  } else if (entry === `${name}.spec.${extension}`) {
2882
- const renamed = (0, import_node_path10.join)(sliceDir, `${name}.${role}.spec.${extension}`);
2883
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(libDir, entry), renamed);
2884
- writeFileEnsured(renamed, repointSpecifier((0, import_node_fs11.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.${role}`));
3106
+ const renamed = (0, import_node_path11.join)(sliceDir, `${name}.${role}.spec.${extension}`);
3107
+ (0, import_node_fs12.renameSync)((0, import_node_path11.join)(libDir, entry), renamed);
3108
+ writeFileEnsured(renamed, repointSpecifier((0, import_node_fs12.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.${role}`));
2885
3109
  } else {
2886
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(libDir, entry), (0, import_node_path10.join)(sliceDir, entry));
3110
+ (0, import_node_fs12.renameSync)((0, import_node_path11.join)(libDir, entry), (0, import_node_path11.join)(sliceDir, entry));
2887
3111
  }
2888
3112
  }
2889
- const barrel = (0, import_node_path10.join)(sourceDir, "index.ts");
2890
- const esm = (0, import_node_fs11.existsSync)(barrel) && (0, import_node_fs11.readFileSync)(barrel, "utf8").includes(`./lib/${name}.js'`);
2891
- writeFileEnsured((0, import_node_path10.join)(sliceDir, "index.ts"), `export * from './${name}.${role}${esm ? ".js" : ""}'
3113
+ const barrel = (0, import_node_path11.join)(sourceDir, "index.ts");
3114
+ const esm = (0, import_node_fs12.existsSync)(barrel) && (0, import_node_fs12.readFileSync)(barrel, "utf8").includes(`./lib/${name}.js'`);
3115
+ writeFileEnsured((0, import_node_path11.join)(sliceDir, "index.ts"), `export * from './${name}.${role}${esm ? ".js" : ""}'
2892
3116
  `);
2893
- if ((0, import_node_fs11.existsSync)(barrel)) {
3117
+ if ((0, import_node_fs12.existsSync)(barrel)) {
2894
3118
  writeFileEnsured(
2895
3119
  barrel,
2896
- (0, import_node_fs11.readFileSync)(barrel, "utf8").replaceAll(`./lib/${name}.js'`, () => `./${name}/index.js'`).replaceAll(`./lib/${name}'`, () => `./${name}'`)
3120
+ (0, import_node_fs12.readFileSync)(barrel, "utf8").replaceAll(`./lib/${name}.js'`, () => `./${name}/index.js'`).replaceAll(`./lib/${name}'`, () => `./${name}'`)
2897
3121
  );
2898
3122
  }
2899
- (0, import_node_fs11.rmSync)(libDir, { recursive: true, force: true });
3123
+ (0, import_node_fs12.rmSync)(libDir, { recursive: true, force: true });
2900
3124
  if (empty) {
2901
3125
  emptySlice(projectRoot, sliceDir);
2902
3126
  } else if (role === "use-case") {
@@ -2906,7 +3130,7 @@ function reshapeScaffoldSlice(projectRoot, name, extension, role, empty) {
2906
3130
  function writeWorkedExample(sliceDir, name, esm) {
2907
3131
  const suffix = esm ? ".js" : "";
2908
3132
  writeFileEnsured(
2909
- (0, import_node_path10.join)(sliceDir, `${name}.contract.ts`),
3133
+ (0, import_node_path11.join)(sliceDir, `${name}.contract.ts`),
2910
3134
  `/** What greeting someone returns. */
2911
3135
  export interface Greeting {
2912
3136
  readonly message: string
@@ -2914,7 +3138,7 @@ export interface Greeting {
2914
3138
  `
2915
3139
  );
2916
3140
  writeFileEnsured(
2917
- (0, import_node_path10.join)(sliceDir, `${name}.use-case.ts`),
3141
+ (0, import_node_path11.join)(sliceDir, `${name}.use-case.ts`),
2918
3142
  `import type { Greeting } from './${name}.contract${suffix}'
2919
3143
 
2920
3144
  /**
@@ -2933,7 +3157,7 @@ export function greet (name: string): Greeting {
2933
3157
  `
2934
3158
  );
2935
3159
  writeFileEnsured(
2936
- (0, import_node_path10.join)(sliceDir, `${name}.use-case.spec.ts`),
3160
+ (0, import_node_path11.join)(sliceDir, `${name}.use-case.spec.ts`),
2937
3161
  `import { greet } from './${name}.use-case${suffix}'
2938
3162
 
2939
3163
  describe('greet', () => {
@@ -2944,7 +3168,7 @@ describe('greet', () => {
2944
3168
  `
2945
3169
  );
2946
3170
  writeFileEnsured(
2947
- (0, import_node_path10.join)(sliceDir, "index.ts"),
3171
+ (0, import_node_path11.join)(sliceDir, "index.ts"),
2948
3172
  `export * from './${name}.contract${suffix}'
2949
3173
  export * from './${name}.use-case${suffix}'
2950
3174
  `
@@ -2958,8 +3182,8 @@ function repointSpecifier(source, from, to) {
2958
3182
  return result;
2959
3183
  }
2960
3184
  function ensureNxPeerOverrides(workspaceRoot) {
2961
- const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
2962
- if (!(0, import_node_fs11.existsSync)(manifestPath)) {
3185
+ const manifestPath = (0, import_node_path11.join)(workspaceRoot, "package.json");
3186
+ if (!(0, import_node_fs12.existsSync)(manifestPath)) {
2963
3187
  return;
2964
3188
  }
2965
3189
  const manifest = readJson(manifestPath);
@@ -2982,11 +3206,11 @@ function registerProjectCommands(workspaceRoot, name, commands) {
2982
3206
  if (commands.start) {
2983
3207
  scripts[`${name}:start`] = commands.start;
2984
3208
  }
2985
- const dependabotPath = (0, import_node_path10.join)(workspaceRoot, ".github/dependabot.yml");
2986
- if ((0, import_node_fs11.existsSync)(dependabotPath)) {
3209
+ const dependabotPath = (0, import_node_path11.join)(workspaceRoot, ".github/dependabot.yml");
3210
+ if ((0, import_node_fs12.existsSync)(dependabotPath)) {
2987
3211
  writeFileEnsured(dependabotPath, dependabotConfig(workspaceRoot));
2988
3212
  }
2989
- const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
3213
+ const manifestPath = (0, import_node_path11.join)(workspaceRoot, "package.json");
2990
3214
  const manifest = readJson(manifestPath);
2991
3215
  const existingScripts = manifest.scripts ?? {};
2992
3216
  writeFileEnsured(
@@ -3024,7 +3248,7 @@ function registerProjectCommands(workspaceRoot, name, commands) {
3024
3248
  var PROJECT_MANIFEST_ROOTS = ["apps", "packages", "libs"];
3025
3249
  function rootRuntimeDependencies(workspaceRoot) {
3026
3250
  try {
3027
- return readJson((0, import_node_path10.join)(workspaceRoot, "package.json")).dependencies ?? {};
3251
+ return readJson((0, import_node_path11.join)(workspaceRoot, "package.json")).dependencies ?? {};
3028
3252
  } catch {
3029
3253
  return {};
3030
3254
  }
@@ -3036,7 +3260,7 @@ function relocateRootRuntimeDependencies(workspaceRoot, projectName, before) {
3036
3260
  return;
3037
3261
  }
3038
3262
  const manifestPath = PROJECT_MANIFEST_ROOTS.map(
3039
- (root) => (0, import_node_path10.join)(workspaceRoot, root, projectName, "package.json")
3263
+ (root) => (0, import_node_path11.join)(workspaceRoot, root, projectName, "package.json")
3040
3264
  ).find((candidate) => fileExists(candidate));
3041
3265
  if (manifestPath === void 0) {
3042
3266
  return;
@@ -3048,10 +3272,10 @@ function relocateRootRuntimeDependencies(workspaceRoot, projectName, before) {
3048
3272
  const remaining = Object.fromEntries(
3049
3273
  Object.entries(after).filter(([name]) => !added.includes(name))
3050
3274
  );
3051
- const rootManifest = readJson((0, import_node_path10.join)(workspaceRoot, "package.json"));
3275
+ const rootManifest = readJson((0, import_node_path11.join)(workspaceRoot, "package.json"));
3052
3276
  const { dependencies: _dropped, ...rest } = rootManifest;
3053
3277
  writeFileEnsured(
3054
- (0, import_node_path10.join)(workspaceRoot, "package.json"),
3278
+ (0, import_node_path11.join)(workspaceRoot, "package.json"),
3055
3279
  toJson(Object.keys(remaining).length > 0 ? { ...rest, dependencies: remaining } : rest)
3056
3280
  );
3057
3281
  logger.step(`Moved ${added.join(", ")} into ${projectName}'s own manifest`);
@@ -3090,28 +3314,28 @@ function scaffoldDotnetProject(workspaceRoot, projectRoot, identity, template) {
3090
3314
  }
3091
3315
  function writeCsharpExample(absoluteRoot, identity, kind) {
3092
3316
  if (kind === "classlib") {
3093
- (0, import_node_fs12.rmSync)((0, import_node_path11.join)(absoluteRoot, "Class1.cs"), { force: true });
3317
+ (0, import_node_fs13.rmSync)((0, import_node_path12.join)(absoluteRoot, "Class1.cs"), { force: true });
3094
3318
  }
3095
3319
  const files = csharpExampleFiles(identity);
3096
3320
  for (const [file, contents] of Object.entries(files)) {
3097
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, file), contents);
3321
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, file), contents);
3098
3322
  }
3099
3323
  if (kind === "console") {
3100
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "Program.cs"), csharpConsoleProgram(identity));
3324
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "Program.cs"), csharpConsoleProgram(identity));
3101
3325
  }
3102
3326
  }
3103
3327
  function addCsharpTestProject(workspaceRoot, projectRoot, identity) {
3104
- const name = (0, import_node_path11.basename)(projectRoot);
3328
+ const name = (0, import_node_path12.basename)(projectRoot);
3105
3329
  const testRoot = `tests/${name}`;
3106
3330
  scaffoldDotnetProject(workspaceRoot, testRoot, `${identity}.Tests`, "xunit");
3107
- (0, import_node_fs12.rmSync)((0, import_node_path11.join)(workspaceRoot, testRoot, "UnitTest1.cs"), { force: true });
3108
- writeFileEnsured((0, import_node_path11.join)(workspaceRoot, testRoot, "GreetUseCaseTests.cs"), csharpExampleTest(identity));
3331
+ (0, import_node_fs13.rmSync)((0, import_node_path12.join)(workspaceRoot, testRoot, "UnitTest1.cs"), { force: true });
3332
+ writeFileEnsured((0, import_node_path12.join)(workspaceRoot, testRoot, "GreetUseCaseTests.cs"), csharpExampleTest(identity));
3109
3333
  writeFileEnsured(
3110
- (0, import_node_path11.join)(workspaceRoot, testRoot, "project.json"),
3334
+ (0, import_node_path12.join)(workspaceRoot, testRoot, "project.json"),
3111
3335
  toJson({ name: `${name}-tests`, tags: ["type:csharp-test"] })
3112
3336
  );
3113
- const reference = (0, import_node_path11.join)(workspaceRoot, projectRoot, `${identity}.csproj`);
3114
- if (runShell("dotnet", ["add", (0, import_node_path11.join)(workspaceRoot, testRoot), "reference", reference], workspaceRoot) !== 0) {
3337
+ const reference = (0, import_node_path12.join)(workspaceRoot, projectRoot, `${identity}.csproj`);
3338
+ if (runShell("dotnet", ["add", (0, import_node_path12.join)(workspaceRoot, testRoot), "reference", reference], workspaceRoot) !== 0) {
3115
3339
  throw new Error(`dotnet add reference failed for ${testRoot}`);
3116
3340
  }
3117
3341
  }
@@ -3138,9 +3362,9 @@ function addCsharpApp(workspaceRoot, name, template = "console") {
3138
3362
  ensureAdmZip(workspaceRoot);
3139
3363
  const projectRoot = `apps/${name}`;
3140
3364
  scaffoldDotnetProject(workspaceRoot, projectRoot, pascalCase(name), template);
3141
- writeCsharpExample((0, import_node_path11.join)(workspaceRoot, projectRoot), pascalCase(name), template);
3365
+ writeCsharpExample((0, import_node_path12.join)(workspaceRoot, projectRoot), pascalCase(name), template);
3142
3366
  addCsharpTestProject(workspaceRoot, projectRoot, pascalCase(name));
3143
- addProjectJsonTargets((0, import_node_path11.join)(workspaceRoot, projectRoot, "project.json"), {
3367
+ addProjectJsonTargets((0, import_node_path12.join)(workspaceRoot, projectRoot, "project.json"), {
3144
3368
  package: csharpAppPackageTarget("csharp-app", projectRoot, name),
3145
3369
  start: csharpAppStartTarget(projectRoot)
3146
3370
  });
@@ -3233,7 +3457,7 @@ class CsharpVersionActions extends VersionActions {
3233
3457
  module.exports = CsharpVersionActions
3234
3458
  `;
3235
3459
  function writeCsharpVersionActions(workspaceRoot) {
3236
- writeFileEnsured((0, import_node_path11.join)(workspaceRoot, CSHARP_VERSION_ACTIONS_PATH), CSHARP_VERSION_ACTIONS);
3460
+ writeFileEnsured((0, import_node_path12.join)(workspaceRoot, CSHARP_VERSION_ACTIONS_PATH), CSHARP_VERSION_ACTIONS);
3237
3461
  }
3238
3462
  function addProjectJsonReleaseVersionActions(projectJsonPath) {
3239
3463
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
@@ -3248,7 +3472,7 @@ function addProjectJsonReleaseVersionActions(projectJsonPath) {
3248
3472
  );
3249
3473
  }
3250
3474
  function addInitialVersion(csprojPath) {
3251
- const contents = (0, import_node_fs12.readFileSync)(csprojPath, "utf8");
3475
+ const contents = (0, import_node_fs13.readFileSync)(csprojPath, "utf8");
3252
3476
  writeFileEnsured(csprojPath, contents.replace("<PropertyGroup>", "<PropertyGroup>\n <Version>0.1.0</Version>"));
3253
3477
  }
3254
3478
  function csharpLibPublishTarget(projectRoot) {
@@ -3263,16 +3487,16 @@ async function addCsharpLib(workspaceRoot, name, options, kindProvided) {
3263
3487
  const projectRoot = `packages/${name}`;
3264
3488
  const identity = `${pascalScope(scope)}.${pascalCase(name)}`;
3265
3489
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "classlib");
3266
- writeCsharpExample((0, import_node_path11.join)(workspaceRoot, projectRoot), identity, "classlib");
3490
+ writeCsharpExample((0, import_node_path12.join)(workspaceRoot, projectRoot), identity, "classlib");
3267
3491
  addCsharpTestProject(workspaceRoot, projectRoot, identity);
3268
- addInitialVersion((0, import_node_path11.join)(workspaceRoot, projectRoot, `${identity}.csproj`));
3492
+ addInitialVersion((0, import_node_path12.join)(workspaceRoot, projectRoot, `${identity}.csproj`));
3269
3493
  writeCsharpVersionActions(workspaceRoot);
3270
- addProjectJsonReleaseVersionActions((0, import_node_path11.join)(workspaceRoot, projectRoot, "project.json"));
3271
- addProjectJsonTargets((0, import_node_path11.join)(workspaceRoot, projectRoot, "project.json"), {
3494
+ addProjectJsonReleaseVersionActions((0, import_node_path12.join)(workspaceRoot, projectRoot, "project.json"));
3495
+ addProjectJsonTargets((0, import_node_path12.join)(workspaceRoot, projectRoot, "project.json"), {
3272
3496
  "nx-release-publish": csharpLibPublishTarget(projectRoot)
3273
3497
  });
3274
3498
  const registry = readMnciConfig(workspaceRoot).registry ?? { kind: "npm" };
3275
- writeFileEnsured((0, import_node_path11.join)(workspaceRoot, "nuget.config"), nugetConfigContent(registry, scope));
3499
+ writeFileEnsured((0, import_node_path12.join)(workspaceRoot, "nuget.config"), nugetConfigContent(registry, scope));
3276
3500
  registerProjectCommands(workspaceRoot, name, { build: true });
3277
3501
  }
3278
3502
  function addCsharpInternalLib(workspaceRoot, name) {
@@ -3281,7 +3505,7 @@ function addCsharpInternalLib(workspaceRoot, name) {
3281
3505
  const projectRoot = `libs/${name}`;
3282
3506
  const identity = pascalCase(name);
3283
3507
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "classlib");
3284
- writeCsharpExample((0, import_node_path11.join)(workspaceRoot, projectRoot), identity, "classlib");
3508
+ writeCsharpExample((0, import_node_path12.join)(workspaceRoot, projectRoot), identity, "classlib");
3285
3509
  addCsharpTestProject(workspaceRoot, projectRoot, identity);
3286
3510
  registerProjectCommands(workspaceRoot, name, { build: false });
3287
3511
  logger.step(
@@ -3350,20 +3574,20 @@ function addCsharpFunctionApp(workspaceRoot, name) {
3350
3574
  const projectRoot = `apps/${name}`;
3351
3575
  const identity = pascalCase(name);
3352
3576
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "console");
3353
- const absoluteRoot = (0, import_node_path11.join)(workspaceRoot, projectRoot);
3354
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, `${identity}.csproj`), csharpFunctionAppCsproj());
3355
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "Program.cs"), CSHARP_FUNCTION_APP_PROGRAM);
3356
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "Hello.cs"), csharpFunctionAppHello(identity));
3577
+ const absoluteRoot = (0, import_node_path12.join)(workspaceRoot, projectRoot);
3578
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, `${identity}.csproj`), csharpFunctionAppCsproj());
3579
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "Program.cs"), CSHARP_FUNCTION_APP_PROGRAM);
3580
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "Hello.cs"), csharpFunctionAppHello(identity));
3357
3581
  const example = csharpExampleFiles(identity);
3358
3582
  for (const [file, contents] of Object.entries(example)) {
3359
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, file), contents);
3583
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, file), contents);
3360
3584
  }
3361
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "host.json"), CSHARP_FUNCTION_APP_HOST_JSON);
3585
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "host.json"), CSHARP_FUNCTION_APP_HOST_JSON);
3362
3586
  if (runShell("dotnet", ["restore", projectRoot], workspaceRoot) !== 0) {
3363
3587
  throw new Error(`dotnet restore failed for ${projectRoot}`);
3364
3588
  }
3365
3589
  addCsharpTestProject(workspaceRoot, projectRoot, identity);
3366
- addProjectJsonTargets((0, import_node_path11.join)(absoluteRoot, "project.json"), {
3590
+ addProjectJsonTargets((0, import_node_path12.join)(absoluteRoot, "project.json"), {
3367
3591
  package: csharpAppPackageTarget("csharp-function-app", projectRoot, name),
3368
3592
  start: csharpFunctionAppStartTarget(projectRoot)
3369
3593
  });
@@ -3371,7 +3595,7 @@ function addCsharpFunctionApp(workspaceRoot, name) {
3371
3595
  }
3372
3596
 
3373
3597
  // src/project-scaffolding/flutter.use-case.ts
3374
- var import_node_path12 = require("path");
3598
+ var import_node_path13 = require("path");
3375
3599
  function flutterAppStartTarget(name) {
3376
3600
  return {
3377
3601
  executor: "nx:run-commands",
@@ -3407,7 +3631,7 @@ function addFlutterApp(workspaceRoot, name) {
3407
3631
  prepareFlutter(workspaceRoot);
3408
3632
  ensureAdmZip(workspaceRoot);
3409
3633
  runNx(["g", "@mnci/nx-flutter:application", name, "--no-interactive"], workspaceRoot);
3410
- addProjectJsonTargets((0, import_node_path12.join)(workspaceRoot, "apps", name, "project.json"), {
3634
+ addProjectJsonTargets((0, import_node_path13.join)(workspaceRoot, "apps", name, "project.json"), {
3411
3635
  start: flutterAppStartTarget(name)
3412
3636
  });
3413
3637
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
@@ -3424,8 +3648,8 @@ function addFlutterInternalLib(workspaceRoot, name) {
3424
3648
  }
3425
3649
 
3426
3650
  // src/project-scaffolding/go.use-case.ts
3427
- var import_node_fs16 = require("fs");
3428
- var import_node_path16 = require("path");
3651
+ var import_node_fs17 = require("fs");
3652
+ var import_node_path17 = require("path");
3429
3653
 
3430
3654
  // src/project-scaffolding/go-example.algorithm.ts
3431
3655
  function greetingContract(packageName) {
@@ -3494,14 +3718,14 @@ function goAppExampleFiles(modulePath) {
3494
3718
  }
3495
3719
 
3496
3720
  // src/go-workspace/go-plugin.use-case.ts
3497
- var import_node_fs13 = require("fs");
3498
- var import_node_path13 = require("path");
3721
+ var import_node_fs14 = require("fs");
3722
+ var import_node_path14 = require("path");
3499
3723
  var NX_GO_PLUGIN = "@nx-go/nx-go";
3500
3724
  function hasGoProject(workspaceRoot) {
3501
- const projectFiles = ["apps", "libs", "packages"].flatMap((directory) => (0, import_node_fs13.globSync)(`${directory}/*/project.json`, { cwd: workspaceRoot }));
3725
+ const projectFiles = ["apps", "libs", "packages"].flatMap((directory) => (0, import_node_fs14.globSync)(`${directory}/*/project.json`, { cwd: workspaceRoot }));
3502
3726
  return projectFiles.some((projectFile) => {
3503
3727
  try {
3504
- const { tags } = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path13.join)(workspaceRoot, projectFile), "utf8"));
3728
+ const { tags } = JSON.parse((0, import_node_fs14.readFileSync)((0, import_node_path14.join)(workspaceRoot, projectFile), "utf8"));
3505
3729
  return (tags ?? []).some((tag) => tag.startsWith("type:go-"));
3506
3730
  } catch {
3507
3731
  return false;
@@ -3509,7 +3733,7 @@ function hasGoProject(workspaceRoot) {
3509
3733
  });
3510
3734
  }
3511
3735
  function isNxGoPluginRegistered(workspaceRoot) {
3512
- const nxJsonPath = (0, import_node_path13.join)(workspaceRoot, "nx.json");
3736
+ const nxJsonPath = (0, import_node_path14.join)(workspaceRoot, "nx.json");
3513
3737
  if (!fileExists(nxJsonPath)) {
3514
3738
  return false;
3515
3739
  }
@@ -3536,7 +3760,7 @@ function goModulePrefix(workspaceRoot) {
3536
3760
  return result.status === 0 ? modulePrefixFromRemoteUrl(result.stdout) : void 0;
3537
3761
  }
3538
3762
  function registerNxGoPlugin(workspaceRoot) {
3539
- const nxJsonPath = (0, import_node_path13.join)(workspaceRoot, "nx.json");
3763
+ const nxJsonPath = (0, import_node_path14.join)(workspaceRoot, "nx.json");
3540
3764
  if (!fileExists(nxJsonPath)) {
3541
3765
  return false;
3542
3766
  }
@@ -3560,8 +3784,8 @@ function registerNxGoPlugin(workspaceRoot) {
3560
3784
  }
3561
3785
 
3562
3786
  // src/project-scaffolding/go-release.use-case.ts
3563
- var import_node_fs14 = require("fs");
3564
- var import_node_path14 = require("path");
3787
+ var import_node_fs15 = require("fs");
3788
+ var import_node_path15 = require("path");
3565
3789
  var GO_RELEASE_SCRIPT_PATH = "tools/go-app-release.cjs";
3566
3790
  var GO_RELEASE_SCRIPT = String.raw`#!/usr/bin/env node
3567
3791
  // Written by mnci: 'mnci add go-app --release' creates it and 'mnci upgrade'
@@ -3687,7 +3911,7 @@ var GO_RELEASE_PUBLISH_TARGET = {
3687
3911
  }
3688
3912
  };
3689
3913
  function makeGoAppReleasable(workspaceRoot, name) {
3690
- const projectJsonPath = (0, import_node_path14.join)(workspaceRoot, "apps", name, "project.json");
3914
+ const projectJsonPath = (0, import_node_path15.join)(workspaceRoot, "apps", name, "project.json");
3691
3915
  if (!fileExists(projectJsonPath)) {
3692
3916
  throw new Error(`No Go app at apps/${name}: cannot make it releasable.`);
3693
3917
  }
@@ -3708,22 +3932,22 @@ function makeGoAppReleasable(workspaceRoot, name) {
3708
3932
  }
3709
3933
  })
3710
3934
  );
3711
- writeFileEnsured((0, import_node_path14.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH), GO_RELEASE_SCRIPT);
3935
+ writeFileEnsured((0, import_node_path15.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH), GO_RELEASE_SCRIPT);
3712
3936
  }
3713
3937
  function refreshGoReleaseScript(workspaceRoot) {
3714
- const apps = (0, import_node_path14.join)(workspaceRoot, "apps");
3938
+ const apps = (0, import_node_path15.join)(workspaceRoot, "apps");
3715
3939
  let entries;
3716
3940
  try {
3717
- entries = (0, import_node_fs14.readdirSync)(apps);
3941
+ entries = (0, import_node_fs15.readdirSync)(apps);
3718
3942
  } catch {
3719
3943
  return false;
3720
3944
  }
3721
3945
  const hasReleasableApp = entries.some((entry) => {
3722
- const projectJsonPath = (0, import_node_path14.join)(apps, entry, "project.json");
3946
+ const projectJsonPath = (0, import_node_path15.join)(apps, entry, "project.json");
3723
3947
  return fileExists(projectJsonPath) && (readJson(projectJsonPath).tags ?? []).includes(GO_RELEASE_TAG);
3724
3948
  });
3725
- const path = (0, import_node_path14.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH);
3726
- if (!hasReleasableApp || fileExists(path) && (0, import_node_fs14.readFileSync)(path, "utf8") === GO_RELEASE_SCRIPT) {
3949
+ const path = (0, import_node_path15.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH);
3950
+ if (!hasReleasableApp || fileExists(path) && (0, import_node_fs15.readFileSync)(path, "utf8") === GO_RELEASE_SCRIPT) {
3727
3951
  return false;
3728
3952
  }
3729
3953
  writeFileEnsured(path, GO_RELEASE_SCRIPT);
@@ -3731,8 +3955,8 @@ function refreshGoReleaseScript(workspaceRoot) {
3731
3955
  }
3732
3956
 
3733
3957
  // src/project-scaffolding/go-web.use-case.ts
3734
- var import_node_fs15 = require("fs");
3735
- var import_node_path15 = require("path");
3958
+ var import_node_fs16 = require("fs");
3959
+ var import_node_path16 = require("path");
3736
3960
  var TARGETS_NEEDING_THE_FRONTEND = ["build", "test", "lint", "start", "build-all", "build-native"];
3737
3961
  var DEFAULT_ADDRESS = "127.0.0.1:8080";
3738
3962
  var GO_WEB_SOURCE = `package main
@@ -3810,18 +4034,18 @@ func TestWebHandlerServesTheBuiltFrontend(t *testing.T) {
3810
4034
  }
3811
4035
  `;
3812
4036
  function assertWebApp(workspaceRoot, web) {
3813
- const directory = (0, import_node_path15.join)(workspaceRoot, "apps", web);
3814
- const isReactApp = fileExists((0, import_node_path15.join)(directory, "package.json")) && (0, import_node_fs15.readdirSync)(directory).some((entry) => entry.startsWith("vite.config."));
4037
+ const directory = (0, import_node_path16.join)(workspaceRoot, "apps", web);
4038
+ const isReactApp = fileExists((0, import_node_path16.join)(directory, "package.json")) && (0, import_node_fs16.readdirSync)(directory).some((entry) => entry.startsWith("vite.config."));
3815
4039
  if (!isReactApp) {
3816
4040
  throw new Error(`--web ${web}: no React app at apps/${web}. Add it first with \`mnci add react-app ${web}\`.`);
3817
4041
  }
3818
4042
  }
3819
4043
  function webProjectName(workspaceRoot, web) {
3820
- const manifest = readJson((0, import_node_path15.join)(workspaceRoot, "apps", web, "package.json"));
4044
+ const manifest = readJson((0, import_node_path16.join)(workspaceRoot, "apps", web, "package.json"));
3821
4045
  return manifest.nx?.name ?? manifest.name ?? web;
3822
4046
  }
3823
4047
  function addApiProxy(viteConfigPath) {
3824
- const source = (0, import_node_fs15.readFileSync)(viteConfigPath, "utf8");
4048
+ const source = (0, import_node_fs16.readFileSync)(viteConfigPath, "utf8");
3825
4049
  if (source.includes("'/api'") || source.includes('"/api"')) {
3826
4050
  return false;
3827
4051
  }
@@ -3834,7 +4058,7 @@ function addApiProxy(viteConfigPath) {
3834
4058
  return true;
3835
4059
  }
3836
4060
  function wireGoAppToWeb(workspaceRoot, name, web) {
3837
- const projectJsonPath = (0, import_node_path15.join)(workspaceRoot, "apps", name, "project.json");
4061
+ const projectJsonPath = (0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json");
3838
4062
  const project = readJson(projectJsonPath);
3839
4063
  const webName = webProjectName(workspaceRoot, web);
3840
4064
  const targets = project.targets ?? {};
@@ -3860,13 +4084,13 @@ function wireGoAppToWeb(workspaceRoot, name, web) {
3860
4084
  projectJsonPath,
3861
4085
  toJson({ ...project, implicitDependencies: [.../* @__PURE__ */ new Set([...project.implicitDependencies ?? [], webName])], targets })
3862
4086
  );
3863
- const directory = (0, import_node_path15.join)(workspaceRoot, "apps", name);
3864
- writeFileEnsured((0, import_node_path15.join)(directory, ".gitignore"), "/web/\n");
3865
- writeFileEnsured((0, import_node_path15.join)(directory, "web.go"), GO_WEB_SOURCE);
3866
- writeFileEnsured((0, import_node_path15.join)(directory, "main.go"), GO_WEB_MAIN);
3867
- writeFileEnsured((0, import_node_path15.join)(directory, "main_test.go"), GO_WEB_MAIN_TEST);
3868
- const viteConfig = (0, import_node_fs15.readdirSync)((0, import_node_path15.join)(workspaceRoot, "apps", web)).find((entry) => entry.startsWith("vite.config."));
3869
- if (viteConfig === void 0 || !addApiProxy((0, import_node_path15.join)(workspaceRoot, "apps", web, viteConfig))) {
4087
+ const directory = (0, import_node_path16.join)(workspaceRoot, "apps", name);
4088
+ writeFileEnsured((0, import_node_path16.join)(directory, ".gitignore"), "/web/\n");
4089
+ writeFileEnsured((0, import_node_path16.join)(directory, "web.go"), GO_WEB_SOURCE);
4090
+ writeFileEnsured((0, import_node_path16.join)(directory, "main.go"), GO_WEB_MAIN);
4091
+ writeFileEnsured((0, import_node_path16.join)(directory, "main_test.go"), GO_WEB_MAIN_TEST);
4092
+ const viteConfig = (0, import_node_fs16.readdirSync)((0, import_node_path16.join)(workspaceRoot, "apps", web)).find((entry) => entry.startsWith("vite.config."));
4093
+ if (viteConfig === void 0 || !addApiProxy((0, import_node_path16.join)(workspaceRoot, "apps", web, viteConfig))) {
3870
4094
  logger.warn(
3871
4095
  `Could not add the /api proxy to apps/${web}'s Vite config: add \`server: { proxy: { '/api': 'http://${DEFAULT_ADDRESS}' } }\` yourself, so \`nx run ${name}:dev\` reaches the Go server.`
3872
4096
  );
@@ -3900,7 +4124,7 @@ function ensureNxGoPlugin(workspaceRoot) {
3900
4124
  }
3901
4125
  }
3902
4126
  function ensureGoModule(workspaceRoot) {
3903
- if (fileExists((0, import_node_path16.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path16.join)(workspaceRoot, "go.mod"))) {
4127
+ if (fileExists((0, import_node_path17.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path17.join)(workspaceRoot, "go.mod"))) {
3904
4128
  return;
3905
4129
  }
3906
4130
  logger.step("Bootstrapping the Go workspace (go.work, one module per project)");
@@ -3908,38 +4132,38 @@ function ensureGoModule(workspaceRoot) {
3908
4132
  }
3909
4133
  function readGoModModule(goModPath) {
3910
4134
  try {
3911
- return /^module\s+(\S+)/m.exec((0, import_node_fs16.readFileSync)(goModPath, "utf8"))?.[1];
4135
+ return /^module\s+(\S+)/m.exec((0, import_node_fs17.readFileSync)(goModPath, "utf8"))?.[1];
3912
4136
  } catch {
3913
4137
  return void 0;
3914
4138
  }
3915
4139
  }
3916
4140
  function goModulePathFor(workspaceRoot, projectDir) {
3917
- const projectModule = readGoModModule((0, import_node_path16.join)(workspaceRoot, projectDir, "go.mod"));
4141
+ const projectModule = readGoModModule((0, import_node_path17.join)(workspaceRoot, projectDir, "go.mod"));
3918
4142
  if (projectModule !== void 0) {
3919
4143
  return projectModule;
3920
4144
  }
3921
- const rootModule = readGoModModule((0, import_node_path16.join)(workspaceRoot, "go.mod"));
4145
+ const rootModule = readGoModModule((0, import_node_path17.join)(workspaceRoot, "go.mod"));
3922
4146
  return rootModule === void 0 ? void 0 : `${rootModule}/${projectDir}`;
3923
4147
  }
3924
4148
  function setGoModulePath(workspaceRoot, projectDir) {
3925
4149
  const prefix = goModulePrefix(workspaceRoot);
3926
- const goModPath = (0, import_node_path16.join)(workspaceRoot, projectDir, "go.mod");
4150
+ const goModPath = (0, import_node_path17.join)(workspaceRoot, projectDir, "go.mod");
3927
4151
  if (prefix === void 0 || !fileExists(goModPath)) {
3928
4152
  return;
3929
4153
  }
3930
- const rewritten = (0, import_node_fs16.readFileSync)(goModPath, "utf8").replace(/^module\s+\S+/m, () => `module ${prefix}/${projectDir}`);
4154
+ const rewritten = (0, import_node_fs17.readFileSync)(goModPath, "utf8").replace(/^module\s+\S+/m, () => `module ${prefix}/${projectDir}`);
3931
4155
  writeFileEnsured(goModPath, rewritten);
3932
4156
  }
3933
4157
  function writeGoAppExample(workspaceRoot, projectDir) {
3934
- const goModPath = (0, import_node_path16.join)(workspaceRoot, projectDir, "go.mod");
3935
- const modulePath = fileExists(goModPath) ? /^module\s+(\S+)/m.exec((0, import_node_fs16.readFileSync)(goModPath, "utf8"))?.[1] : void 0;
4158
+ const goModPath = (0, import_node_path17.join)(workspaceRoot, projectDir, "go.mod");
4159
+ const modulePath = fileExists(goModPath) ? /^module\s+(\S+)/m.exec((0, import_node_fs17.readFileSync)(goModPath, "utf8"))?.[1] : void 0;
3936
4160
  if (modulePath === void 0) {
3937
4161
  return;
3938
4162
  }
3939
- (0, import_node_fs16.rmSync)((0, import_node_path16.join)(workspaceRoot, projectDir, "main_test.go"), { force: true });
4163
+ (0, import_node_fs17.rmSync)((0, import_node_path17.join)(workspaceRoot, projectDir, "main_test.go"), { force: true });
3940
4164
  const example = goAppExampleFiles(modulePath);
3941
4165
  for (const [relative, contents] of Object.entries(example)) {
3942
- writeFileEnsured((0, import_node_path16.join)(workspaceRoot, projectDir, relative), contents);
4166
+ writeFileEnsured((0, import_node_path17.join)(workspaceRoot, projectDir, relative), contents);
3943
4167
  }
3944
4168
  }
3945
4169
  function goTestTarget() {
@@ -4017,16 +4241,16 @@ function goNativePackageTarget(name) {
4017
4241
  }
4018
4242
  function addGoPlatformTargets(workspaceRoot) {
4019
4243
  const changed = [];
4020
- const apps = (0, import_node_path16.join)(workspaceRoot, "apps");
4244
+ const apps = (0, import_node_path17.join)(workspaceRoot, "apps");
4021
4245
  if (!fileExists(apps)) {
4022
4246
  return changed;
4023
4247
  }
4024
- for (const name of (0, import_node_fs16.readdirSync)(apps)) {
4025
- const projectJsonPath = (0, import_node_path16.join)(apps, name, "project.json");
4248
+ for (const name of (0, import_node_fs17.readdirSync)(apps)) {
4249
+ const projectJsonPath = (0, import_node_path17.join)(apps, name, "project.json");
4026
4250
  if (!fileExists(projectJsonPath)) {
4027
4251
  continue;
4028
4252
  }
4029
- const project = JSON.parse((0, import_node_fs16.readFileSync)(projectJsonPath, "utf8"));
4253
+ const project = JSON.parse((0, import_node_fs17.readFileSync)(projectJsonPath, "utf8"));
4030
4254
  const tag = (project.tags ?? []).find((each) => each === "type:go-app" || each === "type:go-function-app")?.slice("type:".length);
4031
4255
  if (tag === void 0 || (project.tags ?? []).includes(GO_CGO_TAG)) {
4032
4256
  continue;
@@ -4062,8 +4286,8 @@ function goLibraryIdentifiers(projectName) {
4062
4286
  }
4063
4287
  function reshapeGoLibraryScaffold(projectRoot, projectName) {
4064
4288
  const { packageName, fileStem } = goLibraryIdentifiers(projectName);
4065
- (0, import_node_fs16.rmSync)((0, import_node_path16.join)(projectRoot, `${projectName}.go`), { force: true });
4066
- (0, import_node_fs16.rmSync)((0, import_node_path16.join)(projectRoot, `${projectName}_test.go`), { force: true });
4289
+ (0, import_node_fs17.rmSync)((0, import_node_path17.join)(projectRoot, `${projectName}.go`), { force: true });
4290
+ (0, import_node_fs17.rmSync)((0, import_node_path17.join)(projectRoot, `${projectName}_test.go`), { force: true });
4067
4291
  const files = [
4068
4292
  [
4069
4293
  "doc.go",
@@ -4073,7 +4297,7 @@ package ${packageName}
4073
4297
  `
4074
4298
  ],
4075
4299
  [
4076
- (0, import_node_path16.join)(packageName, "doc.go"),
4300
+ (0, import_node_path17.join)(packageName, "doc.go"),
4077
4301
  `// Package ${packageName} is the starter slice of ${projectName}: rename it after
4078
4302
  // the outcome it delivers, and add one package per further outcome.
4079
4303
  package ${packageName}
@@ -4081,11 +4305,11 @@ package ${packageName}
4081
4305
  ],
4082
4306
  // The starter slice: a contract, a use case and its test (see goLibraryExampleFiles).
4083
4307
  ...Object.entries(goLibraryExampleFiles(packageName, fileStem)).map(
4084
- ([name, content]) => [(0, import_node_path16.join)(packageName, name), content]
4308
+ ([name, content]) => [(0, import_node_path17.join)(packageName, name), content]
4085
4309
  )
4086
4310
  ];
4087
4311
  for (const [relativePath, content] of files) {
4088
- const path = (0, import_node_path16.join)(projectRoot, relativePath);
4312
+ const path = (0, import_node_path17.join)(projectRoot, relativePath);
4089
4313
  if (!fileExists(path)) {
4090
4314
  writeFileEnsured(path, content);
4091
4315
  }
@@ -4123,7 +4347,7 @@ function addGoApp(workspaceRoot, name, options = {}) {
4123
4347
  if (options.web === void 0) {
4124
4348
  writeGoAppExample(workspaceRoot, `apps/${name}`);
4125
4349
  }
4126
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json"), {
4350
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "apps", name, "project.json"), {
4127
4351
  build: goBuildTarget(name),
4128
4352
  test: goTestTarget(),
4129
4353
  lint: goLintTarget(),
@@ -4163,7 +4387,7 @@ function addGoFunctionApp(workspaceRoot, name) {
4163
4387
  );
4164
4388
  setGoModulePath(workspaceRoot, `apps/${name}`);
4165
4389
  writeGoAppExample(workspaceRoot, `apps/${name}`);
4166
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json"), {
4390
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "apps", name, "project.json"), {
4167
4391
  "build": goBuildTarget(name),
4168
4392
  "test": goTestTarget(),
4169
4393
  "lint": goLintTarget(),
@@ -4187,11 +4411,11 @@ function addGoLib(workspaceRoot, name) {
4187
4411
  workspaceRoot
4188
4412
  );
4189
4413
  setGoModulePath(workspaceRoot, `packages/${name}`);
4190
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "packages", name, "project.json"), {
4414
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "packages", name, "project.json"), {
4191
4415
  test: goTestTarget(),
4192
4416
  lint: goLintTarget()
4193
4417
  });
4194
- const slice = reshapeGoLibraryScaffold((0, import_node_path16.join)(workspaceRoot, "packages", name), name);
4418
+ const slice = reshapeGoLibraryScaffold((0, import_node_path17.join)(workspaceRoot, "packages", name), name);
4195
4419
  registerProjectCommands(workspaceRoot, name, { build: false });
4196
4420
  const module2 = goModulePathFor(workspaceRoot, `packages/${name}`);
4197
4421
  if (module2) {
@@ -4212,11 +4436,11 @@ function addGoInternalLib(workspaceRoot, name) {
4212
4436
  workspaceRoot
4213
4437
  );
4214
4438
  setGoModulePath(workspaceRoot, `libs/${name}`);
4215
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "libs", name, "project.json"), {
4439
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "libs", name, "project.json"), {
4216
4440
  test: goTestTarget(),
4217
4441
  lint: goLintTarget()
4218
4442
  });
4219
- const slice = reshapeGoLibraryScaffold((0, import_node_path16.join)(workspaceRoot, "libs", name), name);
4443
+ const slice = reshapeGoLibraryScaffold((0, import_node_path17.join)(workspaceRoot, "libs", name), name);
4220
4444
  registerProjectCommands(workspaceRoot, name, { build: false });
4221
4445
  const module2 = goModulePathFor(workspaceRoot, `libs/${name}`);
4222
4446
  if (module2) {
@@ -4225,7 +4449,7 @@ function addGoInternalLib(workspaceRoot, name) {
4225
4449
  }
4226
4450
 
4227
4451
  // src/project-scaffolding/node.use-case.ts
4228
- var import_node_path17 = require("path");
4452
+ var import_node_path18 = require("path");
4229
4453
 
4230
4454
  // src/project-scaffolding/node-app-example.algorithm.ts
4231
4455
  var GREET_USE_CASE = `import type { Greeting } from './greeting.contract'
@@ -4348,12 +4572,12 @@ function runNodeApp(workspaceRoot, name, stack, framework) {
4348
4572
  ],
4349
4573
  workspaceRoot
4350
4574
  );
4351
- const appRoot = (0, import_node_path17.join)(workspaceRoot, "apps", name);
4575
+ const appRoot = (0, import_node_path18.join)(workspaceRoot, "apps", name);
4352
4576
  separateDeclarationOutput(appRoot);
4353
4577
  repairAssetMapping(appRoot, name);
4354
4578
  }
4355
4579
  function separateDeclarationOutput(appRoot) {
4356
- const tsconfigPath = (0, import_node_path17.join)(appRoot, "tsconfig.app.json");
4580
+ const tsconfigPath = (0, import_node_path18.join)(appRoot, "tsconfig.app.json");
4357
4581
  if (!fileExists(tsconfigPath)) {
4358
4582
  return;
4359
4583
  }
@@ -4375,7 +4599,7 @@ function separateDeclarationOutput(appRoot) {
4375
4599
  );
4376
4600
  }
4377
4601
  function repairAssetMapping(appRoot, name) {
4378
- const manifestPath = (0, import_node_path17.join)(appRoot, "package.json");
4602
+ const manifestPath = (0, import_node_path18.join)(appRoot, "package.json");
4379
4603
  if (!fileExists(manifestPath)) {
4380
4604
  return;
4381
4605
  }
@@ -4404,11 +4628,11 @@ function addNodeApp(workspaceRoot, name, stack, framework = "none") {
4404
4628
  const example = nodeAppExampleFiles(framework);
4405
4629
  if (example !== null) {
4406
4630
  for (const [relative, contents] of Object.entries(example)) {
4407
- writeFileEnsured((0, import_node_path17.join)(workspaceRoot, "apps", name, "src", relative), contents);
4631
+ writeFileEnsured((0, import_node_path18.join)(workspaceRoot, "apps", name, "src", relative), contents);
4408
4632
  }
4409
4633
  }
4410
4634
  ensureAdmZip(workspaceRoot);
4411
- addNxTargets((0, import_node_path17.join)(workspaceRoot, "apps", name, "package.json"), {
4635
+ addNxTargets((0, import_node_path18.join)(workspaceRoot, "apps", name, "package.json"), {
4412
4636
  package: nodeAppPackageTarget(name)
4413
4637
  });
4414
4638
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
@@ -4477,10 +4701,10 @@ describe('greet', () => {
4477
4701
  })
4478
4702
  `;
4479
4703
  function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
4480
- const manifestPath = (0, import_node_path17.join)(nodeFunctionAppRoot, "package.json");
4704
+ const manifestPath = (0, import_node_path18.join)(nodeFunctionAppRoot, "package.json");
4481
4705
  const manifest = readJson(manifestPath);
4482
4706
  const azureFunctionsVersion = readJson(
4483
- (0, import_node_path17.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
4707
+ (0, import_node_path18.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
4484
4708
  ).version;
4485
4709
  const dependencies = manifest.dependencies ?? {};
4486
4710
  writeFileEnsured(
@@ -4523,20 +4747,20 @@ function nodeFunctionAppStartTarget(name) {
4523
4747
  function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
4524
4748
  runNodeApp(workspaceRoot, name, stack, "none");
4525
4749
  ensureAzureFunctionsPackage(workspaceRoot);
4526
- const nodeFunctionAppRoot = (0, import_node_path17.join)(workspaceRoot, "apps", name);
4527
- writeFileEnsured((0, import_node_path17.join)(nodeFunctionAppRoot, "src/main.ts"), empty ? NODE_FUNCTION_APP_MAIN_EMPTY : NODE_FUNCTION_APP_MAIN);
4750
+ const nodeFunctionAppRoot = (0, import_node_path18.join)(workspaceRoot, "apps", name);
4751
+ writeFileEnsured((0, import_node_path18.join)(nodeFunctionAppRoot, "src/main.ts"), empty ? NODE_FUNCTION_APP_MAIN_EMPTY : NODE_FUNCTION_APP_MAIN);
4528
4752
  if (!empty) {
4529
- const slice = (0, import_node_path17.join)(nodeFunctionAppRoot, "src/hello");
4530
- writeFileEnsured((0, import_node_path17.join)(slice, "hello.handler.ts"), NODE_FUNCTION_APP_HELLO);
4531
- writeFileEnsured((0, import_node_path17.join)(slice, "greet.use-case.ts"), NODE_FUNCTION_APP_GREET_USE_CASE);
4532
- writeFileEnsured((0, import_node_path17.join)(slice, "greet.use-case.spec.ts"), NODE_FUNCTION_APP_GREET_SPEC);
4533
- writeFileEnsured((0, import_node_path17.join)(slice, "greeting.contract.ts"), NODE_FUNCTION_APP_GREETING_CONTRACT);
4534
- writeFileEnsured((0, import_node_path17.join)(slice, "index.ts"), NODE_FUNCTION_APP_HELLO_BARREL);
4535
- }
4536
- writeFileEnsured((0, import_node_path17.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
4753
+ const slice = (0, import_node_path18.join)(nodeFunctionAppRoot, "src/hello");
4754
+ writeFileEnsured((0, import_node_path18.join)(slice, "hello.handler.ts"), NODE_FUNCTION_APP_HELLO);
4755
+ writeFileEnsured((0, import_node_path18.join)(slice, "greet.use-case.ts"), NODE_FUNCTION_APP_GREET_USE_CASE);
4756
+ writeFileEnsured((0, import_node_path18.join)(slice, "greet.use-case.spec.ts"), NODE_FUNCTION_APP_GREET_SPEC);
4757
+ writeFileEnsured((0, import_node_path18.join)(slice, "greeting.contract.ts"), NODE_FUNCTION_APP_GREETING_CONTRACT);
4758
+ writeFileEnsured((0, import_node_path18.join)(slice, "index.ts"), NODE_FUNCTION_APP_HELLO_BARREL);
4759
+ }
4760
+ writeFileEnsured((0, import_node_path18.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
4537
4761
  repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
4538
4762
  ensureAdmZip(workspaceRoot);
4539
- addNxTargets((0, import_node_path17.join)(nodeFunctionAppRoot, "package.json"), {
4763
+ addNxTargets((0, import_node_path18.join)(nodeFunctionAppRoot, "package.json"), {
4540
4764
  package: nodeFunctionAppPackageTarget(name),
4541
4765
  prune: nodeFunctionAppPruneTarget(name),
4542
4766
  start: nodeFunctionAppStartTarget(name),
@@ -4548,11 +4772,11 @@ function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
4548
4772
  }
4549
4773
 
4550
4774
  // src/project-scaffolding/npm-lib.use-case.ts
4551
- var import_node_path21 = require("path");
4775
+ var import_node_path22 = require("path");
4552
4776
 
4553
4777
  // src/rollup-library/repair-publishable-manifest.use-case.ts
4554
- var import_node_fs17 = require("fs");
4555
- var import_node_path18 = require("path");
4778
+ var import_node_fs18 = require("fs");
4779
+ var import_node_path19 = require("path");
4556
4780
  var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
4557
4781
  var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
4558
4782
  var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
@@ -4575,14 +4799,14 @@ function repairPublishableManifest(manifestPath) {
4575
4799
  }
4576
4800
  function repairPublishableManifests(workspaceRoot) {
4577
4801
  const changed = [];
4578
- const manifests = (0, import_node_fs17.globSync)(["packages/*/package.json", "libs/*/package.json"], {
4802
+ const manifests = (0, import_node_fs18.globSync)(["packages/*/package.json", "libs/*/package.json"], {
4579
4803
  cwd: workspaceRoot
4580
4804
  });
4581
4805
  for (const relativePath of manifests) {
4582
- const manifestPath = (0, import_node_path18.join)(workspaceRoot, relativePath);
4583
- const before = (0, import_node_fs17.readFileSync)(manifestPath, "utf8");
4806
+ const manifestPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
4807
+ const before = (0, import_node_fs18.readFileSync)(manifestPath, "utf8");
4584
4808
  repairPublishableManifest(manifestPath);
4585
- const after = (0, import_node_fs17.readFileSync)(manifestPath, "utf8");
4809
+ const after = (0, import_node_fs18.readFileSync)(manifestPath, "utf8");
4586
4810
  if (after !== before) {
4587
4811
  changed.push(relativePath.replaceAll("\\", "/"));
4588
4812
  }
@@ -4591,8 +4815,8 @@ function repairPublishableManifests(workspaceRoot) {
4591
4815
  }
4592
4816
 
4593
4817
  // src/rollup-library/repair-rollup-config.use-case.ts
4594
- var import_node_fs18 = require("fs");
4595
- var import_node_path19 = require("path");
4818
+ var import_node_fs19 = require("fs");
4819
+ var import_node_path20 = require("path");
4596
4820
 
4597
4821
  // src/rollup-library/rollup-config.algorithm.ts
4598
4822
  var ROLLUP_CONFIG_PLACEHOLDER = [
@@ -4794,12 +5018,12 @@ function withUpgradedDeclarationSpecifierPlugin(config) {
4794
5018
  // src/rollup-library/repair-rollup-config.use-case.ts
4795
5019
  function repairRollupSourceMaps(workspaceRoot) {
4796
5020
  const changed = [];
4797
- const configs = (0, import_node_fs18.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5021
+ const configs = (0, import_node_fs19.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
4798
5022
  cwd: workspaceRoot
4799
5023
  });
4800
5024
  for (const relativePath of configs) {
4801
- const configPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
4802
- const before = (0, import_node_fs18.readFileSync)(configPath, "utf8");
5025
+ const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5026
+ const before = (0, import_node_fs19.readFileSync)(configPath, "utf8");
4803
5027
  const after = withRollupSourceMaps(before);
4804
5028
  if (after !== before) {
4805
5029
  writeFileEnsured(configPath, after);
@@ -4810,12 +5034,12 @@ function repairRollupSourceMaps(workspaceRoot) {
4810
5034
  }
4811
5035
  function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
4812
5036
  const changed = [];
4813
- const configs = (0, import_node_fs18.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5037
+ const configs = (0, import_node_fs19.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
4814
5038
  cwd: workspaceRoot
4815
5039
  });
4816
5040
  for (const relativePath of configs) {
4817
- const configPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
4818
- const before = (0, import_node_fs18.readFileSync)(configPath, "utf8");
5041
+ const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5042
+ const before = (0, import_node_fs19.readFileSync)(configPath, "utf8");
4819
5043
  const after = withUpgradedDeclarationSpecifierPlugin(before);
4820
5044
  if (after !== before) {
4821
5045
  writeFileEnsured(configPath, after);
@@ -4825,11 +5049,11 @@ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
4825
5049
  return changed;
4826
5050
  }
4827
5051
  function repairDeclarationSpecifiers(projectRoot) {
4828
- const configPath = (0, import_node_path19.join)(projectRoot, "rollup.config.cjs");
5052
+ const configPath = (0, import_node_path20.join)(projectRoot, "rollup.config.cjs");
4829
5053
  if (!fileExists(configPath)) {
4830
5054
  return;
4831
5055
  }
4832
- const config = (0, import_node_fs18.readFileSync)(configPath, "utf8");
5056
+ const config = (0, import_node_fs19.readFileSync)(configPath, "utf8");
4833
5057
  if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
4834
5058
  return;
4835
5059
  }
@@ -4838,10 +5062,10 @@ function repairDeclarationSpecifiers(projectRoot) {
4838
5062
  }
4839
5063
 
4840
5064
  // src/rollup-library/rollup-config.repository.ts
4841
- var import_node_fs19 = require("fs");
4842
- var import_node_path20 = require("path");
5065
+ var import_node_fs20 = require("fs");
5066
+ var import_node_path21 = require("path");
4843
5067
  function resolveRequireTarget(fromDir, specifier) {
4844
- const base = (0, import_node_path20.join)(fromDir, specifier);
5068
+ const base = (0, import_node_path21.join)(fromDir, specifier);
4845
5069
  return [base, `${base}.cjs`, `${base}.js`].find((candidate) => fileExists(candidate));
4846
5070
  }
4847
5071
  function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()) {
@@ -4851,7 +5075,7 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
4851
5075
  visited.add(configPath);
4852
5076
  let text;
4853
5077
  try {
4854
- text = (0, import_node_fs19.readFileSync)(configPath, "utf8");
5078
+ text = (0, import_node_fs20.readFileSync)(configPath, "utf8");
4855
5079
  } catch {
4856
5080
  return "";
4857
5081
  }
@@ -4859,15 +5083,15 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
4859
5083
  text.matchAll(/require\((['"])(\.[^'"]*)\1\)/g),
4860
5084
  (match) => match[2]
4861
5085
  );
4862
- const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path20.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5086
+ const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path21.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
4863
5087
  return [text, ...requiredText].join("\n");
4864
5088
  }
4865
5089
 
4866
5090
  // src/project-scaffolding/npm-lib.use-case.ts
4867
5091
  async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
4868
5092
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
4869
- const projectRoot = (0, import_node_path21.join)(workspaceRoot, "packages", name);
4870
- const manifestPath = (0, import_node_path21.join)(projectRoot, "package.json");
5093
+ const projectRoot = (0, import_node_path22.join)(workspaceRoot, "packages", name);
5094
+ const manifestPath = (0, import_node_path22.join)(projectRoot, "package.json");
4871
5095
  runGeneratorAndRepair(
4872
5096
  workspaceRoot,
4873
5097
  [
@@ -4896,8 +5120,8 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
4896
5120
  }
4897
5121
 
4898
5122
  // src/project-scaffolding/python.use-case.ts
4899
- var import_node_fs20 = require("fs");
4900
- var import_node_path22 = require("path");
5123
+ var import_node_fs21 = require("fs");
5124
+ var import_node_path23 = require("path");
4901
5125
  function ensurePython(workspaceRoot) {
4902
5126
  const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
4903
5127
  if (!hasPython) {
@@ -4920,7 +5144,7 @@ function ensurePythonPipPlugin(workspaceRoot) {
4920
5144
  registerPythonGraphPlugin(workspaceRoot);
4921
5145
  }
4922
5146
  function registerPythonGraphPlugin(workspaceRoot) {
4923
- const nxJsonPath = (0, import_node_path22.join)(workspaceRoot, "nx.json");
5147
+ const nxJsonPath = (0, import_node_path23.join)(workspaceRoot, "nx.json");
4924
5148
  if (!fileExists(nxJsonPath)) {
4925
5149
  return;
4926
5150
  }
@@ -4943,7 +5167,7 @@ pytest
4943
5167
  pip-audit
4944
5168
  `;
4945
5169
  function ensureRequirementsDev(workspaceRoot) {
4946
- const requirementsDevPath = (0, import_node_path22.join)(workspaceRoot, "requirements-dev.txt");
5170
+ const requirementsDevPath = (0, import_node_path23.join)(workspaceRoot, "requirements-dev.txt");
4947
5171
  if (!fileExists(requirementsDevPath)) {
4948
5172
  writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
4949
5173
  }
@@ -5003,8 +5227,8 @@ function addPythonApp(workspaceRoot, name) {
5003
5227
  ["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
5004
5228
  workspaceRoot
5005
5229
  );
5006
- writeFileEnsured((0, import_node_path22.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5007
- addProjectJsonTargets((0, import_node_path22.join)(workspaceRoot, "apps", name, "project.json"), {
5230
+ writeFileEnsured((0, import_node_path23.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5231
+ addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5008
5232
  package: pythonAppPackageTarget(name),
5009
5233
  start: pythonAppStartTarget(name)
5010
5234
  });
@@ -5026,7 +5250,7 @@ function addPythonFunctionApp(workspaceRoot, name) {
5026
5250
  workspaceRoot
5027
5251
  );
5028
5252
  const moduleDirectory = pythonModuleDirectory(name);
5029
- addProjectJsonTargets((0, import_node_path22.join)(workspaceRoot, "apps", name, "project.json"), {
5253
+ addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5030
5254
  package: pythonFunctionAppPackageTarget(name, moduleDirectory),
5031
5255
  start: pythonFunctionAppStartTarget(name)
5032
5256
  });
@@ -5067,7 +5291,7 @@ function addPythonInternalLib(workspaceRoot, name) {
5067
5291
  var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
5068
5292
  function findPythonProjectDirectory(workspaceRoot, name) {
5069
5293
  return PYTHON_PROJECT_DIRS.find(
5070
- (directory) => fileExists((0, import_node_path22.join)(workspaceRoot, directory, name, "pyproject.toml"))
5294
+ (directory) => fileExists((0, import_node_path23.join)(workspaceRoot, directory, name, "pyproject.toml"))
5071
5295
  );
5072
5296
  }
5073
5297
  function parseVendorEntries(pyprojectToml) {
@@ -5106,7 +5330,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5106
5330
  `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.`
5107
5331
  );
5108
5332
  }
5109
- if (!fileExists((0, import_node_path22.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5333
+ if (!fileExists((0, import_node_path23.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5110
5334
  throw new Error(
5111
5335
  `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.`
5112
5336
  );
@@ -5114,8 +5338,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5114
5338
  if (consumerDirectory === "libs" && consumer === lib) {
5115
5339
  throw new Error(`'${consumer}' cannot vendor itself.`);
5116
5340
  }
5117
- const pyprojectPath = (0, import_node_path22.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5118
- const pyprojectToml = (0, import_node_fs20.readFileSync)(pyprojectPath, "utf8");
5341
+ const pyprojectPath = (0, import_node_path23.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5342
+ const pyprojectToml = (0, import_node_fs21.readFileSync)(pyprojectPath, "utf8");
5119
5343
  if (parseVendorEntries(pyprojectToml).includes(lib)) {
5120
5344
  logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
5121
5345
  return;
@@ -5127,8 +5351,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5127
5351
  }
5128
5352
 
5129
5353
  // src/project-scaffolding/react-app.use-case.ts
5130
- var import_node_fs21 = require("fs");
5131
- var import_node_path23 = require("path");
5354
+ var import_node_fs22 = require("fs");
5355
+ var import_node_path24 = require("path");
5132
5356
 
5133
5357
  // src/project-scaffolding/react-app-example.algorithm.ts
5134
5358
  function reactAppExampleFiles(name) {
@@ -5245,12 +5469,12 @@ function reactAppTargets(name) {
5245
5469
  return targets;
5246
5470
  }
5247
5471
  function allowEnvFiles(workspaceRoot) {
5248
- const gitignorePath = (0, import_node_path23.join)(workspaceRoot, ".gitignore");
5472
+ const gitignorePath = (0, import_node_path24.join)(workspaceRoot, ".gitignore");
5249
5473
  if (!fileExists(gitignorePath)) {
5250
5474
  return;
5251
5475
  }
5252
5476
  const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
5253
- const current = (0, import_node_fs21.readFileSync)(gitignorePath, "utf8");
5477
+ const current = (0, import_node_fs22.readFileSync)(gitignorePath, "utf8");
5254
5478
  if (current.includes(marker)) {
5255
5479
  return;
5256
5480
  }
@@ -5277,30 +5501,30 @@ function addReactApp(workspaceRoot, name, stack) {
5277
5501
  workspaceRoot
5278
5502
  );
5279
5503
  ensureAdmZip(workspaceRoot);
5280
- const reactAppRoot = (0, import_node_path23.join)(workspaceRoot, "apps", name);
5504
+ const reactAppRoot = (0, import_node_path24.join)(workspaceRoot, "apps", name);
5281
5505
  for (const environment of REACT_ENVIRONMENTS) {
5282
- writeFileEnsured((0, import_node_path23.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5506
+ writeFileEnsured((0, import_node_path24.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5283
5507
  }
5284
5508
  allowEnvFiles(workspaceRoot);
5285
- addNxTargets((0, import_node_path23.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5509
+ addNxTargets((0, import_node_path24.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5286
5510
  reshapeReactAppScaffold(reactAppRoot);
5287
- (0, import_node_fs21.rmSync)((0, import_node_path23.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5511
+ (0, import_node_fs22.rmSync)((0, import_node_path24.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5288
5512
  const example = reactAppExampleFiles(name);
5289
5513
  for (const [relative, contents] of Object.entries(example)) {
5290
- writeFileEnsured((0, import_node_path23.join)(reactAppRoot, "src", relative), contents);
5514
+ writeFileEnsured((0, import_node_path24.join)(reactAppRoot, "src", relative), contents);
5291
5515
  }
5292
5516
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
5293
5517
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
5294
5518
  }
5295
5519
 
5296
5520
  // src/project-scaffolding/react-lib.use-case.ts
5297
- var import_node_path24 = require("path");
5521
+ var import_node_path25 = require("path");
5298
5522
  var REACT_LIB_BUNDLER = "rollup";
5299
5523
  async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5300
5524
  ensurePlugin(workspaceRoot, "@nx/react");
5301
5525
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5302
- const projectRoot = (0, import_node_path24.join)(workspaceRoot, "packages", name);
5303
- const publishableManifest = (0, import_node_path24.join)(projectRoot, "package.json");
5526
+ const projectRoot = (0, import_node_path25.join)(workspaceRoot, "packages", name);
5527
+ const publishableManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5304
5528
  runGeneratorAndRepair(
5305
5529
  workspaceRoot,
5306
5530
  [
@@ -5330,8 +5554,8 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5330
5554
  }
5331
5555
  function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5332
5556
  ensurePlugin(workspaceRoot, "@nx/react");
5333
- const projectRoot = (0, import_node_path24.join)(workspaceRoot, "libs", name);
5334
- const privateManifest = (0, import_node_path24.join)(projectRoot, "package.json");
5557
+ const projectRoot = (0, import_node_path25.join)(workspaceRoot, "libs", name);
5558
+ const privateManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5335
5559
  runGeneratorAndRepair(
5336
5560
  workspaceRoot,
5337
5561
  [
@@ -5358,8 +5582,8 @@ function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5358
5582
  }
5359
5583
 
5360
5584
  // src/project-scaffolding/vscode-extension.use-case.ts
5361
- var import_node_fs22 = require("fs");
5362
- var import_node_path25 = require("path");
5585
+ var import_node_fs23 = require("fs");
5586
+ var import_node_path26 = require("path");
5363
5587
  var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
5364
5588
  var VSCODE_ENGINE_FLOOR = "1.96.0";
5365
5589
  var VSCODE_SIDECAR_TARGETS = {
@@ -5544,8 +5768,8 @@ export const window = {
5544
5768
  var VSCODE_STUB_PATH = "test/vscode.stub.ts";
5545
5769
  function mapVscodeToStub(projectRoot, testRunner) {
5546
5770
  const [file, anchor, mapping] = testRunner === "jest" ? ["jest.config.cts", "testEnvironment: 'node',", `moduleNameMapper: { '^vscode$': '<rootDir>/${VSCODE_STUB_PATH}' },`] : ["vitest.config.mts", "environment: 'node',", `alias: { vscode: \`\${import.meta.dirname}/${VSCODE_STUB_PATH}\` },`];
5547
- const path = (0, import_node_path25.join)(projectRoot, file);
5548
- const content = fileExists(path) ? (0, import_node_fs22.readFileSync)(path, "utf8") : "";
5771
+ const path = (0, import_node_path26.join)(projectRoot, file);
5772
+ const content = fileExists(path) ? (0, import_node_fs23.readFileSync)(path, "utf8") : "";
5549
5773
  const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
5550
5774
  if (line === void 0) {
5551
5775
  throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
@@ -5565,11 +5789,11 @@ function ensureVscodeToolchain(workspaceRoot) {
5565
5789
  }
5566
5790
  }
5567
5791
  function defaultPublisher(workspaceRoot) {
5568
- const { name } = readJson((0, import_node_path25.join)(workspaceRoot, "package.json"));
5792
+ const { name } = readJson((0, import_node_path26.join)(workspaceRoot, "package.json"));
5569
5793
  return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
5570
5794
  }
5571
5795
  function reshapeManifest(projectRoot, name, publisher) {
5572
- const manifestPath = (0, import_node_path25.join)(projectRoot, "package.json");
5796
+ const manifestPath = (0, import_node_path26.join)(projectRoot, "package.json");
5573
5797
  const manifest = readJson(manifestPath);
5574
5798
  const { nx = {}, ...rest } = manifest;
5575
5799
  const targets = { ...nx.targets };
@@ -5633,11 +5857,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
5633
5857
  };
5634
5858
  }
5635
5859
  function addDebugLaunch(workspaceRoot, name) {
5636
- const file = (0, import_node_fs22.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
5860
+ const file = (0, import_node_fs23.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
5637
5861
  if (file === void 0) {
5638
5862
  return;
5639
5863
  }
5640
- const path = (0, import_node_path25.join)(workspaceRoot, file);
5864
+ const path = (0, import_node_path26.join)(workspaceRoot, file);
5641
5865
  const workspace = readCodeWorkspace(path) ?? {};
5642
5866
  const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
5643
5867
  const taskLabel = `${name}: build (development)`;
@@ -5670,39 +5894,39 @@ function addDebugLaunch(workspaceRoot, name) {
5670
5894
  );
5671
5895
  }
5672
5896
  function refreshVscodeExtensionScript(workspaceRoot) {
5673
- const apps = (0, import_node_path25.join)(workspaceRoot, "apps");
5897
+ const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
5674
5898
  let entries;
5675
5899
  try {
5676
- entries = (0, import_node_fs22.readdirSync)(apps);
5900
+ entries = (0, import_node_fs23.readdirSync)(apps);
5677
5901
  } catch {
5678
5902
  return false;
5679
5903
  }
5680
5904
  const hasExtension = entries.some((entry) => {
5681
- const manifestPath = (0, import_node_path25.join)(apps, entry, "package.json");
5905
+ const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
5682
5906
  if (!fileExists(manifestPath)) {
5683
5907
  return false;
5684
5908
  }
5685
5909
  const tags = readJson(manifestPath).nx?.tags ?? [];
5686
5910
  return tags.includes(VSCODE_EXTENSION_TAG);
5687
5911
  });
5688
- const path = (0, import_node_path25.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
5689
- if (!hasExtension || fileExists(path) && (0, import_node_fs22.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
5912
+ const path = (0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
5913
+ if (!hasExtension || fileExists(path) && (0, import_node_fs23.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
5690
5914
  return false;
5691
5915
  }
5692
5916
  writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
5693
5917
  return true;
5694
5918
  }
5695
5919
  function pinVscodeExtensionProjectNames(workspaceRoot) {
5696
- const apps = (0, import_node_path25.join)(workspaceRoot, "apps");
5920
+ const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
5697
5921
  let entries;
5698
5922
  try {
5699
- entries = (0, import_node_fs22.readdirSync)(apps);
5923
+ entries = (0, import_node_fs23.readdirSync)(apps);
5700
5924
  } catch {
5701
5925
  return [];
5702
5926
  }
5703
5927
  const updated = [];
5704
5928
  for (const entry of entries) {
5705
- const manifestPath = (0, import_node_path25.join)(apps, entry, "package.json");
5929
+ const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
5706
5930
  if (!fileExists(manifestPath)) {
5707
5931
  continue;
5708
5932
  }
@@ -5722,22 +5946,22 @@ function refreshLockFile(workspaceRoot, name) {
5722
5946
  }
5723
5947
  function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
5724
5948
  const { sidecar } = options;
5725
- if (sidecar !== void 0 && !fileExists((0, import_node_path25.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
5949
+ if (sidecar !== void 0 && !fileExists((0, import_node_path26.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
5726
5950
  throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
5727
5951
  }
5728
5952
  runNodeApp(workspaceRoot, name, stack, "none");
5729
5953
  ensureVscodeToolchain(workspaceRoot);
5730
- const projectRoot = (0, import_node_path25.join)(workspaceRoot, "apps", name);
5954
+ const projectRoot = (0, import_node_path26.join)(workspaceRoot, "apps", name);
5731
5955
  reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot));
5732
- addVscodeTypes((0, import_node_path25.join)(projectRoot, "tsconfig.app.json"));
5733
- addVscodeTypes((0, import_node_path25.join)(projectRoot, "tsconfig.spec.json"));
5734
- writeFileEnsured((0, import_node_path25.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
5735
- writeFileEnsured((0, import_node_path25.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
5736
- writeFileEnsured((0, import_node_path25.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
5956
+ addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.app.json"));
5957
+ addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.spec.json"));
5958
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
5959
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
5960
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
5737
5961
  mapVscodeToStub(projectRoot, stack.testRunner);
5738
- writeFileEnsured((0, import_node_path25.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
5739
- writeFileEnsured((0, import_node_path25.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
5740
- addNxTargets((0, import_node_path25.join)(projectRoot, "package.json"), {
5962
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
5963
+ writeFileEnsured((0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
5964
+ addNxTargets((0, import_node_path26.join)(projectRoot, "package.json"), {
5741
5965
  "package": vscodeExtensionPackageTarget(name, sidecar),
5742
5966
  "nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
5743
5967
  });
@@ -5748,12 +5972,12 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
5748
5972
  }
5749
5973
 
5750
5974
  // src/dependency-management/install-dependencies.use-case.ts
5751
- var import_node_fs24 = require("fs");
5752
- var import_node_path27 = require("path");
5975
+ var import_node_fs25 = require("fs");
5976
+ var import_node_path28 = require("path");
5753
5977
 
5754
5978
  // src/dependency-management/manifest.repository.ts
5755
- var import_node_fs23 = require("fs");
5756
- var import_node_path26 = require("path");
5979
+ var import_node_fs24 = require("fs");
5980
+ var import_node_path27 = require("path");
5757
5981
  var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
5758
5982
  var ROOT_LABEL = "(root)";
5759
5983
  var MANIFEST_GLOBS = {
@@ -5786,23 +6010,23 @@ function projectOf(manifestRelativePath) {
5786
6010
  }
5787
6011
  function hasEcosystem(workspaceRoot, ecosystem) {
5788
6012
  if (ecosystem === "go") {
5789
- return fileExists((0, import_node_path26.join)(workspaceRoot, "go.mod"));
6013
+ return fileExists((0, import_node_path27.join)(workspaceRoot, "go.mod"));
5790
6014
  }
5791
6015
  if (ecosystem === "nuget") {
5792
- return (0, import_node_fs23.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
6016
+ return (0, import_node_fs24.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
5793
6017
  }
5794
6018
  const rootMarker = {
5795
6019
  npm: "package.json",
5796
6020
  pip: "requirements-dev.txt",
5797
6021
  pub: "pubspec.yaml"
5798
6022
  };
5799
- return fileExists((0, import_node_path26.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs23.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
6023
+ return fileExists((0, import_node_path27.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs24.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
5800
6024
  }
5801
6025
  function collectNpm(workspaceRoot) {
5802
6026
  const sites = [];
5803
- const relativePaths = ["package.json", ...(0, import_node_fs23.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
6027
+ const relativePaths = ["package.json", ...(0, import_node_fs24.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
5804
6028
  for (const relativePath of relativePaths) {
5805
- const manifestPath = (0, import_node_path26.join)(workspaceRoot, relativePath);
6029
+ const manifestPath = (0, import_node_path27.join)(workspaceRoot, relativePath);
5806
6030
  try {
5807
6031
  const manifest = readJson(manifestPath);
5808
6032
  sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
@@ -5863,17 +6087,17 @@ function collectPip(workspaceRoot) {
5863
6087
  name: parsed.name,
5864
6088
  ecosystem: "pip",
5865
6089
  project: projectOf(relativePath),
5866
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath),
6090
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
5867
6091
  section,
5868
6092
  spec: parsed.spec,
5869
6093
  rewritable: parsed.rewritable && parsed.spec !== ""
5870
6094
  });
5871
6095
  };
5872
- const pyprojectPaths = (0, import_node_fs23.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6096
+ const pyprojectPaths = (0, import_node_fs24.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
5873
6097
  for (const relativePath of pyprojectPaths) {
5874
6098
  let content;
5875
6099
  try {
5876
- content = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8");
6100
+ content = (0, import_node_fs24.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
5877
6101
  } catch {
5878
6102
  continue;
5879
6103
  }
@@ -5884,14 +6108,14 @@ function collectPip(workspaceRoot) {
5884
6108
  }
5885
6109
  const requirementsPaths = [
5886
6110
  "requirements-dev.txt",
5887
- ...(0, import_node_fs23.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6111
+ ...(0, import_node_fs24.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
5888
6112
  ];
5889
6113
  for (const relativePath of requirementsPaths) {
5890
- if (!fileExists((0, import_node_path26.join)(workspaceRoot, relativePath))) {
6114
+ if (!fileExists((0, import_node_path27.join)(workspaceRoot, relativePath))) {
5891
6115
  continue;
5892
6116
  }
5893
6117
  const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
5894
- const lines = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6118
+ const lines = (0, import_node_fs24.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
5895
6119
  for (const line of lines) {
5896
6120
  push(relativePath, section, line);
5897
6121
  }
@@ -5929,11 +6153,11 @@ function pyprojectDependencies(content) {
5929
6153
  }
5930
6154
  function collectPub(workspaceRoot) {
5931
6155
  const sites = [];
5932
- const pubspecPaths = (0, import_node_fs23.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6156
+ const pubspecPaths = (0, import_node_fs24.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
5933
6157
  for (const relativePath of pubspecPaths) {
5934
6158
  let content;
5935
6159
  try {
5936
- content = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8");
6160
+ content = (0, import_node_fs24.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
5937
6161
  } catch {
5938
6162
  continue;
5939
6163
  }
@@ -5943,7 +6167,7 @@ function collectPub(workspaceRoot) {
5943
6167
  name: entry.name,
5944
6168
  ecosystem: "pub",
5945
6169
  project: projectOf(relativePath),
5946
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath),
6170
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
5947
6171
  section: block === "dependencies" ? "dep" : "devDep",
5948
6172
  spec: entry.spec,
5949
6173
  rewritable: entry.spec !== ""
@@ -5993,11 +6217,11 @@ function stripQuotes(value) {
5993
6217
  }
5994
6218
  function collectNuget(workspaceRoot) {
5995
6219
  const sites = [];
5996
- const csprojPaths = (0, import_node_fs23.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6220
+ const csprojPaths = (0, import_node_fs24.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
5997
6221
  for (const relativePath of csprojPaths) {
5998
6222
  let content;
5999
6223
  try {
6000
- content = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8");
6224
+ content = (0, import_node_fs24.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6001
6225
  } catch {
6002
6226
  continue;
6003
6227
  }
@@ -6006,7 +6230,7 @@ function collectNuget(workspaceRoot) {
6006
6230
  name: entry.name,
6007
6231
  ecosystem: "nuget",
6008
6232
  project: projectOf(relativePath),
6009
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath),
6233
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6010
6234
  section: "dep",
6011
6235
  spec: entry.spec,
6012
6236
  // A plain SemVer string is rewritable; an MSBuild property reference
@@ -6031,13 +6255,13 @@ function csprojPackageReferences(content) {
6031
6255
  return entries;
6032
6256
  }
6033
6257
  function collectGo(workspaceRoot) {
6034
- const manifestPath = (0, import_node_path26.join)(workspaceRoot, "go.mod");
6258
+ const manifestPath = (0, import_node_path27.join)(workspaceRoot, "go.mod");
6035
6259
  if (!fileExists(manifestPath)) {
6036
6260
  return [];
6037
6261
  }
6038
6262
  let content;
6039
6263
  try {
6040
- content = (0, import_node_fs23.readFileSync)(manifestPath, "utf8");
6264
+ content = (0, import_node_fs24.readFileSync)(manifestPath, "utf8");
6041
6265
  } catch {
6042
6266
  return [];
6043
6267
  }
@@ -6086,7 +6310,7 @@ var PROJECT_GLOBS = {
6086
6310
  function locateProjects(workspaceRoot) {
6087
6311
  const locations = [];
6088
6312
  for (const ecosystem of ECOSYSTEMS) {
6089
- const relativePaths = (0, import_node_fs23.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6313
+ const relativePaths = (0, import_node_fs24.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6090
6314
  for (const relativePath of relativePaths) {
6091
6315
  const posix = toPosix(relativePath);
6092
6316
  const dir = posix.slice(0, posix.lastIndexOf("/"));
@@ -6094,7 +6318,7 @@ function locateProjects(workspaceRoot) {
6094
6318
  ecosystem,
6095
6319
  dir,
6096
6320
  name: dir.slice(dir.lastIndexOf("/") + 1),
6097
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath)
6321
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath)
6098
6322
  });
6099
6323
  }
6100
6324
  }
@@ -6115,7 +6339,7 @@ function rewriteSpec(site, spec) {
6115
6339
  writeFileEnsured(site.manifestPath, toJson(manifest));
6116
6340
  return true;
6117
6341
  }
6118
- const before = (0, import_node_fs23.readFileSync)(site.manifestPath, "utf8");
6342
+ const before = (0, import_node_fs24.readFileSync)(site.manifestPath, "utf8");
6119
6343
  const after = (() => {
6120
6344
  switch (site.ecosystem) {
6121
6345
  case "pip": {
@@ -6206,13 +6430,13 @@ function escapeForRegex(value) {
6206
6430
  function isWorkspaceProject(workspaceRoot, name) {
6207
6431
  const short = name.includes("/") ? name.split("/").at(-1) : name;
6208
6432
  return ["apps", "libs", "packages"].some(
6209
- (directory) => fileExists((0, import_node_path26.join)(workspaceRoot, directory, short ?? name, "package.json"))
6433
+ (directory) => fileExists((0, import_node_path27.join)(workspaceRoot, directory, short ?? name, "package.json"))
6210
6434
  );
6211
6435
  }
6212
6436
  function isAliasedInstall(workspaceRoot, name) {
6213
6437
  try {
6214
6438
  const installed = readJson(
6215
- (0, import_node_path26.join)(workspaceRoot, "node_modules", name, "package.json")
6439
+ (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6216
6440
  );
6217
6441
  return installed.name !== void 0 && installed.name !== name;
6218
6442
  } catch {
@@ -6223,14 +6447,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6223
6447
  if (ecosystem === "npm") {
6224
6448
  try {
6225
6449
  return readJson(
6226
- (0, import_node_path26.join)(workspaceRoot, "node_modules", name, "package.json")
6450
+ (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6227
6451
  ).version;
6228
6452
  } catch {
6229
6453
  return void 0;
6230
6454
  }
6231
6455
  }
6232
6456
  if (ecosystem === "pub") {
6233
- const lockPath = (0, import_node_path26.join)(workspaceRoot, "pubspec.lock");
6457
+ const lockPath = (0, import_node_path27.join)(workspaceRoot, "pubspec.lock");
6234
6458
  if (!fileExists(lockPath)) {
6235
6459
  return void 0;
6236
6460
  }
@@ -6238,7 +6462,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6238
6462
  const match = new RegExp(
6239
6463
  String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
6240
6464
  "m"
6241
- ).exec((0, import_node_fs23.readFileSync)(lockPath, "utf8"));
6465
+ ).exec((0, import_node_fs24.readFileSync)(lockPath, "utf8"));
6242
6466
  return match?.[1];
6243
6467
  } catch {
6244
6468
  return void 0;
@@ -6304,7 +6528,7 @@ function resolveTarget(locations, target) {
6304
6528
  return byName[0];
6305
6529
  }
6306
6530
  function installInto(workspaceRoot, location, packages, saveDev) {
6307
- const projectDir = (0, import_node_path27.join)(workspaceRoot, location.dir);
6531
+ const projectDir = (0, import_node_path28.join)(workspaceRoot, location.dir);
6308
6532
  switch (location.ecosystem) {
6309
6533
  case "npm": {
6310
6534
  const flags = saveDev ? ["--save-dev"] : [];
@@ -6357,7 +6581,7 @@ function installInto(workspaceRoot, location, packages, saveDev) {
6357
6581
  function addPythonDependency(manifestPath, specifier) {
6358
6582
  let content;
6359
6583
  try {
6360
- content = (0, import_node_fs24.readFileSync)(manifestPath, "utf8");
6584
+ content = (0, import_node_fs25.readFileSync)(manifestPath, "utf8");
6361
6585
  } catch {
6362
6586
  logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
6363
6587
  return;
@@ -6386,7 +6610,7 @@ function installEverything(workspaceRoot, only) {
6386
6610
  }
6387
6611
  function ecosystemPresent(workspaceRoot, ecosystem) {
6388
6612
  if (ecosystem === "go") {
6389
- return fileExists((0, import_node_path27.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path27.join)(workspaceRoot, "go.mod"));
6613
+ return fileExists((0, import_node_path28.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path28.join)(workspaceRoot, "go.mod"));
6390
6614
  }
6391
6615
  return hasEcosystem(workspaceRoot, ecosystem);
6392
6616
  }
@@ -6405,7 +6629,7 @@ function splitAtLast(value, separator) {
6405
6629
  }
6406
6630
 
6407
6631
  // src/dependency-management/sync-dependencies.use-case.ts
6408
- var import_node_path28 = require("path");
6632
+ var import_node_path29 = require("path");
6409
6633
 
6410
6634
  // src/dependency-management/semver.algorithm.ts
6411
6635
  var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
@@ -6582,7 +6806,7 @@ function describe(finding) {
6582
6806
  return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
6583
6807
  }
6584
6808
  function runSync(workspaceRoot, options) {
6585
- if (!fileExists((0, import_node_path28.join)(workspaceRoot, "nx.json"))) {
6809
+ if (!fileExists((0, import_node_path29.join)(workspaceRoot, "nx.json"))) {
6586
6810
  throw new Error(
6587
6811
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
6588
6812
  );
@@ -6632,7 +6856,7 @@ function runSync(workspaceRoot, options) {
6632
6856
  }
6633
6857
 
6634
6858
  // src/dependency-management/update-dependencies.use-case.ts
6635
- var import_node_path29 = require("path");
6859
+ var import_node_path30 = require("path");
6636
6860
  var import_prompts2 = require("@inquirer/prompts");
6637
6861
 
6638
6862
  // src/dependency-management/registry.client.ts
@@ -6915,7 +7139,7 @@ function reinstall(workspaceRoot, ecosystems) {
6915
7139
  function hasPythonInstallScript(workspaceRoot) {
6916
7140
  try {
6917
7141
  const manifest = readJson(
6918
- (0, import_node_path29.join)(workspaceRoot, "package.json")
7142
+ (0, import_node_path30.join)(workspaceRoot, "package.json")
6919
7143
  );
6920
7144
  return manifest.scripts?.["python:install"] !== void 0;
6921
7145
  } catch {
@@ -6931,7 +7155,7 @@ function applyGoUpdates(workspaceRoot, entries) {
6931
7155
  }
6932
7156
  }
6933
7157
  async function runUp(workspaceRoot, options) {
6934
- if (!fileExists((0, import_node_path29.join)(workspaceRoot, "nx.json"))) {
7158
+ if (!fileExists((0, import_node_path30.join)(workspaceRoot, "nx.json"))) {
6935
7159
  throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
6936
7160
  }
6937
7161
  const ecosystems = resolveEcosystems(options.ecosystem);
@@ -7008,7 +7232,7 @@ var PROJECT_KINDS = [
7008
7232
  var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
7009
7233
  async function runAdd(kind, name, options) {
7010
7234
  const workspaceRoot = process.cwd();
7011
- if (!fileExists((0, import_node_path30.join)(workspaceRoot, "nx.json"))) {
7235
+ if (!fileExists((0, import_node_path31.join)(workspaceRoot, "nx.json"))) {
7012
7236
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
7013
7237
  }
7014
7238
  const stack = readWorkspaceStack(workspaceRoot);
@@ -7071,8 +7295,8 @@ async function runAdd(kind, name, options) {
7071
7295
  ],
7072
7296
  workspaceRoot
7073
7297
  );
7074
- markPrivate((0, import_node_path30.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7075
- renameScaffoldPlaceholder((0, import_node_path30.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7298
+ markPrivate((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7299
+ renameScaffoldPlaceholder((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7076
7300
  removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
7077
7301
  registerProjectCommands(workspaceRoot, resolvedName, { build: true });
7078
7302
  break;
@@ -7164,7 +7388,7 @@ async function runAdd(kind, name, options) {
7164
7388
  }
7165
7389
  function readWorkspaceStack(workspaceRoot) {
7166
7390
  const nxJson = readJson(
7167
- (0, import_node_path30.join)(workspaceRoot, "nx.json")
7391
+ (0, import_node_path31.join)(workspaceRoot, "nx.json")
7168
7392
  );
7169
7393
  const stack = nxJson.mnci?.stack;
7170
7394
  return {
@@ -7213,15 +7437,15 @@ function runKinds(options) {
7213
7437
 
7214
7438
  // src/workspace-diagnostics/check-invariants.use-case.ts
7215
7439
  var import_node_child_process = require("child_process");
7216
- var import_node_fs25 = require("fs");
7217
- var import_node_path31 = require("path");
7440
+ var import_node_fs26 = require("fs");
7441
+ var import_node_path32 = require("path");
7218
7442
  var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
7219
7443
  function toPosix2(path) {
7220
7444
  return path.replaceAll("\\", "/");
7221
7445
  }
7222
7446
  function checkEslintConfigs(workspaceRoot) {
7223
- const rootConfigs = (0, import_node_fs25.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7224
- const projectConfigs = (0, import_node_fs25.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7447
+ const rootConfigs = (0, import_node_fs26.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7448
+ const projectConfigs = (0, import_node_fs26.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7225
7449
  cwd: workspaceRoot
7226
7450
  }).map((config) => toPosix2(config));
7227
7451
  return [
@@ -7241,10 +7465,10 @@ function checkEslintConfigs(workspaceRoot) {
7241
7465
  ];
7242
7466
  }
7243
7467
  function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7244
- const rules = (0, import_node_path31.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7245
- if (!(0, import_node_fs25.existsSync)(rules)) return [];
7246
- const entryPoint = (0, import_node_path31.join)(workspaceRoot, ESLINT_USER_FILENAME);
7247
- const source = (0, import_node_fs25.existsSync)(entryPoint) ? (0, import_node_fs25.readFileSync)(entryPoint, "utf8") : "";
7468
+ const rules = (0, import_node_path32.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7469
+ if (!(0, import_node_fs26.existsSync)(rules)) return [];
7470
+ const entryPoint = (0, import_node_path32.join)(workspaceRoot, ESLINT_USER_FILENAME);
7471
+ const source = (0, import_node_fs26.existsSync)(entryPoint) ? (0, import_node_fs26.readFileSync)(entryPoint, "utf8") : "";
7248
7472
  return [
7249
7473
  {
7250
7474
  check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
@@ -7257,7 +7481,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7257
7481
  function declaredDevDependencies(workspaceRoot) {
7258
7482
  try {
7259
7483
  const manifest = readJson(
7260
- (0, import_node_path31.join)(workspaceRoot, "package.json")
7484
+ (0, import_node_path32.join)(workspaceRoot, "package.json")
7261
7485
  );
7262
7486
  return manifest.devDependencies ?? {};
7263
7487
  } catch {
@@ -7265,7 +7489,7 @@ function declaredDevDependencies(workspaceRoot) {
7265
7489
  }
7266
7490
  }
7267
7491
  function checkNoRetiredFormatter(workspaceRoot) {
7268
- const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path31.join)(workspaceRoot, file)));
7492
+ const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file)));
7269
7493
  const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
7270
7494
  const stale = [...files, ...declared];
7271
7495
  if (stale.length === 0) {
@@ -7291,7 +7515,7 @@ function checkEslintPlugin(nxJson) {
7291
7515
  };
7292
7516
  }
7293
7517
  function checkResolvedEslint(workspaceRoot) {
7294
- const manifestPath = (0, import_node_path31.join)(workspaceRoot, "node_modules/eslint/package.json");
7518
+ const manifestPath = (0, import_node_path32.join)(workspaceRoot, "node_modules/eslint/package.json");
7295
7519
  if (!fileExists(manifestPath)) {
7296
7520
  return void 0;
7297
7521
  }
@@ -7309,11 +7533,11 @@ function checkResolvedEslint(workspaceRoot) {
7309
7533
  }
7310
7534
  }
7311
7535
  function checkNpmrc(workspaceRoot, registry, scope) {
7312
- const npmrcPath = (0, import_node_path31.join)(workspaceRoot, ".npmrc");
7536
+ const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7313
7537
  if (!registry || !fileExists(npmrcPath)) {
7314
7538
  return void 0;
7315
7539
  }
7316
- const npmrc = (0, import_node_fs25.readFileSync)(npmrcPath, "utf8");
7540
+ const npmrc = (0, import_node_fs26.readFileSync)(npmrcPath, "utf8");
7317
7541
  if (registry.kind === "npm") {
7318
7542
  return {
7319
7543
  check: ".npmrc authenticates the public registry",
@@ -7330,11 +7554,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
7330
7554
  };
7331
7555
  }
7332
7556
  function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
7333
- const npmrcPath = (0, import_node_path31.join)(workspaceRoot, ".npmrc");
7557
+ const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7334
7558
  if (!fileExists(npmrcPath)) {
7335
7559
  return void 0;
7336
7560
  }
7337
- const npmrc = (0, import_node_fs25.readFileSync)(npmrcPath, "utf8");
7561
+ const npmrc = (0, import_node_fs26.readFileSync)(npmrcPath, "utf8");
7338
7562
  const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7339
7563
  const referenced = [
7340
7564
  ...new Set(
@@ -7358,13 +7582,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
7358
7582
  };
7359
7583
  }
7360
7584
  function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
7361
- const npmrcPath = (0, import_node_path31.join)(workspaceRoot, ".npmrc");
7362
- const pipelinePath = (0, import_node_path31.join)(workspaceRoot, "azure-pipelines.yml");
7585
+ const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7586
+ const pipelinePath = (0, import_node_path32.join)(workspaceRoot, "azure-pipelines.yml");
7363
7587
  if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
7364
7588
  return void 0;
7365
7589
  }
7366
- const holdsCredentials = (0, import_node_fs25.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7367
- const runsTask = (0, import_node_fs25.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7590
+ const holdsCredentials = (0, import_node_fs26.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7591
+ const runsTask = (0, import_node_fs26.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7368
7592
  if (!holdsCredentials && !runsTask) {
7369
7593
  return {
7370
7594
  check: "npm auth: .npmrc and azure-pipelines.yml agree",
@@ -7409,13 +7633,13 @@ function npmjsCredentialShape(credentials, environment) {
7409
7633
  }
7410
7634
  function checkVersionActions(workspaceRoot) {
7411
7635
  const candidates = [
7412
- ...(0, import_node_fs25.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
7413
- ...(0, import_node_fs25.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
7414
- ...(0, import_node_fs25.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
7636
+ ...(0, import_node_fs26.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
7637
+ ...(0, import_node_fs26.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
7638
+ ...(0, import_node_fs26.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
7415
7639
  ].map((manifest) => toPosix2(manifest));
7416
7640
  return candidates.flatMap((manifest) => {
7417
7641
  const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
7418
- const projectJsonPath = (0, import_node_path31.join)(workspaceRoot, projectRoot, "project.json");
7642
+ const projectJsonPath = (0, import_node_path32.join)(workspaceRoot, projectRoot, "project.json");
7419
7643
  let hasOverride = false;
7420
7644
  try {
7421
7645
  const projectJson = readJson(projectJsonPath);
@@ -7444,7 +7668,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
7444
7668
  ]) {
7445
7669
  try {
7446
7670
  const targets = extract(
7447
- readJson((0, import_node_path31.join)(workspaceRoot, projectRoot, file))
7671
+ readJson((0, import_node_path32.join)(workspaceRoot, projectRoot, file))
7448
7672
  );
7449
7673
  if (targets && typeof targets === "object") {
7450
7674
  sources.push({
@@ -7460,8 +7684,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
7460
7684
  function checkTargetFilesExist(workspaceRoot) {
7461
7685
  const projectRoots = new Set(
7462
7686
  [
7463
- ...(0, import_node_fs25.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
7464
- ...(0, import_node_fs25.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
7687
+ ...(0, import_node_fs26.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
7688
+ ...(0, import_node_fs26.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
7465
7689
  ].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
7466
7690
  );
7467
7691
  return [...projectRoots].flatMap(
@@ -7476,7 +7700,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
7476
7700
  return TARGET_FILE_OPTIONS.flatMap((option) => {
7477
7701
  const value = target?.options?.[option];
7478
7702
  const checkable = typeof value === "string" && !value.includes("{");
7479
- if (!checkable || fileExists((0, import_node_path31.join)(workspaceRoot, value))) {
7703
+ if (!checkable || fileExists((0, import_node_path32.join)(workspaceRoot, value))) {
7480
7704
  return [];
7481
7705
  }
7482
7706
  return [
@@ -7515,15 +7739,15 @@ function checkGoPluginRegistered(workspaceRoot) {
7515
7739
  };
7516
7740
  }
7517
7741
  function checkGoWorkInSync(workspaceRoot) {
7518
- const goWorkPath = (0, import_node_path31.join)(workspaceRoot, "go.work");
7742
+ const goWorkPath = (0, import_node_path32.join)(workspaceRoot, "go.work");
7519
7743
  if (!fileExists(goWorkPath)) {
7520
7744
  return void 0;
7521
7745
  }
7522
- const contents = (0, import_node_fs25.existsSync)(goWorkPath) ? (0, import_node_fs25.readFileSync)(goWorkPath, "utf8") : "";
7746
+ const contents = (0, import_node_fs26.existsSync)(goWorkPath) ? (0, import_node_fs26.readFileSync)(goWorkPath, "utf8") : "";
7523
7747
  const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
7524
7748
  const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
7525
7749
  const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
7526
- const stale = uses.filter((entry) => !(0, import_node_fs25.existsSync)((0, import_node_path31.join)(workspaceRoot, entry, "go.mod")));
7750
+ const stale = uses.filter((entry) => !(0, import_node_fs26.existsSync)((0, import_node_path32.join)(workspaceRoot, entry, "go.mod")));
7527
7751
  return {
7528
7752
  check: "every go.work `use` entry points to a module that still exists",
7529
7753
  ok: stale.length === 0,
@@ -7539,9 +7763,9 @@ function checkNativeApps(workspaceRoot) {
7539
7763
  { file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
7540
7764
  { file: "azure-pipelines.yml", marker: "- job: native" }
7541
7765
  ];
7542
- const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path31.join)(workspaceRoot, file))).map(({ file, marker }) => ({
7766
+ const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).map(({ file, marker }) => ({
7543
7767
  check: `${file} builds the native apps on every OS`,
7544
- ok: (0, import_node_fs25.readFileSync)((0, import_node_path31.join)(workspaceRoot, file), "utf8").includes(marker),
7768
+ ok: (0, import_node_fs26.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8").includes(marker),
7545
7769
  detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
7546
7770
  remedy: "run `mnci upgrade`"
7547
7771
  }));
@@ -7554,7 +7778,7 @@ function checkNativeApps(workspaceRoot) {
7554
7778
  return findings;
7555
7779
  }
7556
7780
  function checkNoRootRuntimeDependencies(workspaceRoot) {
7557
- const manifestPath = (0, import_node_path31.join)(workspaceRoot, "package.json");
7781
+ const manifestPath = (0, import_node_path32.join)(workspaceRoot, "package.json");
7558
7782
  if (!fileExists(manifestPath)) {
7559
7783
  return void 0;
7560
7784
  }
@@ -7574,14 +7798,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
7574
7798
  };
7575
7799
  }
7576
7800
  function checkRollupSourceMaps(workspaceRoot) {
7577
- const configs = (0, import_node_fs25.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7801
+ const configs = (0, import_node_fs26.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7578
7802
  cwd: workspaceRoot
7579
7803
  }).map((config) => toPosix2(config));
7580
7804
  return configs.flatMap((relativePath) => {
7581
- const configPath = (0, import_node_path31.join)(workspaceRoot, relativePath);
7805
+ const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
7582
7806
  let config;
7583
7807
  try {
7584
- config = (0, import_node_fs25.readFileSync)(configPath, "utf8");
7808
+ config = (0, import_node_fs26.readFileSync)(configPath, "utf8");
7585
7809
  } catch {
7586
7810
  return [];
7587
7811
  }
@@ -7596,11 +7820,11 @@ function checkRollupSourceMaps(workspaceRoot) {
7596
7820
  });
7597
7821
  }
7598
7822
  function checkDeclarationSpecifiers(workspaceRoot) {
7599
- const configs = (0, import_node_fs25.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7823
+ const configs = (0, import_node_fs26.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7600
7824
  cwd: workspaceRoot
7601
7825
  }).map((config) => toPosix2(config));
7602
7826
  return configs.flatMap((relativePath) => {
7603
- const configPath = (0, import_node_path31.join)(workspaceRoot, relativePath);
7827
+ const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
7604
7828
  if (!fileExists(configPath)) {
7605
7829
  return [];
7606
7830
  }
@@ -7633,8 +7857,40 @@ function checkDeclarationSpecifiers(workspaceRoot) {
7633
7857
  ];
7634
7858
  });
7635
7859
  }
7860
+ function checkPipelinePhases(workspaceRoot) {
7861
+ const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
7862
+ return files.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).flatMap((file) => {
7863
+ const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs26.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8"));
7864
+ const verify = {
7865
+ check: `${file} runs the enforced verify phase`,
7866
+ ok: verifyActive,
7867
+ detail: `${file} has no active \`mnci ci verify\` call, so CI would build and release code nothing checked`,
7868
+ remedy: "run `mnci upgrade`, which restores it"
7869
+ };
7870
+ const warnings = switchedOff.map((phase) => ({
7871
+ check: `${file}: the ${phase} phase is switched off`,
7872
+ ok: true,
7873
+ warning: true,
7874
+ detail: `${file} does not run \`mnci ci ${phase}\``,
7875
+ remedy: `uncomment the ${phase} block in ${file} to run it again`
7876
+ }));
7877
+ return [verify, ...warnings];
7878
+ });
7879
+ }
7880
+ function checkNativeBuildConfig(workspaceRoot) {
7881
+ const { problems } = readNativeBuildConfig(workspaceRoot);
7882
+ if (problems.length === 0) {
7883
+ return [];
7884
+ }
7885
+ return [{
7886
+ check: "mnci.native in nx.json is valid",
7887
+ ok: false,
7888
+ detail: problems.join("; "),
7889
+ remedy: "fix the entry in the mnci block of nx.json, then run `mnci upgrade`"
7890
+ }];
7891
+ }
7636
7892
  function collectFindings(workspaceRoot) {
7637
- const nxJsonPath = (0, import_node_path31.join)(workspaceRoot, "nx.json");
7893
+ const nxJsonPath = (0, import_node_path32.join)(workspaceRoot, "nx.json");
7638
7894
  if (!fileExists(nxJsonPath)) {
7639
7895
  throw new Error(
7640
7896
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
@@ -7657,7 +7913,9 @@ function collectFindings(workspaceRoot) {
7657
7913
  checkSync(workspaceRoot),
7658
7914
  checkGoPluginRegistered(workspaceRoot),
7659
7915
  checkGoWorkInSync(workspaceRoot),
7660
- ...checkNativeApps(workspaceRoot)
7916
+ ...checkNativeApps(workspaceRoot),
7917
+ ...checkPipelinePhases(workspaceRoot),
7918
+ ...checkNativeBuildConfig(workspaceRoot)
7661
7919
  ].filter((finding) => finding !== void 0);
7662
7920
  }
7663
7921
  function runDoctor(workspaceRoot, options = {}) {
@@ -7671,7 +7929,12 @@ function runDoctor(workspaceRoot, options = {}) {
7671
7929
  return;
7672
7930
  }
7673
7931
  for (const finding of findings) {
7674
- if (finding.ok) {
7932
+ if (finding.ok && finding.warning === true) {
7933
+ logger.warn(`${finding.check} \u2014 ${finding.detail ?? ""}`);
7934
+ if (finding.remedy) {
7935
+ logger.info(` to change it: ${finding.remedy}`);
7936
+ }
7937
+ } else if (finding.ok) {
7675
7938
  logger.success(finding.check);
7676
7939
  } else {
7677
7940
  logger.error(`${finding.check} \u2014 ${finding.detail ?? "failed"}`);
@@ -7758,11 +8021,11 @@ function runCommands(program, options) {
7758
8021
  }
7759
8022
 
7760
8023
  // src/workspace-info/list-projects.use-case.ts
7761
- var import_node_path32 = require("path");
8024
+ var import_node_path33 = require("path");
7762
8025
  var TYPE_TAG_PREFIX = "type:";
7763
8026
  function listProjects(workspaceRoot) {
7764
8027
  return locateProjects(workspaceRoot).map((location) => {
7765
- const projectJsonPath = (0, import_node_path32.join)(workspaceRoot, location.dir, "project.json");
8028
+ const projectJsonPath = (0, import_node_path33.join)(workspaceRoot, location.dir, "project.json");
7766
8029
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
7767
8030
  const typeTag = (project.tags ?? []).find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
7768
8031
  return {
@@ -7775,7 +8038,7 @@ function listProjects(workspaceRoot) {
7775
8038
  }).toSorted((a, b) => a.dir.localeCompare(b.dir));
7776
8039
  }
7777
8040
  function runProjects(workspaceRoot, options) {
7778
- if (!fileExists((0, import_node_path32.join)(workspaceRoot, "nx.json"))) {
8041
+ if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
7779
8042
  throw new Error("No nx.json found here. Run `projects` from the workspace root.");
7780
8043
  }
7781
8044
  const projects = listProjects(workspaceRoot);
@@ -7789,13 +8052,13 @@ function runProjects(workspaceRoot, options) {
7789
8052
  }
7790
8053
 
7791
8054
  // src/workspace-info/read-workspace-info.use-case.ts
7792
- var import_node_path34 = require("path");
8055
+ var import_node_path35 = require("path");
7793
8056
 
7794
8057
  // src/cli-version/check-for-update.use-case.ts
7795
- var import_node_fs26 = require("fs");
7796
- var import_node_path33 = require("path");
8058
+ var import_node_fs27 = require("fs");
8059
+ var import_node_path34 = require("path");
7797
8060
  var import_cross_spawn3 = __toESM(require("cross-spawn"));
7798
- var PACKAGE_NAME = "@mnci/cli";
8061
+ var PACKAGE_NAME2 = "@mnci/cli";
7799
8062
  var REGISTRY_TIMEOUT_MS = 2e3;
7800
8063
  function checkForUpdate(currentVersion2) {
7801
8064
  try {
@@ -7812,7 +8075,7 @@ function checkForUpdate(currentVersion2) {
7812
8075
  }
7813
8076
  }
7814
8077
  function fetchLatestVersion() {
7815
- const result = import_cross_spawn3.default.sync("npm", ["view", PACKAGE_NAME, "version"], {
8078
+ const result = import_cross_spawn3.default.sync("npm", ["view", PACKAGE_NAME2, "version"], {
7816
8079
  encoding: "utf8",
7817
8080
  timeout: REGISTRY_TIMEOUT_MS,
7818
8081
  stdio: ["ignore", "pipe", "ignore"]
@@ -7828,9 +8091,9 @@ function reportIfOutdated(currentVersion2) {
7828
8091
  return;
7829
8092
  }
7830
8093
  logger.info("");
7831
- logger.info(`A new version of ${PACKAGE_NAME} is available: ${latestVersion}`);
8094
+ logger.info(`A new version of ${PACKAGE_NAME2} is available: ${latestVersion}`);
7832
8095
  logger.info(` Current version: ${currentVersion2}`);
7833
- logger.info(` Update with: npm install -g ${PACKAGE_NAME}@latest`);
8096
+ logger.info(` Update with: npm install -g ${PACKAGE_NAME2}@latest`);
7834
8097
  logger.info("");
7835
8098
  }
7836
8099
  function isNewerVersion(candidate, current) {
@@ -7852,8 +8115,8 @@ function releaseTriple(version) {
7852
8115
  }
7853
8116
  function readCliVersion(packageDirectory) {
7854
8117
  try {
7855
- const manifestPath = (0, import_node_path33.join)(packageDirectory, "..", "package.json");
7856
- const manifest = JSON.parse((0, import_node_fs26.readFileSync)(manifestPath, "utf8"));
8118
+ const manifestPath = (0, import_node_path34.join)(packageDirectory, "..", "package.json");
8119
+ const manifest = JSON.parse((0, import_node_fs27.readFileSync)(manifestPath, "utf8"));
7857
8120
  return manifest.version ?? "0.0.0";
7858
8121
  } catch {
7859
8122
  return "0.0.0";
@@ -7863,7 +8126,7 @@ function readCliVersion(packageDirectory) {
7863
8126
  // src/workspace-info/read-workspace-info.use-case.ts
7864
8127
  function readWorkspaceInfo(workspaceRoot, cliVersion) {
7865
8128
  const latest = fetchLatestVersion() ?? null;
7866
- const isWorkspace = fileExists((0, import_node_path34.join)(workspaceRoot, "nx.json"));
8129
+ const isWorkspace = fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"));
7867
8130
  return {
7868
8131
  cli: {
7869
8132
  version: cliVersion,
@@ -7884,8 +8147,8 @@ function runInfo(workspaceRoot, cliVersion, options) {
7884
8147
  }
7885
8148
 
7886
8149
  // src/workspace-creation/adopt-directory.use-case.ts
7887
- var import_node_fs27 = require("fs");
7888
- var import_node_path35 = require("path");
8150
+ var import_node_fs28 = require("fs");
8151
+ var import_node_path36 = require("path");
7889
8152
  var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
7890
8153
  var AGENT_AND_CI_ENTRIES = [
7891
8154
  "AGENTS.md",
@@ -7916,13 +8179,13 @@ var PREFLIGHT_BLOCKERS = [
7916
8179
  "packages"
7917
8180
  ];
7918
8181
  function assertAdoptableDirectory(target) {
7919
- if (!(0, import_node_fs27.existsSync)(target)) {
8182
+ if (!(0, import_node_fs28.existsSync)(target)) {
7920
8183
  throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
7921
8184
  }
7922
- if (!(0, import_node_fs27.statSync)(target).isDirectory()) {
8185
+ if (!(0, import_node_fs28.statSync)(target).isDirectory()) {
7923
8186
  throw new Error(`--into '${target}' is not a directory.`);
7924
8187
  }
7925
- const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs27.existsSync)((0, import_node_path35.join)(target, entry)));
8188
+ const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs28.existsSync)((0, import_node_path36.join)(target, entry)));
7926
8189
  if (blockers.length > 0) {
7927
8190
  throw new Error(
7928
8191
  `--into '${target}' already holds ${blockers.join(", ")}, so it is a project already. Use \`mnci upgrade\` to re-apply the overlay to an existing workspace, or point --into at an empty checkout.`
@@ -7930,15 +8193,15 @@ function assertAdoptableDirectory(target) {
7930
8193
  }
7931
8194
  }
7932
8195
  function mergeGitignore(generatedFile, targetFile) {
7933
- const existing = (0, import_node_fs27.readFileSync)(targetFile, "utf8");
8196
+ const existing = (0, import_node_fs28.readFileSync)(targetFile, "utf8");
7934
8197
  const present = new Set(existing.split("\n").map((line) => line.trim()));
7935
- const additions = (0, import_node_fs27.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8198
+ const additions = (0, import_node_fs28.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
7936
8199
  const trimmed = line.trim();
7937
8200
  return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
7938
8201
  });
7939
8202
  if (additions.length === 0) return false;
7940
8203
  const separator = existing.endsWith("\n") ? "" : "\n";
7941
- (0, import_node_fs27.writeFileSync)(
8204
+ (0, import_node_fs28.writeFileSync)(
7942
8205
  targetFile,
7943
8206
  `${existing}${separator}
7944
8207
  # Added by mnci (Nx workspace)
@@ -7948,9 +8211,9 @@ ${additions.join("\n")}
7948
8211
  return true;
7949
8212
  }
7950
8213
  function adoptGeneratedWorkspace(generatedRoot, target) {
7951
- const entries = (0, import_node_fs27.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8214
+ const entries = (0, import_node_fs28.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
7952
8215
  const collisions = entries.filter(
7953
- (entry) => (0, import_node_fs27.existsSync)((0, import_node_path35.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8216
+ (entry) => (0, import_node_fs28.existsSync)((0, import_node_path36.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
7954
8217
  );
7955
8218
  if (collisions.length > 0) {
7956
8219
  throw new Error(
@@ -7959,28 +8222,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
7959
8222
  }
7960
8223
  const result = { copied: [], kept: [], mergedGitignore: false };
7961
8224
  for (const entry of entries) {
7962
- const from = (0, import_node_path35.join)(generatedRoot, entry);
7963
- const to = (0, import_node_path35.join)(target, entry);
7964
- if (entry === ".gitignore" && (0, import_node_fs27.existsSync)(to)) {
8225
+ const from = (0, import_node_path36.join)(generatedRoot, entry);
8226
+ const to = (0, import_node_path36.join)(target, entry);
8227
+ if (entry === ".gitignore" && (0, import_node_fs28.existsSync)(to)) {
7965
8228
  result.mergedGitignore = mergeGitignore(from, to);
7966
8229
  result.kept.push(entry);
7967
8230
  continue;
7968
8231
  }
7969
- if ((0, import_node_fs27.existsSync)(to)) {
8232
+ if ((0, import_node_fs28.existsSync)(to)) {
7970
8233
  result.kept.push(entry);
7971
8234
  continue;
7972
8235
  }
7973
- (0, import_node_fs27.cpSync)(from, to, { recursive: true });
8236
+ (0, import_node_fs28.cpSync)(from, to, { recursive: true });
7974
8237
  result.copied.push(entry);
7975
8238
  }
7976
- (0, import_node_fs27.rmSync)(generatedRoot, { recursive: true, force: true });
8239
+ (0, import_node_fs28.rmSync)(generatedRoot, { recursive: true, force: true });
7977
8240
  return result;
7978
8241
  }
7979
8242
 
7980
8243
  // src/workspace-creation/create-workspace.use-case.ts
7981
- var import_node_fs28 = require("fs");
8244
+ var import_node_fs29 = require("fs");
7982
8245
  var import_node_os2 = require("os");
7983
- var import_node_path36 = require("path");
8246
+ var import_node_path37 = require("path");
7984
8247
  function nxCloudProviderValue(ci) {
7985
8248
  return ci === "azure" ? "azure" : "github";
7986
8249
  }
@@ -8023,9 +8286,9 @@ async function resolveRegistry(options) {
8023
8286
  return await promptRegistry();
8024
8287
  }
8025
8288
  async function runNew(name, options) {
8026
- const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path36.resolve)(process.cwd(), options.into);
8289
+ const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path37.resolve)(process.cwd(), options.into);
8027
8290
  if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
8028
- const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path36.basename)(adoptTarget));
8291
+ const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path37.basename)(adoptTarget));
8029
8292
  assertValidProjectName(workspaceName, "Workspace name");
8030
8293
  const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
8031
8294
  const registry = await resolveRegistry(options);
@@ -8038,8 +8301,8 @@ async function runNew(name, options) {
8038
8301
  const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
8039
8302
  const stack = await resolveStack(options);
8040
8303
  const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
8041
- const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs28.mkdtempSync)((0, import_node_path36.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8042
- let workspaceRoot = (0, import_node_path36.join)(stagingParent, workspaceName);
8304
+ const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs29.mkdtempSync)((0, import_node_path37.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8305
+ let workspaceRoot = (0, import_node_path37.join)(stagingParent, workspaceName);
8043
8306
  try {
8044
8307
  logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
8045
8308
  runNpx(
@@ -8062,7 +8325,7 @@ async function runNew(name, options) {
8062
8325
  workspaceRoot = adoptTarget;
8063
8326
  }
8064
8327
  } finally {
8065
- if (adoptTarget !== void 0) (0, import_node_fs28.rmSync)(stagingParent, { recursive: true, force: true });
8328
+ if (adoptTarget !== void 0) (0, import_node_fs29.rmSync)(stagingParent, { recursive: true, force: true });
8066
8329
  }
8067
8330
  logger.step(
8068
8331
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
@@ -8072,8 +8335,8 @@ async function runNew(name, options) {
8072
8335
  { workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
8073
8336
  logger.detail
8074
8337
  );
8075
- (0, import_node_fs28.rmSync)((0, import_node_path36.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8076
- (0, import_node_fs28.rmSync)((0, import_node_path36.join)(workspaceRoot, "package-lock.json"), { force: true });
8338
+ (0, import_node_fs29.rmSync)((0, import_node_path37.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8339
+ (0, import_node_fs29.rmSync)((0, import_node_path37.join)(workspaceRoot, "package-lock.json"), { force: true });
8077
8340
  logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
8078
8341
  const installStatus = runShell(
8079
8342
  "npm",
@@ -8111,12 +8374,12 @@ function projectKindHintLines(kinds = PROJECT_KINDS) {
8111
8374
  }
8112
8375
 
8113
8376
  // src/workspace-creation/interactive-wizard.use-case.ts
8114
- var import_node_path38 = require("path");
8377
+ var import_node_path39 = require("path");
8115
8378
  var import_prompts4 = require("@inquirer/prompts");
8116
8379
 
8117
8380
  // src/workspace-upgrade/upgrade-workspace.use-case.ts
8118
- var import_node_fs29 = require("fs");
8119
- var import_node_path37 = require("path");
8381
+ var import_node_fs30 = require("fs");
8382
+ var import_node_path38 = require("path");
8120
8383
  function resolveRegistry2(options, persisted) {
8121
8384
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
8122
8385
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -8145,7 +8408,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8145
8408
  return persisted.workspaceName;
8146
8409
  }
8147
8410
  try {
8148
- const existing = (0, import_node_fs29.readdirSync)(workspaceRoot).find(
8411
+ const existing = (0, import_node_fs30.readdirSync)(workspaceRoot).find(
8149
8412
  (file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
8150
8413
  );
8151
8414
  if (existing) {
@@ -8153,11 +8416,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8153
8416
  }
8154
8417
  } catch {
8155
8418
  }
8156
- return (0, import_node_path37.basename)(workspaceRoot);
8419
+ return (0, import_node_path38.basename)(workspaceRoot);
8157
8420
  }
8158
8421
  function detectNpmAuth(workspaceRoot) {
8159
8422
  try {
8160
- return (0, import_node_fs29.readFileSync)((0, import_node_path37.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8423
+ return (0, import_node_fs30.readFileSync)((0, import_node_path38.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8161
8424
  } catch {
8162
8425
  return void 0;
8163
8426
  }
@@ -8204,7 +8467,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
8204
8467
  };
8205
8468
  }
8206
8469
  function runUpgrade(workspaceRoot, options) {
8207
- if (!fileExists((0, import_node_path37.join)(workspaceRoot, "nx.json"))) {
8470
+ if (!fileExists((0, import_node_path38.join)(workspaceRoot, "nx.json"))) {
8208
8471
  throw new Error(
8209
8472
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
8210
8473
  );
@@ -8270,7 +8533,7 @@ function runUpgrade(workspaceRoot, options) {
8270
8533
 
8271
8534
  // src/workspace-creation/interactive-wizard.use-case.ts
8272
8535
  async function runInteractive() {
8273
- const inWorkspace = fileExists((0, import_node_path38.join)(process.cwd(), "nx.json"));
8536
+ const inWorkspace = fileExists((0, import_node_path39.join)(process.cwd(), "nx.json"));
8274
8537
  const choiceNew = { name: "Create a new monorepo", value: "new" };
8275
8538
  const choiceAdd = { name: "Add a project to this workspace", value: "add" };
8276
8539
  const choiceUpgrade = {