@mnci/cli 1.12.1 → 1.13.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -15,14 +15,14 @@ config package, a custom CI engine, a dependency-injection step for published
15
15
  packages, a doctor/drift-sync system to keep it all consistent — already has a
16
16
  first-party (or established community) Nx equivalent:
17
17
 
18
- | Hand-rolled elsewhere | This CLI uses instead |
19
- | ------------------------------------------ | --------------------------------------------------------------------------- |
20
- | Template engine + per-project config files | `create-nx-workspace --preset=ts` + `nx g` plugin generators |
21
- | A shared toolchain package for configs | The configs the Nx generators emit (one root ESLint/tsconfig) |
22
- | A custom multi-step CI engine | `nx affected -t lint,test,build` + `nx release` (~60-line pipeline) |
23
- | A dist-package dependency injector | `nx release` updates dependent versions natively |
24
- | Hand-written Azure Function templates | `@nx/node:application` (plain Node app) + a thin Azure Functions v4 overlay |
25
- | doctor/drift sync of tool-owned files | Nothing to drift: this CLI owns 5 small files, Nx owns the rest |
18
+ | Hand-rolled elsewhere | This CLI uses instead |
19
+ | ------------------------------------------ | ----------------------------------------------------------------------------- |
20
+ | Template engine + per-project config files | `create-nx-workspace --preset=ts` + `nx g` plugin generators |
21
+ | A shared toolchain package for configs | The configs the Nx generators emit (one root ESLint/tsconfig) |
22
+ | A custom multi-step CI engine | `nx affected -t lint,typecheck,test,build` + `nx release` (~60-line pipeline) |
23
+ | A dist-package dependency injector | `nx release` updates dependent versions natively |
24
+ | Hand-written Azure Function templates | `@nx/node:application` (plain Node app) + a thin Azure Functions v4 overlay |
25
+ | doctor/drift sync of tool-owned files | Nothing to drift: this CLI owns 5 small files, Nx owns the rest |
26
26
 
27
27
  ## Commands (deliberately just three)
28
28
 
@@ -38,6 +38,8 @@ mnci add node-app api --framework express # ...or fastify | koa | nest
38
38
  mnci add node-function-app api # @nx/node + an Azure Functions v4 overlay
39
39
  mnci add npm-lib sdk # @nx/js publishable lib -> packages/
40
40
  mnci add internal-lib utils # @nx/js private lib -> libs/
41
+ mnci add react-lib ui # @nx/react publishable component lib -> packages/
42
+ mnci add react-internal-lib design # @nx/react private component lib -> libs/
41
43
 
42
44
  # Python (@mnci/nx-python-pip — pip + Ruff + pytest + PyPA build/twine, no uv)
43
45
  mnci add python-app svc # app -> apps/ (wheel, zipped into the drop)
@@ -69,7 +71,8 @@ each a single cross-platform command:
69
71
  | `npm run build` | `nx run-many -t build` |
70
72
  | `npm run lint` | `nx run-many -t lint` |
71
73
  | `npm run test` | `nx run-many -t test` |
72
- | `npm run affected` | `nx affected -t lint,test,build` (vs `main`) |
74
+ | `npm run typecheck` | `nx run-many -t typecheck` — its own script because a bundler-built project's `build` strips types without reading them |
75
+ | `npm run affected` | `nx affected -t lint,typecheck,test,build` (vs `main`) |
73
76
  | `npm run graph` | `nx graph` |
74
77
  | `npm run release:preview` | `nx release --dry-run` |
75
78
  | `npm run python:install` | fixed Python toolchain (ruff/pytest/build/twine) + editable-install every Python project — the same two guards CI runs, for local dev |
package/dist/cli.js CHANGED
@@ -38,8 +38,8 @@ module.exports = __toCommonJS(cli_exports);
38
38
  var import_commander = require("commander");
39
39
 
40
40
  // src/commands/add.ts
41
- var import_node_path9 = require("path");
42
- var import_prompts4 = require("@inquirer/prompts");
41
+ var import_node_path10 = require("path");
42
+ var import_prompts5 = require("@inquirer/prompts");
43
43
 
44
44
  // src/nx.ts
45
45
  var import_cross_spawn = __toESM(require("cross-spawn"));
