@mnci/cli 4.37.0 → 4.39.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,14 @@ 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);
430
493
  }
431
494
 
432
495
  // src/pipeline-customization/pipeline-markers.algorithm.ts
@@ -694,9 +757,9 @@ var VSCODE_EXTENSION_TAG = "type:vscode-extension";
694
757
  var GO_RELEASE_TAG = "release:go";
695
758
  var GO_CGO_TAG = "build:cgo";
696
759
  function hasNativeGoApp(workspaceRoot) {
697
- 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) => {
698
761
  try {
699
- 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"));
700
763
  return (tags ?? []).includes(GO_CGO_TAG);
701
764
  } catch {
702
765
  return false;
@@ -1044,15 +1107,15 @@ function isUnmodifiedMnciEslintConfig(content) {
1044
1107
  return code.length === 2 && code[0] === "import mnci from '@mnci/eslint-config'" && code[1] === "export default mnci({ workspaceRoot: import.meta.dirname })";
1045
1108
  }
1046
1109
  function writePipeline(path, onProgress, generated) {
1047
- const { text, notes } = mergePipeline((0, import_node_fs4.existsSync)(path) ? (0, import_node_fs4.readFileSync)(path, "utf8") : void 0, generated);
1110
+ const { text, notes } = mergePipeline((0, import_node_fs5.existsSync)(path) ? (0, import_node_fs5.readFileSync)(path, "utf8") : void 0, generated);
1048
1111
  for (const note of notes) {
1049
1112
  onProgress(` ${note}`);
1050
1113
  }
1051
1114
  writeFileEnsured(path, text);
1052
1115
  }
1053
1116
  function writeEslintEntryPoint(workspaceRoot, onProgress) {
1054
- const path = (0, import_node_path3.join)(workspaceRoot, ESLINT_USER_FILENAME);
1055
- 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"))) {
1056
1119
  onProgress(`${ESLINT_USER_FILENAME} \u2014 kept as it is, it is yours`);
1057
1120
  return;
1058
1121
  }
@@ -1220,7 +1283,7 @@ function mnciConfig(options) {
1220
1283
  };
1221
1284
  }
1222
1285
  function readMnciConfig(workspaceRoot) {
1223
- const nxJson = readJson((0, import_node_path3.join)(workspaceRoot, "nx.json"));
1286
+ const nxJson = readJson((0, import_node_path4.join)(workspaceRoot, "nx.json"));
1224
1287
  return nxJson.mnci ?? {};
1225
1288
  }
1226
1289
  function pythonPublishUrl(registry) {
@@ -1305,8 +1368,7 @@ var DOTNET_SDK_VERSION = "10.0.x";
1305
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)"`;
1306
1369
  var VERIFY_TARGETS = "lint,typecheck,test,build";
1307
1370
  var NATIVE_TARGETS = "lint,test,build-native,package-native";
1308
- var NATIVE_LINUX_PREREQUISITES = "sudo apt-get update && sudo apt-get install -y gcc pkg-config";
1309
- function githubNativeJob(npmAuthName, npmAuthValue) {
1371
+ function githubNativeJob(npmAuthName, npmAuthValue, runners) {
1310
1372
  return `
1311
1373
  # Apps that need a C toolchain (mnci add go-app --cgo) cannot be cross-compiled
1312
1374
  # from the job above, so each is linted, tested, built and packaged here, on a
@@ -1318,7 +1380,7 @@ function githubNativeJob(npmAuthName, npmAuthValue) {
1318
1380
  strategy:
1319
1381
  fail-fast: false
1320
1382
  matrix:
1321
- os: [windows-latest, macos-latest, ubuntu-latest]
1383
+ os: [${runners.join(", ")}]
1322
1384
  steps:
1323
1385
  - uses: actions/checkout@${ACTION_VERSIONS["actions/checkout"]}
1324
1386
  with:
@@ -1346,15 +1408,9 @@ function githubNativeJob(npmAuthName, npmAuthValue) {
1346
1408
  - run: npx mnci ci setup
1347
1409
  name: Set up the Go toolchain
1348
1410
 
1349
- # A C compiler and pkg-config, which is all mnci can know a cgo app needs.
1350
- # Add the -dev packages your app links to this line, for example
1351
- # libgtk-3-dev and libayatana-appindicator3-dev for a system-tray icon.
1352
- # macOS and Windows runners ship their toolchains.
1353
- - run: ${NATIVE_LINUX_PREREQUISITES}
1354
- name: Install native prerequisites (Linux)
1355
- if: \${{ runner.os == 'Linux' }}
1356
-
1357
- # 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
1358
1414
  # main, a releasable native app (--cgo with --release) also gets this OS's zip
1359
1415
  # attached to the GitHub Release the ci job just created, stamped with the
1360
1416
  # tag's version.
@@ -1374,7 +1430,7 @@ function indentYaml(text, spaces) {
1374
1430
  const pad = " ".repeat(spaces);
1375
1431
  return text.split("\n").map((line) => line === "" ? line : pad + line).join("\n");
1376
1432
  }
1377
- function withAzureNativeJob(document, nativeSteps) {
1433
+ function withAzureNativeJob(document, nativeSteps, runners) {
1378
1434
  const poolAt = document.indexOf("\npool:\n");
1379
1435
  const variablesAt = document.indexOf("\nvariables:\n");
1380
1436
  const stepsAt = document.indexOf("\nsteps:\n");
@@ -1385,7 +1441,7 @@ function withAzureNativeJob(document, nativeSteps) {
1385
1441
  const pool2 = document.slice(poolAt + "\npool:\n".length, variablesAt).replace(/\n+$/, "");
1386
1442
  const variables = document.slice(variablesAt + 1, stepsAt).replace(/\n+$/, "");
1387
1443
  const steps = document.slice(stepsAt + "\nsteps:\n".length).replace(/\n+$/, "");
1388
- 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}:
1389
1445
  legName: ${leg}
1390
1446
  vmImage: ${image}`).join("\n");
1391
1447
  return `${head}${variables}
@@ -1424,7 +1480,7 @@ function npmAuthEnvVariable(registryKind, variableReference) {
1424
1480
  function poolBlock(agent) {
1425
1481
  return /^(?:ubuntu|windows|macos)-/i.test(agent) ? ` vmImage: ${agent}` : ` name: ${agent}`;
1426
1482
  }
1427
- 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) {
1428
1484
  const onMain = "and(succeeded(), in(variables['Build.Reason'], 'IndividualCI', 'BatchedCI'), eq(variables['Build.SourceBranchName'], 'main'))";
1429
1485
  const [npmAuthName, npmAuthValue] = npmAuthEnvVariable(registryKind, (name) => `$(${name})`);
1430
1486
  const buildIdentity = npmAuth === "build-identity" && registryKind === "azure-artifacts";
@@ -1686,14 +1742,9 @@ ${npmAuthenticateStep} - script: npm ci
1686
1742
  - script: npx mnci ci setup
1687
1743
  displayName: Set up the Go toolchain
1688
1744
 
1689
- # A C compiler and pkg-config, which is all mnci can know a cgo app needs. Add the
1690
- # -dev packages your app links to this line, for example libgtk-3-dev and
1691
- # libayatana-appindicator3-dev for a system-tray icon. macOS and Windows agents
1692
- # ship their toolchains.
1693
- - script: ${NATIVE_LINUX_PREREQUISITES}
1694
- displayName: Install native prerequisites (Linux)
1695
- condition: eq(variables['Agent.OS'], 'Linux')
1696
-
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.
1697
1748
  - script: npx mnci ci native
1698
1749
  displayName: Lint, test, build and package the native apps
1699
1750
 
@@ -1703,9 +1754,9 @@ ${npmAuthenticateStep} - script: npm ci
1703
1754
  PathtoPublish: $(Build.SourcesDirectory)/dist/drop
1704
1755
  ArtifactName: native-$(legName)
1705
1756
  `;
1706
- return withAzureNativeJob(document, nativeSteps);
1757
+ return withAzureNativeJob(document, nativeSteps, nativeRunners);
1707
1758
  }
1708
- 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) {
1709
1760
  const onMain = "github.event_name == 'push' && github.ref_name == 'main'";
1710
1761
  const [npmAuthName, npmAuthValue] = npmAuthEnvVariable(
1711
1762
  registryKind,
@@ -1891,7 +1942,7 @@ ${phaseStart("release", " ".repeat(6))}
1891
1942
  ${phaseEnd("release", " ".repeat(6))}
1892
1943
 
1893
1944
  ${slotMarkers("after-release", " ".repeat(6))}
1894
- ${nativeApps ? githubNativeJob(npmAuthName, npmAuthValue) : ""}`;
1945
+ ${nativeApps ? githubNativeJob(npmAuthName, npmAuthValue, nativeRunners) : ""}`;
1895
1946
  }
1896
1947
  var PIP_PROJECT_GLOBS = ["apps", "python-packages", "libs"];
1897
1948
  var PUB_PROJECT_GLOBS = ["apps", "packages", "libs"];
@@ -1901,12 +1952,12 @@ var ECOSYSTEM_MANIFESTS = {
1901
1952
  };
1902
1953
  function hasEcosystemProject(workspaceRoot, roots, manifests) {
1903
1954
  return roots.some((root) => {
1904
- const base = (0, import_node_path3.join)(workspaceRoot, root);
1905
- 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)) {
1906
1957
  return false;
1907
1958
  }
1908
- return (0, import_node_fs4.readdirSync)(base, { withFileTypes: true }).some(
1909
- (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)))
1910
1961
  );
1911
1962
  });
1912
1963
  }
@@ -1984,11 +2035,11 @@ var LOCAL_REGISTRY_SCAFFOLDING = {
1984
2035
  rootTarget: "local-registry"
1985
2036
  };
1986
2037
  function removeLocalRegistryScaffolding(workspaceRoot) {
1987
- (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), {
1988
2039
  recursive: true,
1989
2040
  force: true
1990
2041
  });
1991
- const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2042
+ const manifestPath = (0, import_node_path4.join)(workspaceRoot, "package.json");
1992
2043
  if (!fileExists(manifestPath)) return;
1993
2044
  const manifest = readJson(manifestPath);
1994
2045
  if (manifest.devDependencies?.[LOCAL_REGISTRY_SCAFFOLDING.devDependency] !== void 0) {
@@ -2004,23 +2055,23 @@ function removeLocalRegistryScaffolding(workspaceRoot) {
2004
2055
  }
2005
2056
  function removeNxScaffolding(workspaceRoot) {
2006
2057
  for (const entry of NX_SCAFFOLDING_TO_REMOVE) {
2007
- (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 });
2008
2059
  }
2009
2060
  removeNxAuthoredAgentFiles(workspaceRoot);
2010
2061
  removeProjectEslintConfigs(workspaceRoot);
2011
2062
  }
2012
2063
  function removeNxAuthoredAgentFiles(workspaceRoot) {
2013
- (0, import_node_fs4.rmSync)((0, import_node_path3.join)(workspaceRoot, NX_CLAUDE_SETTINGS), { force: true });
2014
- const claudeDirectory = (0, import_node_path3.join)(workspaceRoot, (0, import_node_path3.dirname)(NX_CLAUDE_SETTINGS));
2015
- if ((0, import_node_fs4.existsSync)(claudeDirectory) && (0, import_node_fs4.readdirSync)(claudeDirectory).length === 0) {
2016
- (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 });
2017
2068
  }
2018
2069
  for (const name of NX_AUTHORED_AGENT_FILES) {
2019
- const path = (0, import_node_path3.join)(workspaceRoot, name);
2020
- if (!(0, import_node_fs4.existsSync)(path)) continue;
2021
- 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"));
2022
2073
  if (kept === void 0) continue;
2023
- if (kept.trim() === "") (0, import_node_fs4.rmSync)(path, { force: true });
2074
+ if (kept.trim() === "") (0, import_node_fs5.rmSync)(path, { force: true });
2024
2075
  else writeFileEnsured(path, kept);
2025
2076
  }
2026
2077
  }
@@ -2035,14 +2086,14 @@ function withoutNxAgentRules(content) {
2035
2086
  return `${content.slice(0, start)}${rest}`.replace(/^[\r\n]+/, "");
2036
2087
  }
2037
2088
  function removeIfPresent(path) {
2038
- (0, import_node_fs4.rmSync)(path, { recursive: true, force: true });
2089
+ (0, import_node_fs5.rmSync)(path, { recursive: true, force: true });
2039
2090
  }
2040
2091
  function ensureEslintCacheIgnored(workspaceRoot) {
2041
- const gitignorePath = (0, import_node_path3.join)(workspaceRoot, ".gitignore");
2092
+ const gitignorePath = (0, import_node_path4.join)(workspaceRoot, ".gitignore");
2042
2093
  if (!fileExists(gitignorePath)) {
2043
2094
  return;
2044
2095
  }
2045
- const current = (0, import_node_fs4.readFileSync)(gitignorePath, "utf8");
2096
+ const current = (0, import_node_fs5.readFileSync)(gitignorePath, "utf8");
2046
2097
  if (current.split("\n").some((line) => line.trim() === ".eslintcache")) {
2047
2098
  return;
2048
2099
  }
@@ -2057,18 +2108,18 @@ function ensureEslintCacheIgnored(workspaceRoot) {
2057
2108
  }
2058
2109
  var PYTHON_ARTEFACT_IGNORES = ["__pycache__/", "*.py[cod]"];
2059
2110
  function ensurePythonArtefactsIgnored(workspaceRoot) {
2060
- const gitignorePath = (0, import_node_path3.join)(workspaceRoot, ".gitignore");
2111
+ const gitignorePath = (0, import_node_path4.join)(workspaceRoot, ".gitignore");
2061
2112
  if (!fileExists(gitignorePath)) {
2062
2113
  return;
2063
2114
  }
2064
- const hasPython = (0, import_node_fs4.globSync)(
2115
+ const hasPython = (0, import_node_fs5.globSync)(
2065
2116
  ["python-packages/*/pyproject.toml", "apps/*/pyproject.toml", "libs/*/pyproject.toml"],
2066
2117
  { cwd: workspaceRoot }
2067
2118
  ).length > 0;
2068
2119
  if (!hasPython) {
2069
2120
  return;
2070
2121
  }
2071
- const current = (0, import_node_fs4.readFileSync)(gitignorePath, "utf8");
2122
+ const current = (0, import_node_fs5.readFileSync)(gitignorePath, "utf8");
2072
2123
  const present = new Set(current.split("\n").map((line) => line.trim()));
2073
2124
  const missing = PYTHON_ARTEFACT_IGNORES.filter((line) => !present.has(line));
2074
2125
  if (missing.length === 0) {
@@ -2088,16 +2139,16 @@ ${missing.join("\n")}
2088
2139
  );
2089
2140
  }
2090
2141
  function removeProjectEslintConfigs(workspaceRoot) {
2091
- 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}", {
2092
2143
  cwd: workspaceRoot
2093
2144
  });
2094
2145
  for (const match of matches) {
2095
- (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 });
2096
2147
  }
2097
2148
  }
2098
2149
  function applyOverlay(workspaceRoot, options, onProgress = () => {
2099
2150
  }) {
2100
- const nxJsonPath = (0, import_node_path3.join)(workspaceRoot, "nx.json");
2151
+ const nxJsonPath = (0, import_node_path4.join)(workspaceRoot, "nx.json");
2101
2152
  const nxJson = readJson(nxJsonPath);
2102
2153
  const generators = {
2103
2154
  ...nxJson.generators,
@@ -2105,7 +2156,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2105
2156
  };
2106
2157
  const sync = { ...nxJson.sync, ...SYNC_CONFIG };
2107
2158
  const mnci = { ...nxJson.mnci, ...mnciConfig(options) };
2108
- const rootManifest = readJson((0, import_node_path3.join)(workspaceRoot, "package.json"));
2159
+ const rootManifest = readJson((0, import_node_path4.join)(workspaceRoot, "package.json"));
2109
2160
  const hasPythonPlugin = (rootManifest.devDependencies ?? {})["@mnci/nx-python-pip"] !== void 0 || (rootManifest.dependencies ?? {})["@mnci/nx-python-pip"] !== void 0;
2110
2161
  const withRelease = withReleaseConfig(nxJson, options.ci);
2111
2162
  const patched = withPythonGraphPlugin(
@@ -2115,7 +2166,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2115
2166
  onProgress("nx.json \u2014 release, sync, generators, shared inputs, mnci block");
2116
2167
  writeFileEnsured(nxJsonPath, toJson({ ...patched, generators, sync, mnci }));
2117
2168
  onProgress("package.json \u2014 root scripts, TS compilers, ESLint toolchain, overrides");
2118
- const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2169
+ const manifestPath = (0, import_node_path4.join)(workspaceRoot, "package.json");
2119
2170
  const manifest = readJson(manifestPath);
2120
2171
  const scripts = {
2121
2172
  ...manifest.scripts,
@@ -2167,32 +2218,32 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2167
2218
  `.npmrc \u2014 ${options.registry.kind === "azure-artifacts" ? "Azure Artifacts feed routing and credentials" : "public npm registry auth"}`
2168
2219
  );
2169
2220
  writeFileEnsured(
2170
- (0, import_node_path3.join)(workspaceRoot, ".npmrc"),
2221
+ (0, import_node_path4.join)(workspaceRoot, ".npmrc"),
2171
2222
  npmrcContent(options.registry, options.scope, options.npmAuth)
2172
2223
  );
2173
2224
  onProgress("commitlint.config.mjs and .husky/commit-msg \u2014 conventional commit enforcement");
2174
- writeFileEnsured((0, import_node_path3.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
2175
- 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");
2176
2227
  writeFileEnsured(hookPath, COMMIT_MSG_HOOK);
2177
2228
  markExecutable(hookPath);
2178
2229
  onProgress(`${ESLINT_MNCI_FILENAME} \u2014 the shared lint AND formatting opinion`);
2179
- 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);
2180
2231
  writeEslintEntryPoint(workspaceRoot, onProgress);
2181
2232
  ensureEslintCacheIgnored(workspaceRoot);
2182
2233
  ensurePythonArtefactsIgnored(workspaceRoot);
2183
2234
  for (const retired of RETIRED_FORMATTER_FILES) {
2184
- removeIfPresent((0, import_node_path3.join)(workspaceRoot, retired));
2235
+ removeIfPresent((0, import_node_path4.join)(workspaceRoot, retired));
2185
2236
  }
2186
2237
  onProgress(".devcontainer/devcontainer.json \u2014 a local toolchain matching CI");
2187
2238
  writeFileEnsured(
2188
- (0, import_node_path3.join)(workspaceRoot, ".devcontainer/devcontainer.json"),
2239
+ (0, import_node_path4.join)(workspaceRoot, ".devcontainer/devcontainer.json"),
2189
2240
  devcontainerJson(options.workspaceName)
2190
2241
  );
2191
2242
  removeNxScaffolding(workspaceRoot);
2192
2243
  onProgress(
2193
2244
  `${options.workspaceName}.code-workspace \u2014 settings, extensions, launch configs`
2194
2245
  );
2195
- 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`);
2196
2247
  const existing = readCodeWorkspace(codeWorkspacePath);
2197
2248
  writeFileEnsured(
2198
2249
  codeWorkspacePath,
@@ -2204,15 +2255,16 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2204
2255
  )
2205
2256
  );
2206
2257
  if (options.workspaceName !== "undefined") {
2207
- (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 });
2208
2259
  }
2209
2260
  const publishUrl = pythonPublishUrl(options.registry);
2210
2261
  const nugetUrl = nugetFeedUrl(options.registry);
2211
2262
  const nativeApps = hasNativeGoApp(workspaceRoot);
2263
+ const nativeRunners = readNativeBuildConfig(workspaceRoot).config.runners;
2212
2264
  if (options.ci === "azure" || options.ci === "both") {
2213
2265
  onProgress("azure-pipelines.yml \u2014 build, verify, pack and release");
2214
2266
  writePipeline(
2215
- (0, import_node_path3.join)(workspaceRoot, "azure-pipelines.yml"),
2267
+ (0, import_node_path4.join)(workspaceRoot, "azure-pipelines.yml"),
2216
2268
  onProgress,
2217
2269
  azurePipelinesYaml(
2218
2270
  options.agent,
@@ -2221,18 +2273,19 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2221
2273
  options.registry.kind,
2222
2274
  nugetUrl,
2223
2275
  options.npmAuth,
2224
- nativeApps
2276
+ nativeApps,
2277
+ nativeRunners
2225
2278
  )
2226
2279
  );
2227
2280
  }
2228
2281
  if (options.ci === "github" || options.ci === "both") {
2229
2282
  onProgress(".github/workflows/ci.yml and dependabot.yml");
2230
2283
  writePipeline(
2231
- (0, import_node_path3.join)(workspaceRoot, ".github/workflows/ci.yml"),
2284
+ (0, import_node_path4.join)(workspaceRoot, ".github/workflows/ci.yml"),
2232
2285
  onProgress,
2233
- githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci, nugetUrl, nativeApps)
2286
+ githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci, nugetUrl, nativeApps, nativeRunners)
2234
2287
  );
2235
- 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));
2236
2289
  }
2237
2290
  }
2238
2291
 
@@ -2256,30 +2309,47 @@ function runNative(workspaceRoot, dependencies = {}) {
2256
2309
  }
2257
2310
  return status;
2258
2311
  };
2312
+ if (isLinuxAgent(environment)) {
2313
+ const prerequisites = installLinuxPrerequisites(workspaceRoot, inGroup);
2314
+ if (prerequisites !== 0) {
2315
+ return prerequisites;
2316
+ }
2317
+ }
2259
2318
  const built = inGroup("Lint, test, build and package the native apps", "npx", ["nx", "run-many", "-t", NATIVE_TARGETS, `--projects=tag:${GO_CGO_TAG}`]);
2260
2319
  if (built !== 0) {
2261
2320
  return built;
2262
2321
  }
2263
- 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"))) {
2264
2323
  return 0;
2265
2324
  }
2266
2325
  return inGroup("Attach this OS's zip to the GitHub Release", "node", ["tools/go-app-release.cjs", "assets", "--native"]);
2267
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
+ }
2268
2338
 
2269
2339
  // src/ci-pipeline/pack.use-case.ts
2270
- var import_node_fs6 = require("fs");
2271
- var import_node_path5 = require("path");
2340
+ var import_node_fs7 = require("fs");
2341
+ var import_node_path6 = require("path");
2272
2342
  function hasAppToPack(workspaceRoot) {
2273
- const hasProjectJson = (0, import_node_fs6.globSync)("apps/*/project.json", { cwd: workspaceRoot }).length > 0;
2274
- 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) => {
2275
2345
  try {
2276
- 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"));
2277
2347
  return Boolean(parsed.nx);
2278
2348
  } catch {
2279
2349
  return false;
2280
2350
  }
2281
2351
  });
2282
- 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;
2283
2353
  return hasProjectJson || hasInlineNx || hasCsproj;
2284
2354
  }
2285
2355
  function runPack(workspaceRoot, dependencies = {}) {
@@ -2292,7 +2362,7 @@ function runPack(workspaceRoot, dependencies = {}) {
2292
2362
  console.log(message);
2293
2363
  });
2294
2364
  const host = detectCiHost(environment);
2295
- (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 });
2296
2366
  if (!hasAppToPack(workspaceRoot)) {
2297
2367
  log("No apps to pack - skipping.");
2298
2368
  return 0;
@@ -2306,13 +2376,80 @@ function runPack(workspaceRoot, dependencies = {}) {
2306
2376
  return status;
2307
2377
  }
2308
2378
 
2379
+ // src/ci-pipeline/report-phase.use-case.ts
2380
+ var import_node_fs8 = require("fs");
2381
+
2382
+ // src/ci-pipeline/phase-timing.algorithm.ts
2383
+ function formatDuration(milliseconds) {
2384
+ const seconds = Math.max(0, milliseconds) / 1e3;
2385
+ if (seconds < 60) {
2386
+ return `${seconds.toFixed(1)}s`;
2387
+ }
2388
+ const whole = Math.round(seconds);
2389
+ return `${Math.floor(whole / 60)}m ${String(whole % 60).padStart(2, "0")}s`;
2390
+ }
2391
+ function escapeCommandData(text) {
2392
+ return text.replaceAll("%", "%25").replaceAll("\r", "%0D").replaceAll("\n", "%0A");
2393
+ }
2394
+ function describePhaseOutcome(host, phase, status, milliseconds) {
2395
+ const took = formatDuration(milliseconds);
2396
+ if (status === 0) {
2397
+ return {
2398
+ log: `mnci ci ${phase}: passed in ${took}`,
2399
+ summary: `- \u2705 **${phase}** passed in ${took}`
2400
+ };
2401
+ }
2402
+ const message = `The ${phase} phase failed with exit status ${status} after ${took}`;
2403
+ let annotation;
2404
+ if (host === "github") {
2405
+ annotation = `::error title=mnci ci ${phase}::${escapeCommandData(message)}`;
2406
+ } else if (host === "azure") {
2407
+ annotation = `##vso[task.logissue type=error;]${message}`;
2408
+ }
2409
+ return {
2410
+ log: `mnci ci ${phase}: failed (exit ${status}) in ${took}`,
2411
+ annotation,
2412
+ summary: `- \u274C **${phase}** failed (exit ${status}) after ${took}`
2413
+ };
2414
+ }
2415
+
2416
+ // src/ci-pipeline/report-phase.use-case.ts
2417
+ async function reportPhase(phase, run, dependencies = {}) {
2418
+ const environment = dependencies.environment ?? process.env;
2419
+ const log = dependencies.log ?? ((message) => {
2420
+ console.log(message);
2421
+ });
2422
+ const clock = dependencies.clock ?? (() => Date.now());
2423
+ const host = detectCiHost(environment);
2424
+ const started = clock();
2425
+ const finish = (status) => {
2426
+ const outcome = describePhaseOutcome(host, phase, status, clock() - started);
2427
+ log(outcome.log);
2428
+ if (outcome.annotation !== void 0) {
2429
+ log(outcome.annotation);
2430
+ }
2431
+ if (host === "github" && environment.GITHUB_STEP_SUMMARY) {
2432
+ (0, import_node_fs8.appendFileSync)(environment.GITHUB_STEP_SUMMARY, `${outcome.summary}
2433
+ `);
2434
+ }
2435
+ };
2436
+ try {
2437
+ const status = await run();
2438
+ finish(status);
2439
+ return status;
2440
+ } catch (error) {
2441
+ finish(1);
2442
+ throw error;
2443
+ }
2444
+ }
2445
+
2309
2446
  // src/ci-pipeline/release.use-case.ts
2310
- var import_node_fs7 = require("fs");
2311
- var import_node_path6 = require("path");
2447
+ var import_node_fs9 = require("fs");
2448
+ var import_node_path7 = require("path");
2312
2449
  var SPECIFIER = /^(?:major|minor|patch|\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?)$/;
2313
2450
  function hasTag(workspaceRoot, relativePath, tag) {
2314
2451
  try {
2315
- const parsed = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, relativePath), "utf8"));
2452
+ const parsed = JSON.parse((0, import_node_fs9.readFileSync)((0, import_node_path7.join)(workspaceRoot, relativePath), "utf8"));
2316
2453
  const tags = relativePath.endsWith("project.json") ? parsed.tags : parsed.nx?.tags;
