nx 22.6.0-beta.8 → 22.6.0-beta.9

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.
Files changed (32) hide show
  1. package/.eslintrc.json +0 -2
  2. package/package.json +12 -11
  3. package/src/ai/set-up-ai-agents/set-up-ai-agents.d.ts.map +1 -1
  4. package/src/ai/set-up-ai-agents/set-up-ai-agents.js +133 -24
  5. package/src/command-line/show/command-object.d.ts +1 -0
  6. package/src/command-line/show/command-object.d.ts.map +1 -1
  7. package/src/command-line/show/target.d.ts.map +1 -1
  8. package/src/command-line/show/target.js +13 -10
  9. package/src/daemon/server/project-graph-incremental-recomputation.d.ts.map +1 -1
  10. package/src/daemon/server/project-graph-incremental-recomputation.js +13 -5
  11. package/src/native/native-bindings.js +331 -116
  12. package/src/native/nx.wasi.cjs +45 -57
  13. package/src/project-graph/nx-deps-cache.d.ts +10 -0
  14. package/src/project-graph/nx-deps-cache.d.ts.map +1 -1
  15. package/src/project-graph/nx-deps-cache.js +36 -0
  16. package/src/project-graph/project-graph.d.ts.map +1 -1
  17. package/src/project-graph/project-graph.js +30 -11
  18. package/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts +70 -0
  19. package/src/project-graph/utils/project-configuration/name-substitution-manager.d.ts.map +1 -0
  20. package/src/project-graph/utils/project-configuration/name-substitution-manager.js +427 -0
  21. package/src/project-graph/utils/project-configuration/source-maps.d.ts +70 -0
  22. package/src/project-graph/utils/project-configuration/source-maps.d.ts.map +1 -0
  23. package/src/project-graph/utils/project-configuration/source-maps.js +94 -0
  24. package/src/project-graph/utils/project-configuration-utils.d.ts +5 -3
  25. package/src/project-graph/utils/project-configuration-utils.d.ts.map +1 -1
  26. package/src/project-graph/utils/project-configuration-utils.js +56 -39
  27. package/src/utils/package-manager.d.ts.map +1 -1
  28. package/src/utils/package-manager.js +22 -1
  29. package/src/utils/split-target.d.ts +2 -1
  30. package/src/utils/split-target.d.ts.map +1 -1
  31. package/src/utils/split-target.js +11 -9
  32. package/src/native/nx.wasm32-wasi.wasm +0 -0
package/.eslintrc.json CHANGED
@@ -144,8 +144,6 @@
144
144
  "@nx/conformance",
145
145
  // Nx Docker plugin conditionally available dynamically at runtime
146
146
  "@nx/docker",
147
- // Only used in test-utils at the time of writing
148
- "@ltd/j-toml",
149
147
  // Used in WASI browser implementation (nx.wasi-browser.js)
150
148
  "@napi-rs/wasm-runtime"
151
149
  ]
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nx",
3
- "version": "22.6.0-beta.8",
3
+ "version": "22.6.0-beta.9",
4
4
  "private": false,
5
5
  "description": "The core Nx plugin contains the core functionality of Nx like the project graph, nx commands and task orchestration.",
6
6
  "repository": {
@@ -34,6 +34,7 @@
34
34
  },
35
35
  "homepage": "https://nx.dev",
36
36
  "dependencies": {
37
+ "@ltd/j-toml": "^1.38.0",
37
38
  "@napi-rs/wasm-runtime": "0.2.4",
38
39
  "@yarnpkg/lockfile": "^1.1.0",
39
40
  "@yarnpkg/parsers": "3.0.2",
@@ -84,16 +85,16 @@
84
85
  }
85
86
  },
