@mnci/cli 4.16.0 → 4.17.1

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
@@ -37,6 +37,10 @@ __export(main_exports, {
37
37
  module.exports = __toCommonJS(main_exports);
38
38
  var import_commander = require("commander");
39
39
 
40
+ // src/ci-pipeline/pack.use-case.ts
41
+ var import_node_fs = require("fs");
42
+ var import_node_path = require("path");
43
+
40
44
  // src/nx-workspace/nx.client.ts
41
45
  var import_cross_spawn = __toESM(require("cross-spawn"));
42
46
 
@@ -196,15 +200,95 @@ function runFormatter(cwd, target = ".") {
196
200
  }
197
201
  }
198
202
 
203
+ // src/ci-pipeline/ci-environment.client.ts
204
+ function detectCiHost(environment) {
205
+ if (environment.GITHUB_ACTIONS === "true") {
206
+ return "github";
207
+ }
208
+ if (environment.TF_BUILD !== void 0 && environment.TF_BUILD !== "") {
209
+ return "azure";
210
+ }
211
+ return "local";
212
+ }
213
+ function pullRequestTarget(environment) {
214
+ const reference = environment.GITHUB_BASE_REF || environment.SYSTEM_PULLREQUEST_TARGETBRANCH || "";
215
+ return reference === "" ? void 0 : reference.replace("refs/heads/", "");
216
+ }
217
+ function groupStart(host, title) {
218
+ switch (host) {
219
+ case "github": {
220
+ return `::group::${title}`;
221
+ }
222
+ case "azure": {
223
+ return `##[group]${title}`;
224
+ }
225
+ case "local": {
226
+ return `
227
+ \u25B8 ${title}`;
228
+ }
229
+ }
230
+ }
231
+ function groupEnd(host) {
232
+ switch (host) {
233
+ case "github": {
234
+ return "::endgroup::";
235
+ }
236
+ case "azure": {
237
+ return "##[endgroup]";
238
+ }
239
+ case "local": {
240
+ return void 0;
241
+ }
242
+ }
243
+ }
244
+
245
+ // src/ci-pipeline/pack.use-case.ts
246
+ function hasAppToPack(workspaceRoot) {
247
+ const hasProjectJson = (0, import_node_fs.globSync)("apps/*/project.json", { cwd: workspaceRoot }).length > 0;
248
+ const hasInlineNx = (0, import_node_fs.globSync)("apps/*/package.json", { cwd: workspaceRoot }).some((manifest) => {
249
+ try {
250
+ const parsed = JSON.parse((0, import_node_fs.readFileSync)((0, import_node_path.join)(workspaceRoot, manifest), "utf8"));
251
+ return Boolean(parsed.nx);
252
+ } catch {
253
+ return false;
254
+ }
255
+ });
256
+ const hasCsproj = (0, import_node_fs.globSync)("apps/*/*.csproj", { cwd: workspaceRoot }).length > 0;
257
+ return hasProjectJson || hasInlineNx || hasCsproj;
258
+ }
259
+ function runPack(workspaceRoot, dependencies = {}) {
260
+ const environment = dependencies.environment ?? process.env;
261
+ const processes = dependencies.processes ?? {
262
+ run: (command, arguments_) => runShell(command, arguments_, workspaceRoot),
263
+ capture: () => ({ status: 1, stdout: "" })
264
+ };
265
+ const log = dependencies.log ?? ((message) => {
266
+ console.log(message);
267
+ });
268
+ const host = detectCiHost(environment);
269
+ (0, import_node_fs.mkdirSync)((0, import_node_path.join)(workspaceRoot, "dist", "drop"), { recursive: true });
270
+ if (!hasAppToPack(workspaceRoot)) {
271
+ log("No apps to pack - skipping.");
272
+ return 0;
273
+ }
274
+ log(groupStart(host, "Pack all apps"));
275
+ const status = processes.run("npx", ["nx", "run-many", "-t", "package"]);
276
+ const closing = groupEnd(host);
277
+ if (closing !== void 0) {
278
+ log(closing);
279
+ }
280
+ return status;
281
+ }
282
+
199
283
  // src/workspace-overlay/overlay.use-case.ts
200
- var import_node_fs2 = require("fs");
201
- var import_node_path2 = require("path");
284
+ var import_node_fs3 = require("fs");
285
+ var import_node_path3 = require("path");
202
286
 
203
287
  // src/file-system/file-system.client.ts
204
- var import_node_fs = require("fs");
205
- var import_node_path = require("path");
288
+ var import_node_fs2 = require("fs");
289
+ var import_node_path2 = require("path");
206
290
  function readJson(path) {
207
- return JSON.parse((0, import_node_fs.readFileSync)(path, "utf8"));
291
+ return JSON.parse((0, import_node_fs2.readFileSync)(path, "utf8"));
208
292
  }
209
293
  function stripJsonComments(text) {
210
294
  let result = "";
@@ -261,7 +345,7 @@ function stripJsonComments(text) {
261
345
  }
262
346
  function readCodeWorkspace(path) {
263
347
  try {
264
- const withoutComments = stripJsonComments((0, import_node_fs.readFileSync)(path, "utf8"));
348
+ const withoutComments = stripJsonComments((0, import_node_fs2.readFileSync)(path, "utf8"));
265
349
  return JSON.parse(withoutComments.replaceAll(/,(\s*[}\]])/g, "$1"));
266
350
  } catch {
267
351
  return void 0;
@@ -272,14 +356,14 @@ function toJson(value) {
272
356
  `;
273
357
  }
274
358
  function writeFileEnsured(path, content) {
275
- (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path), { recursive: true });
276
- (0, import_node_fs.writeFileSync)(path, content);
359
+ (0, import_node_fs2.mkdirSync)((0, import_node_path2.dirname)(path), { recursive: true });
360
+ (0, import_node_fs2.writeFileSync)(path, content);
277
361
  }
278
362
  function markExecutable(path) {
279
- (0, import_node_fs.chmodSync)(path, 493);
363
+ (0, import_node_fs2.chmodSync)(path, 493);
280
364
  }
281
365
  function fileExists(path) {
282
- return (0, import_node_fs.existsSync)(path);
366
+ return (0, import_node_fs2.existsSync)(path);
283
367
  }
284
368
 
285
369
  // src/workspace-overlay/overlay.use-case.ts
@@ -422,9 +506,9 @@ var VSCODE_EXTENSION_TAG = "type:vscode-extension";
422
506
  var GO_RELEASE_TAG = "release:go";
423
507
  var GO_CGO_TAG = "build:cgo";
424
508
  function hasNativeGoApp(workspaceRoot) {
425
- return (0, import_node_fs2.globSync)("apps/*/project.json", { cwd: workspaceRoot }).some((projectJson) => {
509
+ return (0, import_node_fs3.globSync)("apps/*/project.json", { cwd: workspaceRoot }).some((projectJson) => {
426
510
  try {
427
- const { tags } = JSON.parse((0, import_node_fs2.readFileSync)((0, import_node_path2.join)(workspaceRoot, projectJson), "utf8"));
511
+ const { tags } = JSON.parse((0, import_node_fs3.readFileSync)((0, import_node_path3.join)(workspaceRoot, projectJson), "utf8"));
428
512
  return (tags ?? []).includes(GO_CGO_TAG);
429
513
  } catch {
430
514
  return false;
@@ -765,8 +849,8 @@ function isUnmodifiedMnciEslintConfig(content) {
765
849
  return code.length === 2 && code[0] === "import mnci from '@mnci/eslint-config'" && code[1] === "export default mnci({ workspaceRoot: import.meta.dirname })";
766
850
  }
767
851
  function writeEslintEntryPoint(workspaceRoot, onProgress) {
768
- const path = (0, import_node_path2.join)(workspaceRoot, ESLINT_USER_FILENAME);
769
- if ((0, import_node_fs2.existsSync)(path) && !isUnmodifiedMnciEslintConfig((0, import_node_fs2.readFileSync)(path, "utf8"))) {
852
+ const path = (0, import_node_path3.join)(workspaceRoot, ESLINT_USER_FILENAME);
853
+ if ((0, import_node_fs3.existsSync)(path) && !isUnmodifiedMnciEslintConfig((0, import_node_fs3.readFileSync)(path, "utf8"))) {
770
854
  onProgress(`${ESLINT_USER_FILENAME} \u2014 kept as it is, it is yours`);
771
855
  return;
772
856
  }
@@ -934,7 +1018,7 @@ function mnciConfig(options) {
934
1018
  };
935
1019
  }
936
1020
  function readMnciConfig(workspaceRoot) {
937
- const nxJson = readJson((0, import_node_path2.join)(workspaceRoot, "nx.json"));
1021
+ const nxJson = readJson((0, import_node_path3.join)(workspaceRoot, "nx.json"));
938
1022
  return nxJson.mnci ?? {};
939
1023
  }
940
1024
  function pythonPublishUrl(registry) {
@@ -1861,12 +1945,12 @@ var ECOSYSTEM_MANIFESTS = {
1861
1945
  };
1862
1946
  function hasEcosystemProject(workspaceRoot, roots, manifests) {
1863
1947
  return roots.some((root) => {
1864
- const base = (0, import_node_path2.join)(workspaceRoot, root);
1865
- if (!(0, import_node_fs2.existsSync)(base)) {
1948
+ const base = (0, import_node_path3.join)(workspaceRoot, root);
1949
+ if (!(0, import_node_fs3.existsSync)(base)) {
1866
1950
  return false;
1867
1951
  }
1868
- return (0, import_node_fs2.readdirSync)(base, { withFileTypes: true }).some(
1869
- (entry) => entry.isDirectory() && manifests.some((manifest) => (0, import_node_fs2.existsSync)((0, import_node_path2.join)(base, entry.name, manifest)))
1952
+ return (0, import_node_fs3.readdirSync)(base, { withFileTypes: true }).some(
1953
+ (entry) => entry.isDirectory() && manifests.some((manifest) => (0, import_node_fs3.existsSync)((0, import_node_path3.join)(base, entry.name, manifest)))
1870
1954
  );
1871
1955
  });
1872
1956
  }
@@ -1944,11 +2028,11 @@ var LOCAL_REGISTRY_SCAFFOLDING = {
1944
2028
  rootTarget: "local-registry"
1945
2029
  };
1946
2030
  function removeLocalRegistryScaffolding(workspaceRoot) {
1947
- (0, import_node_fs2.rmSync)((0, import_node_path2.join)(workspaceRoot, LOCAL_REGISTRY_SCAFFOLDING.directory), {
2031
+ (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, LOCAL_REGISTRY_SCAFFOLDING.directory), {
1948
2032
  recursive: true,
1949
2033
  force: true
1950
2034
  });
1951
- const manifestPath = (0, import_node_path2.join)(workspaceRoot, "package.json");
2035
+ const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
1952
2036
  if (!fileExists(manifestPath)) return;
1953
2037
  const manifest = readJson(manifestPath);
1954
2038
  if (manifest.devDependencies?.[LOCAL_REGISTRY_SCAFFOLDING.devDependency] !== void 0) {
@@ -1964,23 +2048,23 @@ function removeLocalRegistryScaffolding(workspaceRoot) {
1964
2048
  }
1965
2049
  function removeNxScaffolding(workspaceRoot) {
1966
2050
  for (const entry of NX_SCAFFOLDING_TO_REMOVE) {
1967
- (0, import_node_fs2.rmSync)((0, import_node_path2.join)(workspaceRoot, entry), { recursive: true, force: true });
2051
+ (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, entry), { recursive: true, force: true });
1968
2052
  }
1969
2053
  removeNxAuthoredAgentFiles(workspaceRoot);
1970
2054
  removeProjectEslintConfigs(workspaceRoot);
1971
2055
  }
1972
2056
  function removeNxAuthoredAgentFiles(workspaceRoot) {
1973
- (0, import_node_fs2.rmSync)((0, import_node_path2.join)(workspaceRoot, NX_CLAUDE_SETTINGS), { force: true });
1974
- const claudeDirectory = (0, import_node_path2.join)(workspaceRoot, (0, import_node_path2.dirname)(NX_CLAUDE_SETTINGS));
1975
- if ((0, import_node_fs2.existsSync)(claudeDirectory) && (0, import_node_fs2.readdirSync)(claudeDirectory).length === 0) {
1976
- (0, import_node_fs2.rmSync)(claudeDirectory, { recursive: true, force: true });
2057
+ (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, NX_CLAUDE_SETTINGS), { force: true });
2058
+ const claudeDirectory = (0, import_node_path3.join)(workspaceRoot, (0, import_node_path3.dirname)(NX_CLAUDE_SETTINGS));
2059
+ if ((0, import_node_fs3.existsSync)(claudeDirectory) && (0, import_node_fs3.readdirSync)(claudeDirectory).length === 0) {
2060
+ (0, import_node_fs3.rmSync)(claudeDirectory, { recursive: true, force: true });
1977
2061
  }
1978
2062
  for (const name of NX_AUTHORED_AGENT_FILES) {
1979
- const path = (0, import_node_path2.join)(workspaceRoot, name);
1980
- if (!(0, import_node_fs2.existsSync)(path)) continue;
1981
- const kept = withoutNxAgentRules((0, import_node_fs2.readFileSync)(path, "utf8"));
2063
+ const path = (0, import_node_path3.join)(workspaceRoot, name);
2064
+ if (!(0, import_node_fs3.existsSync)(path)) continue;
2065
+ const kept = withoutNxAgentRules((0, import_node_fs3.readFileSync)(path, "utf8"));
1982
2066
  if (kept === void 0) continue;
1983
- if (kept.trim() === "") (0, import_node_fs2.rmSync)(path, { force: true });
2067
+ if (kept.trim() === "") (0, import_node_fs3.rmSync)(path, { force: true });
1984
2068
  else writeFileEnsured(path, kept);
1985
2069
  }
1986
2070
  }
@@ -1995,14 +2079,14 @@ function withoutNxAgentRules(content) {
1995
2079
  return `${content.slice(0, start)}${rest}`.replace(/^[\r\n]+/, "");
1996
2080
  }
1997
2081
  function removeIfPresent(path) {
1998
- (0, import_node_fs2.rmSync)(path, { recursive: true, force: true });
2082
+ (0, import_node_fs3.rmSync)(path, { recursive: true, force: true });
1999
2083
  }
2000
2084
  function ensureEslintCacheIgnored(workspaceRoot) {
2001
- const gitignorePath = (0, import_node_path2.join)(workspaceRoot, ".gitignore");
2085
+ const gitignorePath = (0, import_node_path3.join)(workspaceRoot, ".gitignore");
2002
2086
  if (!fileExists(gitignorePath)) {
2003
2087
  return;
2004
2088
  }
2005
- const current = (0, import_node_fs2.readFileSync)(gitignorePath, "utf8");
2089
+ const current = (0, import_node_fs3.readFileSync)(gitignorePath, "utf8");
2006
2090
  if (current.split("\n").some((line) => line.trim() === ".eslintcache")) {
2007
2091
  return;
2008
2092
  }
@@ -2017,18 +2101,18 @@ function ensureEslintCacheIgnored(workspaceRoot) {
2017
2101
  }
2018
2102
  var PYTHON_ARTEFACT_IGNORES = ["__pycache__/", "*.py[cod]"];
2019
2103
  function ensurePythonArtefactsIgnored(workspaceRoot) {
2020
- const gitignorePath = (0, import_node_path2.join)(workspaceRoot, ".gitignore");
2104
+ const gitignorePath = (0, import_node_path3.join)(workspaceRoot, ".gitignore");
2021
2105
  if (!fileExists(gitignorePath)) {
2022
2106
  return;
2023
2107
  }
2024
- const hasPython = (0, import_node_fs2.globSync)(
2108
+ const hasPython = (0, import_node_fs3.globSync)(
2025
2109
  ["python-packages/*/pyproject.toml", "apps/*/pyproject.toml", "libs/*/pyproject.toml"],
2026
2110
  { cwd: workspaceRoot }
2027
2111
  ).length > 0;
2028
2112
  if (!hasPython) {
2029
2113
  return;
2030
2114
  }
2031
- const current = (0, import_node_fs2.readFileSync)(gitignorePath, "utf8");
2115
+ const current = (0, import_node_fs3.readFileSync)(gitignorePath, "utf8");
2032
2116
  const present = new Set(current.split("\n").map((line) => line.trim()));
2033
2117
  const missing = PYTHON_ARTEFACT_IGNORES.filter((line) => !present.has(line));
2034
2118
  if (missing.length === 0) {
@@ -2048,16 +2132,16 @@ ${missing.join("\n")}
2048
2132
  );
2049
2133
  }
2050
2134
  function removeProjectEslintConfigs(workspaceRoot) {
2051
- const matches = (0, import_node_fs2.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
2135
+ const matches = (0, import_node_fs3.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
2052
2136
  cwd: workspaceRoot
2053
2137
  });
2054
2138
  for (const match of matches) {
2055
- (0, import_node_fs2.rmSync)((0, import_node_path2.join)(workspaceRoot, match), { force: true });
2139
+ (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, match), { force: true });
2056
2140
  }
2057
2141
  }
2058
2142
  function applyOverlay(workspaceRoot, options, onProgress = () => {
2059
2143
  }) {
2060
- const nxJsonPath = (0, import_node_path2.join)(workspaceRoot, "nx.json");
2144
+ const nxJsonPath = (0, import_node_path3.join)(workspaceRoot, "nx.json");
2061
2145
  const nxJson = readJson(nxJsonPath);
2062
2146
  const generators = {
2063
2147
  ...nxJson.generators,
@@ -2065,7 +2149,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2065
2149
  };
2066
2150
  const sync = { ...nxJson.sync, ...SYNC_CONFIG };
2067
2151
  const mnci = { ...nxJson.mnci, ...mnciConfig(options) };
2068
- const rootManifest = readJson((0, import_node_path2.join)(workspaceRoot, "package.json"));
2152
+ const rootManifest = readJson((0, import_node_path3.join)(workspaceRoot, "package.json"));
2069
2153
  const hasPythonPlugin = (rootManifest.devDependencies ?? {})["@mnci/nx-python-pip"] !== void 0 || (rootManifest.dependencies ?? {})["@mnci/nx-python-pip"] !== void 0;
2070
2154
  const withRelease = withReleaseConfig(nxJson, options.ci);
2071
2155
  const patched = withPythonGraphPlugin(
@@ -2075,7 +2159,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2075
2159
  onProgress("nx.json \u2014 release, sync, generators, shared inputs, mnci block");
2076
2160
  writeFileEnsured(nxJsonPath, toJson({ ...patched, generators, sync, mnci }));
2077
2161
  onProgress("package.json \u2014 root scripts, TS compilers, ESLint toolchain, overrides");
2078
- const manifestPath = (0, import_node_path2.join)(workspaceRoot, "package.json");
2162
+ const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2079
2163
  const manifest = readJson(manifestPath);
2080
2164
  const scripts = {
2081
2165
  ...manifest.scripts,
@@ -2127,32 +2211,32 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2127
2211
  `.npmrc \u2014 ${options.registry.kind === "azure-artifacts" ? "Azure Artifacts feed routing and credentials" : "public npm registry auth"}`
2128
2212
  );
2129
2213
  writeFileEnsured(
2130
- (0, import_node_path2.join)(workspaceRoot, ".npmrc"),
2214
+ (0, import_node_path3.join)(workspaceRoot, ".npmrc"),
2131
2215
  npmrcContent(options.registry, options.scope, options.npmAuth)
2132
2216
  );
2133
2217
  onProgress("commitlint.config.mjs and .husky/commit-msg \u2014 conventional commit enforcement");
2134
- writeFileEnsured((0, import_node_path2.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
2135
- const hookPath = (0, import_node_path2.join)(workspaceRoot, ".husky/commit-msg");
2218
+ writeFileEnsured((0, import_node_path3.join)(workspaceRoot, "commitlint.config.mjs"), COMMITLINT_CONFIG);
2219
+ const hookPath = (0, import_node_path3.join)(workspaceRoot, ".husky/commit-msg");
2136
2220
  writeFileEnsured(hookPath, COMMIT_MSG_HOOK);
2137
2221
  markExecutable(hookPath);
2138
2222
  onProgress(`${ESLINT_MNCI_FILENAME} \u2014 the shared lint AND formatting opinion`);
2139
- writeFileEnsured((0, import_node_path2.join)(workspaceRoot, ESLINT_MNCI_FILENAME), ESLINT_MNCI_CONFIG);
2223
+ writeFileEnsured((0, import_node_path3.join)(workspaceRoot, ESLINT_MNCI_FILENAME), ESLINT_MNCI_CONFIG);
2140
2224
  writeEslintEntryPoint(workspaceRoot, onProgress);
2141
2225
  ensureEslintCacheIgnored(workspaceRoot);
2142
2226
  ensurePythonArtefactsIgnored(workspaceRoot);
2143
2227
  for (const retired of RETIRED_FORMATTER_FILES) {
2144
- removeIfPresent((0, import_node_path2.join)(workspaceRoot, retired));
2228
+ removeIfPresent((0, import_node_path3.join)(workspaceRoot, retired));
2145
2229
  }
2146
2230
  onProgress(".devcontainer/devcontainer.json \u2014 a local toolchain matching CI");
2147
2231
  writeFileEnsured(
2148
- (0, import_node_path2.join)(workspaceRoot, ".devcontainer/devcontainer.json"),
2232
+ (0, import_node_path3.join)(workspaceRoot, ".devcontainer/devcontainer.json"),
2149
2233
  devcontainerJson(options.workspaceName)
2150
2234
  );
2151
2235
  removeNxScaffolding(workspaceRoot);
2152
2236
  onProgress(
2153
2237
  `${options.workspaceName}.code-workspace \u2014 settings, extensions, launch configs`
2154
2238
  );
2155
- const codeWorkspacePath = (0, import_node_path2.join)(workspaceRoot, `${options.workspaceName}.code-workspace`);
2239
+ const codeWorkspacePath = (0, import_node_path3.join)(workspaceRoot, `${options.workspaceName}.code-workspace`);
2156
2240
  const existing = readCodeWorkspace(codeWorkspacePath);
2157
2241
  writeFileEnsured(
2158
2242
  codeWorkspacePath,
@@ -2164,7 +2248,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2164
2248
  )
2165
2249
  );
2166
2250
  if (options.workspaceName !== "undefined") {
2167
- (0, import_node_fs2.rmSync)((0, import_node_path2.join)(workspaceRoot, "undefined.code-workspace"), { force: true });
2251
+ (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, "undefined.code-workspace"), { force: true });
2168
2252
  }
2169
2253
  const publishUrl = pythonPublishUrl(options.registry);
2170
2254
  const nugetUrl = nugetFeedUrl(options.registry);
@@ -2172,7 +2256,7 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2172
2256
  if (options.ci === "azure" || options.ci === "both") {
2173
2257
  onProgress("azure-pipelines.yml \u2014 build, verify, pack and release");
2174
2258
  writeFileEnsured(
2175
- (0, import_node_path2.join)(workspaceRoot, "azure-pipelines.yml"),
2259
+ (0, import_node_path3.join)(workspaceRoot, "azure-pipelines.yml"),
2176
2260
  azurePipelinesYaml(
2177
2261
  options.agent,
2178
2262
  options.variableGroup,
@@ -2187,52 +2271,10 @@ function applyOverlay(workspaceRoot, options, onProgress = () => {
2187
2271
  if (options.ci === "github" || options.ci === "both") {
2188
2272
  onProgress(".github/workflows/ci.yml and dependabot.yml");
2189
2273
  writeFileEnsured(
2190
- (0, import_node_path2.join)(workspaceRoot, ".github/workflows/ci.yml"),
2274
+ (0, import_node_path3.join)(workspaceRoot, ".github/workflows/ci.yml"),
2191
2275
  githubActionsYaml(options.agent, publishUrl, options.registry.kind, options.ci, nugetUrl, nativeApps)
2192
2276
  );
2193
- writeFileEnsured((0, import_node_path2.join)(workspaceRoot, ".github/dependabot.yml"), dependabotConfig(workspaceRoot));
2194
- }
2195
- }
2196
-
2197
- // src/ci-pipeline/ci-environment.client.ts
2198
- function detectCiHost(environment) {
2199
- if (environment.GITHUB_ACTIONS === "true") {
2200
- return "github";
2201
- }
2202
- if (environment.TF_BUILD !== void 0 && environment.TF_BUILD !== "") {
2203
- return "azure";
2204
- }
2205
- return "local";
2206
- }
2207
- function pullRequestTarget(environment) {
2208
- const reference = environment.GITHUB_BASE_REF || environment.SYSTEM_PULLREQUEST_TARGETBRANCH || "";
2209
- return reference === "" ? void 0 : reference.replace("refs/heads/", "");
2210
- }
2211
- function groupStart(host, title) {
2212
- switch (host) {
2213
- case "github": {
2214
- return `::group::${title}`;
2215
- }
2216
- case "azure": {
2217
- return `##[group]${title}`;
2218
- }
2219
- case "local": {
2220
- return `
2221
- \u25B8 ${title}`;
2222
- }
2223
- }
2224
- }
2225
- function groupEnd(host) {
2226
- switch (host) {
2227
- case "github": {
2228
- return "::endgroup::";
2229
- }
2230
- case "azure": {
2231
- return "##[endgroup]";
2232
- }
2233
- case "local": {
2234
- return void 0;
2235
- }
2277
+ writeFileEnsured((0, import_node_path3.join)(workspaceRoot, ".github/dependabot.yml"), dependabotConfig(workspaceRoot));
2236
2278
  }
2237
2279
  }