@@ -192,6 +192,21 @@ function hasPlugin(workspaceRoot, packageName) {
192
192
  const installed = { ...manifest.dependencies, ...manifest.devDependencies };
193
193
  return Object.hasOwn(installed, packageName);
194
194
  }
195
+ function ensurePlugin(workspaceRoot, packageName) {
196
+ if (hasPlugin(workspaceRoot, packageName)) {
197
+ return;
198
+ }
199
+ logger.step(`Installing Nx plugin ${packageName}`);
200
+ runNx(["add", packageName], workspaceRoot);
201
+ }
202
+ function markPrivate(manifestPath) {
203
+ const manifest = readJson(manifestPath);
204
+ writeFileEnsured(manifestPath, toJson({ ...manifest, private: true }));
205
+ }
206
+ function markPublic(manifestPath) {
207
+ const manifest = readJson(manifestPath);
208
+ writeFileEnsured(manifestPath, toJson({ ...manifest, publishConfig: { access: "public" } }));
209
+ }
195
210
  function ensureAdmZip(workspaceRoot) {
196
211
  if (hasPlugin(workspaceRoot, "adm-zip")) {
197
212
  return;
@@ -525,7 +540,7 @@ function addGoInternalLib(workspaceRoot, name) {
525
540
 
526
541
  // src/commands/add/node.ts
527
542
  var import_node_path5 = require("path");
528
- function ensurePlugin(workspaceRoot, packageName) {
543
+ function ensurePlugin2(workspaceRoot, packageName) {
529
544
  if (hasPlugin(workspaceRoot, packageName)) {
530
545
  return;
531
546
  }
@@ -533,7 +548,7 @@ function ensurePlugin(workspaceRoot, packageName) {
533
548
  runNx(["add", packageName], workspaceRoot);
534
549
  }
535
550
  function runNodeApp(workspaceRoot, name, stack, framework) {
536
- ensurePlugin(workspaceRoot, "@nx/node");
551
+ ensurePlugin2(workspaceRoot, "@nx/node");
537
552
  runNx(
538
553
  [
539
554
  "g",
@@ -699,10 +714,6 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
699
714
  removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
700
715
  registerProjectCommands(workspaceRoot, name, { build: true });
701
716
  }
702
- function markPublic(manifestPath) {
703
- const manifest = readJson(manifestPath);
704
- writeFileEnsured(manifestPath, toJson({ ...manifest, publishConfig: { access: "public" } }));
705
- }
706
717
 
707
718
  // src/commands/add/python.ts
708
719
  var import_node_fs4 = require("fs");
@@ -926,13 +937,6 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
926
937
  // src/commands/add/reactApp.ts
927
938
  var import_node_fs5 = require("fs");
928
939
  var import_node_path8 = require("path");
929
- function ensurePlugin2(workspaceRoot, packageName) {
930
- if (hasPlugin(workspaceRoot, packageName)) {
931
- return;
932
- }
933
- logger.step(`Installing Nx plugin ${packageName}`);
934
- runNx(["add", packageName], workspaceRoot);
935
- }
936
940
  var REACT_ENVIRONMENTS = ["dev", "uat", "prod"];
937
941
  function reactEnvironmentFile(environment) {
938
942
  return `# Vite compiles VITE_-prefixed vars into the '${environment}' bundle at build time.
@@ -985,7 +989,7 @@ ${allow}
985
989
  `);
986
990
  }
987
991
  function addReactApp(workspaceRoot, name, stack) {
988
- ensurePlugin2(workspaceRoot, "@nx/react");
992
+ ensurePlugin(workspaceRoot, "@nx/react");
989
993
  runNx(
990
994
  [
991
995
  "g",
@@ -1011,9 +1015,73 @@ function addReactApp(workspaceRoot, name, stack) {
1011
1015
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
1012
1016
  }
1013
1017
 
1018
+ // src/commands/add/reactLib.ts
1019
+ var import_node_path9 = require("path");
1020
+ var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
1021
+ var ACTUAL_TYPES_PATH = "./dist/index.d.ts";
1022
+ function repairTypesPath(manifestPath) {
1023
+ const manifest = readJson(manifestPath);
1024
+ if (manifest.types === WRONG_TYPES_PATH) {
1025
+ manifest.types = ACTUAL_TYPES_PATH;
1026
+ }
1027
+ const dot = manifest.exports?.["."];
1028
+ if (typeof dot === "object" && dot.types === WRONG_TYPES_PATH) {
1029
+ dot.types = ACTUAL_TYPES_PATH;
1030
+ }
1031
+ writeFileEnsured(manifestPath, toJson(manifest));
1032
+ }
1033
+ var REACT_LIB_BUNDLER = "rollup";
1034
+ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
1035
+ ensurePlugin(workspaceRoot, "@nx/react");
1036
+ const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
1037
+ runNx(
1038
+ [
1039
+ "g",
1040
+ "@nx/react:library",
1041
+ `packages/${name}`,
1042
+ `--name=${name}`,
1043
+ "--publishable",
1044
+ `--importPath=${scope}/${name}`,
1045
+ `--bundler=${REACT_LIB_BUNDLER}`,
1046
+ `--unitTestRunner=${stack.testRunner}`,
1047
+ "--linter=none",
1048
+ "--no-interactive"
1049
+ ],
1050
+ workspaceRoot
1051
+ );
1052
+ const publishableManifest = (0, import_node_path9.join)(workspaceRoot, "packages", name, "package.json");
1053
+ markPublic(publishableManifest);
1054
+ repairTypesPath(publishableManifest);
1055
+ removeGeneratedEslintConfig(workspaceRoot, `packages/${name}`);
1056
+ registerProjectCommands(workspaceRoot, name, { build: true });
1057
+ }
1058
+ function addReactInternalLib(workspaceRoot, name, stack) {
1059
+ ensurePlugin(workspaceRoot, "@nx/react");
1060
+ runNx(
1061
+ [
1062
+ "g",
1063
+ "@nx/react:library",
1064
+ `libs/${name}`,
1065
+ `--name=${name}`,
1066
+ `--bundler=${REACT_LIB_BUNDLER}`,
1067
+ `--unitTestRunner=${stack.testRunner}`,
1068
+ "--linter=none",
1069
+ "--no-interactive"
1070
+ ],
1071
+ workspaceRoot
1072
+ );
1073
+ const privateManifest = (0, import_node_path9.join)(workspaceRoot, "libs", name, "package.json");
1074
+ markPrivate(privateManifest);
1075
+ repairTypesPath(privateManifest);
1076
+ removeGeneratedEslintConfig(workspaceRoot, `libs/${name}`);
1077
+ registerProjectCommands(workspaceRoot, name, { build: true });
1078
+ }
1079
+
1014
1080
  // src/commands/add.ts
1015
1081
  var PROJECT_KINDS = [
1016
1082
  "react-app",
1083
+ "react-lib",
1084
+ "react-internal-lib",
1017
1085
  "node-app",
1018
1086
  "node-function-app",
1019
1087
  "npm-lib",
@@ -1033,12 +1101,12 @@ var PROJECT_KINDS = [
1033
1101
  ];
1034
1102
  async function runAdd(kind, name, options) {
1035
1103
  const workspaceRoot = process.cwd();
1036
- if (!fileExists((0, import_node_path9.join)(workspaceRoot, "nx.json"))) {
1104
+ if (!fileExists((0, import_node_path10.join)(workspaceRoot, "nx.json"))) {
1037
1105
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
1038
1106
  }
1039
1107
  const stack = readWorkspaceStack(workspaceRoot);
1040
1108
  const kindProvided = kind !== void 0;
1041
- const resolvedKind = kind ?? await (0, import_prompts4.select)({
1109
+ const resolvedKind = kind ?? await (0, import_prompts5.select)({
1042
1110
  message: "What kind of project?",
1043
1111
  choices: PROJECT_KINDS.map((value) => ({ name: value, value }))
1044
1112
  });
@@ -1049,6 +1117,14 @@ async function runAdd(kind, name, options) {
1049
1117
  addReactApp(workspaceRoot, resolvedName, stack);
1050
1118
  break;
1051
1119
  }
1120
+ case "react-lib": {
1121
+ await addReactLib(workspaceRoot, resolvedName, options, kindProvided, stack);
1122
+ break;
1123
+ }
1124
+ case "react-internal-lib": {
1125
+ addReactInternalLib(workspaceRoot, resolvedName, stack);
1126
+ break;
1127
+ }
1052
1128
  case "node-app": {
1053
1129
  addNodeApp(workspaceRoot, resolvedName, stack, options.framework);
1054
1130
  break;
@@ -1074,7 +1150,7 @@ async function runAdd(kind, name, options) {
1074
1150
  ],
1075
1151
  workspaceRoot
1076
1152
  );
1077
- markPrivate((0, import_node_path9.join)(workspaceRoot, "libs", resolvedName, "package.json"));
1153
+ markPrivate((0, import_node_path10.join)(workspaceRoot, "libs", resolvedName, "package.json"));
1078
1154
  removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
1079
1155
  registerProjectCommands(workspaceRoot, resolvedName, { build: true });
1080
1156
  break;
@@ -1150,28 +1226,24 @@ function syncProjectReferences(workspaceRoot) {
1150
1226
  }
1151
1227
  function readWorkspaceStack(workspaceRoot) {
1152
1228
  const nxJson = readJson(
1153
- (0, import_node_path9.join)(workspaceRoot, "nx.json")
1229
+ (0, import_node_path10.join)(workspaceRoot, "nx.json")
1154
1230
  );
1155
1231
  const stack = nxJson.mnci?.stack;
1156
1232
  return {
1157
1233
  testRunner: stack?.testRunner === "vitest" ? "vitest" : "jest"
1158
1234
  };
1159
1235
  }
1160
- function markPrivate(manifestPath) {
1161
- const manifest = readJson(manifestPath);
1162
- writeFileEnsured(manifestPath, toJson({ ...manifest, private: true }));
1163
- }
1164
1236
 
1165
1237
  // src/commands/interactive.ts
1166
- var import_node_path13 = require("path");
1167
- var import_prompts7 = require("@inquirer/prompts");
1238
+ var import_node_path14 = require("path");
1239
+ var import_prompts8 = require("@inquirer/prompts");
1168
1240
 
1169
1241
  // src/commands/new.ts
1170
- var import_node_path11 = require("path");
1242
+ var import_node_path12 = require("path");
1171
1243
 
1172
1244
  // src/overlay.ts
1173
1245
  var import_node_fs6 = require("fs");
1174
- var import_node_path10 = require("path");
1246
+ var import_node_path11 = require("path");
1175
1247
  var DEFAULT_STACK = { testRunner: "jest" };
1176
1248
  var PRETTIER_VERSION = "^3.8.1";
1177
1249
  var TS_COMPILER_DEPENDENCIES = {
@@ -1330,7 +1402,8 @@ var ROOT_SCRIPTS = {
1330
1402
  build: "nx run-many -t build",
1331
1403
  lint: "nx run-many -t lint",
1332
1404
  test: "nx run-many -t test",
1333
- affected: "nx affected -t lint,test,build",
1405
+ typecheck: "nx run-many -t typecheck",
1406
+ affected: "nx affected -t lint,typecheck,test,build",
1334
1407
  graph: "nx graph",
1335
1408
  "release:preview": "nx release --dry-run",
1336
1409
  prepare: "husky"
@@ -1377,7 +1450,7 @@ function mnciConfig(options) {
1377
1450
  };
1378
1451
  }
1379
1452
  function readMnciConfig(workspaceRoot) {
1380
- const nxJson = readJson((0, import_node_path10.join)(workspaceRoot, "nx.json"));
1453
+ const nxJson = readJson((0, import_node_path11.join)(workspaceRoot, "nx.json"));
1381
1454
  return nxJson.mnci ?? {};
1382
1455
  }
1383
1456
  function pythonPublishUrl(registry) {
@@ -1554,10 +1627,14 @@ steps:
1554
1627
  displayName: Check formatting (run 'npm run format' locally to fix)
1555
1628
  # \`lint\` here also runs any Nx lint targets \`npm run lint\` does not cover \u2014
1556
1629
  # notably Python's ruff (every Python project owns a hand-authored \`lint\`
1557
- # target). For the eslint stack the JS lint runs twice, but Nx caches the
1558
- # repeat instantly.
1559
- - script: npx nx run-many -t lint,test,build
1560
- displayName: Lint, test and build everything
1630
+ # target). The JS lint runs twice, but Nx caches the repeat instantly.
1631
+ #
1632
+ # \`typecheck\` is load-bearing and not covered by \`build\`: a bundler-built
1633
+ # project (esbuild, swc) strips types without reading them, so a workspace can
1634
+ # build, test and lint green while carrying real type errors. --preset=ts
1635
+ # infers a typecheck target for every project, so this costs one target name.
1636
+ - script: npx nx run-many -t lint,typecheck,test,build
1637
+ displayName: Lint, typecheck, test and build everything
1561
1638
 
1562
1639
  # Pack every app into dist/drop/<type>-<name>.zip via each app's 'package'
1563
1640
  # target. Portable guard: skip cleanly when the workspace has no apps yet.
@@ -1732,10 +1809,15 @@ jobs:
1732
1809
  name: Check formatting (run 'npm run format' locally to fix)
1733
1810
  # \`lint\` here also runs any Nx lint targets \`npm run lint\` does not cover \u2014
1734
1811
  # notably Python's ruff (every Python project owns a hand-authored \`lint\`
1735
- # target). For the eslint stack the JS lint runs twice, but Nx caches the
1736
- # repeat instantly.
1737
- - run: npx nx run-many -t lint,test,build
1738
- name: Lint, test and build everything
1812
+ # target). The JS lint runs twice, but Nx caches the repeat instantly.
1813
+ #
1814
+ # \`typecheck\` is load-bearing and not covered by \`build\`: a bundler-built
1815
+ # project (esbuild, swc) strips types without reading them, so a workspace
1816
+ # can build, test and lint green while carrying real type errors.
1817
+ # --preset=ts infers a typecheck target for every project, so this costs
1818
+ # one target name.
1819
+ - run: npx nx run-many -t lint,typecheck,test,build
1820
+ name: Lint, typecheck, test and build everything
1739
1821
 
1740
1822
  # Pack every app into dist/drop/<type>-<name>.zip via each app's 'package'
1741
1823
  # target. Portable guard: skip cleanly when the workspace has no apps yet.
@@ -1818,7 +1900,7 @@ updates:
1818
1900
  var NX_SCAFFOLDING_TO_REMOVE = [".prettierrc", ".vscode"];
1819
1901
  function removeNxScaffolding(workspaceRoot) {
1820
1902
  for (const entry of NX_SCAFFOLDING_TO_REMOVE) {
1821
- (0, import_node_fs6.rmSync)((0, import_node_path10.join)(workspaceRoot, entry), { recursive: true, force: true });
1903
+ (0, import_node_fs6.rmSync)((0, import_node_path11.join)(workspaceRoot, entry), { recursive: true, force: true });
1822
1904
  }
1823
1905
  removeProjectEslintConfigs(workspaceRoot);
1824
1906
  }
@@ -1827,11 +1909,11 @@ function removeProjectEslintConfigs(workspaceRoot) {
1827
1909
  cwd: workspaceRoot
1828
1910
  });
1829
1911
  for (const match of matches) {
1830
- (0, import_node_fs6.rmSync)((0, import_node_path10.join)(workspaceRoot, match), { force: true });
1912
+ (0, import_node_fs6.rmSync)((0, import_node_path11.join)(workspaceRoot, match), { force: true });
1831
1913
  }
1832
1914
  }
1833
1915
  function applyOverlay(workspaceRoot, options) {
1834
- const nxJsonPath = (0, import_node_path10.join)(workspaceRoot, "nx.json");
1916
+ const nxJsonPath = (0, import_node_path11.join)(workspaceRoot, "nx.json");
1835
1917
  const nxJson = readJson(nxJsonPath);
1836
1918
  const generators = {
1837
1919
  ...nxJson.generators,
@@ -1841,7 +1923,7 @@ function applyOverlay(workspaceRoot, options) {
1841
1923
  const mnci = { ...nxJson.mnci, ...mnciConfig(options) };
1842
1924
  const patched = withEslintPlugin(withReleaseConfig(nxJson, options.ci));
1843
1925
  writeFileEnsured(nxJsonPath, toJson({ ...patched, generators, sync, mnci }));
1844
- const manifestPath = (0, import_node_path10.join)(workspaceRoot, "package.json");
1926
+ const manifestPath = (0, import_node_path11.join)(workspaceRoot, "package.json");
1845
1927
  const manifest = readJson(manifestPath);
1846
1928
  const scripts = {
1847
1929
  ...manifest.scripts,
@@ -1859,34 +1941,34 @@ function applyOverlay(workspaceRoot, options) {
1859
1941
  manifestPath,
1860
1942
  toJson({ ...manifest, name: `${options.scope}/source`, scripts, devDependencies: devDeps })
1861
1943
  );
1862
- writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".npmrc"), npmrcContent(options.registry, options.scope));
1863
- writeFileEnsured((0, import_node_path10.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
1864
- const hookPath = (0, import_node_path10.join)(workspaceRoot, ".husky/commit-msg");
1944
+ writeFileEnsured((0, import_node_path11.join)(workspaceRoot, ".npmrc"), npmrcContent(options.registry, options.scope));
1945
+ writeFileEnsured((0, import_node_path11.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
1946
+ const hookPath = (0, import_node_path11.join)(workspaceRoot, ".husky/commit-msg");
1865
1947
  writeFileEnsured(hookPath, COMMIT_MSG_HOOK);
1866
1948
  markExecutable(hookPath);
1867
- writeFileEnsured((0, import_node_path10.join)(workspaceRoot, "eslint.config.mjs"), ESLINT_CONFIG);
1868
- writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".prettierrc.json"), PRETTIER_CONFIG);
1869
- writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".prettierignore"), PRETTIER_IGNORE);
1949
+ writeFileEnsured((0, import_node_path11.join)(workspaceRoot, "eslint.config.mjs"), ESLINT_CONFIG);
1950
+ writeFileEnsured((0, import_node_path11.join)(workspaceRoot, ".prettierrc.json"), PRETTIER_CONFIG);
1951
+ writeFileEnsured((0, import_node_path11.join)(workspaceRoot, ".prettierignore"), PRETTIER_IGNORE);
1870
1952
  removeNxScaffolding(workspaceRoot);
1871
- const codeWorkspacePath = (0, import_node_path10.join)(workspaceRoot, `${options.workspaceName}.code-workspace`);
1953
+ const codeWorkspacePath = (0, import_node_path11.join)(workspaceRoot, `${options.workspaceName}.code-workspace`);
1872
1954
  const existing = readCodeWorkspace(codeWorkspacePath);
1873
1955
  writeFileEnsured(codeWorkspacePath, vscodeWorkspace(options.workspaceName, existing?.tasks));
1874
1956
  if (options.workspaceName !== "undefined") {
1875
- (0, import_node_fs6.rmSync)((0, import_node_path10.join)(workspaceRoot, "undefined.code-workspace"), { force: true });
1957
+ (0, import_node_fs6.rmSync)((0, import_node_path11.join)(workspaceRoot, "undefined.code-workspace"), { force: true });
1876
1958
  }
1877
1959
  const publishUrl = pythonPublishUrl(options.registry);
1878
1960
  if (options.ci === "azure" || options.ci === "both") {
1879
1961
  writeFileEnsured(
1880
- (0, import_node_path10.join)(workspaceRoot, "azure-pipelines.yml"),
1962
+ (0, import_node_path11.join)(workspaceRoot, "azure-pipelines.yml"),
1881
1963
  azurePipelinesYaml(options.agent, options.variableGroup, publishUrl, options.registry.kind)
1882
1964
  );
1883
1965
  }
1884
1966
  if (options.ci === "github" || options.ci === "both") {
1885
1967
  writeFileEnsured(
1886
- (0, import_node_path10.join)(workspaceRoot, ".github/workflows/ci.yml"),
1968
+ (0, import_node_path11.join)(workspaceRoot, ".github/workflows/ci.yml"),
1887
1969
  githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci)
1888
1970
  );
1889
- writeFileEnsured((0, import_node_path10.join)(workspaceRoot, ".github/dependabot.yml"), DEPENDABOT_CONFIG);
1971
+ writeFileEnsured((0, import_node_path11.join)(workspaceRoot, ".github/dependabot.yml"), DEPENDABOT_CONFIG);
1890
1972
  }
1891
1973
  }
1892
1974
 
@@ -1955,7 +2037,7 @@ async function runNew(name, options) {
1955
2037
  ],
1956
2038
  process.cwd()
1957
2039
  );
1958
- const workspaceRoot = (0, import_node_path11.join)(process.cwd(), workspaceName);
2040
+ const workspaceRoot = (0, import_node_path12.join)(process.cwd(), workspaceName);
1959
2041
  logger.step(
1960
2042
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
1961
2043
  );
@@ -1974,9 +2056,8 @@ async function runNew(name, options) {
1974
2056
  runPrettier(workspaceRoot);
1975
2057
  logger.success("Done. Next steps:");
1976
2058
  logger.info(` cd ${workspaceName}`);
1977
- logger.info(
1978
- " mnci add react-app web # or: node-app, node-function-app, npm-lib, internal-lib,"
1979
- );
2059
+ logger.info(" mnci add react-app web # or: react-lib, react-internal-lib, node-app,");
2060
+ logger.info(" # node-function-app, npm-lib, internal-lib,");
1980
2061
  logger.info(
1981
2062
  " # python-app, python-function-app, python-lib, python-internal-lib,"
1982
2063
  );
@@ -1991,7 +2072,7 @@ async function runNew(name, options) {
1991
2072
 
1992
2073
  // src/commands/upgrade.ts
1993
2074
  var import_node_fs7 = require("fs");
1994
- var import_node_path12 = require("path");
2075
+ var import_node_path13 = require("path");
1995
2076
  function resolveRegistry2(options, persisted) {
1996
2077
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
1997
2078
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -2028,7 +2109,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
2028
2109
  }
2029
2110
  } catch {
2030
2111
  }
2031
- return (0, import_node_path12.basename)(workspaceRoot);
2112
+ return (0, import_node_path13.basename)(workspaceRoot);
2032
2113
  }
2033
2114
  function resolveOverlayOptions(workspaceRoot, options, persisted) {
2034
2115
  const scope = options.scope ?? persisted.scope;
@@ -2066,7 +2147,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
2066
2147
  };
2067
2148
  }
2068
2149
  function runUpgrade(workspaceRoot, options) {
2069
- if (!fileExists((0, import_node_path12.join)(workspaceRoot, "nx.json"))) {
2150
+ if (!fileExists((0, import_node_path13.join)(workspaceRoot, "nx.json"))) {
2070
2151
  throw new Error(
2071
2152
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
2072
2153
  );
@@ -2083,14 +2164,14 @@ function runUpgrade(workspaceRoot, options) {
2083
2164
 
2084
2165
  // src/commands/interactive.ts
2085
2166
  async function runInteractive() {
2086
- const inWorkspace = fileExists((0, import_node_path13.join)(process.cwd(), "nx.json"));
2167
+ const inWorkspace = fileExists((0, import_node_path14.join)(process.cwd(), "nx.json"));
2087
2168
  const newChoice = { name: "Create a new monorepo", value: "new" };
2088
2169
  const addChoice = { name: "Add a project to this workspace", value: "add" };
2089
2170
  const upgradeChoice = {
2090
2171
  name: "Upgrade this workspace (re-apply the latest overlay)",
2091
2172
  value: "upgrade"
2092
2173
  };
2093
- const action = await (0, import_prompts7.select)({
2174
+ const action = await (0, import_prompts8.select)({
2094
2175
  message: "What would you like to do?",
2095
2176
  choices: inWorkspace ? [addChoice, upgradeChoice, newChoice] : [newChoice, addChoice, upgradeChoice]
2096
2177
  });
@@ -2105,7 +2186,7 @@ async function runInteractive() {
2105
2186
 
2106
2187
  // src/util/versionChecker.ts
2107
2188
  var import_node_fs8 = require("fs");
2108
- var import_node_path14 = require("path");
2189
+ var import_node_path15 = require("path");
2109
2190
  var import_cross_spawn2 = __toESM(require("cross-spawn"));
2110
2191
  var PACKAGE_NAME = "@mnci/cli";
2111
2192
  var REGISTRY_TIMEOUT_MS = 2e3;
@@ -2161,7 +2242,7 @@ function releaseTriple(version) {
2161
2242
  }
2162
2243
  function readCliVersion(packageDirectory) {
2163
2244
  try {
2164
- const manifestPath = (0, import_node_path14.join)(packageDirectory, "..", "package.json");
2245
+ const manifestPath = (0, import_node_path15.join)(packageDirectory, "..", "package.json");
2165
2246
  const manifest = JSON.parse((0, import_node_fs8.readFileSync)(manifestPath, "utf8"));
2166
2247
  return manifest.version ?? "0.0.0";
2167
2248
  } catch {