2317
2454
  return Array.isArray(tags) && tags.includes(tag);
2318
2455
  } catch {
@@ -2321,12 +2458,12 @@ function hasTag(workspaceRoot, relativePath, tag) {
2321
2458
  }
2322
2459
  function releasableCounts(workspaceRoot) {
2323
2460
  return {
2324
- npm: (0, import_node_fs7.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length,
2325
- csharp: (0, import_node_fs7.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }).length,
2326
- python: (0, import_node_fs7.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot }).length,
2327
- dart: (0, import_node_fs7.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }).length,
2328
- vscode: (0, import_node_fs7.globSync)("apps/*/package.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, VSCODE_EXTENSION_TAG)).length,
2329
- go: (0, import_node_fs7.globSync)("apps/*/project.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, GO_RELEASE_TAG)).length
2461
+ npm: (0, import_node_fs9.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length,
2462
+ csharp: (0, import_node_fs9.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }).length,
2463
+ python: (0, import_node_fs9.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot }).length,
2464
+ dart: (0, import_node_fs9.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }).length,
2465
+ vscode: (0, import_node_fs9.globSync)("apps/*/package.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, VSCODE_EXTENSION_TAG)).length,
2466
+ go: (0, import_node_fs9.globSync)("apps/*/project.json", { cwd: workspaceRoot }).filter((path) => hasTag(workspaceRoot, path, GO_RELEASE_TAG)).length
2330
2467
  };
2331
2468
  }