2238
2280
 
@@ -2287,17 +2329,20 @@ function runVerify(workspaceRoot, dependencies = {}) {
2287
2329
  }
2288
2330
 
2289
2331
  // src/ci-pipeline/index.ts
2290
- var CI_PHASES = ["verify"];
2332
+ var CI_PHASES = ["verify", "pack"];
2291
2333
  function runCiPhase(phase, workspaceRoot, dependencies = {}) {
2292
2334
  switch (phase) {
2293
2335
  case "verify": {
2294
2336
  return runVerify(workspaceRoot, dependencies);
2295
2337
  }
2338
+ case "pack": {
2339
+ return runPack(workspaceRoot, dependencies);
2340
+ }
2296
2341
  }
2297
2342
  }
2298
2343
 
2299
2344
  // src/project-scaffolding/add-project.use-case.ts
2300
- var import_node_path21 = require("path");
2345
+ var import_node_path23 = require("path");
2301
2346
  var import_prompts3 = require("@inquirer/prompts");
2302
2347
 
2303
2348
  // src/project-name/project-name.validator.ts
@@ -2310,14 +2355,14 @@ function assertValidProjectName(name, label) {
2310
2355
  }
2311
2356
 
2312
2357
  // src/project-scaffolding/csharp.use-case.ts
2313
- var import_node_fs4 = require("fs");
2314
- var import_node_path4 = require("path");
2358
+ var import_node_fs5 = require("fs");
2359
+ var import_node_path5 = require("path");
2315
2360
 
2316
2361
  // src/project-scaffolding/post-generation.use-case.ts
2317
- var import_node_fs3 = require("fs");
2318
- var import_node_path3 = require("path");
2362
+ var import_node_fs4 = require("fs");
2363
+ var import_node_path4 = require("path");
2319
2364
  function hasPlugin(workspaceRoot, packageName) {
2320
- const manifest = readJson((0, import_node_path3.join)(workspaceRoot, "package.json"));
2365
+ const manifest = readJson((0, import_node_path4.join)(workspaceRoot, "package.json"));
2321
2366
  const installed = { ...manifest.dependencies, ...manifest.devDependencies };
2322
2367
  return Object.hasOwn(installed, packageName);
2323
2368
  }
