@mnci/cli 4.40.2 → 4.40.4

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
@@ -283,12 +283,18 @@ function classifyNpmAudit(report) {
283
283
  });
284
284
  return { blocking, total: all.length, notes };
285
285
  }
286
+ function isNoOpChange(change) {
287
+ const { from, to } = change ?? {};
288
+ return from?.version !== void 0 && from.version === to?.version && from.name === to?.name;
289
+ }
286
290
  function planIsEmpty(stdout) {
287
291
  try {
288
292
  const start = stdout.search(/^\{/m);
289
293
  const plan = JSON.parse(start === -1 ? stdout : stdout.slice(start));
290
- const lists = [plan.add, plan.change, plan.remove];
291
- return lists.every((list) => Array.isArray(list) && list.length === 0);
294
+ if (!Array.isArray(plan.add) || !Array.isArray(plan.change) || !Array.isArray(plan.remove)) {
295
+ return false;
296
+ }
297
+ return plan.add.length === 0 && plan.remove.length === 0 && plan.change.every((change) => isNoOpChange(change));
292
298
  } catch {
293
299
  return false;
294
300
  }
@@ -3168,7 +3174,7 @@ function runPhase(phase, workspaceRoot, dependencies) {
3168
3174
  }
3169
3175
 
3170
3176
  // src/project-scaffolding/add-project.use-case.ts
3171
- var import_node_path31 = require("path");
3177
+ var import_node_path33 = require("path");
3172
3178
  var import_prompts3 = require("@inquirer/prompts");
3173
3179
 
3174
3180
  // src/project-name/project-name.validator.ts
@@ -5076,11 +5082,65 @@ function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
5076
5082
  }
5077
5083
 
5078
5084
  // src/project-scaffolding/npm-lib.use-case.ts
5079
- var import_node_path22 = require("path");
5085
+ var import_node_path24 = require("path");
5080
5086
 
5081
- // src/rollup-library/repair-publishable-manifest.use-case.ts
5087
+ // src/lockfile-pruning/prune-stale-local-registry.use-case.ts
5088
+ var import_node_fs20 = require("fs");
5089
+ var import_node_path20 = require("path");
5090
+
5091
+ // src/lockfile-pruning/stale-local-registry.validator.ts
5082
5092
  var import_node_fs19 = require("fs");
5083
5093
  var import_node_path19 = require("path");
5094
+ var LOCAL_REGISTRY_PACKAGE = "verdaccio";
5095
+ var LOCAL_REGISTRY_LOCK_KEY = `node_modules/${LOCAL_REGISTRY_PACKAGE}`;
5096
+ var DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
5097
+ function readJsonFile(path) {
5098
+ if (!(0, import_node_fs19.existsSync)(path)) {
5099
+ return void 0;
5100
+ }
5101
+ try {
5102
+ return JSON.parse((0, import_node_fs19.readFileSync)(path, "utf8"));
5103
+ } catch {
5104
+ return void 0;
5105
+ }
5106
+ }
5107
+ function declaresLocalRegistry(manifest) {
5108
+ return DEPENDENCY_FIELDS.some((field) => {
5109
+ const list = manifest?.[field];
5110
+ return list !== void 0 && Object.hasOwn(list, LOCAL_REGISTRY_PACKAGE);
5111
+ });
5112
+ }
5113
+ function hasStaleLocalRegistry(workspaceRoot) {
5114
+ const lock = readJsonFile((0, import_node_path19.join)(workspaceRoot, "package-lock.json"));
5115
+ const entries = lock?.packages ?? {};
5116
+ if (!Object.hasOwn(entries, LOCAL_REGISTRY_LOCK_KEY)) {
5117
+ return false;
5118
+ }
5119
+ const members = Object.keys(entries).filter((key) => key !== "" && !key.startsWith("node_modules/") && !key.includes("/node_modules/"));
5120
+ const manifests = ["", ...members].map((directory) => readJsonFile((0, import_node_path19.join)(workspaceRoot, directory, "package.json")));
5121
+ return manifests.every((manifest) => !declaresLocalRegistry(manifest));
5122
+ }
5123
+
5124
+ // src/lockfile-pruning/prune-stale-local-registry.use-case.ts
5125
+ function pruneStaleLocalRegistry(workspaceRoot, resolve2 = runShell) {
5126
+ if (!hasStaleLocalRegistry(workspaceRoot)) {
5127
+ return { stale: false, status: 0 };
5128
+ }
5129
+ const lockPath = (0, import_node_path20.join)(workspaceRoot, "package-lock.json");
5130
+ const lock = JSON.parse((0, import_node_fs20.readFileSync)(lockPath, "utf8"));
5131
+ Reflect.deleteProperty(lock.packages, LOCAL_REGISTRY_LOCK_KEY);
5132
+ const root = lock.packages[""];
5133
+ if (root?.devDependencies !== void 0) {
5134
+ Reflect.deleteProperty(root.devDependencies, LOCAL_REGISTRY_PACKAGE);
5135
+ }
5136
+ (0, import_node_fs20.writeFileSync)(lockPath, `${JSON.stringify(lock, void 0, 2)}
5137
+ `);
5138
+ return { stale: true, status: resolve2("npm", ["install", "--package-lock-only", "--ignore-scripts", "--no-audit", "--no-fund"], workspaceRoot) };
5139
+ }
5140
+
5141
+ // src/rollup-library/repair-publishable-manifest.use-case.ts
5142
+ var import_node_fs21 = require("fs");
5143
+ var import_node_path21 = require("path");
5084
5144
  var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
5085
5145
  var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
5086
5146
  var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
@@ -5103,14 +5163,14 @@ function repairPublishableManifest(manifestPath) {
5103
5163
  }
5104
5164
  function repairPublishableManifests(workspaceRoot) {
5105
5165
  const changed = [];
5106
- const manifests = (0, import_node_fs19.globSync)(["packages/*/package.json", "libs/*/package.json"], {
5166
+ const manifests = (0, import_node_fs21.globSync)(["packages/*/package.json", "libs/*/package.json"], {
5107
5167
  cwd: workspaceRoot
5108
5168
  });
5109
5169
  for (const relativePath of manifests) {
5110
- const manifestPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
5111
- const before = (0, import_node_fs19.readFileSync)(manifestPath, "utf8");
5170
+ const manifestPath = (0, import_node_path21.join)(workspaceRoot, relativePath);
5171
+ const before = (0, import_node_fs21.readFileSync)(manifestPath, "utf8");
5112
5172
  repairPublishableManifest(manifestPath);
5113
- const after = (0, import_node_fs19.readFileSync)(manifestPath, "utf8");
5173
+ const after = (0, import_node_fs21.readFileSync)(manifestPath, "utf8");
5114
5174
  if (after !== before) {
5115
5175
  changed.push(relativePath.replaceAll("\\", "/"));
5116
5176
  }
@@ -5119,8 +5179,8 @@ function repairPublishableManifests(workspaceRoot) {
5119
5179
  }
5120
5180
 
5121
5181
  // src/rollup-library/repair-rollup-config.use-case.ts
5122
- var import_node_fs20 = require("fs");
5123
- var import_node_path20 = require("path");
5182
+ var import_node_fs22 = require("fs");
5183
+ var import_node_path22 = require("path");
5124
5184
 
5125
5185
  // src/rollup-library/rollup-config.algorithm.ts
5126
5186
  var ROLLUP_CONFIG_PLACEHOLDER = [
@@ -5322,12 +5382,12 @@ function withUpgradedDeclarationSpecifierPlugin(config) {
5322
5382
  // src/rollup-library/repair-rollup-config.use-case.ts
5323
5383
  function repairRollupSourceMaps(workspaceRoot) {
5324
5384
  const changed = [];
5325
- const configs = (0, import_node_fs20.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5385
+ const configs = (0, import_node_fs22.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5326
5386
  cwd: workspaceRoot
5327
5387
  });
5328
5388
  for (const relativePath of configs) {
5329
- const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5330
- const before = (0, import_node_fs20.readFileSync)(configPath, "utf8");
5389
+ const configPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
5390
+ const before = (0, import_node_fs22.readFileSync)(configPath, "utf8");
5331
5391
  const after = withRollupSourceMaps(before);
5332
5392
  if (after !== before) {
5333
5393
  writeFileEnsured(configPath, after);
@@ -5338,12 +5398,12 @@ function repairRollupSourceMaps(workspaceRoot) {
5338
5398
  }
5339
5399
  function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
5340
5400
  const changed = [];
5341
- const configs = (0, import_node_fs20.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5401
+ const configs = (0, import_node_fs22.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5342
5402
  cwd: workspaceRoot
5343
5403
  });
5344
5404
  for (const relativePath of configs) {
5345
- const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5346
- const before = (0, import_node_fs20.readFileSync)(configPath, "utf8");
5405
+ const configPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
5406
+ const before = (0, import_node_fs22.readFileSync)(configPath, "utf8");
5347
5407
  const after = withUpgradedDeclarationSpecifierPlugin(before);
5348
5408
  if (after !== before) {
5349
5409
  writeFileEnsured(configPath, after);
@@ -5353,11 +5413,11 @@ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
5353
5413
  return changed;
5354
5414
  }
5355
5415
  function repairDeclarationSpecifiers(projectRoot) {
5356
- const configPath = (0, import_node_path20.join)(projectRoot, "rollup.config.cjs");
5416
+ const configPath = (0, import_node_path22.join)(projectRoot, "rollup.config.cjs");
5357
5417
  if (!fileExists(configPath)) {
5358
5418
  return;
5359
5419
  }
5360
- const config = (0, import_node_fs20.readFileSync)(configPath, "utf8");
5420
+ const config = (0, import_node_fs22.readFileSync)(configPath, "utf8");
5361
5421
  if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
5362
5422
  return;
5363
5423
  }
@@ -5366,10 +5426,10 @@ function repairDeclarationSpecifiers(projectRoot) {
5366
5426
  }
5367
5427
 
5368
5428
  // src/rollup-library/rollup-config.repository.ts
5369
- var import_node_fs21 = require("fs");
5370
- var import_node_path21 = require("path");
5429
+ var import_node_fs23 = require("fs");
5430
+ var import_node_path23 = require("path");
5371
5431
  function resolveRequireTarget(fromDir, specifier) {
5372
- const base = (0, import_node_path21.join)(fromDir, specifier);
5432
+ const base = (0, import_node_path23.join)(fromDir, specifier);
5373
5433
  return [base, `${base}.cjs`, `${base}.js`].find((candidate) => fileExists(candidate));
5374
5434
  }
5375
5435
  function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()) {
@@ -5379,7 +5439,7 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
5379
5439
  visited.add(configPath);
5380
5440
  let text;
5381
5441
  try {
5382
- text = (0, import_node_fs21.readFileSync)(configPath, "utf8");
5442
+ text = (0, import_node_fs23.readFileSync)(configPath, "utf8");
5383
5443
  } catch {
5384
5444
  return "";
5385
5445
  }
@@ -5387,15 +5447,15 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
5387
5447
  text.matchAll(/require\((['"])(\.[^'"]*)\1\)/g),
5388
5448
  (match) => match[2]
5389
5449
  );
5390
- const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path21.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5450
+ const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path23.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5391
5451
  return [text, ...requiredText].join("\n");
5392
5452
  }
5393
5453
 
5394
5454
  // src/project-scaffolding/npm-lib.use-case.ts
5395
5455
  async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
5396
5456
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5397
- const projectRoot = (0, import_node_path22.join)(workspaceRoot, "packages", name);
5398
- const manifestPath = (0, import_node_path22.join)(projectRoot, "package.json");
5457
+ const projectRoot = (0, import_node_path24.join)(workspaceRoot, "packages", name);
5458
+ const manifestPath = (0, import_node_path24.join)(projectRoot, "package.json");
5399
5459
  runGeneratorAndRepair(
5400
5460
  workspaceRoot,
5401
5461
  [
@@ -5418,14 +5478,18 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
5418
5478
  renameScaffoldPlaceholder(projectRoot, name, options.empty === true);
5419
5479
  removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
5420
5480
  removeLocalRegistryScaffolding(workspaceRoot);
5481
+ const pruned = pruneStaleLocalRegistry(workspaceRoot);
5482
+ if (pruned.stale && pruned.status !== 0) {
5483
+ logger.warn("Could not drop the unused local registry from package-lock.json: run `mnci upgrade` once the network is back.");
5484
+ }
5421
5485
  registerProjectCommands(workspaceRoot, name, { build: true });
5422
5486
  }
5423
5487
  );
5424
5488
  }
5425
5489
 
5426
5490
  // src/project-scaffolding/python.use-case.ts
5427
- var import_node_fs22 = require("fs");
5428
- var import_node_path23 = require("path");
5491
+ var import_node_fs24 = require("fs");
5492
+ var import_node_path25 = require("path");
5429
5493
  function ensurePython(workspaceRoot) {
5430
5494
  const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
5431
5495
  if (!hasPython) {
@@ -5448,7 +5512,7 @@ function ensurePythonPipPlugin(workspaceRoot) {
5448
5512
  registerPythonGraphPlugin(workspaceRoot);
5449
5513
  }
5450
5514
  function registerPythonGraphPlugin(workspaceRoot) {
5451
- const nxJsonPath = (0, import_node_path23.join)(workspaceRoot, "nx.json");
5515
+ const nxJsonPath = (0, import_node_path25.join)(workspaceRoot, "nx.json");
5452
5516
  if (!fileExists(nxJsonPath)) {
5453
5517
  return;
5454
5518
  }
@@ -5471,7 +5535,7 @@ pytest
5471
5535
  pip-audit
5472
5536
  `;
5473
5537
  function ensureRequirementsDev(workspaceRoot) {
5474
- const requirementsDevPath = (0, import_node_path23.join)(workspaceRoot, "requirements-dev.txt");
5538
+ const requirementsDevPath = (0, import_node_path25.join)(workspaceRoot, "requirements-dev.txt");
5475
5539
  if (!fileExists(requirementsDevPath)) {
5476
5540
  writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
5477
5541
  }
@@ -5531,8 +5595,8 @@ function addPythonApp(workspaceRoot, name) {
5531
5595
  ["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
5532
5596
  workspaceRoot
5533
5597
  );
5534
- writeFileEnsured((0, import_node_path23.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5535
- addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5598
+ writeFileEnsured((0, import_node_path25.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5599
+ addProjectJsonTargets((0, import_node_path25.join)(workspaceRoot, "apps", name, "project.json"), {
5536
5600
  package: pythonAppPackageTarget(name),
5537
5601
  start: pythonAppStartTarget(name)
5538
5602
  });
@@ -5554,7 +5618,7 @@ function addPythonFunctionApp(workspaceRoot, name) {
5554
5618
  workspaceRoot
5555
5619
  );
5556
5620
  const moduleDirectory = pythonModuleDirectory(name);
5557
- addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5621
+ addProjectJsonTargets((0, import_node_path25.join)(workspaceRoot, "apps", name, "project.json"), {
5558
5622
  package: pythonFunctionAppPackageTarget(name, moduleDirectory),
5559
5623
  start: pythonFunctionAppStartTarget(name)
5560
5624
  });
@@ -5595,7 +5659,7 @@ function addPythonInternalLib(workspaceRoot, name) {
5595
5659
  var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
5596
5660
  function findPythonProjectDirectory(workspaceRoot, name) {
5597
5661
  return PYTHON_PROJECT_DIRS.find(
5598
- (directory) => fileExists((0, import_node_path23.join)(workspaceRoot, directory, name, "pyproject.toml"))
5662
+ (directory) => fileExists((0, import_node_path25.join)(workspaceRoot, directory, name, "pyproject.toml"))
5599
5663
  );
5600
5664
  }
5601
5665
  function parseVendorEntries(pyprojectToml) {
@@ -5634,7 +5698,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5634
5698
  `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.`
5635
5699
  );
5636
5700
  }
5637
- if (!fileExists((0, import_node_path23.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5701
+ if (!fileExists((0, import_node_path25.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5638
5702
  throw new Error(
5639
5703
  `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.`
5640
5704
  );
@@ -5642,8 +5706,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5642
5706
  if (consumerDirectory === "libs" && consumer === lib) {
5643
5707
  throw new Error(`'${consumer}' cannot vendor itself.`);
5644
5708
  }
5645
- const pyprojectPath = (0, import_node_path23.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5646
- const pyprojectToml = (0, import_node_fs22.readFileSync)(pyprojectPath, "utf8");
5709
+ const pyprojectPath = (0, import_node_path25.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5710
+ const pyprojectToml = (0, import_node_fs24.readFileSync)(pyprojectPath, "utf8");
5647
5711
  if (parseVendorEntries(pyprojectToml).includes(lib)) {
5648
5712
  logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
5649
5713
  return;
@@ -5655,8 +5719,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5655
5719
  }
5656
5720
 
5657
5721
  // src/project-scaffolding/react-app.use-case.ts
5658
- var import_node_fs23 = require("fs");
5659
- var import_node_path24 = require("path");
5722
+ var import_node_fs25 = require("fs");
5723
+ var import_node_path26 = require("path");
5660
5724
 
5661
5725
  // src/project-scaffolding/react-app-example.algorithm.ts
5662
5726
  function reactAppExampleFiles(name) {
@@ -5773,12 +5837,12 @@ function reactAppTargets(name) {
5773
5837
  return targets;
5774
5838
  }
5775
5839
  function allowEnvFiles(workspaceRoot) {
5776
- const gitignorePath = (0, import_node_path24.join)(workspaceRoot, ".gitignore");
5840
+ const gitignorePath = (0, import_node_path26.join)(workspaceRoot, ".gitignore");
5777
5841
  if (!fileExists(gitignorePath)) {
5778
5842
  return;
5779
5843
  }
5780
5844
  const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
5781
- const current = (0, import_node_fs23.readFileSync)(gitignorePath, "utf8");
5845
+ const current = (0, import_node_fs25.readFileSync)(gitignorePath, "utf8");
5782
5846
  if (current.includes(marker)) {
5783
5847
  return;
5784
5848
  }
@@ -5805,30 +5869,30 @@ function addReactApp(workspaceRoot, name, stack) {
5805
5869
  workspaceRoot
5806
5870
  );
5807
5871
  ensureAdmZip(workspaceRoot);
5808
- const reactAppRoot = (0, import_node_path24.join)(workspaceRoot, "apps", name);
5872
+ const reactAppRoot = (0, import_node_path26.join)(workspaceRoot, "apps", name);
5809
5873
  for (const environment of REACT_ENVIRONMENTS) {
5810
- writeFileEnsured((0, import_node_path24.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5874
+ writeFileEnsured((0, import_node_path26.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5811
5875
  }
5812
5876
  allowEnvFiles(workspaceRoot);
5813
- addNxTargets((0, import_node_path24.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5877
+ addNxTargets((0, import_node_path26.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5814
5878
  reshapeReactAppScaffold(reactAppRoot);
5815
- (0, import_node_fs23.rmSync)((0, import_node_path24.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5879
+ (0, import_node_fs25.rmSync)((0, import_node_path26.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5816
5880
  const example = reactAppExampleFiles(name);
5817
5881
  for (const [relative, contents] of Object.entries(example)) {
5818
- writeFileEnsured((0, import_node_path24.join)(reactAppRoot, "src", relative), contents);
5882
+ writeFileEnsured((0, import_node_path26.join)(reactAppRoot, "src", relative), contents);
5819
5883
  }
5820
5884
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
5821
5885
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
5822
5886
  }
5823
5887
 
5824
5888
  // src/project-scaffolding/react-lib.use-case.ts
5825
- var import_node_path25 = require("path");
5889
+ var import_node_path27 = require("path");
5826
5890
  var REACT_LIB_BUNDLER = "rollup";
5827
5891
  async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5828
5892
  ensurePlugin(workspaceRoot, "@nx/react");
5829
5893
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5830
- const projectRoot = (0, import_node_path25.join)(workspaceRoot, "packages", name);
5831
- const publishableManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5894
+ const projectRoot = (0, import_node_path27.join)(workspaceRoot, "packages", name);
5895
+ const publishableManifest = (0, import_node_path27.join)(projectRoot, "package.json");
5832
5896
  runGeneratorAndRepair(
5833
5897
  workspaceRoot,
5834
5898
  [
@@ -5852,14 +5916,18 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5852
5916
  reshapeReactScaffold(projectRoot, name, options.empty === true);
5853
5917
  removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
5854
5918
  removeLocalRegistryScaffolding(workspaceRoot);
5919
+ const pruned = pruneStaleLocalRegistry(workspaceRoot);
5920
+ if (pruned.stale && pruned.status !== 0) {
5921
+ logger.warn("Could not drop the unused local registry from package-lock.json: run `mnci upgrade` once the network is back.");
5922
+ }
5855
5923
  registerProjectCommands(workspaceRoot, name, { build: true });
5856
5924
  }
5857
5925
  );
5858
5926
  }
5859
5927
  function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5860
5928
  ensurePlugin(workspaceRoot, "@nx/react");
5861
- const projectRoot = (0, import_node_path25.join)(workspaceRoot, "libs", name);
5862
- const privateManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5929
+ const projectRoot = (0, import_node_path27.join)(workspaceRoot, "libs", name);
5930
+ const privateManifest = (0, import_node_path27.join)(projectRoot, "package.json");
5863
5931
  runGeneratorAndRepair(
5864
5932
  workspaceRoot,
5865
5933
  [
@@ -5886,8 +5954,8 @@ function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5886
5954
  }
5887
5955
 
5888
5956
  // src/project-scaffolding/vscode-extension.use-case.ts
5889
- var import_node_fs24 = require("fs");
5890
- var import_node_path26 = require("path");
5957
+ var import_node_fs26 = require("fs");
5958
+ var import_node_path28 = require("path");
5891
5959
  var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
5892
5960
  var VSCODE_ENGINE_FLOOR = "1.96.0";
5893
5961
  var VSCODE_SIDECAR_TARGETS = {
@@ -6072,8 +6140,8 @@ export const window = {
6072
6140
  var VSCODE_STUB_PATH = "test/vscode.stub.ts";
6073
6141
  function mapVscodeToStub(projectRoot, testRunner) {
6074
6142
  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}\` },`];
6075
- const path = (0, import_node_path26.join)(projectRoot, file);
6076
- const content = fileExists(path) ? (0, import_node_fs24.readFileSync)(path, "utf8") : "";
6143
+ const path = (0, import_node_path28.join)(projectRoot, file);
6144
+ const content = fileExists(path) ? (0, import_node_fs26.readFileSync)(path, "utf8") : "";
6077
6145
  const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
6078
6146
  if (line === void 0) {
6079
6147
  throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
@@ -6093,11 +6161,11 @@ function ensureVscodeToolchain(workspaceRoot) {
6093
6161
  }
6094
6162
  }
6095
6163
  function defaultPublisher(workspaceRoot) {
6096
- const { name } = readJson((0, import_node_path26.join)(workspaceRoot, "package.json"));
6164
+ const { name } = readJson((0, import_node_path28.join)(workspaceRoot, "package.json"));
6097
6165
  return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
6098
6166
  }
6099
6167
  function reshapeManifest(projectRoot, name, publisher) {
6100
- const manifestPath = (0, import_node_path26.join)(projectRoot, "package.json");
6168
+ const manifestPath = (0, import_node_path28.join)(projectRoot, "package.json");
6101
6169
  const manifest = readJson(manifestPath);
6102
6170
  const { nx = {}, ...rest } = manifest;
6103
6171
  const targets = { ...nx.targets };
@@ -6161,11 +6229,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
6161
6229
  };
6162
6230
  }
6163
6231
  function addDebugLaunch(workspaceRoot, name) {
6164
- const file = (0, import_node_fs24.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
6232
+ const file = (0, import_node_fs26.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
6165
6233
  if (file === void 0) {
6166
6234
  return;
6167
6235
  }
6168
- const path = (0, import_node_path26.join)(workspaceRoot, file);
6236
+ const path = (0, import_node_path28.join)(workspaceRoot, file);
6169
6237
  const workspace = readCodeWorkspace(path) ?? {};
6170
6238
  const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
6171
6239
  const taskLabel = `${name}: build (development)`;
@@ -6198,39 +6266,39 @@ function addDebugLaunch(workspaceRoot, name) {
6198
6266
  );
6199
6267
  }
6200
6268
  function refreshVscodeExtensionScript(workspaceRoot) {
6201
- const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
6269
+ const apps = (0, import_node_path28.join)(workspaceRoot, "apps");
6202
6270
  let entries;
6203
6271
  try {
6204
- entries = (0, import_node_fs24.readdirSync)(apps);
6272
+ entries = (0, import_node_fs26.readdirSync)(apps);
6205
6273
  } catch {
6206
6274
  return false;
6207
6275
  }
6208
6276
  const hasExtension = entries.some((entry) => {
6209
- const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
6277
+ const manifestPath = (0, import_node_path28.join)(apps, entry, "package.json");
6210
6278
  if (!fileExists(manifestPath)) {
6211
6279
  return false;
6212
6280
  }
6213
6281
  const tags = readJson(manifestPath).nx?.tags ?? [];
6214
6282
  return tags.includes(VSCODE_EXTENSION_TAG);
6215
6283
  });
6216
- const path = (0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
6217
- if (!hasExtension || fileExists(path) && (0, import_node_fs24.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
6284
+ const path = (0, import_node_path28.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
6285
+ if (!hasExtension || fileExists(path) && (0, import_node_fs26.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
6218
6286
  return false;
6219
6287
  }
6220
6288
  writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
6221
6289
  return true;
6222
6290
  }
6223
6291
  function pinVscodeExtensionProjectNames(workspaceRoot) {
6224
- const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
6292
+ const apps = (0, import_node_path28.join)(workspaceRoot, "apps");
6225
6293
  let entries;
6226
6294
  try {
6227
- entries = (0, import_node_fs24.readdirSync)(apps);
6295
+ entries = (0, import_node_fs26.readdirSync)(apps);
6228
6296
  } catch {
6229
6297
  return [];
6230
6298
  }
6231
6299
  const updated = [];
6232
6300
  for (const entry of entries) {
6233
- const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
6301
+ const manifestPath = (0, import_node_path28.join)(apps, entry, "package.json");
6234
6302
  if (!fileExists(manifestPath)) {
6235
6303
  continue;
6236
6304
  }
@@ -6250,22 +6318,22 @@ function refreshLockFile(workspaceRoot, name) {
6250
6318
  }
6251
6319
  function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
6252
6320
  const { sidecar } = options;
6253
- if (sidecar !== void 0 && !fileExists((0, import_node_path26.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
6321
+ if (sidecar !== void 0 && !fileExists((0, import_node_path28.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
6254
6322
  throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
6255
6323
  }
6256
6324
  runNodeApp(workspaceRoot, name, stack, "none");
6257
6325
  ensureVscodeToolchain(workspaceRoot);
6258
- const projectRoot = (0, import_node_path26.join)(workspaceRoot, "apps", name);
6326
+ const projectRoot = (0, import_node_path28.join)(workspaceRoot, "apps", name);
6259
6327
  reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot));
6260
- addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.app.json"));
6261
- addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.spec.json"));
6262
- writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
6263
- writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
6264
- writeFileEnsured((0, import_node_path26.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
6328
+ addVscodeTypes((0, import_node_path28.join)(projectRoot, "tsconfig.app.json"));
6329
+ addVscodeTypes((0, import_node_path28.join)(projectRoot, "tsconfig.spec.json"));
6330
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
6331
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
6332
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
6265
6333
  mapVscodeToStub(projectRoot, stack.testRunner);
6266
- writeFileEnsured((0, import_node_path26.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
6267
- writeFileEnsured((0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
6268
- addNxTargets((0, import_node_path26.join)(projectRoot, "package.json"), {
6334
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
6335
+ writeFileEnsured((0, import_node_path28.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
6336
+ addNxTargets((0, import_node_path28.join)(projectRoot, "package.json"), {
6269
6337
  "package": vscodeExtensionPackageTarget(name, sidecar),
6270
6338
  "nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
6271
6339
  });
@@ -6276,12 +6344,12 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
6276
6344
  }
6277
6345
 
6278
6346
  // src/dependency-management/install-dependencies.use-case.ts
6279
- var import_node_fs26 = require("fs");
6280
- var import_node_path28 = require("path");
6347
+ var import_node_fs28 = require("fs");
6348
+ var import_node_path30 = require("path");
6281
6349
 
6282
6350
  // src/dependency-management/manifest.repository.ts
6283
- var import_node_fs25 = require("fs");
6284
- var import_node_path27 = require("path");
6351
+ var import_node_fs27 = require("fs");
6352
+ var import_node_path29 = require("path");
6285
6353
  var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
6286
6354
  var ROOT_LABEL = "(root)";
6287
6355
  var MANIFEST_GLOBS = {
@@ -6314,23 +6382,23 @@ function projectOf(manifestRelativePath) {
6314
6382
  }
6315
6383
  function hasEcosystem(workspaceRoot, ecosystem) {
6316
6384
  if (ecosystem === "go") {
6317
- return fileExists((0, import_node_path27.join)(workspaceRoot, "go.mod"));
6385
+ return fileExists((0, import_node_path29.join)(workspaceRoot, "go.mod"));
6318
6386
  }
6319
6387
  if (ecosystem === "nuget") {
6320
- return (0, import_node_fs25.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
6388
+ return (0, import_node_fs27.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
6321
6389
  }
6322
6390
  const rootMarker = {
6323
6391
  npm: "package.json",
6324
6392
  pip: "requirements-dev.txt",
6325
6393
  pub: "pubspec.yaml"
6326
6394
  };
6327
- return fileExists((0, import_node_path27.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs25.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
6395
+ return fileExists((0, import_node_path29.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs27.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
6328
6396
  }
6329
6397
  function collectNpm(workspaceRoot) {
6330
6398
  const sites = [];
6331
- const relativePaths = ["package.json", ...(0, import_node_fs25.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
6399
+ const relativePaths = ["package.json", ...(0, import_node_fs27.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
6332
6400
  for (const relativePath of relativePaths) {
6333
- const manifestPath = (0, import_node_path27.join)(workspaceRoot, relativePath);
6401
+ const manifestPath = (0, import_node_path29.join)(workspaceRoot, relativePath);
6334
6402
  try {
6335
6403
  const manifest = readJson(manifestPath);
6336
6404
  sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
@@ -6391,17 +6459,17 @@ function collectPip(workspaceRoot) {
6391
6459
  name: parsed.name,
6392
6460
  ecosystem: "pip",
6393
6461
  project: projectOf(relativePath),
6394
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6462
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath),
6395
6463
  section,
6396
6464
  spec: parsed.spec,
6397
6465
  rewritable: parsed.rewritable && parsed.spec !== ""
6398
6466
  });
6399
6467
  };
6400
- const pyprojectPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6468
+ const pyprojectPaths = (0, import_node_fs27.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6401
6469
  for (const relativePath of pyprojectPaths) {
6402
6470
  let content;
6403
6471
  try {
6404
- content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6472
+ content = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8");
6405
6473
  } catch {
6406
6474
  continue;
6407
6475
  }
@@ -6412,14 +6480,14 @@ function collectPip(workspaceRoot) {
6412
6480
  }
6413
6481
  const requirementsPaths = [
6414
6482
  "requirements-dev.txt",
6415
- ...(0, import_node_fs25.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6483
+ ...(0, import_node_fs27.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6416
6484
  ];
6417
6485
  for (const relativePath of requirementsPaths) {
6418
- if (!fileExists((0, import_node_path27.join)(workspaceRoot, relativePath))) {
6486
+ if (!fileExists((0, import_node_path29.join)(workspaceRoot, relativePath))) {
6419
6487
  continue;
6420
6488
  }
6421
6489
  const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
6422
- const lines = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6490
+ const lines = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6423
6491
  for (const line of lines) {
6424
6492
  push(relativePath, section, line);
6425
6493
  }
@@ -6457,11 +6525,11 @@ function pyprojectDependencies(content) {
6457
6525
  }
6458
6526
  function collectPub(workspaceRoot) {
6459
6527
  const sites = [];
6460
- const pubspecPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6528
+ const pubspecPaths = (0, import_node_fs27.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6461
6529
  for (const relativePath of pubspecPaths) {
6462
6530
  let content;
6463
6531
  try {
6464
- content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6532
+ content = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8");
6465
6533
  } catch {
6466
6534
  continue;
6467
6535
  }
@@ -6471,7 +6539,7 @@ function collectPub(workspaceRoot) {
6471
6539
  name: entry.name,
6472
6540
  ecosystem: "pub",
6473
6541
  project: projectOf(relativePath),
6474
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6542
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath),
6475
6543
  section: block === "dependencies" ? "dep" : "devDep",
6476
6544
  spec: entry.spec,
6477
6545
  rewritable: entry.spec !== ""
@@ -6521,11 +6589,11 @@ function stripQuotes(value) {
6521
6589
  }
6522
6590
  function collectNuget(workspaceRoot) {
6523
6591
  const sites = [];
6524
- const csprojPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6592
+ const csprojPaths = (0, import_node_fs27.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6525
6593
  for (const relativePath of csprojPaths) {
6526
6594
  let content;
6527
6595
  try {
6528
- content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6596
+ content = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8");
6529
6597
  } catch {
6530
6598
  continue;
6531
6599
  }
@@ -6534,7 +6602,7 @@ function collectNuget(workspaceRoot) {
6534
6602
  name: entry.name,
6535
6603
  ecosystem: "nuget",
6536
6604
  project: projectOf(relativePath),
6537
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6605
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath),
6538
6606
  section: "dep",
6539
6607
  spec: entry.spec,
6540
6608
  // A plain SemVer string is rewritable; an MSBuild property reference
@@ -6559,13 +6627,13 @@ function csprojPackageReferences(content) {
6559
6627
  return entries;
6560
6628
  }
6561
6629
  function collectGo(workspaceRoot) {
6562
- const manifestPath = (0, import_node_path27.join)(workspaceRoot, "go.mod");
6630
+ const manifestPath = (0, import_node_path29.join)(workspaceRoot, "go.mod");
6563
6631
  if (!fileExists(manifestPath)) {
6564
6632
  return [];
6565
6633
  }
6566
6634
  let content;
6567
6635
  try {
6568
- content = (0, import_node_fs25.readFileSync)(manifestPath, "utf8");
6636
+ content = (0, import_node_fs27.readFileSync)(manifestPath, "utf8");
6569
6637
  } catch {
6570
6638
  return [];
6571
6639
  }
@@ -6614,7 +6682,7 @@ var PROJECT_GLOBS = {
6614
6682
  function locateProjects(workspaceRoot) {
6615
6683
  const locations = [];
6616
6684
  for (const ecosystem of ECOSYSTEMS) {
6617
- const relativePaths = (0, import_node_fs25.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6685
+ const relativePaths = (0, import_node_fs27.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6618
6686
  for (const relativePath of relativePaths) {
6619
6687
  const posix = toPosix(relativePath);
6620
6688
  const dir = posix.slice(0, posix.lastIndexOf("/"));
@@ -6622,7 +6690,7 @@ function locateProjects(workspaceRoot) {
6622
6690
  ecosystem,
6623
6691
  dir,
6624
6692
  name: dir.slice(dir.lastIndexOf("/") + 1),
6625
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath)
6693
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath)
6626
6694
  });
6627
6695
  }
6628
6696
  }
@@ -6643,7 +6711,7 @@ function rewriteSpec(site, spec) {
6643
6711
  writeFileEnsured(site.manifestPath, toJson(manifest));
6644
6712
  return true;
6645
6713
  }
6646
- const before = (0, import_node_fs25.readFileSync)(site.manifestPath, "utf8");
6714
+ const before = (0, import_node_fs27.readFileSync)(site.manifestPath, "utf8");
6647
6715
  const after = (() => {
6648
6716
  switch (site.ecosystem) {
6649
6717
  case "pip": {
@@ -6734,13 +6802,13 @@ function escapeForRegex(value) {
6734
6802
  function isWorkspaceProject(workspaceRoot, name) {
6735
6803
  const short = name.includes("/") ? name.split("/").at(-1) : name;
6736
6804
  return ["apps", "libs", "packages"].some(
6737
- (directory) => fileExists((0, import_node_path27.join)(workspaceRoot, directory, short ?? name, "package.json"))
6805
+ (directory) => fileExists((0, import_node_path29.join)(workspaceRoot, directory, short ?? name, "package.json"))
6738
6806
  );
6739
6807
  }
6740
6808
  function isAliasedInstall(workspaceRoot, name) {
6741
6809
  try {
6742
6810
  const installed = readJson(
6743
- (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6811
+ (0, import_node_path29.join)(workspaceRoot, "node_modules", name, "package.json")
6744
6812
  );
6745
6813
  return installed.name !== void 0 && installed.name !== name;
6746
6814
  } catch {
@@ -6751,14 +6819,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6751
6819
  if (ecosystem === "npm") {
6752
6820
  try {
6753
6821
  return readJson(
6754
- (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6822
+ (0, import_node_path29.join)(workspaceRoot, "node_modules", name, "package.json")
6755
6823
  ).version;
6756
6824
  } catch {
6757
6825
  return void 0;
6758
6826
  }
6759
6827
  }
6760
6828
  if (ecosystem === "pub") {
6761
- const lockPath = (0, import_node_path27.join)(workspaceRoot, "pubspec.lock");
6829
+ const lockPath = (0, import_node_path29.join)(workspaceRoot, "pubspec.lock");
6762
6830
  if (!fileExists(lockPath)) {
6763
6831
  return void 0;
6764
6832
  }
@@ -6766,7 +6834,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6766
6834
  const match = new RegExp(
6767
6835
  String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
6768
6836
  "m"
6769
- ).exec((0, import_node_fs25.readFileSync)(lockPath, "utf8"));
6837
+ ).exec((0, import_node_fs27.readFileSync)(lockPath, "utf8"));
6770
6838
  return match?.[1];
6771
6839
  } catch {
6772
6840
  return void 0;
@@ -6832,7 +6900,7 @@ function resolveTarget(locations, target) {
6832
6900
  return byName[0];
6833
6901
  }
6834
6902
  function installInto(workspaceRoot, location, packages, saveDev) {
6835
- const projectDir = (0, import_node_path28.join)(workspaceRoot, location.dir);
6903
+ const projectDir = (0, import_node_path30.join)(workspaceRoot, location.dir);
6836
6904
  switch (location.ecosystem) {
6837
6905
  case "npm": {
6838
6906
  const flags = saveDev ? ["--save-dev"] : [];
@@ -6885,7 +6953,7 @@ function installInto(workspaceRoot, location, packages, saveDev) {
6885
6953
  function addPythonDependency(manifestPath, specifier) {
6886
6954
  let content;
6887
6955
  try {
6888
- content = (0, import_node_fs26.readFileSync)(manifestPath, "utf8");
6956
+ content = (0, import_node_fs28.readFileSync)(manifestPath, "utf8");
6889
6957
  } catch {
6890
6958
  logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
6891
6959
  return;
@@ -6914,7 +6982,7 @@ function installEverything(workspaceRoot, only) {
6914
6982
  }
6915
6983
  function ecosystemPresent(workspaceRoot, ecosystem) {
6916
6984
  if (ecosystem === "go") {
6917
- return fileExists((0, import_node_path28.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path28.join)(workspaceRoot, "go.mod"));
6985
+ return fileExists((0, import_node_path30.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path30.join)(workspaceRoot, "go.mod"));
6918
6986
  }
6919
6987
  return hasEcosystem(workspaceRoot, ecosystem);
6920
6988
  }
@@ -6933,7 +7001,7 @@ function splitAtLast(value, separator) {
6933
7001
  }
6934
7002
 
6935
7003
  // src/dependency-management/sync-dependencies.use-case.ts
6936
- var import_node_path29 = require("path");
7004
+ var import_node_path31 = require("path");
6937
7005
 
6938
7006
  // src/dependency-management/semver.algorithm.ts
6939
7007
  var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
@@ -7110,7 +7178,7 @@ function describe(finding) {
7110
7178
  return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
7111
7179
  }
7112
7180
  function runSync(workspaceRoot, options) {
7113
- if (!fileExists((0, import_node_path29.join)(workspaceRoot, "nx.json"))) {
7181
+ if (!fileExists((0, import_node_path31.join)(workspaceRoot, "nx.json"))) {
7114
7182
  throw new Error(
7115
7183
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
7116
7184
  );
@@ -7160,7 +7228,7 @@ function runSync(workspaceRoot, options) {
7160
7228
  }
7161
7229
 
7162
7230
  // src/dependency-management/update-dependencies.use-case.ts
7163
- var import_node_path30 = require("path");
7231
+ var import_node_path32 = require("path");
7164
7232
  var import_prompts2 = require("@inquirer/prompts");
7165
7233
 
7166
7234
  // src/dependency-management/registry.client.ts
@@ -7443,7 +7511,7 @@ function reinstall(workspaceRoot, ecosystems) {
7443
7511
  function hasPythonInstallScript(workspaceRoot) {
7444
7512
  try {
7445
7513
  const manifest = readJson(
7446
- (0, import_node_path30.join)(workspaceRoot, "package.json")
7514
+ (0, import_node_path32.join)(workspaceRoot, "package.json")
7447
7515
  );
7448
7516
  return manifest.scripts?.["python:install"] !== void 0;
7449
7517
  } catch {
@@ -7459,7 +7527,7 @@ function applyGoUpdates(workspaceRoot, entries) {
7459
7527
  }
7460
7528
  }
7461
7529
  async function runUp(workspaceRoot, options) {
7462
- if (!fileExists((0, import_node_path30.join)(workspaceRoot, "nx.json"))) {
7530
+ if (!fileExists((0, import_node_path32.join)(workspaceRoot, "nx.json"))) {
7463
7531
  throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
7464
7532
  }
7465
7533
  const ecosystems = resolveEcosystems(options.ecosystem);
@@ -7536,7 +7604,7 @@ var PROJECT_KINDS = [
7536
7604
  var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
7537
7605
  async function runAdd(kind, name, options) {
7538
7606
  const workspaceRoot = process.cwd();
7539
- if (!fileExists((0, import_node_path31.join)(workspaceRoot, "nx.json"))) {
7607
+ if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
7540
7608
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
7541
7609
  }
7542
7610
  const stack = readWorkspaceStack(workspaceRoot);
@@ -7599,8 +7667,8 @@ async function runAdd(kind, name, options) {
7599
7667
  ],
7600
7668
  workspaceRoot
7601
7669
  );
7602
- markPrivate((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7603
- renameScaffoldPlaceholder((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7670
+ markPrivate((0, import_node_path33.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7671
+ renameScaffoldPlaceholder((0, import_node_path33.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7604
7672
  removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
7605
7673
  registerProjectCommands(workspaceRoot, resolvedName, { build: true });
7606
7674
  break;
@@ -7692,7 +7760,7 @@ async function runAdd(kind, name, options) {
7692
7760
  }
7693
7761
  function readWorkspaceStack(workspaceRoot) {
7694
7762
  const nxJson = readJson(
7695
- (0, import_node_path31.join)(workspaceRoot, "nx.json")
7763
+ (0, import_node_path33.join)(workspaceRoot, "nx.json")
7696
7764
  );
7697
7765
  const stack = nxJson.mnci?.stack;
7698
7766
  return {
@@ -7741,15 +7809,15 @@ function runKinds(options) {
7741
7809
 
7742
7810
  // src/workspace-diagnostics/check-invariants.use-case.ts
7743
7811
  var import_node_child_process = require("child_process");
7744
- var import_node_fs27 = require("fs");
7745
- var import_node_path32 = require("path");
7812
+ var import_node_fs29 = require("fs");
7813
+ var import_node_path34 = require("path");
7746
7814
  var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
7747
7815
  function toPosix2(path) {
7748
7816
  return path.replaceAll("\\", "/");
7749
7817
  }
7750
7818
  function checkEslintConfigs(workspaceRoot) {
7751
- const rootConfigs = (0, import_node_fs27.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7752
- const projectConfigs = (0, import_node_fs27.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7819
+ const rootConfigs = (0, import_node_fs29.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7820
+ const projectConfigs = (0, import_node_fs29.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7753
7821
  cwd: workspaceRoot
7754
7822
  }).map((config) => toPosix2(config));
7755
7823
  return [
@@ -7769,10 +7837,10 @@ function checkEslintConfigs(workspaceRoot) {
7769
7837
  ];
7770
7838
  }
7771
7839
  function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7772
- const rules = (0, import_node_path32.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7773
- if (!(0, import_node_fs27.existsSync)(rules)) return [];
7774
- const entryPoint = (0, import_node_path32.join)(workspaceRoot, ESLINT_USER_FILENAME);
7775
- const source = (0, import_node_fs27.existsSync)(entryPoint) ? (0, import_node_fs27.readFileSync)(entryPoint, "utf8") : "";
7840
+ const rules = (0, import_node_path34.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7841
+ if (!(0, import_node_fs29.existsSync)(rules)) return [];
7842
+ const entryPoint = (0, import_node_path34.join)(workspaceRoot, ESLINT_USER_FILENAME);
7843
+ const source = (0, import_node_fs29.existsSync)(entryPoint) ? (0, import_node_fs29.readFileSync)(entryPoint, "utf8") : "";
7776
7844
  return [
7777
7845
  {
7778
7846
  check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
@@ -7785,7 +7853,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7785
7853
  function declaredDevDependencies(workspaceRoot) {
7786
7854
  try {
7787
7855
  const manifest = readJson(
7788
- (0, import_node_path32.join)(workspaceRoot, "package.json")
7856
+ (0, import_node_path34.join)(workspaceRoot, "package.json")
7789
7857
  );
7790
7858
  return manifest.devDependencies ?? {};
7791
7859
  } catch {
@@ -7793,7 +7861,7 @@ function declaredDevDependencies(workspaceRoot) {
7793
7861
  }
7794
7862
  }
7795
7863
  function checkNoRetiredFormatter(workspaceRoot) {
7796
- const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file)));
7864
+ const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path34.join)(workspaceRoot, file)));
7797
7865
  const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
7798
7866
  const stale = [...files, ...declared];
7799
7867
  if (stale.length === 0) {
@@ -7819,7 +7887,7 @@ function checkEslintPlugin(nxJson) {
7819
7887
  };
7820
7888
  }
7821
7889
  function checkResolvedEslint(workspaceRoot) {
7822
- const manifestPath = (0, import_node_path32.join)(workspaceRoot, "node_modules/eslint/package.json");
7890
+ const manifestPath = (0, import_node_path34.join)(workspaceRoot, "node_modules/eslint/package.json");
7823
7891
  if (!fileExists(manifestPath)) {
7824
7892
  return void 0;
7825
7893
  }
@@ -7837,11 +7905,11 @@ function checkResolvedEslint(workspaceRoot) {
7837
7905
  }
7838
7906
  }
7839
7907
  function checkNpmrc(workspaceRoot, registry, scope) {
7840
- const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7908
+ const npmrcPath = (0, import_node_path34.join)(workspaceRoot, ".npmrc");
7841
7909
  if (!registry || !fileExists(npmrcPath)) {
7842
7910
  return void 0;
7843
7911
  }
7844
- const npmrc = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8");
7912
+ const npmrc = (0, import_node_fs29.readFileSync)(npmrcPath, "utf8");
7845
7913
  if (registry.kind === "npm") {
7846
7914
  return {
7847
7915
  check: ".npmrc authenticates the public registry",
@@ -7858,11 +7926,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
7858
7926
  };
7859
7927
  }
7860
7928
  function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
7861
- const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7929
+ const npmrcPath = (0, import_node_path34.join)(workspaceRoot, ".npmrc");
7862
7930
  if (!fileExists(npmrcPath)) {
7863
7931
  return void 0;
7864
7932
  }
7865
- const npmrc = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8");
7933
+ const npmrc = (0, import_node_fs29.readFileSync)(npmrcPath, "utf8");
7866
7934
  const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7867
7935
  const referenced = [
7868
7936
  ...new Set(
@@ -7886,13 +7954,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
7886
7954
  };
7887
7955
  }
7888
7956
  function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
7889
- const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7890
- const pipelinePath = (0, import_node_path32.join)(workspaceRoot, "azure-pipelines.yml");
7957
+ const npmrcPath = (0, import_node_path34.join)(workspaceRoot, ".npmrc");
7958
+ const pipelinePath = (0, import_node_path34.join)(workspaceRoot, "azure-pipelines.yml");
7891
7959
  if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
7892
7960
  return void 0;
7893
7961
  }
7894
- 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));
7895
- const runsTask = (0, import_node_fs27.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7962
+ const holdsCredentials = (0, import_node_fs29.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7963
+ const runsTask = (0, import_node_fs29.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7896
7964
  if (!holdsCredentials && !runsTask) {
7897
7965
  return {
7898
7966
  check: "npm auth: .npmrc and azure-pipelines.yml agree",
@@ -7937,13 +8005,13 @@ function npmjsCredentialShape(credentials, environment) {
7937
8005
  }
7938
8006
  function checkVersionActions(workspaceRoot) {
7939
8007
  const candidates = [
7940
- ...(0, import_node_fs27.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
7941
- ...(0, import_node_fs27.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
7942
- ...(0, import_node_fs27.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
8008
+ ...(0, import_node_fs29.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
8009
+ ...(0, import_node_fs29.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
8010
+ ...(0, import_node_fs29.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
7943
8011
  ].map((manifest) => toPosix2(manifest));
7944
8012
  return candidates.flatMap((manifest) => {
7945
8013
  const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
7946
- const projectJsonPath = (0, import_node_path32.join)(workspaceRoot, projectRoot, "project.json");
8014
+ const projectJsonPath = (0, import_node_path34.join)(workspaceRoot, projectRoot, "project.json");
7947
8015
  let hasOverride = false;
7948
8016
  try {
7949
8017
  const projectJson = readJson(projectJsonPath);
@@ -7972,7 +8040,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
7972
8040
  ]) {
7973
8041
  try {
7974
8042
  const targets = extract(
7975
- readJson((0, import_node_path32.join)(workspaceRoot, projectRoot, file))
8043
+ readJson((0, import_node_path34.join)(workspaceRoot, projectRoot, file))
7976
8044
  );
7977
8045
  if (targets && typeof targets === "object") {
7978
8046
  sources.push({
@@ -7988,8 +8056,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
7988
8056
  function checkTargetFilesExist(workspaceRoot) {
7989
8057
  const projectRoots = new Set(
7990
8058
  [
7991
- ...(0, import_node_fs27.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
7992
- ...(0, import_node_fs27.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
8059
+ ...(0, import_node_fs29.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
8060
+ ...(0, import_node_fs29.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
7993
8061
  ].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
7994
8062
  );
7995
8063
  return [...projectRoots].flatMap(
@@ -8004,7 +8072,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
8004
8072
  return TARGET_FILE_OPTIONS.flatMap((option) => {
8005
8073
  const value = target?.options?.[option];
8006
8074
  const checkable = typeof value === "string" && !value.includes("{");
8007
- if (!checkable || fileExists((0, import_node_path32.join)(workspaceRoot, value))) {
8075
+ if (!checkable || fileExists((0, import_node_path34.join)(workspaceRoot, value))) {
8008
8076
  return [];
8009
8077
  }
8010
8078
  return [
@@ -8043,15 +8111,15 @@ function checkGoPluginRegistered(workspaceRoot) {
8043
8111
  };
8044
8112
  }
8045
8113
  function checkGoWorkInSync(workspaceRoot) {
8046
- const goWorkPath = (0, import_node_path32.join)(workspaceRoot, "go.work");
8114
+ const goWorkPath = (0, import_node_path34.join)(workspaceRoot, "go.work");
8047
8115
  if (!fileExists(goWorkPath)) {
8048
8116
  return void 0;
8049
8117
  }
8050
- const contents = (0, import_node_fs27.existsSync)(goWorkPath) ? (0, import_node_fs27.readFileSync)(goWorkPath, "utf8") : "";
8118
+ const contents = (0, import_node_fs29.existsSync)(goWorkPath) ? (0, import_node_fs29.readFileSync)(goWorkPath, "utf8") : "";
8051
8119
  const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
8052
8120
  const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
8053
8121
  const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
8054
- const stale = uses.filter((entry) => !(0, import_node_fs27.existsSync)((0, import_node_path32.join)(workspaceRoot, entry, "go.mod")));
8122
+ const stale = uses.filter((entry) => !(0, import_node_fs29.existsSync)((0, import_node_path34.join)(workspaceRoot, entry, "go.mod")));
8055
8123
  return {
8056
8124
  check: "every go.work `use` entry points to a module that still exists",
8057
8125
  ok: stale.length === 0,
@@ -8067,9 +8135,9 @@ function checkNativeApps(workspaceRoot) {
8067
8135
  { file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
8068
8136
  { file: "azure-pipelines.yml", marker: "- job: native" }
8069
8137
  ];
8070
- const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).map(({ file, marker }) => ({
8138
+ const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path34.join)(workspaceRoot, file))).map(({ file, marker }) => ({
8071
8139
  check: `${file} builds the native apps on every OS`,
8072
- ok: (0, import_node_fs27.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8").includes(marker),
8140
+ ok: (0, import_node_fs29.readFileSync)((0, import_node_path34.join)(workspaceRoot, file), "utf8").includes(marker),
8073
8141
  detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
8074
8142
  remedy: "run `mnci upgrade`"
8075
8143
  }));
@@ -8082,7 +8150,7 @@ function checkNativeApps(workspaceRoot) {
8082
8150
  return findings;
8083
8151
  }
8084
8152
  function checkNoRootRuntimeDependencies(workspaceRoot) {
8085
- const manifestPath = (0, import_node_path32.join)(workspaceRoot, "package.json");
8153
+ const manifestPath = (0, import_node_path34.join)(workspaceRoot, "package.json");
8086
8154
  if (!fileExists(manifestPath)) {
8087
8155
  return void 0;
8088
8156
  }
@@ -8102,14 +8170,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
8102
8170
  };
8103
8171
  }
8104
8172
  function checkRollupSourceMaps(workspaceRoot) {
8105
- const configs = (0, import_node_fs27.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8173
+ const configs = (0, import_node_fs29.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8106
8174
  cwd: workspaceRoot
8107
8175
  }).map((config) => toPosix2(config));
8108
8176
  return configs.flatMap((relativePath) => {
8109
- const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
8177
+ const configPath = (0, import_node_path34.join)(workspaceRoot, relativePath);
8110
8178
  let config;
8111
8179
  try {
8112
- config = (0, import_node_fs27.readFileSync)(configPath, "utf8");
8180
+ config = (0, import_node_fs29.readFileSync)(configPath, "utf8");
8113
8181
  } catch {
8114
8182
  return [];
8115
8183
  }
@@ -8124,11 +8192,11 @@ function checkRollupSourceMaps(workspaceRoot) {
8124
8192
  });
8125
8193
  }
8126
8194
  function checkDeclarationSpecifiers(workspaceRoot) {
8127
- const configs = (0, import_node_fs27.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8195
+ const configs = (0, import_node_fs29.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8128
8196
  cwd: workspaceRoot
8129
8197
  }).map((config) => toPosix2(config));
8130
8198
  return configs.flatMap((relativePath) => {
8131
- const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
8199
+ const configPath = (0, import_node_path34.join)(workspaceRoot, relativePath);
8132
8200
  if (!fileExists(configPath)) {
8133
8201
  return [];
8134
8202
  }
@@ -8163,8 +8231,8 @@ function checkDeclarationSpecifiers(workspaceRoot) {
8163
8231
  }
8164
8232
  function checkPipelinePhases(workspaceRoot) {
8165
8233
  const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
8166
- return files.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).flatMap((file) => {
8167
- const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs27.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8"));
8234
+ return files.filter((file) => fileExists((0, import_node_path34.join)(workspaceRoot, file))).flatMap((file) => {
8235
+ const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs29.readFileSync)((0, import_node_path34.join)(workspaceRoot, file), "utf8"));
8168
8236
  const verify = {
8169
8237
  check: `${file} runs the enforced verify phase`,
8170
8238
  ok: verifyActive,
@@ -8204,8 +8272,19 @@ function checkDependencyRangesNotPreserved(nxJson) {
8204
8272
  remedy: "run `mnci upgrade`, or set release.version.preserveMatchingDependencyRanges to false in nx.json"
8205
8273
  };
8206
8274
  }
8275
+ function checkLockfileHasNoLocalRegistry(workspaceRoot) {
8276
+ if (!fileExists((0, import_node_path34.join)(workspaceRoot, "package-lock.json"))) {
8277
+ return void 0;
8278
+ }
8279
+ return {
8280
+ check: "package-lock.json carries no unused local registry (verdaccio)",
8281
+ ok: !hasStaleLocalRegistry(workspaceRoot),
8282
+ detail: "package-lock.json still holds verdaccio and its chain, which no manifest declares; npm audit reports high advisories (braces has no patched release) on packages nothing uses",
8283
+ remedy: "run `mnci upgrade`, which removes it, then commit package-lock.json"
8284
+ };
8285
+ }
8207
8286
  function collectFindings(workspaceRoot) {
8208
- const nxJsonPath = (0, import_node_path32.join)(workspaceRoot, "nx.json");
8287
+ const nxJsonPath = (0, import_node_path34.join)(workspaceRoot, "nx.json");
8209
8288
  if (!fileExists(nxJsonPath)) {
8210
8289
  throw new Error(
8211
8290
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
@@ -8231,7 +8310,8 @@ function collectFindings(workspaceRoot) {
8231
8310
  ...checkNativeApps(workspaceRoot),
8232
8311
  ...checkPipelinePhases(workspaceRoot),
8233
8312
  ...checkNativeBuildConfig(workspaceRoot),
8234
- checkDependencyRangesNotPreserved(nxJson)
8313
+ checkDependencyRangesNotPreserved(nxJson),
8314
+ checkLockfileHasNoLocalRegistry(workspaceRoot)
8235
8315
  ].filter((finding) => finding !== void 0);
8236
8316
  }
8237
8317
  function runDoctor(workspaceRoot, options = {}) {
@@ -8337,11 +8417,11 @@ function runCommands(program, options) {
8337
8417
  }
8338
8418
 
8339
8419
  // src/workspace-info/list-projects.use-case.ts
8340
- var import_node_path33 = require("path");
8420
+ var import_node_path35 = require("path");
8341
8421
  var TYPE_TAG_PREFIX = "type:";
8342
8422
  function listProjects(workspaceRoot) {
8343
8423
  return locateProjects(workspaceRoot).map((location) => {
8344
- const projectJsonPath = (0, import_node_path33.join)(workspaceRoot, location.dir, "project.json");
8424
+ const projectJsonPath = (0, import_node_path35.join)(workspaceRoot, location.dir, "project.json");
8345
8425
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
8346
8426
  const typeTag = (project.tags ?? []).find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
8347
8427
  return {
@@ -8354,7 +8434,7 @@ function listProjects(workspaceRoot) {
8354
8434
  }).toSorted((a, b) => a.dir.localeCompare(b.dir));
8355
8435
  }
8356
8436
  function runProjects(workspaceRoot, options) {
8357
- if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
8437
+ if (!fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"))) {
8358
8438
  throw new Error("No nx.json found here. Run `projects` from the workspace root.");
8359
8439
  }
8360
8440
  const projects = listProjects(workspaceRoot);
@@ -8368,11 +8448,11 @@ function runProjects(workspaceRoot, options) {
8368
8448
  }
8369
8449
 
8370
8450
  // src/workspace-info/read-workspace-info.use-case.ts
8371
- var import_node_path35 = require("path");
8451
+ var import_node_path37 = require("path");
8372
8452
 
8373
8453
  // src/cli-version/check-for-update.use-case.ts
8374
- var import_node_fs28 = require("fs");
8375
- var import_node_path34 = require("path");
8454
+ var import_node_fs30 = require("fs");
8455
+ var import_node_path36 = require("path");
8376
8456
  var import_cross_spawn3 = __toESM(require("cross-spawn"));
8377
8457
  var PACKAGE_NAME2 = "@mnci/cli";
8378
8458
  var REGISTRY_TIMEOUT_MS = 2e3;
@@ -8431,8 +8511,8 @@ function releaseTriple(version) {
8431
8511
  }
8432
8512
  function readCliVersion(packageDirectory) {
8433
8513
  try {
8434
- const manifestPath = (0, import_node_path34.join)(packageDirectory, "..", "package.json");
8435
- const manifest = JSON.parse((0, import_node_fs28.readFileSync)(manifestPath, "utf8"));
8514
+ const manifestPath = (0, import_node_path36.join)(packageDirectory, "..", "package.json");
8515
+ const manifest = JSON.parse((0, import_node_fs30.readFileSync)(manifestPath, "utf8"));
8436
8516
  return manifest.version ?? "0.0.0";
8437
8517
  } catch {
8438
8518
  return "0.0.0";
@@ -8442,7 +8522,7 @@ function readCliVersion(packageDirectory) {
8442
8522
  // src/workspace-info/read-workspace-info.use-case.ts
8443
8523
  function readWorkspaceInfo(workspaceRoot, cliVersion) {
8444
8524
  const latest = fetchLatestVersion() ?? null;
8445
- const isWorkspace = fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"));
8525
+ const isWorkspace = fileExists((0, import_node_path37.join)(workspaceRoot, "nx.json"));
8446
8526
  return {
8447
8527
  cli: {
8448
8528
  version: cliVersion,
@@ -8463,8 +8543,8 @@ function runInfo(workspaceRoot, cliVersion, options) {
8463
8543
  }
8464
8544
 
8465
8545
  // src/workspace-creation/adopt-directory.use-case.ts
8466
- var import_node_fs29 = require("fs");
8467
- var import_node_path36 = require("path");
8546
+ var import_node_fs31 = require("fs");
8547
+ var import_node_path38 = require("path");
8468
8548
  var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
8469
8549
  var AGENT_AND_CI_ENTRIES = [
8470
8550
  "AGENTS.md",
@@ -8495,13 +8575,13 @@ var PREFLIGHT_BLOCKERS = [
8495
8575
  "packages"
8496
8576
  ];
8497
8577
  function assertAdoptableDirectory(target) {
8498
- if (!(0, import_node_fs29.existsSync)(target)) {
8578
+ if (!(0, import_node_fs31.existsSync)(target)) {
8499
8579
  throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
8500
8580
  }
8501
- if (!(0, import_node_fs29.statSync)(target).isDirectory()) {
8581
+ if (!(0, import_node_fs31.statSync)(target).isDirectory()) {
8502
8582
  throw new Error(`--into '${target}' is not a directory.`);
8503
8583
  }
8504
- const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs29.existsSync)((0, import_node_path36.join)(target, entry)));
8584
+ const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs31.existsSync)((0, import_node_path38.join)(target, entry)));
8505
8585
  if (blockers.length > 0) {
8506
8586
  throw new Error(
8507
8587
  `--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.`
@@ -8509,15 +8589,15 @@ function assertAdoptableDirectory(target) {
8509
8589
  }
8510
8590
  }
8511
8591
  function mergeGitignore(generatedFile, targetFile) {
8512
- const existing = (0, import_node_fs29.readFileSync)(targetFile, "utf8");
8592
+ const existing = (0, import_node_fs31.readFileSync)(targetFile, "utf8");
8513
8593
  const present = new Set(existing.split("\n").map((line) => line.trim()));
8514
- const additions = (0, import_node_fs29.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8594
+ const additions = (0, import_node_fs31.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8515
8595
  const trimmed = line.trim();
8516
8596
  return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
8517
8597
  });
8518
8598
  if (additions.length === 0) return false;
8519
8599
  const separator = existing.endsWith("\n") ? "" : "\n";
8520
- (0, import_node_fs29.writeFileSync)(
8600
+ (0, import_node_fs31.writeFileSync)(
8521
8601
  targetFile,
8522
8602
  `${existing}${separator}
8523
8603
  # Added by mnci (Nx workspace)
@@ -8527,9 +8607,9 @@ ${additions.join("\n")}
8527
8607
  return true;
8528
8608
  }
8529
8609
  function adoptGeneratedWorkspace(generatedRoot, target) {
8530
- const entries = (0, import_node_fs29.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8610
+ const entries = (0, import_node_fs31.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8531
8611
  const collisions = entries.filter(
8532
- (entry) => (0, import_node_fs29.existsSync)((0, import_node_path36.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8612
+ (entry) => (0, import_node_fs31.existsSync)((0, import_node_path38.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8533
8613
  );
8534
8614
  if (collisions.length > 0) {
8535
8615
  throw new Error(
@@ -8538,28 +8618,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
8538
8618
  }
8539
8619
  const result = { copied: [], kept: [], mergedGitignore: false };
8540
8620
  for (const entry of entries) {
8541
- const from = (0, import_node_path36.join)(generatedRoot, entry);
8542
- const to = (0, import_node_path36.join)(target, entry);
8543
- if (entry === ".gitignore" && (0, import_node_fs29.existsSync)(to)) {
8621
+ const from = (0, import_node_path38.join)(generatedRoot, entry);
8622
+ const to = (0, import_node_path38.join)(target, entry);
8623
+ if (entry === ".gitignore" && (0, import_node_fs31.existsSync)(to)) {
8544
8624
  result.mergedGitignore = mergeGitignore(from, to);
8545
8625
  result.kept.push(entry);
8546
8626
  continue;
8547
8627
  }
8548
- if ((0, import_node_fs29.existsSync)(to)) {
8628
+ if ((0, import_node_fs31.existsSync)(to)) {
8549
8629
  result.kept.push(entry);
8550
8630
  continue;
8551
8631
  }
8552
- (0, import_node_fs29.cpSync)(from, to, { recursive: true });
8632
+ (0, import_node_fs31.cpSync)(from, to, { recursive: true });
8553
8633
  result.copied.push(entry);
8554
8634
  }
8555
- (0, import_node_fs29.rmSync)(generatedRoot, { recursive: true, force: true });
8635
+ (0, import_node_fs31.rmSync)(generatedRoot, { recursive: true, force: true });
8556
8636
  return result;
8557
8637
  }
8558
8638
 
8559
8639
  // src/workspace-creation/create-workspace.use-case.ts
8560
- var import_node_fs30 = require("fs");
8640
+ var import_node_fs32 = require("fs");
8561
8641
  var import_node_os2 = require("os");
8562
- var import_node_path37 = require("path");
8642
+ var import_node_path39 = require("path");
8563
8643
  function nxCloudProviderValue(ci) {
8564
8644
  return ci === "azure" ? "azure" : "github";
8565
8645
  }
@@ -8602,9 +8682,9 @@ async function resolveRegistry(options) {
8602
8682
  return await promptRegistry();
8603
8683
  }
8604
8684
  async function runNew(name, options) {
8605
- const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path37.resolve)(process.cwd(), options.into);
8685
+ const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path39.resolve)(process.cwd(), options.into);
8606
8686
  if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
8607
- const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path37.basename)(adoptTarget));
8687
+ const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path39.basename)(adoptTarget));
8608
8688
  assertValidProjectName(workspaceName, "Workspace name");
8609
8689
  const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
8610
8690
  const registry = await resolveRegistry(options);
@@ -8617,8 +8697,8 @@ async function runNew(name, options) {
8617
8697
  const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
8618
8698
  const stack = await resolveStack(options);
8619
8699
  const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
8620
- const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs30.mkdtempSync)((0, import_node_path37.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8621
- let workspaceRoot = (0, import_node_path37.join)(stagingParent, workspaceName);
8700
+ const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs32.mkdtempSync)((0, import_node_path39.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8701
+ let workspaceRoot = (0, import_node_path39.join)(stagingParent, workspaceName);
8622
8702
  try {
8623
8703
  logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
8624
8704
  runNpx(
@@ -8641,7 +8721,7 @@ async function runNew(name, options) {
8641
8721
  workspaceRoot = adoptTarget;
8642
8722
  }
8643
8723
  } finally {
8644
- if (adoptTarget !== void 0) (0, import_node_fs30.rmSync)(stagingParent, { recursive: true, force: true });
8724
+ if (adoptTarget !== void 0) (0, import_node_fs32.rmSync)(stagingParent, { recursive: true, force: true });
8645
8725
  }
8646
8726
  logger.step(
8647
8727
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
@@ -8651,8 +8731,8 @@ async function runNew(name, options) {
8651
8731
  { workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
8652
8732
  logger.detail
8653
8733
  );
8654
- (0, import_node_fs30.rmSync)((0, import_node_path37.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8655
- (0, import_node_fs30.rmSync)((0, import_node_path37.join)(workspaceRoot, "package-lock.json"), { force: true });
8734
+ (0, import_node_fs32.rmSync)((0, import_node_path39.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8735
+ (0, import_node_fs32.rmSync)((0, import_node_path39.join)(workspaceRoot, "package-lock.json"), { force: true });
8656
8736
  logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
8657
8737
  const installStatus = runShell(
8658
8738
  "npm",
@@ -8690,12 +8770,12 @@ function projectKindHintLines(kinds = PROJECT_KINDS) {
8690
8770
  }
8691
8771
 
8692
8772
  // src/workspace-creation/interactive-wizard.use-case.ts
8693
- var import_node_path39 = require("path");
8773
+ var import_node_path41 = require("path");
8694
8774
  var import_prompts4 = require("@inquirer/prompts");
8695
8775
 
8696
8776
  // src/workspace-upgrade/upgrade-workspace.use-case.ts
8697
- var import_node_fs31 = require("fs");
8698
- var import_node_path38 = require("path");
8777
+ var import_node_fs33 = require("fs");
8778
+ var import_node_path40 = require("path");
8699
8779
  function resolveRegistry2(options, persisted) {
8700
8780
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
8701
8781
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -8724,7 +8804,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8724
8804
  return persisted.workspaceName;
8725
8805
  }
8726
8806
  try {
8727
- const existing = (0, import_node_fs31.readdirSync)(workspaceRoot).find(
8807
+ const existing = (0, import_node_fs33.readdirSync)(workspaceRoot).find(
8728
8808
  (file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
8729
8809
  );
8730
8810
  if (existing) {
@@ -8732,11 +8812,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8732
8812
  }
8733
8813
  } catch {
8734
8814
  }
8735
- return (0, import_node_path38.basename)(workspaceRoot);
8815
+ return (0, import_node_path40.basename)(workspaceRoot);
8736
8816
  }
8737
8817
  function detectNpmAuth(workspaceRoot) {
8738
8818
  try {
8739
- return (0, import_node_fs31.readFileSync)((0, import_node_path38.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8819
+ return (0, import_node_fs33.readFileSync)((0, import_node_path40.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8740
8820
  } catch {
8741
8821
  return void 0;
8742
8822
  }
@@ -8783,7 +8863,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
8783
8863
  };
8784
8864
  }
8785
8865
  function runUpgrade(workspaceRoot, options) {
8786
- if (!fileExists((0, import_node_path38.join)(workspaceRoot, "nx.json"))) {
8866
+ if (!fileExists((0, import_node_path40.join)(workspaceRoot, "nx.json"))) {
8787
8867
  throw new Error(
8788
8868
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
8789
8869
  );
@@ -8806,6 +8886,13 @@ function runUpgrade(workspaceRoot, options) {
8806
8886
  logger.detail(`updated ${path}`);
8807
8887
  }
8808
8888
  }
8889
+ const lockfile = pruneStaleLocalRegistry(workspaceRoot);
8890
+ if (lockfile.stale) {
8891
+ logger.step("Dropping the unused local registry (verdaccio) from package-lock.json");
8892
+ if (lockfile.status !== 0) {
8893
+ logger.warn("npm could not re-resolve the lockfile; run `npm install --package-lock-only` once you are online.");
8894
+ }
8895
+ }
8809
8896
  const goApps = addGoPlatformTargets(workspaceRoot);
8810
8897
  if (goApps.length > 0) {
8811
8898
  logger.step("Adding the six-platform build to Go apps (build-all, package-all)");
@@ -8849,7 +8936,7 @@ function runUpgrade(workspaceRoot, options) {
8849
8936
 
8850
8937
  // src/workspace-creation/interactive-wizard.use-case.ts
8851
8938
  async function runInteractive() {
8852
- const inWorkspace = fileExists((0, import_node_path39.join)(process.cwd(), "nx.json"));
8939
+ const inWorkspace = fileExists((0, import_node_path41.join)(process.cwd(), "nx.json"));
8853
8940
  const choiceNew = { name: "Create a new monorepo", value: "new" };
8854
8941
  const choiceAdd = { name: "Add a project to this workspace", value: "add" };
8855
8942
  const choiceUpgrade = {