@mnci/cli 4.40.1 → 4.40.3

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,7 +283,17 @@ function classifyNpmAudit(report) {
283
283
  });
284
284
  return { blocking, total: all.length, notes };
285
285
  }
286
- function auditNpm(result, log) {
286
+ function planIsEmpty(stdout) {
287
+ try {
288
+ const start = stdout.search(/^\{/m);
289
+ 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);
292
+ } catch {
293
+ return false;
294
+ }
295
+ }
296
+ function auditNpm(result, dryRun, log) {
287
297
  let report;
288
298
  try {
289
299
  report = JSON.parse(result.stdout);
@@ -299,6 +309,13 @@ function auditNpm(result, log) {
299
309
  log(`npm audit - ${total} advisory(ies), none actionable at moderate or above.`);
300
310
  return 0;
301
311
  }
312
+ if (planIsEmpty(dryRun().stdout)) {
313
+ for (const advisory of blocking) {
314
+ log(` note [${advisory.severity}] ${advisory.name} - npm reports a fix, but npm audit fix has nothing to apply`);
315
+ }
316
+ log(`npm audit - ${total} advisory(ies); ${blocking.length} reported as fixable, but no patched release is reachable, so there is nothing to do here.`);
317
+ return 0;
318
+ }
302
319
  for (const advisory of blocking) {
303
320
  log(` BLOCKING [${advisory.severity}] ${advisory.name} - fix available`);
304
321
  }
@@ -325,7 +342,7 @@ function runAudit(workspaceRoot, dependencies = {}) {
325
342
  }
326
343
  };
327
344
  log(groupStart(host, "npm audit"));
328
- const npm = auditNpm(processes.capture("npm", ["audit", "--json"]), log);
345
+ const npm = auditNpm(processes.capture("npm", ["audit", "--json"]), () => processes.capture("npm", ["audit", "fix", "--dry-run", "--json"]), log);
329
346
  closeGroup();
330
347
  if (npm !== 0) {
331
348
  return npm;
@@ -3151,7 +3168,7 @@ function runPhase(phase, workspaceRoot, dependencies) {
3151
3168
  }
3152
3169
 
3153
3170
  // src/project-scaffolding/add-project.use-case.ts
3154
- var import_node_path31 = require("path");
3171
+ var import_node_path33 = require("path");
3155
3172
  var import_prompts3 = require("@inquirer/prompts");
3156
3173
 
3157
3174
  // src/project-name/project-name.validator.ts
@@ -5059,11 +5076,65 @@ function addNodeFunctionApp(workspaceRoot, name, stack, empty = false) {
5059
5076
  }
5060
5077
 
5061
5078
  // src/project-scaffolding/npm-lib.use-case.ts
5062
- var import_node_path22 = require("path");
5079
+ var import_node_path24 = require("path");
5063
5080
 
5064
- // src/rollup-library/repair-publishable-manifest.use-case.ts
5081
+ // src/lockfile-pruning/prune-stale-local-registry.use-case.ts
5082
+ var import_node_fs20 = require("fs");
5083
+ var import_node_path20 = require("path");
5084
+
5085
+ // src/lockfile-pruning/stale-local-registry.validator.ts
5065
5086
  var import_node_fs19 = require("fs");
5066
5087
  var import_node_path19 = require("path");
5088
+ var LOCAL_REGISTRY_PACKAGE = "verdaccio";
5089
+ var LOCAL_REGISTRY_LOCK_KEY = `node_modules/${LOCAL_REGISTRY_PACKAGE}`;
5090
+ var DEPENDENCY_FIELDS = ["dependencies", "devDependencies", "optionalDependencies", "peerDependencies"];
5091
+ function readJsonFile(path) {
5092
+ if (!(0, import_node_fs19.existsSync)(path)) {
5093
+ return void 0;
5094
+ }
5095
+ try {
5096
+ return JSON.parse((0, import_node_fs19.readFileSync)(path, "utf8"));
5097
+ } catch {
5098
+ return void 0;
5099
+ }
5100
+ }
5101
+ function declaresLocalRegistry(manifest) {
5102
+ return DEPENDENCY_FIELDS.some((field) => {
5103
+ const list = manifest?.[field];
5104
+ return list !== void 0 && Object.hasOwn(list, LOCAL_REGISTRY_PACKAGE);
5105
+ });
5106
+ }
5107
+ function hasStaleLocalRegistry(workspaceRoot) {
5108
+ const lock = readJsonFile((0, import_node_path19.join)(workspaceRoot, "package-lock.json"));
5109
+ const entries = lock?.packages ?? {};
5110
+ if (!Object.hasOwn(entries, LOCAL_REGISTRY_LOCK_KEY)) {
5111
+ return false;
5112
+ }
5113
+ const members = Object.keys(entries).filter((key) => key !== "" && !key.startsWith("node_modules/") && !key.includes("/node_modules/"));
5114
+ const manifests = ["", ...members].map((directory) => readJsonFile((0, import_node_path19.join)(workspaceRoot, directory, "package.json")));
5115
+ return manifests.every((manifest) => !declaresLocalRegistry(manifest));
5116
+ }
5117
+
5118
+ // src/lockfile-pruning/prune-stale-local-registry.use-case.ts
5119
+ function pruneStaleLocalRegistry(workspaceRoot, resolve2 = runShell) {
5120
+ if (!hasStaleLocalRegistry(workspaceRoot)) {
5121
+ return { stale: false, status: 0 };
5122
+ }
5123
+ const lockPath = (0, import_node_path20.join)(workspaceRoot, "package-lock.json");
5124
+ const lock = JSON.parse((0, import_node_fs20.readFileSync)(lockPath, "utf8"));
5125
+ Reflect.deleteProperty(lock.packages, LOCAL_REGISTRY_LOCK_KEY);
5126
+ const root = lock.packages[""];
5127
+ if (root?.devDependencies !== void 0) {
5128
+ Reflect.deleteProperty(root.devDependencies, LOCAL_REGISTRY_PACKAGE);
5129
+ }
5130
+ (0, import_node_fs20.writeFileSync)(lockPath, `${JSON.stringify(lock, void 0, 2)}
5131
+ `);
5132
+ return { stale: true, status: resolve2("npm", ["install", "--package-lock-only", "--ignore-scripts", "--no-audit", "--no-fund"], workspaceRoot) };
5133
+ }
5134
+
5135
+ // src/rollup-library/repair-publishable-manifest.use-case.ts
5136
+ var import_node_fs21 = require("fs");
5137
+ var import_node_path21 = require("path");
5067
5138
  var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
5068
5139
  var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
5069
5140
  var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
@@ -5086,14 +5157,14 @@ function repairPublishableManifest(manifestPath) {
5086
5157
  }
5087
5158
  function repairPublishableManifests(workspaceRoot) {
5088
5159
  const changed = [];
5089
- const manifests = (0, import_node_fs19.globSync)(["packages/*/package.json", "libs/*/package.json"], {
5160
+ const manifests = (0, import_node_fs21.globSync)(["packages/*/package.json", "libs/*/package.json"], {
5090
5161
  cwd: workspaceRoot
5091
5162
  });
5092
5163
  for (const relativePath of manifests) {
5093
- const manifestPath = (0, import_node_path19.join)(workspaceRoot, relativePath);
5094
- const before = (0, import_node_fs19.readFileSync)(manifestPath, "utf8");
5164
+ const manifestPath = (0, import_node_path21.join)(workspaceRoot, relativePath);
5165
+ const before = (0, import_node_fs21.readFileSync)(manifestPath, "utf8");
5095
5166
  repairPublishableManifest(manifestPath);
5096
- const after = (0, import_node_fs19.readFileSync)(manifestPath, "utf8");
5167
+ const after = (0, import_node_fs21.readFileSync)(manifestPath, "utf8");
5097
5168
  if (after !== before) {
5098
5169
  changed.push(relativePath.replaceAll("\\", "/"));
5099
5170
  }
@@ -5102,8 +5173,8 @@ function repairPublishableManifests(workspaceRoot) {
5102
5173
  }
5103
5174
 
5104
5175
  // src/rollup-library/repair-rollup-config.use-case.ts
5105
- var import_node_fs20 = require("fs");
5106
- var import_node_path20 = require("path");
5176
+ var import_node_fs22 = require("fs");
5177
+ var import_node_path22 = require("path");
5107
5178
 
5108
5179
  // src/rollup-library/rollup-config.algorithm.ts
5109
5180
  var ROLLUP_CONFIG_PLACEHOLDER = [
@@ -5305,12 +5376,12 @@ function withUpgradedDeclarationSpecifierPlugin(config) {
5305
5376
  // src/rollup-library/repair-rollup-config.use-case.ts
5306
5377
  function repairRollupSourceMaps(workspaceRoot) {
5307
5378
  const changed = [];
5308
- const configs = (0, import_node_fs20.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5379
+ const configs = (0, import_node_fs22.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5309
5380
  cwd: workspaceRoot
5310
5381
  });
5311
5382
  for (const relativePath of configs) {
5312
- const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5313
- const before = (0, import_node_fs20.readFileSync)(configPath, "utf8");
5383
+ const configPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
5384
+ const before = (0, import_node_fs22.readFileSync)(configPath, "utf8");
5314
5385
  const after = withRollupSourceMaps(before);
5315
5386
  if (after !== before) {
5316
5387
  writeFileEnsured(configPath, after);
@@ -5321,12 +5392,12 @@ function repairRollupSourceMaps(workspaceRoot) {
5321
5392
  }
5322
5393
  function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
5323
5394
  const changed = [];
5324
- const configs = (0, import_node_fs20.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5395
+ const configs = (0, import_node_fs22.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
5325
5396
  cwd: workspaceRoot
5326
5397
  });
5327
5398
  for (const relativePath of configs) {
5328
- const configPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
5329
- const before = (0, import_node_fs20.readFileSync)(configPath, "utf8");
5399
+ const configPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
5400
+ const before = (0, import_node_fs22.readFileSync)(configPath, "utf8");
5330
5401
  const after = withUpgradedDeclarationSpecifierPlugin(before);
5331
5402
  if (after !== before) {
5332
5403
  writeFileEnsured(configPath, after);
@@ -5336,11 +5407,11 @@ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
5336
5407
  return changed;
5337
5408
  }
5338
5409
  function repairDeclarationSpecifiers(projectRoot) {
5339
- const configPath = (0, import_node_path20.join)(projectRoot, "rollup.config.cjs");
5410
+ const configPath = (0, import_node_path22.join)(projectRoot, "rollup.config.cjs");
5340
5411
  if (!fileExists(configPath)) {
5341
5412
  return;
5342
5413
  }
5343
- const config = (0, import_node_fs20.readFileSync)(configPath, "utf8");
5414
+ const config = (0, import_node_fs22.readFileSync)(configPath, "utf8");
5344
5415
  if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
5345
5416
  return;
5346
5417
  }
@@ -5349,10 +5420,10 @@ function repairDeclarationSpecifiers(projectRoot) {
5349
5420
  }
5350
5421
 
5351
5422
  // src/rollup-library/rollup-config.repository.ts
5352
- var import_node_fs21 = require("fs");
5353
- var import_node_path21 = require("path");
5423
+ var import_node_fs23 = require("fs");
5424
+ var import_node_path23 = require("path");
5354
5425
  function resolveRequireTarget(fromDir, specifier) {
5355
- const base = (0, import_node_path21.join)(fromDir, specifier);
5426
+ const base = (0, import_node_path23.join)(fromDir, specifier);
5356
5427
  return [base, `${base}.cjs`, `${base}.js`].find((candidate) => fileExists(candidate));
5357
5428
  }
5358
5429
  function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()) {
@@ -5362,7 +5433,7 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
5362
5433
  visited.add(configPath);
5363
5434
  let text;
5364
5435
  try {
5365
- text = (0, import_node_fs21.readFileSync)(configPath, "utf8");
5436
+ text = (0, import_node_fs23.readFileSync)(configPath, "utf8");
5366
5437
  } catch {
5367
5438
  return "";
5368
5439
  }
@@ -5370,15 +5441,15 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
5370
5441
  text.matchAll(/require\((['"])(\.[^'"]*)\1\)/g),
5371
5442
  (match) => match[2]
5372
5443
  );
5373
- const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path21.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5444
+ const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path23.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
5374
5445
  return [text, ...requiredText].join("\n");
5375
5446
  }
5376
5447
 
5377
5448
  // src/project-scaffolding/npm-lib.use-case.ts
5378
5449
  async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
5379
5450
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5380
- const projectRoot = (0, import_node_path22.join)(workspaceRoot, "packages", name);
5381
- const manifestPath = (0, import_node_path22.join)(projectRoot, "package.json");
5451
+ const projectRoot = (0, import_node_path24.join)(workspaceRoot, "packages", name);
5452
+ const manifestPath = (0, import_node_path24.join)(projectRoot, "package.json");
5382
5453
  runGeneratorAndRepair(
5383
5454
  workspaceRoot,
5384
5455
  [
@@ -5401,14 +5472,18 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
5401
5472
  renameScaffoldPlaceholder(projectRoot, name, options.empty === true);
5402
5473
  removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
5403
5474
  removeLocalRegistryScaffolding(workspaceRoot);
5475
+ const pruned = pruneStaleLocalRegistry(workspaceRoot);
5476
+ if (pruned.stale && pruned.status !== 0) {
5477
+ logger.warn("Could not drop the unused local registry from package-lock.json: run `mnci upgrade` once the network is back.");
5478
+ }
5404
5479
  registerProjectCommands(workspaceRoot, name, { build: true });
5405
5480
  }
5406
5481
  );
5407
5482
  }
5408
5483
 
5409
5484
  // src/project-scaffolding/python.use-case.ts
5410
- var import_node_fs22 = require("fs");
5411
- var import_node_path23 = require("path");
5485
+ var import_node_fs24 = require("fs");
5486
+ var import_node_path25 = require("path");
5412
5487
  function ensurePython(workspaceRoot) {
5413
5488
  const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
5414
5489
  if (!hasPython) {
@@ -5431,7 +5506,7 @@ function ensurePythonPipPlugin(workspaceRoot) {
5431
5506
  registerPythonGraphPlugin(workspaceRoot);
5432
5507
  }
5433
5508
  function registerPythonGraphPlugin(workspaceRoot) {
5434
- const nxJsonPath = (0, import_node_path23.join)(workspaceRoot, "nx.json");
5509
+ const nxJsonPath = (0, import_node_path25.join)(workspaceRoot, "nx.json");
5435
5510
  if (!fileExists(nxJsonPath)) {
5436
5511
  return;
5437
5512
  }
@@ -5454,7 +5529,7 @@ pytest
5454
5529
  pip-audit
5455
5530
  `;
5456
5531
  function ensureRequirementsDev(workspaceRoot) {
5457
- const requirementsDevPath = (0, import_node_path23.join)(workspaceRoot, "requirements-dev.txt");
5532
+ const requirementsDevPath = (0, import_node_path25.join)(workspaceRoot, "requirements-dev.txt");
5458
5533
  if (!fileExists(requirementsDevPath)) {
5459
5534
  writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
5460
5535
  }
@@ -5514,8 +5589,8 @@ function addPythonApp(workspaceRoot, name) {
5514
5589
  ["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
5515
5590
  workspaceRoot
5516
5591
  );
5517
- writeFileEnsured((0, import_node_path23.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5518
- addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5592
+ writeFileEnsured((0, import_node_path25.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
5593
+ addProjectJsonTargets((0, import_node_path25.join)(workspaceRoot, "apps", name, "project.json"), {
5519
5594
  package: pythonAppPackageTarget(name),
5520
5595
  start: pythonAppStartTarget(name)
5521
5596
  });
@@ -5537,7 +5612,7 @@ function addPythonFunctionApp(workspaceRoot, name) {
5537
5612
  workspaceRoot
5538
5613
  );
5539
5614
  const moduleDirectory = pythonModuleDirectory(name);
5540
- addProjectJsonTargets((0, import_node_path23.join)(workspaceRoot, "apps", name, "project.json"), {
5615
+ addProjectJsonTargets((0, import_node_path25.join)(workspaceRoot, "apps", name, "project.json"), {
5541
5616
  package: pythonFunctionAppPackageTarget(name, moduleDirectory),
5542
5617
  start: pythonFunctionAppStartTarget(name)
5543
5618
  });
@@ -5578,7 +5653,7 @@ function addPythonInternalLib(workspaceRoot, name) {
5578
5653
  var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
5579
5654
  function findPythonProjectDirectory(workspaceRoot, name) {
5580
5655
  return PYTHON_PROJECT_DIRS.find(
5581
- (directory) => fileExists((0, import_node_path23.join)(workspaceRoot, directory, name, "pyproject.toml"))
5656
+ (directory) => fileExists((0, import_node_path25.join)(workspaceRoot, directory, name, "pyproject.toml"))
5582
5657
  );
5583
5658
  }
5584
5659
  function parseVendorEntries(pyprojectToml) {
@@ -5617,7 +5692,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5617
5692
  `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.`
5618
5693
  );
5619
5694
  }
5620
- if (!fileExists((0, import_node_path23.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5695
+ if (!fileExists((0, import_node_path25.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
5621
5696
  throw new Error(
5622
5697
  `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.`
5623
5698
  );
@@ -5625,8 +5700,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5625
5700
  if (consumerDirectory === "libs" && consumer === lib) {
5626
5701
  throw new Error(`'${consumer}' cannot vendor itself.`);
5627
5702
  }
5628
- const pyprojectPath = (0, import_node_path23.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5629
- const pyprojectToml = (0, import_node_fs22.readFileSync)(pyprojectPath, "utf8");
5703
+ const pyprojectPath = (0, import_node_path25.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
5704
+ const pyprojectToml = (0, import_node_fs24.readFileSync)(pyprojectPath, "utf8");
5630
5705
  if (parseVendorEntries(pyprojectToml).includes(lib)) {
5631
5706
  logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
5632
5707
  return;
@@ -5638,8 +5713,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
5638
5713
  }
5639
5714
 
5640
5715
  // src/project-scaffolding/react-app.use-case.ts
5641
- var import_node_fs23 = require("fs");
5642
- var import_node_path24 = require("path");
5716
+ var import_node_fs25 = require("fs");
5717
+ var import_node_path26 = require("path");
5643
5718
 
5644
5719
  // src/project-scaffolding/react-app-example.algorithm.ts
5645
5720
  function reactAppExampleFiles(name) {
@@ -5756,12 +5831,12 @@ function reactAppTargets(name) {
5756
5831
  return targets;
5757
5832
  }
5758
5833
  function allowEnvFiles(workspaceRoot) {
5759
- const gitignorePath = (0, import_node_path24.join)(workspaceRoot, ".gitignore");
5834
+ const gitignorePath = (0, import_node_path26.join)(workspaceRoot, ".gitignore");
5760
5835
  if (!fileExists(gitignorePath)) {
5761
5836
  return;
5762
5837
  }
5763
5838
  const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
5764
- const current = (0, import_node_fs23.readFileSync)(gitignorePath, "utf8");
5839
+ const current = (0, import_node_fs25.readFileSync)(gitignorePath, "utf8");
5765
5840
  if (current.includes(marker)) {
5766
5841
  return;
5767
5842
  }
@@ -5788,30 +5863,30 @@ function addReactApp(workspaceRoot, name, stack) {
5788
5863
  workspaceRoot
5789
5864
  );
5790
5865
  ensureAdmZip(workspaceRoot);
5791
- const reactAppRoot = (0, import_node_path24.join)(workspaceRoot, "apps", name);
5866
+ const reactAppRoot = (0, import_node_path26.join)(workspaceRoot, "apps", name);
5792
5867
  for (const environment of REACT_ENVIRONMENTS) {
5793
- writeFileEnsured((0, import_node_path24.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5868
+ writeFileEnsured((0, import_node_path26.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
5794
5869
  }
5795
5870
  allowEnvFiles(workspaceRoot);
5796
- addNxTargets((0, import_node_path24.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5871
+ addNxTargets((0, import_node_path26.join)(reactAppRoot, "package.json"), reactAppTargets(name));
5797
5872
  reshapeReactAppScaffold(reactAppRoot);
5798
- (0, import_node_fs23.rmSync)((0, import_node_path24.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5873
+ (0, import_node_fs25.rmSync)((0, import_node_path26.join)(reactAppRoot, "src/app/nx-welcome.component.tsx"), { force: true });
5799
5874
  const example = reactAppExampleFiles(name);
5800
5875
  for (const [relative, contents] of Object.entries(example)) {
5801
- writeFileEnsured((0, import_node_path24.join)(reactAppRoot, "src", relative), contents);
5876
+ writeFileEnsured((0, import_node_path26.join)(reactAppRoot, "src", relative), contents);
5802
5877
  }
5803
5878
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
5804
5879
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
5805
5880
  }
5806
5881
 
5807
5882
  // src/project-scaffolding/react-lib.use-case.ts
5808
- var import_node_path25 = require("path");
5883
+ var import_node_path27 = require("path");
5809
5884
  var REACT_LIB_BUNDLER = "rollup";
5810
5885
  async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5811
5886
  ensurePlugin(workspaceRoot, "@nx/react");
5812
5887
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
5813
- const projectRoot = (0, import_node_path25.join)(workspaceRoot, "packages", name);
5814
- const publishableManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5888
+ const projectRoot = (0, import_node_path27.join)(workspaceRoot, "packages", name);
5889
+ const publishableManifest = (0, import_node_path27.join)(projectRoot, "package.json");
5815
5890
  runGeneratorAndRepair(
5816
5891
  workspaceRoot,
5817
5892
  [
@@ -5835,14 +5910,18 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
5835
5910
  reshapeReactScaffold(projectRoot, name, options.empty === true);
5836
5911
  removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
5837
5912
  removeLocalRegistryScaffolding(workspaceRoot);
5913
+ const pruned = pruneStaleLocalRegistry(workspaceRoot);
5914
+ if (pruned.stale && pruned.status !== 0) {
5915
+ logger.warn("Could not drop the unused local registry from package-lock.json: run `mnci upgrade` once the network is back.");
5916
+ }
5838
5917
  registerProjectCommands(workspaceRoot, name, { build: true });
5839
5918
  }
5840
5919
  );
5841
5920
  }
5842
5921
  function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5843
5922
  ensurePlugin(workspaceRoot, "@nx/react");
5844
- const projectRoot = (0, import_node_path25.join)(workspaceRoot, "libs", name);
5845
- const privateManifest = (0, import_node_path25.join)(projectRoot, "package.json");
5923
+ const projectRoot = (0, import_node_path27.join)(workspaceRoot, "libs", name);
5924
+ const privateManifest = (0, import_node_path27.join)(projectRoot, "package.json");
5846
5925
  runGeneratorAndRepair(
5847
5926
  workspaceRoot,
5848
5927
  [
@@ -5869,8 +5948,8 @@ function addReactInternalLib(workspaceRoot, name, stack, empty = false) {
5869
5948
  }
5870
5949
 
5871
5950
  // src/project-scaffolding/vscode-extension.use-case.ts
5872
- var import_node_fs24 = require("fs");
5873
- var import_node_path26 = require("path");
5951
+ var import_node_fs26 = require("fs");
5952
+ var import_node_path28 = require("path");
5874
5953
  var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
5875
5954
  var VSCODE_ENGINE_FLOOR = "1.96.0";
5876
5955
  var VSCODE_SIDECAR_TARGETS = {
@@ -6055,8 +6134,8 @@ export const window = {
6055
6134
  var VSCODE_STUB_PATH = "test/vscode.stub.ts";
6056
6135
  function mapVscodeToStub(projectRoot, testRunner) {
6057
6136
  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}\` },`];
6058
- const path = (0, import_node_path26.join)(projectRoot, file);
6059
- const content = fileExists(path) ? (0, import_node_fs24.readFileSync)(path, "utf8") : "";
6137
+ const path = (0, import_node_path28.join)(projectRoot, file);
6138
+ const content = fileExists(path) ? (0, import_node_fs26.readFileSync)(path, "utf8") : "";
6060
6139
  const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
6061
6140
  if (line === void 0) {
6062
6141
  throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
@@ -6076,11 +6155,11 @@ function ensureVscodeToolchain(workspaceRoot) {
6076
6155
  }
6077
6156
  }
6078
6157
  function defaultPublisher(workspaceRoot) {
6079
- const { name } = readJson((0, import_node_path26.join)(workspaceRoot, "package.json"));
6158
+ const { name } = readJson((0, import_node_path28.join)(workspaceRoot, "package.json"));
6080
6159
  return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
6081
6160
  }
6082
6161
  function reshapeManifest(projectRoot, name, publisher) {
6083
- const manifestPath = (0, import_node_path26.join)(projectRoot, "package.json");
6162
+ const manifestPath = (0, import_node_path28.join)(projectRoot, "package.json");
6084
6163
  const manifest = readJson(manifestPath);
6085
6164
  const { nx = {}, ...rest } = manifest;
6086
6165
  const targets = { ...nx.targets };
@@ -6144,11 +6223,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
6144
6223
  };
6145
6224
  }
6146
6225
  function addDebugLaunch(workspaceRoot, name) {
6147
- const file = (0, import_node_fs24.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
6226
+ const file = (0, import_node_fs26.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
6148
6227
  if (file === void 0) {
6149
6228
  return;
6150
6229
  }
6151
- const path = (0, import_node_path26.join)(workspaceRoot, file);
6230
+ const path = (0, import_node_path28.join)(workspaceRoot, file);
6152
6231
  const workspace = readCodeWorkspace(path) ?? {};
6153
6232
  const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
6154
6233
  const taskLabel = `${name}: build (development)`;
@@ -6181,39 +6260,39 @@ function addDebugLaunch(workspaceRoot, name) {
6181
6260
  );
6182
6261
  }
6183
6262
  function refreshVscodeExtensionScript(workspaceRoot) {
6184
- const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
6263
+ const apps = (0, import_node_path28.join)(workspaceRoot, "apps");
6185
6264
  let entries;
6186
6265
  try {
6187
- entries = (0, import_node_fs24.readdirSync)(apps);
6266
+ entries = (0, import_node_fs26.readdirSync)(apps);
6188
6267
  } catch {
6189
6268
  return false;
6190
6269
  }
6191
6270
  const hasExtension = entries.some((entry) => {
6192
- const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
6271
+ const manifestPath = (0, import_node_path28.join)(apps, entry, "package.json");
6193
6272
  if (!fileExists(manifestPath)) {
6194
6273
  return false;
6195
6274
  }
6196
6275
  const tags = readJson(manifestPath).nx?.tags ?? [];
6197
6276
  return tags.includes(VSCODE_EXTENSION_TAG);
6198
6277
  });
6199
- const path = (0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
6200
- if (!hasExtension || fileExists(path) && (0, import_node_fs24.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
6278
+ const path = (0, import_node_path28.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
6279
+ if (!hasExtension || fileExists(path) && (0, import_node_fs26.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
6201
6280
  return false;
6202
6281
  }
6203
6282
  writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
6204
6283
  return true;
6205
6284
  }
6206
6285
  function pinVscodeExtensionProjectNames(workspaceRoot) {
6207
- const apps = (0, import_node_path26.join)(workspaceRoot, "apps");
6286
+ const apps = (0, import_node_path28.join)(workspaceRoot, "apps");
6208
6287
  let entries;
6209
6288
  try {
6210
- entries = (0, import_node_fs24.readdirSync)(apps);
6289
+ entries = (0, import_node_fs26.readdirSync)(apps);
6211
6290
  } catch {
6212
6291
  return [];
6213
6292
  }
6214
6293
  const updated = [];
6215
6294
  for (const entry of entries) {
6216
- const manifestPath = (0, import_node_path26.join)(apps, entry, "package.json");
6295
+ const manifestPath = (0, import_node_path28.join)(apps, entry, "package.json");
6217
6296
  if (!fileExists(manifestPath)) {
6218
6297
  continue;
6219
6298
  }
@@ -6233,22 +6312,22 @@ function refreshLockFile(workspaceRoot, name) {
6233
6312
  }
6234
6313
  function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
6235
6314
  const { sidecar } = options;
6236
- if (sidecar !== void 0 && !fileExists((0, import_node_path26.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
6315
+ if (sidecar !== void 0 && !fileExists((0, import_node_path28.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
6237
6316
  throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
6238
6317
  }
6239
6318
  runNodeApp(workspaceRoot, name, stack, "none");
6240
6319
  ensureVscodeToolchain(workspaceRoot);
6241
- const projectRoot = (0, import_node_path26.join)(workspaceRoot, "apps", name);
6320
+ const projectRoot = (0, import_node_path28.join)(workspaceRoot, "apps", name);
6242
6321
  reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot));
6243
- addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.app.json"));
6244
- addVscodeTypes((0, import_node_path26.join)(projectRoot, "tsconfig.spec.json"));
6245
- writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
6246
- writeFileEnsured((0, import_node_path26.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
6247
- writeFileEnsured((0, import_node_path26.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
6322
+ addVscodeTypes((0, import_node_path28.join)(projectRoot, "tsconfig.app.json"));
6323
+ addVscodeTypes((0, import_node_path28.join)(projectRoot, "tsconfig.spec.json"));
6324
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
6325
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
6326
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
6248
6327
  mapVscodeToStub(projectRoot, stack.testRunner);
6249
- writeFileEnsured((0, import_node_path26.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
6250
- writeFileEnsured((0, import_node_path26.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
6251
- addNxTargets((0, import_node_path26.join)(projectRoot, "package.json"), {
6328
+ writeFileEnsured((0, import_node_path28.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
6329
+ writeFileEnsured((0, import_node_path28.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
6330
+ addNxTargets((0, import_node_path28.join)(projectRoot, "package.json"), {
6252
6331
  "package": vscodeExtensionPackageTarget(name, sidecar),
6253
6332
  "nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
6254
6333
  });
@@ -6259,12 +6338,12 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
6259
6338
  }
6260
6339
 
6261
6340
  // src/dependency-management/install-dependencies.use-case.ts
6262
- var import_node_fs26 = require("fs");
6263
- var import_node_path28 = require("path");
6341
+ var import_node_fs28 = require("fs");
6342
+ var import_node_path30 = require("path");
6264
6343
 
6265
6344
  // src/dependency-management/manifest.repository.ts
6266
- var import_node_fs25 = require("fs");
6267
- var import_node_path27 = require("path");
6345
+ var import_node_fs27 = require("fs");
6346
+ var import_node_path29 = require("path");
6268
6347
  var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
6269
6348
  var ROOT_LABEL = "(root)";
6270
6349
  var MANIFEST_GLOBS = {
@@ -6297,23 +6376,23 @@ function projectOf(manifestRelativePath) {
6297
6376
  }
6298
6377
  function hasEcosystem(workspaceRoot, ecosystem) {
6299
6378
  if (ecosystem === "go") {
6300
- return fileExists((0, import_node_path27.join)(workspaceRoot, "go.mod"));
6379
+ return fileExists((0, import_node_path29.join)(workspaceRoot, "go.mod"));
6301
6380
  }
6302
6381
  if (ecosystem === "nuget") {
6303
- return (0, import_node_fs25.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
6382
+ return (0, import_node_fs27.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
6304
6383
  }
6305
6384
  const rootMarker = {
6306
6385
  npm: "package.json",
6307
6386
  pip: "requirements-dev.txt",
6308
6387
  pub: "pubspec.yaml"
6309
6388
  };
6310
- return fileExists((0, import_node_path27.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs25.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
6389
+ return fileExists((0, import_node_path29.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs27.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
6311
6390
  }
6312
6391
  function collectNpm(workspaceRoot) {
6313
6392
  const sites = [];
6314
- const relativePaths = ["package.json", ...(0, import_node_fs25.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
6393
+ const relativePaths = ["package.json", ...(0, import_node_fs27.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
6315
6394
  for (const relativePath of relativePaths) {
6316
- const manifestPath = (0, import_node_path27.join)(workspaceRoot, relativePath);
6395
+ const manifestPath = (0, import_node_path29.join)(workspaceRoot, relativePath);
6317
6396
  try {
6318
6397
  const manifest = readJson(manifestPath);
6319
6398
  sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
@@ -6374,17 +6453,17 @@ function collectPip(workspaceRoot) {
6374
6453
  name: parsed.name,
6375
6454
  ecosystem: "pip",
6376
6455
  project: projectOf(relativePath),
6377
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6456
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath),
6378
6457
  section,
6379
6458
  spec: parsed.spec,
6380
6459
  rewritable: parsed.rewritable && parsed.spec !== ""
6381
6460
  });
6382
6461
  };
6383
- const pyprojectPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6462
+ const pyprojectPaths = (0, import_node_fs27.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
6384
6463
  for (const relativePath of pyprojectPaths) {
6385
6464
  let content;
6386
6465
  try {
6387
- content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6466
+ content = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8");
6388
6467
  } catch {
6389
6468
  continue;
6390
6469
  }
@@ -6395,14 +6474,14 @@ function collectPip(workspaceRoot) {
6395
6474
  }
6396
6475
  const requirementsPaths = [
6397
6476
  "requirements-dev.txt",
6398
- ...(0, import_node_fs25.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6477
+ ...(0, import_node_fs27.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
6399
6478
  ];
6400
6479
  for (const relativePath of requirementsPaths) {
6401
- if (!fileExists((0, import_node_path27.join)(workspaceRoot, relativePath))) {
6480
+ if (!fileExists((0, import_node_path29.join)(workspaceRoot, relativePath))) {
6402
6481
  continue;
6403
6482
  }
6404
6483
  const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
6405
- const lines = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6484
+ const lines = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
6406
6485
  for (const line of lines) {
6407
6486
  push(relativePath, section, line);
6408
6487
  }
@@ -6440,11 +6519,11 @@ function pyprojectDependencies(content) {
6440
6519
  }
6441
6520
  function collectPub(workspaceRoot) {
6442
6521
  const sites = [];
6443
- const pubspecPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6522
+ const pubspecPaths = (0, import_node_fs27.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
6444
6523
  for (const relativePath of pubspecPaths) {
6445
6524
  let content;
6446
6525
  try {
6447
- content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6526
+ content = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8");
6448
6527
  } catch {
6449
6528
  continue;
6450
6529
  }
@@ -6454,7 +6533,7 @@ function collectPub(workspaceRoot) {
6454
6533
  name: entry.name,
6455
6534
  ecosystem: "pub",
6456
6535
  project: projectOf(relativePath),
6457
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6536
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath),
6458
6537
  section: block === "dependencies" ? "dep" : "devDep",
6459
6538
  spec: entry.spec,
6460
6539
  rewritable: entry.spec !== ""
@@ -6504,11 +6583,11 @@ function stripQuotes(value) {
6504
6583
  }
6505
6584
  function collectNuget(workspaceRoot) {
6506
6585
  const sites = [];
6507
- const csprojPaths = (0, import_node_fs25.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6586
+ const csprojPaths = (0, import_node_fs27.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
6508
6587
  for (const relativePath of csprojPaths) {
6509
6588
  let content;
6510
6589
  try {
6511
- content = (0, import_node_fs25.readFileSync)((0, import_node_path27.join)(workspaceRoot, relativePath), "utf8");
6590
+ content = (0, import_node_fs27.readFileSync)((0, import_node_path29.join)(workspaceRoot, relativePath), "utf8");
6512
6591
  } catch {
6513
6592
  continue;
6514
6593
  }
@@ -6517,7 +6596,7 @@ function collectNuget(workspaceRoot) {
6517
6596
  name: entry.name,
6518
6597
  ecosystem: "nuget",
6519
6598
  project: projectOf(relativePath),
6520
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath),
6599
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath),
6521
6600
  section: "dep",
6522
6601
  spec: entry.spec,
6523
6602
  // A plain SemVer string is rewritable; an MSBuild property reference
@@ -6542,13 +6621,13 @@ function csprojPackageReferences(content) {
6542
6621
  return entries;
6543
6622
  }
6544
6623
  function collectGo(workspaceRoot) {
6545
- const manifestPath = (0, import_node_path27.join)(workspaceRoot, "go.mod");
6624
+ const manifestPath = (0, import_node_path29.join)(workspaceRoot, "go.mod");
6546
6625
  if (!fileExists(manifestPath)) {
6547
6626
  return [];
6548
6627
  }
6549
6628
  let content;
6550
6629
  try {
6551
- content = (0, import_node_fs25.readFileSync)(manifestPath, "utf8");
6630
+ content = (0, import_node_fs27.readFileSync)(manifestPath, "utf8");
6552
6631
  } catch {
6553
6632
  return [];
6554
6633
  }
@@ -6597,7 +6676,7 @@ var PROJECT_GLOBS = {
6597
6676
  function locateProjects(workspaceRoot) {
6598
6677
  const locations = [];
6599
6678
  for (const ecosystem of ECOSYSTEMS) {
6600
- const relativePaths = (0, import_node_fs25.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6679
+ const relativePaths = (0, import_node_fs27.globSync)(PROJECT_GLOBS[ecosystem], { cwd: workspaceRoot });
6601
6680
  for (const relativePath of relativePaths) {
6602
6681
  const posix = toPosix(relativePath);
6603
6682
  const dir = posix.slice(0, posix.lastIndexOf("/"));
@@ -6605,7 +6684,7 @@ function locateProjects(workspaceRoot) {
6605
6684
  ecosystem,
6606
6685
  dir,
6607
6686
  name: dir.slice(dir.lastIndexOf("/") + 1),
6608
- manifestPath: (0, import_node_path27.join)(workspaceRoot, relativePath)
6687
+ manifestPath: (0, import_node_path29.join)(workspaceRoot, relativePath)
6609
6688
  });
6610
6689
  }
6611
6690
  }
@@ -6626,7 +6705,7 @@ function rewriteSpec(site, spec) {
6626
6705
  writeFileEnsured(site.manifestPath, toJson(manifest));
6627
6706
  return true;
6628
6707
  }
6629
- const before = (0, import_node_fs25.readFileSync)(site.manifestPath, "utf8");
6708
+ const before = (0, import_node_fs27.readFileSync)(site.manifestPath, "utf8");
6630
6709
  const after = (() => {
6631
6710
  switch (site.ecosystem) {
6632
6711
  case "pip": {
@@ -6717,13 +6796,13 @@ function escapeForRegex(value) {
6717
6796
  function isWorkspaceProject(workspaceRoot, name) {
6718
6797
  const short = name.includes("/") ? name.split("/").at(-1) : name;
6719
6798
  return ["apps", "libs", "packages"].some(
6720
- (directory) => fileExists((0, import_node_path27.join)(workspaceRoot, directory, short ?? name, "package.json"))
6799
+ (directory) => fileExists((0, import_node_path29.join)(workspaceRoot, directory, short ?? name, "package.json"))
6721
6800
  );
6722
6801
  }
6723
6802
  function isAliasedInstall(workspaceRoot, name) {
6724
6803
  try {
6725
6804
  const installed = readJson(
6726
- (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6805
+ (0, import_node_path29.join)(workspaceRoot, "node_modules", name, "package.json")
6727
6806
  );
6728
6807
  return installed.name !== void 0 && installed.name !== name;
6729
6808
  } catch {
@@ -6734,14 +6813,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6734
6813
  if (ecosystem === "npm") {
6735
6814
  try {
6736
6815
  return readJson(
6737
- (0, import_node_path27.join)(workspaceRoot, "node_modules", name, "package.json")
6816
+ (0, import_node_path29.join)(workspaceRoot, "node_modules", name, "package.json")
6738
6817
  ).version;
6739
6818
  } catch {
6740
6819
  return void 0;
6741
6820
  }
6742
6821
  }
6743
6822
  if (ecosystem === "pub") {
6744
- const lockPath = (0, import_node_path27.join)(workspaceRoot, "pubspec.lock");
6823
+ const lockPath = (0, import_node_path29.join)(workspaceRoot, "pubspec.lock");
6745
6824
  if (!fileExists(lockPath)) {
6746
6825
  return void 0;
6747
6826
  }
@@ -6749,7 +6828,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
6749
6828
  const match = new RegExp(
6750
6829
  String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
6751
6830
  "m"
6752
- ).exec((0, import_node_fs25.readFileSync)(lockPath, "utf8"));
6831
+ ).exec((0, import_node_fs27.readFileSync)(lockPath, "utf8"));
6753
6832
  return match?.[1];
6754
6833
  } catch {
6755
6834
  return void 0;
@@ -6815,7 +6894,7 @@ function resolveTarget(locations, target) {
6815
6894
  return byName[0];
6816
6895
  }
6817
6896
  function installInto(workspaceRoot, location, packages, saveDev) {
6818
- const projectDir = (0, import_node_path28.join)(workspaceRoot, location.dir);
6897
+ const projectDir = (0, import_node_path30.join)(workspaceRoot, location.dir);
6819
6898
  switch (location.ecosystem) {
6820
6899
  case "npm": {
6821
6900
  const flags = saveDev ? ["--save-dev"] : [];
@@ -6868,7 +6947,7 @@ function installInto(workspaceRoot, location, packages, saveDev) {
6868
6947
  function addPythonDependency(manifestPath, specifier) {
6869
6948
  let content;
6870
6949
  try {
6871
- content = (0, import_node_fs26.readFileSync)(manifestPath, "utf8");
6950
+ content = (0, import_node_fs28.readFileSync)(manifestPath, "utf8");
6872
6951
  } catch {
6873
6952
  logger.warn(`Could not read ${manifestPath} \u2014 skipped ${specifier}`);
6874
6953
  return;
@@ -6897,7 +6976,7 @@ function installEverything(workspaceRoot, only) {
6897
6976
  }
6898
6977
  function ecosystemPresent(workspaceRoot, ecosystem) {
6899
6978
  if (ecosystem === "go") {
6900
- return fileExists((0, import_node_path28.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path28.join)(workspaceRoot, "go.mod"));
6979
+ return fileExists((0, import_node_path30.join)(workspaceRoot, "go.work")) || fileExists((0, import_node_path30.join)(workspaceRoot, "go.mod"));
6901
6980
  }
6902
6981
  return hasEcosystem(workspaceRoot, ecosystem);
6903
6982
  }
@@ -6916,7 +6995,7 @@ function splitAtLast(value, separator) {
6916
6995
  }
6917
6996
 
6918
6997
  // src/dependency-management/sync-dependencies.use-case.ts
6919
- var import_node_path29 = require("path");
6998
+ var import_node_path31 = require("path");
6920
6999
 
6921
7000
  // src/dependency-management/semver.algorithm.ts
6922
7001
  var UPDATE_KINDS = ["patch", "minor", "major", "non-semver"];
@@ -7093,7 +7172,7 @@ function describe(finding) {
7093
7172
  return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
7094
7173
  }
7095
7174
  function runSync(workspaceRoot, options) {
7096
- if (!fileExists((0, import_node_path29.join)(workspaceRoot, "nx.json"))) {
7175
+ if (!fileExists((0, import_node_path31.join)(workspaceRoot, "nx.json"))) {
7097
7176
  throw new Error(
7098
7177
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
7099
7178
  );
@@ -7143,7 +7222,7 @@ function runSync(workspaceRoot, options) {
7143
7222
  }
7144
7223
 
7145
7224
  // src/dependency-management/update-dependencies.use-case.ts
7146
- var import_node_path30 = require("path");
7225
+ var import_node_path32 = require("path");
7147
7226
  var import_prompts2 = require("@inquirer/prompts");
7148
7227
 
7149
7228
  // src/dependency-management/registry.client.ts
@@ -7426,7 +7505,7 @@ function reinstall(workspaceRoot, ecosystems) {
7426
7505
  function hasPythonInstallScript(workspaceRoot) {
7427
7506
  try {
7428
7507
  const manifest = readJson(
7429
- (0, import_node_path30.join)(workspaceRoot, "package.json")
7508
+ (0, import_node_path32.join)(workspaceRoot, "package.json")
7430
7509
  );
7431
7510
  return manifest.scripts?.["python:install"] !== void 0;
7432
7511
  } catch {
@@ -7442,7 +7521,7 @@ function applyGoUpdates(workspaceRoot, entries) {
7442
7521
  }
7443
7522
  }
7444
7523
  async function runUp(workspaceRoot, options) {
7445
- if (!fileExists((0, import_node_path30.join)(workspaceRoot, "nx.json"))) {
7524
+ if (!fileExists((0, import_node_path32.join)(workspaceRoot, "nx.json"))) {
7446
7525
  throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
7447
7526
  }
7448
7527
  const ecosystems = resolveEcosystems(options.ecosystem);
@@ -7519,7 +7598,7 @@ var PROJECT_KINDS = [
7519
7598
  var EMPTY_KINDS = /* @__PURE__ */ new Set(["npm-lib", "internal-lib", "react-lib", "react-internal-lib", "node-function-app"]);
7520
7599
  async function runAdd(kind, name, options) {
7521
7600
  const workspaceRoot = process.cwd();
7522
- if (!fileExists((0, import_node_path31.join)(workspaceRoot, "nx.json"))) {
7601
+ if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
7523
7602
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
7524
7603
  }
7525
7604
  const stack = readWorkspaceStack(workspaceRoot);
@@ -7582,8 +7661,8 @@ async function runAdd(kind, name, options) {
7582
7661
  ],
7583
7662
  workspaceRoot
7584
7663
  );
7585
- markPrivate((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7586
- renameScaffoldPlaceholder((0, import_node_path31.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7664
+ markPrivate((0, import_node_path33.join)(workspaceRoot, "libs", resolvedName, "package.json"));
7665
+ renameScaffoldPlaceholder((0, import_node_path33.join)(workspaceRoot, "libs", resolvedName), resolvedName, options.empty === true);
7587
7666
  removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
7588
7667
  registerProjectCommands(workspaceRoot, resolvedName, { build: true });
7589
7668
  break;
@@ -7675,7 +7754,7 @@ async function runAdd(kind, name, options) {
7675
7754
  }
7676
7755
  function readWorkspaceStack(workspaceRoot) {
7677
7756
  const nxJson = readJson(
7678
- (0, import_node_path31.join)(workspaceRoot, "nx.json")
7757
+ (0, import_node_path33.join)(workspaceRoot, "nx.json")
7679
7758
  );
7680
7759
  const stack = nxJson.mnci?.stack;
7681
7760
  return {
@@ -7724,15 +7803,15 @@ function runKinds(options) {
7724
7803
 
7725
7804
  // src/workspace-diagnostics/check-invariants.use-case.ts
7726
7805
  var import_node_child_process = require("child_process");
7727
- var import_node_fs27 = require("fs");
7728
- var import_node_path32 = require("path");
7806
+ var import_node_fs29 = require("fs");
7807
+ var import_node_path34 = require("path");
7729
7808
  var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
7730
7809
  function toPosix2(path) {
7731
7810
  return path.replaceAll("\\", "/");
7732
7811
  }
7733
7812
  function checkEslintConfigs(workspaceRoot) {
7734
- const rootConfigs = (0, import_node_fs27.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7735
- const projectConfigs = (0, import_node_fs27.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7813
+ const rootConfigs = (0, import_node_fs29.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
7814
+ const projectConfigs = (0, import_node_fs29.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
7736
7815
  cwd: workspaceRoot
7737
7816
  }).map((config) => toPosix2(config));
7738
7817
  return [
@@ -7752,10 +7831,10 @@ function checkEslintConfigs(workspaceRoot) {
7752
7831
  ];
7753
7832
  }
7754
7833
  function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7755
- const rules = (0, import_node_path32.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7756
- if (!(0, import_node_fs27.existsSync)(rules)) return [];
7757
- const entryPoint = (0, import_node_path32.join)(workspaceRoot, ESLINT_USER_FILENAME);
7758
- const source = (0, import_node_fs27.existsSync)(entryPoint) ? (0, import_node_fs27.readFileSync)(entryPoint, "utf8") : "";
7834
+ const rules = (0, import_node_path34.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
7835
+ if (!(0, import_node_fs29.existsSync)(rules)) return [];
7836
+ const entryPoint = (0, import_node_path34.join)(workspaceRoot, ESLINT_USER_FILENAME);
7837
+ const source = (0, import_node_fs29.existsSync)(entryPoint) ? (0, import_node_fs29.readFileSync)(entryPoint, "utf8") : "";
7759
7838
  return [
7760
7839
  {
7761
7840
  check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
@@ -7768,7 +7847,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
7768
7847
  function declaredDevDependencies(workspaceRoot) {
7769
7848
  try {
7770
7849
  const manifest = readJson(
7771
- (0, import_node_path32.join)(workspaceRoot, "package.json")
7850
+ (0, import_node_path34.join)(workspaceRoot, "package.json")
7772
7851
  );
7773
7852
  return manifest.devDependencies ?? {};
7774
7853
  } catch {
@@ -7776,7 +7855,7 @@ function declaredDevDependencies(workspaceRoot) {
7776
7855
  }
7777
7856
  }
7778
7857
  function checkNoRetiredFormatter(workspaceRoot) {
7779
- const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file)));
7858
+ const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path34.join)(workspaceRoot, file)));
7780
7859
  const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
7781
7860
  const stale = [...files, ...declared];
7782
7861
  if (stale.length === 0) {
@@ -7802,7 +7881,7 @@ function checkEslintPlugin(nxJson) {
7802
7881
  };
7803
7882
  }
7804
7883
  function checkResolvedEslint(workspaceRoot) {
7805
- const manifestPath = (0, import_node_path32.join)(workspaceRoot, "node_modules/eslint/package.json");
7884
+ const manifestPath = (0, import_node_path34.join)(workspaceRoot, "node_modules/eslint/package.json");
7806
7885
  if (!fileExists(manifestPath)) {
7807
7886
  return void 0;
7808
7887
  }
@@ -7820,11 +7899,11 @@ function checkResolvedEslint(workspaceRoot) {
7820
7899
  }
7821
7900
  }
7822
7901
  function checkNpmrc(workspaceRoot, registry, scope) {
7823
- const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7902
+ const npmrcPath = (0, import_node_path34.join)(workspaceRoot, ".npmrc");
7824
7903
  if (!registry || !fileExists(npmrcPath)) {
7825
7904
  return void 0;
7826
7905
  }
7827
- const npmrc = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8");
7906
+ const npmrc = (0, import_node_fs29.readFileSync)(npmrcPath, "utf8");
7828
7907
  if (registry.kind === "npm") {
7829
7908
  return {
7830
7909
  check: ".npmrc authenticates the public registry",
@@ -7841,11 +7920,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
7841
7920
  };
7842
7921
  }
7843
7922
  function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
7844
- const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7923
+ const npmrcPath = (0, import_node_path34.join)(workspaceRoot, ".npmrc");
7845
7924
  if (!fileExists(npmrcPath)) {
7846
7925
  return void 0;
7847
7926
  }
7848
- const npmrc = (0, import_node_fs27.readFileSync)(npmrcPath, "utf8");
7927
+ const npmrc = (0, import_node_fs29.readFileSync)(npmrcPath, "utf8");
7849
7928
  const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
7850
7929
  const referenced = [
7851
7930
  ...new Set(
@@ -7869,13 +7948,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
7869
7948
  };
7870
7949
  }
7871
7950
  function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
7872
- const npmrcPath = (0, import_node_path32.join)(workspaceRoot, ".npmrc");
7873
- const pipelinePath = (0, import_node_path32.join)(workspaceRoot, "azure-pipelines.yml");
7951
+ const npmrcPath = (0, import_node_path34.join)(workspaceRoot, ".npmrc");
7952
+ const pipelinePath = (0, import_node_path34.join)(workspaceRoot, "azure-pipelines.yml");
7874
7953
  if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
7875
7954
  return void 0;
7876
7955
  }
7877
- 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));
7878
- const runsTask = (0, import_node_fs27.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7956
+ 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));
7957
+ const runsTask = (0, import_node_fs29.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
7879
7958
  if (!holdsCredentials && !runsTask) {
7880
7959
  return {
7881
7960
  check: "npm auth: .npmrc and azure-pipelines.yml agree",
@@ -7920,13 +7999,13 @@ function npmjsCredentialShape(credentials, environment) {
7920
7999
  }
7921
8000
  function checkVersionActions(workspaceRoot) {
7922
8001
  const candidates = [
7923
- ...(0, import_node_fs27.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
7924
- ...(0, import_node_fs27.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
7925
- ...(0, import_node_fs27.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
8002
+ ...(0, import_node_fs29.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
8003
+ ...(0, import_node_fs29.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
8004
+ ...(0, import_node_fs29.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
7926
8005
  ].map((manifest) => toPosix2(manifest));
7927
8006
  return candidates.flatMap((manifest) => {
7928
8007
  const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
7929
- const projectJsonPath = (0, import_node_path32.join)(workspaceRoot, projectRoot, "project.json");
8008
+ const projectJsonPath = (0, import_node_path34.join)(workspaceRoot, projectRoot, "project.json");
7930
8009
  let hasOverride = false;
7931
8010
  try {
7932
8011
  const projectJson = readJson(projectJsonPath);
@@ -7955,7 +8034,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
7955
8034
  ]) {
7956
8035
  try {
7957
8036
  const targets = extract(
7958
- readJson((0, import_node_path32.join)(workspaceRoot, projectRoot, file))
8037
+ readJson((0, import_node_path34.join)(workspaceRoot, projectRoot, file))
7959
8038
  );
7960
8039
  if (targets && typeof targets === "object") {
7961
8040
  sources.push({
@@ -7971,8 +8050,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
7971
8050
  function checkTargetFilesExist(workspaceRoot) {
7972
8051
  const projectRoots = new Set(
7973
8052
  [
7974
- ...(0, import_node_fs27.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
7975
- ...(0, import_node_fs27.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
8053
+ ...(0, import_node_fs29.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
8054
+ ...(0, import_node_fs29.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
7976
8055
  ].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
7977
8056
  );
7978
8057
  return [...projectRoots].flatMap(
@@ -7987,7 +8066,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
7987
8066
  return TARGET_FILE_OPTIONS.flatMap((option) => {
7988
8067
  const value = target?.options?.[option];
7989
8068
  const checkable = typeof value === "string" && !value.includes("{");
7990
- if (!checkable || fileExists((0, import_node_path32.join)(workspaceRoot, value))) {
8069
+ if (!checkable || fileExists((0, import_node_path34.join)(workspaceRoot, value))) {
7991
8070
  return [];
7992
8071
  }
7993
8072
  return [
@@ -8026,15 +8105,15 @@ function checkGoPluginRegistered(workspaceRoot) {
8026
8105
  };
8027
8106
  }
8028
8107
  function checkGoWorkInSync(workspaceRoot) {
8029
- const goWorkPath = (0, import_node_path32.join)(workspaceRoot, "go.work");
8108
+ const goWorkPath = (0, import_node_path34.join)(workspaceRoot, "go.work");
8030
8109
  if (!fileExists(goWorkPath)) {
8031
8110
  return void 0;
8032
8111
  }
8033
- const contents = (0, import_node_fs27.existsSync)(goWorkPath) ? (0, import_node_fs27.readFileSync)(goWorkPath, "utf8") : "";
8112
+ const contents = (0, import_node_fs29.existsSync)(goWorkPath) ? (0, import_node_fs29.readFileSync)(goWorkPath, "utf8") : "";
8034
8113
  const blockEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+\(([^)]*)\)/g), (match) => match[1].split("\n")).flat();
8035
8114
  const singleEntries = Array.from(contents.matchAll(/(?:^|\n)\s*use\s+(\.\S+)/g), (match) => match[1]);
8036
8115
  const uses = [...blockEntries, ...singleEntries].map((entry) => entry.trim()).filter(Boolean);
8037
- const stale = uses.filter((entry) => !(0, import_node_fs27.existsSync)((0, import_node_path32.join)(workspaceRoot, entry, "go.mod")));
8116
+ const stale = uses.filter((entry) => !(0, import_node_fs29.existsSync)((0, import_node_path34.join)(workspaceRoot, entry, "go.mod")));
8038
8117
  return {
8039
8118
  check: "every go.work `use` entry points to a module that still exists",
8040
8119
  ok: stale.length === 0,
@@ -8050,9 +8129,9 @@ function checkNativeApps(workspaceRoot) {
8050
8129
  { file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
8051
8130
  { file: "azure-pipelines.yml", marker: "- job: native" }
8052
8131
  ];
8053
- const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).map(({ file, marker }) => ({
8132
+ const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path34.join)(workspaceRoot, file))).map(({ file, marker }) => ({
8054
8133
  check: `${file} builds the native apps on every OS`,
8055
- ok: (0, import_node_fs27.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8").includes(marker),
8134
+ ok: (0, import_node_fs29.readFileSync)((0, import_node_path34.join)(workspaceRoot, file), "utf8").includes(marker),
8056
8135
  detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
8057
8136
  remedy: "run `mnci upgrade`"
8058
8137
  }));
@@ -8065,7 +8144,7 @@ function checkNativeApps(workspaceRoot) {
8065
8144
  return findings;
8066
8145
  }
8067
8146
  function checkNoRootRuntimeDependencies(workspaceRoot) {
8068
- const manifestPath = (0, import_node_path32.join)(workspaceRoot, "package.json");
8147
+ const manifestPath = (0, import_node_path34.join)(workspaceRoot, "package.json");
8069
8148
  if (!fileExists(manifestPath)) {
8070
8149
  return void 0;
8071
8150
  }
@@ -8085,14 +8164,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
8085
8164
  };
8086
8165
  }
8087
8166
  function checkRollupSourceMaps(workspaceRoot) {
8088
- const configs = (0, import_node_fs27.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8167
+ const configs = (0, import_node_fs29.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8089
8168
  cwd: workspaceRoot
8090
8169
  }).map((config) => toPosix2(config));
8091
8170
  return configs.flatMap((relativePath) => {
8092
- const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
8171
+ const configPath = (0, import_node_path34.join)(workspaceRoot, relativePath);
8093
8172
  let config;
8094
8173
  try {
8095
- config = (0, import_node_fs27.readFileSync)(configPath, "utf8");
8174
+ config = (0, import_node_fs29.readFileSync)(configPath, "utf8");
8096
8175
  } catch {
8097
8176
  return [];
8098
8177
  }
@@ -8107,11 +8186,11 @@ function checkRollupSourceMaps(workspaceRoot) {
8107
8186
  });
8108
8187
  }
8109
8188
  function checkDeclarationSpecifiers(workspaceRoot) {
8110
- const configs = (0, import_node_fs27.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8189
+ const configs = (0, import_node_fs29.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
8111
8190
  cwd: workspaceRoot
8112
8191
  }).map((config) => toPosix2(config));
8113
8192
  return configs.flatMap((relativePath) => {
8114
- const configPath = (0, import_node_path32.join)(workspaceRoot, relativePath);
8193
+ const configPath = (0, import_node_path34.join)(workspaceRoot, relativePath);
8115
8194
  if (!fileExists(configPath)) {
8116
8195
  return [];
8117
8196
  }
@@ -8146,8 +8225,8 @@ function checkDeclarationSpecifiers(workspaceRoot) {
8146
8225
  }
8147
8226
  function checkPipelinePhases(workspaceRoot) {
8148
8227
  const files = ["azure-pipelines.yml", ".github/workflows/ci.yml"];
8149
- return files.filter((file) => fileExists((0, import_node_path32.join)(workspaceRoot, file))).flatMap((file) => {
8150
- const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs27.readFileSync)((0, import_node_path32.join)(workspaceRoot, file), "utf8"));
8228
+ return files.filter((file) => fileExists((0, import_node_path34.join)(workspaceRoot, file))).flatMap((file) => {
8229
+ const { verifyActive, switchedOff } = inspectPipeline((0, import_node_fs29.readFileSync)((0, import_node_path34.join)(workspaceRoot, file), "utf8"));
8151
8230
  const verify = {
8152
8231
  check: `${file} runs the enforced verify phase`,
8153
8232
  ok: verifyActive,
@@ -8187,8 +8266,19 @@ function checkDependencyRangesNotPreserved(nxJson) {
8187
8266
  remedy: "run `mnci upgrade`, or set release.version.preserveMatchingDependencyRanges to false in nx.json"
8188
8267
  };
8189
8268
  }
8269
+ function checkLockfileHasNoLocalRegistry(workspaceRoot) {
8270
+ if (!fileExists((0, import_node_path34.join)(workspaceRoot, "package-lock.json"))) {
8271
+ return void 0;
8272
+ }
8273
+ return {
8274
+ check: "package-lock.json carries no unused local registry (verdaccio)",
8275
+ ok: !hasStaleLocalRegistry(workspaceRoot),
8276
+ 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",
8277
+ remedy: "run `mnci upgrade`, which removes it, then commit package-lock.json"
8278
+ };
8279
+ }
8190
8280
  function collectFindings(workspaceRoot) {
8191
- const nxJsonPath = (0, import_node_path32.join)(workspaceRoot, "nx.json");
8281
+ const nxJsonPath = (0, import_node_path34.join)(workspaceRoot, "nx.json");
8192
8282
  if (!fileExists(nxJsonPath)) {
8193
8283
  throw new Error(
8194
8284
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
@@ -8214,7 +8304,8 @@ function collectFindings(workspaceRoot) {
8214
8304
  ...checkNativeApps(workspaceRoot),
8215
8305
  ...checkPipelinePhases(workspaceRoot),
8216
8306
  ...checkNativeBuildConfig(workspaceRoot),
8217
- checkDependencyRangesNotPreserved(nxJson)
8307
+ checkDependencyRangesNotPreserved(nxJson),
8308
+ checkLockfileHasNoLocalRegistry(workspaceRoot)
8218
8309
  ].filter((finding) => finding !== void 0);
8219
8310
  }
8220
8311
  function runDoctor(workspaceRoot, options = {}) {
@@ -8320,11 +8411,11 @@ function runCommands(program, options) {
8320
8411
  }
8321
8412
 
8322
8413
  // src/workspace-info/list-projects.use-case.ts
8323
- var import_node_path33 = require("path");
8414
+ var import_node_path35 = require("path");
8324
8415
  var TYPE_TAG_PREFIX = "type:";
8325
8416
  function listProjects(workspaceRoot) {
8326
8417
  return locateProjects(workspaceRoot).map((location) => {
8327
- const projectJsonPath = (0, import_node_path33.join)(workspaceRoot, location.dir, "project.json");
8418
+ const projectJsonPath = (0, import_node_path35.join)(workspaceRoot, location.dir, "project.json");
8328
8419
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
8329
8420
  const typeTag = (project.tags ?? []).find((tag) => tag.startsWith(TYPE_TAG_PREFIX));
8330
8421
  return {
@@ -8337,7 +8428,7 @@ function listProjects(workspaceRoot) {
8337
8428
  }).toSorted((a, b) => a.dir.localeCompare(b.dir));
8338
8429
  }
8339
8430
  function runProjects(workspaceRoot, options) {
8340
- if (!fileExists((0, import_node_path33.join)(workspaceRoot, "nx.json"))) {
8431
+ if (!fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"))) {
8341
8432
  throw new Error("No nx.json found here. Run `projects` from the workspace root.");
8342
8433
  }
8343
8434
  const projects = listProjects(workspaceRoot);
@@ -8351,11 +8442,11 @@ function runProjects(workspaceRoot, options) {
8351
8442
  }
8352
8443
 
8353
8444
  // src/workspace-info/read-workspace-info.use-case.ts
8354
- var import_node_path35 = require("path");
8445
+ var import_node_path37 = require("path");
8355
8446
 
8356
8447
  // src/cli-version/check-for-update.use-case.ts
8357
- var import_node_fs28 = require("fs");
8358
- var import_node_path34 = require("path");
8448
+ var import_node_fs30 = require("fs");
8449
+ var import_node_path36 = require("path");
8359
8450
  var import_cross_spawn3 = __toESM(require("cross-spawn"));
8360
8451
  var PACKAGE_NAME2 = "@mnci/cli";
8361
8452
  var REGISTRY_TIMEOUT_MS = 2e3;
@@ -8414,8 +8505,8 @@ function releaseTriple(version) {
8414
8505
  }
8415
8506
  function readCliVersion(packageDirectory) {
8416
8507
  try {
8417
- const manifestPath = (0, import_node_path34.join)(packageDirectory, "..", "package.json");
8418
- const manifest = JSON.parse((0, import_node_fs28.readFileSync)(manifestPath, "utf8"));
8508
+ const manifestPath = (0, import_node_path36.join)(packageDirectory, "..", "package.json");
8509
+ const manifest = JSON.parse((0, import_node_fs30.readFileSync)(manifestPath, "utf8"));
8419
8510
  return manifest.version ?? "0.0.0";
8420
8511
  } catch {
8421
8512
  return "0.0.0";
@@ -8425,7 +8516,7 @@ function readCliVersion(packageDirectory) {
8425
8516
  // src/workspace-info/read-workspace-info.use-case.ts
8426
8517
  function readWorkspaceInfo(workspaceRoot, cliVersion) {
8427
8518
  const latest = fetchLatestVersion() ?? null;
8428
- const isWorkspace = fileExists((0, import_node_path35.join)(workspaceRoot, "nx.json"));
8519
+ const isWorkspace = fileExists((0, import_node_path37.join)(workspaceRoot, "nx.json"));
8429
8520
  return {
8430
8521
  cli: {
8431
8522
  version: cliVersion,
@@ -8446,8 +8537,8 @@ function runInfo(workspaceRoot, cliVersion, options) {
8446
8537
  }
8447
8538
 
8448
8539
  // src/workspace-creation/adopt-directory.use-case.ts
8449
- var import_node_fs29 = require("fs");
8450
- var import_node_path36 = require("path");
8540
+ var import_node_fs31 = require("fs");
8541
+ var import_node_path38 = require("path");
8451
8542
  var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
8452
8543
  var AGENT_AND_CI_ENTRIES = [
8453
8544
  "AGENTS.md",
@@ -8478,13 +8569,13 @@ var PREFLIGHT_BLOCKERS = [
8478
8569
  "packages"
8479
8570
  ];
8480
8571
  function assertAdoptableDirectory(target) {
8481
- if (!(0, import_node_fs29.existsSync)(target)) {
8572
+ if (!(0, import_node_fs31.existsSync)(target)) {
8482
8573
  throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
8483
8574
  }
8484
- if (!(0, import_node_fs29.statSync)(target).isDirectory()) {
8575
+ if (!(0, import_node_fs31.statSync)(target).isDirectory()) {
8485
8576
  throw new Error(`--into '${target}' is not a directory.`);
8486
8577
  }
8487
- const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs29.existsSync)((0, import_node_path36.join)(target, entry)));
8578
+ const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs31.existsSync)((0, import_node_path38.join)(target, entry)));
8488
8579
  if (blockers.length > 0) {
8489
8580
  throw new Error(
8490
8581
  `--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.`
@@ -8492,15 +8583,15 @@ function assertAdoptableDirectory(target) {
8492
8583
  }
8493
8584
  }
8494
8585
  function mergeGitignore(generatedFile, targetFile) {
8495
- const existing = (0, import_node_fs29.readFileSync)(targetFile, "utf8");
8586
+ const existing = (0, import_node_fs31.readFileSync)(targetFile, "utf8");
8496
8587
  const present = new Set(existing.split("\n").map((line) => line.trim()));
8497
- const additions = (0, import_node_fs29.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8588
+ const additions = (0, import_node_fs31.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
8498
8589
  const trimmed = line.trim();
8499
8590
  return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
8500
8591
  });
8501
8592
  if (additions.length === 0) return false;
8502
8593
  const separator = existing.endsWith("\n") ? "" : "\n";
8503
- (0, import_node_fs29.writeFileSync)(
8594
+ (0, import_node_fs31.writeFileSync)(
8504
8595
  targetFile,
8505
8596
  `${existing}${separator}
8506
8597
  # Added by mnci (Nx workspace)
@@ -8510,9 +8601,9 @@ ${additions.join("\n")}
8510
8601
  return true;
8511
8602
  }
8512
8603
  function adoptGeneratedWorkspace(generatedRoot, target) {
8513
- const entries = (0, import_node_fs29.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8604
+ const entries = (0, import_node_fs31.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
8514
8605
  const collisions = entries.filter(
8515
- (entry) => (0, import_node_fs29.existsSync)((0, import_node_path36.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8606
+ (entry) => (0, import_node_fs31.existsSync)((0, import_node_path38.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
8516
8607
  );
8517
8608
  if (collisions.length > 0) {
8518
8609
  throw new Error(
@@ -8521,28 +8612,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
8521
8612
  }
8522
8613
  const result = { copied: [], kept: [], mergedGitignore: false };
8523
8614
  for (const entry of entries) {
8524
- const from = (0, import_node_path36.join)(generatedRoot, entry);
8525
- const to = (0, import_node_path36.join)(target, entry);
8526
- if (entry === ".gitignore" && (0, import_node_fs29.existsSync)(to)) {
8615
+ const from = (0, import_node_path38.join)(generatedRoot, entry);
8616
+ const to = (0, import_node_path38.join)(target, entry);
8617
+ if (entry === ".gitignore" && (0, import_node_fs31.existsSync)(to)) {
8527
8618
  result.mergedGitignore = mergeGitignore(from, to);
8528
8619
  result.kept.push(entry);
8529
8620
  continue;
8530
8621
  }
8531
- if ((0, import_node_fs29.existsSync)(to)) {
8622
+ if ((0, import_node_fs31.existsSync)(to)) {
8532
8623
  result.kept.push(entry);
8533
8624
  continue;
8534
8625
  }
8535
- (0, import_node_fs29.cpSync)(from, to, { recursive: true });
8626
+ (0, import_node_fs31.cpSync)(from, to, { recursive: true });
8536
8627
  result.copied.push(entry);
8537
8628
  }
8538
- (0, import_node_fs29.rmSync)(generatedRoot, { recursive: true, force: true });
8629
+ (0, import_node_fs31.rmSync)(generatedRoot, { recursive: true, force: true });
8539
8630
  return result;
8540
8631
  }
8541
8632
 
8542
8633
  // src/workspace-creation/create-workspace.use-case.ts
8543
- var import_node_fs30 = require("fs");
8634
+ var import_node_fs32 = require("fs");
8544
8635
  var import_node_os2 = require("os");
8545
- var import_node_path37 = require("path");
8636
+ var import_node_path39 = require("path");
8546
8637
  function nxCloudProviderValue(ci) {
8547
8638
  return ci === "azure" ? "azure" : "github";
8548
8639
  }
@@ -8585,9 +8676,9 @@ async function resolveRegistry(options) {
8585
8676
  return await promptRegistry();
8586
8677
  }
8587
8678
  async function runNew(name, options) {
8588
- const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path37.resolve)(process.cwd(), options.into);
8679
+ const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path39.resolve)(process.cwd(), options.into);
8589
8680
  if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
8590
- const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path37.basename)(adoptTarget));
8681
+ const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path39.basename)(adoptTarget));
8591
8682
  assertValidProjectName(workspaceName, "Workspace name");
8592
8683
  const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
8593
8684
  const registry = await resolveRegistry(options);
@@ -8600,8 +8691,8 @@ async function runNew(name, options) {
8600
8691
  const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
8601
8692
  const stack = await resolveStack(options);
8602
8693
  const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
8603
- const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs30.mkdtempSync)((0, import_node_path37.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8604
- let workspaceRoot = (0, import_node_path37.join)(stagingParent, workspaceName);
8694
+ const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs32.mkdtempSync)((0, import_node_path39.join)((0, import_node_os2.tmpdir)(), "mnci-new-"));
8695
+ let workspaceRoot = (0, import_node_path39.join)(stagingParent, workspaceName);
8605
8696
  try {
8606
8697
  logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
8607
8698
  runNpx(
@@ -8624,7 +8715,7 @@ async function runNew(name, options) {
8624
8715
  workspaceRoot = adoptTarget;
8625
8716
  }
8626
8717
  } finally {
8627
- if (adoptTarget !== void 0) (0, import_node_fs30.rmSync)(stagingParent, { recursive: true, force: true });
8718
+ if (adoptTarget !== void 0) (0, import_node_fs32.rmSync)(stagingParent, { recursive: true, force: true });
8628
8719
  }
8629
8720
  logger.step(
8630
8721
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
@@ -8634,8 +8725,8 @@ async function runNew(name, options) {
8634
8725
  { workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
8635
8726
  logger.detail
8636
8727
  );
8637
- (0, import_node_fs30.rmSync)((0, import_node_path37.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8638
- (0, import_node_fs30.rmSync)((0, import_node_path37.join)(workspaceRoot, "package-lock.json"), { force: true });
8728
+ (0, import_node_fs32.rmSync)((0, import_node_path39.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
8729
+ (0, import_node_fs32.rmSync)((0, import_node_path39.join)(workspaceRoot, "package-lock.json"), { force: true });
8639
8730
  logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
8640
8731
  const installStatus = runShell(
8641
8732
  "npm",
@@ -8673,12 +8764,12 @@ function projectKindHintLines(kinds = PROJECT_KINDS) {
8673
8764
  }
8674
8765
 
8675
8766
  // src/workspace-creation/interactive-wizard.use-case.ts
8676
- var import_node_path39 = require("path");
8767
+ var import_node_path41 = require("path");
8677
8768
  var import_prompts4 = require("@inquirer/prompts");
8678
8769
 
8679
8770
  // src/workspace-upgrade/upgrade-workspace.use-case.ts
8680
- var import_node_fs31 = require("fs");
8681
- var import_node_path38 = require("path");
8771
+ var import_node_fs33 = require("fs");
8772
+ var import_node_path40 = require("path");
8682
8773
  function resolveRegistry2(options, persisted) {
8683
8774
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
8684
8775
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -8707,7 +8798,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8707
8798
  return persisted.workspaceName;
8708
8799
  }
8709
8800
  try {
8710
- const existing = (0, import_node_fs31.readdirSync)(workspaceRoot).find(
8801
+ const existing = (0, import_node_fs33.readdirSync)(workspaceRoot).find(
8711
8802
  (file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
8712
8803
  );
8713
8804
  if (existing) {
@@ -8715,11 +8806,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
8715
8806
  }
8716
8807
  } catch {
8717
8808
  }
8718
- return (0, import_node_path38.basename)(workspaceRoot);
8809
+ return (0, import_node_path40.basename)(workspaceRoot);
8719
8810
  }
8720
8811
  function detectNpmAuth(workspaceRoot) {
8721
8812
  try {
8722
- return (0, import_node_fs31.readFileSync)((0, import_node_path38.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8813
+ return (0, import_node_fs33.readFileSync)((0, import_node_path40.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
8723
8814
  } catch {
8724
8815
  return void 0;
8725
8816
  }
@@ -8766,7 +8857,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
8766
8857
  };
8767
8858
  }
8768
8859
  function runUpgrade(workspaceRoot, options) {
8769
- if (!fileExists((0, import_node_path38.join)(workspaceRoot, "nx.json"))) {
8860
+ if (!fileExists((0, import_node_path40.join)(workspaceRoot, "nx.json"))) {
8770
8861
  throw new Error(
8771
8862
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
8772
8863
  );
@@ -8789,6 +8880,13 @@ function runUpgrade(workspaceRoot, options) {
8789
8880
  logger.detail(`updated ${path}`);
8790
8881
  }
8791
8882
  }
8883
+ const lockfile = pruneStaleLocalRegistry(workspaceRoot);
8884
+ if (lockfile.stale) {
8885
+ logger.step("Dropping the unused local registry (verdaccio) from package-lock.json");
8886
+ if (lockfile.status !== 0) {
8887
+ logger.warn("npm could not re-resolve the lockfile; run `npm install --package-lock-only` once you are online.");
8888
+ }
8889
+ }
8792
8890
  const goApps = addGoPlatformTargets(workspaceRoot);
8793
8891
  if (goApps.length > 0) {
8794
8892
  logger.step("Adding the six-platform build to Go apps (build-all, package-all)");
@@ -8832,7 +8930,7 @@ function runUpgrade(workspaceRoot, options) {
8832
8930
 
8833
8931
  // src/workspace-creation/interactive-wizard.use-case.ts
8834
8932
  async function runInteractive() {
8835
- const inWorkspace = fileExists((0, import_node_path39.join)(process.cwd(), "nx.json"));
8933
+ const inWorkspace = fileExists((0, import_node_path41.join)(process.cwd(), "nx.json"));
8836
8934
  const choiceNew = { name: "Create a new monorepo", value: "new" };
8837
8935
  const choiceAdd = { name: "Add a project to this workspace", value: "add" };
8838
8936
  const choiceUpgrade = {