@@ -2356,7 +2401,7 @@ function markPublic(manifestPath) {
2356
2401
  function writeProjectReadme(projectRoot, projectName, testRunner) {
2357
2402
  const runner = testRunner === "vitest" ? "[Vitest](https://vitest.dev)" : "[Jest](https://jestjs.io)";
2358
2403
  writeFileEnsured(
2359
- (0, import_node_path3.join)(projectRoot, "README.md"),
2404
+ (0, import_node_path4.join)(projectRoot, "README.md"),
2360
2405
  [
2361
2406
  `# ${projectName}`,
2362
2407
  "",
@@ -2375,13 +2420,13 @@ function writeProjectReadme(projectRoot, projectName, testRunner) {
2375
2420
  }
2376
2421
  function removeStaleGitkeeps(workspaceRoot) {
2377
2422
  for (const scaffold of ["apps", "libs", "packages"]) {
2378
- const directory = (0, import_node_path3.join)(workspaceRoot, scaffold);
2423
+ const directory = (0, import_node_path4.join)(workspaceRoot, scaffold);
2379
2424
  try {
2380
- const holdsAProject = (0, import_node_fs3.readdirSync)(directory, { withFileTypes: true }).some(
2425
+ const holdsAProject = (0, import_node_fs4.readdirSync)(directory, { withFileTypes: true }).some(
2381
2426
  (entry) => entry.isDirectory()
2382
2427
  );
2383
2428
  if (holdsAProject) {
2384
- (0, import_node_fs3.rmSync)((0, import_node_path3.join)(directory, ".gitkeep"), { force: true });
2429
+ (0, import_node_fs4.rmSync)((0, import_node_path4.join)(directory, ".gitkeep"), { force: true });
2385
2430
  }
2386
2431
  } catch {
2387
2432
  }
@@ -2401,7 +2446,7 @@ function ensureAdmZip(workspaceRoot) {
2401
2446
  }
2402
2447
  }
2403
2448
  function defaultScope(workspaceRoot) {
2404
- const { name } = readJson((0, import_node_path3.join)(workspaceRoot, "package.json"));
2449
+ const { name } = readJson((0, import_node_path4.join)(workspaceRoot, "package.json"));
2405
2450
  const base = (name.startsWith("@") ? name.slice(1) : name).split("/", 1)[0];
2406
2451
  return `@${base}`;
2407
2452
  }
@@ -2429,14 +2474,14 @@ var ESLINT_CONFIG_FILENAMES = [
2429
2474
  ];
2430
2475
  function removeGeneratedEslintConfig(workspaceRoot, projectRoot) {
2431
2476
  for (const filename of ESLINT_CONFIG_FILENAMES) {
2432
- (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, projectRoot, filename), { force: true });
2477
+ (0, import_node_fs4.rmSync)((0, import_node_path4.join)(workspaceRoot, projectRoot, filename), { force: true });
2433
2478
  }
2434
- (0, import_node_fs3.rmSync)((0, import_node_path3.join)(workspaceRoot, ".vscode"), { recursive: true, force: true });
2479
+ (0, import_node_fs4.rmSync)((0, import_node_path4.join)(workspaceRoot, ".vscode"), { recursive: true, force: true });
2435
2480
  }
2436
2481
  function findCodeWorkspaceFile(workspaceRoot) {
2437
2482
  try {
2438
- const entry = (0, import_node_fs3.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
2439
- return entry ? (0, import_node_path3.join)(workspaceRoot, entry) : void 0;
2483
+ const entry = (0, import_node_fs4.readdirSync)(workspaceRoot).find((file) => file.endsWith(".code-workspace"));
2484
+ return entry ? (0, import_node_path4.join)(workspaceRoot, entry) : void 0;
2440
2485
  } catch {
2441
2486
  return void 0;
2442
2487
  }
@@ -2447,25 +2492,25 @@ function projectTask(name, kind) {
2447
2492
  return kind === "start" ? { ...base, isBackground: true } : { ...base, group: kind };
2448
2493
  }
2449
2494
  function renameScaffoldPlaceholder(projectRoot, name) {
2450
- const placeholder = (0, import_node_path3.join)(projectRoot, "src", "lib", `${name}.ts`);
2451
- if (!(0, import_node_fs3.existsSync)(placeholder)) {
2495
+ const placeholder = (0, import_node_path4.join)(projectRoot, "src", "lib", `${name}.ts`);
2496
+ if (!(0, import_node_fs4.existsSync)(placeholder)) {
2452
2497
  return;
2453
2498
  }
2454
- (0, import_node_fs3.renameSync)(placeholder, (0, import_node_path3.join)(projectRoot, "src", "lib", `${name}.use-case.ts`));
2455
- const spec = (0, import_node_path3.join)(projectRoot, "src", "lib", `${name}.spec.ts`);
2456
- if ((0, import_node_fs3.existsSync)(spec)) {
2457
- const renamed = (0, import_node_path3.join)(projectRoot, "src", "lib", `${name}.use-case.spec.ts`);
2458
- (0, import_node_fs3.renameSync)(spec, renamed);
2499
+ (0, import_node_fs4.renameSync)(placeholder, (0, import_node_path4.join)(projectRoot, "src", "lib", `${name}.use-case.ts`));
2500
+ const spec = (0, import_node_path4.join)(projectRoot, "src", "lib", `${name}.spec.ts`);
2501
+ if ((0, import_node_fs4.existsSync)(spec)) {
2502
+ const renamed = (0, import_node_path4.join)(projectRoot, "src", "lib", `${name}.use-case.spec.ts`);
2503
+ (0, import_node_fs4.renameSync)(spec, renamed);
2459
2504
  writeFileEnsured(
2460
2505
  renamed,
2461
- repointSpecifier((0, import_node_fs3.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.use-case`)
2506
+ repointSpecifier((0, import_node_fs4.readFileSync)(renamed, "utf8"), `./${name}`, `./${name}.use-case`)
2462
2507
  );
2463
2508
  }
2464
- const barrel = (0, import_node_path3.join)(projectRoot, "src", "index.ts");
2465
- if ((0, import_node_fs3.existsSync)(barrel)) {
2509
+ const barrel = (0, import_node_path4.join)(projectRoot, "src", "index.ts");
2510
+ if ((0, import_node_fs4.existsSync)(barrel)) {
2466
2511
  writeFileEnsured(
2467
2512
  barrel,
2468
- repointSpecifier((0, import_node_fs3.readFileSync)(barrel, "utf8"), `./lib/${name}`, `./lib/${name}.use-case`)
2513
+ repointSpecifier((0, import_node_fs4.readFileSync)(barrel, "utf8"), `./lib/${name}`, `./lib/${name}.use-case`)
2469
2514
  );
2470
2515
  }
2471
2516
  }
@@ -2473,8 +2518,8 @@ function repointSpecifier(source, from, to) {
2473
2518
  return source.replaceAll(`${from}'`, () => `${to}'`).replaceAll(`${from}.js'`, () => `${to}.js'`);
2474
2519
  }
2475
2520
  function ensureNxPeerOverrides(workspaceRoot) {
2476
- const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2477
- if (!(0, import_node_fs3.existsSync)(manifestPath)) {
2521
+ const manifestPath = (0, import_node_path4.join)(workspaceRoot, "package.json");
2522
+ if (!(0, import_node_fs4.existsSync)(manifestPath)) {
2478
2523
  return;
2479
2524
  }
2480
2525
  const manifest = readJson(manifestPath);
@@ -2497,11 +2542,11 @@ function registerProjectCommands(workspaceRoot, name, commands) {
2497
2542
  if (commands.start) {
2498
2543
  scripts[`${name}:start`] = commands.start;
2499
2544
  }
2500
- const dependabotPath = (0, import_node_path3.join)(workspaceRoot, ".github/dependabot.yml");
2501
- if ((0, import_node_fs3.existsSync)(dependabotPath)) {
2545
+ const dependabotPath = (0, import_node_path4.join)(workspaceRoot, ".github/dependabot.yml");
2546
+ if ((0, import_node_fs4.existsSync)(dependabotPath)) {
2502
2547
  writeFileEnsured(dependabotPath, dependabotConfig(workspaceRoot));
2503
2548
  }
2504
- const manifestPath = (0, import_node_path3.join)(workspaceRoot, "package.json");
2549
+ const manifestPath = (0, import_node_path4.join)(workspaceRoot, "package.json");
2505
2550
  const manifest = readJson(manifestPath);
2506
2551
  const existingScripts = manifest.scripts ?? {};
2507
2552
  writeFileEnsured(
@@ -2539,7 +2584,7 @@ function registerProjectCommands(workspaceRoot, name, commands) {
2539
2584
  var PROJECT_MANIFEST_ROOTS = ["apps", "packages", "libs"];
2540
2585
  function rootRuntimeDependencies(workspaceRoot) {
2541
2586
  try {
2542
- return readJson((0, import_node_path3.join)(workspaceRoot, "package.json")).dependencies ?? {};
2587
+ return readJson((0, import_node_path4.join)(workspaceRoot, "package.json")).dependencies ?? {};
2543
2588
  } catch {
2544
2589
  return {};
2545
2590
  }
@@ -2551,7 +2596,7 @@ function relocateRootRuntimeDependencies(workspaceRoot, projectName, before) {
2551
2596
  return;
2552
2597
  }
2553
2598
  const manifestPath = PROJECT_MANIFEST_ROOTS.map(
2554
- (root) => (0, import_node_path3.join)(workspaceRoot, root, projectName, "package.json")
2599
+ (root) => (0, import_node_path4.join)(workspaceRoot, root, projectName, "package.json")
2555
2600
  ).find((candidate) => fileExists(candidate));
2556
2601
  if (manifestPath === void 0) {
2557
2602
  return;
@@ -2563,10 +2608,10 @@ function relocateRootRuntimeDependencies(workspaceRoot, projectName, before) {
2563
2608
  const remaining = Object.fromEntries(
2564
2609
  Object.entries(after).filter(([name]) => !added.includes(name))
2565
2610
  );
2566
- const rootManifest = readJson((0, import_node_path3.join)(workspaceRoot, "package.json"));
2611
+ const rootManifest = readJson((0, import_node_path4.join)(workspaceRoot, "package.json"));
2567
2612
  const { dependencies: _dropped, ...rest } = rootManifest;
2568
2613
  writeFileEnsured(
2569
- (0, import_node_path3.join)(workspaceRoot, "package.json"),
2614
+ (0, import_node_path4.join)(workspaceRoot, "package.json"),
2570
2615
  toJson(Object.keys(remaining).length > 0 ? { ...rest, dependencies: remaining } : rest)
2571
2616
  );
2572
2617
  logger.step(`Moved ${added.join(", ")} into ${projectName}'s own manifest`);
@@ -2626,7 +2671,7 @@ function addCsharpApp(workspaceRoot, name, template = "console") {
2626
2671
  ensureAdmZip(workspaceRoot);
2627
2672
  const projectRoot = `apps/${name}`;
2628
2673
  scaffoldDotnetProject(workspaceRoot, projectRoot, pascalCase(name), template);
2629
- addProjectJsonTargets((0, import_node_path4.join)(workspaceRoot, projectRoot, "project.json"), {
2674
+ addProjectJsonTargets((0, import_node_path5.join)(workspaceRoot, projectRoot, "project.json"), {
2630
2675
  package: csharpAppPackageTarget("csharp-app", projectRoot, name),
2631
2676
  start: csharpAppStartTarget(projectRoot)
2632
2677
  });
@@ -2719,7 +2764,7 @@ class CsharpVersionActions extends VersionActions {
2719
2764
  module.exports = CsharpVersionActions
2720
2765
  `;
2721
2766
  function writeCsharpVersionActions(workspaceRoot) {
2722
- writeFileEnsured((0, import_node_path4.join)(workspaceRoot, CSHARP_VERSION_ACTIONS_PATH), CSHARP_VERSION_ACTIONS);
2767
+ writeFileEnsured((0, import_node_path5.join)(workspaceRoot, CSHARP_VERSION_ACTIONS_PATH), CSHARP_VERSION_ACTIONS);
2723
2768
  }
2724
2769
  function addProjectJsonReleaseVersionActions(projectJsonPath) {
2725
2770
  const project = fileExists(projectJsonPath) ? readJson(projectJsonPath) : {};
@@ -2734,7 +2779,7 @@ function addProjectJsonReleaseVersionActions(projectJsonPath) {
2734
2779
  );
2735
2780
  }
2736
2781
  function addInitialVersion(csprojPath) {
2737
- const contents = (0, import_node_fs4.readFileSync)(csprojPath, "utf8");
2782
+ const contents = (0, import_node_fs5.readFileSync)(csprojPath, "utf8");
2738
2783
  writeFileEnsured(csprojPath, contents.replace("<PropertyGroup>", "<PropertyGroup>\n <Version>0.1.0</Version>"));
2739
2784
  }
2740
2785
  function csharpLibPublishTarget(projectRoot) {
@@ -2749,14 +2794,14 @@ async function addCsharpLib(workspaceRoot, name, options, kindProvided) {
2749
2794
  const projectRoot = `packages/${name}`;
2750
2795
  const identity = `${pascalScope(scope)}.${pascalCase(name)}`;
2751
2796
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "classlib");
2752
- addInitialVersion((0, import_node_path4.join)(workspaceRoot, projectRoot, `${identity}.csproj`));
2797
+ addInitialVersion((0, import_node_path5.join)(workspaceRoot, projectRoot, `${identity}.csproj`));
2753
2798
  writeCsharpVersionActions(workspaceRoot);
2754
- addProjectJsonReleaseVersionActions((0, import_node_path4.join)(workspaceRoot, projectRoot, "project.json"));
2755
- addProjectJsonTargets((0, import_node_path4.join)(workspaceRoot, projectRoot, "project.json"), {
2799
+ addProjectJsonReleaseVersionActions((0, import_node_path5.join)(workspaceRoot, projectRoot, "project.json"));
2800
+ addProjectJsonTargets((0, import_node_path5.join)(workspaceRoot, projectRoot, "project.json"), {
2756
2801
  "nx-release-publish": csharpLibPublishTarget(projectRoot)
2757
2802
  });
2758
2803
  const registry = readMnciConfig(workspaceRoot).registry ?? { kind: "npm" };
2759
- writeFileEnsured((0, import_node_path4.join)(workspaceRoot, "nuget.config"), nugetConfigContent(registry, scope));
2804
+ writeFileEnsured((0, import_node_path5.join)(workspaceRoot, "nuget.config"), nugetConfigContent(registry, scope));
2760
2805
  registerProjectCommands(workspaceRoot, name, { build: true });
2761
2806
  }
2762
2807
  function addCsharpInternalLib(workspaceRoot, name) {
@@ -2832,15 +2877,15 @@ function addCsharpFunctionApp(workspaceRoot, name) {
2832
2877
  const projectRoot = `apps/${name}`;
2833
2878
  const identity = pascalCase(name);
2834
2879
  scaffoldDotnetProject(workspaceRoot, projectRoot, identity, "console");
2835
- const absoluteRoot = (0, import_node_path4.join)(workspaceRoot, projectRoot);
2836
- writeFileEnsured((0, import_node_path4.join)(absoluteRoot, `${identity}.csproj`), csharpFunctionAppCsproj());
2837
- writeFileEnsured((0, import_node_path4.join)(absoluteRoot, "Program.cs"), CSHARP_FUNCTION_APP_PROGRAM);
2838
- writeFileEnsured((0, import_node_path4.join)(absoluteRoot, "Hello.cs"), csharpFunctionAppHello(identity));
2839
- writeFileEnsured((0, import_node_path4.join)(absoluteRoot, "host.json"), CSHARP_FUNCTION_APP_HOST_JSON);
2880
+ const absoluteRoot = (0, import_node_path5.join)(workspaceRoot, projectRoot);
2881
+ writeFileEnsured((0, import_node_path5.join)(absoluteRoot, `${identity}.csproj`), csharpFunctionAppCsproj());
2882
+ writeFileEnsured((0, import_node_path5.join)(absoluteRoot, "Program.cs"), CSHARP_FUNCTION_APP_PROGRAM);
2883
+ writeFileEnsured((0, import_node_path5.join)(absoluteRoot, "Hello.cs"), csharpFunctionAppHello(identity));
2884
+ writeFileEnsured((0, import_node_path5.join)(absoluteRoot, "host.json"), CSHARP_FUNCTION_APP_HOST_JSON);
2840
2885
  if (runShell("dotnet", ["restore", projectRoot], workspaceRoot) !== 0) {
2841
2886
  throw new Error(`dotnet restore failed for ${projectRoot}`);
2842
2887
  }
2843
- addProjectJsonTargets((0, import_node_path4.join)(absoluteRoot, "project.json"), {
2888
+ addProjectJsonTargets((0, import_node_path5.join)(absoluteRoot, "project.json"), {
2844
2889
  package: csharpAppPackageTarget("csharp-function-app", projectRoot, name),
2845
2890
  start: csharpFunctionAppStartTarget(projectRoot)
2846
2891
  });
@@ -2848,7 +2893,7 @@ function addCsharpFunctionApp(workspaceRoot, name) {
2848
2893
  }
2849
2894
 
2850
2895
  // src/project-scaffolding/flutter.use-case.ts
2851
- var import_node_path5 = require("path");
2896
+ var import_node_path6 = require("path");
2852
2897
  function flutterAppStartTarget(name) {
2853
2898
  return {
2854
2899
  executor: "nx:run-commands",
@@ -2884,7 +2929,7 @@ function addFlutterApp(workspaceRoot, name) {
2884
2929
  prepareFlutter(workspaceRoot);
2885
2930
  ensureAdmZip(workspaceRoot);
2886
2931
  runNx(["g", "@mnci/nx-flutter:application", name, "--no-interactive"], workspaceRoot);
2887
- addProjectJsonTargets((0, import_node_path5.join)(workspaceRoot, "apps", name, "project.json"), {
2932
+ addProjectJsonTargets((0, import_node_path6.join)(workspaceRoot, "apps", name, "project.json"), {
2888
2933
  start: flutterAppStartTarget(name)
2889
2934
  });
2890
2935
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
@@ -2901,18 +2946,18 @@ function addFlutterInternalLib(workspaceRoot, name) {
2901
2946
  }
2902
2947
 
2903
2948
  // src/project-scaffolding/go.use-case.ts
2904
- var import_node_fs7 = require("fs");
2905
- var import_node_path8 = require("path");
2949
+ var import_node_fs9 = require("fs");
2950
+ var import_node_path10 = require("path");
2906
2951
 
2907
2952
  // src/go-workspace/go-plugin.use-case.ts
2908
- var import_node_fs5 = require("fs");
2909
- var import_node_path6 = require("path");
2953
+ var import_node_fs6 = require("fs");
2954
+ var import_node_path7 = require("path");
2910
2955
  var NX_GO_PLUGIN = "@nx-go/nx-go";
2911
2956
  function hasGoProject(workspaceRoot) {
2912
- const projectFiles = ["apps", "libs", "packages"].flatMap((directory) => (0, import_node_fs5.globSync)(`${directory}/*/project.json`, { cwd: workspaceRoot }));
2957
+ const projectFiles = ["apps", "libs", "packages"].flatMap((directory) => (0, import_node_fs6.globSync)(`${directory}/*/project.json`, { cwd: workspaceRoot }));
2913
2958
  return projectFiles.some((projectFile) => {
2914
2959
  try {
2915
- const { tags } = JSON.parse((0, import_node_fs5.readFileSync)((0, import_node_path6.join)(workspaceRoot, projectFile), "utf8"));
2960
+ const { tags } = JSON.parse((0, import_node_fs6.readFileSync)((0, import_node_path7.join)(workspaceRoot, projectFile), "utf8"));
2916
2961
  return (tags ?? []).some((tag) => tag.startsWith("type:go-"));
2917
2962
  } catch {
2918
2963
  return false;
@@ -2920,14 +2965,14 @@ function hasGoProject(workspaceRoot) {
2920
2965
  });
2921
2966
  }
2922
2967
  function isNxGoPluginRegistered(workspaceRoot) {
2923
- const nxJsonPath = (0, import_node_path6.join)(workspaceRoot, "nx.json");
2968
+ const nxJsonPath = (0, import_node_path7.join)(workspaceRoot, "nx.json");
2924
2969
  if (!fileExists(nxJsonPath)) {
2925
2970
  return false;
2926
2971
  }
2927
2972
  return (readJson(nxJsonPath).plugins ?? []).some((entry) => (typeof entry === "string" ? entry : entry.plugin) === NX_GO_PLUGIN);
2928
2973
  }
2929
2974
  function registerNxGoPlugin(workspaceRoot) {
2930
- const nxJsonPath = (0, import_node_path6.join)(workspaceRoot, "nx.json");
2975
+ const nxJsonPath = (0, import_node_path7.join)(workspaceRoot, "nx.json");
2931
2976
  if (!fileExists(nxJsonPath) || isNxGoPluginRegistered(workspaceRoot)) {
2932
2977
  return false;
2933
2978
  }
@@ -2937,8 +2982,8 @@ function registerNxGoPlugin(workspaceRoot) {
2937
2982
  }
2938
2983
 
2939
2984
  // src/project-scaffolding/go-release.use-case.ts
2940
- var import_node_fs6 = require("fs");
2941
- var import_node_path7 = require("path");
2985
+ var import_node_fs7 = require("fs");
2986
+ var import_node_path8 = require("path");
2942
2987
  var GO_RELEASE_SCRIPT_PATH = "tools/go-app-release.cjs";
2943
2988
  var GO_RELEASE_SCRIPT = String.raw`#!/usr/bin/env node
2944
2989
  // Written by mnci: 'mnci add go-app --release' creates it and 'mnci upgrade'
@@ -3064,7 +3109,7 @@ var GO_RELEASE_PUBLISH_TARGET = {
3064
3109
  }
3065
3110
  };
3066
3111
  function makeGoAppReleasable(workspaceRoot, name) {
3067
- const projectJsonPath = (0, import_node_path7.join)(workspaceRoot, "apps", name, "project.json");
3112
+ const projectJsonPath = (0, import_node_path8.join)(workspaceRoot, "apps", name, "project.json");
3068
3113
  if (!fileExists(projectJsonPath)) {
3069
3114
  throw new Error(`No Go app at apps/${name}: cannot make it releasable.`);
3070
3115
  }
@@ -3085,28 +3130,171 @@ function makeGoAppReleasable(workspaceRoot, name) {
3085
3130
  }
3086
3131
  })
3087
3132
  );
3088
- writeFileEnsured((0, import_node_path7.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH), GO_RELEASE_SCRIPT);
3133
+ writeFileEnsured((0, import_node_path8.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH), GO_RELEASE_SCRIPT);
3089
3134
  }
3090
3135
  function refreshGoReleaseScript(workspaceRoot) {
3091
- const apps = (0, import_node_path7.join)(workspaceRoot, "apps");
3136
+ const apps = (0, import_node_path8.join)(workspaceRoot, "apps");
3092
3137
  let entries;
3093
3138
  try {
3094
- entries = (0, import_node_fs6.readdirSync)(apps);
3139
+ entries = (0, import_node_fs7.readdirSync)(apps);
3095
3140
  } catch {
3096
3141
  return false;
3097
3142
  }
3098
3143
  const hasReleasableApp = entries.some((entry) => {
3099
- const projectJsonPath = (0, import_node_path7.join)(apps, entry, "project.json");
3144
+ const projectJsonPath = (0, import_node_path8.join)(apps, entry, "project.json");
3100
3145
  return fileExists(projectJsonPath) && (readJson(projectJsonPath).tags ?? []).includes(GO_RELEASE_TAG);
3101
3146
  });
3102
- const path = (0, import_node_path7.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH);
3103
- if (!hasReleasableApp || fileExists(path) && (0, import_node_fs6.readFileSync)(path, "utf8") === GO_RELEASE_SCRIPT) {
3147
+ const path = (0, import_node_path8.join)(workspaceRoot, GO_RELEASE_SCRIPT_PATH);
3148
+ if (!hasReleasableApp || fileExists(path) && (0, import_node_fs7.readFileSync)(path, "utf8") === GO_RELEASE_SCRIPT) {
3104
3149
  return false;
3105
3150
  }
3106
3151
  writeFileEnsured(path, GO_RELEASE_SCRIPT);
3107
3152
  return true;
3108
3153
  }
3109
3154
 
3155
+ // src/project-scaffolding/go-web.use-case.ts
3156
+ var import_node_fs8 = require("fs");
3157
+ var import_node_path9 = require("path");
3158
+ var TARGETS_NEEDING_THE_FRONTEND = ["build", "test", "lint", "start", "build-all", "build-native"];
3159
+ var DEFAULT_ADDRESS = "127.0.0.1:8080";
3160
+ var GO_WEB_SOURCE = `package main
3161
+
3162
+ import (
3163
+ "embed"
3164
+ "io/fs"
3165
+ "net/http"
3166
+ "path"
3167
+ )
3168
+
3169
+ // The built frontend. The stage-web target copies it into web/ before Go compiles.
3170
+ //
3171
+ //go:embed all:web
3172
+ var webFiles embed.FS
3173
+
3174
+ // webHandler serves the built frontend. A path that is not a file falls back to
3175
+ // index.html, so a client-side route survives a reload.
3176
+ func webHandler() http.Handler {
3177
+ root, err := fs.Sub(webFiles, "web")
3178
+ if err != nil {
3179
+ panic(err)
3180
+ }
3181
+ files := http.FileServer(http.FS(root))
3182
+
3183
+ return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
3184
+ name := path.Clean(r.URL.Path)[1:]
3185
+ if name != "" {
3186
+ if _, err := fs.Stat(root, name); err != nil {
3187
+ r.URL.Path = "/"
3188
+ }
3189
+ }
3190
+ files.ServeHTTP(w, r)
3191
+ })
3192
+ }
3193
+ `;
3194
+ var GO_WEB_MAIN = `package main
3195
+
3196
+ import (
3197
+ "log"
3198
+ "net/http"
3199
+ "os"
3200
+ )
3201
+
3202
+ var version = "dev"
3203
+
3204
+ func main() {
3205
+ address := os.Getenv("ADDR")
3206
+ if address == "" {
3207
+ address = "${DEFAULT_ADDRESS}"
3208
+ }
3209
+ mux := http.NewServeMux()
3210
+ mux.Handle("/", webHandler())
3211
+ log.Printf("%s serving on http://%s", version, address)
3212
+ log.Fatal(http.ListenAndServe(address, mux))
3213
+ }
3214
+ `;
3215
+ var GO_WEB_MAIN_TEST = `package main
3216
+
3217
+ import (
3218
+ "net/http"
3219
+ "net/http/httptest"
3220
+ "strings"
3221
+ "testing"
3222
+ )
3223
+
3224
+ func TestWebHandlerServesTheBuiltFrontend(t *testing.T) {
3225
+ for _, target := range []string{"/", "/a/client/side/route"} {
3226
+ recorder := httptest.NewRecorder()
3227
+ webHandler().ServeHTTP(recorder, httptest.NewRequest(http.MethodGet, target, nil))
3228
+ if recorder.Code != http.StatusOK || !strings.Contains(recorder.Body.String(), "<html") {
3229
+ t.Fatalf("GET %s: %d %q", target, recorder.Code, recorder.Body.String())
3230
+ }
3231
+ }
3232
+ }
3233
+ `;
3234
+ function assertWebApp(workspaceRoot, web) {
3235
+ const directory = (0, import_node_path9.join)(workspaceRoot, "apps", web);
3236
+ const isReactApp = fileExists((0, import_node_path9.join)(directory, "package.json")) && (0, import_node_fs8.readdirSync)(directory).some((entry) => entry.startsWith("vite.config."));
3237
+ if (!isReactApp) {
3238
+ throw new Error(`--web ${web}: no React app at apps/${web}. Add it first with \`mnci add react-app ${web}\`.`);
3239
+ }
3240
+ }
3241
+ function webProjectName(workspaceRoot, web) {
3242
+ const manifest = readJson((0, import_node_path9.join)(workspaceRoot, "apps", web, "package.json"));
3243
+ return manifest.nx?.name ?? manifest.name ?? web;
3244
+ }
3245
+ function addApiProxy(viteConfigPath) {
3246
+ const source = (0, import_node_fs8.readFileSync)(viteConfigPath, "utf8");
3247
+ if (source.includes("'/api'") || source.includes('"/api"')) {
3248
+ return false;
3249
+ }
3250
+ const patched = source.replace(/server:\s*\{/, (serverBlock) => `${serverBlock}
3251
+ proxy: { '/api': 'http://${DEFAULT_ADDRESS}' },`);
3252
+ if (patched === source) {
3253
+ return false;
3254
+ }
3255
+ writeFileEnsured(viteConfigPath, patched);
3256
+ return true;
3257
+ }
3258
+ function wireGoAppToWeb(workspaceRoot, name, web) {
3259
+ const projectJsonPath = (0, import_node_path9.join)(workspaceRoot, "apps", name, "project.json");
3260
+ const project = readJson(projectJsonPath);
3261
+ const webName = webProjectName(workspaceRoot, web);
3262
+ const targets = project.targets ?? {};
3263
+ for (const target of TARGETS_NEEDING_THE_FRONTEND) {
3264
+ if (targets[target] !== void 0) {
3265
+ targets[target].dependsOn = [.../* @__PURE__ */ new Set([...targets[target].dependsOn ?? [], "stage-web"])];
3266
+ }
3267
+ }
3268
+ targets["stage-web"] = {
3269
+ executor: "nx:run-commands",
3270
+ dependsOn: [{ projects: [webName], target: "build" }],
3271
+ inputs: [{ dependentTasksOutputFiles: "**/*" }],
3272
+ outputs: [`{workspaceRoot}/apps/${name}/web`],
3273
+ options: {
3274
+ command: `node -e "const fs=require('node:fs');fs.rmSync('apps/${name}/web',{recursive:true,force:true});fs.cpSync('apps/${web}/dist','apps/${name}/web',{recursive:true})"`
3275
+ }
3276
+ };
3277
+ targets.dev = {
3278
+ executor: "nx:run-commands",
3279
+ options: { commands: [`nx run ${webName}:serve`, `nx run ${name}:start`], parallel: true }
3280
+ };
3281
+ writeFileEnsured(
3282
+ projectJsonPath,
3283
+ toJson({ ...project, implicitDependencies: [.../* @__PURE__ */ new Set([...project.implicitDependencies ?? [], webName])], targets })
3284
+ );
3285
+ const directory = (0, import_node_path9.join)(workspaceRoot, "apps", name);
3286
+ writeFileEnsured((0, import_node_path9.join)(directory, ".gitignore"), "/web/\n");
3287
+ writeFileEnsured((0, import_node_path9.join)(directory, "web.go"), GO_WEB_SOURCE);
3288
+ writeFileEnsured((0, import_node_path9.join)(directory, "main.go"), GO_WEB_MAIN);
3289
+ writeFileEnsured((0, import_node_path9.join)(directory, "main_test.go"), GO_WEB_MAIN_TEST);
3290
+ const viteConfig = (0, import_node_fs8.readdirSync)((0, import_node_path9.join)(workspaceRoot, "apps", web)).find((entry) => entry.startsWith("vite.config."));
3291
+ if (viteConfig === void 0 || !addApiProxy((0, import_node_path9.join)(workspaceRoot, "apps", web, viteConfig))) {
3292
+ logger.warn(
3293
+ `Could not add the /api proxy to apps/${web}'s Vite config: add \`server: { proxy: { '/api': 'http://${DEFAULT_ADDRESS}' } }\` yourself, so \`nx run ${name}:dev\` reaches the Go server.`
3294
+ );
3295
+ }
3296
+ }
3297
+
3110
3298
  // src/project-scaffolding/go.use-case.ts
3111
3299
  function ensureGo(workspaceRoot) {
3112
3300
  if (runShell("go", ["version"], workspaceRoot) !== 0) {
@@ -3134,7 +3322,7 @@ function ensureNxGoPlugin(workspaceRoot) {
3134
3322
  }
3135
3323
  }
3136
3324
  function ensureGoModule(workspaceRoot) {
3137
- if (fileExists((0, import_node_path8.join)(workspaceRoot, "go.mod"))) {
3325
+ if (fileExists((0, import_node_path10.join)(workspaceRoot, "go.mod"))) {
3138
3326
  return;
3139
3327
  }
3140
3328
  logger.step("Bootstrapping the workspace Go module (single root go.mod)");
@@ -3143,7 +3331,7 @@ function ensureGoModule(workspaceRoot) {
3143
3331
  }
3144
3332
  function goModulePath(workspaceRoot) {
3145
3333
  try {
3146
- const contents = (0, import_node_fs7.readFileSync)((0, import_node_path8.join)(workspaceRoot, "go.mod"), "utf8");
3334
+ const contents = (0, import_node_fs9.readFileSync)((0, import_node_path10.join)(workspaceRoot, "go.mod"), "utf8");
3147
3335
  return /^module\s+(\S+)/m.exec(contents)?.[1];
3148
3336
  } catch {
3149
3337
  return void 0;
@@ -3224,16 +3412,16 @@ function goNativePackageTarget(name) {
3224
3412
  }
3225
3413
  function addGoPlatformTargets(workspaceRoot) {
3226
3414
  const changed = [];
3227
- const apps = (0, import_node_path8.join)(workspaceRoot, "apps");
3415
+ const apps = (0, import_node_path10.join)(workspaceRoot, "apps");
3228
3416
  if (!fileExists(apps)) {
3229
3417
  return changed;
3230
3418
  }
3231
- for (const name of (0, import_node_fs7.readdirSync)(apps)) {
3232
- const projectJsonPath = (0, import_node_path8.join)(apps, name, "project.json");
3419
+ for (const name of (0, import_node_fs9.readdirSync)(apps)) {
3420
+ const projectJsonPath = (0, import_node_path10.join)(apps, name, "project.json");
3233
3421
  if (!fileExists(projectJsonPath)) {
3234
3422
  continue;
3235
3423
  }
3236
- const project = JSON.parse((0, import_node_fs7.readFileSync)(projectJsonPath, "utf8"));
3424
+ const project = JSON.parse((0, import_node_fs9.readFileSync)(projectJsonPath, "utf8"));
3237
3425
  const tag = (project.tags ?? []).find((each) => each === "type:go-app" || each === "type:go-function-app")?.slice("type:".length);
3238
3426
  if (tag === void 0 || (project.tags ?? []).includes(GO_CGO_TAG)) {
3239
3427
  continue;
@@ -3269,8 +3457,8 @@ function goLibraryIdentifiers(projectName) {
3269
3457
  }
3270
3458
  function reshapeGoLibraryScaffold(projectRoot, projectName) {
3271
3459
  const { packageName, functionName, fileStem } = goLibraryIdentifiers(projectName);
3272
- (0, import_node_fs7.rmSync)((0, import_node_path8.join)(projectRoot, `${projectName}.go`), { force: true });
3273
- (0, import_node_fs7.rmSync)((0, import_node_path8.join)(projectRoot, `${projectName}_test.go`), { force: true });
3460
+ (0, import_node_fs9.rmSync)((0, import_node_path10.join)(projectRoot, `${projectName}.go`), { force: true });
3461
+ (0, import_node_fs9.rmSync)((0, import_node_path10.join)(projectRoot, `${projectName}_test.go`), { force: true });
3274
3462
  const files = [
3275
3463
  [
3276
3464
  "doc.go",
@@ -3280,14 +3468,14 @@ package ${packageName}
3280
3468
  `
3281
3469
  ],
3282
3470
  [
3283
- (0, import_node_path8.join)(packageName, "doc.go"),
3471
+ (0, import_node_path10.join)(packageName, "doc.go"),
3284
3472
  `// Package ${packageName} is the starter slice of ${projectName}: rename it after
3285
3473
  // the outcome it delivers, and add one package per further outcome.
3286
3474
  package ${packageName}
3287
3475
  `
3288
3476
  ],
3289
3477
  [
3290
- (0, import_node_path8.join)(packageName, `${fileStem}_use_case.go`),
3478
+ (0, import_node_path10.join)(packageName, `${fileStem}_use_case.go`),
3291
3479
  `package ${packageName}
3292
3480
 
3293
3481
  // ${functionName} is the generator's sample behaviour, kept so the slice builds and tests.
@@ -3297,7 +3485,7 @@ func ${functionName}(name string) string {
3297
3485
  `
3298
3486
  ],
3299
3487
  [
3300
- (0, import_node_path8.join)(packageName, `${fileStem}_use_case_test.go`),
3488
+ (0, import_node_path10.join)(packageName, `${fileStem}_use_case_test.go`),
3301
3489
  `package ${packageName}
3302
3490
 
3303
3491
  import "testing"
@@ -3311,7 +3499,7 @@ func Test${functionName}(t *testing.T) {
3311
3499
  ]
3312
3500
  ];
3313
3501
  for (const [relativePath, content] of files) {
3314
- const path = (0, import_node_path8.join)(projectRoot, relativePath);
3502
+ const path = (0, import_node_path10.join)(projectRoot, relativePath);
3315
3503
  if (!fileExists(path)) {
3316
3504
  writeFileEnsured(path, content);
3317
3505
  }
@@ -3329,6 +3517,9 @@ function prepareGo(workspaceRoot) {
3329
3517
  }
3330
3518
  function addGoApp(workspaceRoot, name, options = {}) {
3331
3519
  const cgo = options.cgo === true;
3520
+ if (options.web !== void 0) {
3521
+ assertWebApp(workspaceRoot, options.web);
3522
+ }
3332
3523
  prepareGo(workspaceRoot);
3333
3524
  ensureAdmZip(workspaceRoot);
3334
3525
  runNx(
@@ -3342,7 +3533,7 @@ function addGoApp(workspaceRoot, name, options = {}) {
3342
3533
  ],
3343
3534
  workspaceRoot
3344
3535
  );
3345
- addProjectJsonTargets((0, import_node_path8.join)(workspaceRoot, "apps", name, "project.json"), {
3536
+ addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "apps", name, "project.json"), {
3346
3537
  build: goBuildTarget(name),
3347
3538
  test: goTestTarget(),
3348
3539
  lint: goLintTarget(),
@@ -3356,6 +3547,9 @@ function addGoApp(workspaceRoot, name, options = {}) {
3356
3547
  if (options.release === true) {
3357
3548
  makeGoAppReleasable(workspaceRoot, name);
3358
3549
  }
3550
+ if (options.web !== void 0) {
3551
+ wireGoAppToWeb(workspaceRoot, name, options.web);
3552
+ }
3359
3553
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:start` });
3360
3554
  if (cgo) {
3361
3555
  logger.warn(
@@ -3377,7 +3571,7 @@ function addGoFunctionApp(workspaceRoot, name) {
3377
3571
  ],
3378
3572
  workspaceRoot
3379
3573
  );
3380
- addProjectJsonTargets((0, import_node_path8.join)(workspaceRoot, "apps", name, "project.json"), {
3574
+ addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "apps", name, "project.json"), {
3381
3575
  "build": goBuildTarget(name),
3382
3576
  "test": goTestTarget(),
3383
3577
  "lint": goLintTarget(),
@@ -3400,11 +3594,11 @@ function addGoLib(workspaceRoot, name) {
3400
3594
  ],
3401
3595
  workspaceRoot
3402
3596
  );
3403
- addProjectJsonTargets((0, import_node_path8.join)(workspaceRoot, "packages", name, "project.json"), {
3597
+ addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "packages", name, "project.json"), {
3404
3598
  test: goTestTarget(),
3405
3599
  lint: goLintTarget()
3406
3600
  });
3407
- const slice = reshapeGoLibraryScaffold((0, import_node_path8.join)(workspaceRoot, "packages", name), name);
3601
+ const slice = reshapeGoLibraryScaffold((0, import_node_path10.join)(workspaceRoot, "packages", name), name);
3408
3602
  registerProjectCommands(workspaceRoot, name, { build: false });
3409
3603
  const module2 = goModulePath(workspaceRoot);
3410
3604
  if (module2) {
@@ -3424,11 +3618,11 @@ function addGoInternalLib(workspaceRoot, name) {
3424
3618
  ],
3425
3619
  workspaceRoot
3426
3620
  );
3427
- addProjectJsonTargets((0, import_node_path8.join)(workspaceRoot, "libs", name, "project.json"), {
3621
+ addProjectJsonTargets((0, import_node_path10.join)(workspaceRoot, "libs", name, "project.json"), {
3428
3622
  test: goTestTarget(),
3429
3623
  lint: goLintTarget()
3430
3624
  });
3431
- const slice = reshapeGoLibraryScaffold((0, import_node_path8.join)(workspaceRoot, "libs", name), name);
3625
+ const slice = reshapeGoLibraryScaffold((0, import_node_path10.join)(workspaceRoot, "libs", name), name);
3432
3626
  registerProjectCommands(workspaceRoot, name, { build: false });
3433
3627
  const module2 = goModulePath(workspaceRoot);
3434
3628
  if (module2) {
@@ -3437,7 +3631,7 @@ function addGoInternalLib(workspaceRoot, name) {
3437
3631
  }
3438
3632
 
3439
3633
  // src/project-scaffolding/node.use-case.ts
3440
- var import_node_path9 = require("path");
3634
+ var import_node_path11 = require("path");
3441
3635
  function ensurePlugin2(workspaceRoot, packageName) {
3442
3636
  if (hasPlugin(workspaceRoot, packageName)) {
3443
3637
  return;
@@ -3461,12 +3655,12 @@ function runNodeApp(workspaceRoot, name, stack, framework) {
3461
3655
  ],
3462
3656
  workspaceRoot
3463
3657
  );
3464
- const appRoot = (0, import_node_path9.join)(workspaceRoot, "apps", name);
3658
+ const appRoot = (0, import_node_path11.join)(workspaceRoot, "apps", name);
3465
3659
  separateDeclarationOutput(appRoot);
3466
3660
  repairAssetMapping(appRoot, name);
3467
3661
  }
3468
3662
  function separateDeclarationOutput(appRoot) {
3469
- const tsconfigPath = (0, import_node_path9.join)(appRoot, "tsconfig.app.json");
3663
+ const tsconfigPath = (0, import_node_path11.join)(appRoot, "tsconfig.app.json");
3470
3664
  if (!fileExists(tsconfigPath)) {
3471
3665
  return;
3472
3666
  }
@@ -3488,7 +3682,7 @@ function separateDeclarationOutput(appRoot) {
3488
3682
  );
3489
3683
  }
3490
3684
  function repairAssetMapping(appRoot, name) {
3491
- const manifestPath = (0, import_node_path9.join)(appRoot, "package.json");
3685
+ const manifestPath = (0, import_node_path11.join)(appRoot, "package.json");
3492
3686
  if (!fileExists(manifestPath)) {
3493
3687
  return;
3494
3688
  }
@@ -3515,7 +3709,7 @@ function nodeAppPackageTarget(name) {
3515
3709
  function addNodeApp(workspaceRoot, name, stack, framework = "none") {
3516
3710
  runNodeApp(workspaceRoot, name, stack, framework);
3517
3711
  ensureAdmZip(workspaceRoot);
3518
- addNxTargets((0, import_node_path9.join)(workspaceRoot, "apps", name, "package.json"), {
3712
+ addNxTargets((0, import_node_path11.join)(workspaceRoot, "apps", name, "package.json"), {
3519
3713
  package: nodeAppPackageTarget(name)
3520
3714
  });
3521
3715
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
@@ -3571,10 +3765,10 @@ describe('buildGreeting', () => {
3571
3765
  })
3572
3766
  `;
3573
3767
  function repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot) {
3574
- const manifestPath = (0, import_node_path9.join)(nodeFunctionAppRoot, "package.json");
3768
+ const manifestPath = (0, import_node_path11.join)(nodeFunctionAppRoot, "package.json");
3575
3769
  const manifest = readJson(manifestPath);
3576
3770
  const azureFunctionsVersion = readJson(
3577
- (0, import_node_path9.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
3771
+ (0, import_node_path11.join)(workspaceRoot, "node_modules/@azure/functions/package.json")
3578
3772
  ).version;
3579
3773
  const dependencies = manifest.dependencies ?? {};
3580
3774
  writeFileEnsured(
@@ -3617,21 +3811,21 @@ function nodeFunctionAppStartTarget(name) {
3617
3811
  function addNodeFunctionApp(workspaceRoot, name, stack) {
3618
3812
  runNodeApp(workspaceRoot, name, stack, "none");
3619
3813
  ensureAzureFunctionsPackage(workspaceRoot);
3620
- const nodeFunctionAppRoot = (0, import_node_path9.join)(workspaceRoot, "apps", name);
3621
- writeFileEnsured((0, import_node_path9.join)(nodeFunctionAppRoot, "src/main.ts"), NODE_FUNCTION_APP_MAIN);
3622
- writeFileEnsured((0, import_node_path9.join)(nodeFunctionAppRoot, "src/functions/hello.ts"), NODE_FUNCTION_APP_HELLO);
3814
+ const nodeFunctionAppRoot = (0, import_node_path11.join)(workspaceRoot, "apps", name);
3815
+ writeFileEnsured((0, import_node_path11.join)(nodeFunctionAppRoot, "src/main.ts"), NODE_FUNCTION_APP_MAIN);
3816
+ writeFileEnsured((0, import_node_path11.join)(nodeFunctionAppRoot, "src/functions/hello.ts"), NODE_FUNCTION_APP_HELLO);
3623
3817
  writeFileEnsured(
3624
- (0, import_node_path9.join)(nodeFunctionAppRoot, "src/functions/greeting.ts"),
3818
+ (0, import_node_path11.join)(nodeFunctionAppRoot, "src/functions/greeting.ts"),
3625
3819
  NODE_FUNCTION_APP_GREETING
3626
3820
  );
3627
3821
  writeFileEnsured(
3628
- (0, import_node_path9.join)(nodeFunctionAppRoot, "src/functions/greeting.spec.ts"),
3822
+ (0, import_node_path11.join)(nodeFunctionAppRoot, "src/functions/greeting.spec.ts"),
3629
3823
  NODE_FUNCTION_APP_GREETING_SPEC
3630
3824
  );
3631
- writeFileEnsured((0, import_node_path9.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
3825
+ writeFileEnsured((0, import_node_path11.join)(nodeFunctionAppRoot, "host.json"), NODE_FUNCTION_APP_HOST_JSON);
3632
3826
  repairNodeFunctionAppManifest(nodeFunctionAppRoot, workspaceRoot);
3633
3827
  ensureAdmZip(workspaceRoot);
3634
- addNxTargets((0, import_node_path9.join)(nodeFunctionAppRoot, "package.json"), {
3828
+ addNxTargets((0, import_node_path11.join)(nodeFunctionAppRoot, "package.json"), {
3635
3829
  package: nodeFunctionAppPackageTarget(name),
3636
3830
  prune: nodeFunctionAppPruneTarget(name),
3637
3831
  start: nodeFunctionAppStartTarget(name)
@@ -3641,11 +3835,11 @@ function addNodeFunctionApp(workspaceRoot, name, stack) {
3641
3835
  }
3642
3836
 
3643
3837
  // src/project-scaffolding/npm-lib.use-case.ts
3644
- var import_node_path13 = require("path");
3838
+ var import_node_path15 = require("path");
3645
3839
 
3646
3840
  // src/rollup-library/repair-publishable-manifest.use-case.ts
3647
- var import_node_fs8 = require("fs");
3648
- var import_node_path10 = require("path");
3841
+ var import_node_fs10 = require("fs");
3842
+ var import_node_path12 = require("path");
3649
3843
  var WRONG_TYPES_PATH = "./dist/index.esm.d.ts";
3650
3844
  var ACTUAL_TYPES_PATH = "./dist/src/index.d.ts";
3651
3845
  var DECLARATION_MAP_EXCLUSION = "!**/*.d.ts.map";
@@ -3668,14 +3862,14 @@ function repairPublishableManifest(manifestPath) {
3668
3862
  }
3669
3863
  function repairPublishableManifests(workspaceRoot) {
3670
3864
  const changed = [];
3671
- const manifests = (0, import_node_fs8.globSync)(["packages/*/package.json", "libs/*/package.json"], {
3865
+ const manifests = (0, import_node_fs10.globSync)(["packages/*/package.json", "libs/*/package.json"], {
3672
3866
  cwd: workspaceRoot
3673
3867
  });
3674
3868
  for (const relativePath of manifests) {
3675
- const manifestPath = (0, import_node_path10.join)(workspaceRoot, relativePath);
3676
- const before = (0, import_node_fs8.readFileSync)(manifestPath, "utf8");
3869
+ const manifestPath = (0, import_node_path12.join)(workspaceRoot, relativePath);
3870
+ const before = (0, import_node_fs10.readFileSync)(manifestPath, "utf8");
3677
3871
  repairPublishableManifest(manifestPath);
3678
- const after = (0, import_node_fs8.readFileSync)(manifestPath, "utf8");
3872
+ const after = (0, import_node_fs10.readFileSync)(manifestPath, "utf8");
3679
3873
  if (after !== before) {
3680
3874
  changed.push(relativePath.replaceAll("\\", "/"));
3681
3875
  }
@@ -3684,8 +3878,8 @@ function repairPublishableManifests(workspaceRoot) {
3684
3878
  }
3685
3879
 
3686
3880
  // src/rollup-library/repair-rollup-config.use-case.ts
3687
- var import_node_fs9 = require("fs");
3688
- var import_node_path11 = require("path");
3881
+ var import_node_fs11 = require("fs");
3882
+ var import_node_path13 = require("path");
3689
3883
 
3690
3884
  // src/rollup-library/rollup-config.algorithm.ts
3691
3885
  var ROLLUP_CONFIG_PLACEHOLDER = [
@@ -3887,12 +4081,12 @@ function withUpgradedDeclarationSpecifierPlugin(config) {
3887
4081
  // src/rollup-library/repair-rollup-config.use-case.ts
3888
4082
  function repairRollupSourceMaps(workspaceRoot) {
3889
4083
  const changed = [];
3890
- const configs = (0, import_node_fs9.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
4084
+ const configs = (0, import_node_fs11.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
3891
4085
  cwd: workspaceRoot
3892
4086
  });
3893
4087
  for (const relativePath of configs) {
3894
- const configPath = (0, import_node_path11.join)(workspaceRoot, relativePath);
3895
- const before = (0, import_node_fs9.readFileSync)(configPath, "utf8");
4088
+ const configPath = (0, import_node_path13.join)(workspaceRoot, relativePath);
4089
+ const before = (0, import_node_fs11.readFileSync)(configPath, "utf8");
3896
4090
  const after = withRollupSourceMaps(before);
3897
4091
  if (after !== before) {
3898
4092
  writeFileEnsured(configPath, after);
@@ -3903,12 +4097,12 @@ function repairRollupSourceMaps(workspaceRoot) {
3903
4097
  }
3904
4098
  function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
3905
4099
  const changed = [];
3906
- const configs = (0, import_node_fs9.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
4100
+ const configs = (0, import_node_fs11.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
3907
4101
  cwd: workspaceRoot
3908
4102
  });
3909
4103
  for (const relativePath of configs) {
3910
- const configPath = (0, import_node_path11.join)(workspaceRoot, relativePath);
3911
- const before = (0, import_node_fs9.readFileSync)(configPath, "utf8");
4104
+ const configPath = (0, import_node_path13.join)(workspaceRoot, relativePath);
4105
+ const before = (0, import_node_fs11.readFileSync)(configPath, "utf8");
3912
4106
  const after = withUpgradedDeclarationSpecifierPlugin(before);
3913
4107
  if (after !== before) {
3914
4108
  writeFileEnsured(configPath, after);
@@ -3918,11 +4112,11 @@ function upgradeDeclarationSpecifierPlugins(workspaceRoot) {
3918
4112
  return changed;
3919
4113
  }
3920
4114
  function repairDeclarationSpecifiers(projectRoot) {
3921
- const configPath = (0, import_node_path11.join)(projectRoot, "rollup.config.cjs");
4115
+ const configPath = (0, import_node_path13.join)(projectRoot, "rollup.config.cjs");
3922
4116
  if (!fileExists(configPath)) {
3923
4117
  return;
3924
4118
  }
3925
- const config = (0, import_node_fs9.readFileSync)(configPath, "utf8");
4119
+ const config = (0, import_node_fs11.readFileSync)(configPath, "utf8");
3926
4120
  if (!config.includes(ROLLUP_CONFIG_PLACEHOLDER)) {
3927
4121
  return;
3928
4122
  }
@@ -3931,10 +4125,10 @@ function repairDeclarationSpecifiers(projectRoot) {
3931
4125
  }
3932
4126
 
3933
4127
  // src/rollup-library/rollup-config.repository.ts
3934
- var import_node_fs10 = require("fs");
3935
- var import_node_path12 = require("path");
4128
+ var import_node_fs12 = require("fs");
4129
+ var import_node_path14 = require("path");
3936
4130
  function resolveRequireTarget(fromDir, specifier) {
3937
- const base = (0, import_node_path12.join)(fromDir, specifier);
4131
+ const base = (0, import_node_path14.join)(fromDir, specifier);
3938
4132
  return [base, `${base}.cjs`, `${base}.js`].find((candidate) => fileExists(candidate));
3939
4133
  }
3940
4134
  function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()) {
@@ -3944,7 +4138,7 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
3944
4138
  visited.add(configPath);
3945
4139
  let text;
3946
4140
  try {
3947
- text = (0, import_node_fs10.readFileSync)(configPath, "utf8");
4141
+ text = (0, import_node_fs12.readFileSync)(configPath, "utf8");
3948
4142
  } catch {
3949
4143
  return "";
3950
4144
  }
@@ -3952,15 +4146,15 @@ function resolveRollupConfigText(configPath, visited = /* @__PURE__ */ new Set()
3952
4146
  text.matchAll(/require\((['"])(\.[^'"]*)\1\)/g),
3953
4147
  (match) => match[2]
3954
4148
  );
3955
- const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path12.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
4149
+ const requiredText = specifiers.map((specifier) => resolveRequireTarget((0, import_node_path14.dirname)(configPath), specifier)).filter((target) => target !== void 0).map((target) => resolveRollupConfigText(target, visited));
3956
4150
  return [text, ...requiredText].join("\n");
3957
4151
  }
3958
4152
 
3959
4153
  // src/project-scaffolding/npm-lib.use-case.ts
3960
4154
  async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
3961
4155
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
3962
- const projectRoot = (0, import_node_path13.join)(workspaceRoot, "packages", name);
3963
- const manifestPath = (0, import_node_path13.join)(projectRoot, "package.json");
4156
+ const projectRoot = (0, import_node_path15.join)(workspaceRoot, "packages", name);
4157
+ const manifestPath = (0, import_node_path15.join)(projectRoot, "package.json");
3964
4158
  runGeneratorAndRepair(
3965
4159
  workspaceRoot,
3966
4160
  [
@@ -3989,8 +4183,8 @@ async function addNpmLib(workspaceRoot, name, options, kindProvided, stack) {
3989
4183
  }
3990
4184
 
3991
4185
  // src/project-scaffolding/python.use-case.ts
3992
- var import_node_fs11 = require("fs");
3993
- var import_node_path14 = require("path");
4186
+ var import_node_fs13 = require("fs");
4187
+ var import_node_path16 = require("path");
3994
4188
  function ensurePython(workspaceRoot) {
3995
4189
  const hasPython = runShell("python3", ["--version"], workspaceRoot) === 0 || runShell("python", ["--version"], workspaceRoot) === 0;
3996
4190
  if (!hasPython) {
@@ -4013,7 +4207,7 @@ function ensurePythonPipPlugin(workspaceRoot) {
4013
4207
  registerPythonGraphPlugin(workspaceRoot);
4014
4208
  }
4015
4209
  function registerPythonGraphPlugin(workspaceRoot) {
4016
- const nxJsonPath = (0, import_node_path14.join)(workspaceRoot, "nx.json");
4210
+ const nxJsonPath = (0, import_node_path16.join)(workspaceRoot, "nx.json");
4017
4211
  if (!fileExists(nxJsonPath)) {
4018
4212
  return;
4019
4213
  }
@@ -4036,7 +4230,7 @@ pytest
4036
4230
  pip-audit
4037
4231
  `;
4038
4232
  function ensureRequirementsDev(workspaceRoot) {
4039
- const requirementsDevPath = (0, import_node_path14.join)(workspaceRoot, "requirements-dev.txt");
4233
+ const requirementsDevPath = (0, import_node_path16.join)(workspaceRoot, "requirements-dev.txt");
4040
4234
  if (!fileExists(requirementsDevPath)) {
4041
4235
  writeFileEnsured(requirementsDevPath, PYTHON_REQUIREMENTS_DEV);
4042
4236
  }
@@ -4096,8 +4290,8 @@ function addPythonApp(workspaceRoot, name) {
4096
4290
  ["g", "@mnci/nx-python-pip:application", name, `--directory=apps/${name}`, "--no-interactive"],
4097
4291
  workspaceRoot
4098
4292
  );
4099
- writeFileEnsured((0, import_node_path14.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
4100
- addProjectJsonTargets((0, import_node_path14.join)(workspaceRoot, "apps", name, "project.json"), {
4293
+ writeFileEnsured((0, import_node_path16.join)(workspaceRoot, "apps", name, "main.py"), pythonAppMain(name));
4294
+ addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json"), {
4101
4295
  package: pythonAppPackageTarget(name),
4102
4296
  start: pythonAppStartTarget(name)
4103
4297
  });
@@ -4119,7 +4313,7 @@ function addPythonFunctionApp(workspaceRoot, name) {
4119
4313
  workspaceRoot
4120
4314
  );
4121
4315
  const moduleDirectory = pythonModuleDirectory(name);
4122
- addProjectJsonTargets((0, import_node_path14.join)(workspaceRoot, "apps", name, "project.json"), {
4316
+ addProjectJsonTargets((0, import_node_path16.join)(workspaceRoot, "apps", name, "project.json"), {
4123
4317
  package: pythonFunctionAppPackageTarget(name, moduleDirectory),
4124
4318
  start: pythonFunctionAppStartTarget(name)
4125
4319
  });
@@ -4160,7 +4354,7 @@ function addPythonInternalLib(workspaceRoot, name) {
4160
4354
  var PYTHON_PROJECT_DIRS = ["apps", "python-packages", "libs"];
4161
4355
  function findPythonProjectDirectory(workspaceRoot, name) {
4162
4356
  return PYTHON_PROJECT_DIRS.find(
4163
- (directory) => fileExists((0, import_node_path14.join)(workspaceRoot, directory, name, "pyproject.toml"))
4357
+ (directory) => fileExists((0, import_node_path16.join)(workspaceRoot, directory, name, "pyproject.toml"))
4164
4358
  );
4165
4359
  }
4166
4360
  function parseVendorEntries(pyprojectToml) {
@@ -4199,7 +4393,7 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
4199
4393
  `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.`
4200
4394
  );
4201
4395
  }
4202
- if (!fileExists((0, import_node_path14.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
4396
+ if (!fileExists((0, import_node_path16.join)(workspaceRoot, "libs", lib, "pyproject.toml"))) {
4203
4397
  throw new Error(
4204
4398
  `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.`
4205
4399
  );
@@ -4207,8 +4401,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
4207
4401
  if (consumerDirectory === "libs" && consumer === lib) {
4208
4402
  throw new Error(`'${consumer}' cannot vendor itself.`);
4209
4403
  }
4210
- const pyprojectPath = (0, import_node_path14.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
4211
- const pyprojectToml = (0, import_node_fs11.readFileSync)(pyprojectPath, "utf8");
4404
+ const pyprojectPath = (0, import_node_path16.join)(workspaceRoot, consumerDirectory, consumer, "pyproject.toml");
4405
+ const pyprojectToml = (0, import_node_fs13.readFileSync)(pyprojectPath, "utf8");
4212
4406
  if (parseVendorEntries(pyprojectToml).includes(lib)) {
4213
4407
  logger.info(`'${consumer}' already vendors '${lib}' \u2014 nothing to do.`);
4214
4408
  return;
@@ -4220,8 +4414,8 @@ async function addPythonVendor(workspaceRoot, consumer, options, kindProvided) {
4220
4414
  }
4221
4415
 
4222
4416
  // src/project-scaffolding/react-app.use-case.ts
4223
- var import_node_fs12 = require("fs");
4224
- var import_node_path15 = require("path");
4417
+ var import_node_fs14 = require("fs");
4418
+ var import_node_path17 = require("path");
4225
4419
  var REACT_ENVIRONMENTS = ["dev", "uat", "prod"];
4226
4420
  function reactEnvironmentFile(environment) {
4227
4421
  return `# Vite compiles VITE_-prefixed vars into the '${environment}' bundle at build time.
@@ -4258,12 +4452,12 @@ function reactAppTargets(name) {
4258
4452
  return targets;
4259
4453
  }
4260
4454
  function allowEnvFiles(workspaceRoot) {
4261
- const gitignorePath = (0, import_node_path15.join)(workspaceRoot, ".gitignore");
4455
+ const gitignorePath = (0, import_node_path17.join)(workspaceRoot, ".gitignore");
4262
4456
  if (!fileExists(gitignorePath)) {
4263
4457
  return;
4264
4458
  }
4265
4459
  const marker = "# MoNecromanCI: keep the committed per-environment Vite config (public VITE_ values)";
4266
- const current = (0, import_node_fs12.readFileSync)(gitignorePath, "utf8");
4460
+ const current = (0, import_node_fs14.readFileSync)(gitignorePath, "utf8");
4267
4461
  if (current.includes(marker)) {
4268
4462
  return;
4269
4463
  }
@@ -4290,24 +4484,24 @@ function addReactApp(workspaceRoot, name, stack) {
4290
4484
  workspaceRoot
4291
4485
  );
4292
4486
  ensureAdmZip(workspaceRoot);
4293
- const reactAppRoot = (0, import_node_path15.join)(workspaceRoot, "apps", name);
4487
+ const reactAppRoot = (0, import_node_path17.join)(workspaceRoot, "apps", name);
4294
4488
  for (const environment of REACT_ENVIRONMENTS) {
4295
- writeFileEnsured((0, import_node_path15.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
4489
+ writeFileEnsured((0, import_node_path17.join)(reactAppRoot, `.env.${environment}`), reactEnvironmentFile(environment));
4296
4490
  }
4297
4491
  allowEnvFiles(workspaceRoot);
4298
- addNxTargets((0, import_node_path15.join)(reactAppRoot, "package.json"), reactAppTargets(name));
4492
+ addNxTargets((0, import_node_path17.join)(reactAppRoot, "package.json"), reactAppTargets(name));
4299
4493
  removeGeneratedEslintConfig(workspaceRoot, `apps/${name}`);
4300
4494
  registerProjectCommands(workspaceRoot, name, { build: true, start: `nx run ${name}:serve` });
4301
4495
  }
4302
4496
 
4303
4497
  // src/project-scaffolding/react-lib.use-case.ts
4304
- var import_node_path16 = require("path");
4498
+ var import_node_path18 = require("path");
4305
4499
  var REACT_LIB_BUNDLER = "rollup";
4306
4500
  async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
4307
4501
  ensurePlugin(workspaceRoot, "@nx/react");
4308
4502
  const scope = options.scope ?? (kindProvided ? defaultScope(workspaceRoot) : await promptText("npm scope for the published package", defaultScope(workspaceRoot)));
4309
- const projectRoot = (0, import_node_path16.join)(workspaceRoot, "packages", name);
4310
- const publishableManifest = (0, import_node_path16.join)(projectRoot, "package.json");
4503
+ const projectRoot = (0, import_node_path18.join)(workspaceRoot, "packages", name);
4504
+ const publishableManifest = (0, import_node_path18.join)(projectRoot, "package.json");
4311
4505
  runGeneratorAndRepair(
4312
4506
  workspaceRoot,
4313
4507
  [
@@ -4336,8 +4530,8 @@ async function addReactLib(workspaceRoot, name, options, kindProvided, stack) {
4336
4530
  }
4337
4531
  function addReactInternalLib(workspaceRoot, name, stack) {
4338
4532
  ensurePlugin(workspaceRoot, "@nx/react");
4339
- const projectRoot = (0, import_node_path16.join)(workspaceRoot, "libs", name);
4340
- const privateManifest = (0, import_node_path16.join)(projectRoot, "package.json");
4533
+ const projectRoot = (0, import_node_path18.join)(workspaceRoot, "libs", name);
4534
+ const privateManifest = (0, import_node_path18.join)(projectRoot, "package.json");
4341
4535
  runGeneratorAndRepair(
4342
4536
  workspaceRoot,
4343
4537
  [
@@ -4363,8 +4557,8 @@ function addReactInternalLib(workspaceRoot, name, stack) {
4363
4557
  }
4364
4558
 
4365
4559
  // src/project-scaffolding/vscode-extension.use-case.ts
4366
- var import_node_fs13 = require("fs");
4367
- var import_node_path17 = require("path");
4560
+ var import_node_fs15 = require("fs");
4561
+ var import_node_path19 = require("path");
4368
4562
  var VSCODE_EXTENSION_SCRIPT_PATH = "tools/vscode-extension.cjs";
4369
4563
  var VSCODE_SIDECAR_TARGETS = {
4370
4564
  "win32-x64": "windows-amd64",
@@ -4548,8 +4742,8 @@ export const window = {
4548
4742
  var VSCODE_STUB_PATH = "test/vscode.stub.ts";
4549
4743
  function mapVscodeToStub(projectRoot, testRunner) {
4550
4744
  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}\` },`];
4551
- const path = (0, import_node_path17.join)(projectRoot, file);
4552
- const content = fileExists(path) ? (0, import_node_fs13.readFileSync)(path, "utf8") : "";
4745
+ const path = (0, import_node_path19.join)(projectRoot, file);
4746
+ const content = fileExists(path) ? (0, import_node_fs15.readFileSync)(path, "utf8") : "";
4553
4747
  const line = content.split("\n").find((candidate) => candidate.trim() === anchor);
4554
4748
  if (line === void 0) {
4555
4749
  throw new Error(`${file} has no "${anchor}" line to map the vscode module after; map 'vscode' to ${VSCODE_STUB_PATH} by hand.`);
@@ -4569,11 +4763,11 @@ function ensureVscodeToolchain(workspaceRoot) {
4569
4763
  }
4570
4764
  }
4571
4765
  function defaultPublisher(workspaceRoot) {
4572
- const { name } = readJson((0, import_node_path17.join)(workspaceRoot, "package.json"));
4766
+ const { name } = readJson((0, import_node_path19.join)(workspaceRoot, "package.json"));
4573
4767
  return (name ?? "publisher").replace(/^@/, "").split("/", 1)[0];
4574
4768
  }
4575
4769
  function reshapeManifest(projectRoot, name, publisher, typesVersion) {
4576
- const manifestPath = (0, import_node_path17.join)(projectRoot, "package.json");
4770
+ const manifestPath = (0, import_node_path19.join)(projectRoot, "package.json");
4577
4771
  const manifest = readJson(manifestPath);
4578
4772
  const { nx = {}, ...rest } = manifest;
4579
4773
  const targets = { ...nx.targets };
@@ -4637,11 +4831,11 @@ function vscodeExtensionPublishTarget(name, sidecar) {
4637
4831
  };
4638
4832
  }
4639
4833
  function addDebugLaunch(workspaceRoot, name) {
4640
- const file = (0, import_node_fs13.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
4834
+ const file = (0, import_node_fs15.readdirSync)(workspaceRoot).find((entry) => entry.endsWith(".code-workspace"));
4641
4835
  if (file === void 0) {
4642
4836
  return;
4643
4837
  }
4644
- const path = (0, import_node_path17.join)(workspaceRoot, file);
4838
+ const path = (0, import_node_path19.join)(workspaceRoot, file);
4645
4839
  const workspace = readCodeWorkspace(path) ?? {};
4646
4840
  const folder = `\${workspaceFolder:${workspace.folders?.[0]?.name ?? file.replace(/\.code-workspace$/, "")}}`;
4647
4841
  const taskLabel = `${name}: build (development)`;
@@ -4674,39 +4868,39 @@ function addDebugLaunch(workspaceRoot, name) {
4674
4868
  );
4675
4869
  }
4676
4870
  function refreshVscodeExtensionScript(workspaceRoot) {
4677
- const apps = (0, import_node_path17.join)(workspaceRoot, "apps");
4871
+ const apps = (0, import_node_path19.join)(workspaceRoot, "apps");
4678
4872
  let entries;
4679
4873
  try {
4680
- entries = (0, import_node_fs13.readdirSync)(apps);
4874
+ entries = (0, import_node_fs15.readdirSync)(apps);
4681
4875
  } catch {
4682
4876
  return false;
4683
4877
  }
4684
4878
  const hasExtension = entries.some((entry) => {
4685
- const manifestPath = (0, import_node_path17.join)(apps, entry, "package.json");
4879
+ const manifestPath = (0, import_node_path19.join)(apps, entry, "package.json");
4686
4880
  if (!fileExists(manifestPath)) {
4687
4881
  return false;
4688
4882
  }
4689
4883
  const tags = readJson(manifestPath).nx?.tags ?? [];
4690
4884
  return tags.includes(VSCODE_EXTENSION_TAG);
4691
4885
  });
4692
- const path = (0, import_node_path17.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
4693
- if (!hasExtension || fileExists(path) && (0, import_node_fs13.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
4886
+ const path = (0, import_node_path19.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH);
4887
+ if (!hasExtension || fileExists(path) && (0, import_node_fs15.readFileSync)(path, "utf8") === VSCODE_EXTENSION_SCRIPT) {
4694
4888
  return false;
4695
4889
  }
4696
4890
  writeFileEnsured(path, VSCODE_EXTENSION_SCRIPT);
4697
4891
  return true;
4698
4892
  }
4699
4893
  function pinVscodeExtensionProjectNames(workspaceRoot) {
4700
- const apps = (0, import_node_path17.join)(workspaceRoot, "apps");
4894
+ const apps = (0, import_node_path19.join)(workspaceRoot, "apps");
4701
4895
  let entries;
4702
4896
  try {
4703
- entries = (0, import_node_fs13.readdirSync)(apps);
4897
+ entries = (0, import_node_fs15.readdirSync)(apps);
4704
4898
  } catch {
4705
4899
  return [];
4706
4900
  }
4707
4901
  const updated = [];
4708
4902
  for (const entry of entries) {
4709
- const manifestPath = (0, import_node_path17.join)(apps, entry, "package.json");
4903
+ const manifestPath = (0, import_node_path19.join)(apps, entry, "package.json");
4710
4904
  if (!fileExists(manifestPath)) {
4711
4905
  continue;
4712
4906
  }
@@ -4726,23 +4920,23 @@ function refreshLockFile(workspaceRoot, name) {
4726
4920
  }
4727
4921
  function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
4728
4922
  const { sidecar } = options;
4729
- if (sidecar !== void 0 && !fileExists((0, import_node_path17.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
4923
+ if (sidecar !== void 0 && !fileExists((0, import_node_path19.join)(workspaceRoot, "apps", sidecar, "project.json"))) {
4730
4924
  throw new Error(`--sidecar ${sidecar}: no Go app at apps/${sidecar}. Add it first with \`mnci add go-app ${sidecar}\`.`);
4731
4925
  }
4732
4926
  runNodeApp(workspaceRoot, name, stack, "none");
4733
4927
  ensureVscodeToolchain(workspaceRoot);
4734
- const projectRoot = (0, import_node_path17.join)(workspaceRoot, "apps", name);
4735
- const typesVersion = readJson((0, import_node_path17.join)(workspaceRoot, "node_modules/@types/vscode/package.json")).version;
4928
+ const projectRoot = (0, import_node_path19.join)(workspaceRoot, "apps", name);
4929
+ const typesVersion = readJson((0, import_node_path19.join)(workspaceRoot, "node_modules/@types/vscode/package.json")).version;
4736
4930
  reshapeManifest(projectRoot, name, options.publisher ?? defaultPublisher(workspaceRoot), typesVersion);
4737
- addVscodeTypes((0, import_node_path17.join)(projectRoot, "tsconfig.app.json"));
4738
- addVscodeTypes((0, import_node_path17.join)(projectRoot, "tsconfig.spec.json"));
4739
- writeFileEnsured((0, import_node_path17.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
4740
- writeFileEnsured((0, import_node_path17.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
4741
- writeFileEnsured((0, import_node_path17.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
4931
+ addVscodeTypes((0, import_node_path19.join)(projectRoot, "tsconfig.app.json"));
4932
+ addVscodeTypes((0, import_node_path19.join)(projectRoot, "tsconfig.spec.json"));
4933
+ writeFileEnsured((0, import_node_path19.join)(projectRoot, "src/main.ts"), vscodeExtensionMain(name));
4934
+ writeFileEnsured((0, import_node_path19.join)(projectRoot, "src/main.spec.ts"), vscodeExtensionMainSpec(name));
4935
+ writeFileEnsured((0, import_node_path19.join)(projectRoot, VSCODE_STUB_PATH), VSCODE_STUB);
4742
4936
  mapVscodeToStub(projectRoot, stack.testRunner);
4743
- writeFileEnsured((0, import_node_path17.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
4744
- writeFileEnsured((0, import_node_path17.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
4745
- addNxTargets((0, import_node_path17.join)(projectRoot, "package.json"), {
4937
+ writeFileEnsured((0, import_node_path19.join)(projectRoot, ".vscodeignore"), VSCODE_IGNORE);
4938
+ writeFileEnsured((0, import_node_path19.join)(workspaceRoot, VSCODE_EXTENSION_SCRIPT_PATH), VSCODE_EXTENSION_SCRIPT);
4939
+ addNxTargets((0, import_node_path19.join)(projectRoot, "package.json"), {
4746
4940
  "package": vscodeExtensionPackageTarget(name, sidecar),
4747
4941
  "nx-release-publish": vscodeExtensionPublishTarget(name, sidecar)
4748
4942
  });
@@ -4753,11 +4947,11 @@ function addVscodeExtension(workspaceRoot, name, stack, options = {}) {
4753
4947
  }
4754
4948
 
4755
4949
  // src/dependency-management/sync-dependencies.use-case.ts
4756
- var import_node_path19 = require("path");
4950
+ var import_node_path21 = require("path");
4757
4951
 
4758
4952
  // src/dependency-management/manifest.repository.ts
4759
- var import_node_fs14 = require("fs");
4760
- var import_node_path18 = require("path");
4953
+ var import_node_fs16 = require("fs");
4954
+ var import_node_path20 = require("path");
4761
4955
  var ECOSYSTEMS = ["npm", "pip", "pub", "nuget", "go"];
4762
4956
  var ROOT_LABEL = "(root)";
4763
4957
  var MANIFEST_GLOBS = {
@@ -4790,23 +4984,23 @@ function projectOf(manifestRelativePath) {
4790
4984
  }
4791
4985
  function hasEcosystem(workspaceRoot, ecosystem) {
4792
4986
  if (ecosystem === "go") {
4793
- return fileExists((0, import_node_path18.join)(workspaceRoot, "go.mod"));
4987
+ return fileExists((0, import_node_path20.join)(workspaceRoot, "go.mod"));
4794
4988
  }
4795
4989
  if (ecosystem === "nuget") {
4796
- return (0, import_node_fs14.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
4990
+ return (0, import_node_fs16.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot }).length > 0;
4797
4991
  }
4798
4992
  const rootMarker = {
4799
4993
  npm: "package.json",
4800
4994
  pip: "requirements-dev.txt",
4801
4995
  pub: "pubspec.yaml"
4802
4996
  };
4803
- return fileExists((0, import_node_path18.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs14.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
4997
+ return fileExists((0, import_node_path20.join)(workspaceRoot, rootMarker[ecosystem])) || (0, import_node_fs16.globSync)(MANIFEST_GLOBS[ecosystem], { cwd: workspaceRoot }).length > 0;
4804
4998
  }
4805
4999
  function collectNpm(workspaceRoot) {
4806
5000
  const sites = [];
4807
- const relativePaths = ["package.json", ...(0, import_node_fs14.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
5001
+ const relativePaths = ["package.json", ...(0, import_node_fs16.globSync)(MANIFEST_GLOBS.npm, { cwd: workspaceRoot })];
4808
5002
  for (const relativePath of relativePaths) {
4809
- const manifestPath = (0, import_node_path18.join)(workspaceRoot, relativePath);
5003
+ const manifestPath = (0, import_node_path20.join)(workspaceRoot, relativePath);
4810
5004
  try {
4811
5005
  const manifest = readJson(manifestPath);
4812
5006
  sites.push(...npmManifestSites(manifest, relativePath, manifestPath));
@@ -4867,17 +5061,17 @@ function collectPip(workspaceRoot) {
4867
5061
  name: parsed.name,
4868
5062
  ecosystem: "pip",
4869
5063
  project: projectOf(relativePath),
4870
- manifestPath: (0, import_node_path18.join)(workspaceRoot, relativePath),
5064
+ manifestPath: (0, import_node_path20.join)(workspaceRoot, relativePath),
4871
5065
  section,
4872
5066
  spec: parsed.spec,
4873
5067
  rewritable: parsed.rewritable && parsed.spec !== ""
4874
5068
  });
4875
5069
  };
4876
- const pyprojectPaths = (0, import_node_fs14.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
5070
+ const pyprojectPaths = (0, import_node_fs16.globSync)(MANIFEST_GLOBS.pip, { cwd: workspaceRoot });
4877
5071
  for (const relativePath of pyprojectPaths) {
4878
5072
  let content;
4879
5073
  try {
4880
- content = (0, import_node_fs14.readFileSync)((0, import_node_path18.join)(workspaceRoot, relativePath), "utf8");
5074
+ content = (0, import_node_fs16.readFileSync)((0, import_node_path20.join)(workspaceRoot, relativePath), "utf8");
4881
5075
  } catch {
4882
5076
  continue;
4883
5077
  }
@@ -4888,14 +5082,14 @@ function collectPip(workspaceRoot) {
4888
5082
  }
4889
5083
  const requirementsPaths = [
4890
5084
  "requirements-dev.txt",
4891
- ...(0, import_node_fs14.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
5085
+ ...(0, import_node_fs16.globSync)("apps/*/requirements.txt", { cwd: workspaceRoot })
4892
5086
  ];
4893
5087
  for (const relativePath of requirementsPaths) {
4894
- if (!fileExists((0, import_node_path18.join)(workspaceRoot, relativePath))) {
5088
+ if (!fileExists((0, import_node_path20.join)(workspaceRoot, relativePath))) {
4895
5089
  continue;
4896
5090
  }
4897
5091
  const section = relativePath === "requirements-dev.txt" ? "devDep" : "dep";
4898
- const lines = (0, import_node_fs14.readFileSync)((0, import_node_path18.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
5092
+ const lines = (0, import_node_fs16.readFileSync)((0, import_node_path20.join)(workspaceRoot, relativePath), "utf8").split(/\r?\n/);
4899
5093
  for (const line of lines) {
4900
5094
  push(relativePath, section, line);
4901
5095
  }
@@ -4933,11 +5127,11 @@ function pyprojectDependencies(content) {
4933
5127
  }
4934
5128
  function collectPub(workspaceRoot) {
4935
5129
  const sites = [];
4936
- const pubspecPaths = (0, import_node_fs14.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
5130
+ const pubspecPaths = (0, import_node_fs16.globSync)(MANIFEST_GLOBS.pub, { cwd: workspaceRoot });
4937
5131
  for (const relativePath of pubspecPaths) {
4938
5132
  let content;
4939
5133
  try {
4940
- content = (0, import_node_fs14.readFileSync)((0, import_node_path18.join)(workspaceRoot, relativePath), "utf8");
5134
+ content = (0, import_node_fs16.readFileSync)((0, import_node_path20.join)(workspaceRoot, relativePath), "utf8");
4941
5135
  } catch {
4942
5136
  continue;
4943
5137
  }
@@ -4947,7 +5141,7 @@ function collectPub(workspaceRoot) {
4947
5141
  name: entry.name,
4948
5142
  ecosystem: "pub",
4949
5143
  project: projectOf(relativePath),
4950
- manifestPath: (0, import_node_path18.join)(workspaceRoot, relativePath),
5144
+ manifestPath: (0, import_node_path20.join)(workspaceRoot, relativePath),
4951
5145
  section: block === "dependencies" ? "dep" : "devDep",
4952
5146
  spec: entry.spec,
4953
5147
  rewritable: entry.spec !== ""
@@ -4997,11 +5191,11 @@ function stripQuotes(value) {
4997
5191
  }
4998
5192
  function collectNuget(workspaceRoot) {
4999
5193
  const sites = [];
5000
- const csprojPaths = (0, import_node_fs14.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
5194
+ const csprojPaths = (0, import_node_fs16.globSync)(MANIFEST_GLOBS.nuget, { cwd: workspaceRoot });
5001
5195
  for (const relativePath of csprojPaths) {
5002
5196
  let content;
5003
5197
  try {
5004
- content = (0, import_node_fs14.readFileSync)((0, import_node_path18.join)(workspaceRoot, relativePath), "utf8");
5198
+ content = (0, import_node_fs16.readFileSync)((0, import_node_path20.join)(workspaceRoot, relativePath), "utf8");
5005
5199
  } catch {
5006
5200
  continue;
5007
5201
  }
@@ -5010,7 +5204,7 @@ function collectNuget(workspaceRoot) {
5010
5204
  name: entry.name,
5011
5205
  ecosystem: "nuget",
5012
5206
  project: projectOf(relativePath),
5013
- manifestPath: (0, import_node_path18.join)(workspaceRoot, relativePath),
5207
+ manifestPath: (0, import_node_path20.join)(workspaceRoot, relativePath),
5014
5208
  section: "dep",
5015
5209
  spec: entry.spec,
5016
5210
  // A plain SemVer string is rewritable; an MSBuild property reference
@@ -5035,13 +5229,13 @@ function csprojPackageReferences(content) {
5035
5229
  return entries;
5036
5230
  }
5037
5231
  function collectGo(workspaceRoot) {
5038
- const manifestPath = (0, import_node_path18.join)(workspaceRoot, "go.mod");
5232
+ const manifestPath = (0, import_node_path20.join)(workspaceRoot, "go.mod");
5039
5233
  if (!fileExists(manifestPath)) {
5040
5234
  return [];
5041
5235
  }
5042
5236
  let content;
5043
5237
  try {
5044
- content = (0, import_node_fs14.readFileSync)(manifestPath, "utf8");
5238
+ content = (0, import_node_fs16.readFileSync)(manifestPath, "utf8");
5045
5239
  } catch {
5046
5240
  return [];
5047
5241
  }
@@ -5098,7 +5292,7 @@ function rewriteSpec(site, spec) {
5098
5292
  writeFileEnsured(site.manifestPath, toJson(manifest));
5099
5293
  return true;
5100
5294
  }
5101
- const before = (0, import_node_fs14.readFileSync)(site.manifestPath, "utf8");
5295
+ const before = (0, import_node_fs16.readFileSync)(site.manifestPath, "utf8");
5102
5296
  const after = (() => {
5103
5297
  switch (site.ecosystem) {
5104
5298
  case "pip": {
@@ -5154,13 +5348,13 @@ function escapeForRegex(value) {
5154
5348
  function isWorkspaceProject(workspaceRoot, name) {
5155
5349
  const short = name.includes("/") ? name.split("/").at(-1) : name;
5156
5350
  return ["apps", "libs", "packages"].some(
5157
- (directory) => fileExists((0, import_node_path18.join)(workspaceRoot, directory, short ?? name, "package.json"))
5351
+ (directory) => fileExists((0, import_node_path20.join)(workspaceRoot, directory, short ?? name, "package.json"))
5158
5352
  );
5159
5353
  }
5160
5354
  function isAliasedInstall(workspaceRoot, name) {
5161
5355
  try {
5162
5356
  const installed = readJson(
5163
- (0, import_node_path18.join)(workspaceRoot, "node_modules", name, "package.json")
5357
+ (0, import_node_path20.join)(workspaceRoot, "node_modules", name, "package.json")
5164
5358
  );
5165
5359
  return installed.name !== void 0 && installed.name !== name;
5166
5360
  } catch {
@@ -5171,14 +5365,14 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
5171
5365
  if (ecosystem === "npm") {
5172
5366
  try {
5173
5367
  return readJson(
5174
- (0, import_node_path18.join)(workspaceRoot, "node_modules", name, "package.json")
5368
+ (0, import_node_path20.join)(workspaceRoot, "node_modules", name, "package.json")
5175
5369
  ).version;
5176
5370
  } catch {
5177
5371
  return void 0;
5178
5372
  }
5179
5373
  }
5180
5374
  if (ecosystem === "pub") {
5181
- const lockPath = (0, import_node_path18.join)(workspaceRoot, "pubspec.lock");
5375
+ const lockPath = (0, import_node_path20.join)(workspaceRoot, "pubspec.lock");
5182
5376
  if (!fileExists(lockPath)) {
5183
5377
  return void 0;
5184
5378
  }
@@ -5186,7 +5380,7 @@ function resolvedVersion(workspaceRoot, ecosystem, name) {
5186
5380
  const match = new RegExp(
5187
5381
  String.raw`^\s{2}${escapeForRegex(name)}:[^]*?^\s+version:\s*["']?([^"'\s]+)`,
5188
5382
  "m"
5189
- ).exec((0, import_node_fs14.readFileSync)(lockPath, "utf8"));
5383
+ ).exec((0, import_node_fs16.readFileSync)(lockPath, "utf8"));
5190
5384
  return match?.[1];
5191
5385
  } catch {
5192
5386
  return void 0;
@@ -5378,7 +5572,7 @@ function describe(finding) {
5378
5572
  return `${finding.name} \u2192 ${finding.target} (${finding.reason}); disagreeing: ${sites}`;
5379
5573
  }
5380
5574
  function runSync(workspaceRoot, options) {
5381
- if (!fileExists((0, import_node_path19.join)(workspaceRoot, "nx.json"))) {
5575
+ if (!fileExists((0, import_node_path21.join)(workspaceRoot, "nx.json"))) {
5382
5576
  throw new Error(
5383
5577
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci sync' from the workspace root.`
5384
5578
  );
@@ -5428,7 +5622,7 @@ function runSync(workspaceRoot, options) {
5428
5622
  }
5429
5623
 
5430
5624
  // src/dependency-management/update-dependencies.use-case.ts
5431
- var import_node_path20 = require("path");
5625
+ var import_node_path22 = require("path");
5432
5626
  var import_prompts2 = require("@inquirer/prompts");
5433
5627
 
5434
5628
  // src/dependency-management/registry.client.ts
@@ -5711,7 +5905,7 @@ function reinstall(workspaceRoot, ecosystems) {
5711
5905
  function hasPythonInstallScript(workspaceRoot) {
5712
5906
  try {
5713
5907
  const manifest = readJson(
5714
- (0, import_node_path20.join)(workspaceRoot, "package.json")
5908
+ (0, import_node_path22.join)(workspaceRoot, "package.json")
5715
5909
  );
5716
5910
  return manifest.scripts?.["python:install"] !== void 0;
5717
5911
  } catch {
@@ -5727,7 +5921,7 @@ function applyGoUpdates(workspaceRoot, entries) {
5727
5921
  }
5728
5922
  }
5729
5923
  async function runUp(workspaceRoot, options) {
5730
- if (!fileExists((0, import_node_path20.join)(workspaceRoot, "nx.json"))) {
5924
+ if (!fileExists((0, import_node_path22.join)(workspaceRoot, "nx.json"))) {
5731
5925
  throw new Error(`No nx.json found in ${workspaceRoot} \u2014 run 'mnci up' from the workspace root.`);
5732
5926
  }
5733
5927
  const ecosystems = resolveEcosystems(options.ecosystem);
@@ -5803,7 +5997,7 @@ var PROJECT_KINDS = [
5803
5997
  ];
5804
5998
  async function runAdd(kind, name, options) {
5805
5999
  const workspaceRoot = process.cwd();
5806
- if (!fileExists((0, import_node_path21.join)(workspaceRoot, "nx.json"))) {
6000
+ if (!fileExists((0, import_node_path23.join)(workspaceRoot, "nx.json"))) {
5807
6001
  throw new Error("No nx.json found here. Run `add` from the workspace root.");
5808
6002
  }
5809
6003
  const stack = readWorkspaceStack(workspaceRoot);
@@ -5812,8 +6006,12 @@ async function runAdd(kind, name, options) {
5812
6006
  message: "What kind of project?",
5813
6007
  choices: PROJECT_KINDS.map((value) => ({ name: value, value }))
5814
6008
  });
5815
- for (const [flag, requested] of [["--release", options.release], ["--cgo", options.cgo]]) {
5816
- if (resolvedKind !== "go-app" && requested === true) {
6009
+ for (const [flag, requested] of [
6010
+ ["--release", options.release === true],
6011
+ ["--cgo", options.cgo === true],
6012
+ ["--web", options.web !== void 0]
6013
+ ]) {
6014
+ if (resolvedKind !== "go-app" && requested) {
5817
6015
  throw new Error(`${flag} applies to go-app only, not ${resolvedKind}.`);
5818
6016
  }
5819
6017
  }
@@ -5859,8 +6057,8 @@ async function runAdd(kind, name, options) {
5859
6057
  ],
5860
6058
  workspaceRoot
5861
6059
  );
5862
- markPrivate((0, import_node_path21.join)(workspaceRoot, "libs", resolvedName, "package.json"));
5863
- renameScaffoldPlaceholder((0, import_node_path21.join)(workspaceRoot, "libs", resolvedName), resolvedName);
6060
+ markPrivate((0, import_node_path23.join)(workspaceRoot, "libs", resolvedName, "package.json"));
6061
+ renameScaffoldPlaceholder((0, import_node_path23.join)(workspaceRoot, "libs", resolvedName), resolvedName);
5864
6062
  removeGeneratedEslintConfig(workspaceRoot, `libs/${resolvedName}`);
5865
6063
  registerProjectCommands(workspaceRoot, resolvedName, { build: true });
5866
6064
  break;
@@ -5882,7 +6080,7 @@ async function runAdd(kind, name, options) {
5882
6080
  break;
5883
6081
  }
5884
6082
  case "go-app": {
5885
- addGoApp(workspaceRoot, resolvedName, { release: options.release, cgo: options.cgo });
6083
+ addGoApp(workspaceRoot, resolvedName, { release: options.release, cgo: options.cgo, web: options.web });
5886
6084
  break;
5887
6085
  }
5888
6086
  case "go-function-app": {
@@ -5952,7 +6150,7 @@ async function runAdd(kind, name, options) {
5952
6150
  }
5953
6151
  function readWorkspaceStack(workspaceRoot) {
5954
6152
  const nxJson = readJson(
5955
- (0, import_node_path21.join)(workspaceRoot, "nx.json")
6153
+ (0, import_node_path23.join)(workspaceRoot, "nx.json")
5956
6154
  );
5957
6155
  const stack = nxJson.mnci?.stack;
5958
6156
  return {
@@ -5962,15 +6160,15 @@ function readWorkspaceStack(workspaceRoot) {
5962
6160
 
5963
6161
  // src/workspace-diagnostics/check-invariants.use-case.ts
5964
6162
  var import_node_child_process = require("child_process");
5965
- var import_node_fs15 = require("fs");
5966
- var import_node_path22 = require("path");
6163
+ var import_node_fs17 = require("fs");
6164
+ var import_node_path24 = require("path");
5967
6165
  var SUPPORTED_ESLINT_MAJOR = ESLINT_VERSION.replace(/^\D*/, "").split(".", 1)[0];
5968
6166
  function toPosix2(path) {
5969
6167
  return path.replaceAll("\\", "/");
5970
6168
  }
5971
6169
  function checkEslintConfigs(workspaceRoot) {
5972
- const rootConfigs = (0, import_node_fs15.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
5973
- const projectConfigs = (0, import_node_fs15.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
6170
+ const rootConfigs = (0, import_node_fs17.globSync)("eslint.config.{js,mjs,cjs,ts,mts,cts}", { cwd: workspaceRoot });
6171
+ const projectConfigs = (0, import_node_fs17.globSync)("{apps,libs,packages}/*/eslint.config.{js,mjs,cjs,ts,mts,cts}", {
5974
6172
  cwd: workspaceRoot
5975
6173
  }).map((config) => toPosix2(config));
5976
6174
  return [
@@ -5990,10 +6188,10 @@ function checkEslintConfigs(workspaceRoot) {
5990
6188
  ];
5991
6189
  }
5992
6190
  function checkEslintEntryPointReachesTheRules(workspaceRoot) {
5993
- const rules = (0, import_node_path22.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
5994
- if (!(0, import_node_fs15.existsSync)(rules)) return [];
5995
- const entryPoint = (0, import_node_path22.join)(workspaceRoot, ESLINT_USER_FILENAME);
5996
- const source = (0, import_node_fs15.existsSync)(entryPoint) ? (0, import_node_fs15.readFileSync)(entryPoint, "utf8") : "";
6191
+ const rules = (0, import_node_path24.join)(workspaceRoot, ESLINT_MNCI_FILENAME);
6192
+ if (!(0, import_node_fs17.existsSync)(rules)) return [];
6193
+ const entryPoint = (0, import_node_path24.join)(workspaceRoot, ESLINT_USER_FILENAME);
6194
+ const source = (0, import_node_fs17.existsSync)(entryPoint) ? (0, import_node_fs17.readFileSync)(entryPoint, "utf8") : "";
5997
6195
  return [
5998
6196
  {
5999
6197
  check: `${ESLINT_USER_FILENAME} imports the mnci rules`,
@@ -6006,7 +6204,7 @@ function checkEslintEntryPointReachesTheRules(workspaceRoot) {
6006
6204
  function declaredDevDependencies(workspaceRoot) {
6007
6205
  try {
6008
6206
  const manifest = readJson(
6009
- (0, import_node_path22.join)(workspaceRoot, "package.json")
6207
+ (0, import_node_path24.join)(workspaceRoot, "package.json")
6010
6208
  );
6011
6209
  return manifest.devDependencies ?? {};
6012
6210
  } catch {
@@ -6014,7 +6212,7 @@ function declaredDevDependencies(workspaceRoot) {
6014
6212
  }
6015
6213
  }
6016
6214
  function checkNoRetiredFormatter(workspaceRoot) {
6017
- const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path22.join)(workspaceRoot, file)));
6215
+ const files = RETIRED_FORMATTER_FILES.filter((file) => fileExists((0, import_node_path24.join)(workspaceRoot, file)));
6018
6216
  const declared = ["prettier", "eslint-config-prettier", "oxlint", "oxfmt", "@mnci/oxlint-config"].filter((name) => declaredDevDependencies(workspaceRoot)[name] !== void 0);
6019
6217
  const stale = [...files, ...declared];
6020
6218
  if (stale.length === 0) {
@@ -6040,7 +6238,7 @@ function checkEslintPlugin(nxJson) {
6040
6238
  };
6041
6239
  }
6042
6240
  function checkResolvedEslint(workspaceRoot) {
6043
- const manifestPath = (0, import_node_path22.join)(workspaceRoot, "node_modules/eslint/package.json");
6241
+ const manifestPath = (0, import_node_path24.join)(workspaceRoot, "node_modules/eslint/package.json");
6044
6242
  if (!fileExists(manifestPath)) {
6045
6243
  return void 0;
6046
6244
  }
@@ -6058,11 +6256,11 @@ function checkResolvedEslint(workspaceRoot) {
6058
6256
  }
6059
6257
  }
6060
6258
  function checkNpmrc(workspaceRoot, registry, scope) {
6061
- const npmrcPath = (0, import_node_path22.join)(workspaceRoot, ".npmrc");
6259
+ const npmrcPath = (0, import_node_path24.join)(workspaceRoot, ".npmrc");
6062
6260
  if (!registry || !fileExists(npmrcPath)) {
6063
6261
  return void 0;
6064
6262
  }
6065
- const npmrc = (0, import_node_fs15.readFileSync)(npmrcPath, "utf8");
6263
+ const npmrc = (0, import_node_fs17.readFileSync)(npmrcPath, "utf8");
6066
6264
  if (registry.kind === "npm") {
6067
6265
  return {
6068
6266
  check: ".npmrc authenticates the public registry",
@@ -6079,11 +6277,11 @@ function checkNpmrc(workspaceRoot, registry, scope) {
6079
6277
  };
6080
6278
  }
6081
6279
  function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env) {
6082
- const npmrcPath = (0, import_node_path22.join)(workspaceRoot, ".npmrc");
6280
+ const npmrcPath = (0, import_node_path24.join)(workspaceRoot, ".npmrc");
6083
6281
  if (!fileExists(npmrcPath)) {
6084
6282
  return void 0;
6085
6283
  }
6086
- const npmrc = (0, import_node_fs15.readFileSync)(npmrcPath, "utf8");
6284
+ const npmrc = (0, import_node_fs17.readFileSync)(npmrcPath, "utf8");
6087
6285
  const credentials = npmrc.split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).filter((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
6088
6286
  const referenced = [
6089
6287
  ...new Set(
@@ -6107,13 +6305,13 @@ function checkNpmrcCredentialResolves(workspaceRoot, environment = process.env)
6107
6305
  };
6108
6306
  }
6109
6307
  function checkNpmAuthMatchesPipeline(workspaceRoot, registry) {
6110
- const npmrcPath = (0, import_node_path22.join)(workspaceRoot, ".npmrc");
6111
- const pipelinePath = (0, import_node_path22.join)(workspaceRoot, "azure-pipelines.yml");
6308
+ const npmrcPath = (0, import_node_path24.join)(workspaceRoot, ".npmrc");
6309
+ const pipelinePath = (0, import_node_path24.join)(workspaceRoot, "azure-pipelines.yml");
6112
6310
  if (registry?.kind !== "azure-artifacts" || !fileExists(npmrcPath) || !fileExists(pipelinePath)) {
6113
6311
  return void 0;
6114
6312
  }
6115
- const holdsCredentials = (0, import_node_fs15.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
6116
- const runsTask = (0, import_node_fs15.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
6313
+ const holdsCredentials = (0, import_node_fs17.readFileSync)(npmrcPath, "utf8").split("\n").filter((line) => !line.trimStart().startsWith(";") && !line.trimStart().startsWith("#")).some((line) => /(?:_authToken|_password|_auth)\s*=/u.test(line));
6314
+ const runsTask = (0, import_node_fs17.readFileSync)(pipelinePath, "utf8").includes("npmAuthenticate@0");
6117
6315
  if (!holdsCredentials && !runsTask) {
6118
6316
  return {
6119
6317
  check: "npm auth: .npmrc and azure-pipelines.yml agree",
@@ -6158,13 +6356,13 @@ function npmjsCredentialShape(credentials, environment) {
6158
6356
  }
6159
6357
  function checkVersionActions(workspaceRoot) {
6160
6358
  const candidates = [
6161
- ...(0, import_node_fs15.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
6162
- ...(0, import_node_fs15.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
6163
- ...(0, import_node_fs15.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
6359
+ ...(0, import_node_fs17.globSync)("packages/*/pubspec.yaml", { cwd: workspaceRoot }),
6360
+ ...(0, import_node_fs17.globSync)("packages/*/*.csproj", { cwd: workspaceRoot }),
6361
+ ...(0, import_node_fs17.globSync)("python-packages/*/pyproject.toml", { cwd: workspaceRoot })
6164
6362
  ].map((manifest) => toPosix2(manifest));
6165
6363
  return candidates.flatMap((manifest) => {
6166
6364
  const projectRoot = manifest.slice(0, manifest.lastIndexOf("/"));
6167
- const projectJsonPath = (0, import_node_path22.join)(workspaceRoot, projectRoot, "project.json");
6365
+ const projectJsonPath = (0, import_node_path24.join)(workspaceRoot, projectRoot, "project.json");
6168
6366
  let hasOverride = false;
6169
6367
  try {
6170
6368
  const projectJson = readJson(projectJsonPath);
@@ -6193,7 +6391,7 @@ function declaredTargets(workspaceRoot, projectRoot) {
6193
6391
  ]) {
6194
6392
  try {
6195
6393
  const targets = extract(
6196
- readJson((0, import_node_path22.join)(workspaceRoot, projectRoot, file))
6394
+ readJson((0, import_node_path24.join)(workspaceRoot, projectRoot, file))
6197
6395
  );
6198
6396
  if (targets && typeof targets === "object") {
6199
6397
  sources.push({
@@ -6209,8 +6407,8 @@ function declaredTargets(workspaceRoot, projectRoot) {
6209
6407
  function checkTargetFilesExist(workspaceRoot) {
6210
6408
  const projectRoots = new Set(
6211
6409
  [
6212
- ...(0, import_node_fs15.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
6213
- ...(0, import_node_fs15.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
6410
+ ...(0, import_node_fs17.globSync)("{apps,libs,packages}/*/project.json", { cwd: workspaceRoot }),
6411
+ ...(0, import_node_fs17.globSync)("{apps,libs,packages}/*/package.json", { cwd: workspaceRoot })
6214
6412
  ].map((manifest) => toPosix2(manifest).split("/").slice(0, 2).join("/"))
6215
6413
  );
6216
6414
  return [...projectRoots].flatMap(
@@ -6225,7 +6423,7 @@ function checkOneTargetsFiles(workspaceRoot, source, targetName, target) {
6225
6423
  return TARGET_FILE_OPTIONS.flatMap((option) => {
6226
6424
  const value = target?.options?.[option];
6227
6425
  const checkable = typeof value === "string" && !value.includes("{");
6228
- if (!checkable || fileExists((0, import_node_path22.join)(workspaceRoot, value))) {
6426
+ if (!checkable || fileExists((0, import_node_path24.join)(workspaceRoot, value))) {
6229
6427
  return [];
6230
6428
  }
6231
6429
  return [
@@ -6269,9 +6467,9 @@ function checkNativeApps(workspaceRoot) {
6269
6467
  { file: ".github/workflows/ci.yml", marker: "native (${{ matrix.os }})" },
6270
6468
  { file: "azure-pipelines.yml", marker: "- job: native" }
6271
6469
  ];
6272
- const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path22.join)(workspaceRoot, file))).map(({ file, marker }) => ({
6470
+ const findings = pipelines.filter(({ file }) => fileExists((0, import_node_path24.join)(workspaceRoot, file))).map(({ file, marker }) => ({
6273
6471
  check: `${file} builds the native apps on every OS`,
6274
- ok: (0, import_node_fs15.readFileSync)((0, import_node_path22.join)(workspaceRoot, file), "utf8").includes(marker),
6472
+ ok: (0, import_node_fs17.readFileSync)((0, import_node_path24.join)(workspaceRoot, file), "utf8").includes(marker),
6275
6473
  detail: `${file} has no native job: CI would verify a cgo app on the one agent that cannot build it`,
6276
6474
  remedy: "run `mnci upgrade`"
6277
6475
  }));
@@ -6284,7 +6482,7 @@ function checkNativeApps(workspaceRoot) {
6284
6482
  return findings;
6285
6483
  }
6286
6484
  function checkNoRootRuntimeDependencies(workspaceRoot) {
6287
- const manifestPath = (0, import_node_path22.join)(workspaceRoot, "package.json");
6485
+ const manifestPath = (0, import_node_path24.join)(workspaceRoot, "package.json");
6288
6486
  if (!fileExists(manifestPath)) {
6289
6487
  return void 0;
6290
6488
  }
@@ -6304,14 +6502,14 @@ function checkNoRootRuntimeDependencies(workspaceRoot) {
6304
6502
  };
6305
6503
  }
6306
6504
  function checkRollupSourceMaps(workspaceRoot) {
6307
- const configs = (0, import_node_fs15.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
6505
+ const configs = (0, import_node_fs17.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
6308
6506
  cwd: workspaceRoot
6309
6507
  }).map((config) => toPosix2(config));
6310
6508
  return configs.flatMap((relativePath) => {
6311
- const configPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
6509
+ const configPath = (0, import_node_path24.join)(workspaceRoot, relativePath);
6312
6510
  let config;
6313
6511
  try {
6314
- config = (0, import_node_fs15.readFileSync)(configPath, "utf8");
6512
+ config = (0, import_node_fs17.readFileSync)(configPath, "utf8");
6315
6513
  } catch {
6316
6514
  return [];
6317
6515
  }
@@ -6326,11 +6524,11 @@ function checkRollupSourceMaps(workspaceRoot) {
6326
6524
  });
6327
6525
  }
6328
6526
  function checkDeclarationSpecifiers(workspaceRoot) {
6329
- const configs = (0, import_node_fs15.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
6527
+ const configs = (0, import_node_fs17.globSync)(["packages/*/rollup.config.cjs", "libs/*/rollup.config.cjs"], {
6330
6528
  cwd: workspaceRoot
6331
6529
  }).map((config) => toPosix2(config));
6332
6530
  return configs.flatMap((relativePath) => {
6333
- const configPath = (0, import_node_path22.join)(workspaceRoot, relativePath);
6531
+ const configPath = (0, import_node_path24.join)(workspaceRoot, relativePath);
6334
6532
  if (!fileExists(configPath)) {
6335
6533
  return [];
6336
6534
  }
@@ -6364,7 +6562,7 @@ function checkDeclarationSpecifiers(workspaceRoot) {
6364
6562
  });
6365
6563
  }
6366
6564
  function collectFindings(workspaceRoot) {
6367
- const nxJsonPath = (0, import_node_path22.join)(workspaceRoot, "nx.json");
6565
+ const nxJsonPath = (0, import_node_path24.join)(workspaceRoot, "nx.json");
6368
6566
  if (!fileExists(nxJsonPath)) {
6369
6567
  throw new Error(
6370
6568
  `No nx.json found in ${workspaceRoot} \u2014 run 'mnci doctor' from the workspace root.`
@@ -6411,8 +6609,8 @@ function runDoctor(workspaceRoot) {
6411
6609
  }
6412
6610
 
6413
6611
  // src/workspace-creation/adopt-directory.use-case.ts
6414
- var import_node_fs16 = require("fs");
6415
- var import_node_path23 = require("path");
6612
+ var import_node_fs18 = require("fs");
6613
+ var import_node_path25 = require("path");
6416
6614
  var NEVER_COPIED = /* @__PURE__ */ new Set([".git", "node_modules"]);
6417
6615
  var AGENT_AND_CI_ENTRIES = [
6418
6616
  "AGENTS.md",
@@ -6443,13 +6641,13 @@ var PREFLIGHT_BLOCKERS = [
6443
6641
  "packages"
6444
6642
  ];
6445
6643
  function assertAdoptableDirectory(target) {
6446
- if (!(0, import_node_fs16.existsSync)(target)) {
6644
+ if (!(0, import_node_fs18.existsSync)(target)) {
6447
6645
  throw new Error(`--into '${target}' does not exist. Create or clone it first.`);
6448
6646
  }
6449
- if (!(0, import_node_fs16.statSync)(target).isDirectory()) {
6647
+ if (!(0, import_node_fs18.statSync)(target).isDirectory()) {
6450
6648
  throw new Error(`--into '${target}' is not a directory.`);
6451
6649
  }
6452
- const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs16.existsSync)((0, import_node_path23.join)(target, entry)));
6650
+ const blockers = PREFLIGHT_BLOCKERS.filter((entry) => (0, import_node_fs18.existsSync)((0, import_node_path25.join)(target, entry)));
6453
6651
  if (blockers.length > 0) {
6454
6652
  throw new Error(
6455
6653
  `--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.`
@@ -6457,15 +6655,15 @@ function assertAdoptableDirectory(target) {
6457
6655
  }
6458
6656
  }
6459
6657
  function mergeGitignore(generatedFile, targetFile) {
6460
- const existing = (0, import_node_fs16.readFileSync)(targetFile, "utf8");
6658
+ const existing = (0, import_node_fs18.readFileSync)(targetFile, "utf8");
6461
6659
  const present = new Set(existing.split("\n").map((line) => line.trim()));
6462
- const additions = (0, import_node_fs16.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
6660
+ const additions = (0, import_node_fs18.readFileSync)(generatedFile, "utf8").split("\n").map((line) => line.trimEnd()).filter((line) => {
6463
6661
  const trimmed = line.trim();
6464
6662
  return trimmed !== "" && !trimmed.startsWith("#") && !present.has(trimmed);
6465
6663
  });
6466
6664
  if (additions.length === 0) return false;
6467
6665
  const separator = existing.endsWith("\n") ? "" : "\n";
6468
- (0, import_node_fs16.writeFileSync)(
6666
+ (0, import_node_fs18.writeFileSync)(
6469
6667
  targetFile,
6470
6668
  `${existing}${separator}
6471
6669
  # Added by mnci (Nx workspace)
@@ -6475,9 +6673,9 @@ ${additions.join("\n")}
6475
6673
  return true;
6476
6674
  }
6477
6675
  function adoptGeneratedWorkspace(generatedRoot, target) {
6478
- const entries = (0, import_node_fs16.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
6676
+ const entries = (0, import_node_fs18.readdirSync)(generatedRoot).filter((entry) => !NEVER_COPIED.has(entry));
6479
6677
  const collisions = entries.filter(
6480
- (entry) => (0, import_node_fs16.existsSync)((0, import_node_path23.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
6678
+ (entry) => (0, import_node_fs18.existsSync)((0, import_node_path25.join)(target, entry)) && !EXISTING_WINS.has(entry) && entry !== ".gitignore"
6481
6679
  );
6482
6680
  if (collisions.length > 0) {
6483
6681
  throw new Error(
@@ -6486,28 +6684,28 @@ function adoptGeneratedWorkspace(generatedRoot, target) {
6486
6684
  }
6487
6685
  const result = { copied: [], kept: [], mergedGitignore: false };
6488
6686
  for (const entry of entries) {
6489
- const from = (0, import_node_path23.join)(generatedRoot, entry);
6490
- const to = (0, import_node_path23.join)(target, entry);
6491
- if (entry === ".gitignore" && (0, import_node_fs16.existsSync)(to)) {
6687
+ const from = (0, import_node_path25.join)(generatedRoot, entry);
6688
+ const to = (0, import_node_path25.join)(target, entry);
6689
+ if (entry === ".gitignore" && (0, import_node_fs18.existsSync)(to)) {
6492
6690
  result.mergedGitignore = mergeGitignore(from, to);
6493
6691
  result.kept.push(entry);
6494
6692
  continue;
6495
6693
  }
6496
- if ((0, import_node_fs16.existsSync)(to)) {
6694
+ if ((0, import_node_fs18.existsSync)(to)) {
6497
6695
  result.kept.push(entry);
6498
6696
  continue;
6499
6697
  }
6500
- (0, import_node_fs16.cpSync)(from, to, { recursive: true });
6698
+ (0, import_node_fs18.cpSync)(from, to, { recursive: true });
6501
6699
  result.copied.push(entry);
6502
6700
  }
6503
- (0, import_node_fs16.rmSync)(generatedRoot, { recursive: true, force: true });
6701
+ (0, import_node_fs18.rmSync)(generatedRoot, { recursive: true, force: true });
6504
6702
  return result;
6505
6703
  }
6506
6704
 
6507
6705
  // src/workspace-creation/create-workspace.use-case.ts
6508
- var import_node_fs17 = require("fs");
6706
+ var import_node_fs19 = require("fs");
6509
6707
  var import_node_os = require("os");
6510
- var import_node_path24 = require("path");
6708
+ var import_node_path26 = require("path");
6511
6709
  function nxCloudProviderValue(ci) {
6512
6710
  return ci === "azure" ? "azure" : "github";
6513
6711
  }
@@ -6543,9 +6741,9 @@ async function resolveRegistry(options) {
6543
6741
  return await promptRegistry();
6544
6742
  }
6545
6743
  async function runNew(name, options) {
6546
- const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path24.resolve)(process.cwd(), options.into);
6744
+ const adoptTarget = options.into === void 0 ? void 0 : (0, import_node_path26.resolve)(process.cwd(), options.into);
6547
6745
  if (adoptTarget !== void 0) assertAdoptableDirectory(adoptTarget);
6548
- const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path24.basename)(adoptTarget));
6746
+ const workspaceName = name ?? (adoptTarget === void 0 ? await promptText("Workspace name") : (0, import_node_path26.basename)(adoptTarget));
6549
6747
  assertValidProjectName(workspaceName, "Workspace name");
6550
6748
  const scope = options.scope ?? (options.yes ? `@${workspaceName}` : await promptText("npm scope for publishable packages", `@${workspaceName}`));
6551
6749
  const registry = await resolveRegistry(options);
@@ -6558,8 +6756,8 @@ async function runNew(name, options) {
6558
6756
  const npmAuth = resolveNpmAuth(options.npmAuth, registry, ci);
6559
6757
  const stack = await resolveStack(options);
6560
6758
  const nxCloud = options.nxCloud ?? (options.yes ? false : await promptNxCloud());
6561
- const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs17.mkdtempSync)((0, import_node_path24.join)((0, import_node_os.tmpdir)(), "mnci-new-"));
6562
- let workspaceRoot = (0, import_node_path24.join)(stagingParent, workspaceName);
6759
+ const stagingParent = adoptTarget === void 0 ? process.cwd() : (0, import_node_fs19.mkdtempSync)((0, import_node_path26.join)((0, import_node_os.tmpdir)(), "mnci-new-"));
6760
+ let workspaceRoot = (0, import_node_path26.join)(stagingParent, workspaceName);
6563
6761
  try {
6564
6762
  logger.step(`Creating Nx workspace '${workspaceName}' (preset: ts)`);
6565
6763
  runNpx(
@@ -6582,7 +6780,7 @@ async function runNew(name, options) {
6582
6780
  workspaceRoot = adoptTarget;
6583
6781
  }
6584
6782
  } finally {
6585
- if (adoptTarget !== void 0) (0, import_node_fs17.rmSync)(stagingParent, { recursive: true, force: true });
6783
+ if (adoptTarget !== void 0) (0, import_node_fs19.rmSync)(stagingParent, { recursive: true, force: true });
6586
6784
  }
6587
6785
  logger.step(
6588
6786
  "Applying MoNecromanCI overlay (VS Code workspace, release config, .npmrc, commitlint, pipeline, stack)"
@@ -6592,8 +6790,8 @@ async function runNew(name, options) {
6592
6790
  { workspaceName, scope, registry, agent, variableGroup, ci, stack, ...npmAuth && { npmAuth } },
6593
6791
  logger.detail
6594
6792
  );
6595
- (0, import_node_fs17.rmSync)((0, import_node_path24.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
6596
- (0, import_node_fs17.rmSync)((0, import_node_path24.join)(workspaceRoot, "package-lock.json"), { force: true });
6793
+ (0, import_node_fs19.rmSync)((0, import_node_path26.join)(workspaceRoot, "node_modules"), { recursive: true, force: true });
6794
+ (0, import_node_fs19.rmSync)((0, import_node_path26.join)(workspaceRoot, "package-lock.json"), { force: true });
6597
6795
  logger.step("Installing the toolchain (commitlint + husky + linting/formatting)");
6598
6796
  const installStatus = runShell(
6599
6797
  "npm",
@@ -6624,12 +6822,12 @@ async function runNew(name, options) {
6624
6822
  }
6625
6823
 
6626
6824
  // src/workspace-creation/interactive-wizard.use-case.ts
6627
- var import_node_path26 = require("path");
6825
+ var import_node_path28 = require("path");
6628
6826
  var import_prompts4 = require("@inquirer/prompts");
6629
6827
 
6630
6828
  // src/workspace-upgrade/upgrade-workspace.use-case.ts
6631
- var import_node_fs18 = require("fs");
6632
- var import_node_path25 = require("path");
6829
+ var import_node_fs20 = require("fs");
6830
+ var import_node_path27 = require("path");
6633
6831
  function resolveRegistry2(options, persisted) {
6634
6832
  if (options.registry === "azure-artifacts" || options.organization && options.artifactsFeed) {
6635
6833
  const persistedAzure = persisted?.kind === "azure-artifacts" ? persisted : void 0;
@@ -6658,7 +6856,7 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
6658
6856
  return persisted.workspaceName;
6659
6857
  }
6660
6858
  try {
6661
- const existing = (0, import_node_fs18.readdirSync)(workspaceRoot).find(
6859
+ const existing = (0, import_node_fs20.readdirSync)(workspaceRoot).find(
6662
6860
  (file) => file.endsWith(".code-workspace") && file !== "undefined.code-workspace"
6663
6861
  );
6664
6862
  if (existing) {
@@ -6666,11 +6864,11 @@ function resolveWorkspaceName(workspaceRoot, persisted) {
6666
6864
  }
6667
6865
  } catch {
6668
6866
  }
6669
- return (0, import_node_path25.basename)(workspaceRoot);
6867
+ return (0, import_node_path27.basename)(workspaceRoot);
6670
6868
  }
6671
6869
  function detectNpmAuth(workspaceRoot) {
6672
6870
  try {
6673
- return (0, import_node_fs18.readFileSync)((0, import_node_path25.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
6871
+ return (0, import_node_fs20.readFileSync)((0, import_node_path27.join)(workspaceRoot, "azure-pipelines.yml"), "utf8").includes("npmAuthenticate@0") ? "build-identity" : void 0;
6674
6872
  } catch {
6675
6873
  return void 0;
6676
6874
  }
@@ -6717,7 +6915,7 @@ function resolveOverlayOptions(workspaceRoot, options, persisted) {
6717
6915
  };
6718
6916
  }
6719
6917
  function runUpgrade(workspaceRoot, options) {
6720
- if (!fileExists((0, import_node_path25.join)(workspaceRoot, "nx.json"))) {
6918
+ if (!fileExists((0, import_node_path27.join)(workspaceRoot, "nx.json"))) {
6721
6919
  throw new Error(
6722
6920
  `No nx.json found in ${workspaceRoot} \u2014 this does not look like an Nx workspace. Run 'mnci upgrade' from the workspace root.`
6723
6921
  );
@@ -6782,7 +6980,7 @@ function runUpgrade(workspaceRoot, options) {
6782
6980
 
6783
6981
  // src/workspace-creation/interactive-wizard.use-case.ts
6784
6982
  async function runInteractive() {
6785
- const inWorkspace = fileExists((0, import_node_path26.join)(process.cwd(), "nx.json"));
6983
+ const inWorkspace = fileExists((0, import_node_path28.join)(process.cwd(), "nx.json"));
6786
6984
  const choiceNew = { name: "Create a new monorepo", value: "new" };
6787
6985
  const choiceAdd = { name: "Add a project to this workspace", value: "add" };
6788
6986
  const choiceUpgrade = {
@@ -6803,8 +7001,8 @@ async function runInteractive() {
6803
7001
  }
6804
7002
 
6805
7003
  // src/cli-version/check-for-update.use-case.ts
6806
- var import_node_fs19 = require("fs");
6807
- var import_node_path27 = require("path");
7004
+ var import_node_fs21 = require("fs");
7005
+ var import_node_path29 = require("path");
6808
7006
  var import_cross_spawn2 = __toESM(require("cross-spawn"));
6809
7007
  var PACKAGE_NAME = "@mnci/cli";
6810
7008
  var REGISTRY_TIMEOUT_MS = 2e3;
@@ -6860,8 +7058,8 @@ function releaseTriple(version) {
6860
7058
  }
6861
7059
  function readCliVersion(packageDirectory) {
6862
7060
  try {
6863
- const manifestPath = (0, import_node_path27.join)(packageDirectory, "..", "package.json");
6864
- const manifest = JSON.parse((0, import_node_fs19.readFileSync)(manifestPath, "utf8"));
7061
+ const manifestPath = (0, import_node_path29.join)(packageDirectory, "..", "package.json");
7062
+ const manifest = JSON.parse((0, import_node_fs21.readFileSync)(manifestPath, "utf8"));
6865
7063
  return manifest.version ?? "0.0.0";
6866
7064
  } catch {
6867
7065
  return "0.0.0";
@@ -6933,6 +7131,9 @@ function buildProgram(cliVersion) {
6933
7131
  ).option(
6934
7132
  "--cgo",
6935
7133
  "go-app only: the app needs a C toolchain (a tray icon, a native GUI, a cgo driver), so CI builds it on a runner of each OS instead of cross-compiling"
7134
+ ).option(
7135
+ "--web <react-app>",
7136
+ "go-app only: embed and serve this React app (apps/<react-app>, added first): built before the Go app, staged for go:embed, with a dev target that runs both"
6936
7137
  ).action(
6937
7138
  async (kind, name, options) => {
6938
7139
  await runAdd(kind, name, options);