86
87
  "optionalDependencies": {
87
- "@nx/nx-darwin-arm64": "22.6.0-beta.8",
88
- "@nx/nx-darwin-x64": "22.6.0-beta.8",
89
- "@nx/nx-freebsd-x64": "22.6.0-beta.8",
90
- "@nx/nx-linux-arm-gnueabihf": "22.6.0-beta.8",
91
- "@nx/nx-linux-arm64-gnu": "22.6.0-beta.8",
92
- "@nx/nx-linux-arm64-musl": "22.6.0-beta.8",
93
- "@nx/nx-linux-x64-gnu": "22.6.0-beta.8",
94
- "@nx/nx-linux-x64-musl": "22.6.0-beta.8",
95
- "@nx/nx-win32-arm64-msvc": "22.6.0-beta.8",
96
- "@nx/nx-win32-x64-msvc": "22.6.0-beta.8"
88
+ "@nx/nx-darwin-arm64": "22.6.0-beta.9",
89
+ "@nx/nx-darwin-x64": "22.6.0-beta.9",
90
+ "@nx/nx-freebsd-x64": "22.6.0-beta.9",
91
+ "@nx/nx-linux-arm-gnueabihf": "22.6.0-beta.9",
92
+ "@nx/nx-linux-arm64-gnu": "22.6.0-beta.9",
93
+ "@nx/nx-linux-arm64-musl": "22.6.0-beta.9",
94
+ "@nx/nx-linux-x64-gnu": "22.6.0-beta.9",
95
+ "@nx/nx-linux-x64-musl": "22.6.0-beta.9",
96
+ "@nx/nx-win32-arm64-msvc": "22.6.0-beta.9",
97
+ "@nx/nx-win32-x64-msvc": "22.6.0-beta.9"
97
98
  },