2332
2469
  function shallowCloneGuard(processes, log) {
@@ -2342,7 +2479,7 @@ function shallowCloneGuard(processes, log) {
2342
2479
  return 0;
2343
2480
  }
2344
2481
  function npmPreflight(workspaceRoot, registryKind, environment, processes, log) {
2345
- if (registryKind !== "npm" || (0, import_node_fs7.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length === 0) {
2482
+ if (registryKind !== "npm" || (0, import_node_fs9.globSync)("packages/*/package.json", { cwd: workspaceRoot }).length === 0) {
2346
2483
  return 0;
2347
2484
  }
2348
2485
  if (!environment.NODE_AUTH_TOKEN) {
@@ -2358,7 +2495,7 @@ function npmPreflight(workspaceRoot, registryKind, environment, processes, log)
2358
2495
  return 0;
2359
2496
  }
2360
2497
  async function pypiPreflight(workspaceRoot, registryKind, environment, log, fetchStatus) {
2361
- const files = (0, import_node_fs7.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot });
2498
+ const files = (0, import_node_fs9.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot });
2362
2499
  if (registryKind !== "npm" || files.length === 0) {
2363
2500
  return 0;
2364
2501
  }
@@ -2371,7 +2508,7 @@ async function pypiPreflight(workspaceRoot, registryKind, environment, log, fetc
2371
2508
  return 1;
2372
2509
  }
2373
2510
  const names = files.map((file) => {
2374
- const text = (0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, file), "utf8");
2511
+ const text = (0, import_node_fs9.readFileSync)((0, import_node_path7.join)(workspaceRoot, file), "utf8");
2375
2512
  const block = text.slice(text.indexOf("[project]"));
2376
2513
  const line = block.split("\n").find((entry) => entry.trimStart().startsWith("name"));
2377
2514
  return line ? line.split("=", 2)[1].replaceAll(/[^\w.-]/gi, "") : "";
@@ -2446,14 +2583,14 @@ function runReleaseCommand(workspaceRoot, registry, counts, environment, process
2446
2583
  }
2447
2584
  function nxPushesTags(workspaceRoot) {
2448
2585
  try {
2449
- const nx = JSON.parse((0, import_node_fs7.readFileSync)((0, import_node_path6.join)(workspaceRoot, "nx.json"), "utf8"));
2586
+ const nx = JSON.parse((0, import_node_fs9.readFileSync)((0, import_node_path7.join)(workspaceRoot, "nx.json"), "utf8"));
2450
2587
  return nx.release?.git?.push === true;
2451
2588
  } catch {
2452
2589
  return false;
2453
2590
  }
2454
2591
  }
2455
2592
  function afterRelease(workspaceRoot, processes, githubReleases) {
2456
- if (githubReleases && (0, import_node_fs7.existsSync)((0, import_node_path6.join)(workspaceRoot, "tools", "go-app-release.cjs"))) {
2593
+ if (githubReleases && (0, import_node_fs9.existsSync)((0, import_node_path7.join)(workspaceRoot, "tools", "go-app-release.cjs"))) {
2457
2594
  const assets = processes.run("node", ["tools/go-app-release.cjs", "assets"]);
2458
2595
  if (assets !== 0) {
2459
2596
  return assets;
@@ -2504,17 +2641,17 @@ async function runRelease(workspaceRoot, dependencies = {}) {
2504
2641
  }
2505
2642
 
2506
2643
  // src/ci-pipeline/setup.use-case.ts
2507
- var import_node_fs10 = require("fs");
2508
- var import_node_path9 = require("path");
2644
+ var import_node_fs12 = require("fs");
2645
+ var import_node_path10 = require("path");
2509
2646
 
2510
2647
  // src/ci-pipeline/flutter-sdk.use-case.ts
2511
- var import_node_fs8 = require("fs");
2512
- var import_node_path7 = require("path");
2648
+ var import_node_fs10 = require("fs");
2649
+ var import_node_path8 = require("path");
2513
2650
  function flutterSdkDirectory(machine) {
2514
- return (0, import_node_path7.join)(machine.home, `.mnci-flutter-${FLUTTER_SDK_VERSION}`);
2651
+ return (0, import_node_path8.join)(machine.home, `.mnci-flutter-${FLUTTER_SDK_VERSION}`);
2515
2652
  }
2516
2653
  function installFlutterSdk(workspaceRoot, processes, log, machine) {
2517
- if (!(0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "pubspec.yaml"))) {
2654
+ if (!(0, import_node_fs10.existsSync)((0, import_node_path8.join)(workspaceRoot, "pubspec.yaml"))) {
2518
2655
  log("No Flutter projects - skipping.");
2519
2656
  return 0;
2520
2657
  }
@@ -2523,26 +2660,26 @@ function installFlutterSdk(workspaceRoot, processes, log, machine) {
2523
2660
  return 0;
2524
2661
  }
2525
2662
  const sdk = flutterSdkDirectory(machine);
2526
- if ((0, import_node_fs8.existsSync)(sdk)) {
2663
+ if ((0, import_node_fs10.existsSync)(sdk)) {
2527
2664
  log(`Flutter SDK already installed at ${sdk} - skipping.`);
2528
2665
  return 0;
2529
2666
  }
2530
2667
  return processes.run("git", ["clone", "--depth", "1", "--branch", FLUTTER_SDK_VERSION, "https://github.com/flutter/flutter.git", sdk]);
2531
2668
  }
2532
2669
  function publishFlutterSdk(workspaceRoot, host, environment, log, machine) {
2533
- if (!(0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "pubspec.yaml"))) {
2670
+ if (!(0, import_node_fs10.existsSync)((0, import_node_path8.join)(workspaceRoot, "pubspec.yaml"))) {
2534
2671
  log("No Flutter projects - skipping.");
2535
2672
  return;
2536
2673
  }
2537
2674
  const sdk = flutterSdkDirectory(machine);
2538
- if (!(0, import_node_fs8.existsSync)(sdk)) {
2675
+ if (!(0, import_node_fs10.existsSync)(sdk)) {
2539
2676
  log("Flutter SDK was not installed by mnci (already on PATH) - skipping.");
2540
2677
  return;
2541
2678
  }
2542
- addToPath(host, environment, (0, import_node_path7.join)(sdk, "bin"), log);
2679
+ addToPath(host, environment, (0, import_node_path8.join)(sdk, "bin"), log);
2543
2680
  }
2544
2681
  function resolveDartDependencies(workspaceRoot, processes, log) {
2545
- if (!(0, import_node_fs8.existsSync)((0, import_node_path7.join)(workspaceRoot, "pubspec.yaml"))) {
2682
+ if (!(0, import_node_fs10.existsSync)((0, import_node_path8.join)(workspaceRoot, "pubspec.yaml"))) {
2546
2683
  log("No Flutter projects - skipping.");
2547
2684
  return 0;
2548
2685
  }
@@ -2551,15 +2688,15 @@ function resolveDartDependencies(workspaceRoot, processes, log) {
2551
2688
 
2552
2689
  // src/ci-pipeline/go-tools.use-case.ts
2553
2690
  var import_node_crypto = require("crypto");
2554
- var import_node_fs9 = require("fs");
2691
+ var import_node_fs11 = require("fs");
2555
2692
  var import_node_os = require("os");
2556
- var import_node_path8 = require("path");
2693
+ var import_node_path9 = require("path");
2557
2694
  function currentMachine() {
2558
2695
  return { platform: process.platform, architecture: process.arch, home: (0, import_node_os.homedir)() };
2559
2696
  }
2560
2697
  var GOLANGCI_LINT_MODULE = "github.com/golangci/golangci-lint/v2/cmd/golangci-lint";
2561
2698
  function downloadGoModules(workspaceRoot, processes, log) {
2562
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
2699
+ if (!(0, import_node_fs11.existsSync)((0, import_node_path9.join)(workspaceRoot, "go.mod"))) {
2563
2700
  log("No Go projects - skipping.");
2564
2701
  return 0;
2565
2702
  }
@@ -2567,7 +2704,7 @@ function downloadGoModules(workspaceRoot, processes, log) {
2567
2704
  }
2568
2705
  async function installGolangciLint(workspaceRoot, dependencies, machine) {
2569
2706
  const { processes, log, fetchBytes } = dependencies;
2570
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
2707
+ if (!(0, import_node_fs11.existsSync)((0, import_node_path9.join)(workspaceRoot, "go.mod"))) {
2571
2708
  log("No Go projects - skipping.");
2572
2709
  return 0;
2573
2710
  }
@@ -2604,30 +2741,30 @@ async function installGolangciLint(workspaceRoot, dependencies, machine) {
2604
2741
  if ((0, import_node_crypto.createHash)("sha256").update(archive).digest("hex") !== entry[0]) {
2605
2742
  throw new Error(`checksum mismatch for ${file}`);
2606
2743
  }
2607
- temporary = (0, import_node_fs9.mkdtempSync)((0, import_node_path8.join)((0, import_node_os.tmpdir)(), "golangci-lint-"));
2608
- const archivePath = (0, import_node_path8.join)(temporary, file);
2609
- (0, import_node_fs9.writeFileSync)(archivePath, archive);
2610
- const tar = platform === "windows" ? (0, import_node_path8.join)(process.env.SystemRoot ?? "", "System32", "tar.exe") : "tar";
2744
+ temporary = (0, import_node_fs11.mkdtempSync)((0, import_node_path9.join)((0, import_node_os.tmpdir)(), "golangci-lint-"));
2745
+ const archivePath = (0, import_node_path9.join)(temporary, file);
2746
+ (0, import_node_fs11.writeFileSync)(archivePath, archive);
2747
+ const tar = platform === "windows" ? (0, import_node_path9.join)(process.env.SystemRoot ?? "", "System32", "tar.exe") : "tar";
2611
2748
  if (processes.run(tar, ["-xf", archivePath, "-C", temporary]) !== 0) {
2612
2749
  throw new Error(`could not extract ${file}`);
2613
2750
  }
2614
2751
  const executable = `golangci-lint${platform === "windows" ? ".exe" : ""}`;
2615
- const bin = (0, import_node_path8.join)(gopath.stdout.trim(), "bin");
2616
- (0, import_node_fs9.mkdirSync)(bin, { recursive: true });
2617
- (0, import_node_fs9.copyFileSync)((0, import_node_path8.join)(temporary, name, executable), (0, import_node_path8.join)(bin, executable));
2618
- (0, import_node_fs9.chmodSync)((0, import_node_path8.join)(bin, executable), 493);
2752
+ const bin = (0, import_node_path9.join)(gopath.stdout.trim(), "bin");
2753
+ (0, import_node_fs11.mkdirSync)(bin, { recursive: true });
2754
+ (0, import_node_fs11.copyFileSync)((0, import_node_path9.join)(temporary, name, executable), (0, import_node_path9.join)(bin, executable));
2755
+ (0, import_node_fs11.chmodSync)((0, import_node_path9.join)(bin, executable), 493);
2619
2756
  log(`golangci-lint ${version} installed from its checksum-verified prebuilt release into ${bin}`);
2620
2757
  return 0;
2621
2758
  } catch (error) {
2622
2759
  return fallback(error instanceof Error ? error.message : String(error));
2623
2760
  } finally {
2624
2761
  if (temporary !== void 0) {
2625
- (0, import_node_fs9.rmSync)(temporary, { recursive: true, force: true });
2762
+ (0, import_node_fs11.rmSync)(temporary, { recursive: true, force: true });
2626
2763
  }
2627
2764
  }
2628
2765
  }
2629
2766
  function publishGoTools(workspaceRoot, host, environment, processes, log) {
2630
- if (!(0, import_node_fs9.existsSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
2767
+ if (!(0, import_node_fs11.existsSync)((0, import_node_path9.join)(workspaceRoot, "go.mod"))) {
2631
2768
  log("No Go projects - skipping.");
2632
2769
  return;
2633
2770
  }
@@ -2636,7 +2773,7 @@ function publishGoTools(workspaceRoot, host, environment, processes, log) {
2636
2773
  log("Could not resolve GOPATH - skipping.");
2637
2774
  return;
2638
2775
  }
2639
- addToPath(host, environment, (0, import_node_path8.join)(gopath.stdout.trim(), "bin"), log);
2776
+ addToPath(host, environment, (0, import_node_path9.join)(gopath.stdout.trim(), "bin"), log);
2640
2777
  }
2641
2778
 
2642
2779
  // src/ci-pipeline/setup.use-case.ts
@@ -2644,15 +2781,15 @@ function pythonCommand(machine) {
2644
2781
  return machine.platform === "win32" ? "python" : "python3";
2645
2782
  }
2646
2783
  function installPythonToolchain(workspaceRoot, processes, log, machine) {
2647
- if (!(0, import_node_fs10.existsSync)((0, import_node_path9.join)(workspaceRoot, "requirements-dev.txt"))) {
2784
+ if (!(0, import_node_fs12.existsSync)((0, import_node_path10.join)(workspaceRoot, "requirements-dev.txt"))) {
2648
2785
  log("No Python projects - skipping.");
2649
2786
  return 0;
2650
2787
  }
2651
2788
  return processes.run(pythonCommand(machine), ["-m", "pip", "install", "-r", "requirements-dev.txt"]);
2652
2789
  }
2653
2790
  function installPythonProjects(workspaceRoot, processes, log, machine) {
2654
- 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));
2655
- const requirements = (0, import_node_fs10.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot });
2791
+ const editable = ["apps/*/pyproject.toml", "python-packages/*/pyproject.toml", "libs/*/pyproject.toml"].flatMap((pattern) => (0, import_node_fs12.globSync)(pattern, { cwd: workspaceRoot })).map((path) => (0, import_node_path10.dirname)(path));
2792
+ const requirements = (0, import_node_fs12.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot });
2656
2793
  if (editable.length === 0 && requirements.length === 0) {
2657
2794
  log("No Python projects - skipping.");
2658
2795
  return 0;
@@ -2771,6 +2908,9 @@ function runVerify(workspaceRoot, dependencies = {}) {
2771
2908
  // src/ci-pipeline/index.ts
2772
2909
  var CI_PHASES = ["setup", "audit", "verify", "pack", "release", "native"];
2773
2910
  function runCiPhase(phase, workspaceRoot, dependencies = {}) {
2911
+ return reportPhase(phase, () => runPhase(phase, workspaceRoot, dependencies), dependencies);
2912
+ }
2913
+ function runPhase(phase, workspaceRoot, dependencies) {
2774
2914
  switch (phase) {
2775
2915
  case "verify": {
2776
2916
  return runVerify(workspaceRoot, dependencies);
@@ -2794,7 +2934,7 @@ function runCiPhase(phase, workspaceRoot, dependencies = {}) {
2794
2934
  }
2795
2935
 
2796
2936
  // src/project-scaffolding/add-project.use-case.ts
2797
- var import_node_path30 = require("path");
2937
+ var import_node_path31 = require("path");
2798
2938
  var import_prompts3 = require("@inquirer/prompts");
2799
2939
 
2800
2940
  // src/project-name/project-name.validator.ts
@@ -2807,8 +2947,8 @@ function assertValidProjectName(name, label) {
2807
2947
  }
2808
2948
 
2809
2949
  // src/project-scaffolding/csharp.use-case.ts
2810
- var import_node_fs12 = require("fs");
2811
- var import_node_path11 = require("path");
2950
+ var import_node_fs14 = require("fs");
2951
+ var import_node_path12 = require("path");
2812
2952
 
2813
2953
  // src/project-scaffolding/csharp-example.algorithm.ts
2814
2954
  function csharpExampleFiles(identity) {
@@ -2849,10 +2989,10 @@ public class GreetUseCaseTests
2849
2989
  }
2850
2990
 
2851
2991
  // src/project-scaffolding/post-generation.use-case.ts
2852
- var import_node_fs11 = require("fs");
2853
- var import_node_path10 = require("path");
2992
+ var import_node_fs13 = require("fs");
2993
+ var import_node_path11 = require("path");
2854
2994
  function hasPlugin(workspaceRoot, packageName) {
2855
- const manifest = readJson((0, import_node_path10.join)(workspaceRoot, "package.json"));
2995
+ const manifest = readJson((0, import_node_path11.join)(workspaceRoot, "package.json"));
2856
2996
  const installed = { ...manifest.dependencies, ...manifest.devDependencies };
2857
2997
  return Object.hasOwn(installed, packageName);
2858
2998
  }
@@ -2891,7 +3031,7 @@ function markPublic(manifestPath) {
2891
3031
  function writeProjectReadme(projectRoot, projectName, testRunner) {
2892
3032
  const runner = testRunner === "vitest" ? "[Vitest](https://vitest.dev)" : "[Jest](https://jestjs.io)";
2893
3033
  writeFileEnsured(
2894
- (0, import_node_path10.join)(projectRoot, "README.md"),
3034
+ (0, import_node_path11.join)(projectRoot, "README.md"),
2895
3035
  [
2896
3036
  `# ${projectName}`,
2897
3037
  "",
@@ -2910,13 +3050,13 @@ function writeProjectReadme(projectRoot, projectName, testRunner) {
2910
3050
  }
2911
3051
  function removeStaleGitkeeps(workspaceRoot) {
2912
3052
  for (const scaffold of ["apps", "libs", "packages"]) {
2913
- const directory = (0, import_node_path10.join)(workspaceRoot, scaffold);
3053
+ const directory = (0, import_node_path11.join)(workspaceRoot, scaffold);
2914
3054
  try {
2915
- const holdsAProject = (0, import_node_fs11.readdirSync)(directory, { withFileTypes: true }).some(
3055
+ const holdsAProject = (0, import_node_fs13.readdirSync)(directory, { withFileTypes: true }).some(
2916
3056
  (entry) => entry.isDirectory()
2917
3057
  );
2918
3058
  if (holdsAProject) {
2919
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(directory, ".gitkeep"), { force: true });
3059
+ (0, import_node_fs13.rmSync)((0, import_node_path11.join)(directory, ".gitkeep"), { force: true });
2920
3060
  }
2921
3061
  } catch {
2922
3062
  }
@@ -2936,7 +3076,7 @@ function ensureAdmZip(workspaceRoot) {
2936
3076
  }
2937
3077
  }
2938
3078
  function defaultScope(workspaceRoot) {
2939
- const { name } = readJson((0, import_node_path10.join)(workspaceRoot, "package.json"));
3079
+ const { name } = readJson((0, import_node_path11.join)(workspaceRoot, "package.json"));
2940
3080
  const base = (name.startsWith("@") ? name.slice(1) : name).split("/", 1)[0];
2941
3081
  return `@${base}`;
2942
3082
  }
@@ -2964,14 +3104,14 @@ var ESLINT_CONFIG_FILENAMES = [
2964
3104
  ];
2965
3105
  function removeGeneratedEslintConfig(workspaceRoot, projectRoot) {
2966
3106
  for (const filename of ESLINT_CONFIG_FILENAMES) {
2967
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(workspaceRoot, projectRoot, filename), { force: true });
3107
+ (0, import_node_fs13.rmSync)((0, import_node_path11.join)(workspaceRoot, projectRoot, filename), { force: true });
2968
3108
  }
2969
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(workspaceRoot, ".vscode"), { recursive: true, force: true });
3109
+ (0, import_node_fs13.rmSync)((0, import_node_path11.join)(workspaceRoot, ".vscode"), { recursive: true, force: true });
2970
3110
  }
2971
3111
  function findCodeWorkspaceFile(workspaceRoot) {
2972
3112
  try {
2973
- const entry = (0, import_node_fs11.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
2974
- return entry ? (0, import_node_path10.join)(workspaceRoot, entry) : void 0;
3113
+ const entry = (0, import_node_fs13.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
3114
+ return entry ? (0, import_node_path11.join)(workspaceRoot, entry) : void 0;
2975
3115
  } catch {
2976
3116
  return void 0;
2977
3117
  }
@@ -2988,8 +3128,8 @@ function reshapeReactScaffold(projectRoot, name, empty = false) {
2988
3128
  reshapeScaffoldSlice(projectRoot, name, "tsx", "component", empty);
2989
3129
  }
2990
3130
  function reshapeReactAppScaffold(projectRoot) {
2991
- const appDir = (0, import_node_path10.join)(projectRoot, "src", "app");
2992
- if (!(0, import_node_fs11.existsSync)((0, import_node_path10.join)(appDir, "app.tsx"))) {
3131
+ const appDir = (0, import_node_path11.join)(projectRoot, "src", "app");
3132
+ if (!(0, import_node_fs13.existsSync)((0, import_node_path11.join)(appDir, "app.tsx"))) {
2993
3133
  return;
2994
3134
  }
2995
3135
  for (const [from, to] of [
@@ -2997,60 +3137,60 @@ function reshapeReactAppScaffold(projectRoot) {
2997
3137
  ["app.spec.tsx", "app.component.spec.tsx"],
2998
3138
  ["nx-welcome.tsx", "nx-welcome.component.tsx"]
2999
3139
  ]) {
3000
- if ((0, import_node_fs11.existsSync)((0, import_node_path10.join)(appDir, from))) {
3001
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(appDir, from), (0, import_node_path10.join)(appDir, to));
3140
+ if ((0, import_node_fs13.existsSync)((0, import_node_path11.join)(appDir, from))) {
3141
+ (0, import_node_fs13.renameSync)((0, import_node_path11.join)(appDir, from), (0, import_node_path11.join)(appDir, to));
3002
3142
  }
3003
3143
  }
3004
3144
  const rewrite = (file, from, to) => {
3005
- if ((0, import_node_fs11.existsSync)(file)) {
3006
- writeFileEnsured(file, repointSpecifier((0, import_node_fs11.readFileSync)(file, "utf8"), from, to));
3145
+ if ((0, import_node_fs13.existsSync)(file)) {
3146
+ writeFileEnsured(file, repointSpecifier((0, import_node_fs13.readFileSync)(file, "utf8"), from, to));
3007
3147
  }
3008
3148
  };
3009
- rewrite((0, import_node_path10.join)(appDir, "app.component.tsx"), "./nx-welcome", "./nx-welcome.component");
3010
- rewrite((0, import_node_path10.join)(appDir, "app.component.spec.tsx"), "./app", "./app.component");
3011
- rewrite((0, import_node_path10.join)(projectRoot, "src", "main.tsx"), "./app/app", "./app");
3149
+ rewrite((0, import_node_path11.join)(appDir, "app.component.tsx"), "./nx-welcome", "./nx-welcome.component");
3150
+ rewrite((0, import_node_path11.join)(appDir, "app.component.spec.tsx"), "./app", "./app.component");
3151
+ rewrite((0, import_node_path11.join)(projectRoot, "src", "main.tsx"), "./app/app", "./app");
3012
3152
  writeFileEnsured(
3013
- (0, import_node_path10.join)(appDir, "index.ts"),
3153
+ (0, import_node_path11.join)(appDir, "index.ts"),
3014
3154
  "export * from './app.component'\nexport { default } from './app.component'\n"
3015
3155
  );
3016
3156
  }
3017
3157
  function emptySlice(projectRoot, sliceDir) {
3018
- for (const entry of (0, import_node_fs11.readdirSync)(sliceDir)) {
3019
- (0, import_node_fs11.rmSync)((0, import_node_path10.join)(sliceDir, entry), { recursive: true, force: true });
3158
+ for (const entry of (0, import_node_fs13.readdirSync)(sliceDir)) {
3159
+ (0, import_node_fs13.rmSync)((0, import_node_path11.join)(sliceDir, entry), { recursive: true, force: true });
3020
3160
  }
3021
- writeFileEnsured((0, import_node_path10.join)(sliceDir, "index.ts"), "export {}\n");
3022
- addNxTargets((0, import_node_path10.join)(projectRoot, "package.json"), { test: { options: { passWithNoTests: true } } });
3161
+ writeFileEnsured((0, import_node_path11.join)(sliceDir, "index.ts"), "export {}\n");
3162
+ addNxTargets((0, import_node_path11.join)(projectRoot, "package.json"), { test: { options: { passWithNoTests: true } } });
3023
3163
  }
3024
3164
  function reshapeScaffoldSlice(projectRoot, name, extension, role, empty) {
3025
- const sourceDir = (0, import_node_path10.join)(projectRoot, "src");
3026
- const libDir = (0, import_node_path10.join)(sourceDir, "lib");
3027
- if (!(0, import_node_fs11.existsSync)((0, import_node_path10.join)(libDir, `${name}.${extension}`))) {
3165
+ const sourceDir = (0, import_node_path11.join)(projectRoot, "src");
3166
+ const libDir = (0, import_node_path11.join)(sourceDir, "lib");
3167
+ if (!(0, import_node_fs13.existsSync)((0, import_node_path11.join)(libDir, `${name}.${extension}`))) {
3028
3168
  return;
3029
3169
  }
3030
- const sliceDir = (0, import_node_path10.join)(sourceDir, name);
3031
- (0, import_node_fs11.mkdirSync)(sliceDir, { recursive: true });
3032
- for (const entry of (0, import_node_fs11.readdirSync)(libDir)) {
3170
+ const sliceDir = (0, import_node_path11.join)(sourceDir, name);
3171
+ (0, import_node_fs13.mkdirSync)(sliceDir, { recursive: true });
3172
+ for (const entry of (0, import_node_fs13.readdirSync)(libDir)) {
3033
3173
  if (entry === `${name}.${extension}`) {
3034
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(libDir, entry), (0, import_node_path10.join)(sliceDir, `${name}.${role}.${extension}`));
3174
+ (0, import_node_fs13.renameSync)((0, import_node_path11.join)(libDir, entry), (0, import_node_path11.join)(sliceDir, `${name}.${role}.${extension}`));
3035
3175
  } else if (entry === `${name}.spec.${extension}`) {
3036
- const renamed = (0, import_node_path10.join)(sliceDir, `${name}.${role}.spec.${extension}`);
3037
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(libDir, entry), renamed);
3038
- writeFileEnsured(renamed, repointSpecifier((0, import_node_fs11.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.${role}`));
3176
+ const renamed = (0, import_node_path11.join)(sliceDir, `${name}.${role}.spec.${extension}`);
3177
+ (0, import_node_fs13.renameSync)((0, import_node_path11.join)(libDir, entry), renamed);
3178
+ writeFileEnsured(renamed, repointSpecifier((0, import_node_fs13.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.${role}`));
3039
3179
  } else {
3040
- (0, import_node_fs11.renameSync)((0, import_node_path10.join)(libDir, entry), (0, import_node_path10.join)(sliceDir, entry));
3180
+ (0, import_node_fs13.renameSync)((0, import_node_path11.join)(libDir, entry), (0, import_node_path11.join)(sliceDir, entry));
3041
3181
  }
3042
3182
  }
3043
- const barrel = (0, import_node_path10.join)(sourceDir, "index.ts");
3044
- const esm = (0, import_node_fs11.existsSync)(barrel) && (0, import_node_fs11.readFileSync)(barrel, "utf8").includes(`./lib/${name}.js'`);
3045
- writeFileEnsured((0, import_node_path10.join)(sliceDir, "index.ts"), `export * from './${name}.${role}${esm ? ".js" : ""}'
3183
+ const barrel = (0, import_node_path11.join)(sourceDir, "index.ts");
3184
+ const esm = (0, import_node_fs13.existsSync)(barrel) && (0, import_node_fs13.readFileSync)(barrel, "utf8").includes(`./lib/${name}.js'`);
3185
+ writeFileEnsured((0, import_node_path11.join)(sliceDir, "index.ts"), `export * from './${name}.${role}${esm ? ".js" : ""}'
3046
3186
  `);
3047
- if ((0, import_node_fs11.existsSync)(barrel)) {
3187
+ if ((0, import_node_fs13.existsSync)(barrel)) {
3048
3188
  writeFileEnsured(
3049
3189
  barrel,
3050
- (0, import_node_fs11.readFileSync)(barrel, "utf8").replaceAll(`./lib/${name}.js'`, () => `./${name}/index.js'`).replaceAll(`./lib/${name}'`, () => `./${name}'`)
3190
+ (0, import_node_fs13.readFileSync)(barrel, "utf8").replaceAll(`./lib/${name}.js'`, () => `./${name}/index.js'`).replaceAll(`./lib/${name}'`, () => `./${name}'`)
3051
3191
  );
3052
3192
  }
3053
- (0, import_node_fs11.rmSync)(libDir, { recursive: true, force: true });
3193
+ (0, import_node_fs13.rmSync)(libDir, { recursive: true, force: true });
3054
3194
  if (empty) {
3055
3195
  emptySlice(projectRoot, sliceDir);
3056
3196
  } else if (role === "use-case") {
@@ -3060,7 +3200,7 @@ function reshapeScaffoldSlice(projectRoot, name, extension, role, empty) {
3060
3200
  function writeWorkedExample(sliceDir, name, esm) {
3061
3201
  const suffix = esm ? ".js" : "";
3062
3202
  writeFileEnsured(
3063
- (0, import_node_path10.join)(sliceDir, `${name}.contract.ts`),
3203
+ (0, import_node_path11.join)(sliceDir, `${name}.contract.ts`),
3064
3204
  `/** What greeting someone returns. */
3065
3205
  export interface Greeting {
3066
3206
  readonly message: string
@@ -3068,7 +3208,7 @@ export interface Greeting {
3068
3208
  `
3069
3209
  );
3070
3210
  writeFileEnsured(
3071
- (0, import_node_path10.join)(sliceDir, `${name}.use-case.ts`),
3211
+ (0, import_node_path11.join)(sliceDir, `${name}.use-case.ts`),
3072
3212
  `import type { Greeting } from './${name}.contract${suffix}'
3073
3213
 
3074
3214
  /**
@@ -3087,7 +3227,7 @@ export function greet (name: string): Greeting {
3087
3227
  `
3088
3228
  );
3089
3229
  writeFileEnsured(
3090
- (0, import_node_path10.join)(sliceDir, `${name}.use-case.spec.ts`),
3230
+ (0, import_node_path11.join)(sliceDir, `${name}.use-case.spec.ts`),
3091
3231
  `import { greet } from './${name}.use-case${suffix}'
3092
3232
 
3093
3233
  describe('greet', () => {
@@ -3098,7 +3238,7 @@ describe('greet', () => {
3098
3238
  `
3099
3239
  );
3100
3240
  writeFileEnsured(
3101
- (0, import_node_path10.join)(sliceDir, "index.ts"),
3241
+ (0, import_node_path11.join)(sliceDir, "index.ts"),
3102
3242
  `export * from './${name}.contract${suffix}'
3103
3243
  export * from './${name}.use-case${suffix}'
3104
3244
  `
@@ -3112,8 +3252,8 @@ function repointSpecifier(source, from, to) {
3112
3252
  return result;
3113
3253
  }
3114
3254
  function ensureNxPeerOverrides(workspaceRoot) {
3115
- const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
3116
- if (!(0, import_node_fs11.existsSync)(manifestPath)) {
3255
+ const manifestPath = (0, import_node_path11.join)(workspaceRoot, "package.json");
3256
+ if (!(0, import_node_fs13.existsSync)(manifestPath)) {
3117
3257
  return;
3118
3258
  }
3119
3259
  const manifest = readJson(manifestPath);
@@ -3136,11 +3276,11 @@ function registerProjectCommands(workspaceRoot, name, commands) {
3136
3276
  if (commands.start) {
3137
3277
  scripts[`${name}:start`] = commands.start;
3138
3278
  }
3139
- const dependabotPath = (0, import_node_path10.join)(workspaceRoot, ".github/dependabot.yml");
3140
- if ((0, import_node_fs11.existsSync)(dependabotPath)) {
3279
+ const dependabotPath = (0, import_node_path11.join)(workspaceRoot, ".github/dependabot.yml");
3280
+ if ((0, import_node_fs13.existsSync)(dependabotPath)) {
3141
3281
  writeFileEnsured(dependabotPath, dependabotConfig(workspaceRoot));
3142
3282
  }
3143
- const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
3283
+ const manifestPath = (0, import_node_path11.join)(workspaceRoot, "package.json");
3144
3284
  const manifest = readJson(manifestPath);
3145
3285
  const existingScripts = manifest.scripts ?? {};
3146
3286
  writeFileEnsured(
@@ -3178,7 +3318,7 @@ function registerProjectCommands(workspaceRoot, name, commands) {
3178
3318
  var PROJECT_MANIFEST_ROOTS = ["apps", "packages", "libs"];
3179
3319
  function rootRuntimeDependencies(workspaceRoot) {
3180
3320
  try {
3181
- return readJson((0, import_node_path10.join)(workspaceRoot, "package.json")).dependencies ?? {};
3321
+ return readJson((0, import_node_path11.join)(workspaceRoot, "package.json")).dependencies ?? {};
3182
3322
  } catch {
3183
3323
  return {};
3184
3324
  }
@@ -3190,7 +3330,7 @@ function relocateRootRuntimeDependencies(workspaceRoot, projectName, before) {
3190
3330
  return;
3191
3331
  }
3192
3332
  const manifestPath = PROJECT_MANIFEST_ROOTS.map(
3193
- (root) => (0, import_node_path10.join)(workspaceRoot, root, projectName, "package.json")
3333
+ (root) => (0, import_node_path11.join)(workspaceRoot, root, projectName, "package.json")
3194
3334
  ).find((candidate) => fileExists(candidate));
3195
3335
  if (manifestPath === void 0) {
3196
3336
  return;
@@ -3202,10 +3342,10 @@ function relocateRootRuntimeDependencies(workspaceRoot, projectName, before) {
3202
3342
  const remaining = Object.fromEntries(
3203
3343
  Object.entries(after).filter(([name]) => !added.includes(name))
3204
3344
  );
3205
- const rootManifest = readJson((0, import_node_path10.join)(workspaceRoot, "package.json"));
3345
+ const rootManifest = readJson((0, import_node_path11.join)(workspaceRoot, "package.json"));
3206
3346
  const { dependencies: _dropped, ...rest } = rootManifest;
3207
3347
  writeFileEnsured(
3208
- (0, import_node_path10.join)(workspaceRoot, "package.json"),
3348
+ (0, import_node_path11.join)(workspaceRoot, "package.json"),
3209
3349
  toJson(Object.keys(remaining).length > 0 ? { ...rest, dependencies: remaining } : rest)
3210
3350
  );
3211
3351
  logger.step(`Moved ${added.join(", ")} into ${projectName}'s own manifest`);
@@ -3244,28 +3384,28 @@ function scaffoldDotnetProject(workspaceRoot, projectRoot, identity, template) {
3244
3384
  }
3245
3385
  function writeCsharpExample(absoluteRoot, identity, kind) {
3246
3386
  if (kind === "classlib") {
3247
- (0, import_node_fs12.rmSync)((0, import_node_path11.join)(absoluteRoot, "Class1.cs"), { force: true });
3387
+ (0, import_node_fs14.rmSync)((0, import_node_path12.join)(absoluteRoot, "Class1.cs"), { force: true });
3248
3388
  }
3249
3389
  const files = csharpExampleFiles(identity);
3250
3390
  for (const [file, contents] of Object.entries(files)) {
3251
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, file), contents);
3391
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, file), contents);
3252
3392
  }
3253
3393
  if (kind === "console") {
3254
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "Program.cs"), csharpConsoleProgram(identity));
3394
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "Program.cs"), csharpConsoleProgram(identity));
3255
3395
  }
3256
3396
  }
3257
3397
  function addCsharpTestProject(workspaceRoot, projectRoot, identity) {
3258
- const name = (0, import_node_path11.basename)(projectRoot);
3398
+ const name = (0, import_node_path12.basename)(projectRoot);
3259
3399
  const testRoot = `tests/${name}`;
3260
3400
  scaffoldDotnetProject(workspaceRoot, testRoot, `${identity}.Tests`, "xunit");
3261
- (0, import_node_fs12.rmSync)((0, import_node_path11.join)(workspaceRoot, testRoot, "UnitTest1.cs"), { force: true });
3262
- writeFileEnsured((0, import_node_path11.join)(workspaceRoot, testRoot, "GreetUseCaseTests.cs"), csharpExampleTest(identity));
3401
+ (0, import_node_fs14.rmSync)((0, import_node_path12.join)(workspaceRoot, testRoot, "UnitTest1.cs"), { force: true });
3402
+ writeFileEnsured((0, import_node_path12.join)(workspaceRoot, testRoot, "GreetUseCaseTests.cs"), csharpExampleTest(identity));
3263
3403
  writeFileEnsured(
3264
- (0, import_node_path11.join)(workspaceRoot, testRoot, "project.json"),
3404
+ (0, import_node_path12.join)(workspaceRoot, testRoot, "project.json"),
3265
3405
  toJson({ name: `${name}-tests`, tags: ["type:csharp-test"] })
3266
3406
  );
3267
- const reference = (0, import_node_path11.join)(workspaceRoot, projectRoot, `${identity}.csproj`);
3268
- if (runShell("dotnet", ["add", (0, import_node_path11.join)(workspaceRoot, testRoot), "reference", reference], workspaceRoot) !== 0) {
3407
+ const reference = (0, import_node_path12.join)(workspaceRoot, projectRoot, `${identity}.csproj`);
3408
+ if (runShell("dotnet", ["add", (0, import_node_path12.join)(workspaceRoot, testRoot), "reference", reference], workspaceRoot) !== 0) {
3269
3409
  throw new Error(`dotnet add reference failed for ${testRoot}`);
3270
3410
  }
3271
3411
  }
@@ -3292,9 +3432,9 @@ function addCsharpApp(workspaceRoot, name, template = "console") {
3292
3432
  ensureAdmZip(workspaceRoot);
3293
3433
  const projectRoot = `apps/${name}`;
3294
3434
  scaffoldDotnetProject(workspaceRoot, projectRoot, pascalCase(name), template);
3295
- writeCsharpExample((0, import_node_path11.join)(workspaceRoot, projectRoot), pascalCase(name), template);
3435
+ writeCsharpExample((0, import_node_path12.join)(workspaceRoot, projectRoot), pascalCase(name), template);
3296
3436
  addCsharpTestProject(workspaceRoot, projectRoot, pascalCase(name));
3297
- addProjectJsonTargets((0, import_node_path11.join)(workspaceRoot, projectRoot, "project.json"), {
3437
+ addProjectJsonTargets((0, import_node_path12.join)(workspaceRoot, projectRoot, "project.json"), {
3298
3438
  package: csharpAppPackageTarget("csharp-app", projectRoot, name),
3299
3439
  start: csharpAppStartTarget(projectRoot)
3300
3440
  });
@@ -3387,7 +3527,7 @@ class CsharpVersionActions extends VersionActions {
3387
3527
  module.exports = CsharpVersionActions
3388
3528
  `;
3389
3529
  function writeCsharpVersionActions(workspaceRoot) {
3390
- writeFileEnsured((0, import_node_path11.join)(workspaceRoot, CSHARP_VERSION_ACTIONS_PATH), CSHARP_VERSION_ACTIONS);
3530
+ writeFileEnsured((0, import_node_path12.join)(workspaceRoot, CSHARP_VERSION_ACTIONS_PATH), CSHARP_VERSION_ACTIONS);
3391
3531
  }
3392
3532
  function addProjectJsonReleaseVersionActions(projectJsonPath) {
3393
3533
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
@@ -3402,7 +3542,7 @@ function addProjectJsonReleaseVersionActions(projectJsonPath) {
3402
3542
  );
3403
3543
  }
3404
3544
  function addInitialVersion(csprojPath) {
3405
- const contents = (0, import_node_fs12.readFileSync)(csprojPath, "utf8");
3545
+ const contents = (0, import_node_fs14.readFileSync)(csprojPath, "utf8");
3406
3546
  writeFileEnsured(csprojPath, contents.replace("<PropertyGroup>", "<PropertyGroup>\n <Version>0.1.0</Version>"));
3407
3547
  }
3408
3548
  function csharpLibPublishTarget(projectRoot) {
@@ -3417,16 +3557,16 @@ async function addCsharpLib(workspaceRoot, name, options, kindProvided) {
3417
3557
  const projectRoot = `packages/${name}`;
3418
3558
  const identity = `${pascalScope(scope)}.${pascalCase(name)}`;
3419
3559
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "classlib");
3420
- writeCsharpExample((0, import_node_path11.join)(workspaceRoot, projectRoot), identity, "classlib");
3560
+ writeCsharpExample((0, import_node_path12.join)(workspaceRoot, projectRoot), identity, "classlib");
3421
3561
  addCsharpTestProject(workspaceRoot, projectRoot, identity);
3422
- addInitialVersion((0, import_node_path11.join)(workspaceRoot, projectRoot, `${identity}.csproj`));
3562
+ addInitialVersion((0, import_node_path12.join)(workspaceRoot, projectRoot, `${identity}.csproj`));
3423
3563
  writeCsharpVersionActions(workspaceRoot);
3424
- addProjectJsonReleaseVersionActions((0, import_node_path11.join)(workspaceRoot, projectRoot, "project.json"));
3425
- addProjectJsonTargets((0, import_node_path11.join)(workspaceRoot, projectRoot, "project.json"), {
3564
+ addProjectJsonReleaseVersionActions((0, import_node_path12.join)(workspaceRoot, projectRoot, "project.json"));
3565
+ addProjectJsonTargets((0, import_node_path12.join)(workspaceRoot, projectRoot, "project.json"), {
3426
3566
  "nx-release-publish": csharpLibPublishTarget(projectRoot)
3427
3567
  });
3428
3568
  const registry = readMnciConfig(workspaceRoot).registry ?? { kind: "npm" };
3429
- writeFileEnsured((0, import_node_path11.join)(workspaceRoot, "nuget.config"), nugetConfigContent(registry, scope));
3569
+ writeFileEnsured((0, import_node_path12.join)(workspaceRoot, "nuget.config"), nugetConfigContent(registry, scope));
3430
3570
  registerProjectCommands(workspaceRoot, name, { build: true });
3431
3571
  }
3432
3572
  function addCsharpInternalLib(workspaceRoot, name) {
@@ -3435,7 +3575,7 @@ function addCsharpInternalLib(workspaceRoot, name) {
3435
3575
  const projectRoot = `libs/${name}`;
3436
3576
  const identity = pascalCase(name);
3437
3577
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "classlib");
3438
- writeCsharpExample((0, import_node_path11.join)(workspaceRoot, projectRoot), identity, "classlib");
3578
+ writeCsharpExample((0, import_node_path12.join)(workspaceRoot, projectRoot), identity, "classlib");
3439
3579
  addCsharpTestProject(workspaceRoot, projectRoot, identity);
3440
3580
  registerProjectCommands(workspaceRoot, name, { build: false });
3441
3581
  logger.step(
@@ -3504,20 +3644,20 @@ function addCsharpFunctionApp(workspaceRoot, name) {
3504
3644
  const projectRoot = `apps/${name}`;
3505
3645
  const identity = pascalCase(name);
3506
3646
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "console");
3507
- const absoluteRoot = (0, import_node_path11.join)(workspaceRoot, projectRoot);
3508
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, `${identity}.csproj`), csharpFunctionAppCsproj());
3509
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "Program.cs"), CSHARP_FUNCTION_APP_PROGRAM);
3510
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "Hello.cs"), csharpFunctionAppHello(identity));
3647
+ const absoluteRoot = (0, import_node_path12.join)(workspaceRoot, projectRoot);
3648
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, `${identity}.csproj`), csharpFunctionAppCsproj());
3649
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "Program.cs"), CSHARP_FUNCTION_APP_PROGRAM);
3650
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "Hello.cs"), csharpFunctionAppHello(identity));
3511
3651
  const example = csharpExampleFiles(identity);
3512
3652
  for (const [file, contents] of Object.entries(example)) {
3513
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, file), contents);
3653
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, file), contents);
3514
3654
  }
3515
- writeFileEnsured((0, import_node_path11.join)(absoluteRoot, "host.json"), CSHARP_FUNCTION_APP_HOST_JSON);
3655
+ writeFileEnsured((0, import_node_path12.join)(absoluteRoot, "host.json"), CSHARP_FUNCTION_APP_HOST_JSON);
3516
3656
  if (runShell("dotnet", ["restore", projectRoot], workspaceRoot) !== 0) {
3517
3657
  throw new Error(`dotnet restore failed for ${projectRoot}`);
3518
3658
  }
3519
3659
  addCsharpTestProject(workspaceRoot, projectRoot, identity);
3520
- addProjectJsonTargets((0, import_node_path11.join)(absoluteRoot, "project.json"), {
3660
+ addProjectJsonTargets((0, import_node_path12.join)(absoluteRoot, "project.json"), {
3521
3661
  package: csharpAppPackageTarget("csharp-function-app", projectRoot, name),
3522
3662
  start: csharpFunctionAppStartTarget(projectRoot)
3523
3663
  });
@@ -3525,7 +3665,7 @@ function addCsharpFunctionApp(workspaceRoot, name) {
3525
3665
  }
3526
3666
 
3527
3667
  // src/project-scaffolding/flutter.use-case.ts
3528
- var import_node_path12 = require("path");
3668
+ var import_node_path13 = require("path");
3529
3669
  function flutterAppStartTarget(name) {
3530
3670
  return {
3531
3671
  executor: "nx:run-commands",
@@ -3561,7 +3701,7 @@ function addFlutterApp(workspaceRoot, name) {
3561
3701
  prepareFlutter(workspaceRoot);
3562
3702
  ensureAdmZip(workspaceRoot);
3563
3703
  runNx(["g", "@mnci/nx-flutter:application", name, "--no-interactive"], workspaceRoot);
3564
- addProjectJsonTargets((0, import_node_path12.join)(workspaceRoot, "apps", name, "project.json"), {
3704
+ addProjectJsonTargets((0, import_node_path13.join)(workspaceRoot, "apps", name, "project.json"), {
3565
3705
  start: flutterAppStartTarget(name)
3566
3706
  });
3567
3707
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
@@ -3578,8 +3718,8 @@ function addFlutterInternalLib(workspaceRoot, name) {
3578
3718
  }
3579
3719
 
3580
3720
  // src/project-scaffolding/go.use-case.ts
3581
- var import_node_fs16 = require("fs");
3582
- var import_node_path16 = require("path");
3721
+ var import_node_fs18 = require("fs");
3722
+ var import_node_path17 = require("path");
3583
3723
 
3584
3724
  // src/project-scaffolding/go-example.algorithm.ts
3585
3725
  function greetingContract(packageName) {
@@ -3648,14 +3788,14 @@ function goAppExampleFiles(modulePath) {
3648
3788
  }
3649
3789
 
3650
3790
  // src/go-workspace/go-plugin.use-case.ts
3651
- var import_node_fs13 = require("fs");
3652
- var import_node_path13 = require("path");
3791
+ var import_node_fs15 = require("fs");
3792
+ var import_node_path14 = require("path");
3653
3793
  var NX_GO_PLUGIN = "@nx-go/nx-go";
3654
3794
  function hasGoProject(workspaceRoot) {
3655
- const projectFiles = ["apps", "libs", "packages"].flatMap((directory) => (0, import_node_fs13.globSync)(`${directory}/*/project.json`, { cwd: workspaceRoot }));
3795
+ const projectFiles = ["apps", "libs", "packages"].flatMap((directory) => (0, import_node_fs15.globSync)(`${directory}/*/project.json`, { cwd: workspaceRoot }));
3656
3796
  return projectFiles.some((projectFile) => {
3657
3797
  try {
3658
- const { tags } = JSON.parse((0, import_node_fs13.readFileSync)((0, import_node_path13.join)(workspaceRoot, projectFile), "utf8"));
3798
+ const { tags } = JSON.parse((0, import_node_fs15.readFileSync)((0, import_node_path14.join)(workspaceRoot, projectFile), "utf8"));
3659
3799
  return (tags ?? []).some((tag) => tag.startsWith("type:go-"));
3660
3800
  } catch {
3661
3801
  return false;
@@ -3663,7 +3803,7 @@ function hasGoProject(workspaceRoot) {
3663
3803
  });
3664
3804
  }
3665
3805
  function isNxGoPluginRegistered(workspaceRoot) {
3666
- const nxJsonPath = (0, import_node_path13.join)(workspaceRoot, "nx.json");
3806
+ const nxJsonPath = (0, import_node_path14.join)(workspaceRoot, "nx.json");
3667
3807
  if (!fileExists(nxJsonPath)) {
3668
3808
  return false;
3669
3809
  }
@@ -3690,7 +3830,7 @@ function goModulePrefix(workspaceRoot) {
3690
3830
  return result.status === 0 ? modulePrefixFromRemoteUrl(result.stdout) : void 0;
3691
3831
  }
3692
3832
  function registerNxGoPlugin(workspaceRoot) {
3693
- const nxJsonPath = (0, import_node_path13.join)(workspaceRoot, "nx.json");
3833
+ const nxJsonPath = (0, import_node_path14.join)(workspaceRoot, "nx.json");
3694
3834
  if (!fileExists(nxJsonPath)) {
3695
3835
  return false;
3696
3836
  }
@@ -3714,8 +3854,8 @@ function registerNxGoPlugin(workspaceRoot) {
3714
3854
  }
3715
3855
 
3716
3856
  // src/project-scaffolding/go-release.use-case.ts
3717
- var import_node_fs14 = require("fs");
3718
- var import_node_path14 = require("path");
3857
+ var import_node_fs16 = require("fs");
3858
+ var import_node_path15 = require("path");
3719
3859
  var GO_RELEASE_SCRIPT_PATH = "tools/go-app-release.cjs";
3720
3860
  var GO_RELEASE_SCRIPT = String.raw`#!/usr/bin/env node
3721
3861
  // Written by mnci: 'mnci add go-app --release' creates it and 'mnci upgrade'
@@ -3841,7 +3981,7 @@ var GO_RELEASE_PUBLISH_TARGET = {
3841
3981
  }
3842
3982
  };
3843
3983
  function makeGoAppReleasable(workspaceRoot, name) {
3844
- const projectJsonPath = (0, import_node_path14.join)(workspaceRoot, "apps", name, "project.json");
3984
+ const projectJsonPath = (0, import_node_path15.join)(workspaceRoot, "apps", name, "project.json");
3845
3985
  if (!fileExists(projectJsonPath)) {
3846
3986
  throw new Error(`No Go app at apps/${name}: cannot make it releasable.`);
3847
3987
  }
@@ -3862,22 +4002,22 @@ function makeGoAppReleasable(workspaceRoot, name) {
3862
4002
  }
3863
4003
  })
3864
4004
  );
3865
- writeFileEnsured((0, import_node_path14.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH), GO_RELEASE_SCRIPT);
4005
+ writeFileEnsured((0, import_node_path15.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH), GO_RELEASE_SCRIPT);
3866
4006
  }
3867
4007
  function refreshGoReleaseScript(workspaceRoot) {
3868
- const apps = (0, import_node_path14.join)(workspaceRoot, "apps");
4008
+ const apps = (0, import_node_path15.join)(workspaceRoot, "apps");
3869
4009
  let entries;
3870
4010
  try {
3871
- entries = (0, import_node_fs14.readdirSync)(apps);
4011
+ entries = (0, import_node_fs16.readdirSync)(apps);
3872
4012
  } catch {
3873
4013
  return false;
3874
4014
  }
3875
4015
  const hasReleasableApp = entries.some((entry) => {
3876
- const projectJsonPath = (0, import_node_path14.join)(apps, entry, "project.json");
4016
+ const projectJsonPath = (0, import_node_path15.join)(apps, entry, "project.json");
3877
4017
  return fileExists(projectJsonPath) && (readJson(projectJsonPath).tags ?? []).includes(GO_RELEASE_TAG);
3878
4018
  });
3879
- const path = (0, import_node_path14.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH);
3880
- if (!hasReleasableApp || fileExists(path) && (0, import_node_fs14.readFileSync)(path, "utf8") === GO_RELEASE_SCRIPT) {
4019
+ const path = (0, import_node_path15.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH);
4020
+ if (!hasReleasableApp || fileExists(path) && (0, import_node_fs16.readFileSync)(path, "utf8") === GO_RELEASE_SCRIPT) {
3881
4021
  return false;
3882
4022
  }
3883
4023
  writeFileEnsured(path, GO_RELEASE_SCRIPT);
@@ -3885,8 +4025,8 @@ function refreshGoReleaseScript(workspaceRoot) {
3885
4025
  }
3886
4026
 
3887
4027
  // src/project-scaffolding/go-web.use-case.ts
3888
- var import_node_fs15 = require("fs");
3889
- var import_node_path15 = require("path");
4028
+ var import_node_fs17 = require("fs");
4029
+ var import_node_path16 = require("path");
3890
4030
  var TARGETS_NEEDING_THE_FRONTEND = ["build", "test", "lint", "start", "build-all", "build-native"];
3891
4031
  var DEFAULT_ADDRESS = "127.0.0.1:8080";
3892
4032
  var GO_WEB_SOURCE = `package main
@@ -3964,18 +4104,18 @@ func TestWebHandlerServesTheBuiltFrontend(t *testing.T) {
3964
4104
  }
3965
4105
  `;
3966
4106
  function assertWebApp(workspaceRoot, web) {
3967
- const directory = (0, import_node_path15.join)(workspaceRoot, "apps", web);
3968
- const isReactApp = fileExists((0, import_node_path15.join)(directory, "package.json")) && (0, import_node_fs15.readdirSync)(directory).some((entry) => entry.startsWith("vite.config."));
4107
+ const directory = (0, import_node_path16.join)(workspaceRoot, "apps", web);
4108
+ const isReactApp = fileExists((0, import_node_path16.join)(directory, "package.json")) && (0, import_node_fs17.readdirSync)(directory).some((entry) => entry.startsWith("vite.config."));
3969
4109
  if (!isReactApp) {
3970
4110
  throw new Error(`--web ${web}: no React app at apps/${web}. Add it first with \`mnci add react-app ${web}\`.`);
3971
4111
  }
3972
4112
  }
3973
4113
  function webProjectName(workspaceRoot, web) {
3974
- const manifest = readJson((0, import_node_path15.join)(workspaceRoot, "apps", web, "package.json"));
4114
+ const manifest = readJson((0, import_node_path16.join)(workspaceRoot, "apps", web, "package.json"));
3975
4115
  return manifest.nx?.name ?? manifest.name ?? web;
3976
4116
  }
3977
4117
  function addApiProxy(viteConfigPath) {
3978
- const source = (0, import_node_fs15.readFileSync)(viteConfigPath, "utf8");
4118
+ const source = (0, import_node_fs17.readFileSync)(viteConfigPath, "utf8");
3979
4119
  if (source.includes("'/api'") || source.includes('"/api"')) {
3980
4120
  return false;
3981
4121
  }
@@ -3988,7 +4128,7 @@ function addApiProxy(viteConfigPath) {
3988
4128
  return true;
3989
4129
  }
3990
4130
  function wireGoAppToWeb(workspaceRoot, name, web) {
3991
- const projectJsonPath = (0, import_node_path15.join)(workspaceRoot, "apps", name, "project.json");
4131
+ const projectJsonPath = (0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json");
3992
4132
  const project = readJson(projectJsonPath);
3993
4133
  const webName = webProjectName(workspaceRoot, web);
3994
4134
  const targets = project.targets ?? {};
@@ -4014,13 +4154,13 @@ function wireGoAppToWeb(workspaceRoot, name, web) {
4014
4154
  projectJsonPath,
4015
4155
  toJson({ ...project, implicitDependencies: [.../* @__PURE__ */ new Set([...project.implicitDependencies ?? [], webName])], targets })
4016
4156
  );
4017
- const directory = (0, import_node_path15.join)(workspaceRoot, "apps", name);
4018
- writeFileEnsured((0, import_node_path15.join)(directory, ".gitignore"), "/web/\n");
4019
- writeFileEnsured((0, import_node_path15.join)(directory, "web.go"), GO_WEB_SOURCE);
4020
- writeFileEnsured((0, import_node_path15.join)(directory, "main.go"), GO_WEB_MAIN);
4021
- writeFileEnsured((0, import_node_path15.join)(directory, "main_test.go"), GO_WEB_MAIN_TEST);
4022
- const viteConfig = (0, import_node_fs15.readdirSync)((0, import_node_path15.join)(workspaceRoot, "apps", web)).find((entry) => entry.startsWith("vite.config."));
4023
- if (viteConfig === void 0 || !addApiProxy((0, import_node_path15.join)(workspaceRoot, "apps", web, viteConfig))) {
4157
+ const directory = (0, import_node_path16.join)(workspaceRoot, "apps", name);
4158
+ writeFileEnsured((0, import_node_path16.join)(directory, ".gitignore"), "/web/\n");
4159
+ writeFileEnsured((0, import_node_path16.join)(directory, "web.go"), GO_WEB_SOURCE);
4160
+ writeFileEnsured((0, import_node_path16.join)(directory, "main.go"), GO_WEB_MAIN);
4161
+ writeFileEnsured((0, import_node_path16.join)(directory, "main_test.go"), GO_WEB_MAIN_TEST);
4162
+ const viteConfig = (0, import_node_fs17.readdirSync)((0, import_node_path16.join)(workspaceRoot, "apps", web)).find((entry) => entry.startsWith("vite.config."));
4163
+ if (viteConfig === void 0 || !addApiProxy((0, import_node_path16.join)(workspaceRoot, "apps", web, viteConfig))) {
4024
4164
  logger.warn(
4025
4165
  `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.`
4026
4166
  );
@@ -4054,7 +4194,7 @@ function ensureNxGoPlugin(workspaceRoot) {
4054
4194
  }
4055
4195
  }
4056
4196
  function ensureGoModule(workspaceRoot) {
4057
- if (fileExists((0, import_node_path16.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path16.join)(workspaceRoot, "go.mod"))) {
4197
+ if (fileExists((0, import_node_path17.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path17.join)(workspaceRoot, "go.mod"))) {
4058
4198
  return;
4059
4199
  }
4060
4200
  logger.step("Bootstrapping the Go workspace (go.work, one module per project)");
@@ -4062,38 +4202,38 @@ function ensureGoModule(workspaceRoot) {
4062
4202
  }
4063
4203
  function readGoModModule(goModPath) {
4064
4204
  try {
4065
- return /^module\s+(\S+)/m.exec((0, import_node_fs16.readFileSync)(goModPath, "utf8"))?.[1];
4205
+ return /^module\s+(\S+)/m.exec((0, import_node_fs18.readFileSync)(goModPath, "utf8"))?.[1];
4066
4206
  } catch {
4067
4207
  return void 0;
4068
4208
  }
4069
4209
  }
4070
4210
  function goModulePathFor(workspaceRoot, projectDir) {
4071
- const projectModule = readGoModModule((0, import_node_path16.join)(workspaceRoot, projectDir, "go.mod"));
4211
+ const projectModule = readGoModModule((0, import_node_path17.join)(workspaceRoot, projectDir, "go.mod"));
4072
4212
  if (projectModule !== void 0) {
4073
4213
  return projectModule;
4074
4214
  }
4075
- const rootModule = readGoModModule((0, import_node_path16.join)(workspaceRoot, "go.mod"));
4215
+ const rootModule = readGoModModule((0, import_node_path17.join)(workspaceRoot, "go.mod"));
4076
4216
  return rootModule === void 0 ? void 0 : `${rootModule}/${projectDir}`;
4077
4217
  }
4078
4218
  function setGoModulePath(workspaceRoot, projectDir) {
4079
4219
  const prefix = goModulePrefix(workspaceRoot);
4080
- const goModPath = (0, import_node_path16.join)(workspaceRoot, projectDir, "go.mod");
4220
+ const goModPath = (0, import_node_path17.join)(workspaceRoot, projectDir, "go.mod");
4081
4221
  if (prefix === void 0 || !fileExists(goModPath)) {
4082
4222
  return;
4083
4223
  }
4084
- const rewritten = (0, import_node_fs16.readFileSync)(goModPath, "utf8").replace(/^module\s+\S+/m, () => `module ${prefix}/${projectDir}`);
4224
+ const rewritten = (0, import_node_fs18.readFileSync)(goModPath, "utf8").replace(/^module\s+\S+/m, () => `module ${prefix}/${projectDir}`);
4085
4225
  writeFileEnsured(goModPath, rewritten);
4086
4226
  }
4087
4227
  function writeGoAppExample(workspaceRoot, projectDir) {
4088
- const goModPath = (0, import_node_path16.join)(workspaceRoot, projectDir, "go.mod");
4089
- const modulePath = fileExists(goModPath) ? /^module\s+(\S+)/m.exec((0, import_node_fs16.readFileSync)(goModPath, "utf8"))?.[1] : void 0;
4228
+ const goModPath = (0, import_node_path17.join)(workspaceRoot, projectDir, "go.mod");
4229
+ const modulePath = fileExists(goModPath) ? /^module\s+(\S+)/m.exec((0, import_node_fs18.readFileSync)(goModPath, "utf8"))?.[1] : void 0;
4090
4230
  if (modulePath === void 0) {
4091
4231
  return;
4092
4232
  }
4093
- (0, import_node_fs16.rmSync)((0, import_node_path16.join)(workspaceRoot, projectDir, "main_test.go"), { force: true });
4233
+ (0, import_node_fs18.rmSync)((0, import_node_path17.join)(workspaceRoot, projectDir, "main_test.go"), { force: true });
4094
4234
  const example = goAppExampleFiles(modulePath);
4095
4235
  for (const [relative, contents] of Object.entries(example)) {
4096
- writeFileEnsured((0, import_node_path16.join)(workspaceRoot, projectDir, relative), contents);
4236
+ writeFileEnsured((0, import_node_path17.join)(workspaceRoot, projectDir, relative), contents);
4097
4237
  }
4098
4238
  }
4099
4239
  function goTestTarget() {
@@ -4171,16 +4311,16 @@ function goNativePackageTarget(name) {
4171
4311
  }
4172
4312
  function addGoPlatformTargets(workspaceRoot) {
4173
4313
  const changed = [];
4174
- const apps = (0, import_node_path16.join)(workspaceRoot, "apps");
4314
+ const apps = (0, import_node_path17.join)(workspaceRoot, "apps");
4175
4315
  if (!fileExists(apps)) {
4176
4316
  return changed;
4177
4317
  }
4178
- for (const name of (0, import_node_fs16.readdirSync)(apps)) {
4179
- const projectJsonPath = (0, import_node_path16.join)(apps, name, "project.json");
4318
+ for (const name of (0, import_node_fs18.readdirSync)(apps)) {
4319
+ const projectJsonPath = (0, import_node_path17.join)(apps, name, "project.json");
4180
4320
  if (!fileExists(projectJsonPath)) {
4181
4321
  continue;
4182
4322
  }
4183
- const project = JSON.parse((0, import_node_fs16.readFileSync)(projectJsonPath, "utf8"));
4323
+ const project = JSON.parse((0, import_node_fs18.readFileSync)(projectJsonPath, "utf8"));
4184
4324
  const tag = (project.tags ?? []).find((each) => each === "type:go-app" || each === "type:go-function-app")?.slice("type:".length);
4185
4325
  if (tag === void 0 || (project.tags ?? []).includes(GO_CGO_TAG)) {
4186
4326
  continue;
@@ -4216,8 +4356,8 @@ function goLibraryIdentifiers(projectName) {
4216
4356
  }
4217
4357
  function reshapeGoLibraryScaffold(projectRoot, projectName) {
4218
4358
  const { packageName, fileStem } = goLibraryIdentifiers(projectName);
4219
- (0, import_node_fs16.rmSync)((0, import_node_path16.join)(projectRoot, `${projectName}.go`), { force: true });
4220
- (0, import_node_fs16.rmSync)((0, import_node_path16.join)(projectRoot, `${projectName}_test.go`), { force: true });
4359
+ (0, import_node_fs18.rmSync)((0, import_node_path17.join)(projectRoot, `${projectName}.go`), { force: true });
4360
+ (0, import_node_fs18.rmSync)((0, import_node_path17.join)(projectRoot, `${projectName}_test.go`), { force: true });
4221
4361
  const files = [
4222
4362
  [
4223
4363
  "doc.go",
@@ -4227,7 +4367,7 @@ package ${packageName}
4227
4367
  `
4228
4368
  ],
4229
4369
  [
4230
- (0, import_node_path16.join)(packageName, "doc.go"),
4370
+ (0, import_node_path17.join)(packageName, "doc.go"),
4231
4371
  `// Package ${packageName} is the starter slice of ${projectName}: rename it after
4232
4372
  // the outcome it delivers, and add one package per further outcome.
4233
4373
  package ${packageName}
@@ -4235,11 +4375,11 @@ package ${packageName}
4235
4375
  ],
4236
4376
  // The starter slice: a contract, a use case and its test (see goLibraryExampleFiles).
4237
4377
  ...Object.entries(goLibraryExampleFiles(packageName, fileStem)).map(
4238
- ([name, content]) => [(0, import_node_path16.join)(packageName, name), content]
4378
+ ([name, content]) => [(0, import_node_path17.join)(packageName, name), content]
4239
4379
  )
4240
4380
  ];
4241
4381
  for (const [relativePath, content] of files) {
4242
- const path = (0, import_node_path16.join)(projectRoot, relativePath);
4382
+ const path = (0, import_node_path17.join)(projectRoot, relativePath);
4243
4383
  if (!fileExists(path)) {
4244
4384
  writeFileEnsured(path, content);
4245
4385
  }
@@ -4277,7 +4417,7 @@ function addGoApp(workspaceRoot, name, options = {}) {
4277
4417
  if (options.web === void 0) {
4278
4418
  writeGoAppExample(workspaceRoot, `apps/${name}`);
4279
4419
  }
4280
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json"), {
4420
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "apps", name, "project.json"), {
4281
4421
  build: goBuildTarget(name),
4282
4422
  test: goTestTarget(),
4283
4423
  lint: goLintTarget(),
@@ -4317,7 +4457,7 @@ function addGoFunctionApp(workspaceRoot, name) {
4317
4457
  );
4318
4458
  setGoModulePath(workspaceRoot, `apps/${name}`);
4319
4459
  writeGoAppExample(workspaceRoot, `apps/${name}`);
4320
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json"), {
4460
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "apps", name, "project.json"), {
4321
4461
  "build": goBuildTarget(name),
4322
4462
  "test": goTestTarget(),
4323
4463
  "lint": goLintTarget(),
@@ -4341,11 +4481,11 @@ function addGoLib(workspaceRoot, name) {
4341
4481
  workspaceRoot
4342
4482
  );
4343
4483
  setGoModulePath(workspaceRoot, `packages/${name}`);
4344
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "packages", name, "project.json"), {
4484
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "packages", name, "project.json"), {
4345
4485
  test: goTestTarget(),
4346
4486
  lint: goLintTarget()
4347
4487
  });
4348
- const slice = reshapeGoLibraryScaffold((0, import_node_path16.join)(workspaceRoot, "packages", name), name);
4488
+ const slice = reshapeGoLibraryScaffold((0, import_node_path17.join)(workspaceRoot, "packages", name), name);
4349
4489
  registerProjectCommands(workspaceRoot, name, { build: false });
4350
4490
  const module2 = goModulePathFor(workspaceRoot, `packages/${name}`);
4351
4491
  if (module2) {
@@ -4366,11 +4506,11 @@ function addGoInternalLib(workspaceRoot, name) {
4366
4506
  workspaceRoot
4367
4507
  );
4368
4508
  setGoModulePath(workspaceRoot, `libs/${name}`);
4369
- addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "libs", name, "project.json"), {
4509
+ addProjectJsonTargets((0, import_node_path17.join)(workspaceRoot, "libs", name, "project.json"), {
4370
4510
  test: goTestTarget(),
4371
4511
  lint: goLintTarget()
4372
4512
  });
4373
- const slice = reshapeGoLibraryScaffold((0, import_node_path16.join)(workspaceRoot, "libs", name), name);
4513
+ const slice = reshapeGoLibraryScaffold((0, import_node_path17.join)(workspaceRoot, "libs", name), name);
4374
4514
  registerProjectCommands(workspaceRoot, name, { build: false });
4375
4515
  const module2 = goModulePathFor(workspaceRoot, `libs/${name}`);
4376
4516
  if (module2) {
@@ -4379,7 +4519,7 @@ function addGoInternalLib(workspaceRoot, name) {
4379
4519
  }
4380
4520
 
4381
4521
  // src/project-scaffolding/node.use-case.ts
4382
- var import_node_path17 = require("path");
4522
+ var import_node_path18 = require("path");
4383
4523
 
4384
4524
  // src/project-scaffolding/node-app-example.algorithm.ts
4385
4525
  var GREET_USE_CASE = `import type { Greeting } from './greeting.contract'
@@ -4502,12 +4642,12 @@ function runNodeApp(workspaceRoot, name, stack, framework) {
4502
4642
  ],
4503
4643
  workspaceRoot
4504
4644
  );
4505
- const appRoot = (0, import_node_path17.join)(workspaceRoot, "apps", name);
4645
+ const appRoot = (0, import_node_path18.join)(workspaceRoot, "apps", name);
4506
4646
  separateDeclarationOutput(appRoot);
4507
4647
  repairAssetMapping(appRoot, name);
4508
4648
  }
4509
4649
  function separateDeclarationOutput(appRoot) {
4510
- const tsconfigPath = (0, import_node_path17.join)(appRoot, "tsconfig.app.json");
4650
+ const tsconfigPath = (0, import_node_path18.join)(appRoot, "tsconfig.app.json");
4511
4651
  if (!fileExists(tsconfigPath)) {
4512
4652
  return;
4513
4653
  }
@@ -4529,7 +4669,7 @@ function separateDeclarationOutput(appRoot) {
4529
4669
  );
4530
4670
  }
4531
4671
  function repairAssetMapping(appRoot, name) {
4532
- const manifestPath = (0, import_node_path17.join)(appRoot, "package.json");
4672
+ const manifestPath = (0, import_node_path18.join)(appRoot, "package.json");
4533
4673
  if (!fileExists(manifestPath)) {
4534
4674
  return;
4535
4675
  }
@@ -4558,11 +4698,11 @@ function addNodeApp(workspaceRoot, name, stack, framework = "none") {
4558
4698
  const example = nodeAppExampleFiles(framework);
4559
4699
  if (example !== null) {
4560
4700
  for (const [relative, contents] of Object.entries(example)) {
4561
- writeFileEnsured((0, import_node_path17.join)(workspaceRoot, "apps", name, "src", relative), contents);
4701
+ writeFileEnsured((0, import_node_path18.join)(workspaceRoot, "apps", name, "src", relative), contents);
4562
4702
  }
4563
4703
  }
4564
4704
  ensureAdmZip(workspaceRoot);
4565
- addNxTargets((0, import_node_path17.join)(workspaceRoot, "apps", name, "package.json"), {
4705
+ addNxTargets((0, import_node_path18.join)(workspaceRoot, "apps", name, "package.json"), {
4566
4706
  package: nodeAppPackageTarget(name)
4567
4707
  });
4568
4708
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
@@ -4631,10 +4771,10 @@ describe('greet', () => {
4631
4771
  })
4632
4772
  `;
4633
4773
  function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
4634
- const manifestPath = (0, import_node_path17.join)(nodeFunctionAppRoot, "package.json");
4774
+ const manifestPath = (0, import_node_path18.join)(nodeFunctionAppRoot, "package.json");
4635
4775
  const manifest = readJson(manifestPath);
4636
4776
  const azureFunctionsVersion = readJson(
4637
- (0, import_node_path17.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
4777
+ (0, import_node_path18.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
4638
4778
  ).version;
4639
4779
  const dependencies = manifest.dependencies ?? {};
4640
4780
  writeFileEnsured(
@@ -4677,20 +4817,20 @@ function nodeFunctionAppStartTarget(name) {
4677
4817
  function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
4678
4818
  runNodeApp(workspaceRoot, name, stack, "none");
4679
4819
  ensureAzureFunctionsPackage(workspaceRoot);
4680
- const nodeFunctionAppRoot = (0, import_node_path17.join)(workspaceRoot, "apps", name);
4681
- writeFileEnsured((0, import_node_path17.join)(nodeFunctionAppRoot, "src/main.ts"), empty ? NODE_FUNCTION_APP_MAIN_EMPTY : NODE_FUNCTION_APP_MAIN);
4820
+ const nodeFunctionAppRoot = (0, import_node_path18.join)(workspaceRoot, "apps", name);
4821
+ writeFileEnsured((0, import_node_path18.join)(nodeFunctionAppRoot, "src/main.ts"), empty ? NODE_FUNCTION_APP_MAIN_EMPTY : NODE_FUNCTION_APP_MAIN);
4682
4822
  if (!empty) {
4683
- const slice = (0, import_node_path17.join)(nodeFunctionAppRoot, "src/hello");
4684
- writeFileEnsured((0, import_node_path17.join)(slice, "hello.handler.ts"), NODE_FUNCTION_APP_HELLO);
4685
- writeFileEnsured((0, import_node_path17.join)(slice, "greet.use-case.ts"), NODE_FUNCTION_APP_GREET_USE_CASE);
4686
- writeFileEnsured((0, import_node_path17.join)(slice, "greet.use-case.spec.ts"), NODE_FUNCTION_APP_GREET_SPEC);
4687
- writeFileEnsured((0, import_node_path17.join)(slice, "greeting.contract.ts"), NODE_FUNCTION_APP_GREETING_CONTRACT);
4688
- writeFileEnsured((0, import_node_path17.join)(slice, "index.ts"), NODE_FUNCTION_APP_HELLO_BARREL);
4689
- }
4690
- writeFileEnsured((0, import_node_path17.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
4823
+ const slice = (0, import_node_path18.join)(nodeFunctionAppRoot, "src/hello");
4824
+ writeFileEnsured((0, import_node_path18.join)(slice, "hello.handler.ts"), NODE_FUNCTION_APP_HELLO);
4825
+ writeFileEnsured((0, import_node_path18.join)(slice, "greet.use-case.ts"), NODE_FUNCTION_APP_GREET_USE_CASE);
4826
+ writeFileEnsured((0, import_node_path18.join)(slice, "greet.use-case.spec.ts"), NODE_FUNCTION_APP_GREET_SPEC);
4827
+ writeFileEnsured((0, import_node_path18.join)(slice, "greeting.contract.ts"), NODE_FUNCTION_APP_GREETING_CONTRACT);
4828
+ writeFileEnsured((0, import_node_path18.join)(slice, "index.ts"), NODE_FUNCTION_APP_HELLO_BARREL);
4829
+ }
4830
+ writeFileEnsured((0, import_node_path18.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
4691
4831
  repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
4692
4832
  ensureAdmZip(workspaceRoot);
4693
- addNxTargets((0, import_node_path17.join)(nodeFunctionAppRoot, "package.json"), {
4833
+ addNxTargets((0, import_node_path18.join)(nodeFunctionAppRoot, "package.json"), {
4694
4834
  package: nodeFunctionAppPackageTarget(name),
4695
4835
  prune: nodeFunctionAppPruneTarget(name),
4696
4836
  start: nodeFunctionAppStartTarget(name),
@@ -4702,11 +4842,11 @@ function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
4702
4842
  }
4703
4843
 
4704
4844
  // src/project-scaffolding/npm-lib.use-case.ts
4705
- var import_node_path21 = require("path");
4845
+ var import_node_path22 = require("path");
4706
4846
 
4707
4847
  // src/rollup-library/repair-publishable-manifest.use-case.ts
4708
- var import_node_fs17 = require("fs");
4709
- var import_node_path18 = require("path");
4848
+ var import_node_fs19 = require("fs");
4849
+ var import_node_path19 = require("path");
4710
4850
  var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
4711
4851
  var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
4712
4852
  var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
@@ -4729,14 +4869,14 @@ function repairPublishableManifest(manifestPath) {
4729
4869
  }
4730
4870
  function repairPublishableManifests(workspaceRoot) {
4731
4871
  const changed = [];
4732
- const manifests = (0, import_node_fs17.globSync)(["packages/*/package.json", "libs/*/package.json"], {
4872
+ const manifests = (0, import_node_fs19.globSync)(["packages/*/package.json", "libs/*/package.json"], {
4733
4873
  cwd: workspaceRoot
4734
4874
  });
4735
4875
  for (const relativePath of manifests) {
4736
- const manifestPath = (0, import_node_path18.join)(workspaceRoot, relativePath);
4737
- const before = (0, import_node_fs17.readFileSync)(manifestPath, "utf8");
4876
+ const manifestPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
4877
+ const before = (0, import_node_fs19.readFileSync)(manifestPath, "utf8");
4738
4878
  repairPublishableManifest(manifestPath);
4739
- const after = (0, import_node_fs17.readFileSync)(manifestPath, "utf8");
4879
+ const after = (0, import_node_fs19.readFileSync)(manifestPath, "utf8");
4740
4880
  if (after !== before) {
4741
4881
  changed.push(relativePath.replaceAll("\\", "/"));
4742
4882
  }
@@ -4745,8 +4885,8 @@ function repairPublishableManifests(workspaceRoot) {
4745
4885
  }
4746
4886
 
4747
4887
  // src/rollup-library/repair-rollup-config.use-case.ts
4748
- var import_node_fs18 = require("fs");
4749
- var import_node_path19 = require("path");
4888
+ var import_node_fs20 = require("fs");
4889
+ var import_node_path20 = require("path");
4750
4890
 
4751
4891
  // src/rollup-library/rollup-config.algorithm.ts
4752
4892
  var ROLLUP_CONFIG_PLACEHOLDER = [
@@ -4948,12 +5088,12 @@ function withUpgradedDeclarationSpecifierPlugin(config) {
4948
5088
  // src/rollup-library/repair-rollup-config.use-case.ts
4949
5089
  function repairRollupSourceMaps(workspaceRoot) {
4950
5090
  const changed = [];
4951
- const configs = (0, import_node_fs18.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5091
+ const configs = (0, import_node_fs20.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
4952
5092
  cwd: workspaceRoot
4953
5093
  });
4954
5094
  for (const relativePath of configs) {
4955
- const configPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
4956
- const before = (0, import_node_fs18.readFileSync)(configPath, "utf8");
5095
+ const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5096
+ const before = (0, import_node_fs20.readFileSync)(configPath, "utf8");
4957
5097
  const after = withRollupSourceMaps(before);
4958
5098
  if (after !== before) {
4959
5099
  writeFileEnsured(configPath, after);
@@ -4964,12 +5104,12 @@ function repairRollupSourceMaps(workspaceRoot) {
4964
5104
  }
4965
5105
  function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
4966
5106
  const changed = [];
4967
- const configs = (0, import_node_fs18.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5107
+ const configs = (0, import_node_fs20.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
4968
5108
  cwd: workspaceRoot
4969
5109
  });
4970
5110
  for (const relativePath of configs) {
4971
- const configPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
4972
- const before = (0, import_node_fs18.readFileSync)(configPath, "utf8");
5111
+ const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5112
+ const before = (0, import_node_fs20.readFileSync)(configPath, "utf8");
4973
5113
  const after = withUpgradedDeclarationSpecifierPlugin(before);
4974
5114
  if (after !== before) {
4975
5115
  writeFileEnsured(configPath, after);
@@ -4979,11 +5119,11 @@ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
4979
5119
  return changed;
4980
5120
  }
4981
5121
  function repairDeclarationSpecifiers(projectRoot) {
4982
- const configPath = (0, import_node_path19.join)(projectRoot, "rollup.config.cjs");
5122
+ const configPath = (0, import_node_path20.join)(projectRoot, "rollup.config.cjs");
4983
5123
  if (!fileExists(configPath)) {
4984
5124
  return;
4985
5125
  }
4986
- const config = (0, import_node_fs18.readFileSync)(configPath, "utf8");
5126
+ const config = (0, import_node_fs20.readFileSync)(configPath, "utf8");
4987
5127
  if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
4988
5128
  return;
4989
5129
  }
@@ -4992,10 +5132,10 @@ function repairDeclarationSpecifiers(projectRoot) {
4992
5132
  }
4993
5133
 
4994
5134
  // src/rollup-library/rollup-config.repository.ts
4995
- var import_node_fs19 = require("fs");
4996
- var import_node_path20 = require("path");
5135
+ var import_node_fs21 = require("fs");
5136
+ var import_node_path21 = require("path");
4997
5137
  function resolveRequireTarget(fromDir, specifier) {
4998
- const base = (0, import_node_path20.join)(fromDir, specifier);
5138
+ const base = (0, import_node_path21.join)(fromDir, specifier);
4999
5139
  return [base, `${base}.cjs`, `${base}.js`].find((candidate) => fileExists(candidate));
5000
5140
  }
5001
5141
  function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()) {
@@ -5005,7 +5145,7 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
5005
5145
  visited.add(configPath);
5006
5146
  let text;
5007
5147
  try {
5008
- text = (0, import_node_fs19.readFileSync)(configPath, "utf8");
5148
+ text = (0, import_node_fs21.readFileSync)(configPath, "utf8");
5009
5149
  } catch {
5010
5150
  return "";
5011
5151
  }
@@ -5013,15 +5153,15 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
5013
5153
  text.matchAll(/require\((['"])(\.[^'"]*)\1\)/g),
5014
5154
  (match) => match[2]
5015
5155
  );
5016
- const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path20.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5156
+ const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path21.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5017
5157
  return [text, ...requiredText].join("\n");
5018
5158
  }
5019
5159
 
5020
5160
  // src/project-scaffolding/npm-lib.use-case.ts
5021
5161
  async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
5022
5162
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5023
- const projectRoot = (0, import_node_path21.join)(workspaceRoot, "packages", name);
5024
- const manifestPath = (0, import_node_path21.join)(projectRoot, "package.json");
5163
+ const projectRoot = (0, import_node_path22.join)(workspaceRoot, "packages", name);
5164
+ const manifestPath = (0, import_node_path22.join)(projectRoot, "package.json");
5025
5165
  runGeneratorAndRepair(
5026
5166
  workspaceRoot,
5027
5167
  [
@@ -5050,8 +5190,8 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
5050
5190
  }
5051
5191
 
5052
5192
  // src/project-scaffolding/python.use-case.ts
5053
- var import_node_fs20 = require("fs");
5054
- var import_node_path22 = require("path");
5193
+ var import_node_fs22 = require("fs");
5194
+ var import_node_path23 = require("path");
5055
5195
  function ensurePython(workspaceRoot) {
5056
5196
  const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
5057
5197
  if (!hasPython) {
@@ -5074,7 +5214,7 @@ function ensurePythonPipPlugin(workspaceRoot) {
5074
5214
  registerPythonGraphPlugin(workspaceRoot);
5075
5215
  }
5076
5216
  function registerPythonGraphPlugin(workspaceRoot) {
5077
- const nxJsonPath = (0, import_node_path22.join)(workspaceRoot, "nx.json");
5217
+ const nxJsonPath = (0, import_node_path23.join)(workspaceRoot, "nx.json");
5078
5218
  if (!fileExists(nxJsonPath)) {
5079
5219
  return;
5080
5220
  }
@@ -5097,7 +5237,7 @@ pytest
5097
5237
  pip-audit
5098
5238
  `;
5099
5239
  function ensureRequirementsDev(workspaceRoot) {
5100
- const requirementsDevPath = (0, import_node_path22.join)(workspaceRoot, "requirements-dev.txt");
5240
+ const requirementsDevPath = (0, import_node_path23.join)(workspaceRoot, "requirements-dev.txt");
5101
5241
  if (!fileExists(requirementsDevPath)) {
5102
5242
  writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
5103
5243
  }
@@ -5157,8 +5297,8 @@ function addPythonApp(workspaceRoot, name) {
5157
5297
  ["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
5158
5298
  workspaceRoot
5159
5299
  );
5160
- writeFileEnsured((0, import_node_path22.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5161
- addProjectJsonTargets((0, import_node_path22.join)(workspaceRoot, "apps", name, "project.json"), {
5300
+ writeFileEnsured((0, import_node_path23.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5301
+ addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5162
5302
  package: pythonAppPackageTarget(name),
5163
5303
  start: pythonAppStartTarget(name)
5164
5304
  });
@@ -5180,7 +5320,7 @@ function addPythonFunctionApp(workspaceRoot, name) {
5180
5320
  workspaceRoot
5181
5321
  );
5182
5322
  const moduleDirectory = pythonModuleDirectory(name);
5183
- addProjectJsonTargets((0, import_node_path22.join)(workspaceRoot, "apps", name, "project.json"), {
5323
+ addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5184
5324
  package: pythonFunctionAppPackageTarget(name, moduleDirectory),
5185
5325
  start: pythonFunctionAppStartTarget(name)
5186
5326
  });
@@ -5221,7 +5361,7 @@ function addPythonInternalLib(workspaceRoot, name) {
5221
5361
  var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
5222
5362
  function findPythonProjectDirectory(workspaceRoot, name) {
5223
5363
  return PYTHON_PROJECT_DIRS.find(
5224
- (directory) => fileExists((0, import_node_path22.join)(workspaceRoot, directory, name, "pyproject.toml"))
5364
+ (directory) => fileExists((0, import_node_path23.join)(workspaceRoot, directory, name, "pyproject.toml"))
5225
5365
  );
5226
5366
  }
5227
5367
  function parseVendorEntries(pyprojectToml) {
@@ -5260,7 +5400,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5260
5400
  `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.`
5261
5401
  );
5262
5402
  }
5263
- if (!fileExists((0, import_node_path22.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5403
+ if (!fileExists((0, import_node_path23.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5264
5404
  throw new Error(
5265
5405
  `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.`
5266
5406
  );
@@ -5268,8 +5408,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5268
5408
  if (consumerDirectory === "libs" && consumer === lib) {
5269
5409
  throw new Error(`'${consumer}' cannot vendor itself.`);
5270
5410
  }
5271
- const pyprojectPath = (0, import_node_path22.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5272
- const pyprojectToml = (0, import_node_fs20.readFileSync)(pyprojectPath, "utf8");
5411
+ const pyprojectPath = (0, import_node_path23.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5412
+ const pyprojectToml = (0, import_node_fs22.readFileSync)(pyprojectPath, "utf8");
5273
5413
  if (parseVendorEntries(pyprojectToml).includes(lib)) {
5274
5414
  logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
5275
5415
  return;
@@ -5281,8 +5421,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5281
5421
  }
5282
5422
 
5283
5423
  // src/project-scaffolding/react-app.use-case.ts
5284
- var import_node_fs21 = require("fs");
5285
- var import_node_path23 = require("path");
5424
+ var import_node_fs23 = require("fs");
5425
+ var import_node_path24 = require("path");
5286
5426
 
5287
5427
  // src/project-scaffolding/react-app-example.algorithm.ts
5288
5428
  function reactAppExampleFiles(name) {
@@ -5399,12 +5539,12 @@ function reactAppTargets(name) {
5399
5539
  return targets;
5400
5540
  }
5401
5541
  function allowEnvFiles(workspaceRoot) {
5402
- const gitignorePath = (0, import_node_path23.join)(workspaceRoot, ".gitignore");
5542
+ const gitignorePath = (0, import_node_path24.join)(workspaceRoot, ".gitignore");
5403
5543
  if (!fileExists(gitignorePath)) {
5404
5544
  return;
5405
5545
  }
5406
5546
  const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
5407
- const current = (0, import_node_fs21.readFileSync)(gitignorePath, "utf8");
5547
+ const current = (0, import_node_fs23.readFileSync)(gitignorePath, "utf8");
5408
5548
  if (current.includes(marker)) {
5409
5549
  return;
5410
5550
  }
@@ -5431,30 +5571,30 @@ function addReactApp(workspaceRoot, name, stack) {
5431
5571
  workspaceRoot
5432
5572
  );
5433
5573
  ensureAdmZip(workspaceRoot);
5434
- const reactAppRoot = (0, import_node_path23.join)(workspaceRoot, "apps", name);
5574
+ const reactAppRoot = (0, import_node_path24.join)(workspaceRoot, "apps", name);
5435
5575
  for (const environment of REACT_ENVIRONMENTS) {
5436
- writeFileEnsured((0, import_node_path23.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5576
+ writeFileEnsured((0, import_node_path24.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5437
5577
  }
5438
5578
  allowEnvFiles(workspaceRoot);
5439
- addNxTargets((0, import_node_path23.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5579
+ addNxTargets((0, import_node_path24.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5440
5580
  reshapeReactAppScaffold(reactAppRoot);
5441
- (0, import_node_fs21.rmSync)((0, import_node_path23.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5581
+ (0, import_node_fs23.rmSync)((0, import_node_path24.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5442
5582
  const example = reactAppExampleFiles(name);
5443
5583
  for (const [relative, contents] of Object.entries(example)) {
5444
- writeFileEnsured((0, import_node_path23.join)(reactAppRoot, "src", relative), contents);
5584
+ writeFileEnsured((0, import_node_path24.join)(reactAppRoot, "src", relative), contents);
5445
5585
  }
5446
5586
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
5447
5587
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
5448
5588
  }
5449
5589
 
5450
5590
  // src/project-scaffolding/react-lib.use-case.ts
5451
- var import_node_path24 = require("path");
5591
+ var import_node_path25 = require("path");
5452
5592
  var REACT_LIB_BUNDLER = "rollup";
5453
5593
  async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5454
5594
  ensurePlugin(workspaceRoot, "@nx/react");
5455
5595
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5456
- const projectRoot = (0, import_node_path24.join)(workspaceRoot, "packages", name);
5457
- const publishableManifest = (0, import_node_path24.join)(projectRoot, "package.json");
5596
+ const projectRoot = (0, import_node_path25.join)(workspaceRoot, "packages", name);
5597
+ const publishableManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5458
5598
  runGeneratorAndRepair(
5459
5599
  workspaceRoot,
5460
5600
  [
@@ -5484,8 +5624,8 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5484
5624
  }
5485
5625
  function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5486
5626
  ensurePlugin(workspaceRoot, "@nx/react");
5487
- const projectRoot = (0, import_node_path24.join)(workspaceRoot, "libs", name);
5488
- const privateManifest = (0, import_node_path24.join)(projectRoot, "package.json");
5627
+ const projectRoot = (0, import_node_path25.join)(workspaceRoot, "libs", name);
5628
+ const privateManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5489
5629
  runGeneratorAndRepair(
5490
5630
  workspaceRoot,
5491
5631
  [
@@ -5512,8 +5652,8 @@ function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5512
5652
  }
5513
5653
 
5514
5654
  // src/project-scaffolding/vscode-extension.use-case.ts
5515
- var import_node_fs22 = require("fs");
5516
- var import_node_path25 = require("path");
5655
+ var import_node_fs24 = require("fs");
5656
+ var import_node_path26 = require("path");
5517
5657
  var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
5518
5658
  var VSCODE_ENGINE_FLOOR = "1.96.0";
5519
5659
  var VSCODE_SIDECAR_TARGETS = {
@@ -5698,8 +5838,8 @@ export const window = {
5698
5838
  var VSCODE_STUB_PATH = "test/vscode.stub.ts";
5699
5839
  function mapVscodeToStub(projectRoot, testRunner) {
5700
5840
  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}\` },`];
5701
- const path = (0, import_node_path25.join)(projectRoot, file);
5702
- const content = fileExists(path) ? (0, import_node_fs22.readFileSync)(path, "utf8") : "";
5841
+ const path = (0, import_node_path26.join)(projectRoot, file);
5842
+ const content = fileExists(path) ? (0, import_node_fs24.readFileSync)(path, "utf8") : "";
5703
5843
  const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
5704
5844
  if (line === void 0) {
5705
5845
  throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
@@ -5719,11 +5859,11 @@ function ensureVscodeToolchain(workspaceRoot) {
5719
5859
  }
5720
5860
  }
5721
5861
  function defaultPublisher(workspaceRoot) {
5722
- const { name } = readJson((0, import_node_path25.join)(workspaceRoot, "package.json"));
5862
+ const { name } = readJson((0, import_node_path26.join)(workspaceRoot, "package.json"));
5723
5863
  return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
5724
5864
  }
5725
5865
  function reshapeManifest(projectRoot, name, publisher) {
5726
- const manifestPath = (0, import_node_path25.join)(projectRoot, "package.json");
5866
+ const manifestPath = (0, import_node_path26.join)(projectRoot, "package.json");
5727
5867
  const manifest = readJson(manifestPath);
5728
5868
  const { nx = {}, ...rest } = manifest;
5729
5869
  const targets = { ...nx.targets };
@@ -5787,11 +5927,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
5787
5927
  };
5788
5928
  }
5789
5929
  function addDebugLaunch(workspaceRoot, name) {
5790
- const file = (0, import_node_fs22.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
5930
+ const file = (0, import_node_fs24.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
5791
5931
  if (file === void 0) {
5792
5932
  return;
5793
5933
  }
5794
- const path = (0, import_node_path25.join)(workspaceRoot, file);
5934
+ const path = (0, import_node_path26.join)(workspaceRoot, file);
5795
5935
  const workspace = readCodeWorkspace(path) ?? {};
5796
5936
  const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
5797
5937
  const taskLabel = `${name}: build (development)`;
@@ -5824,39 +5964,39 @@ function addDebugLaunch(workspaceRoot, name) {
5824
5964
  );
5825
5965
  }
5826
5966
  function refreshVscodeExtensionScript(workspaceRoot) {
5827
- const apps = (0, import_node_path25.join)(workspaceRoot, "apps");
5967
+ const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
5828
5968
  let entries;
5829
5969
  try {
5830
- entries = (0, import_node_fs22.readdirSync)(apps);
5970
+ entries = (0, import_node_fs24.readdirSync)(apps);
5831
5971
  } catch {
5832
5972
  return false;
5833
5973
  }
5834
5974
  const hasExtension = entries.some((entry) => {
5835
- const manifestPath = (0, import_node_path25.join)(apps, entry, "package.json");
5975
+ const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
5836
5976
  if (!fileExists(manifestPath)) {
5837
5977
  return false;
5838
5978
  }
5839
5979
  const tags = readJson(manifestPath).nx?.tags ?? [];
5840
5980
  return tags.includes(VSCODE_EXTENSION_TAG);
5841
5981
  });
5842
- const path = (0, import_node_path25.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
5843
- if (!hasExtension || fileExists(path) && (0, import_node_fs22.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
5982
+ const path = (0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
5983
+ if (!hasExtension || fileExists(path) && (0, import_node_fs24.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
5844
5984
  return false;
5845
5985
  }
5846
5986
  writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
5847
5987
  return true;
5848
5988
  }
5849
5989
  function pinVscodeExtensionProjectNames(workspaceRoot) {
5850
- const apps = (0, import_node_path25.join)(workspaceRoot, "apps");
5990
+ const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
5851
5991
  let entries;
5852
5992
  try {
5853
- entries = (0, import_node_fs22.readdirSync)(apps);
5993
+ entries = (0, import_node_fs24.readdirSync)(apps);
5854
5994
  } catch {
5855
5995
  return [];
5856
5996
  }
5857
5997
  const updated = [];
5858
5998
  for (const entry of entries) {
5859
- const manifestPath = (0, import_node_path25.join)(apps, entry, "package.json");
5999
+ const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
5860
6000
  if (!fileExists(manifestPath)) {
5861
6001
  continue;
5862
6002
  }
@@ -5876,22 +6016,22 @@ function refreshLockFile(workspaceRoot, name) {
5876
6016
  }
5877
6017
  function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
5878
6018
  const { sidecar } = options;
5879
- if (sidecar !== void 0 && !fileExists((0, import_node_path25.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
6019
+ if (sidecar !== void 0 && !fileExists((0, import_node_path26.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
5880
6020
  throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
5881
6021
  }
5882
6022
  runNodeApp(workspaceRoot, name, stack, "none");
5883
6023
  ensureVscodeToolchain(workspaceRoot);
5884
- const projectRoot = (0, import_node_path25.join)(workspaceRoot, "apps", name);
6024
+ const projectRoot = (0, import_node_path26.join)(workspaceRoot, "apps", name);
5885
6025
  reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot));
5886
- addVscodeTypes((0, import_node_path25.join)(projectRoot, "tsconfig.app.json"));
5887
- addVscodeTypes((0, import_node_path25.join)(projectRoot, "tsconfig.spec.json"));
5888
- writeFileEnsured((0, import_node_path25.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
5889
- writeFileEnsured((0, import_node_path25.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
5890
- writeFileEnsured((0, import_node_path25.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
6026
+ addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.app.json"));
6027
+ addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.spec.json"));
6028
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
6029
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
6030
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
5891
6031
  mapVscodeToStub(projectRoot, stack.testRunner);
5892
- writeFileEnsured((0, import_node_path25.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
5893
- writeFileEnsured((0, import_node_path25.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
5894
- addNxTargets((0, import_node_path25.join)(projectRoot, "package.json"), {
6032
+ writeFileEnsured((0, import_node_path26.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
6033
+ writeFileEnsured((0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
6034
+ addNxTargets((0, import_node_path26.join)(projectRoot, "package.json"), {
5895
6035
  "package": vscodeExtensionPackageTarget(name, sidecar),
5896
6036
  "nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
5897
6037
  });
@@ -5902,12 +6042,12 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
5902
6042
  }
5903
6043
 
5904
6044
  // src/dependency-management/install-dependencies.use-case.ts
5905
- var import_node_fs24 = require("fs");
5906
- var import_node_path27 = require("path");
6045
+ var import_node_fs26 = require("fs");
6046
+ var import_node_path28 = require("path");
5907
6047
 
5908
6048
  // src/dependency-management/manifest.repository.ts
5909
- var import_node_fs23 = require("fs");
5910
- var import_node_path26 = require("path");
6049
+ var import_node_fs25 = require("fs");
6050
+ var import_node_path27 = require("path");
5911
6051
  var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
5912
6052
  var ROOT_LABEL = "(root)";
5913
6053
  var MANIFEST_GLOBS = {
@@ -5940,23 +6080,23 @@ function projectOf(manifestRelativePath) {
5940
6080
  }
5941
6081
  function hasEcosystem(workspaceRoot, ecosystem) {
5942
6082
  if (ecosystem === "go") {
5943
- return fileExists((0, import_node_path26.join)(workspaceRoot, "go.mod"));
6083
+ return fileExists((0, import_node_path27.join)(workspaceRoot, "go.mod"));
5944
6084
  }
5945
6085
  if (ecosystem === "nuget") {
5946
- return (0, import_node_fs23.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
6086
+ return (0, import_node_fs25.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
5947
6087
  }
5948
6088
  const rootMarker = {
5949
6089
  npm: "package.json",
5950
6090
  pip: "requirements-dev.txt",
5951
6091
  pub: "pubspec.yaml"
5952
6092
  };
5953
- return fileExists((0, import_node_path26.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs23.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
6093
+ return fileExists((0, import_node_path27.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs25.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
5954
6094
  }
5955
6095
  function collectNpm(workspaceRoot) {
5956
6096
  const sites = [];
5957
- const relativePaths = ["package.json", ...(0, import_node_fs23.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
6097
+ const relativePaths = ["package.json", ...(0, import_node_fs25.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
5958
6098
  for (const relativePath of relativePaths) {
5959
- const manifestPath = (0, import_node_path26.join)(workspaceRoot, relativePath);
6099
+ const manifestPath = (0, import_node_path27.join)(workspaceRoot, relativePath);
5960
6100
  try {
5961
6101
  const manifest = readJson(manifestPath);
5962
6102
  sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
@@ -6017,17 +6157,17 @@ function collectPip(workspaceRoot) {
6017
6157
  name: parsed.name,
6018
6158
  ecosystem: "pip",
6019
6159
  project: projectOf(relativePath),
6020
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath),
6160
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6021
6161
  section,
6022
6162
  spec: parsed.spec,
6023
6163
  rewritable: parsed.rewritable && parsed.spec !== ""
6024
6164
  });
6025
6165
  };
6026
- const pyprojectPaths = (0, import_node_fs23.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6166
+ const pyprojectPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6027
6167
  for (const relativePath of pyprojectPaths) {
6028
6168
  let content;
6029
6169
  try {
6030
- content = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8");
6170
+ content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6031
6171
  } catch {
6032
6172
  continue;
6033
6173
  }
@@ -6038,14 +6178,14 @@ function collectPip(workspaceRoot) {
6038
6178
  }
6039
6179
  const requirementsPaths = [
6040
6180
  "requirements-dev.txt",
6041
- ...(0, import_node_fs23.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6181
+ ...(0, import_node_fs25.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6042
6182
  ];
6043
6183
  for (const relativePath of requirementsPaths) {
6044
- if (!fileExists((0, import_node_path26.join)(workspaceRoot, relativePath))) {
6184
+ if (!fileExists((0, import_node_path27.join)(workspaceRoot, relativePath))) {
6045
6185
  continue;
6046
6186
  }
6047
6187
  const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
6048
- const lines = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6188
+ const lines = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6049
6189
  for (const line of lines) {
6050
6190
  push(relativePath, section, line);
6051
6191
  }
@@ -6083,11 +6223,11 @@ function pyprojectDependencies(content) {
6083
6223
  }
6084
6224
  function collectPub(workspaceRoot) {
6085
6225
  const sites = [];
6086
- const pubspecPaths = (0, import_node_fs23.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6226
+ const pubspecPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6087
6227
  for (const relativePath of pubspecPaths) {
6088
6228
  let content;
6089
6229
  try {
6090
- content = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8");
6230
+ content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6091
6231
  } catch {
6092
6232
  continue;
6093
6233
  }
@@ -6097,7 +6237,7 @@ function collectPub(workspaceRoot) {
6097
6237
  name: entry.name,
6098
6238
  ecosystem: "pub",
6099
6239
  project: projectOf(relativePath),
6100
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath),
6240
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6101
6241
  section: block === "dependencies" ? "dep" : "devDep",
6102
6242
  spec: entry.spec,
6103
6243
  rewritable: entry.spec !== ""
@@ -6147,11 +6287,11 @@ function stripQuotes(value) {
6147
6287
  }
6148
6288
  function collectNuget(workspaceRoot) {
6149
6289
  const sites = [];
6150
- const csprojPaths = (0, import_node_fs23.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6290
+ const csprojPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6151
6291
  for (const relativePath of csprojPaths) {
6152
6292
  let content;
6153
6293
  try {
6154
- content = (0, import_node_fs23.readFileSync)((0, import_node_path26.join)(workspaceRoot, relativePath), "utf8");
6294
+ content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6155
6295
  } catch {
6156
6296
  continue;
6157
6297
  }
@@ -6160,7 +6300,7 @@ function collectNuget(workspaceRoot) {
6160
6300
  name: entry.name,
6161
6301
  ecosystem: "nuget",
6162
6302
  project: projectOf(relativePath),
6163
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath),
6303
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6164
6304
  section: "dep",
6165
6305
  spec: entry.spec,
6166
6306
  // A plain SemVer string is rewritable; an MSBuild property reference
@@ -6185,13 +6325,13 @@ function csprojPackageReferences(content) {
6185
6325
  return entries;
6186
6326
  }
6187
6327
  function collectGo(workspaceRoot) {
6188
- const manifestPath = (0, import_node_path26.join)(workspaceRoot, "go.mod");
6328
+ const manifestPath = (0, import_node_path27.join)(workspaceRoot, "go.mod");
6189
6329
  if (!fileExists(manifestPath)) {
6190
6330
  return [];
6191
6331
  }
6192
6332
  let content;
6193
6333
  try {
6194
- content = (0, import_node_fs23.readFileSync)(manifestPath, "utf8");
6334
+ content = (0, import_node_fs25.readFileSync)(manifestPath, "utf8");
6195
6335
  } catch {
6196
6336
  return [];
6197
6337
  }
@@ -6240,7 +6380,7 @@ var PROJECT_GLOBS = {
6240
6380
  function locateProjects(workspaceRoot) {
6241
6381
  const locations = [];
6242
6382
  for (const ecosystem of ECOSYSTEMS) {
6243
- const relativePaths = (0, import_node_fs23.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6383
+ const relativePaths = (0, import_node_fs25.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6244
6384
  for (const relativePath of relativePaths) {
6245
6385
  const posix = toPosix(relativePath);
6246
6386
  const dir = posix.slice(0, posix.lastIndexOf("/"));
@@ -6248,7 +6388,7 @@ function locateProjects(workspaceRoot) {
6248
6388
  ecosystem,
6249
6389
  dir,
6250
6390
  name: dir.slice(dir.lastIndexOf("/") + 1),
6251
- manifestPath: (0, import_node_path26.join)(workspaceRoot, relativePath)
6391
+ manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath)
6252
6392
  });
6253
6393
  }
6254
6394
  }
@@ -6269,7 +6409,7 @@ function rewriteSpec(site, spec) {
6269
6409
  writeFileEnsured(site.manifestPath, toJson(manifest));
6270
6410
  return true;
6271
6411
  }
6272
- const before = (0, import_node_fs23.readFileSync)(site.manifestPath, "utf8");
6412
+ const before = (0, import_node_fs25.readFileSync)(site.manifestPath, "utf8");
6273
6413
  const after = (() => {
6274
6414
  switch (site.ecosystem) {
6275
6415
  case "pip": {
@@ -6360,13 +6500,13 @@ function escapeForRegex(value) {
6360
6500
  function isWorkspaceProject(workspaceRoot, name) {
6361
6501
  const short = name.includes("/") ? name.split("/").at(-1) : name;
6362
6502
  return ["apps", "libs", "packages"].some(
6363
- (directory) => fileExists((0, import_node_path26.join)(workspaceRoot, directory, short ?? name, "package.json"))
6503
+ (directory) => fileExists((0, import_node_path27.join)(workspaceRoot, directory, short ?? name, "package.json"))
6364
6504
  );
6365
6505
  }
6366
6506
  function isAliasedInstall(workspaceRoot, name) {
6367
6507
  try {
6368
6508
  const installed = readJson(
6369
- (0, import_node_path26.join)(workspaceRoot, "node_modules", name, "package.json")
6509
+ (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6370
6510
  );
6371
6511
  return installed.name !== void 0 && installed.name !== name;
6372
6512
  } catch {
@@ -6377,14 +6517,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6377
6517
  if (ecosystem === "npm") {
6378
6518
  try {
6379
6519
  return readJson(
6380
- (0, import_node_path26.join)(workspaceRoot, "node_modules", name, "package.json")
6520
+ (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6381
6521
  ).version;
6382
6522
  } catch {
6383
6523
  return void 0;
6384
6524
  }
6385
6525
  }
6386
6526
  if (ecosystem === "pub") {
6387
- const lockPath = (0, import_node_path26.join)(workspaceRoot, "pubspec.lock");
6527
+ const lockPath = (0, import_node_path27.join)(workspaceRoot, "pubspec.lock");
6388
6528
  if (!fileExists(lockPath)) {
6389
6529
  return void 0;
6390
6530
  }
@@ -6392,7 +6532,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6392
6532
  const match = new RegExp(
6393
6533
  String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
6394
6534
  "m"
6395
- ).exec((0, import_node_fs23.readFileSync)(lockPath, "utf8"));
6535
+ ).exec((0, import_node_fs25.readFileSync)(lockPath, "utf8"));
6396
6536
  return match?.[1];
6397
6537
  } catch {
6398
6538
  return void 0;
@@ -6458,7 +6598,7 @@ function resolveTarget(locations, target) {
6458
6598
  return byName[0];
6459
6599
  }
6460
6600
  function installInto(workspaceRoot, location, packages, saveDev) {
6461
- const projectDir = (0, import_node_path27.join)(workspaceRoot, location.dir);
6601
+ const projectDir = (0, import_node_path28.join)(workspaceRoot, location.dir);
6462
6602
  switch (location.ecosystem) {
6463
6603
  case "npm": {
6464
6604
  const flags = saveDev ? ["--save-dev"] : [];
@@ -6511,7 +6651,7 @@ function installInto(workspaceRoot, location, packages, saveDev) {
6511
6651
  function addPythonDependency(manifestPath, specifier) {
6512
6652
  let content;
6513
6653
  try {
6514
- content = (0, import_node_fs24.readFileSync)(manifestPath, "utf8");
6654
+ content = (0, import_node_fs26.readFileSync)(manifestPath, "utf8");
6515
6655
  } catch {
6516
6656
  logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
6517
6657
  return;
@@ -6540,7 +6680,7 @@ function installEverything(workspaceRoot, only) {
6540
6680
  }
6541
6681
  function ecosystemPresent(workspaceRoot, ecosystem) {
6542
6682
  if (ecosystem === "go") {
6543
- return fileExists((0, import_node_path27.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path27.join)(workspaceRoot, "go.mod"));
6683
+ return fileExists((0, import_node_path28.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path28.join)(workspaceRoot, "go.mod"));
6544
6684
  }
6545
6685
  return hasEcosystem(workspaceRoot, ecosystem);
6546
6686
  }
@@ -6559,7 +6699,7 @@ function splitAtLast(value, separator) {
6559
6699
  }
6560
6700
 
6561
6701
  // src/dependency-management/sync-dependencies.use-case.ts
6562
- var import_node_path28 = require("path");
6702
+ var import_node_path29 = require("path");
6563
6703
 
6564
6704
  // src/dependency-management/semver.algorithm.ts
6565
6705
  var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
@@ -6736,7 +6876,7 @@ function describe(finding) {
6736
6876
  return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
6737
6877
  }
6738
6878
  function runSync(workspaceRoot, options) {
6739
- if (!fileExists((0, import_node_path28.join)(workspaceRoot, "nx.json"))) {
6879
+ if (!fileExists((0, import_node_path29.join)(workspaceRoot, "nx.json"))) {
6740
6880
  throw new Error(
6741
6881
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
6742
6882
  );
@@ -6786,7 +6926,7 @@ function runSync(workspaceRoot, options) {
6786
6926
  }
6787
6927
 
6788
6928
  // src/dependency-management/update-dependencies.use-case.ts
6789
- var import_node_path29 = require("path");
6929
+ var import_node_path30 = require("path");
6790
6930
  var import_prompts2 = require("@inquirer/prompts");
6791
6931
 
6792
6932
  // src/dependency-management/registry.client.ts
@@ -7069,7 +7209,7 @@ function reinstall(workspaceRoot, ecosystems) {
7069
7209
  function hasPythonInstallScript(workspaceRoot) {
7070
7210
  try {
7071
7211
  const manifest = readJson(
7072
- (0, import_node_path29.join)(workspaceRoot, "package.json")
7212
+ (0, import_node_path30.join)(workspaceRoot, "package.json")
7073
7213
  );
7074
7214
  return manifest.scripts?.["python:install"] !== void 0;
7075
7215
  } catch {
@@ -7085,7 +7225,7 @@ function applyGoUpdates(workspaceRoot, entries) {
7085
7225
  }
7086
7226
  }
7087
7227
  async function runUp(workspaceRoot, options) {
7088
- if (!fileExists((0, import_node_path29.join)(workspaceRoot, "nx.json"))) {
7228
+ if (!fileExists((0, import_node_path30.join)(workspaceRoot, "nx.json"))) {
7089
7229
  throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
7090
7230
  }
7091
7231
  const ecosystems = resolveEcosystems(options.ecosystem);
@@ -7162,7 +7302,7 @@ var PROJECT_KINDS = [
7162
7302
  var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
7163
7303
  async function runAdd(kind, name, options) {
7164
7304
  const workspaceRoot = process.cwd();
7165
- if (!fileExists((0, import_node_path30.join)(workspaceRoot, "nx.json"))) {
7305
+ if (!fileExists((0, import_node_path31.join)(workspaceRoot, "nx.json"))) {
7166
7306
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
7167
7307
  }
7168
7308
  const stack = readWorkspaceStack(workspaceRoot);
@@ -7225,8 +7365,8 @@ async function runAdd(kind, name, options) {
7225
7365
  ],
7226
7366
  workspaceRoot
7227
7367
  );
7228
- markPrivate((0, import_node_path30.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7229
- renameScaffoldPlaceholder((0, import_node_path30.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7368
+ markPrivate((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7369
+ renameScaffoldPlaceholder((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7230
7370
  removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
7231
7371
  registerProjectCommands(workspaceRoot, resolvedName, { build: true });
7232
7372
  break;
@@ -7318,7 +7458,7 @@ async function runAdd(kind, name, options) {
7318
7458
  }
7319
7459
  function readWorkspaceStack(workspaceRoot) {
7320
7460
  const nxJson = readJson(
7321
- (0, import_node_path30.join)(workspaceRoot, "nx.json")
7461
+ (0, import_node_path31.join)(workspaceRoot, "nx.json")
7322
7462
  );
7323
7463
  const stack = nxJson.mnci?.stack;
7324
7464
  return {
@@ -7367,15 +7507,15 @@ function runKinds(options) {
7367
7507
 
7368
7508
  // src/workspace-diagnostics/check-invariants.use-case.ts
7369
7509
  var import_node_child_process = require("child_process");
7370
- var import_node_fs25 = require("fs");
7371
- var import_node_path31 = require("path");
7510
+ var import_node_fs27 = require("fs");
7511
+ var import_node_path32 = require("path");
7372
7512
  var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
7373
7513
  function toPosix2(path) {
7374
7514
  return path.replaceAll("\\", "/");
7375
7515
  }
7376
7516
  function checkEslintConfigs(workspaceRoot) {
7377
- const rootConfigs = (0, import_node_fs25.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7378
- const projectConfigs = (0, import_node_fs25.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7517
+ const rootConfigs = (0, import_node_fs27.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7518
+ const projectConfigs = (0, import_node_fs27.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7379
7519
  cwd: workspaceRoot
7380
7520
  }).map((config) => toPosix2(config));
7381
7521
  return [
@@ -7395,10 +7535,10 @@ function checkEslintConfigs(workspaceRoot) {
7395
7535
  ];
7396
7536
  }
7397
7537
  function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7398
- const rules = (0, import_node_path31.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7399
- if (!(0, import_node_fs25.existsSync)(rules)) return [];
7400
- const entryPoint = (0, import_node_path31.join)(workspaceRoot, ESLINT_USER_FILENAME);
7401
- const source = (0, import_node_fs25.existsSync)(entryPoint) ? (0, import_node_fs25.readFileSync)(entryPoint, "utf8") : "";
7538
+ const rules = (0, import_node_path32.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7539
+ if (!(0, import_node_fs27.existsSync)(rules)) return [];
7540
+ const entryPoint = (0, import_node_path32.join)(workspaceRoot, ESLINT_USER_FILENAME);
7541
+ const source = (0, import_node_fs27.existsSync)(entryPoint) ? (0, import_node_fs27.readFileSync)(entryPoint, "utf8") : "";
7402
7542
  return [
7403
7543
  {
7404
7544
  check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
@@ -7411,7 +7551,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7411
7551
  function declaredDevDependencies(workspaceRoot) {
7412
7552
  try {
7413
7553
  const manifest = readJson(
7414
- (0, import_node_path31.join)(workspaceRoot, "package.json")
7554
+ (0, import_node_path32.join)(workspaceRoot, "package.json")
7415
7555
  );
7416
7556
  return manifest.devDependencies ?? {};
7417
7557
  } catch {
@@ -7419,7 +7559,7 @@ function declaredDevDependencies(workspaceRoot) {
7419
7559
  }
7420
7560
  }
7421
7561
  function checkNoRetiredFormatter(workspaceRoot) {
7422
- const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path31.join)(workspaceRoot, file)));
7562
+ const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file)));
7423
7563
  const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
7424
7564
  const stale = [...files, ...declared];
7425
7565
  if (stale.length === 0) {
@@ -7445,7 +7585,7 @@ function checkEslintPlugin(nxJson) {
7445
7585
  };
7446
7586
  }
7447
7587
  function checkResolvedEslint(workspaceRoot) {
7448
- const manifestPath = (0, import_node_path31.join)(workspaceRoot, "node_modules/eslint/package.json");
7588
+ const manifestPath = (0, import_node_path32.join)(workspaceRoot, "node_modules/eslint/package.json");
7449
7589
  if (!fileExists(manifestPath)) {
7450
7590
  return void 0;
7451
7591
  }
@@ -7463,11 +7603,11 @@ function checkResolvedEslint(workspaceRoot) {
7463
7603
  }
7464
7604
  }
7465
7605
  function checkNpmrc(workspaceRoot, registry, scope) {
7466
- const npmrcPath = (0, import_node_path31.join)(workspaceRoot, ".npmrc");
7606
+ const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7467
7607
  if (!registry || !fileExists(npmrcPath)) {
7468
7608
  return void 0;
7469
7609
  }
7470
- const npmrc = (0, import_node_fs25.readFileSync)(npmrcPath, "utf8");
7610
+ const npmrc = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8");
7471
7611
  if (registry.kind === "npm") {
7472
7612
  return {
7473
7613
  check: ".npmrc authenticates the public registry",
@@ -7484,11 +7624,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
7484
7624
  };
7485
7625
  }
7486
7626
  function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
7487
- const npmrcPath = (0, import_node_path31.join)(workspaceRoot, ".npmrc");
7627
+ const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7488
7628
  if (!fileExists(npmrcPath)) {
7489
7629
  return void 0;
7490
7630
  }
7491
- const npmrc = (0, import_node_fs25.readFileSync)(npmrcPath, "utf8");
7631
+ const npmrc = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8");
7492
7632
  const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7493
7633
  const referenced = [
7494
7634
  ...new Set(
@@ -7512,13 +7652,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
7512
7652
  };
7513
7653
  }
7514
7654
  function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
7515
- const npmrcPath = (0, import_node_path31.join)(workspaceRoot, ".npmrc");
7516
- const pipelinePath = (0, import_node_path31.join)(workspaceRoot, "azure-pipelines.yml");
7655
+ const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7656
+ const pipelinePath = (0, import_node_path32.join)(workspaceRoot, "azure-pipelines.yml");
7517
7657
  if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
7518
7658
  return void 0;
7519
7659
  }
7520
- 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));
7521
- const runsTask = (0, import_node_fs25.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7660
+ const holdsCredentials = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7661
+ const runsTask = (0, import_node_fs27.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7522
7662
  if (!holdsCredentials && !runsTask) {
7523
7663
  return {
7524
7664
  check: "npm auth: .npmrc and azure-pipelines.yml agree",
@@ -7563,13 +7703,13 @@ function npmjsCredentialShape(credentials, environment) {
7563
7703
  }
7564
7704
  function checkVersionActions(workspaceRoot) {
7565
7705
  const candidates = [
7566
- ...(0, import_node_fs25.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
7567
- ...(0, import_node_fs25.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
7568
- ...(0, import_node_fs25.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
7706
+ ...(0, import_node_fs27.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
7707
+ ...(0, import_node_fs27.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
7708
+ ...(0, import_node_fs27.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
7569
7709
  ].map((manifest) => toPosix2(manifest));
7570
7710
  return candidates.flatMap((manifest) => {
7571
7711
  const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
7572
- const projectJsonPath = (0, import_node_path31.join)(workspaceRoot, projectRoot, "project.json");
7712
+ const projectJsonPath = (0, import_node_path32.join)(workspaceRoot, projectRoot, "project.json");
7573
7713
  let hasOverride = false;
7574
7714
  try {
7575
7715
  const projectJson = readJson(projectJsonPath);
@@ -7598,7 +7738,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
7598
7738
  ]) {
7599
7739
  try {
7600
7740
  const targets = extract(
7601
- readJson((0, import_node_path31.join)(workspaceRoot, projectRoot, file))
7741
+ readJson((0, import_node_path32.join)(workspaceRoot, projectRoot, file))
7602
7742
  );
7603
7743
  if (targets && typeof targets === "object") {
7604
7744
  sources.push({
@@ -7614,8 +7754,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
7614
7754
  function checkTargetFilesExist(workspaceRoot) {
7615
7755
  const projectRoots = new Set(
7616
7756
  [
7617
- ...(0, import_node_fs25.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
7618
- ...(0, import_node_fs25.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
7757
+ ...(0, import_node_fs27.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
7758
+ ...(0, import_node_fs27.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
7619
7759
  ].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
7620
7760
  );
7621
7761
  return [...projectRoots].flatMap(
@@ -7630,7 +7770,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
7630
7770
  return TARGET_FILE_OPTIONS.flatMap((option) => {
7631
7771
  const value = target?.options?.[option];
7632
7772
  const checkable = typeof value === "string" && !value.includes("{");
7633
- if (!checkable || fileExists((0, import_node_path31.join)(workspaceRoot, value))) {
7773
+ if (!checkable || fileExists((0, import_node_path32.join)(workspaceRoot, value))) {
7634
7774
  return [];
7635
7775
  }
7636
7776
  return [
@@ -7669,15 +7809,15 @@ function checkGoPluginRegistered(workspaceRoot) {
7669
7809
  };
7670
7810
  }
7671
7811
  function checkGoWorkInSync(workspaceRoot) {
7672
- const goWorkPath = (0, import_node_path31.join)(workspaceRoot, "go.work");
7812
+ const goWorkPath = (0, import_node_path32.join)(workspaceRoot, "go.work");
7673
7813
  if (!fileExists(goWorkPath)) {
7674
7814
  return void 0;
7675
7815
  }
7676
- const contents = (0, import_node_fs25.existsSync)(goWorkPath) ? (0, import_node_fs25.readFileSync)(goWorkPath, "utf8") : "";
7816
+ const contents = (0, import_node_fs27.existsSync)(goWorkPath) ? (0, import_node_fs27.readFileSync)(goWorkPath, "utf8") : "";
7677
7817
  const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
7678
7818
  const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
7679
7819
  const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
7680
- const stale = uses.filter((entry) => !(0, import_node_fs25.existsSync)((0, import_node_path31.join)(workspaceRoot, entry, "go.mod")));
7820
+ const stale = uses.filter((entry) => !(0, import_node_fs27.existsSync)((0, import_node_path32.join)(workspaceRoot, entry, "go.mod")));
7681
7821
  return {
7682
7822
  check: "every go.work `use` entry points to a module that still exists",
7683
7823
  ok: stale.length === 0,
@@ -7693,9 +7833,9 @@ function checkNativeApps(workspaceRoot) {
7693
7833
  { file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
7694
7834
  { file: "azure-pipelines.yml", marker: "- job: native" }
7695
7835
  ];
7696
- const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path31.join)(workspaceRoot, file))).map(({ file, marker }) => ({
7836
+ const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).map(({ file, marker }) => ({
7697
7837
  check: `${file} builds the native apps on every OS`,
7698
- ok: (0, import_node_fs25.readFileSync)((0, import_node_path31.join)(workspaceRoot, file), "utf8").includes(marker),
7838
+ ok: (0, import_node_fs27.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8").includes(marker),
7699
7839
  detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
7700
7840
  remedy: "run `mnci upgrade`"
7701
7841
  }));
@@ -7708,7 +7848,7 @@ function checkNativeApps(workspaceRoot) {
7708
7848
  return findings;
7709
7849
  }
7710
7850
  function checkNoRootRuntimeDependencies(workspaceRoot) {
7711
- const manifestPath = (0, import_node_path31.join)(workspaceRoot, "package.json");
7851
+ const manifestPath = (0, import_node_path32.join)(workspaceRoot, "package.json");
7712
7852
  if (!fileExists(manifestPath)) {
7713
7853
  return void 0;
7714
7854
  }
@@ -7728,14 +7868,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
7728
7868
  };
7729
7869
  }
7730
7870
  function checkRollupSourceMaps(workspaceRoot) {
7731
- const configs = (0, import_node_fs25.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7871
+ const configs = (0, import_node_fs27.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7732
7872
  cwd: workspaceRoot
7733
7873
  }).map((config) => toPosix2(config));
7734
7874
  return configs.flatMap((relativePath) => {
7735
- const configPath = (0, import_node_path31.join)(workspaceRoot, relativePath);
7875
+ const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
7736
7876
  let config;
7737
7877
  try {
7738
- config = (0, import_node_fs25.readFileSync)(configPath, "utf8");
7878
+ config = (0, import_node_fs27.readFileSync)(configPath, "utf8");
7739
7879
  } catch {
7740
7880
  return [];
7741
7881
  }
@@ -7750,11 +7890,11 @@ function checkRollupSourceMaps(workspaceRoot) {
7750
7890
  });
7751
7891
  }
7752
7892
  function checkDeclarationSpecifiers(workspaceRoot) {
7753
- const configs = (0, import_node_fs25.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7893
+ const configs = (0, import_node_fs27.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
7754
7894
  cwd: workspaceRoot
7755
7895
  }).map((config) => toPosix2(config));
7756
7896
  return configs.flatMap((relativePath) => {
7757
- const configPath = (0, import_node_path31.join)(workspaceRoot, relativePath);
7897
+ const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
7758
7898
  if (!fileExists(configPath)) {
7759
7899
  return [];
7760
7900
  }
@@ -7789,8 +7929,8 @@ function checkDeclarationSpecifiers(workspaceRoot) {
7789
7929
  }
7790
7930
  function checkPipelinePhases(workspaceRoot) {
7791
7931
  const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
7792
- return files.filter((file) => fileExists((0, import_node_path31.join)(workspaceRoot, file))).flatMap((file) => {
7793
- const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs25.readFileSync)((0, import_node_path31.join)(workspaceRoot, file), "utf8"));
7932
+ return files.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).flatMap((file) => {
7933
+ const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs27.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8"));
7794
7934
  const verify = {
7795
7935
  check: `${file} runs the enforced verify phase`,
7796
7936
  ok: verifyActive,
@@ -7807,8 +7947,20 @@ function checkPipelinePhases(workspaceRoot) {
7807
7947
  return [verify, ...warnings];
7808
7948
  });
7809
7949
  }
7950
+ function checkNativeBuildConfig(workspaceRoot) {
7951
+ const { problems } = readNativeBuildConfig(workspaceRoot);
7952
+ if (problems.length === 0) {
7953
+ return [];
7954
+ }
7955
+ return [{
7956
+ check: "mnci.native in nx.json is valid",
7957
+ ok: false,
7958
+ detail: problems.join("; "),
7959
+ remedy: "fix the entry in the mnci block of nx.json, then run `mnci upgrade`"
7960
+ }];
7961
+ }
7810
7962
  function collectFindings(workspaceRoot) {
7811
- const nxJsonPath = (0, import_node_path31.join)(workspaceRoot, "nx.json");
7963
+ const nxJsonPath = (0, import_node_path32.join)(workspaceRoot, "nx.json");
7812
7964
  if (!fileExists(nxJsonPath)) {
7813
7965
  throw new Error(
7814
7966
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
@@ -7832,7 +7984,8 @@ function collectFindings(workspaceRoot) {
7832
7984
  checkGoPluginRegistered(workspaceRoot),
7833
7985
  checkGoWorkInSync(workspaceRoot),
7834
7986
  ...checkNativeApps(workspaceRoot),
7835
- ...checkPipelinePhases(workspaceRoot)
7987
+ ...checkPipelinePhases(workspaceRoot),
7988
+ ...checkNativeBuildConfig(workspaceRoot)
7836
7989
  ].filter((finding) => finding !== void 0);
7837
7990
  }
7838
7991
  function runDoctor(workspaceRoot, options = {}) {
@@ -7938,11 +8091,11 @@ function runCommands(program, options) {
7938
8091
  }
7939
8092
 
7940
8093
  // src/workspace-info/list-projects.use-case.ts
7941
- var import_node_path32 = require("path");
8094
+ var import_node_path33 = require("path");
7942
8095
  var TYPE_TAG_PREFIX = "type:";
7943
8096
  function listProjects(workspaceRoot) {
7944
8097
  return locateProjects(workspaceRoot).map((location) => {
7945
- const projectJsonPath = (0, import_node_path32.join)(workspaceRoot, location.dir, "project.json");
8098
+ const projectJsonPath = (0, import_node_path33.join)(workspaceRoot, location.dir, "project.json");
7946
8099
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
7947
8100
  const typeTag = (project.tags ?? []).find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
7948
8101
  return {
@@ -7955,7 +8108,7 @@ function listProjects(workspaceRoot) {
7955
8108
  }).toSorted((a, b) => a.dir.localeCompare(b.dir));
7956
8109
  }
7957
8110
  function runProjects(workspaceRoot, options) {
7958
- if (!fileExists((0, import_node_path32.join)(workspaceRoot, "nx.json"))) {
8111
+ if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
7959
8112
  throw new Error("No nx.json found here. Run `projects` from the workspace root.");
7960
8113
  }
7961
8114
  const projects = listProjects(workspaceRoot);
@@ -7969,13 +8122,13 @@ function runProjects(workspaceRoot, options) {
7969
8122
  }
7970
8123
 
7971
8124
  // src/workspace-info/read-workspace-info.use-case.ts
7972
- var import_node_path34 = require("path");
8125
+ var import_node_path35 = require("path");
7973
8126
 
7974
8127
  // src/cli-version/check-for-update.use-case.ts
7975
- var import_node_fs26 = require("fs");
7976
- var import_node_path33 = require("path");
8128
+ var import_node_fs28 = require("fs");
8129
+ var import_node_path34 = require("path");
7977
8130
  var import_cross_spawn3 = __toESM(require("cross-spawn"));
7978
- var PACKAGE_NAME = "@mnci/cli";
8131
+ var PACKAGE_NAME2 = "@mnci/cli";
7979
8132
  var REGISTRY_TIMEOUT_MS = 2e3;
7980
8133
  function checkForUpdate(currentVersion2) {
7981
8134
  try {
@@ -7992,7 +8145,7 @@ function checkForUpdate(currentVersion2) {
7992
8145
  }
7993
8146
  }
7994
8147
  function fetchLatestVersion() {
7995
- const result = import_cross_spawn3.default.sync("npm", ["view", PACKAGE_NAME, "version"], {
8148
+ const result = import_cross_spawn3.default.sync("npm", ["view", PACKAGE_NAME2, "version"], {
7996
8149
  encoding: "utf8",
7997
8150
  timeout: REGISTRY_TIMEOUT_MS,
7998
8151
  stdio: ["ignore", "pipe", "ignore"]
@@ -8008,9 +8161,9 @@ function reportIfOutdated(currentVersion2) {
8008
8161
  return;
8009
8162
  }
8010
8163
  logger.info("");
8011
- logger.info(`A new version of ${PACKAGE_NAME} is available: ${latestVersion}`);
8164
+ logger.info(`A new version of ${PACKAGE_NAME2} is available: ${latestVersion}`);
8012
8165
  logger.info(` Current version: ${currentVersion2}`);
8013
- logger.info(` Update with: npm install -g ${PACKAGE_NAME}@latest`);
8166
+ logger.info(` Update with: npm install -g ${PACKAGE_NAME2}@latest`);
8014
8167
  logger.info("");
8015
8168
  }
8016
8169
  function isNewerVersion(candidate, current) {
@@ -8032,8 +8185,8 @@ function releaseTriple(version) {
8032
8185
  }
8033
8186
  function readCliVersion(packageDirectory) {
8034
8187
  try {
8035
- const manifestPath = (0, import_node_path33.join)(packageDirectory, "..", "package.json");
8036
- const manifest = JSON.parse((0, import_node_fs26.readFileSync)(manifestPath, "utf8"));
8188
+ const manifestPath = (0, import_node_path34.join)(packageDirectory, "..", "package.json");
8189
+ const manifest = JSON.parse((0, import_node_fs28.readFileSync)(manifestPath, "utf8"));
8037
8190
  return manifest.version ?? "0.0.0";
8038
8191
  } catch {
8039
8192
  return "0.0.0";
@@ -8043,7 +8196,7 @@ function readCliVersion(packageDirectory) {
8043
8196
  // src/workspace-info/read-workspace-info.use-case.ts
8044
8197
  function readWorkspaceInfo(workspaceRoot, cliVersion) {
8045
8198
  const latest = fetchLatestVersion() ?? null;
8046
- const isWorkspace = fileExists((0, import_node_path34.join)(workspaceRoot, "nx.json"));
8199
+ const isWorkspace = fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"));
8047
8200
  return {
8048
8201
  cli: {
8049
8202
  version: cliVersion,
@@ -8064,8 +8217,8 @@ function runInfo(workspaceRoot, cliVersion, options) {
8064
8217
  }
8065
8218
 
8066
8219
  // src/workspace-creation/adopt-directory.use-case.ts
8067
- var import_node_fs27 = require("fs");
8068
- var import_node_path35 = require("path");
8220
+ var import_node_fs29 = require("fs");
8221
+ var import_node_path36 = require("path");
8069
8222
  var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
8070
8223
  var AGENT_AND_CI_ENTRIES = [
8071
8224
  "AGENTS.md",
@@ -8096,13 +8249,13 @@ var PREFLIGHT_BLOCKERS = [
8096
8249
  "packages"
8097
8250
  ];
8098
8251
  function assertAdoptableDirectory(target) {
8099
- if (!(0, import_node_fs27.existsSync)(target)) {
8252
+ if (!(0, import_node_fs29.existsSync)(target)) {
8100
8253
  throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
8101
8254
  }
8102
- if (!(0, import_node_fs27.statSync)(target).isDirectory()) {
8255
+ if (!(0, import_node_fs29.statSync)(target).isDirectory()) {
8103
8256
  throw new Error(`--into '${target}' is not a directory.`);
8104
8257
  }
8105
- const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs27.existsSync)((0, import_node_path35.join)(target, entry)));
8258
+ const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs29.existsSync)((0, import_node_path36.join)(target, entry)));
8106
8259
  if (blockers.length > 0) {
8107
8260
  throw new Error(
8108
8261
  `--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.`
@@ -8110,15 +8263,15 @@ function assertAdoptableDirectory(target) {
8110
8263
  }
8111
8264
  }
8112
8265
  function mergeGitignore(generatedFile, targetFile) {
8113
- const existing = (0, import_node_fs27.readFileSync)(targetFile, "utf8");
8266
+ const existing = (0, import_node_fs29.readFileSync)(targetFile, "utf8");
8114
8267
  const present = new Set(existing.split("\n").map((line) => line.trim()));
8115
- const additions = (0, import_node_fs27.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8268
+ const additions = (0, import_node_fs29.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8116
8269
  const trimmed = line.trim();
8117
8270
  return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
8118
8271
  });
8119
8272
  if (additions.length === 0) return false;
8120
8273
  const separator = existing.endsWith("\n") ? "" : "\n";
8121
- (0, import_node_fs27.writeFileSync)(
8274
+ (0, import_node_fs29.writeFileSync)(
8122
8275
  targetFile,
8123
8276
  `${existing}${separator}
8124
8277
  # Added by mnci (Nx workspace)
@@ -8128,9 +8281,9 @@ ${additions.join("\n")}
8128
8281
  return true;
8129
8282
  }
8130
8283
  function adoptGeneratedWorkspace(generatedRoot, target) {
8131
- const entries = (0, import_node_fs27.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8284
+ const entries = (0, import_node_fs29.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8132
8285
  const collisions = entries.filter(
8133
- (entry) => (0, import_node_fs27.existsSync)((0, import_node_path35.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8286
+ (entry) => (0, import_node_fs29.existsSync)((0, import_node_path36.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8134
8287
  );
8135
8288
  if (collisions.length > 0) {
8136
8289
  throw new Error(
@@ -8139,28 +8292,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
8139
8292
  }
8140
8293
  const result = { copied: [], kept: [], mergedGitignore: false };
8141
8294
  for (const entry of entries) {
8142
- const from = (0, import_node_path35.join)(generatedRoot, entry);
8143
- const to = (0, import_node_path35.join)(target, entry);
8144
- if (entry === ".gitignore" && (0, import_node_fs27.existsSync)(to)) {
8295
+ const from = (0, import_node_path36.join)(generatedRoot, entry);
8296
+ const to = (0, import_node_path36.join)(target, entry);
8297
+ if (entry === ".gitignore" && (0, import_node_fs29.existsSync)(to)) {
8145
8298
  result.mergedGitignore = mergeGitignore(from, to);
8146
8299
  result.kept.push(entry);
8147
8300
  continue;
8148
8301
  }
8149
- if ((0, import_node_fs27.existsSync)(to)) {
8302
+ if ((0, import_node_fs29.existsSync)(to)) {
8150
8303
  result.kept.push(entry);
8151
8304
  continue;
8152
8305
  }
8153
- (0, import_node_fs27.cpSync)(from, to, { recursive: true });
8306
+ (0, import_node_fs29.cpSync)(from, to, { recursive: true });
8154
8307
  result.copied.push(entry);
8155
8308
  }
8156
- (0, import_node_fs27.rmSync)(generatedRoot, { recursive: true, force: true });
8309
+ (0, import_node_fs29.rmSync)(generatedRoot, { recursive: true, force: true });
8157
8310
  return result;
8158
8311
  }
8159
8312
 
8160
8313
  // src/workspace-creation/create-workspace.use-case.ts
8161
- var import_node_fs28 = require("fs");
8314
+ var import_node_fs30 = require("fs");
8162
8315
  var import_node_os2 = require("os");
8163
- var import_node_path36 = require("path");
8316
+ var import_node_path37 = require("path");
8164
8317
  function nxCloudProviderValue(ci) {
8165
8318
  return ci === "azure" ? "azure" : "github";
8166
8319
  }
@@ -8203,9 +8356,9 @@ async function resolveRegistry(options) {
8203
8356
  return await promptRegistry();
8204
8357
  }
8205
8358
  async function runNew(name, options) {
8206
- const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path36.resolve)(process.cwd(), options.into);
8359
+ const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path37.resolve)(process.cwd(), options.into);
8207
8360
  if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
8208
- const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path36.basename)(adoptTarget));
8361
+ const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path37.basename)(adoptTarget));
8209
8362
  assertValidProjectName(workspaceName, "Workspace name");
8210
8363
  const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
8211
8364
  const registry = await resolveRegistry(options);
@@ -8218,8 +8371,8 @@ async function runNew(name, options) {
8218
8371
  const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
8219
8372
  const stack = await resolveStack(options);
8220
8373
  const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
8221
- const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs28.mkdtempSync)((0, import_node_path36.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8222
- let workspaceRoot = (0, import_node_path36.join)(stagingParent, workspaceName);
8374
+ const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs30.mkdtempSync)((0, import_node_path37.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8375
+ let workspaceRoot = (0, import_node_path37.join)(stagingParent, workspaceName);
8223
8376
  try {
8224
8377
  logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
8225
8378
  runNpx(
@@ -8242,7 +8395,7 @@ async function runNew(name, options) {
8242
8395
  workspaceRoot = adoptTarget;
8243
8396
  }
8244
8397
  } finally {
8245
- if (adoptTarget !== void 0) (0, import_node_fs28.rmSync)(stagingParent, { recursive: true, force: true });
8398
+ if (adoptTarget !== void 0) (0, import_node_fs30.rmSync)(stagingParent, { recursive: true, force: true });
8246
8399
  }
8247
8400
  logger.step(
8248
8401
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
@@ -8252,8 +8405,8 @@ async function runNew(name, options) {
8252
8405
  { workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
8253
8406
  logger.detail
8254
8407
  );
8255
- (0, import_node_fs28.rmSync)((0, import_node_path36.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8256
- (0, import_node_fs28.rmSync)((0, import_node_path36.join)(workspaceRoot, "package-lock.json"), { force: true });
8408
+ (0, import_node_fs30.rmSync)((0, import_node_path37.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8409
+ (0, import_node_fs30.rmSync)((0, import_node_path37.join)(workspaceRoot, "package-lock.json"), { force: true });
8257
8410
  logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
8258
8411
  const installStatus = runShell(
8259
8412
  "npm",
@@ -8291,12 +8444,12 @@ function projectKindHintLines(kinds = PROJECT_KINDS) {
8291
8444
  }
8292
8445
 
8293
8446
  // src/workspace-creation/interactive-wizard.use-case.ts
8294
- var import_node_path38 = require("path");
8447
+ var import_node_path39 = require("path");
8295
8448
  var import_prompts4 = require("@inquirer/prompts");
8296
8449
 
8297
8450
  // src/workspace-upgrade/upgrade-workspace.use-case.ts
8298
- var import_node_fs29 = require("fs");
8299
- var import_node_path37 = require("path");
8451
+ var import_node_fs31 = require("fs");
8452
+ var import_node_path38 = require("path");
8300
8453
  function resolveRegistry2(options, persisted) {
8301
8454
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
8302
8455
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -8325,7 +8478,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8325
8478
  return persisted.workspaceName;
8326
8479
  }
8327
8480
  try {
8328
- const existing = (0, import_node_fs29.readdirSync)(workspaceRoot).find(
8481
+ const existing = (0, import_node_fs31.readdirSync)(workspaceRoot).find(
8329
8482
  (file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
8330
8483
  );
8331
8484
  if (existing) {
@@ -8333,11 +8486,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8333
8486
  }
8334
8487
  } catch {
8335
8488
  }
8336
- return (0, import_node_path37.basename)(workspaceRoot);
8489
+ return (0, import_node_path38.basename)(workspaceRoot);
8337
8490
  }
8338
8491
  function detectNpmAuth(workspaceRoot) {
8339
8492
  try {
8340
- return (0, import_node_fs29.readFileSync)((0, import_node_path37.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8493
+ return (0, import_node_fs31.readFileSync)((0, import_node_path38.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8341
8494
  } catch {
8342
8495
  return void 0;
8343
8496
  }
@@ -8384,7 +8537,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
8384
8537
  };
8385
8538
  }
8386
8539
  function runUpgrade(workspaceRoot, options) {
8387
- if (!fileExists((0, import_node_path37.join)(workspaceRoot, "nx.json"))) {
8540
+ if (!fileExists((0, import_node_path38.join)(workspaceRoot, "nx.json"))) {
8388
8541
  throw new Error(
8389
8542
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
8390
8543
  );
@@ -8450,7 +8603,7 @@ function runUpgrade(workspaceRoot, options) {
8450
8603
 
8451
8604
  // src/workspace-creation/interactive-wizard.use-case.ts
8452
8605
  async function runInteractive() {
8453
- const inWorkspace = fileExists((0, import_node_path38.join)(process.cwd(), "nx.json"));
8606
+ const inWorkspace = fileExists((0, import_node_path39.join)(process.cwd(), "nx.json"));
8454
8607
  const choiceNew = { name: "Create a new monorepo", value: "new" };
8455
8608
  const choiceAdd = { name: "Add a project to this workspace", value: "add" };
8456
8609
  const choiceUpgrade = {