98
99
  "nx-migrations": {
99
100
  "migrations": "./migrations.json",
@@ -1 +1 @@
1
- {"version":3,"file":"set-up-ai-agents.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/ai/set-up-ai-agents/set-up-ai-agents.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAS7C,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAyB5B,OAAO,EACL,sCAAsC,EACtC,4BAA4B,EAC7B,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC,CAAC;AAmCF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,4BAA4B,EACrC,KAAK,UAAQ,GACZ,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAmC5D;AAaD,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,sCAAsC,GAC9C,OAAO,CAAC,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAuO7C;AAqJD,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"set-up-ai-agents.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/ai/set-up-ai-agents/set-up-ai-agents.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AAS7C,OAAO,EACL,qBAAqB,EACrB,oBAAoB,EACrB,MAAM,oBAAoB,CAAC;AAuB5B,OAAO,EACL,sCAAsC,EACtC,4BAA4B,EAC7B,MAAM,UAAU,CAAC;AAElB,MAAM,MAAM,mBAAmB,GAAG;IAChC,QAAQ,EAAE,oBAAoB,EAAE,CAAC;IACjC,MAAM,EAAE,qBAAqB,EAAE,CAAC;CACjC,CAAC;AAmCF,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,4BAA4B,EACrC,KAAK,UAAQ,GACZ,OAAO,CAAC,CAAC,KAAK,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,mBAAmB,CAAC,CAAC,CAmC5D;AAaD,wBAAsB,0BAA0B,CAC9C,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,sCAAsC,GAC9C,OAAO,CAAC,MAAM,OAAO,CAAC,mBAAmB,CAAC,CAAC,CA8O7C;AAuRD,eAAe,sBAAsB,CAAC"}
@@ -5,6 +5,7 @@ exports.setupAiAgentsGeneratorImpl = setupAiAgentsGeneratorImpl;
5
5
  const fs_1 = require("fs");
6
6
  const path_1 = require("path");
7
7
  const semver_1 = require("semver");
8
+ const j_toml_1 = require("@ltd/j-toml");
8
9
  const format_changed_files_with_prettier_if_available_1 = require("../../generators/internal-utils/format-changed-files-with-prettier-if-available");
9
10
  const generate_files_1 = require("../../generators/utils/generate-files");
10
11
  const json_1 = require("../../generators/utils/json");
@@ -16,7 +17,6 @@ const workspace_root_1 = require("../../utils/workspace-root");
16
17
  const constants_1 = require("../constants");
17
18
  const clone_ai_config_repo_1 = require("../clone-ai-config-repo");
18
19
  const utils_1 = require("../utils");
19
- const constants_2 = require("../constants");
20
20
  /**
21
21
  * Get the installed Nx version, with fallback to workspace package.json or default version.
22
22
  */
@@ -139,19 +139,25 @@ async function setupAiAgentsGeneratorImpl(tree, options) {
139
139
  }
140
140
  (0, json_1.updateJson)(tree, opencodeMcpJsonPath, (json) => opencodeMcpConfigUpdater(json, nxVersion));
141
141
  }
142
- if (hasAgent('codex')) {
143
- const codexTomlPath = (0, path_1.join)(options.directory, '.codex', 'config.toml');
144
- const tomlConfig = (0, constants_2.getNxMcpTomlConfig)(nxVersion);
145
- if (!tree.exists(codexTomlPath)) {
146
- tree.write(codexTomlPath, tomlConfig);
142
+ // Get the ai-config repo path once for all non-Claude agents that need it
143
+ const needsAiConfigRepo = hasAgent('codex') ||
144
+ hasAgent('opencode') ||
145
+ hasAgent('copilot') ||
146
+ hasAgent('cursor') ||
147
+ hasAgent('gemini');
148
+ let aiConfigRepoPath;
149
+ if (needsAiConfigRepo) {
150
+ try {
151
+ aiConfigRepoPath = (0, clone_ai_config_repo_1.getAiConfigRepoPath)();
147
152
  }
148
- else {
149
- const existing = tree.read(codexTomlPath, 'utf-8');
150
- if (!existing.includes(constants_2.nxMcpTomlHeader)) {
151
- tree.write(codexTomlPath, existing + '\n' + tomlConfig);
152
- }
153
+ catch {
154
+ // Network/clone failure individual consumers handle fallback
153
155
  }
154
156
  }
157
+ if (hasAgent('codex')) {
158
+ const codexTomlPath = (0, path_1.join)(options.directory, '.codex', 'config.toml');
159
+ writeCodexConfig(tree, codexTomlPath, nxVersion, aiConfigRepoPath);
160
+ }
155
161
  if (hasAgent('gemini')) {
156
162
  const geminiSettingsPath = (0, path_1.join)(options.directory, '.gemini', 'settings.json');
157
163
  if (!tree.exists(geminiSettingsPath)) {
@@ -173,17 +179,18 @@ async function setupAiAgentsGeneratorImpl(tree, options) {
173
179
  }
174
180
  }
175
181
  // Copy extensibility artifacts (commands, skills, subagents) for non-Claude agents
176
- if (hasAgent('opencode') ||
177
- hasAgent('copilot') ||
178
- hasAgent('cursor') ||
179
- hasAgent('codex') ||
180
- hasAgent('gemini')) {
181
- const repoPath = (0, clone_ai_config_repo_1.getAiConfigRepoPath)();
182
+ if (aiConfigRepoPath) {
183
+ const repoPath = aiConfigRepoPath;
182
184
  const agentDirs = [
183
185
  { agent: 'opencode', src: 'generated/.opencode', dest: '.opencode' },
184
186
  { agent: 'copilot', src: 'generated/.github', dest: '.github' },
185
187
  { agent: 'cursor', src: 'generated/.cursor', dest: '.cursor' },
186
188
  { agent: 'codex', src: 'generated/.agents', dest: '.agents' },
189
+ {
190
+ agent: 'codex',
191
+ src: 'generated/.codex/agents',
192
+ dest: '.codex/agents',
193
+ },
187
194
  { agent: 'gemini', src: 'generated/.gemini', dest: '.gemini' },
188
195
  ];
189
196
  for (const { agent, src, dest } of agentDirs) {
@@ -265,7 +272,7 @@ async function setupAiAgentsGeneratorImpl(tree, options) {
265
272
  function writeAgentRules(tree, path, writeNxCloudRules) {
266
273
  if (!tree.exists(path)) {
267
274
  // File doesn't exist - create with h1 header (standalone content)
268
- const expectedRules = (0, constants_2.getAgentRulesWrapped)({
275
+ const expectedRules = (0, constants_1.getAgentRulesWrapped)({
269
276
  writeNxCloudRules,
270
277
  useH1: true,
271
278
  });
@@ -273,21 +280,21 @@ function writeAgentRules(tree, path, writeNxCloudRules) {
273
280
  return;
274
281
  }
275
282
  const existing = tree.read(path, 'utf-8');
276
- const regex = constants_2.rulesRegex;
283
+ const regex = constants_1.rulesRegex;
277
284
  const existingNxConfiguration = existing.match(regex);
278
285
  if (existingNxConfiguration) {
279
286
  // Check the rest of the file (outside nx block) for an h1 header
280
287
  // to ensure only one h1 exists in the document
281
288
  const contentWithoutNxBlock = existing.replace(regex, '');
282
289
  const hasExternalH1 = /^# /m.test(contentWithoutNxBlock);
283
- const expectedRules = (0, constants_2.getAgentRulesWrapped)({
290
+ const expectedRules = (0, constants_1.getAgentRulesWrapped)({
284
291
  writeNxCloudRules,
285
292
  useH1: !hasExternalH1,
286
293
  });
287
294
  const contentOnly = (str) => str
288
- .replace(constants_2.nxRulesMarkerCommentStart, '')
289
- .replace(constants_2.nxRulesMarkerCommentEnd, '')
290
- .replace(constants_2.nxRulesMarkerCommentDescription, '')
295
+ .replace(constants_1.nxRulesMarkerCommentStart, '')
296
+ .replace(constants_1.nxRulesMarkerCommentEnd, '')
297
+ .replace(constants_1.nxRulesMarkerCommentDescription, '')
291
298
  .replace(/\s/g, '');
292
299
  // we don't want to make updates on whitespace-only changes
293
300
  if (contentOnly(existingNxConfiguration[0]) === contentOnly(expectedRules)) {
@@ -301,13 +308,115 @@ function writeAgentRules(tree, path, writeNxCloudRules) {
301
308
  // Appending to existing content - use h2 only if the file already has an h1 header
302
309
  // This prevents unnecessary changes when users add content without their own h1
303
310
  const hasExistingH1 = /^# /m.test(existing);
304
- const expectedRules = (0, constants_2.getAgentRulesWrapped)({
311
+ const expectedRules = (0, constants_1.getAgentRulesWrapped)({
305
312
  writeNxCloudRules,
306
313
  useH1: !hasExistingH1,
307
314
  });
308
315
  tree.write(path, existing + '\n\n' + expectedRules);
309
316
  }
310
317
  }
318
+ /**
319
+ * Write or merge the Codex config.toml.
320
+ *
321
+ * Reads the generated config.toml from the nx-ai-agents-config repo (which
322
+ * contains MCP servers, agent definitions, and feature flags) and deep-merges
323
+ * it into the user's existing config.toml using proper TOML parsing.
324
+ *
325
+ * Merge rules:
326
+ * - [mcp_servers."nx-mcp"] — upsert with version-adjusted args, preserving extra user args
327
+ * - [features] multi_agent — set to true unless user has explicitly set it to false
328
+ * - [agents.*] — upsert each agent definition
329
+ * - All other user config is preserved untouched
330
+ *
331
+ * Falls back to a minimal hardcoded MCP config if the generated file is unavailable.
332
+ */
333
+ function writeCodexConfig(tree, codexTomlPath, nxVersion, aiConfigRepoPath) {
334
+ let generated = null;
335
+ if (aiConfigRepoPath) {
336
+ const generatedConfigPath = (0, path_1.join)(aiConfigRepoPath, 'generated', '.codex', 'config.toml');
337
+ if ((0, fs_1.existsSync)(generatedConfigPath)) {
338
+ const generatedConfig = (0, fs_1.readFileSync)(generatedConfigPath, 'utf-8');
339
+ generated = j_toml_1.default.parse(generatedConfig);
340
+ }
341
+ }
342
+ if (!generated) {
343
+ // Fallback: use hardcoded MCP-only config (no agents/features)
344
+ const tomlConfig = (0, constants_1.getNxMcpTomlConfig)(nxVersion);
345
+ if (!tree.exists(codexTomlPath)) {
346
+ tree.write(codexTomlPath, tomlConfig);
347
+ }
348
+ else {
349
+ const existing = tree.read(codexTomlPath, 'utf-8');
350
+ if (!existing.includes(constants_1.nxMcpTomlHeader)) {
351
+ tree.write(codexTomlPath, existing + '\n' + tomlConfig);
352
+ }
353
+ }
354
+ return;
355
+ }
356
+ // Parse existing config (or start empty)
357
+ let config = {};
358
+ if (tree.exists(codexTomlPath)) {
359
+ try {
360
+ config = j_toml_1.default.parse(tree.read(codexTomlPath, 'utf-8'));
361
+ }
362
+ catch {
363
+ // If existing file can't be parsed, start fresh
364
+ config = {};
365
+ }
366
+ }
367
+ // ── Merge MCP servers ──
368
+ const majorVersion = (0, semver_1.major)(nxVersion);
369
+ const mcpArgs = majorVersion >= 22 ? ['nx', 'mcp'] : ['nx-mcp'];
370
+ // Preserve extra user args from existing config
371
+ const existingArgs = config.mcp_servers?.['nx-mcp']?.args ?? [];
372
+ const extraArgs = stripKnownMcpBaseArgs(existingArgs);
373
+ mcpArgs.push(...extraArgs);
374
+ config.mcp_servers ??= {};
375
+ config.mcp_servers['nx-mcp'] = {
376
+ command: 'npx',
377
+ args: mcpArgs,
378
+ };
379
+ // ── Merge features ──
380
+ // Only set multi_agent = true if user hasn't explicitly set it to false
381
+ const userSetMultiAgentFalse = config.features?.multi_agent === false;
382
+ if (!userSetMultiAgentFalse && generated.features) {
383
+ config.features ??= {};
384
+ Object.assign(config.features, generated.features);
385
+ }
386
+ // ── Merge agents ──
387
+ if (generated.agents) {
388
+ config.agents ??= {};
389
+ for (const [name, def] of Object.entries(generated.agents)) {
390
+ config.agents[name] = def;
391
+ }
392
+ }
393
+ // ── Serialize and write ──
394
+ const tomlString = j_toml_1.default.stringify(config, {
395
+ newlineAround: 'section',
396
+ });
397
+ tree.write(codexTomlPath, Array.isArray(tomlString) ? tomlString.join('\n') : tomlString);
398
+ }
399
+ /**
400
+ * Strip known MCP base command args (["nx", "mcp"] or ["nx-mcp"]) from an
401
+ * args array, returning only the extra user-added args.
402
+ */
403
+ function stripKnownMcpBaseArgs(args) {
404
+ const knownBasePatterns = [['nx', 'mcp'], ['nx-mcp']];
405
+ for (const pattern of knownBasePatterns) {
406
+ if (args.length < pattern.length)
407
+ continue;
408
+ const matches = pattern.every((baseArg, i) => {
409
+ if (baseArg === 'nx-mcp') {
410
+ return args[i] === 'nx-mcp' || args[i].startsWith('nx-mcp@');
411
+ }
412
+ return args[i] === baseArg;
413
+ });
414
+ if (matches) {
415
+ return args.slice(pattern.length);
416
+ }
417
+ }
418
+ return [];
419
+ }
311
420
  /**
312
421
  * Extract user-added extra args/flags from an existing MCP config args array
313
422
  * by stripping the known base command prefix.
@@ -30,6 +30,7 @@ export type ShowTargetBaseOptions = NxShowArgs & {
30
30
  };
31
31
  export type ShowTargetInputsOptions = NxShowArgs & {
32
32
  target?: string;
33
+ configuration?: string;
33
34
  check?: string[];
34
35
  verbose?: boolean;
35
36
  };
@@ -1 +1 @@
1
- {"version":3,"file":"command-object.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/command-line/show/command-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAY,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAQ1E,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,GAAG;IAC7D,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,UAAU,CA0CX,CAAC"}
1
+ {"version":3,"file":"command-object.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/command-line/show/command-object.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAY,MAAM,OAAO,CAAC;AAChD,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4BAA4B,CAAC;AAQ1E,MAAM,WAAW,UAAU;IACzB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,MAAM,mBAAmB,GAAG,UAAU,GAAG;IAC7C,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,GAAG,CAAC;IAClB,SAAS,CAAC,EAAE,GAAG,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,IAAI,CAAC,EAAE,uBAAuB,CAAC,MAAM,CAAC,CAAC;IACvC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,EAAE,CAAC;IACtB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG,UAAU,GAAG;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,OAAO,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG,UAAU,GAAG;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,UAAU,GAAG;IACjD,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG,qBAAqB,GAAG;IAC7D,KAAK,CAAC,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,eAAO,MAAM,gBAAgB,EAAE,aAAa,CAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACvB,UAAU,CA0CX,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/command-line/show/target.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAI1B,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAuDf;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAuDf"}
1
+ {"version":3,"file":"target.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/command-line/show/target.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EACV,qBAAqB,EACrB,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,kBAAkB,CAAC;AAI1B,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,qBAAqB,GAC1B,OAAO,CAAC,IAAI,CAAC,CA+Bf;AAED,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,uBAAuB,GAC5B,OAAO,CAAC,IAAI,CAAC,CAqDf;AAED,wBAAsB,wBAAwB,CAC5C,IAAI,EAAE,wBAAwB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAuDf"}
@@ -37,13 +37,14 @@ async function showTargetInputsHandler(args) {
37
37
  performance.measure('code-loading', 'init-local', 'code-loading:end');
38
38
  const graph = await (0, project_graph_1.createProjectGraphAsync)();
39
39
  const nxJson = (0, configuration_1.readNxJson)();
40
- const { projectName, targetName } = resolveTargetIdentifier(args, graph, nxJson);
40
+ const { projectName, targetName, configurationName } = resolveTargetIdentifier(args, graph, nxJson);
41
41
  const node = resolveProjectNode(projectName, graph);
42
42
  const targetConfig = node.data.targets?.[targetName];
43
43
  if (!targetConfig) {
44
44
  return reportTargetNotFound(projectName, targetName, node);
45
45
  }
46
- const hashInputs = await resolveInputFiles(projectName, targetName, undefined, graph, nxJson);
46
+ const configuration = configurationName ?? args.configuration;
47
+ const hashInputs = await resolveInputFiles(projectName, targetName, configuration, graph, nxJson);
47
48
  if (args.check !== undefined) {
48
49
  const checkItems = deduplicateFolderEntries(args.check);
49
50
  const results = checkItems.map((input) => resolveCheckFromInputs(input, projectName, targetName, hashInputs));
@@ -254,14 +255,16 @@ async function resolveInputFiles(projectName, targetName, configuration, graph,
254
255
  target: targetName,
255
256
  configuration,
256
257
  });
257
- const taskId = `${projectName}:${targetName}`;
258
- return (plan[taskId] ?? {
259
- files: [],
260
- runtime: [],
261
- environment: [],
262
- depOutputs: [],
263
- external: [],
264
- });
258
+ const targetConfig = graph.nodes[projectName]?.data?.targets?.[targetName];
259
+ const effectiveConfig = configuration ?? targetConfig?.defaultConfiguration;
260
+ const taskId = effectiveConfig
261
+ ? `${projectName}:${targetName}:${effectiveConfig}`
262
+ : `${projectName}:${targetName}`;
263
+ const result = plan[taskId];
264
+ if (!result) {
265
+ throw new Error(`Could not find hash plan for task "${taskId}". Available tasks: ${Object.keys(plan).join(', ')}`);
266
+ }
267
+ return result;
265
268
  }
266
269
  function resolveCheckFromInputs(rawValue, projectName, targetName, inputs) {
267
270
  // Check non-file categories first (exact match on raw value)
@@ -1 +1 @@
1
- {"version":3,"file":"project-graph-incremental-recomputation.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EAEb,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EACL,YAAY,EAIb,MAAM,mCAAmC,CAAC;AAe3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAEL,uBAAuB,EACxB,MAAM,uDAAuD,CAAC;AAS/D,UAAU,sBAAsB;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,iBAAiB,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACrC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC3C,cAAc,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAClD;AAGD,eAAO,IAAI,gBAAgB,EACvB;IACE,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,cAAc,EAAE,yBAAyB,CAAC;CAC3C,GACD,SAAS,CAAC;AACd,eAAO,IAAI,0BAA0B,EAAE,YAAY,GAAG,SAAS,CAAC;AAChE,eAAO,IAAI,mBAAmB,EAAE,YAAY,GAAG,SAAS,CAAC;AAoBzD,wBAAsB,sCAAsC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAgF9F;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,QAiDvB;AAED,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,CACR,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,uBAAuB,EACnC,KAAK,EAAE,KAAK,GAAG,IAAI,KAChB,IAAI,QAGV"}
1
+ {"version":3,"file":"project-graph-incremental-recomputation.d.ts","sourceRoot":"","sources":["../../../../../../packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,OAAO,EACP,YAAY,EAEb,MAAM,4BAA4B,CAAC;AAKpC,OAAO,EACL,YAAY,EAKb,MAAM,mCAAmC,CAAC;AAe3C,OAAO,EAAE,yBAAyB,EAAE,MAAM,cAAc,CAAC;AACzD,OAAO,EAEL,uBAAuB,EACxB,MAAM,uDAAuD,CAAC;AAS/D,UAAU,sBAAsB;IAC9B,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IACpB,YAAY,EAAE,YAAY,GAAG,IAAI,CAAC;IAClC,mBAAmB,EAAE,YAAY,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,OAAO,GAAG,IAAI,CAAC;IACxB,iBAAiB,EAAE,QAAQ,EAAE,GAAG,IAAI,CAAC;IACrC,sBAAsB,EAAE,MAAM,GAAG,IAAI,CAAC;IACtC,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAC;IACpC,UAAU,EAAE,uBAAuB,GAAG,IAAI,CAAC;IAC3C,cAAc,EAAE,yBAAyB,GAAG,IAAI,CAAC;CAClD;AAGD,eAAO,IAAI,gBAAgB,EACvB;IACE,OAAO,EAAE,OAAO,CAAC;IACjB,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,cAAc,EAAE,yBAAyB,CAAC;CAC3C,GACD,SAAS,CAAC;AACd,eAAO,IAAI,0BAA0B,EAAE,YAAY,GAAG,SAAS,CAAC;AAChE,eAAO,IAAI,mBAAmB,EAAE,YAAY,GAAG,SAAS,CAAC;AAoBzD,wBAAsB,sCAAsC,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAyF9F;AAED,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,EACtB,YAAY,EAAE,MAAM,EAAE,QAiDvB;AAED,wBAAgB,yCAAyC,CACvD,QAAQ,EAAE,CACR,YAAY,EAAE,YAAY,EAC1B,UAAU,EAAE,uBAAuB,EACnC,KAAK,EAAE,KAAK,GAAG,IAAI,KAChB,IAAI,QAGV"}
@@ -45,6 +45,7 @@ async function getCachedSerializedProjectGraphPromise() {
45
45
  waitPeriod = 100;
46
46
  await resetInternalStateIfNxDepsMissing();
47
47
  const plugins = await (0, get_plugins_1.getPlugins)();
48
+ const previousPromise = cachedSerializedProjectGraphPromise;
48
49
  if (collectedUpdatedFiles.size == 0 && collectedDeletedFiles.size == 0) {
49
50
  if (!cachedSerializedProjectGraphPromise) {
50
51
  cachedSerializedProjectGraphPromise =
@@ -60,6 +61,7 @@ async function getCachedSerializedProjectGraphPromise() {
60
61
  cachedSerializedProjectGraphPromise =
61
62
  processFilesAndCreateAndSerializeProjectGraph(plugins);
62
63
  }
64
+ const graphWasRecomputed = cachedSerializedProjectGraphPromise !== previousPromise;
63
65
  const result = await cachedSerializedProjectGraphPromise;
64
66
  if (wasScheduled) {
65
67
  notifyProjectGraphRecomputationListeners(result.projectGraph, result.sourceMaps, result.error);
@@ -69,14 +71,20 @@ async function getCachedSerializedProjectGraphPromise() {
69
71
  ? result.error.errors
70
72
  : [result.error]
71
73
  : [];
72
- // Always write the daemon's current graph to disk to ensure disk cache
73
- // stays in sync with the daemon's in-memory cache. This prevents issues
74
- // where a non-daemon process writes a stale/errored cache that never
75
- // gets overwritten by the daemon's valid graph.
74
+ // Write the daemon's current graph to disk to ensure disk cache stays
75
+ // in sync with the daemon's in-memory cache. This prevents issues where
76
+ // a non-daemon process writes a stale/errored cache that never gets
77
+ // overwritten by the daemon's valid graph.
78
+ //
79
+ // When the graph was just recomputed, always write so the new graph is
80
+ // persisted. When serving the same graph from memory, use
81
+ // writeCacheIfStale to skip the write unless an external process has
82
+ // modified the file since this process last wrote it.
76
83
  if (result.projectGraph &&
77
84
  result.projectFileMapCache &&
78
85
  result.sourceMaps) {
79
- (0, nx_deps_cache_1.writeCache)(result.projectFileMapCache, result.projectGraph, result.sourceMaps, errors);
86
+ const writeFn = graphWasRecomputed ? nx_deps_cache_1.writeCache : nx_deps_cache_1.writeCacheIfStale;
87
+ writeFn(result.projectFileMapCache, result.projectGraph, result.sourceMaps, errors);
80
88
  }
81
89
  return result;
82
90
  }