## Current Behavior
Running `nx migrate latest` updates all `@nx/*` packages except
`@nx/angular-rspack` and `@nx/angular-rspack-compiler`.
## Expected Behavior
`nx migrate latest` updates `@nx/angular-rspack` and
`@nx/angular-rspack-compiler` along with all other `@nx/*` packages.
## Related Issue(s)
Fixes#32772
## Current Behavior
The `getOutputs()` function in the `@nx/js/typescript` plugin derives
`.tsbuildinfo` filenames from `config.basenameNoExt` (the outer
`ConfigContext`, which always corresponds to `tsconfig.json`) instead of
the currently iterated internal project reference. This causes all
internal references to produce `dist/tsconfig.tsbuildinfo` as the output
path instead of the correct filenames like
`dist/tsconfig.lib.tsbuildinfo` and `dist/tsconfig.spec.tsbuildinfo`.
This leads to:
- Cache misses because Nx looks for `dist/tsconfig.tsbuildinfo` which
doesn't exist
- Missing actual `.tsbuildinfo` files from cache outputs
- Potential race conditions in parallel `tsc --build` invocations
## Expected Behavior
The `.tsbuildinfo` filename should be derived from each individual
tsconfig's file path. For a project with:
- `tsconfig.lib.json` → `dist/tsconfig.lib.tsbuildinfo`
- `tsconfig.spec.json` → `dist/tsconfig.spec.tsbuildinfo`
- `cypress/tsconfig.json` → `cypress/dist/tsconfig.tsbuildinfo`
The fix changes the loop in `getOutputs()` to iterate over entries (path
+ data pairs) so the basename can be correctly derived from each
tsconfig's file path. Also fixes the `outFile` and no-outDir branches
which had similar issues using the outer config parameter instead of the
loop variable.
## Related Issue(s)
Fixes#34737
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: vsavkin <vsavkin@users.noreply.github.com>
Rewrite README to reflect Nx's current capabilities: zero-config caching,
polyglot plugin system, CI distribution, AI-native tooling, and self-healing CI.
Remove stale badges (Gitter, Semantic Release). Point courses banner to nx.dev/courses.
## Current Behavior
When running `@nx/vitest:configuration` on an Angular project, the
generator always generates `import
'@analogjs/vitest-angular/setup-zone'` regardless of whether the app is
zoneless. Additionally, the setup file generation logic for Angular 21+
(which uses `setupTestBed()`) only exists in
`packages/angular/src/generators/utils/add-vitest.ts`
(`createAnalogSetupFile`), making the vitest generator not
self-contained.
## Expected Behavior
The vitest configuration generator should:
- Auto-detect whether an Angular project is zoneless (by checking
polyfills for apps, or zone.js dependency for libraries)
- Generate `setup-snapshots` instead of `setup-zone` for zoneless
projects
- Handle Angular 21+ `setupTestBed()` setup directly, without requiring
a separate function in the angular package
- Accept an explicit `zoneless` option to override auto-detection
## Related Issue(s)
Fixes#33983
## Current Behavior
The `resolveId` hook in `nxViteTsPaths` processes all import paths,
including Vite root-relative paths (e.g. `/src/test-setup.ts`). In Vite,
`/foo` means "relative to project root," but `nxViteTsPaths` resolves it
via tsconfig's `baseUrl` (workspace root), producing wrong paths.
In an Angular standalone workspace with Vitest + Analog, generating a
library and running `nx test test-lib` fails with `Error: Need to call
TestBed.initTestEnvironment() first` because the library's
`src/test-setup.ts` resolves to the root app's file instead. The Analog
Angular compiler never compiled that file, so the transform returns
empty content and `setupTestBed()` never runs.
## Expected Behavior
`nxViteTsPaths` should skip `/`-prefixed paths and let Vite's built-in
resolver handle them. These are filesystem paths (absolute or
root-relative), not TypeScript import specifiers. Library tests should
work correctly with their own `test-setup.ts`.
## Related Issue(s)
Fixes#34300
## Current Behavior
The TypeScript plugin's typecheck target inference was tied to
`tsconfig.json`, so users could not configure a different tsconfig file
name for typecheck inference.
## Expected Behavior
The plugin supports configuring `typecheck.configName`, which defaults
to `tsconfig.json`.
## Current Behavior
Running Nx Cloud commands (login, logout, polygraph, etc.) from outside
an Nx workspace fails with 'The current directory is not part of an Nx
workspace' because handleNoWorkspace exits before reaching the cloud
command handler. Additionally, polygraph was not in the isNxCloudCommand
list.
## Expected Behavior
Nx Cloud commands work regardless of whether you are inside an Nx
workspace, since they only delegate to the cloud client.
## Related Issue(s)
N/A
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Current Behavior
Plugin cache writes (`writeJsonFile`, `writeFileSync`) across the
codebase have inconsistent error handling:
- Some throw on failure, aborting project graph calculation entirely
- Some silently swallow errors, leaving corrupted cache files on disk
- No mechanism exists to recover from oversized or corrupted caches
- `nx-deps-cache.ts` retries 5 times then throws, crashing the graph
## Expected Behavior
- Plugin cache write failures **never** abort graph calculation — they
warn and continue
- A centralized `safeWritePluginCache` utility handles all hash-map
plugin caches with a 3-step strategy:
1. Attempt full write
2. On failure: evict oldest 50% of entries (LRU) and retry
3. On second failure: wipe cache file, log warning, return without
throwing
- `PluginCache<T>` class wraps cache data with a Proxy that
transparently tracks access order, enabling true LRU
eviction (not just insertion order)
- Access order is stored as a simple `string[]` array — front is oldest,
back is most recent
- Backward-compatible with 3 on-disk formats: legacy plain `Record`,
timestamp-based `{ entries, accessedAt }`, and
current `{ entries, accessOrder }`
- All plugin cache consumers migrated: package-json, js/lockfile,
dotnet, cypress, playwright, gradle, maven
- `nx-deps-cache.ts` changed from throw-after-retries to warn + cleanup
- New utilities exported via `@nx/devkit` internals for plugin authors
## Related Issue(s)
Fixes NXC-3833"
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
## Current Behavior
Several security-related issues reported:
1. **copy-webpack-plugin** (#34632): `@nx/webpack` and `@nx/next` pin
`copy-webpack-plugin@^10.2.4` which transitively depends on
`serialize-javascript@^6.0.1` (vulnerable) and `fast-glob` (supply-chain
risk).
2. **koa** (#34621): `@nx/module-federation` transitively pulls
`koa@3.0.3` via `@module-federation/dts-plugin`, which is vulnerable to
CVE-2026-27959 (Host Header Injection, fixed in koa 3.1.2).
3. **css-minimizer-webpack-plugin**: `@nx/webpack` pins `^5.0.0` which
also depends on vulnerable `serialize-javascript@^6.0.1`.
4. **@module-federation/enhanced**: Versions `<2.1.0` transitively
install vulnerable `koa` via `dts-plugin`.
5. **Next.js**: Versions `16.0.x` are vulnerable to GHSA-9g9p-9gw9-jx7f
(Image Optimizer DoS) and GHSA-5f7q-jpqc-wp7h (PPR Resume memory
consumption).
6. **minimatch** (#34701): User reports minimatch vulnerability, but the
Nx pnpm catalog already pins the patched version `10.2.4`. No code
change needed — users should delete their lockfile and reinstall.
## Expected Behavior
1. **copy-webpack-plugin** bumped to `^14.0.0` which uses
`serialize-javascript@^7.0.3` (patched). Added `noErrorOnMissing: true`
to all 3 copy-webpack-plugin usage sites to handle the v14 breaking
change where missing glob patterns now throw errors by default.
2. **css-minimizer-webpack-plugin** bumped to `^8.0.0` which uses
`serialize-javascript@^7.0.3` (patched).
3. **koa** bumped to `^3.1.2` in `@nx/node` versions.ts.
`@module-federation/dts-plugin@2.1.0` completely removes koa dependency.
4. **@module-federation/enhanced**, **runtime**, **sdk** bumped to
`^2.1.0` across all packages (`@nx/module-federation`, `@nx/react`,
`@nx/angular`, `@nx/rspack`). Added `noErrorOnMissing` fix for
`@module-federation/enhanced` 2.x `runtime-library-control.plugin.ts`
compatibility.
5. **Next.js** bumped to `~16.1.6` and `eslint-config-next` to
`^16.1.6`.
6. **minimatch** — no change needed, already resolved.
### Migrations added (22.6.0-beta.10)
- `@nx/module-federation`: Bump MF packages to `^2.1.0`
- `@nx/react`: Bump `@module-federation/enhanced` to `^2.1.0`
- `@nx/angular`: Bump `@module-federation/enhanced` to `^2.1.0`
- `@nx/node`: Bump `koa` to `^3.1.2`
- `@nx/next`: Bump `next` to `~16.1.6`
### Skipped
- **esbuild** (`<=0.24.2`, moderate severity, dev server only): Fix
requires breaking change jump from `^0.19.2` to `0.25+`. Will address
separately.
## Testing
Created a fresh Nx workspace with all affected plugins to verify `npm
audit` is clean after changes:
- `@nx/next` (nextapp)
- `@nx/webpack` (webpackapp)
- `@nx/rspack` (shell, remote1, remote2 via Module Federation)
- `@nx/module-federation` (shell + remotes with MF config)
- `@nx/react` (MF host/remotes)
- `@nx/node` + koa (api)
```
├── apps
│ ├── api # @nx/node (koa)
│ ├── nextapp # @nx/next
│ ├── remote1 # @nx/react + rspack + MF
│ ├── remote2 # @nx/react + rspack + MF
│ ├── shell # @nx/react + rspack + MF (host)
│ └── webpackapp # @nx/webpack
```
Post-change audit result — only remaining issue is esbuild (moderate,
skipped intentionally):
```
# npm audit report
esbuild <=0.24.2
Severity: moderate
esbuild enables any website to send any requests to the development server
and read the response - https://github.com/advisories/GHSA-67mh-4wv8-2f99
fix available via `npm audit fix --force`
Will install esbuild@0.27.3, which is a breaking change
1 moderate severity vulnerability
```
## Related Issue(s)
Fixes#34632Fixes#34621Fixes#34701
This addresses feedback on PR #34726 - .netlify directories are build
artifacts and should be in .gitignore rather than .nxignore. This also
generalizes the pattern from `astro-docs/.netlify` to `.netlify` to
cover the root-level `.netlify/static/documentation` directory that was
causing duplicate project detection.
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
This PR surfaces install errors instead of silently failing without
anything useful printed. It also records `needs_input` in the AX flow as
`cancelled` so we account for cases where AI agents exit without
recording either success, complete, or cancelled.
BEFORE:
<img width="1288" height="381" alt="image"
src="https://github.com/user-attachments/assets/44fe9642-764e-452b-90be-f30c4a230be5"
/>
AFTER:
<img width="1279" height="850" alt="Screenshot 2026-03-05 at 12 30
25 PM"
src="https://github.com/user-attachments/assets/24c96584-2790-4dcb-8404-7e221c50876c"
/>
## Notes
1. **Remove `--silent` from all PM install commands** — since
`execAndWait` uses `exec()` (captures output in memory, never shown to
terminal), `--silent` just suppressed error info for no benefit
2. **Increase `maxBuffer`** from default 1MB to 10MB to prevent process
being killed when PMs emit verbose output
3. **Fallback error message** when both stderr and stdout are empty —
includes exit code and log file path
4. **Structured sandbox error** with exit code, log file, and actionable
hint
5. **Record telemetry stat** for AI agent `needs_input` flow (was
previously missing)
6. **Migrate from deprecated `CreateNxWorkspaceError`** to `CnwError` in
`execAndWait`
## Related Issue(s)
Fixes NXC-4035
## Current Behavior
[The courses
page](https://deploy-preview-34669--nx-dev.netlify.app/courses) has a
hero section with title and subtitle but no mention of the YouTube
channel for one-off educational videos.
## Expected Behavior
A subtle callout link with a YouTube icon appears below the hero
subtitle, directing users to the Nx YouTube channel for one-off
educational videos.
## Related Issue(s)
N/A
## Current Behavior
No blog post covering the AX principles behind recent Nx CLI
improvements.
## Expected Behavior
New draft blog post (`docs/blog/2026-03-05-making-nx-agent-ready.md`)
covering:
- Why agentic experience (AX) matters for developer tools
- AX principles: context management, structured feedback, idempotency,
informative output
- The open question of human vs agent experience divergence
- A forward look at `nx connect` going agentic
The post is set to `draft: true` and scheduled for Thursday March 5th.
## Related Issue(s)
N/A — new content
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Juri <juri.strumpflohner@gmail.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: MaxKless <MaxKless@users.noreply.github.com>
## Current Behavior
When Claude Code creates worktrees under `.claude/worktrees/`, Nx picks
them up as workspace projects. This causes duplicate project errors that
break the project graph.
## Expected Behavior
`.claude/worktrees` is gitignored so worktree copies of the repo don't
interfere with Nx's project detection.
## Current Behavior
After the napi v2→v3 migration, running tasks with TUI enabled while Nx
Console is connected causes a panic: `there is no reactor running, must
be called from the context of a Tokio 1.x runtime`. This happens because
`end_command` is a sync NAPI callback that calls `end_running_tasks()`
which uses `tokio::spawn`, but napi v3 no longer wraps sync callbacks
with Tokio runtime context by default.
## Expected Behavior
Tasks complete without panic when Nx Console is connected and TUI is
enabled.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Bump Nx version to 22.6.0-beta.8
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
On Windows, the `@nx/js` TypeScript plugin fails during project graph
creation with a path mismatch assertion error. The plugin uses
`path.join()` and `path.relative()` from Node's `path` module, which
produce backslash-separated paths on Windows. These are passed to
TypeScript's `readConfigFile` API, which has an internal inconsistency:
its parser normalizes paths to forward slashes for diagnostics but
retains the original (backslash) path on the source file, causing an
assertion failure when parse diagnostics are present.
Additionally, `posix.normalize()` was incorrectly relied upon to convert
backslashes to forward slashes — it only normalizes paths already in
POSIX format.
## Expected Behavior
The TypeScript plugin normalizes paths to POSIX format (forward slashes)
for TypeScript API compatibility and cache key consistency, working
correctly on both Windows and Unix systems.
## Related Issue(s)
Fixes#31232
## Current Behavior
When creating a new Angular standalone project with Vitest
(`create-nx-workspace` → Angular → Standalone), running tests fails
with:
```
✘ [ERROR] TS2304: Cannot find name 'Disposable'. [plugin angular-compiler]
node_modules/@vitest/spy/dist/index.d.ts:158:80:
158 │ ...tends Procedure | Constructable = Procedure> extends Disposable {
```
For standalone (root) projects, `getRootTsConfigFileName` returns
`tsconfig.json` — the same file as the project tsconfig.
`getNeededCompilerOptionOverrides` compares the file against itself,
sees `skipLibCheck: true` already matches, and strips it. The result:
`skipLibCheck` disappears from the final `tsconfig.json`.
## Expected Behavior
Standalone Angular projects should have `skipLibCheck: true` in their
`tsconfig.json` (matching what Angular CLI generates), preventing type
errors from third-party `.d.ts` files like `@vitest/spy`.
## Related Issue(s)
Fixes#34164
## Current Behavior
When using `generatePackageJson: true`, Nx generates a pruned
`pnpm-lock.yaml` that includes the `catalogs:` section from the root
lockfile. Since the dist folder doesn't include `pnpm-workspace.yaml`,
pnpm 10.24.0+ throws `ERR_PNPM_LOCKFILE_CONFIG_MISMATCH` during `pnpm
install --frozen-lockfile`.
## Expected Behavior
The pruned lockfile strips the `catalogs` section since the dist folder
has no `pnpm-workspace.yaml` to define them.
## Related Issue(s)
Fixes#34337
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
When `NX_PREFIX_OUTPUT=true` (e.g. `--output-style=stream`),
`nx:run-commands` tasks are forced out of the fast direct execution path
and into a slower forked process, because the direct path had no
mechanism to prefix output with project names.
## Expected Behavior
`nx:run-commands` tasks stay on the direct execution path even when
output prefixing is needed. The PTY's `quiet` mode suppresses direct
stdout writes, and the orchestrator intercepts output via `onOutput`
callbacks to prefix each line with the colored project name before
writing to stdout.
### Changes
- Allow `nx:run-commands` to use the direct execution path regardless of
prefix output setting
- When prefixing is enabled, suppress direct stream output and intercept
it via `onOutput` to add colored project-name prefixes
- Extract a shared `writePrefixedLines` utility used by both the direct
path and the existing `addPrefixTransformer` stream — eliminates
duplicated split/filter/prefix logic
- Use `os.EOL` instead of manual platform newline detection
- Hoist formatted prefix string outside the per-line callback for
efficiency
- Simplify boolean expressions (`streamOutput && !shouldPrefix` instead
of ternary, remove redundant guard)
## Related Issue(s)
N/A — performance improvement for streaming output mode.
## Current Behavior
Requests to `/.netlify/images?url=...` are intercepted by the Framer
proxy edge function and forwarded to Framer, returning broken images on
docs pages (e.g. sandboxing page).
## Expected Behavior
`/.netlify/*` requests pass through to Next.js, which rewrites them to
the astro-docs site where the actual images are hosted.
## Related Issue(s)
Fixes DOC-436
This PR adds a new feature page for sandboxing.
- What task sandboxing is (hermetic task execution with IO tracing)
- Why hermeticity matters for caching correctness, with concrete Vite
examples
- How to investigate sandbox violations in the Nx Cloud UI (with
annotated screenshots)
- How to inspect declared inputs/outputs with `nx show target` and `nx
show project`
- How to enable sandboxing (`NX_CLOUD_IO_TRACING_DIRECTORY`) and
configure path exclusions
The page is listed under Orchestration & CI in the sidebar.
Preview:
https://deploy-preview-34686--nx-docs.netlify.app/docs/features/ci-features/sandboxing
<img width="396" height="658" alt="image"
src="https://github.com/user-attachments/assets/96dc802a-eb1a-4b4a-9df4-bde846ed2775"
/>
## Related Issue(s)
Closes DOC-429
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
The sandboxing config only excludes reads for `node_modules`, `.nx`,
`.git`, and `package.json` paths. No write exclusions are configured,
and `pnpm-workspace.yaml` is not excluded from reads.
## Expected Behavior
- The `nx/**/*` directory is excluded from write sandboxing, allowing
write operations to the nx directory during CI workflows.
- `pnpm-workspace.yaml` is excluded from read sandboxing, similar to
other workspace config files.
## Related Issue(s)
N/A
This PR brings our CNW experience back to previous state.
## Current Behavior
The CNW prompt flow diverges from v22.1.3 in several ways:
- Shows "Which starter do you want to use?" template prompt
- Cloud prompt says "Try the full Nx platform?" instead of caching
question
- Preset flow uses simplified cloud prompt instead of CI provider →
caching fallback
- Completion message shows box banner with `accessToken=undefined`
manual URL
- Setup message includes `github.com/new` link not present in v22.1.3
## Expected Behavior
Human-visible CNW flow identical to v22.1.3 while preserving:
- NDJSON AI output (agentic experience)
- `--template` flag (works via CLI, not surfaced in prompts)
- Telemetry, error handling, AI agent detection
Changes:
- Skip template prompt, go straight to preset/stack flow
- Restore "Would you like remote caching?" with v22.1.3 wording
- Restore CI provider → caching fallback prompt chain for preset flow
- Pass actual nxCloud to createEmptyWorkspace so cloud token is real
- Restore v22.1.3 completion message ("Your remote cache is almost
complete.")
- Restore v22.1.3 getNxCloudInfo signature with rawNxCloud URL
visibility
- Restore "Nx Cloud has been set up successfully" spinner text
- Remove github.com/new link from push message
## Related Issue(s)
Closes NXC-4020
## Current Behavior
when you run things like `pnpm nx@latest init`, there might not be a
pnpm lockfile yet. So nx commands will detect the PM as `npm` by
default... even though the fact that the user is invoking the command
via `pnpm` is a strong signal that that's the PM they want to use.
## Expected Behavior
We fall back to detecting the invoking PM via env var if no lockfile
exists.
## Summary
- Read generated `config.toml` from `nx-ai-agents-config` repo as single
source of truth for Codex config format
- Deep-merge into user's existing `.codex/config.toml` using
`@ltd/j-toml` (already in monorepo)
- Adjust MCP args dynamically for Nx version (`["nx", "mcp"]` for ≥22,
`["nx-mcp"]` for <22), preserving extra user args
- Respect `multi_agent = false` if explicitly set by user
- Copy `.codex/agents/` subagent TOML files alongside existing
`.agents/skills/`
- Add unit tests (7) and e2e tests (4) for the new functionality
## Test plan
- [ ] Unit tests: `nx test nx -- --testPathPatterns set-up-ai-agents`
- [ ] E2e tests: `nx e2e e2e-nx -- --testPathPatterns
configure-ai-agents` (codex agent describe block)
- [ ] Verify codex config merges correctly with existing user config
- [ ] Verify `multi_agent = false` is not overwritten on re-run
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Current Behavior
The `extras.test.ts` e2e test is flaking on master because the snapshot
file expects `.github/workflows/ci.yml` in the "general" task inputs,
but `create-nx-workspace --no-interactive` no longer generates it.
PR #34332 accidentally updated the snapshot to include this file — the
author likely ran tests against a cached workspace from before PR #34616
fixed the CI workflow generation bug.
## Expected Behavior
The snapshot should not include `.github/workflows/ci.yml` since
`create-nx-workspace` correctly skips CI workflow generation in
non-interactive mode (fixed in PR #34616).
## Related Issue(s)
Fixes the `e2e-nx:e2e-ci--src/extras.test.ts` CI flakiness on master.
## Current Behavior
There's a bug currently where is a plugin returns a dependsOn dependency
or input that directly references another project by name, and a later
plugin renames that project, the dependsOn or input entry is left stale
and pointing at a now non-existent project.
## Expected Behavior
The old refs are kept up to date as the nodes get merged together
## AI Summary
This pull request introduces a new mechanism to handle project name
substitutions in the Nx project graph, ensuring that references to
project names in `inputs` and `dependsOn` blocks remain accurate even if
a plugin changes a project's name during graph construction. The main
addition is the `ProjectNameInNodePropsManager`, which tracks and
updates references when project names change. Several related
refactorings and improvements were made to integrate this manager into
the project configuration merging process.
**Project name substitution and consistency:**
* Added a new `ProjectNameInNodePropsManager` class to manage and apply
project name substitutions when project names change, ensuring that all
references in `inputs` and `dependsOn` blocks remain consistent.
* Integrated the `ProjectNameInNodePropsManager` into the
`mergeCreateNodesResults` function, registering substitutors for node
results, marking roots as dirty when names change, and applying
substitutions after merging.
[[1]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117R518)
[[2]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117L521-R551)
[[3]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117R563-R571)
**API and function changes:**
* Modified `mergeProjectConfigurationIntoRootMap` to return an object
indicating whether a project name was changed, instead of just returning
void.
[[1]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117L59-R62)
[[2]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117R238-R244)
**Code organization and import cleanup:**
* Refactored imports in `project-configuration-utils.ts` for better
organization and to accommodate the new manager.
[[1]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117L9-R25)
[[2]](diffhunk://#diff-774ce1a4fd8ec0c898c989fb75e2d8c87a0055549bca680945bce50f717db117R43-L43)
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
The clean-up PR inverted the reverse proxy logic such that only the
defined paths are passed to Next.js. The default is to return Framer
pages. Since we also remove the Nextjs redirect, we lose the `/docs` one
that was missing from `_redirects` file.
https://github.com/nrwl/nx/pull/34672
This PR adds the redirect to fix it again.
Bun includes extra consecutive async frames for async functions in call
stacks, causing `preventRecursionInGraphConstruction` to falsely detect
a recursive loop during normal project graph construction.
## Root Cause
`preventRecursionInGraphConstruction` uses `getCallSites().slice(2)` to
skip the top 2 frames (itself +
`buildProjectGraphAndSourceMapsWithoutDaemon`), then checks if
`buildProjectGraphAndSourceMapsWithoutDaemon` appears again in the
remaining frames.
In Bun, `buildProjectGraphAndSourceMapsWithoutDaemon` appears **twice
consecutively** due to async frame duplication — leaving one occurrence
after the slice, which incorrectly triggers the loop error.
**Node call stack (after `slice(2)`):**
```
#0 createProjectGraphAndSourceMapsAsync ← clean
#1 createProjectGraphAsync
#2 runOne
```
**Bun call stack (after `slice(2)`):**
```
#0 buildProjectGraphAndSourceMapsWithoutDaemon ← false positive!
#1 createProjectGraphAndSourceMapsAsync
#2 createProjectGraphAndSourceMapsAsync ← Bun duplicates async frames
#3 createProjectGraphAsync
```
## Fix
Since the call stack recursion check does not work reliably under Bun,
`preventRecursionInGraphConstruction` now returns early when running
under Bun, detected via `'Bun' in globalThis` — consistent with the
existing Bun runtime detection pattern used elsewhere in the codebase
(e.g., `isolated-plugin.ts`). The original `slice(2)` logic is preserved
unchanged for Node.js and other runtimes.
```ts
export function preventRecursionInGraphConstruction() {
// Bun's async stack traces include extra frames that cause false positives in the
// recursion check below, so we skip the check when running under Bun.
if ('Bun' in globalThis) {
return;
}
// ... existing Node.js check ...
}
```
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
----
*This section details on the original issue you should resolve*
<issue_title>getCallSites output differs between Node and Bun triggering
loop detection</issue_title>
<issue_description>### Current Behavior
Hey team,
I am trying to use Bun (1.3.5) instead of Node (v22.17.0) for running Nx
(v22.1.3) and bumped into the following error:
Command:
```bash
bunx --bun nx run api:build
```
Error:
```
NX Project graph construction cannot be performed due to a loop detected in the call stack. This can happen if 'createProjectGraphAsync' is called directly or indirectly during project graph construction.
To avoid this, you can add a check against "global.NX_GRAPH_CREATION" before calling "createProjectGraphAsync".
Call stack:
buildProjectGraphAndSourceMapsWithoutDaemon (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:81:62)
createProjectGraphAndSourceMapsAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:274:31)
createProjectGraphAndSourceMapsAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:225:53)
createProjectGraphAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:222:45)
createProjectGraphAsync (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/project-graph/project-graph.js:205:40)
runOne (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/command-line/run/run-one.js:23:52)
runOne (/app/node_modules/.pnpm/nx@22.1.3_@swc-node+register@1.10.9_@swc+core@1.11.1_@swc+helpers@0.5.15__@swc+types@0.1.18_t_twtgkxomntuzxcyp4ewkmtxn2q/node_modules/nx/src/command-line/run/run-one.js:16:23)
Pass --verbose to see the stacktrace.
```
After some digging I found that the stack trace produced by
https://github.com/nrwl/nx/blob/691bb320ce1e9cc2872e1a1b364d3fdeb9e1ad0e/packages/nx/src/utils/call-sites.ts
differs between Node and Bun. When
https://github.com/nrwl/nx/blob/691bb320ce1e9cc2872e1a1b364d3fdeb9e1ad0e/packages/nx/src/project-graph/project-graph.ts#L422
is run, the produced function call tracing is:
Node (v22.17.0):
```
nrwl/nx#0 createProjectGraphAndSourceMapsAsync
nrwl/nx#1 createProjectGraphAsync
nrwl/nx#2 runOne
nrwl/nx#3 <anonymous>
nrwl/nx#4 <anonymous>
nrwl/nx#5 handleErrors
nrwl/nx#6 handler
```
Bun (1.3.5):
```
nrwl/nx#0 buildProjectGraphAndSourceMapsWithoutDaemon <- This entry causes Nx to detect a loop
nrwl/nx#1 createProjectGraphAndSourceMapsAsync
nrwl/nx#2 createProjectGraphAndSourceMapsAsync
nrwl/nx#3 createProjectGraphAsync
nrwl/nx#4 createProjectGraphAsync
nrwl/nx#5 runOne
nrwl/nx#6 runOne
```
This is not a Nx bug per-se, but wondering if this falls into the
efforts of supporting Bun into Nx (i.e.
https://nx.dev/blog/nx-19-5-adds-stackblitz-new-features-and-more#bun-and-pnpm-v9-support)?
I will cross post the above into the Bun repo too for input.
### Expected Behavior
Able to execute Nx commands with Bun
### GitHub Repo
_No response_
### Steps to Reproduce
1. Run bunx --bun nx run api:build
### Nx Report
```shell
NX_DAEMON=true bunx --bun nx --disableNxCache --disableRemoteCache --outputStyle dynamic-legacy report 1 ✘ 16:18:00
NX Report complete - copy this into the issue template
Node : 24.3.0
OS : darwin-arm64
Native Target : aarch64-macos
pnpm : 9.6.0
nx : 22.1.3
@nx/js : 22.1.3
@nx/jest : 22.1.3
@nx/eslint : 22.1.3
@nx/workspace : 22.1.3
@nx/cypress : 22.1.3
@nx/devkit : 22.1.3
@nx/esbuild : 22.1.3
@nx/eslint-plugin : 22.1.3
@nx/module-federation : 22.1.3
@nx/nest : 22.1.3
@nx/next : 22.1.3
@nx/node : 22.1.3
@nx/playwright : 22.1.3
@nx/plugin : 22.1.3
@nx/react : 22.1.3
@nx/rollup : 22.1.3
@nx/storybook : 22.1.3
@nx/vite : 22.1.3
@nx/vitest : 22.1.3
@nx/web : 22.1.3
@nx/webpack : 22.1.3
@nx/docker : 22.1.3
nx-cloud : 19.1.0
@nrwl/nx-cloud : 19.1.0
typescript : 5.7.3
---------------------------------------
Registered Plugins:
@nxlv/python
---------------------------------------
Community plu...
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesnrwl/nx#33997
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for you](https://github.com/nrwl/nx/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot) — coding agent works faster and does higher quality work when set up for your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>
## Current Behavior
Frequent write cache calls during tasks hashing results in delays
## Expected Behavior
Cache is validated but only written when changed
## AI Summary
This pull request introduces an optimization to the project graph cache
writing logic, reducing unnecessary disk writes when serving repeated
requests with unchanged graphs. The main change is the addition of a
mechanism to track the cache file's modification time and only write to
disk if the file has been externally modified or not written yet by the
current process.
Optimizations to cache writing:
* Added `writeCacheIfStale` function in `nx-deps-cache.ts` to prevent
redundant cache writes by checking the cache file's modification time
before writing. This function is now used in the daemon's graph
recomputation logic, replacing the previous unconditional write.
[[1]](diffhunk://#diff-82bd1a5a7b7320ffc3233470f191782c054bf69a696dc16001d2c4b1d0b04963R285-R312)
[[2]](diffhunk://#diff-d5bf3c66e62cac1884a071bf07fd1991320a3e62b07bfc03af3b9557b714c892L17-R17)
[[3]](diffhunk://#diff-d5bf3c66e62cac1884a071bf07fd1991320a3e62b07bfc03af3b9557b714c892L136-R149)
* Introduced `lastWrittenCacheMtimeMs` variable to track the last
successful write's modification time, updated after each cache write.
[[1]](diffhunk://#diff-82bd1a5a7b7320ffc3233470f191782c054bf69a696dc16001d2c4b1d0b04963R202-R208)
[[2]](diffhunk://#diff-82bd1a5a7b7320ffc3233470f191782c054bf69a696dc16001d2c4b1d0b04963R256-R261)
Codebase updates:
* Updated imports in `nx-deps-cache.ts` to include `statSync` for file
modification time checks.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
`{projectRoot}` and `{projectName}` tokens inside `{workspaceRoot}/...`
input patterns were silently never substituted in the native Rust
hasher, causing the glob to match zero files and those inputs to be
entirely excluded from the cache hash — a silent cache correctness bug.
## Root Cause
In `gather_self_inputs` (`hash_planner.rs`), workspace filesets (those
starting with `{workspaceRoot}/`) were forwarded as-is to
`HashInstruction::WorkspaceFileSet`. When `globs_from_workspace_globs`
later stripped `{workspaceRoot}/`, the remaining `{projectRoot}/**/*.go`
was matched literally — which never exists on disk.
## Changes
- **`hash_planner.rs`**: Before storing workspace filesets in
`HashInstruction::WorkspaceFileSet`, replace `{projectRoot}` and
`{projectName}` with their actual values from the project graph node.
- **`planner.spec.ts`**: Added a test verifying that a pattern like
`{workspaceRoot}/{projectRoot}/**/*.go` correctly resolves to
`{workspaceRoot}/libs/parent/**/*.go` in the hash plan.
```json
// nx.json — this pattern now works correctly
"namedInputs": {
"goSource": ["{workspaceRoot}/{projectRoot}/**/*.go"]
}
```
This pattern is documented as valid per the [Nx inputs
reference](https://nx.dev/docs/reference/inputs): `{projectRoot}` and
`{projectName}` can appear anywhere after the leading `{workspaceRoot}`.
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `repo.gradle.org`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m
-Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en` (dns
block)
> - `staging.nx.app`
> - Triggering command:
`/home/REDACTED/work/_temp/ghcca-node/node/bin/node node
./bin/post-install` (dns block)
> - Triggering command: `/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/home/REDACTED/work/nx/nx/node_modules/.pnpm/nx@22.6.0-beta.5_@swc-node+register@1.11.1_@swc+core@1.15.10_@swc+helpers@0.5.18__@swc+_a827ebc424be037fc154d90301143d4e/node_modules/nx/src/project-graph/plugins/isolation/plugin-worker
/tmp/plugin4368-16-420.890618.sock @nx/enterprise-cloud` (dns block)
> - Triggering command: `/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/opt/hostedtoolcache/node/24.13.1/x64/bin/node
/home/REDACTED/work/nx/nx/node_modules/.pnpm/nx@22.6.0-beta.5_@swc-node+register@1.11.1_@swc+core@1.15.10_@swc+helpers@0.5.18__@swc+_a827ebc424be037fc154d90301143d4e/node_modules/nx/src/project-graph/plugins/isolation/plugin-worker
/tmp/plugin5770-16-420.874901.sock @nx/enterprise-cloud` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/nrwl/nx/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>{projectRoot} not interpolated inside {workspaceRoot}
input patterns in native hasher</issue_title>
> <issue_description>## Current Behavior
>
> When using a `{workspaceRoot}/{projectRoot}/**/*.go` pattern in target
inputs, the `{projectRoot}` token is **not interpolated** by the native
Rust hash planner. The pattern silently matches zero files, causing the
cache hash to exclude those files entirely.
>
> ```json
> // nx.json
> "namedInputs": {
> "gosourceUnfiltered": ["{workspaceRoot}/{projectRoot}/**/*.go"]
> }
> ```
>
> ```json
> // target config
> "format": {
> "inputs": ["gosourceUnfiltered", { "externalDependencies": [] }]
> }
> ```
>
> The hash plan for this target contains **zero `.go` file inputs**:
>
> ```
> Task: my-project:format:write
> Inputs:
> my-project:ProjectConfiguration
> my-project:TsConfig
> env:NX_CLOUD_ENCRYPTION_KEY
> file:nx.json
> file:.gitignore
> // no .go files!
> ```
>
> ## Root Cause
>
> In the Rust hash planner (`hash_planner.rs`), fileset inputs are
partitioned based on their prefix:
>
> ```rust
> .partition(|file_set| {
> file_set.starts_with("{projectRoot}/") ||
file_set.starts_with("!{projectRoot}/")
> });
> ```
>
> A pattern starting with `{workspaceRoot}/` is classified as a
**workspace fileset**. It then flows to `hash_workspace_files.rs` where
`{workspaceRoot}/` is stripped via `strip_prefix("{workspaceRoot}/")`,
leaving `{projectRoot}/**/*.go`. But `{projectRoot}` is **never
substituted** with the actual project root, so the glob literally tries
to match paths starting with `{projectRoot}/` — which don't exist.
>
> ## Expected Behavior
>
> Per the [Nx docs on inputs](https://nx.dev/docs/reference/inputs):
>
> > `{workspaceRoot}` should only appear in the beginning of an input
but **`{projectRoot}` and `{projectName}` can be specified later in the
input to interpolate the root or name of the project** into the input
location.
>
> The native hasher should interpolate `{projectRoot}` (and
`{projectName}`) within `{workspaceRoot}` patterns before glob matching.
After stripping `{workspaceRoot}/` and interpolating `{projectRoot}`,
the pattern should become e.g. `packages/shared/go/middleware/**/*.go`
and correctly match files.
>
> ## Impact
>
> This is a **silent cache correctness issue**: targets using this
pattern appear to work but their cache hash doesn't include the matched
files. Changes to those files won't invalidate the cache. There's no
warning or error emitted.
>
> ## Workaround
>
> Use the literal path instead of `{projectRoot}` inside workspace-level
patterns:
>
> ```js
> // In a createNodes plugin, instead of:
> inputs: ["{workspaceRoot}/{projectRoot}/**/*.go"]
> // Use:
> inputs: [`{workspaceRoot}/${actualProjectRoot}/**/*.go`]
> ```
>
> ## Related
>
> - nrwl/nx#34225 — Nested Project Files Excluded from Parent Project
Inputs (the reason `{workspaceRoot}/{projectRoot}` patterns are used in
the first place: to bypass project file filtering and include files from
nested sub-projects)
>
> ## Environment
>
> - **Nx version**: 22.6.0-beta.3
> - **OS**: macOS (Darwin 24.6.0)
> - **Package manager**: pnpm</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesnrwl/nx#34595
<!-- START COPILOT CODING AGENT TIPS -->
---
🔒 GitHub Advanced Security automatically protects Copilot coding agent
pull requests. You can protect all pull requests by enabling Advanced
Security for your repositories. [Learn more about Advanced
Security.](https://gh.io/cca-advanced-security)
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>
`nx show target inputs` returns empty results for any target with
`defaultConfiguration` set because
`HashPlanInspector.inspectTaskInputs()` keys results as
`project:target:config` (e.g. `my-app:build:local`), but the lookup was
using `project:target` — a guaranteed miss.
## Changes
- **`packages/nx/src/command-line/show/target.ts`**: In
`resolveInputFiles`, construct the plan lookup key using the explicitly
passed `configuration` first, then fall back to the target's
`defaultConfiguration`:
```ts
const targetConfig = graph.nodes[projectName]?.data?.targets?.[targetName];
const effectiveConfig = configuration ?? targetConfig?.defaultConfiguration;
const taskId = effectiveConfig
? `${projectName}:${targetName}:${effectiveConfig}`
: `${projectName}:${targetName}`;
```
If the computed `taskId` is not found in the hash plan, an error is
thrown instead of silently returning empty results.
- **`showTargetInputsHandler`**: Now extracts the configuration from the
target string (`project:target:config`) or the `-c`/`--configuration`
flag and forwards it to `resolveInputFiles`.
- **`ShowTargetInputsOptions`** (`command-object.ts`): Added
`configuration?: string` so the type correctly reflects the prop.
- **`packages/nx/src/command-line/show/target.spec.ts`**: Added tests
covering:
- Resolving input files when `defaultConfiguration` is set
- Preferring an explicit `configuration` over `defaultConfiguration`
- Throwing when the task ID is not found in the hash plan
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>nx show target inputs returns empty when target has
defaultConfiguration</issue_title>
> <issue_description>## Current Behavior
>
> `nx show target inputs <project>:<target> --json` returns no files for
any target that has a `defaultConfiguration` set (directly or via
`targetDefaults`).
>
> ```bash
> $ nx show target inputs card-api-lambda:build --json
> {
> "project": "card-api-lambda",
> "target": "build"
> }
> # Expected: files array with resolved input files
> ```
>
> The `--check` flag also reports files as not being inputs when they
should be:
>
> ```bash
> $ nx show target inputs card-api-lambda:build --check
packages/card/api/lambda/main.go
> ✗ packages/card/api/lambda/main.go is not an input for
card-api-lambda:build
> ```
>
> Targets **without** `defaultConfiguration` on the same project resolve
correctly:
>
> ```bash
> $ nx show target inputs card-api-lambda:generate-docs --json
> {
> "project": "card-api-lambda",
> "target": "generate-docs",
> "files": [ ".gitignore", "nx.json",
"packages/card/api/lambda/main.go", ... ]
> }
> ```
>
> ## Root Cause
>
> In `packages/nx/src/command-line/show/target.ts`, the
`resolveInputFiles` function constructs the lookup key as:
>
> ```js
> const taskId = `${projectName}:${targetName}`;
> ```
>
> But the native `HashPlanInspector.inspectTaskInputs()` returns results
keyed by the **full task ID including the default configuration**, e.g.
`card-api-lambda:build:local`.
>
> When a target has `defaultConfiguration: "local"`, the plan result is
keyed as `project:target:local`, but the lookup searches for
`project:target` — which doesn't exist — so it falls through to the
empty default `{ files: [], ... }`.
>
> Verified by calling `inspectTaskInputs` directly:
>
> ```
> === build ===
> Task IDs in result: card-api-lambda:generate-docs,
card-api-lambda:build:local
> # lookup for "card-api-lambda:build" → miss → empty
>
> === generate-docs ===
> Task IDs in result: card-api-lambda:generate-docs
> # lookup for "card-api-lambda:generate-docs" → hit → 142 files
> ```
>
> ## Suggested Fix
>
> The lookup key should account for the default configuration:
>
> ```js
> const defaultConfig =
graph.nodes[projectName]?.data?.targets?.[targetName]?.defaultConfiguration;
> const taskId = defaultConfig
> ? `${projectName}:${targetName}:${defaultConfig}`
> : `${projectName}:${targetName}`;
> ```
>
> ## Expected Behavior
>
> `nx show target inputs` should resolve and display input files
regardless of whether the target has a `defaultConfiguration`.
>
> ## Environment
>
> - **Nx version**: 22.6.0-beta.3
> - **OS**: macOS (Darwin 24.6.0)
> - **Node**: v22
> - **Package manager**: pnpm</issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesnrwl/nx#34594
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>
## Current Behavior
napi-derive v2 has a bug where the type definition temp file doesn't get
cleaned between builds with different profiles (release vs dev), causing
duplicate class declarations in `index.d.ts`.
## Expected Behavior
With napi-rs v3, the temp file handling is fixed — each crate gets its
own folder, preventing duplicate declarations across build profiles.
## Related Issue(s)
N/A — internal build tooling improvement.
## Changes
### Dependency upgrades
- **Cargo.toml**: `napi` 2.x → 3.8.3, `napi-derive` 2.x → 3.5.2,
`napi-build` 1.x → 2.3.1
- **package.json**: `@napi-rs/cli` → 3.5.1 (was 3.0.0-alpha.56)
### External data sharing (Arc pattern)
- Replaced raw-pointer `StoredExternal<T>` wrapper with napi-recommended
`Arc<T>` pattern for shared ownership
- Read-only data: `External::new(Arc::new(data))` at creation, `Arc<T>`
in struct fields
- Mutable data (DB): `External::new(Arc::new(Mutex::new(data)))`,
`Arc<Mutex<T>>` in struct fields
- Constructors take `&External<Arc<T>>`, clone the Arc;
`#[napi(ts_arg_type)]` preserves TS types
- Deleted `types/external_compat.rs` (86 lines of unsafe code removed)
### API migrations
- `ThreadsafeFunction`: Accept directly as napi parameters instead of
building from `Function<'_>`
- Return-only structs: Use `#[napi(object, object_from_js = false)]` for
structs with `External<T>` fields
- `env.create_object()` → `Object::new(&env)`, `JsObject` → `PromiseRaw`
for async returns
### Watcher fix
- Deferred `Watchexec::default()` creation from constructor to `watch()`
inside napi's `spawn()` block
- `Watchexec::default()` internally calls `tokio::spawn()` which
requires a Tokio runtime in TLS — the `#[napi(constructor)]` runs on the
JS main thread with no runtime context
- Changed `napi::tokio::spawn(...)` to `spawn(...)` (napi's
`bindgen_prelude::spawn` which uses a static runtime, works from any
thread)
- Store `watch_exec` as `Arc<Mutex<Option<Arc<Watchexec>>>>` for lazy
initialization
### TUI fix
- Same Tokio runtime issue: `tokio::spawn(async {})` placeholder in
`Tui::new()` panicked on JS main thread
- Changed `task` field from `JoinHandle<()>` to
`Option<JoinHandle<()>>`, initialized as `None`
- Moved `tui.start()` (which calls `tokio::spawn`) inside napi's
`spawn()` async block
- Changed `napi::tokio::spawn(...)` to `spawn(...)` in lifecycle.rs
### Platform-specific watcher improvements
- Gated non-macOS watcher functions with `#[cfg(not(target_os =
"macos"))]`
- Added `rlib` to `crate-type` in Cargo.toml for cargo test
compatibility
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
Several Rust native modules and one TS utility have unnecessary
allocations:
- `hash_planner.rs`: visited set uses `HashSet<String>` with
`to_string()` per insert; unnecessary `.collect::<Vec<_>>()` creating
temp vecs; no pre-allocation for dependency inputs
- `context.rs`: `update_files` allocates a String per map entry inside
retain loop
- `hash_workspace_files.rs`: `.clone()` before `.as_bytes()` — 2
needless heap allocs per file
- `find_matching_projects.rs`: collects HashMap keys into Vec + linear
search instead of O(1) lookup
- `validate_outputs.rs`: compiles regex on every call
- `project-configuration-utils.ts`: uses `JSON.parse(JSON.stringify())`
for deep cloning
## Expected Behavior
All unnecessary allocations removed:
- Borrow `&str` from project graph instead of cloning Strings into
visited set
- Use `Path::new()` once outside retain closure (also more correct —
component-boundary-aware matching)
- Call `.as_bytes()` directly without clone
- Use `HashMap::get_key_value()` for O(1) lookup
- Cache compiled regex with `LazyLock<Regex>`
- Use `structuredClone` (Node 18+) instead of JSON round-trip
See individual commits for detailed rationale per change.
## Current Behavior
When using `@nx/angular-rspack` with SCSS imports that reference
external assets (e.g., `flag-icon-css`), the `postcss-cli-resources`
plugin generates absolute filesystem paths in CSS `url()` values:
```css
.flag-icon-us{background-image:url(/some/project/path/dist/bug-demo/browser/media/us.2d0a1dd6.svg)}
```
This happens because `normalizeOutputPath()` makes `outputPath.media`
absolute, and this absolute path is passed directly as
`resourcesOutputPath` to `postcss-cli-resources`.
## Expected Behavior
CSS `url()` values contain relative paths:
```css
.flag-icon-us{background-image:url(media/us.2d0a1dd6.svg)}
```
## Related Issue(s)
Fixes#34092
## Current Behavior
CSS `url()` references to fonts and assets fail to resolve on Windows
with webpack, rspack, and angular-rspack builds. The
`postcss-cli-resources` plugin passes Windows absolute paths (e.g.
`E:\dev\project\font.woff2`) to `new URL(path, 'file:///')`, which
misinterprets the drive letter (`E:`) as a URL protocol, stripping it
from `pathname` and producing unresolvable paths like
`\dev\project\font.woff2`.
## Expected Behavior
CSS `url()` references to fonts, images, and other assets resolve
correctly on all platforms.
## Related Issue(s)
Fixes#33052
## Current Behavior
The Netlify edge function reads `NEXT_PUBLIC_FRAMER_REWRITES` env var to
determine which paths to proxy to Framer. As more pages move to Framer,
this growing allowlist becomes cumbersome to maintain.
## Expected Behavior
The edge function now proxies all requests to Framer by default. Only
paths explicitly listed in `nextjsPaths` and `excludedPath` are served
by Next.js. This removes the need for the `NEXT_PUBLIC_FRAMER_REWRITES`
env var (should be removed from Netlify dashboard manually).
Deleted 25 page files (pages router + app router) that are now served by
Framer: homepage, 404, enterprise/*, contact/*, solutions/*, community,
company, customers, nx-cloud, partners, brands, careers, java, react,
remote-cache, resources, webinar.
**Next.js paths kept:** `/blog/*`, `/courses/*`, `/pricing`, `/podcast`,
`/ai-chat`, `/changelog`, `/resources-library`, `/whitepaper-fast-ci`,
`/500`, `/api/*`, `/docs/*`
**Manual follow-up:** Remove `NEXT_PUBLIC_FRAMER_REWRITES` env var from
Netlify dashboard.
## Related Issue(s)
Closes DOC-431
## Current Behavior
10 `nx.dev` URLs return 404 — broken links in CLI output, graph UI, and
cloud UI. Additionally:
- ~20 wildcard redirect rules silently broken because `:slug*` was never
converted to Netlify's `*`/`:splat` syntax
- Specific `/getting-started/` rules ordered after the wildcard
catch-all, sending users to the generic intro page instead of the
correct page (e.g., `/getting-started/editor-setup`)
- Redirect chain breaks where intermediate targets (e.g.,
`/nx-api/powerpack-*-cache` → `/nx-api/*-cache`) had no rule
## Expected Behavior
All documented `nx.dev` URLs resolve correctly. `_redirects` is the sole
source of truth — no more JS generator pipeline.
### Changes
1. **Fixed `_redirects`**:
- Converted all `:slug*` to `*`/`:splat` (Netlify syntax)
- Reordered specific `/getting-started/` rules before the wildcard
catch-all
- Added 13 new redirect rules for broken 404 URLs
2. **Fixed `astro-docs/netlify.toml`**:
- Added 3 redirects for `/docs/` path typos (trailing-s, wrong path)
3. **Deleted legacy files** (-2,248 lines):
- `redirect-rules.js`
- `redirect-rules-docs-to-astro.js`
- `redirect-rules.spec.js`
- `scripts/generate-netlify-redirects.mjs`
## Related Issue(s)
Fixes DOC-428
## Current Behavior
When running Gradle batch tasks (e.g. `nx build my-gradle-project
--no-tui`), the terminal shows no task output. The Gradle build output
is captured into `ByteArrayOutputStream` for JSON results but never
forwarded to the terminal. Users can only see the output in Nx Cloud
task results.
## Expected Behavior
Gradle batch task output (build logs, test results, etc.) should be
visible in the terminal in real-time as the batch executes.
## Changes
- **`TeeOutputStream.kt`** (new): An `OutputStream` that writes to two
destinations simultaneously — captures output for JSON results while
also forwarding to `System.err` for terminal display.
- **`GradleRunner.kt`**: Wrap `setStandardOutput` and `setStandardError`
with `TeeOutputStream` to tee into `System.err` in both
`runBuildLauncher` and `runTestLauncher`.
- **`gradle-batch.impl.ts`**: Replace `PseudoTerminal` (which swallowed
all output with `quiet: true`) with `execSync` using `stdio: ['pipe',
'pipe', 'inherit']` so stderr flows directly to the terminal.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
The `build-base` target in `nx.json` has a manual `inputs` override of
`["production", "^production"]` which shadows the more accurate inputs
inferred by the `@nx/js/typescript` plugin.
## Expected Behavior
Let the `@nx/js/typescript` plugin infer the correct inputs for
`build-base` tasks, providing more accurate cache invalidation based on
the actual tsconfig project references.
## Lint Rule Changes
Removing the broad `inputs` override causes the `@nx/dependency-checks`
lint rule to flag a few dependencies as "unused" across three packages.
This happens because the rule uses the build target's inputs to
determine which files to scan for imports, and the narrower tsc-inferred
inputs don't cover certain files:
- **`packages/nx`**: `@napi-rs/wasm-runtime` — used in
`nx.wasi-browser.js`, a `.js` file outside tsconfig scope
- **`packages/angular`**: `@angular-devkit/core` — only referenced as a
string (for `ensurePackage()`, migrations config) and is a
`peerDependency`, not directly imported at runtime
- **`packages/angular-rspack-compiler`**: `semver` — used in
`patch/patch-angular-build.js`, a `.js` patch file outside tsconfig
scope
These are all legitimate dependencies. Adding the `.js` files to
tsconfig would require `allowJs` and pull non-TS scripts into the build
pipeline unnecessarily. Adding them to `ignoredDependencies` in each
package's `.eslintrc.json` is the correct fix.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
The vitest executor ignores `reporter`/`reporters` set in target options
(project.json). Both forms leak through as passthrough CLI args, causing
vitest's `resolveConfig` to override the `reporters` array (which
includes NxReporter), making the executor hang indefinitely.
Additionally, when the vite config uses `reporter` (singular), the
config value always overrides the `reporters` array passed as inline
options — again removing NxReporter.
## Expected Behavior
Target-level `reporter`/`reporters` options take priority over
config-file values. NxReporter is always preserved in the final
reporters array regardless of configuration source.
Priority chain: target `reporter` (singular) > target `reporters`
(plural) > config `reporter` (singular) > config `reporters` (plural).
## Related Issue(s)
Fixes#34495
This PR updates the guide for integrated -> TS solution setup with
additional information. It also adds `% llm_copy_prompt %}` and `{%
llm_only %}` components to provide instructions to the AI agent to
perform the migration.
Preview:
https://deploy-preview-34646--nx-docs.netlify.app/docs/technologies/typescript/guides/switch-to-workspaces-project-references
## Current Behavior
The migration guide covers basic steps but is missing several nuances
discovered in the ocean repo's convert-ts-solution generator and through
end-to-end validation against a real workspace.
## Expected Behavior
The guide covers all steps needed for a successful migration, including:
- .gitignore updates for out-tsc/dist/test-output artifacts
- Order of operations (install before removing paths)
- Root tsconfig cleanup (remove paths entirely, baseUrl, rootDir)
- Package.json self-export and nested path alias strategies
- Update build targets (remove @nx/js:tsc for non-buildable libs)
- Import path updates after package renaming
- Bundler config updates (webpack auto-detect, Jest resolver,
Vite/Vitest)
- Edge cases: circular deps, e2e projects, non-standard locations,
tsconfig include/exclude patterns
Validated end-to-end against a test workspace with 5 libs and 2 React
apps (webpack+jest, vite+vitest) across 2 clean iterations.
## Screenshots
<img width="810" height="458" alt="Screenshot 2026-02-27 at 7 31 16 AM"
src="https://github.com/user-attachments/assets/80ad87db-6ebe-4f54-9995-65f2ee2c46f1"
/>
<img width="784" height="735" alt="Screenshot 2026-02-27 at 7 31 20 AM"
src="https://github.com/user-attachments/assets/a0a7fe26-7d7d-4225-94bb-f82e5fc49178"
/>
<img width="897" height="161" alt="Screenshot 2026-02-27 at 7 31 39 AM"
src="https://github.com/user-attachments/assets/3b410092-5fb4-420d-9909-ee83c34ff0d6"
/>
## Related Issue(s)
NXC-2950
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
## Current Behavior
Searching for CLI commands like `nx watch` on the docs site does not
surface the [Nx Commands reference
page](https://nx.dev/docs/reference/nx-commands) on the first page of
results, even when filtering by "References."
Root causes:
- **Term saturation**: "nx" appears 150+ times on the CLI reference page
(in every heading, usage block, and example), causing it to saturate and
contribute almost nothing to ranking differentiation.
- **Page length penalty**: The current `pageLength: 0.5` setting
actively penalizes long pages—the CLI reference is one of the longest on
the site.
- **No weight boost**: The CLI page had no `weight` set, while
generators/executors pages already get `weight: 2.0`.
## Expected Behavior
Searching for `nx watch`, `nx run-many`, or other CLI commands should
surface the Nx Commands reference page prominently in results.
This PR applies two quick-win tuning changes:
1. **`weight: 4`** on the CLI commands page entry — gives body text ~16×
impact (quadratic scaling), making it competitive with shorter pages
that mention commands incidentally. include the command name in the sub
headers for more improvement in relevancy search without impacting other
pages
2. **`termSaturation: 1.2`** (down from default 1.4) — makes highly
repeated terms like "nx" saturate faster so that the differentiating
term (e.g. "watch") carries more relative weight.
## Related Issue(s)
Addresses
[DOC-401](https://linear.app/nxdev/issue/DOC-401/investigate-boosting-cli-command-reference-pages-in-search)
## Current Behavior
When running `pnpm nx-release --local false`, the `nx release version`
step modifies `package.json` files for `angular-rspack`,
`angular-rspack-compiler`, `dotnet`, and `maven` (bumping versions and
resolving `workspace:*` protocols). The local release path (`--local
false`, non-CI) exits early before reaching the reset logic that the CI
path uses, leaving unstaged changes behind.
## Expected Behavior
After the release script completes (or is interrupted), the source
`package.json` files should be restored to their original state. The
version bumps are only needed in `dist/` for publishing — the source
files should stay at `0.0.1` with `workspace:*` protocols.
This PR:
- Extracts a shared `resetPackageJsons()` function used by both the
local and CI code paths
- Wraps the local release steps in `try/finally` so files are restored
even on errors
- Adds a `SIGINT` handler so files are restored on ctrl+C
Add sandboxing-config.yaml to exclude node_modules from reads in Nx
Cloud workflow sandboxing.
## Current Behavior
No sandboxing configuration exists for Nx Cloud workflows.
## Expected Behavior
Nx Cloud workflows use sandboxing config that excludes `node_modules/**`
from reads.
## Related Issue(s)
N/A
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
In `internalCreateNodesV2`, the ESLint plugin creates a **new `ESLint`
instance per child project root** to check whether the project has
non-ignored lintable files via `isPathIgnored`:
```ts
const eslint = new ESLint({
cwd: join(context.workspaceRoot, projectRoot),
});
for (const file of lintableFilesPerProjectRoot.get(projectRoot) ?? []) {
if (!(await eslint.isPathIgnored(...))) { ... }
}
```
In large monorepos, this means hundreds or thousands of ESLint
instantiations during graph calculation. Each instantiation involves
loading and resolving the ESLint configuration, which is the dominant
cost in the plugin.
## Expected Behavior
A single ESLint instance should be shared across all child projects
under the same ESLint config directory. Since `isPathIgnored` receives
**absolute paths**, the instance's `cwd` does not affect the result — it
only needs to resolve the correct config, which is the same for all
children of a given config root.
## Changes
* In `internalCreateNodesV2`: create one lazily-initialized shared
ESLint instance per config directory (the `configDir`), reused across
all child project roots
* Projects that have their own `.eslintignore` file fall back to a
per-project ESLint instance, preserving correct behavior for ESLint v8
(which resolves `.eslintignore` relative to `cwd`)
## Benchmark
Measured on a real monorepo with **1,609 projects** and a single root
ESLint config.
| | Before | After | Change |
|---|---|---|---|
| Cold run (avg of 3) | **~18,700ms** | **~7,300ms** | **-61%** |
| ESLint instances created | 1,457 | 8 | **-99.5%** |
### Breakdown
| Version | Run 1 | Run 2 | Run 3 |
|---|---|---|---|
| Baseline (upstream) | 23,482ms | 16,238ms | 16,389ms |
| With shared instance | 7,473ms | 7,012ms | 7,515ms |
### Methodology
* `NX_DAEMON=false` to prevent daemon caching
* ESLint plugin hash cache cleared between each cold run
* `performance.now()` instrumentation around `internalCreateNodesV2`
* Each measurement repeated 3 times
* **Verified same number of lint targets** (1,473) before and after — no
behavior change
### Why `configDir === '.'` is not excluded
The earlier revision excluded root-level ESLint configs (`configDir ===
'.'`) from the optimization as a conservative safety measure. However,
benchmarking showed this **completely disables the optimization** for
the most common monorepo setup (single root ESLint config), dropping
1,456 of 1,457 instances back to per-project instantiation with zero
measurable improvement.
The per-project `.eslintignore` check already handles the ESLint v8
concern: projects with their own `.eslintignore` still get dedicated
instances, while all others share one instance whose `cwd` correctly
resolves the root config and root `.eslintignore`.
## Related
This is the `createNodesV2` (Nx plugin) code path. The change does not
affect ESLint execution itself — only the graph calculation phase.
When latest >= next, the build-migrations script now preserves the
existing x-prompt and requires fields from the pre-release entry, rather
than skipping them, and adjusts the requires upper bound to the stable
version.
## Current Behavior
The Maven batch runner uses a parallel thread pool to execute tasks.
When multiple tasks are independent roots in the task graph, they get
picked up by separate threads simultaneously. Both threads call
`invoke()` on the same shared `CachingResidentMavenInvoker` (Maven 4) or
`CachingMaven3Invoker` (Maven 3) instance concurrently.
Maven 4's `LookupInvoker.invoke()` is not thread-safe — it
snapshots/restores `System.getProperties()` and the thread context
classloader in a `finally` block, and all concurrent invocations share
the same resident `MavenContext`. This can cause deadlocks in Maven's
internal session machinery.
## Expected Behavior
Maven executions through the shared invoker are serialized via
`@Synchronized`, preventing concurrent access to non-thread-safe Maven
internals. The parallel thread pool still handles task graph management,
build state recording, and result emission concurrently.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Current Behavior
When running `nx release` with Git remotes configured as **canonical SSH
URLs**, the repository slug is extracted incorrectly.
Examples of affected remotes include:
- `ssh://git@ssh.github.com:443/org/repo.git`
- `ssh://git@gitlab.company.com:2222/group/subgroup/repo.git`
In these cases, the existing regex-based logic misinterprets the port
number as part of the repository path (for example: `443/org`). This
causes the release creation request to be built with an invalid
repository slug and results in `404 Not Found` errors from the GitHub or
GitLab APIs.
## Expected Behavior
`nx release` should correctly extract the repository slug from all valid
Git remote URL formats, regardless of whether the remote uses HTTPS,
SCP-style SSH, or fully qualified SSH URLs with explicit ports.
Valid examples should resolve to the correct slug:
- `ssh://git@ssh.github.com:443/org/repo.git` => `org/repo`
- `ssh://git@gitlab.company.com:2222/group/subgroup/repo.git`=>
`group/subgroup/repo`
Users should not need to modify their Git remote configuration in order
for `nx release` to work correctly.
## What’s Changed
- Introduced a shared utility
([`extractRepoSlug`](https://github.com/nrwl/nx/pull/31684/changes#diff-799188c178b8a084e86dbe9063ec88a7c324212a8ef79729777f56e4bf7f455cR29-R60))
to consistently extract repository slugs from Git remote URLs.
- Replaced provider-specific, regex-based parsing in:
- `GithubRemoteReleaseClient`
- `GitLabRemoteReleaseClient`
- Added support for:
- HTTPS remotes
- SCP-style SSH remotes (`git@host:org/repo.git`)
- Fully qualified SSH URLs with custom ports
- Arbitrarily nested GitLab group and subgroup paths
- Self-hosted GitHub and GitLab instances via hostname matching
- Added comprehensive unit tests covering valid and invalid URL formats
for both providers.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#31682
## Current Behavior
The Nx native module (Rust cdylib loaded by Node.js) uses the system
allocator. The daemon process retains a large RSS footprint after the
initial project graph build, even though most of that memory is no
longer in use. On macOS and Linux, the system allocator doesn't
aggressively return freed pages to the OS.
## Expected Behavior
The daemon's steady-state RSS drops significantly after graph build by
using jemalloc with tuned page purge timers. Peak RSS and wall time are
unaffected.
## Changes
Adds [tikv-jemallocator](https://github.com/tikv/jemallocator) as the
global allocator on Linux and macOS, with two compile-time settings:
- **`dirty_decay_ms:1000`** — returns freed pages to the OS after 1s
instead of the default 10s. Tuned to Nx's phase-separated workload
(graph build → idle → task execution), where transitions happen every
~30-60s. Benchmarked against 5s and 10s — both too slow to purge between
phases.
- **`muzzy_decay_ms:0`** — skips the lazy purge phase (`MADV_FREE`) and
goes straight to `MADV_DONTNEED`. Required on macOS and Linux ≥ 4.5
where `MADV_FREE` doesn't actually reduce RSS.
Windows and WASI continue using the system allocator. Windows is
excluded because `tikv-jemalloc-sys` fails to build with MSVC (spaces in
`cl.exe` path break the autoconf configure script). Tracked upstream in
[tikv/jemallocator#99](https://github.com/tikv/jemallocator/pull/99).
### Other Settings Considered
Tested narenas reduction, tcache_max, extent fit tuning, background
threads, and decay timer values. Only the decay timer configuration
improved steady-state RSS without wall time regression.
closed#32190
## Current Behavior
eslint crashes when tsconfig.base.json path includes a * and you have an
import going to that project
## Expected Behavior
The plugin shouldn't crash and it should auto fix to a working import
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
https://github.com/nrwl/nx/issues/32190Fixes#32190
## Current Behavior
The `replace-removed-matcher-aliases` migration uses `tsquery.replace()`
which reprints the entire AST through TypeScript's Printer. This causes
two problems:
1. **Syntax corruption**: Valid TypeScript files are mangled:
- Destructuring patterns: `{ result }` becomes `{result}:`
- Arrow functions: missing opening braces
- Nested callbacks: collapsed/merged code blocks
2. **Unnecessary file changes**: Every test file is written back to disk
even when no matchers are replaced. This triggers `formatFiles()` to
reformat unchanged files, creating large whitespace-only diffs. In large
codebases, this can result in hundreds or thousands of files being
modified unnecessarily, making the migration PR difficult to review.
**Why I care a Lot**
I was running this on a multi-million-LOC monorepo and ran into two
issues:
* I got ~10k modified files with whitespace-only changes from the
removal of newlines. These changes couldn't be fixed with Prettier
because it didn't care about the number of newlines, so the diff was
unmergeable.
* I got ~8 files with malformed Typescript, causing commit hooks, CI,
etc. to fail without manual intervention.
## Expected Behavior
The migration should:
1. Only replace the deprecated matcher names (e.g., `toBeCalled` →
`toHaveBeenCalled`)
2. Preserve all surrounding code exactly as written
5. Only touch files that actually contain deprecated matchers
## Solution
Replace AST-reprinting with surgical text replacement:
- Use `tsquery.query()` to find matching AST nodes
- Collect text positions (start/end) for each node to replace
- Apply replacements in reverse order using string slicing
- Only write files that actually changed
This pattern is already used successfully in other Nx migrations (e.g.,
`rename-cy-exec-code-property.ts` in the Cypress package).
**Additional improvements:**
- Single AST parse with regex selector vs. 11 separate passes
- Quick string check skips parsing files without deprecated matchers
- New regression test covers complex patterns that triggered corruption
## Related Issue(s)
Fixes#32062
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
## Current Behavior
E2E tests may timeout without clear error messages, making it difficult
to diagnose test failures.
## Expected Behavior
E2E test utilities should provide better timeout handling and logging to
help diagnose test failures.
## Changes
- Add timeout handling to e2e test utilities (`runCLI` and
`runLernaCLI`)
- Add command logging to track execution time
- Improve timeout error messages with process output
- Bump cache bust value
## Related Issue(s)
CI stability and debugging improvements
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
`@nx/eslint` relies on ESLint internals that changed in ESLint v10
(`use-at-your-own-risk`), which causes failures.
It looks like https://github.com/nrwl/nx/pull/24632 originally attempted
to use `loadESLint()` which would've been forward compatible with v10,
but it was later removed in https://github.com/nrwl/nx/pull/27404 in
favor of the `use-at-your-own-risk` import.
## Expected Behavior
`@nx/eslint` supports ESLint v10.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#34415
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
If you specify both the `all` and `initialRun` options when running `nx
watch`, `initialRun` have no effect.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The command should be called once at the beginning even if there are no
file changes.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#32281
## Current Behavior
nx-maven-plugin 0.0.12 is also changing the base directory along with
the pom file when the plugins like flatten-maven-plugin /
maven-shade-plugin produces pomFile in different directory other than
the base directory
## Expected Behavior
plugin should only update the pom file and not the base directory
location
## Related Issue(s)
Fixes#34181https://github.com/mojohaus/flatten-maven-plugin/issues/50
Co-authored-by: anurag.ag <anuragagarwal561994@users.noreply.github.com>
## Current Behavior
Technology introduction pages have inconsistent or missing version
requirements information. Some pages have no Requirements section,
others use ad-hoc formats (asides, bullet lists under Prerequisites),
and page titles follow different naming conventions ("Overview of the Nx
X Plugin", "Nx X Plugin Overview", "Introduction - X", etc.).
## Expected Behavior
Every technology introduction page now has a standardized Requirements
section with:
- A version support table using consistent semver range format
- Code-formatted package names in the `Package` column
- An intro sentence identifying the Nx plugin (e.g. "The `@nx/react`
plugin supports the following package versions.")
- A note linking to [code generation docs](/docs/features/generate-code)
for auto-installed packages
- Consistent **"X Plugin for Nx"** page title pattern across all intro
pages
Additional changes:
- Deleted the standalone Node.js/TypeScript compatibility page, inlining
its content into the respective plugin intro pages
- Created a proper introduction page for Angular Rsbuild (previously
linked directly to `createConfig` API reference)
- Added Requirements tables to Java, Gradle, and Maven pages with system
dependency versions
- Updated sidebar links and redirects for removed/moved pages
- Applied style guide fixes across all edited pages (removed "allows you
to", "easily", product possessives, etc.)
## Related Issue(s)
Fixes DOC-423
## Current Behavior
After #34580, `determineNxCloudV2()` returns `'skip'` in non-interactive
mode, but the caller remaps it to `nxCloud = 'yes'` with
`skipCloudConnect = true`. This causes `setupCI()` to run and generate
`.github/workflows/ci.yml` in new workspaces — which didn't happen
before.
This breaks the `extras.test.ts` e2e snapshot test because
`.github/workflows/ci.yml` now appears in the expanded default task
inputs.
## Expected Behavior
Keep `nxCloud = 'skip'` when the cloud choice is `'skip'`, which
prevents CI file generation in non-interactive mode. This restores the
behavior prior to #34580.
## Related Issue(s)
Fixes the `extras.test.ts` e2e snapshot failure introduced by #34580.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Bump project graph plugin version.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Current Behavior
`build_glob_set` recompiles identical glob pattern sets on every call,
even when the same set of patterns has been compiled before.
## Expected Behavior
Compiled `NxGlobSet` instances are cached in a static `DashMap` keyed by
sorted glob strings. Repeated calls with the same patterns return a
shared `Arc<NxGlobSet>` instead of recompiling. Profiling `nx run-many
-t build lint test --parallel 8` in the Nx repo measured 95.6% cache hit
rate (9,758 of 10,202 calls) with only 444 unique pattern sets, reducing
hashing-phase CPU by ~40%.
## Current Behavior
All 1,200+ redirect rules are processed by the Next.js serverless
function via the `redirects()` config in `next.config.js`. Every
redirect request requires a cold start of the serverless function, which
contributed to the 10-minute outage reported in DOC-415.
## Expected Behavior
Redirects are handled at the Netlify CDN edge via a plain `_redirects`
file, which is faster and doesn't depend on the Next.js serverless
function being healthy.
- Converted all redirect rules from `redirect-rules.js` and
`redirect-rules-docs-to-astro.js` into Netlify `_redirects` format
(1,231 rules)
- Expanded Next.js regex group patterns (e.g. `/(l|latest)/...`) into
individual Netlify rules since Netlify doesn't support regex
- Converted `:path*` wildcards to Netlify `*`/`:splat` syntax
- Rewrites (Astro docs proxy) remain in `next.config.js` as they require
server-side processing
- Original JS redirect files kept for reference (can be removed in
follow-up)
## Related Issue(s)
Fixes DOC-415
## Current Behavior
`TargetProjectLocator.findProjectFromImport` stores `null` for
unresolved imports using a bare `importExpr` key, but
`findNpmProjectFromImport` looks up cache entries using
`${packageName}__${dirPath}`. The key mismatch means repeated lookups
for the same import+directory re-run the full resolution waterfall
(typescript + require.resolve) instead of returning the cached `null`.
## Expected Behavior
Store `null` for unresolved imports using the same
`${packageName}__${dirPath}` key that `findNpmProjectFromImport` uses
for lookups. Repeated lookups for already-failed imports skip the
expensive resolution steps.
Also removes an unused cache write for builtin module imports as a minor
cleanup.
## Current Behavior
After migrating from chalk to picocolors (#34305), `FORCE_COLOR=0` no
longer disables colors. picocolors checks `!!env.FORCE_COLOR`, and since
`!!"0"` is `true` in JavaScript, it treats `FORCE_COLOR=0` as "enable
colors."
This breaks CI environments and tools like Homebrew that set
`FORCE_COLOR=0` to get plain text output.
## Expected Behavior
`FORCE_COLOR=0` should disable ANSI color output, matching the previous
chalk behavior and the [FORCE_COLOR spec](https://force-color.org/).
## Related Issue(s)
Fixes#34387
Upstream issue filed:
https://github.com/alexeyraspopov/picocolors/issues/100
## Current Behavior
When processing Gradle tasks, Nx tracks dependent task output files by
recording individual file paths for each output. This can lead to
incorrect cache invalidation behavior since we are prefixing the paths
unnecessarily. We will therefore never match.
## Expected Behavior
Nx now consolidates dependent task output files using glob patterns
based on file extensions (e.g., **/*.jar, **/*.class). This focuses on
the types of files produced rather than their specific paths. The
approach groups all output files by extension and generates a single
glob pattern per extension, reducing the complexity of input tracking
while maintaining correctness.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #Q-247
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The dependsOn of atomized tasks should match the base non-atomized task.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes Q-174
## Current Behavior
The CNW cloud prompt is locked to auto-select deferred connection
(CLOUD-4255), always generating a short URL but never writing nxCloudId
to nx.json. Users have no explicit choice.
## Expected Behavior
The cloud prompt now offers three explicit choices:
- Yes: connect now, generate nxCloudId in nx.json, show strong
completion message
- Skip for now: deferred connection (no nxCloudId), still show short URL
and update README
- No: full opt-out, set neverConnectToCloud: true in nx.json, no URL, no
README update, no cloud messaging
**CLI args:** `--nxCloud=skip`, `--nxCloud=never` (new),
`--nxCloud=yes`. Non-interactive defaults to skip.
Closes CLOUD-4242
## Current Behavior
PR #34523 fixed the macOS file watcher issue (#34522) but did not
include comprehensive test coverage.
## Expected Behavior
Tests should verify that the fix works correctly and catch any future
regressions.
## Related Issue(s)
Adds test coverage for #34523 and #34522
---
## Changes
**TypeScript integration test**
(`packages/nx/src/native/tests/watcher.spec.ts`):
Added **"should detect file changes in large directory structures"** - a
comprehensive integration test that:
1. Creates 10,000+ directories simulating a monorepo-scale workspace
2. Starts a real `Watcher` instance
3. Creates and modifies files deep in the directory tree
4. Verifies that file change events are actually delivered
This test validates the actual behavior users care about - that file
watching works reliably in large repos - rather than testing
implementation details. It would catch any regression where events fail
to be delivered at scale.
## Testing
TypeScript integration test validates the actual bug fix - that file
events are delivered reliably in large directory structures with 10,000+
directories.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Given the following Vite config:
```ts
import { defineConfig } from 'vite';
export default defineConfig((config) => {
console.log(config);
return {};
});
```
`npx nx preview` logs:
```ts
{
mode: 'development',
command: 'build',
isSsrBuild: false,
isPreview: false
}
```
## Expected Behavior
`npx nx preview` should log:
```ts
{
mode: 'development',
command: 'build',
isSsrBuild: false,
isPreview: true
}
```
## Related Issue(s)
https://github.com/vitejs/vite/issues/15694
Fixes #
## Current Behavior
`BatchProcess` accumulates all stdout/stderr output in
`terminalOutputChunks` and exposes it via `getTerminalOutput()`, but
nothing ever calls `getTerminalOutput()`. The accumulated strings are
unique allocations (created via `chunk.toString()`), not shared with the
output callbacks or `process.stdout.write`.
For verbose batched tasks (e.g., Maven/Gradle with hundreds of tasks),
this can hold tens to hundreds of MB for the entire batch duration.
## Expected Behavior
Remove the dead accumulation code. stdout/stderr chunks are still
forwarded to `process.stdout`/`process.stderr` and output callbacks as
before — only the unused storage is removed.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
When generating a library with vitest as the test runner and a non-vite
bundler (e.g. `tsc`), the js library generator creates two config files:
- `vitest.config.mts` (from the vitest `configurationGenerator`) with
`root: __dirname`
- `vite.config.ts` (from a second `createOrEditViteConfig` call) with
`root: import.meta.dirname`
The redundant `vite.config.ts` uses ESM-only `import.meta.dirname`
syntax, which causes TS1470 when the project targets CommonJS output:
```
vite.config.ts:5:9 - error TS1470: The 'import.meta' meta-property is not allowed in files which will build into CommonJS output.
5 root: import.meta.dirname,
~~~~~~~~~~~
```
## Expected Behavior
Only `vitest.config.mts` should be generated. The vitest
`configurationGenerator` already handles creating the correct config
file with `root: __dirname`. The second `createOrEditViteConfig` call
from `@nx/vite` was redundant and produced the conflicting file.
## Related Issue(s)
Fixes#34399
## Current Behavior
Since Nx 22.5.0, the daemon's native file watcher silently drops all
file change events on macOS in large monorepos (~5,250+ watched
directories). `nx watch`, `nx serve`, and any daemon-dependent file
watching is broken.
The root cause is that #34329 switched all watched paths to
`WatchedPath::non_recursive()`. On macOS, the `notify` crate uses
**kqueue** for non-recursive watches instead of **FSEvents**. kqueue
silently fails at scale due to vnode table pressure (`kern.num_vnodes ==
kern.maxvnodes`), causing the daemon to never detect file changes.
This is a **scale-dependent** bug: it works fine in small workspaces
(~30 directories) but breaks silently in large ones.
| | **Nx 22.4.5** | **Nx 22.5.0+** |
|---|---|---|
| **Small repo (~30 dirs)** | Works (FSEvents) | Works (~30 kqueue
watches) |
| **Large repo (~5,250+ dirs)** | Works (FSEvents) | **Broken** (kqueue
silently drops all events) |
## Expected Behavior
The macOS file watcher should detect file creates, modifications, and
deletions at any scale, matching the behavior of Nx 22.4.x.
## Fix
Use platform-conditional watch modes:
- **macOS:** Single recursive watch on the workspace root (uses FSEvents
natively)
- **Linux/Windows:** Non-recursive per-directory watches (preserves the
#33781 inotify fix)
On macOS, FSEvents handles recursive watching from a single root path,
so directory enumeration and dynamic registration are skipped entirely.
This also improves daemon startup time on macOS from ~10 minutes to <1
second in a 354-project monorepo.
### What changed in `watcher.rs`
1. **Initial pathset:** On macOS, watch only the root directory
recursively via FSEvents instead of enumerating all directories for
non-recursive kqueue watches.
2. **Dynamic directory registration (`on_action`):** Wrapped in
`#[cfg(not(target_os = "macos"))]` since FSEvents already watches the
full tree.
Linux/Windows behavior is completely unchanged.
### Why the event filter is fine as-is
We verified that with recursive FSEvents watches, macOS emits specific
`FileEventKind` variants (`Create(File)`, `Modify(Data(Content))`,
`Remove(File)`, `Modify(Name(Any))`) that the current
`watch_filterer.rs` already handles correctly. Zero events were rejected
by the catch-all. The `Modify(Any)` / `Create(Any)` variants are kqueue
artifacts that are not needed with FSEvents.
### Why kqueue fails silently
Apple's [File System Events Programming
Guide](https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/FSEvents_ProgGuide/KernelQueues/KernelQueues.html)
explicitly recommends FSEvents over kqueue for large hierarchies: *"If
you are monitoring a large hierarchy of content, you should use file
system events instead."* kqueue requires `open(path, O_EVTONLY)` per
watched directory. Under vnode table pressure, the kernel recycles
vnodes with kqueue watches attached without notifying the watcher. There
is no error, no partial delivery, and no diagnostic signal.
## Tested on
- macOS 26.3 (Tahoe), Apple Silicon (arm64), APFS
- 354-project pnpm monorepo (~19,865 non-ignored directories)
- Verified: file modifications, file creates, and file deletes all
detected
- Daemon init time: ~10 min (with enumeration) -> <1s (with root-only
FSEvents watch)
## Related Issue(s)
Fixes#34522
Co-authored-by: Amp <amp@ampcode.com>
## Current Behavior
When nx release runs with docker-configured projects (either via
explicit config or
@nx/docker plugin inference), git tags are created with the literal
string {version}
instead of the actual version number (e.g., v{version} instead of
v1.0.6, or
app-3@{version} instead of app-3@1.0.0).
This happens because:
1. If ANY project in a release group has docker config,
preferDockerVersion is auto-set to
true for the ENTIRE group
2. createGitTagValues() then blindly selects
projectVersionData.dockerVersion, which is
null for non-docker projects (or projects with no changes)
3. The interpolate() function receives null for {version} and returns
the literal
placeholder unchanged
Commit messages are unaffected because createCommitMessageValues() only
uses newVersion and
already guards against null. The changelog code (changelog.ts:1117-1121)
also already has
the correct null-safe pattern.
## Expected Behavior
When preferDockerVersion is true but dockerVersion is null, git tags
should fall back to
using newVersion instead of producing literal {version} placeholders.
When both versions
are null, no tag should be created.
For mixed release groups (some projects have docker config, some don't),
the auto-enable
logic should use 'both' mode instead of true, which already has proper
null-safe checks for
each version type.
## Changes
- shared.ts: Added null-safe fallback (??) in createGitTagValues() for
both independent and
fixed group code paths, plus a guard to skip tag creation when both
versions are null
- config.ts: Refined auto-enable logic to check whether ALL or only SOME
projects have
docker config — mixed groups now get 'both' mode instead of true
- shared.spec.ts: Added 5 test cases covering null version fallback
scenarios for fixed
groups, independent groups, both-null, reverse fallback, and mixed
groups
## Related Issue(s)
Fixes#34382Fixes#33890Fixes#34391
## Current Behavior
The "7. Thriving Community" section on
`nx.dev/docs/guides/adopting-nx/from-turborepo` displayed an outdated Nx
download statistic (~5 million downloads per week).
## Expected Behavior
The "7. Thriving Community" section on
`nx.dev/docs/guides/adopting-nx/from-turborepo` now reflects the latest
Nx download statistic (~9 million downloads per week).
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: MaxKless <MaxKless@users.noreply.github.com>
When we optimized the `process.env` values to not embed the full object
unnecessarily, we also regressed in cases where users do use
`process.env` instead of `process.env["NX_PUBLIC_FOO"]`.
## Current behavior
Users cannot use `process.env` and must access each key individuall.
Although the serializing the full object can bloat bundle sizes, we also
don't want to break existing apps unnecessarily.
## Expected behavior
Existing apps should continue to work as usual.
## Related issues
Fixes#34279
## Current Behavior
When running `@nx/js:prune-lockfile` on a monorepo with transitive
dependencies that have multiple versions where neither version is
reachable from a direct dependency in package.json, the executor throws:
```
NX An error occurred while creating pruned lockfile
Original error: Cannot read properties of undefined (reading 'name')
TypeError: Cannot read properties of undefined (reading 'name')
at switchNodeToHoisted (node_modules/nx/src/plugins/js/lock-file/project-graph-pruning.js:165:31)
```
## Expected Behavior
The lockfile pruning should complete without crashing, even when some
transitive dependencies cannot be traced back to a direct dependency.
## Root Cause
In `rehoistNodes()`, when there are multiple nested nodes for a package,
the code finds the "closest" node by computing `pathLengthToIncoming()`
for each. However, when none of the nested nodes have a path to any
direct dependency in package.json, `pathLengthToIncoming()` returns
`undefined` for all of them. Since `undefined < Infinity` is `false` in
JavaScript, `closest` remains `undefined`, and then
`switchNodeToHoisted(undefined, ...)` crashes.
## Fix
Add a guard to only call `switchNodeToHoisted()` when a closest node was
actually found:
```typescript
if (closest) {
switchNodeToHoisted(closest, builder, invBuilder);
}
```
This allows the pruning to continue - the nested nodes simply won't be
rehoisted if no closest node can be determined.
## Related Issue
Fixes#34322
## Test Added
Added a unit test that verifies `rehoistNodes()` doesn't crash when
nested nodes have no path to package.json dependencies.
## Current Behavior
When importing a `package.json` file in an Angular application built
with `@nx/angular-rspack`, the build fails with a Babel syntax error if
the `package.json` contains `@angular/*` dependencies:
```
SyntaxError: /path/to/package.json: Missing semicolon. (2:10)
1 | {
> 2 | "name": "@org/app",
| ^
3 | "version": "4.0.2",
4 | "dependencies": {
5 | "@angular/platform-browser": "20.3.7",
```
This happens because the `JS_ALL_EXT_REGEX` pattern
`/\.[cm]?(js)[^x]?\??/` incorrectly matches `.json` files. When the JSON
file content contains `@angular` strings, the
`angular-partial-transform-loader` attempts to process it through Babel,
which fails because JSON is not valid JavaScript.
**Root cause:** The regex `[^x]?` (optional character that is NOT 'x')
allows `.json` to match because 'o' is not 'x'.
## Expected Behavior
- `.json` files should NOT match `JS_ALL_EXT_REGEX` or
`TS_ALL_EXT_REGEX`
- Importing `package.json` in Angular applications should work correctly
- All existing matches for `.js`, `.jsx`, `.mjs`, `.cjs` (and TypeScript
equivalents) should continue to work
## Related Issue(s)
https://github.com/nrwl/nx/issues/32649
## Current Behavior
Documentation bugfix on
https://nx.dev/docs/concepts/typescript-project-linking#set-up-typescript-project-references
In the section about setting up TypeScript project references, the
documentation currently states:
"Each project's tsconfig.lib.json file extends the project's
tsconfig.json file and adds references to the tsconfig.lib.json files of
project dependencies."
## Expected Behavior
In a standard Nx workspace configuration, tsconfig.lib.json extends the
workspace-level tsconfig.base.json, not the project-level tsconfig.json
(and the example provided just after is correct).
Suggested correction:
"Each project's tsconfig.lib.json file extends the workspace
tsconfig.base.json file and adds references to the tsconfig.lib.json
files of project dependencies."
## Related Issue(s)
Fixes #34118
---------
Co-authored-by: Aude Planchamp <aude.planchamp@ekino.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
When a plugin worker process exits unexpectedly, the exit handler
previously sent synthetic `loadResult` messages to all pending response
handlers. If any handler was waiting for a different result type (e.g.
`createNodesResult`), the type validation would reject with a confusing
"Expected createNodesResult, got loadResult" error instead of surfacing
the actual cause.
Split response handlers into `onMessage` / `onError` callbacks so the
exit handler can reject each pending promise directly with a clear
"Plugin worker exited unexpectedly" error.
Also use unique transaction IDs for `load` messages (via `generateTxId`)
to avoid potential handler overwrites during worker restarts.
Fixes#34564
## Summary
Testing CI behavior with continuous assignment disabled and cache bust
set to 4.
This is part of investigating flakiness potentially related to
continuous assignment in CI.
## Test plan
- Monitor CI execution behavior
- Compare with other test branches (bust=2, bust=3)
## Current Behavior
Documentation pages across Getting Started, How Nx Works, and Platform
Features sections contain:
1. Duplicated content — mental-model.mdoc has a ~70-line caching section
and a ~20-line DTE section that are near-verbatim
copies of how-caching-works.mdoc and distribute-task-execution.mdoc
respectively. remote-cache.mdoc re-explains local caching
in its intro instead of linking to the canonical page.
2. Missing cross-reference links — Key concepts like "affected command",
"remote cache", "project graph", and "task pipeline
configuration" are mentioned without linking to their dedicated pages.
3. Style guide violations — Trust-undermining words ("simply", "just",
"straightforward"), anti-AI phrases ("Let's take",
"Whether you're..."), product possessives ("Nx's"), customer perspective
issues ("allows you to"), and em dashes appear
across Getting Started and How Nx Works pages.
## Expected Behavior
1. Content consolidation — mental-model.mdoc is trimmed by ~85 lines,
keeping the concept + images and linking to dedicated
pages for details. remote-cache.mdoc intro references the canonical
caching page. publish-conformance-rules-to-nx-cloud.mdoc
deduplicates its intro. maintain-typescript-monorepos.mdoc shortens its
inferred tasks re-explanation.
2. Cross-reference links added — First-mention links for affected,
remote cache, computation caching, task pipeline
configuration (in mental-model) and project graph (in self-healing-ci).
3. Style guide compliance — 18 fixes across 10 Getting Started and How
Nx Works pages, removing banned phrases and aligning
with the new STYLE_GUIDE.md.
4. Sidebar improvements — Cache Task Results added after Run Tasks in
Platform Features; Maintain TypeScript Monorepos moved
to first in KB > TypeScript.
## Pages changed
```
┌─────────────────┬─────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Section │ Pages │
├─────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Getting Started │ intro, index, nx-cloud, ai-setup, start-with-existing-project │
├─────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────┤
│ How Nx Works │ mental-model, how-caching-works, task-pipeline-configuration, nx-plugins, nx-daemon │
├─────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Features │ remote-cache, self-healing-ci, maintain-typescript-monorepos, cache-task-results (sidebar only) │
├─────────────────┼─────────────────────────────────────────────────────────────────────────────────────────────────┤
│ Enterprise │ publish-conformance-rules-to-nx-cloud │
└─────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────┘
```
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
### 1. Continuous tasks missing from `postTasksExecution` hook
When running continuous tasks (e.g., `nx serve app`) and stopping them
with Ctrl+C, the `postTasksExecution` lifecycle hook does not include
them in `taskResults`. This breaks plugins that rely on post-run
statistics (e.g., uploading task stats to DataDog).
### 2. Confusing TUI status when sibling continuous task exits
When multiple continuous tasks run together and one exits unexpectedly,
its sibling is marked as "failed" even though it was intentionally
terminated/stopped by the task orchestrator.
## Expected Behavior
1. All tasks, including continuous ones, are included in `taskResults`
for the `postTasksExecution` hook
2. Continuous tasks that are intentionally stopped (because dependent
tasks completed or during graceful shutdown) report as `success` with
`Stopped` display status
3. Continuous tasks that exit unexpectedly (crash) report as `failure`
4. TUI summary shows correct status: success when all tasks completed
successfully, square icon for stopped tasks
## Related Issue(s)
Fixes https://github.com/nrwl/nx/issues/33561
Supersedes:
- https://github.com/nrwl/nx/pull/33562
- https://github.com/nrwl/nx/pull/34132
Add NX_CLOUD_IO_TRACING_DIRECTORY environment variable.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes Q-245
## Current Behavior
No documentation exists explaining the concept of synthetic monorepos —
how they bridge polyrepo and monorepo setups by connecting separate
repositories into a unified dependency graph.
https://deploy-preview-34565--nx-docs.netlify.app/docs/concepts/synthetic-monorepos
## Expected Behavior
New concept page under "How Nx Works" that explains:
- What synthetic monorepos are (unified graph across separate repos
without moving code)
- Why they matter for humans (visibility, cross-repo coordination) and
AI agents (seeing beyond repo boundaries)
- What they provide (cross-repo graph, actionable tooling, AI agent
enablement)
- How they serve as a gradual entry point toward deeper monorepo
adoption
## Related Issue(s)
N/A — new documentation page based on existing content from webinars and
internal knowledge.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: juristr <juristr@users.noreply.github.com>
## Current Behavior
When users hit the `generatePackageJson: true` error with TS Solution
Setup, the error tells them to "unset the option" but gives no guidance
on the replacement workflow.
## Expected Behavior
The error message now includes a link to the pruning guide at
https://nx.dev/docs/technologies/node/guides/deploying-node-projects so
users can immediately find the migration steps.
## Related Issue(s)
Related #30146
When plugin isolation is off, concurrent createNodesV2 invocations share
the same module instance. The module-level mutable `cache` variable
caused
invocation A's `finally` block to null it out while invocation B was
still
reading from it, resulting in "Cannot read properties of null (reading
'configContexts')".
Replace the shared mutable `cache` with a Symbol-keyed Map so each
invocation gets its own isolated cache. The tsconfig disk cache is
shared
across invocations with an idempotent initialization guard.
CLOSES NXC-3971
## Summary
- Updated version of the classic "Misconceptions about Monorepos"
article
- New sections on AI compatibility, scaling strategies (affected,
caching, distribution, atomization), and `@nx/owners`
- Custom SVG diagrams for project graph illustrations (replacing old
Medium images)
- Authors: Victor Savkin, Juri Strumpflohner
## Test plan
- [ ] Verify blog post renders correctly on preview
- [ ] Check all images load (SVGs + avif)
- [ ] Verify internal doc links resolve
- [ ] Check TOC renders properly
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: juristr <juristr@users.noreply.github.com>
## Current Behavior
folks had to type in `nx-cloud apply-locally`
## Expected Behavior
now `nx apply-locally` works
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
### Current Behavior
nx list <plugin> shows generator/executor names and descriptions in text
format only. It does not show where the plugin or its
generators/executors are located on disk, and there is no
machine-readable output option.
### Expected Behavior
- nx list --json outputs all local and installed plugins with their
paths and capability types
- nx list <plugin> --json outputs detailed structured JSON including
resolved paths to each generator/executor implementation and schema
- nx list <plugin> (text mode) now also shows the plugin's root path
## Current Behavior
In TS Solution Setup, the esbuild executor forces `runTypeCheck` even
when `skipTypeCheck: true` and `declaration: false`, due to the `||
options.isTsSolutionSetup` condition in `esbuild.impl.ts` (lines 139-140
and 195).
When `declaration: false`, this type check runs in `noEmit` mode with
`ignoreDiagnostics: true` — making it **completely pointless** (no
declarations emitted, no diagnostics reported). Its only observable
effect is writing a poisoned 19-byte tsbuildinfo file that causes race
conditions with `tsc --build`.
## Expected Behavior
When `skipTypeCheck: true` and `declaration: false`, the esbuild
executor should not run type checking at all. The `isTsSolutionSetup`
override should only force type checking when declarations actually need
to be generated.
## Fix
### Primary: Skip unnecessary type check (`esbuild.impl.ts`)
```diff
// Non-watch mode (line 195)
- if (!options.skipTypeCheck || options.isTsSolutionSetup) {
+ if (!options.skipTypeCheck || (options.isTsSolutionSetup && options.declaration)) {
// Watch mode (lines 139-140)
- options.isTsSolutionSetup
+ (options.isTsSolutionSetup && options.declaration)
```
Only force type checking in TS Solution Setup when declarations need to
be generated. This eliminates the pointless type check entirely.
### Defense-in-depth: Prevent tsbuildinfo in `noEmit` mode
(`run-type-check.ts`)
```diff
- : { noEmit: true };
+ : { noEmit: true, composite: false };
```
Setting `composite: false` alongside `noEmit: true` prevents TypeScript
from writing tsbuildinfo files, protecting against this class of bug
from any caller of `runTypeCheck`.
## Why This is Safe
| Scenario | Before | After |
|----------|--------|-------|
| `skipTypeCheck: false`, `declaration: false`, `isTsSolutionSetup:
true` | Runs type check (noEmit) | Still runs (`!false \|\| ...` = true)
|
| `skipTypeCheck: false`, `declaration: true`, `isTsSolutionSetup: true`
| Runs type check (emitDeclarationOnly) | Still runs |
| `skipTypeCheck: true`, `declaration: true`, `isTsSolutionSetup: true`
| normalize.ts overrides skipTypeCheck to false; runs type check | Still
runs (same normalization) |
| **`skipTypeCheck: true`, `declaration: false`, `isTsSolutionSetup:
true`** | **Runs pointless type check (noEmit + ignoreDiagnostics),
writes poisoned tsbuildinfo** | **Skipped entirely** |
The only behavior change is in the last row — the case where the type
check was doing nothing useful but causing harm.
## Related Issue(s)
Fixes#34492
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
## Current Behavior
Users migrating to Nx 20's TS Solution Setup lose `generatePackageJson`
support and have no documentation on the replacement prune workflow
(`prune-lockfile`, `copy-workspace-modules`). The error message tells
them to "unset the option" but doesn't explain what to do instead.
## Expected Behavior
A dedicated guide at
`/docs/technologies/node/guides/deploying-node-projects` covers the full
prune workflow: when to use pruning vs bundling, target configuration,
Dockerfile setup, and step-by-step migration from `generatePackageJson`.
Also updated the existing bundling guide to match the same structure
(intro table, cross-links, style guide compliance). The two articles are
sister guides covering the two ways to deploy Node.js apps: bundle
everything into a single file, or prune dependencies for a
`node_modules`-based install.
Cross-links added from the bundling guide and ci-deployment guide.
## Related Issue(s)
Closes#30146
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
## Current Behavior
The `checkAllBranchesWhen` option is documented as type `string` with a
minimal description, which does not match the actual implementation.
## Expected Behavior
Document the correct type (`boolean | string[]`) and explain the default
branch resolution behavior, the three value modes (true, false,
string[]), and when this option is useful.
## Related Issue(s)
Closes DOC-414
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
## Current Behavior
When multiple Nx processes (task hasher, daemon, workers) access the
SQLite database concurrently, the `NxDbConnection::transaction()` method
only retries the BEGIN step using the `retry_db_operation_when_busy!`
macro. Operations executed inside the transaction and the COMMIT are not
retried, so if the database is busy during those steps, the task crashes
with:
```
Error: DB transaction operation error: SqliteFailure(Error { code: DatabaseBusy, extended_code: 5 }, Some("database is locked"))
```
This is particularly common during parallel task hashing with continuous
tasks, where `TaskDetails.recordTaskDetails()` and `RunningTasksService`
compete for write access.
## Expected Behavior
The entire transaction (begin, execute, commit) is retried as a single
unit when any step encounters a `DatabaseBusy` error. If the database is
busy during the operation or commit, the transaction is automatically
rolled back (via drop) and retried with the same exponential backoff
used everywhere else.
## Related Issue(s)
<!-- No public issue linked -->
## Current Behavior
The NPM audit CI job is failing due to a critical XSS vulnerability
(CVE-2026-25896) in `fast-xml-parser` version 4.5.3.
## Expected Behavior
The NPM audit should pass with no critical vulnerabilities.
## Related Issue(s)
Fixes the failing NPM audit CI run:
https://github.com/nrwl/nx/actions/runs/22288455713
---
This PR upgrades `fast-xml-parser` from `^4.2.7` to `^5.3.7` to address
GHSA-m7jm-9gc2-mpf2, a critical XSS vulnerability that allows entity
encoding bypass via regex injection in DOCTYPE entity names.
The package is only used in
`scripts/documentation/internal-link-checker.ts` for parsing XML
sitemaps, so the risk of this upgrade is low.
## Current Behavior
Batch mode is binary:
- `--batch` flag → batch ALL executors that support it
- No flag → batch NOTHING
This means users of gradle/maven must always remember to pass `--batch`
to get the performance benefits.
## Expected Behavior
Plugin authors can now set `preferBatch: true` in their executor config
to indicate batch mode should be used by default. Users can still
opt-out with `--no-batch`.
Three states:
- `--batch` → batch everything
- `--no-batch` → batch nothing
- (not specified) → use each executor's `preferBatch` preference
| `--batch` flag | `preferBatch` | Result |
|----------------|---------------|--------|
| `true` | any | Batch |
| `false` | any | No batch |
| not set | `true` | Batch |
| not set | `false`/undefined | No batch |
## Changes
- Added `preferBatch?: boolean` to `ExecutorJsonEntryConfig` and
`ExecutorConfig` interfaces
- Updated `--batch` default from `false` to `undefined` to allow
`preferBatch` to decide
- Modified batch scheduling logic to respect `preferBatch`
- Enabled `preferBatch: true` for gradle and maven executors
- Added 5 unit tests covering all `preferBatch` scenarios
## Related Issue(s)
<!-- Link any related issues here -->
PR #30826 introduced a fallback definition for `process.env`:
```ts
{ 'process.env': '{}' }
```
Since `DefinePlugin` performs raw textual replacement, this can generate
invalid JavaScript when user code accesses environment variables via dot
notation:
```ts
process.env.SOME_KEY
```
becomes:
```js
{}.SOME_KEY
```
`{}` is parsed as a block statement (not an object literal), resulting
in:
> Unexpected token: punc (.)
This PR updates the fallback to a parenthesized object literal:
```ts
{ 'process.env': '({})' }
```
which produces valid output:
```js
({}).SOME_KEY
```
This preserves the intended bundle-size optimization while ensuring
syntactically correct output for standard `process.env.X` access
patterns.
## Related Issue(s)
Refs #30826Fixes#34460
//CC @Coly010 @coolassassin
## Current Behavior
`nx import` relies on interactive prompts (enquirer) and spinners (ora)
for user interaction. AI agents cannot parse this output or respond to
prompts, making `nx import` unusable in agent workflows.
## Expected Behavior
When `isAiAgent()` is true, `nx import` now:
- Skips all interactive prompts and spinners
- Emits NDJSON progress to stdout (`starting`, `cloning`, `filtering`,
`merging`, `detecting-plugins`, `complete`)
- Returns structured `needs_input` when required args are missing (all
at once to minimize round-trips)
- Returns structured `needs_input` for plugin selection when `--plugins`
flag is not provided
- Returns structured success/error results with hints and next steps
- Supports new `--plugins` flag (`skip`/`all`/comma-separated list)
Shared AI output types extracted from `init` into
`packages/nx/src/command-line/ai/ai-output.ts` for reuse across
commands.
## Current Behavior
Running `configure-ai-agents` overwrites the entire `source` object in
`extraKnownMarketplaces['nx-claude-plugins']`, removing any user-added
properties like `ref`.
## Expected Behavior
User-added source properties (e.g. `ref`) are preserved, while `source`
and `repo` are always set to the correct values.
The nx-welcome component inline styles were always using CSS/SCSS syntax
(with braces and semicolons) regardless of the selected style option.
When --style=sass is chosen, the component now correctly uses SASS
indented syntax (no braces or semicolons) matching the expected
behavior for the .sass file format.
Fixes#33489
## Current Behavior
When `configure-ai-agents` is invoked from within an AI agent (e.g.
Claude Code), it either shows an interactive multi-select prompt (which
the agent can't interact with) or requires `--agents` and
`--no-interactive` flags to work correctly. This makes the experience
awkward when AI agents call the command as part of workspace setup.
## Expected Behavior
When an AI agent is detected (via environment variables like
`CLAUDECODE`), the command now:
1. **Auto-configures the detected agent** if it's not yet configured,
partially configured, or outdated — no prompts needed
2. **Auto-updates any other outdated agents** alongside the detected one
3. **Reports non-configured agents** with a suggested `nx
configure-ai-agents --agents ...` command
4. **Reports up-to-date status** if the detected agent is already fully
configured
When `--agents` is explicitly passed, detection is ignored entirely
(existing behavior preserved). `--check` mode also works with detection
— it checks the detected agent plus all other configured agents.
Additionally:
- Strips AI agent detection env vars (`CLAUDECODE`, `CLAUDE_CODE`,
`OPENCODE`, `GEMINI_CLI`, etc.) from e2e subprocess environments to
prevent the test runner's environment from leaking into tests
- Fixes e2e tests to use `AGENTS.md` (not `GEMINI.md`) for gemini
assertions, matching what the gemini generator actually creates for
fresh installations
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
- Cypress `start-dev-server.ts` file creates a port lock file next to
the source code
- Native temp DB files created by tests are not properly ignored
- Astro config timestamp file is not ignored
These all trigger watch file change events, which cause the project
graph to be recomputed unnecessarily.
## Expected Behavior
Output files should not trigger watch file change events. The project
graph should not be recomputed unnecessarily.
## Current Behavior
Several Nx packages directly depend on a minimatch version with a
high-severity vulnerability
(https://github.com/advisories/GHSA-3ppc-4f35-3m26).
## Expected Behavior
Several Nx packages should depend directly on a minimatch version that
does not include the reported high-severity vulnerability.
Note: unsafe `minimatch` versions can still be pulled in transitively.
Upstream deps need to be updated, and then we need to update the Nx
packages to newer versions.
## Related Issue(s)
Fixes#34507
---------
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
## Current Behavior
Users specifying directory paths in `inputs` without a trailing slash or
glob pattern find that files are not matched. For example,
`{projectRoot}/src` does not match any files, while `outputs` allows
naked directory paths without issue.
## Expected Behavior
Documentation clearly explains that directory paths in `inputs` require
a trailing slash or glob pattern:
```jsonc
{
"inputs": [
"{projectRoot}/src/", // ✓ Works (trailing slash)
"{projectRoot}/src/**/*", // ✓ Works (glob pattern)
"{projectRoot}/src" // ✗ Does NOT work
]
}
```
### Changes
- **Reference doc** (`reference/inputs.mdoc`): Added "Directory Paths"
section explaining the requirement with examples
- **Guide** (`configure-inputs.mdoc`): Added callout warning at top
alerting users to this behavior
- Both docs note the difference from `outputs`, which do support naked
directory paths
## Related Issue(s)
Fixes
https://linear.app/nxdev/issue/NXC-2102/clarify-trailing-slash-requirement-for-inputs-in-directory-paths
Co-authored-by: Steven Nance <steven@nrwl.io>
## Current Behavior
When creating a new workspace using `create-nx-workspace` with the
"custom" preset flow, an `nxCloudId` is generated and added to
`nx.json`. This happens even though the onboarding flow is supposed to
handle Cloud setup separately via a short URL.
## Expected Behavior
New workspaces created via `create-nx-workspace` should not have
`nxCloudId` set in `nx.json`. Instead, a short URL is provided for users
to finish Cloud onboarding on their own. The `nxCloud: 'skip'` option is
now passed for the custom flow to prevent the ID from being generated.
E2E tests are updated to verify that `nxCloudId` is undefined in the
generated `nx.json` across all workspace presets.
## Related Issue(s)
N/A - internal fix for workspace creation behavior.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
`--help` on commands that hit yargs help are hanging
## Expected Behavior
It doesn't hang. This contains a quick fix in adding the process.exit
call, but also adds the unref needed to maintain previous working
behavior. We'll need to investigate long term if additional areas keep
commands alive, but adding this unref theoretically allows removing the
process.exit calls from `nx show`
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
## Current Behavior
14 e2e test suites were disabled (`xdescribe`) due to an ESM import
issue in `@microsoft/api-extractor@7.57.0` (see
https://github.com/qmhc/unplugin-dts/issues/461).
## Expected Behavior
With the upstream issue resolved, all 14 e2e test suites are re-enabled
(`describe`) and should pass normally.
## Related Issue(s)
Reverts #34516
## Current Behavior
Running `nx test` for Next.js projects causes Jest to hang with:
```
Jest did not exit one second after the test run has completed.
```
This happens because `next/jest` loads `next.config.js`, which calls
`withNx` → `createProjectGraphAsync()`. The daemon client socket
connection is left open, keeping the Node.js event loop alive and
preventing Jest from exiting. Non-Next.js projects are unaffected since
they don't trigger this code path.
## Expected Behavior
Jest exits cleanly after tests complete for Next.js projects, without
needing `forceExit: true`.
## Fix
Pass `resetDaemonClient: true` to `createProjectGraphAsync()` in
`packages/next/plugins/with-nx.ts`. This tells the project graph
function to call `daemonClient.reset()` after fetching the graph, which
closes the socket and allows Jest to exit.
### Verification
| Scenario | Before | After |
|----------|--------|-------|
| `nx test next-app` | Hangs | Exits cleanly |
| `NX_DAEMON=false nx test next-app` | Exits cleanly | Exits cleanly |
| Direct `npx jest` | Exits cleanly | Exits cleanly |
| Non-Next.js `nx test react-lib` | Exits cleanly | Exits cleanly |
## Related Issue(s)
Fixes#32880
## Current Behavior
The Maven plugin is on version `0.0.13`.
## Expected Behavior
The Maven plugin is bumped to version `0.0.14`, with a migration
generated for Nx `22.6.0-beta.1`.
## Current Behavior
Agents are silent and hard to diagnose
## Expected Behavior
Agents should print debug logs without making all of Nx print debug logs
## Current Behavior
14 e2e tests are failing across master with "Failed to process project
graph" errors. The root cause is `@microsoft/api-extractor@7.57.0` which
has a broken ESM export (`ConsoleMessageId`). When `@nx/vite/plugin` or
`@nx/vitest` plugins load `vite.config.mts` files, they transitively
import api-extractor which crashes.
## Expected Behavior
Broken e2e tests are disabled via `xdescribe` so they no longer block
CI. Tests should be re-enabled once the upstream api-extractor ESM issue
is fixed.
## Disabled Tests
| Project | Test File |
|---------|-----------|
| e2e-vite | `vite.test.ts`, `vite-legacy.test.ts`,
`vite-ts-solution.test.ts` |
| e2e-vue | `vue.test.ts`, `vue-legacy.test.ts`,
`vue-ts-solution.test.ts` |
| e2e-js | `js-ts-solution.test.ts` |
| e2e-web | `web-vite.test.ts` |
| e2e-react | `react-vite.test.ts`, `react-ts-solution.test.ts` |
| e2e-next | `next-ts-solutions.test.ts` |
| e2e-release | `release-publishable-libraries.test.ts`,
`release-publishable-libraries-ts-solution.test.ts` |
| e2e-storybook | `storybook-nested.test.ts` |
## Related Issue(s)
Upstream: https://github.com/qmhc/unplugin-dts/issues/461
## Current Behavior
The `maven-shade-plugin` at version 3.5.0 intermittently fails on CI
with:
```
Could not replace original artifact with shaded artifact!
```
This is a file-locking race condition where the plugin fails to
atomically replace the original JAR with the shaded JAR.
## Expected Behavior
Upgrading to 3.6.0 resolves the intermittent CI failures by using
improved file-handling logic with better retry behavior during the
artifact replacement step.
## Related Issue(s)
N/A - fixes intermittent CI flakiness in `maven-batch-runner` builds.
Closes#19779
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
## Current Behavior
When targeting Windows the resulting binary (nx.dll) dynamically links
against Microsoft Visual C++ runtime (msvcrt140.dll). This means nx
won't be able to run on Windows systems without this runtime installed.
## Expected Behavior
I'd like to avoid this dependency by linking the runtime statically into
the nx binary. (This is also how e.g. cargo.exe for Windows is built.)
## Related Issue(s)
Fixes#19779
---------
Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
## Current Behavior
Terminal output in the task runner is accumulated via repeated string
concatenation (`terminalOutput += chunk`). Each `+=` on a growing string
causes V8 to allocate a new, larger string and copy the old contents,
resulting in O(n²) allocation behavior for tasks with large output.
Additionally, `PseudoTtyProcess.onExit` didn't pass `terminalOutput` to
its callbacks, forcing callers like `TaskOrchestrator` to duplicate
output accumulation logic with a separate `onOutput` listener.
## Expected Behavior
- Terminal output is collected in `string[]` arrays and joined once at
the end, reducing intermediate allocations from O(n²) to O(n)
- `PseudoTtyProcess.onExit` now passes `terminalOutput` as a second
argument, matching the signature of other `RunningTask` implementations
- `TaskOrchestrator` no longer needs a special code path for
`PseudoTtyProcess` — unified `onExit` handling for all task types
- `tui-summary-life-cycle` accumulates output in chunks during execution
and stores the finalized string on task completion, allowing chunk
arrays to be GC'd
- `SeriallyRunningTasks` and `RunningNodeProcess` similarly switched to
chunk-based accumulation
- `BatchProcess` and `NodeChildProcessWithNonDirectOutput` lazily join
and cache their terminal output
Work on making a tech intro pages more consistent with each other and
focus on "answering the 80%" for the given technology.
Focusing on
- Angular
- Maven/Gradle
- react
- TS
- Vite
- Vitest/Jest
The changes are based around answering the following, where each
"category" of page might have a different set of depth for the answer.
1. Why do I want to use this plugin?
- Plugins are considered fully optional and are aimed at providing
better DX for a technology, such as inferred setup, generators,
migrations.
- some plugins (like TSC) might have special call outs in some of this,
but generally the same for all plugins.
2. How do I use this plugin in my workspace?
- also pretty commonly the "same" for all plugins in terms of "setup"
- where they differ is mostly for frameworks, e.g. Angular, React.
You're looking at setting up a project to use these tools
- For Build/Test tools you're looking at adding to an existing project,
or converting from one to another.
- Build/Test tools are "means to an end", so should callout if the goal
is tool + framework in a "new" context point to the framework based
plugin page. Otherwise, show adding to an existing project like React
project.
3. What do I need to know about using this plugin?
- understanding finer details of a plugin options, e.g. buildable &
publishable
- extra generators for the plugin. e.g. "convert-to-swc"
- generally I like the idea of having a "CI considerations" where we
talk about CI setups that can help, e.g. options or batch mode etc.
closes DOC-407
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: barbados-clemens <barbados-clemens@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
navigation of the breadcrumbs could lead to confusing state since they
were based around the folder structure.
Breadcrumbs are now based around the sidebar structure so they match the
hierarchy of content.
Note: I left the existing index file based route pages in place in case
there are any links people have booked marked/linked to in other
locations. these will get cleaned up when we finally rewrite all the
URLs to their new content locations
## Current Behavior
When file changes arrive rapidly, the daemon triggers multiple
concurrent project graph recomputations that all run to completion —
wasting CPU/memory on redundant work and returning stale results.
Additionally, after processing file changes, the daemon clears all
tracked files indiscriminately. Files that changed mid-recomputation are
silently lost and never reflected in the project graph until another
unrelated file change arrives.
## Expected Behavior
Stale recomputations detect when a newer one has started and exit early,
chaining to the newer promise so callers always get the freshest result.
File change tracking now uses versioned maps. Each batch of file watcher
events gets a unique version, and only files matching the snapshotted
version are cleared after processing. Files that changed
mid-recomputation are preserved and picked up by the next cycle.
## Current Behavior
Two categories of e2e CI failures were observed in run
https://github.com/nrwl/nx/actions/runs/22127884259:
1. **`e2e-nx-init` and `e2e-js` fail on Node 22.12.0** with:
```
error eslint-visitor-keys@5.0.0: The engine "node" is incompatible with
this module.
Expected version "^20.19.0 || ^22.13.0 || >=24". Got "22.12.0"
```
Node 22.12.0 is one minor version short of the `^22.13.0` range required
by `eslint-visitor-keys@5.0.0`.
2. **`e2e-nx` tests fail because `[isolated-plugin]` / `[plugin-worker]`
verbose messages leak into captured stdout**, causing:
- `JSON.parse(runCLI('show project --json'))` to throw `SyntaxError:
Unexpected token 'i', "[isolated-p"...`
- `expect(runCLI('show projects')).toEqual('')` to fail with worker
spawn noise
- The `@nx/workspace:infer-targets` test to unexpectedly find
`@nx/remix` in output (from a worker spawn message)
Root cause: in `isolated-plugin.ts`, the plugin worker's stdout was
piped directly to `process.stdout`, so `[plugin-worker]` verbose
messages written by the worker ended up in the stdout captured by
`runCLI` in e2e tests.
## Expected Behavior
1. The CI matrix uses a Node 22.x version that satisfies `^22.13.0`.
2. Plugin worker verbose/diagnostic messages go to `process.stderr` (not
`process.stdout`), so they don't contaminate output captured by `runCLI`
in e2e tests. Both worker stdout and stderr now pipe to
`process.stderr`, and the max listener bump is consolidated to `+2` on
stderr.
## Related Issue(s)
N/A — identified from CI run
https://github.com/nrwl/nx/actions/runs/22127884259
## Current Behavior
When running in maven 4 batch mode, the build state is recorded only
after the full batch is done.
This means that nx caching records the state of a task before build
state is recorded to disk.
When running another maven task that depends on this partially recorded
cache, the build state file is missing and we get errors.
## Expected Behavior
build state should be recorded after every task is done and before nx
caching can kick in. This way we can ensure that nx cache is correct.
---------
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Current Behavior
When running generators or migrations, Nx automatically skips Prettier
formatting if no root Prettier config is detected (added in #30426).
However, there's no way to explicitly skip Prettier formatting when a
config IS present but the user wants to bypass it for specific
operations.
This can be needed when:
- When running something like Oxfmt that may treat prettier slightly
differently, even with the same config (this is the main thing I ran
into)
- Running migrations where Prettier reformatting causes unintended side
effects (e.g., breaking `eslint-disable` comments)
- Temporarily disabling formatting for debugging purposes
- Using a formatter that coexists with Prettier in the workspace but
should take precedence for certain files
## Expected Behavior
Users can set `NX_SKIP_FORMAT=true` to explicitly skip Prettier
formatting in generators and migrations, regardless of whether Prettier
is configured. TSConfig path sorting (controlled by
`sortRootTsconfigPaths` or `NX_FORMAT_SORT_TSCONFIG_PATHS`) continues to
work independently.
```bash
NX_SKIP_FORMAT=true nx migrate --run-migrations
NX_SKIP_FORMAT=true nx g @nx/react:app my-app
```
## Related Issue(s)
Related to #30403 and #30426. This enhancement adds explicit user
control for cases where auto-detection of Prettier configuration isn't
sufficient.
## Current Behavior
When publish fails due to missing OTP code, its not clear as a user who
is using the top level command what to do next.
## Expected Behavior
Add the --otp flag to the top-level `nx release` command so users can
provide a one-time password for 2FA-enabled registries when running the
full release orchestration (version + changelog + publish).
When publish fails due to an expired or missing OTP (EOTP error),
display a helpful warning listing affected projects and the exact
command to re-run the publish step in isolation with a new OTP.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Codex has only basic MCP/AGENTS.md support right now. Also, because it
used to have only global-level config files, we had some extra logic
around configuring that.
We want Codex to get the latest skills too (they don't support custom
subagents yet, though) and use project-level config files that they now
support.
After running nx build (or any task), the daemon now shows a hint if
your AI agent configuration is outdated: "Your AI agent configuration is
outdated. Run nx configure-ai-agents to update."
The daemon computes and caches the full agent configuration status
(fully configured, outdated, partially configured, non-configured) using
latest Nx from npm, so the check is always against the newest available
configuration. Running nx configure-ai-agents resets the daemon's cache
so the message disappears on the next build.
Key changes
- Daemon agent status endpoint: New GET_CONFIGURE_AI_AGENTS_STATUS /
RESET_CONFIGURE_AI_AGENTS_STATUS message types. The handler fires off
computation in the background and returns immediately (never blocks the
request). Results are cached for the daemon's lifetime.
- Shared latest-nx module: Extracted the "install nx@latest to tmp"
logic from nx-console-operations into daemon/server/latest-nx.ts so both
Nx Console and AI agents handlers share a single cached installation.
Includes a race-condition guard (in-flight promise deduplication).
- Post-task outdated hint: run-command.ts queries the daemon after task
execution and prints a single dim line if agents are outdated.
- Daemon reset from configure-ai-agents: The CLI sets NX_DAEMON=false
for configure-ai-agents, so we bypass daemonClient.enabled() and use
isServerAvailable() directly to reach an already-running daemon. The
socket is closed in a finally block so the process exits cleanly.
- Async editor detection (Rust): Made isEditorInstalled,
canInstallNxConsoleForEditor, installNxConsole, and related napi
functions async so they run on the libuv thread pool instead of blocking
Node's event loop. This prevents the daemon from stalling for ~3.5s when
checking editor extensions.
- output.logRawLine: New helper that prints a single line without the NX
prefix.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
We want to minimize prompts for people and agents. But we also want to
help them by setting up nx config for them so their agents can work
optimally.
If they're executing `nx init` or `create-nx-workspace` from within an
agent, it's a reasonable assumption that they'll want the best AI config
for that specific agent - so we set it up for them.
## Current Behavior
The `nx watch` file watcher uses the `ignore-files` and
`watchexec-filterer-ignore` crates to handle `.gitignore` matching.
These crates use a trie-based approach that has a bug with
path-component matching — certain gitignore patterns (e.g., prefix
patterns) don't match correctly, causing files that should be ignored to
trigger unnecessary watch events.
## Expected Behavior
Gitignore patterns are matched correctly using per-directory `Gitignore`
instances from the `ignore` crate — the same crate already used by the
file walker. Each `.gitignore` file is scoped to its directory, and
matching is done deepest-first so that nested gitignores take priority —
matching standard git behavior.
### What changed
- Replaced `ignore-files` + `watchexec-filterer-ignore` with direct use
of `ignore::gitignore::{Gitignore, GitignoreBuilder}`, aligning the
watcher with the approach already used by the file walker
- Each `.gitignore` is now compiled as a standalone instance tied to its
parent directory
- Gitignore evaluation walks deepest-first; first match wins
- `.nxignore` matching now uses `matched_path_or_any_parents` for
correct ancestor checking
- `create_filter` is now synchronous (no longer `async`) since the new
approach doesn't need async I/O
- Removed 2 crate dependencies (`ignore-files`,
`watchexec-filterer-ignore`)
## Current Behavior
When a project-level `tsconfig.json` (e.g., `apps/aurora/tsconfig.json`)
inherits `paths` via `extends` from `tsconfig.base.json` at the
workspace root and no explicit `baseUrl` is set, Nx incorrectly resolves
`./`-prefixed path mappings relative to the project tsconfig directory
instead of the workspace root where the paths were defined.
This causes errors when loading TypeScript config files (e.g.,
`rspack.config.ts`) that import workspace libraries using path aliases:
NX Cannot find module './libs/plugins/rspack/src'
`@swc-node/register`'s `readDefaultTsConfig` auto-sets `baseUrl` to
`dirname(tsConfigPath)` (the project directory) when not explicitly
configured, causing SWC to rewrite imports to incorrect relative paths
during transpilation.
## Expected Behavior
Path aliases defined in `tsconfig.base.json` (e.g.,
`"@trellis/plugins/rspack": ["./libs/plugins/rspack/src/index.ts"]`)
should resolve relative to the workspace root when no `baseUrl` is
configured.
This is needed so that when using `tsgo` and needing to prefix all paths
with `./` (no more `baseUrl` allowed) the paths are still resolved from
the right spot.
I tested this fix against our codebase on the branch I was trying to
switch to tsgo on and it seemed to work.
## Related Issue(s)
Fixes
https://discord.com/channels/1143497901675401286/1471627045694865581
## Current Behavior
CONTRIBUTING.md contains an outdated "How to Get Started Video" section
and references Stack Overflow for general questions.
## Expected Behavior
Remove outdated video section and point users to the Discord community
instead of Stack Overflow for general questions.
## Related Issue(s)
N/A
When switching from inline mode to full-screen TUI (or during window
resize), the PTY resize operation reparsed ALL raw terminal output
through a new vt100 parser synchronously on the event loop. For tasks
with large output, this caused a noticeable hang.
Add `resize_async()` which moves the expensive reparse to a background
thread using a snapshot-and-replay pattern:
1. Quick snapshot of raw output (brief read lock)
2. Expensive reparse on background thread (no locks held)
3. Quick swap with replay of any new output (brief write lock)
A generation counter prevents stale resizes from overwriting newer ones.
Also combine two separate O(n) scrollback processing calls in inline
mode into a single pass.
## Current Behavior
Copyright year shows 2017-2025 and README uses older tagline.
## Expected Behavior
Copyright reflects current year 2026 and README uses updated repository
description.
## Changes
- **LICENSE**: Updated copyright year from `2017-2025` to `2017-2026`
- **README.md**: Replaced heading and description
- New heading: "The Monorepo Platform that amplifies both developers and
AI agents. Nx optimizes your builds, scales your CI, and fixes failed
PRs automatically. Ship in half the time."
- Removed redundant description line below heading
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
> ## Update License and README
>
> Please make the following changes:
>
> 1. **Update LICENSE file**: Change the copyright year from `2017-2025`
to `2017-2026`
> - File: `LICENSE`
> - Line 3: Update `Copyright (c) 2017-2025 Narwhal Technologies Inc.`
to `Copyright (c) 2017-2026 Narwhal Technologies Inc.`
>
> 2. **Update README.md description**: Replace the current description
with the repository's official description
> - File: `README.md`
> - Line 22: Change the heading from `# Smart Monorepos · Fast Builds`
to `# The Monorepo Platform that amplifies both developers and AI
agents. Nx optimizes your builds, scales your CI, and fixes failed PRs
automatically. Ship in half the time.`
> - Line 24: Remove the current description line: `Get to green PRs in
half the time. Nx optimizes your builds, scales your CI, and fixes
failed PRs. Built for developers and AI agents.`
>
> The new README should have the repository description as the main
heading, followed immediately by the "Create a new Nx workspace with"
section.
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
*This pull request was created from Copilot chat.*
>
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: FrozenPandaz <8104246+FrozenPandaz@users.noreply.github.com>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
## Current Behavior
`tui_logger::init_logger()` and `TuiTracingSubscriberLayer` are
initialized unconditionally in `initialize_logger()`. This spawns a
background thread, causing unnecessary allocation churn and increased
processing.
## Expected Behavior
`tui_logger` is only initialized when `NX_TUI=true`, avoiding the
background thread and allocation overhead for all non-TUI contexts.
## Current Behavior
We have ~1,657 redirect rules across `redirect-rules.js` and
`redirect-rules-docs-to-astro.js`, getting close to Netlify's limit and
we need room for more as the Astro migration continues.
## Expected Behavior
Reduced to **1,139 rules** (~31% reduction) by:
- Resolving duplicate/conflicting source paths across sections
- Flattening multi-hop redirect chains to point directly to final
destinations
- Consolidating groups of individual rules into wildcard patterns
(tutorials, CLI, helm, concepts, recipes, etc.)
- Removing old 2022-era sections (`schemaUrls`, `overviewUrls`,
`packagesIndexes`, `packagesDocuments`) whose destinations chain 3-5
hops deep and are long superseded by newer redirects
- made sure old links in nx code base still have redirects (will update
in future PR)
Build, tests, and internal link check all pass with no issues.
## Related Issue(s)
Fixes DOC-403
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: barbados-clemens <barbados-clemens@users.noreply.github.com>
## Current Behavior
When AI agents (Claude Code, Cursor, Windsurf, etc.) run `nx init`, the
command works but:
- Uses interactive prompts that AI agents can't handle
- Outputs human-readable text that AI agents must parse
- Doesn't provide structured progress or error information
## Expected Behavior
When `nx init` detects an AI agent (via environment variables like
`CLAUDE_CODE=1`), it should:
- Skip interactive prompts and use sensible defaults
- Output structured NDJSON for progress updates, success, and errors
- Include detailed context for AI agents to understand and fix issues
## Changes
This PR adds agentic mode to `nx init`:
### `nx init` Changes
- Detect AI agents via `isAiAgent()` native function
- Auto-defaults: `interactive=false`, `nxCloud=false`, auto-detect `.nx`
installation
- NDJSON output with `type: progress|success|error`
- Error logs written to `.nx/ai-errors/` with full context
- Cursor restoration escape sequence skipped for AI agents (prevents
NDJSON corruption)
### Output Format
```jsonl
{"type":"progress","step":"starting","message":"Initializing Nx..."}
{"type":"success","nxVersion":"22.5.0","projectsDetected":1,"pluginsInstalled":["@nx/vite"]}
```
Or on error:
```jsonl
{"type":"error","message":"Failed to install","code":"INSTALL_ERROR","errorLogPath":".nx/ai-errors/nx-init-error-2025-01-15T10-30-00.log"}
```
## Current Behavior
we pull from latest all the time even if the current version is already
latest
## Expected Behavior
we can skip this extra work sometimes
## Current Behavior
Pages proxied from Framer contain canonical URLs pointing to the Framer
domain (`ready-knowledge-238309.framer.app`), causing duplicate indexing
issues in search engines.
## Expected Behavior
Canonical URLs and other references in Framer-proxied pages now point to
`nx.dev`, ensuring proper SEO indexing.
### Implementation
Consolidated all Framer logic into a single Netlify edge function
(`rewrite-framer-urls.ts`) that:
1. Checks if the request path matches a Framer-proxied path (using
`FRAMER_REWRITES` env var)
2. Fetches directly from Framer (using `FRAMER_URL` env var)
3. Rewrites all Framer URLs to `nx.dev` in the HTML response (handles
`<link rel="canonical">`, `og:url`, etc.)
4. For non-Framer paths, passes through to Next.js
The edge function uses the `accept: ['text/html']` config to only run on
HTML requests, matching the pattern from `track-page-requests.ts` in
astro-docs.
The Next.js middleware has been removed since all Framer routing is now
handled by the edge function.
### Environment Variables
The edge function expects these env vars in Netlify (already added
previously):
- `NEXT_PUBLIC_FRAMER_URL`: e.g.,
`https://ready-knowledge-238309.framer.app`
- `NEXT_PUBLIC_FRAMER_REWRITES`: comma-separated list of paths, e.g.,
`/pricing,/enterprise`
## Demo
1. Go to https://deploy-preview-34445--nx-dev.netlify.app/
2. View source and look for canonical
3. See it is nx.dev not framer domain
<img width="1347" height="161" alt="image"
src="https://github.com/user-attachments/assets/d4a515da-e39f-41cb-a7b4-668fe0bedbbd"
/>
## Related Issue(s)
Closes CLOUD-4148
## Current Behavior
The `release` function returned by `createAPI` has a return type of
`Promise<NxReleaseVersionResult | number>`. The `| number` union member
is inaccurate since the function always returns
`NxReleaseVersionResult`, which can mislead consumers of the
programmatic API.
## Expected Behavior
The return type is narrowed to `Promise<NxReleaseVersionResult>`,
accurately reflecting what the function actually returns and giving API
consumers correct type information.
Co-authored-by: Andreas Hörnicke <andreas.hoernicke@contentful.com>
Blog post draft about the evolution from MCP tools to agent skills.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: MaxKless <MaxKless@users.noreply.github.com>
Co-authored-by: Juri Strumpflohner <juri.strumpflohner@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
`^` and `dependencies: true` only work for fileset inputs
## Expected Behavior
Adds support for inputs of the form `^{projectRoot}/**/*.ts` as
syntactic sugar for specifying a fileset input that should be collected
from dependency projects.
Previously, only named inputs could use the `^` prefix to include
dependencies (e.g., `^production`). Now filesets can also use this
syntax directly without needing to define a named input first.
Examples:
- `^{projectRoot}/**/*.ts` - include .ts files from all dependencies
- `^{workspaceRoot}/tools/**/*` - include workspace tools from
dependencies
- `{ fileset: '{projectRoot}/**/*.ts', dependencies: true }` - object
form
Detection is deterministic: if the string after `^` starts with
`{projectRoot}` or `{workspaceRoot}`, it's treated as a dependency
fileset; otherwise, it's treated as a named input reference.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
- In some `nx run-many` executions, terminal output can appear staggered
or visually misaligned instead of updating cleanly in place.
- For `run-many` cases that end up running a single task (especially
when TUI is not active), the spinner/status line can be rendered twice.
## Expected Behavior
- Dynamic terminal output updates should remain stable and aligned, with
clean in-place refreshes.
- Single-task `run-many` should display a single spinner/status line
with no duplicate rendering.
Add uncaughtException handler for ERR_USE_AFTER_CLOSE to prevent
ugly stack trace when pressing Ctrl+C during enquirer prompts
(Node 24 stricter readline behavior). Matches existing pattern
used in nx init and create-nx-workspace.
## Current Behavior
The publish workflow uses `sudo npm install -g npm@11.5.2` which was
added in #34409. This causes issues with OIDC token permissions in the
release pipeline since `sudo` runs as a different user context.
## Expected Behavior
The publish workflow should use `npm install -g npm@11.5.2` without
`sudo`, matching the standard approach used elsewhere and avoiding
permission context issues during release.
## Related Issue(s)
Reverts #34409
## Current Behavior
The publish workflow uses `addnab/docker-run-action@v3` which is based
on `docker:20.10` (Docker API 1.41). GitHub's `ubuntu-24.04` runners now
ship Docker Engine 28.x which requires minimum API version 1.44, causing
all 4 Linux Docker builds to fail:
```
docker: Error response from daemon: client version 1.41 is too old. Minimum supported API version is 1.44, please upgrade your client to a newer version.
```
Failed run: https://github.com/nrwl/nx/actions/runs/21961139962
## Expected Behavior
Linux Docker builds (x86_64-gnu, x86_64-musl, aarch64-gnu, aarch64-musl)
complete successfully using the host's modern Docker CLI.
https://github.com/nrwl/nx/actions/runs/21996143819
## Related Issue(s)
The `addnab/docker-run-action` repo is abandoned (last release March
2021, last commit May 2021) with open issues about this exact problem.
## Current Behavior
There's a chance that windows can falsely flag our native binaries as a
threat. We do not use the shellapi feature from winapi.
## Expected Behavior
We hope that removing this API doesn't break things, and the threat
messaging goes away
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #https://github.com/nrwl/nx/issues/34186
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Pressing `[1]` or `[2]` on a task that's already pinned to that slot
**focuses** the pane instead of unpinning it. This means there's no way
to unpin a single pane via keyboard — you can only nuke everything with
`[0]`.
This regression was introduced in #34175, which fixed a real problem:
pressing Enter on an already-pinned task would unpin it, leaving focus
on an invisible pane (a ghost pane — you're staring at nothing but the
TUI thinks you're looking at output). The fix was to make the "already
pinned to this pane" branch focus instead of unpin. The problem is that
`[1]`, `[2]`, and Enter all flowed through the same function
(`assign_current_task_to_pane`), so changing behavior for Enter changed
it for everyone. One lock got swapped out, and every door started
behaving the same way.
## Expected Behavior
`[1]` and `[2]` are **toggles**: press once to pin, press again to
unpin. Enter is a **display** action: show me this task's output and put
my cursor there — if it's already visible somewhere, just take me to it.
After this change:
- **`[1]` / `[2]`** on an already-pinned task → unpins it (pane
disappears, layout adjusts, focus returns to task list if no panes
remain)
- **Enter** on an already-pinned task → focuses whichever pane it's in
(even if it's in pane 2 and you'd normally expect pane 1)
- **Init** (startup restore of pinned tasks) → pure assignment, no
toggling, no focusing
## Approach
The old code had one function trying to serve three masters. Rather than
adding a flag parameter (`should_toggle: bool`) — which would just be a
boolean that lies about its intentions at every call site — the function
was split along the actual semantic boundaries:
| Function | Used by | "Already pinned here" behavior |
|---|---|---|
| `toggle_current_task_in_pane` | `[1]` / `[2]` keys | **Unpin** (toggle
off) |
| `assign_current_task_to_pane` | `init()` | No-op (task is where it
should be) |
| `display_and_focus_current_task_in_terminal_pane` | Enter key |
**Focus** the existing pane |
The shared logic — exiting spacebar mode, moving a task between panes,
fresh-pinning — lives in two small helpers (`exit_spacebar_and_pin`,
`move_or_pin_selection`) that both `toggle` and `assign` delegate to.
The only code that differs is the "what do we do when it's already
here?" branch, which is exactly the part that *should* differ.
**Why not keep one function with a mode parameter?** Because the three
behaviors aren't variations of the same action — they're genuinely
different user intents. A toggle is "I changed my mind." A focus is
"Take me there." An assignment is "Put this here." Encoding that as an
enum parameter just moves the branching somewhere less obvious and makes
the call sites harder to read. The function names now document the
intent at the point of use, and there's no shared state to accidentally
couple.
**Why does Enter check all panes, not just pane 0?** Because if you
pinned a task to pane 2 via `[2]` and then press Enter on it, the least
surprising thing is to jump to where it already lives — not to silently
duplicate it into pane 1 or ignore you. The task is already on screen;
Enter means "show me."
## Related Issue(s)
Fixes the regression introduced by #34175.
## Current Behavior
CNW (Create Nx Workspace) has A/B testing logic that randomly selects
between variants 0, 1, and 2 for the Nx Cloud connection flow. Each
variant shows different prompts and banners.
## Expected Behavior
Lock in variant 2 as the permanent behavior:
- **No cloud prompt** - users are not asked about Nx Cloud during
workspace creation
- **Deferred connection** - no `nxCloudId` is written to `nx.json` (uses
`skipCloudConnect: true`)
- **Variant 2 banner** - shows "Enable remote caching and automatic
fixes when CI fails" with a link to complete setup later
### Changes
- Simplified `ab-testing.ts` - removed caching, random selection;
`getFlowVariant()` always returns `'2'`
- `shouldShowCloudPrompt()` always returns `false`
- `determineNxCloudV2()` returns `'github'` with `skipCloudConnect:
true` for deferred connection
- Removed variant 1 banner logic from `messages.ts`
- Updated tests to reflect the locked-in behavior
## Demo
https://www.loom.com/share/7f688eed6052428cbe91dd9db837cbbd
## Related Issue(s)
Closes CLOUD-4255
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Simplified form targeting by replacing the global `reactHubspotForm` ID
with a deterministic `targetId` that incorporates portal, form, and
calendly IDs. This improves scalability and avoids potential ID
collisions.
## Current Behavior
When banner content changes in Framer, the nx-docs and nx-dev sites need
to be manually redeployed to pick up the new content.
## Expected Behavior
A scheduled workflow monitors the banner URL every 15 minutes and
automatically triggers Netlify production deploys when content changes.
## How it works
1. Fetches `BANNER_URL` content (from repository variable)
2. Computes SHA256 hash
3. Compares to cached hash from previous run
4. If different → triggers both Netlify deploys, updates cache
5. If unchanged → no-op
## Required Setup
1. **Repository variable** (`Settings → Secrets and variables → Actions
→ Variables`):
- `BANNER_URL` = Framer banner API URL
2. **Repository secret** (`Settings → Secrets and variables → Actions →
Secrets`):
- `NETLIFY_AUTH_TOKEN` = Netlify personal access token
## Related Issue(s)
Fixes DOC-405
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Negation patterns are ignored in plugin configuration for the `include`
and `exclude` properties.
## Expected Behavior
- Negation patterns should work in the same way that they do for other
`include`/`exclude` configurations
**Example: Excluding all e2e projects except one**
```jsonc
// nx.json
{
"plugins": [
{
"plugin": "@nx/jest/plugin",
"exclude": ["**/*-e2e/**/*", "!**/toolkit-workspace-e2e/**/*"],
},
],
}
```
This will exclude all e2e projects except `toolkit-workspace-e2e`.
**Example: Including packages except legacy ones**
```jsonc
// nx.json
{
"plugins": [
{
"plugin": "@nx/vite/plugin",
"include": ["packages/**/*", "!packages/legacy/**/*"],
},
],
}
```
**How negation patterns work:**
- Patterns are processed in order from first to last
- A pattern starting with `!` removes files from the match set
- A pattern without `!` adds files to the match set
- The last matching pattern determines if a file is included
- If the first pattern is a negation, all files are matched initially
---------
Co-authored-by: Claude Sonnet 4.5 <noreply@anthropic.com>
## Current Behavior
There is currently no plugin.md file for Gradle.
Other plugin.md files can be improved
## Expected Behavior
Add plugin.md file for Gradle to aid with verification with Agents.
Add plugin.md file for Vite for workspaces that have not migrated to
@nx/vitest.
## Related Issue(s)
CLOSES NXC-3843
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
The Playwright executor does not support configuring a custom cache
directory for Playwright's internal cache (browser binaries, etc.).
Users who need to control where Playwright stores its cache, for example
in CI environments with specific disk constraints like not being able to
DTE tasks or shared caching setups, have no way to set this through the
executor configuration.
## Expected Behavior
A new `cacheDir` option is available on the Playwright executor. When
provided, it sets the `PWTEST_CACHE_DIR` environment variable on the
forked Playwright process, allowing users to control where Playwright
stores its internal cache.
```json
{
"targets": {
"e2e": {
"executor": "@nx/playwright:playwright",
"options": {
"cacheDir": "/tmp/playwright-cache"
}
}
}
}
```
## Related Issue(s)
Replaces #34397
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Current Behavior
The SECURITY.md file does not clarify what types of reports should be
sent to the security email, leading to reports about outdated
dependencies and vulnerability scanner output.
## Expected Behavior
The file now clarifies that the security email is for demonstrable,
verified vulnerabilities in the Nx codebase itself, not for:
- Outdated dependency reports
- Dependencies with CVEs that don't directly affect Nx
- General vulnerability scanner output
## Related Issue(s)
Fixes NXC-3898
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
The `npm install -g npm@11.5.2` step in the publish workflow fails with
`EACCES: permission denied, mkdir '/usr/local/share/man/man5'` on newer
GitHub Actions runner images.
## Expected Behavior
The global npm install step completes successfully regardless of runner
image permissions on `/usr/local/share/man/`.
## Related Issue(s)
This is a known issue with GitHub Actions runners:
https://github.com/actions/runner-images/issues/9644
Add isSandbox() utility that checks for sandbox environment variables
(SANDBOX_RUNTIME, GEMINI_SANDBOX, CODEX_SANDBOX, CURSOR_SANDBOX) and
use it to disable the daemon and plugin isolation in sandbox
environments.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: meeroslav <meeroslav@users.noreply.github.com>
## Current Behavior
Running ai agents in sandbox mode causes issues with Nx's daemon and
plugin isolation
## Expected Behavior
Running ai agents in sandbox mode should work
## Related Issue(s)
CLOSES NXA-828
## Current Behavior
We do not include NxVersion when creating short urls.
## Expected Behavior
Include NxVersion when creating short urls.
## Related Issue(s)
CLOSES NXC-3879
When cache outputs include both glob patterns and directory patterns
containing symlinks, the cache restore fails with EEXIST (os error 17).
This happens because `fs_extra::remove_items` silently skips dangling
symlinks (since `is_dir()`/`is_file()` follow links and return false),
leaving stale symlinks that cause `symlink()` to fail.
The fix makes symlink creation idempotent by checking for and removing
any existing symlink at the destination before creating a new one, using
`symlink_metadata()` which correctly detects dangling symlinks.
Fixes#34013
## Current Behavior
The Maven plugin's `createNodes` and `createDependencies` functions both
independently compute a hash of all pom.xml directories, then use that
hash to look up cached Maven analysis data from disk. When Maven
projects have `<includes>` or `<excludes>` in their plugin config, the
hash can differ between the two calls, causing `createDependencies` to
fail to find the data that `createNodes` stored.
## Expected Behavior
`createDependencies` reliably receives the Maven analysis data from
`createNodes` regardless of hash differences, by reading it from a
module-level variable instead of re-hashing and looking it up from disk.
This matches the pattern already used by the Gradle plugin
(`getCurrentGradleReport`).
## Related Issue(s)
## Current Behavior
Runtime cache keys could be nondeterministic because the order of
environment variables varied, leading to inconsistent cache hits across
runs.
## Expected Behavior
Runtime cache keys are deterministic regardless of the insertion order
of env variables, improving cache stability.
## Current Behavior
Cycles in the task graph could remove unrelated `continuousDependencies`
when the cycle exists only in `dependencies`, leading to missing
continuous task edges.
## Expected Behavior
Cycle removal only removes the specific cyclic edge from the list where
it appears, preserving unrelated continuous dependencies.
## Current Behavior
When running Nx tasks in CI environments (e.g., Buildkite) where the
host's /tmp is mounted to containers, intermittent EADDRINUSE errors
occur in PseudoIPCServer.init(). This happens because:
1. PseudoIPCServer doesn't clean up its Unix socket file before calling
listen()
2. ForkedProcessTaskRunner.createPseudoTerminal() instantiates
PseudoTerminal directly instead of using the createPseudoTerminal()
helper, bypassing shutdown callback registration
When a new container starts with the same PID as a previous run (PID
recycling), it generates the same socket path and hits EADDRINUSE
because the stale socket file still exists.
## Expected Behavior
No EADDRINUSE errors should occur. The PseudoIPCServer should
defensively remove any stale socket file before attempting to listen,
similar to how the daemon server handles this.
## Related Issue(s)
Fixes#34233
Streamlined analytics tracking by removing Cookiebot and direct GA
(gtag.js) integrations. Consolidated event logging through GTM's
dataLayer for consistency and maintenance simplicity.
## Current Behavior
Batch IDs are generated in two places: the task scheduler uses an
incremental counter (`executorName N`) while the forked process task
runner generates its own using the process PID (`executorName-pid`).
This means the batch ID registered in metrics doesn't match the one used
everywhere else.
## Expected Behavior
Batch IDs are only created by the task scheduler. The forked process
task runner uses the scheduler-assigned ID to ensure consistency across
the system.
## Current Behavior
right now if users modify their mcp params like `--minimal`, we will
override them on `configure-ai-agents`
## Expected Behavior
We want to bring users up to latest without overriding their valid
configurations
## Current Behavior
The Bun package manager config uses `--frozen-lockfile` for
`updateLockFile`:
```typescript
updateLockFile: 'bun install --frozen-lockfile',
```
However, `--frozen-lockfile` **prevents** changes to the lockfile,
causing `nx release` to fail when trying to update the lockfile after
version bumps.
## Expected Behavior
Use `--lockfile-only` which generates/updates the lockfile without
installing dependencies:
```typescript
updateLockFile: 'bun install --lockfile-only',
```
This is consistent with other package managers:
- npm: `npm install --package-lock-only`
- pnpm: `pnpm install --lockfile-only`
- yarn berry: `yarn install --mode update-lockfile`
## Background
When Bun support was added in PR #22602 (April 2024), `--lockfile-only`
didn't exist in Bun. Bun has since added this flag.
Closes#34344
Co-authored-by: Kai Gritun <kai@kaigritun.com>
## Current Behavior
Several GitHub Actions workflows hardcode pnpm version `10.11.1`, while
`package.json` specifies `pnpm@10.28.2` in the `packageManager` field.
This causes CI failures with:
```
Error: Multiple versions of pnpm specified:
- version 10.11.1 in the GitHub Action config with the key "version"
- version pnpm@10.28.2 in the package.json with the key "packageManager"
```
## Expected Behavior
All pnpm version references across CI workflows should match the
`packageManager` field in `package.json` (`10.28.2`).
## Related Issue(s)
N/A — Fixing CI breakage from version mismatch.
## Changes
Updated pnpm version from `10.11.1` → `10.28.2` in:
- `.github/workflows/npm-audit.yml` — `pnpm/action-setup` version
- `.github/workflows/publish.yml` — `PNPM_VERSION` env var and FreeBSD
install
- `.github/workflows/issue-notifier.yml` — `pnpm/action-setup` version
- `.github/workflows/generate-embeddings.yml` — `pnpm/action-setup`
version
## Current Behavior
The Windows build (`aarch64-pc-windows-msvc`) fails to compile with:
```
error[E0433]: failed to resolve: use of undeclared type `FileType`
--> packages\nx\src\native\watch\types.rs:128:55
```
The `FileType` type is used inside a `#[cfg(target_os = "windows")]`
block but was not imported.
## Expected Behavior
The Windows build compiles successfully. The `FileType` import is scoped
inside the `#[cfg(target_os = "windows")]` block (matching the existing
pattern in the macOS block) so there are no unused imports on any
platform.
## Related Issue(s)
N/A — build breakage discovered during CI publish workflow.
## Current Behavior
The daemon's file watcher uses watchexec 3.0.1 which hardcodes
`RecursiveMode::Recursive` when registering inotify watches. This means
**every** directory gets an inotify watch — including all of
`node_modules`, `.git`, and other ignored trees.
On a typical workspace with a large `node_modules`, this can consume
thousands of inotify watches, eating kernel memory and CPU. The
`WatchFilterer` only filters **events** after watches are already
registered — the watches themselves are never prevented.
## Expected Behavior
Only non-ignored directories (workspace source code) get inotify
watches. Ignored directories like `node_modules`, `.git`, `.nx/cache`,
`.nx/workspace-data`, and `.yarn/cache` are skipped entirely at the
watch registration level.
This dramatically reduces:
- **inotify watch count** (from thousands to hundreds)
- **Memory usage** (each watch consumes kernel memory)
- **CPU overhead** (fewer watches = less kernel bookkeeping)
### How it works
- Upgraded watchexec 3.0.1 → 8.0.1 which supports
`WatchedPath::non_recursive()`
- Added `create_watch_walker()` using `ignore::WalkBuilder` (same
pattern as `walker.rs`) to enumerate only non-ignored directories
- Each directory is watched with `NonRecursive` mode — like putting
security cameras only in the rooms you care about instead of every room
in the building
- New directories created at runtime are dynamically added to the watch
set via the `on_action` handler
- Event-level filtering via `WatchFilterer` is unchanged — same behavior
for gitignore/nxignore patterns
### macOS Support for Dynamic Directory Registration
The initial implementation worked on Linux and Windows but failed tests
on macOS because macOS FSEvents doesn't always provide the same
`FileEventKind` tags as Linux inotify or Windows ReadDirectoryChangesW.
**Three changes to support macOS:**
1. **watcher.rs**: On macOS, check all events for directory creation
(not just events with specific FileEventKind tags) and verify via
filesystem
2. **types.rs**: Filter directory events from JavaScript callbacks on
macOS (similar to Windows behavior)
3. **watch_filterer.rs**: Allow macOS directory events (`Create(Folder)`
and `Modify(Metadata)`) through the filter so the action handler can
register them
All changes use `#[cfg(target_os = "macos")]` for compile-time
conditional compilation, so Linux/Windows behavior is completely
unchanged and there's zero runtime overhead.
### Additional notes
- Pinned `serde` to `<1.0.220` because serde 1.0.220+ moved `__private`
to `serde_core`, breaking `swc_common 0.31.22`
- No TypeScript changes — the napi interface is identical
- `watch_filterer.rs`, `types.rs`, `utils.rs` required no changes (APIs
are compatible)
## Related Issue(s)
Fixes https://github.com/nrwl/nx/issues/33781
Fixes https://github.com/nrwl/nx-console/issues/2468
<!-- No specific issue linked yet -->
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Re-enabling tests and putting back kotlin e2e tests for gradle.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
Flaky task detection warns about all tasks that have different exit
codes for the same hash, including non-cacheable tasks. This is
misleading because the flaky task warning message points users to Nx
Cloud's flaky task retry feature, which is only relevant for cached
tasks.
## Expected Behavior
Flaky task detection should only consider tasks where `task.cache ===
true`, making the warning more meaningful and avoiding noise for
non-cacheable tasks.
## Related Issue(s)
N/A - Internal improvement
## Changes Made
###
`packages/nx/src/tasks-runner/life-cycles/task-history-life-cycle.ts`
1. Added `cacheable: boolean` to the `TaskRun` interface
2. In `endTasks`, now tracks `cacheable: taskResult.task.cache === true`
for each task
3. In `endCommand`, filters to only check flaky tasks among cacheable
tasks
###
`packages/nx/src/tasks-runner/life-cycles/task-history-life-cycle-old.ts`
1. Added `cacheableHashes: Set<string>` to track which task hashes are
cacheable
2. In `endTasks`, tracks cacheable tasks by adding their hash to the set
3. In `endCommand`, only checks for flaky tasks among cacheable task
hashes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
A new version compatibility table is added to help users understand
which versions of the Gradle plugin work with which versions of the Nx
plugin. The targetNamePrefix configuration option is now documented with
an explanation of its use case in polyglot workspaces where target name
collisions may occur.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Gradle plugin to 0.1.12
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
- No way to run the batch executor in debug mode
- Any flags passed into the nx gradle batch command get forwarded into
the `gradlew` command.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
- Allow for an env variable to be set for debug flags so that the batch
runner jar can be run with a debugger hooked in.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #NXC-3797
---------
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
## Current Behavior
In some resize/background scenarios, the TUI could crash while rendering
output panes, displaying a "Scrollbar area is empty" message.
## Expected Behavior
The TUI remains stable during resizes and backgrounding. Output panes no
longer crash when a scrollbar would render in an invalid area.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
When Nx processes Gradle subprojects, task dependencies reference the
wrong project names. For a subproject structure like :app or :lib:core,
the generated task dependencies use only the simple project name (app or
core) instead of the full build tree path (:app or :lib:core). This
causes dependent tasks to be generated with incorrect project
references, breaking the task graph for multi-project Gradle builds.
## Expected Behavior
Task dependencies should use the full Gradle build tree path for
subprojects. When a task in :app depends on a task in :lib, the
dependency should be correctly referenced as :lib:taskName.
The fix introduces a getNxProjectName() utility function that correctly
resolves the Nx project name based on the Gradle project's
buildTreePath, and applies it consistently across all dependency
resolution logic in ProjectUtils.kt and
TaskUtils.kt. New tests verify the fix works for both single and nested
subproject structures.
Also removed --rerun-tasks from the batch and non batch runners, we
found that during parallel task executions with the non batch runner,
the flag would cause cache conflicts that would fail tasks.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
When a task has outputs at different path depths, some outputs may not
be tracked. This causes:
- Deleted output files not being detected
- Cache restoration being skipped with message "existing outputs match
the cache, left as is"
- Files not being restored even though they exist in cache
## Expected Behavior
All task outputs are tracked regardless of their path depth, ensuring:
- Deleted outputs are correctly detected
- Cache restoration happens when outputs are missing
## Current Behavior
When a task output directory contains a nested `.gitignore` that hides
its contents, Nx can treat the outputs as already present and skip
restoring them from cache. This can result in generated files being
missing from disk, even though the cache entry is valid.
## Expected Behavior
Nx should restore cached outputs regardless of ignore rules inside the
output directory.
## Related Issue(s)
Fixes#32620
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Disabling Gradle e2e tests until foojay toolchain service back online.
Ensures that gradle within the Nx repo uses mise to download java
toolchain, but gradle workspaces within the e2e environments download
their own toolchain.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #Q-175
AI agents are detected via environment variables (CLAUDECODE, OPENCODE)
and receive NDJSON streaming output, non-interactive mode, structured
JSON results with explicit GitHub setup instructions.
Related NXC-3628
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Add documentation for batch mode. Remove references to removed custom
overrides for intTest.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
The only way to download the cloud client is to run a specific cloud
command or a task with cloud configured.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
A new command is added where we only download the cloud client with:
```
nx download-cloud-client
```
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
add guide to clarify various ways to bundle a node app for different
bundlers
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: barbados-clemens <barbados-clemens@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
In the TUI, when any standalone task finishes,
`handle_standalone_task_finished` unconditionally switches the user's
selection to another in-progress task — even if the finished task wasn't
the one the user had selected. This causes the selection to jump
unexpectedly while the user is watching a different task.
## Expected Behavior
Selection should only change when the task the user is actively viewing
finishes. If an unrelated background task finishes, the user's selection
should remain on whatever they chose.
## Related Issue(s)
N/A — discovered during development testing.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
NX_NATIVE_LOGGING is hardcoded and can't be customized on the daemon
server
## Expected Behavior
Log settings can be customized by changing them in the env of the first
command to spawn the daemon
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
we were including native binaries in the final netlify function build
for nextjs which was fine until we reach the limit of 250mb causing a
failure to upload the function (AWS imposed lambda limit)
Now we strip out any deps we know we don't need for the app which are
dev deps and not runtime required.
## Current Behavior
- Canary releases calculate their base version by incrementing the minor
of `nx@latest`, or using `nx@next` major when majors differ
- PR releases always use `0.0.0` as their base version (e.g.
`0.0.0-pr-1234-abc1234`)
- This means canary and PR versions don't clearly relate to the current
beta release line
## Expected Behavior
- Both canary and PR releases derive their base version directly from
`nx@next`
- If next is `22.5.0-beta.5`, then:
- Canary: `22.5.0-canary.20260204-abc1234`
- PR: `22.5.0-pr.1234.abc1234`
- All prerelease channels now share the same base version, making it
clear which release line they belong to
## Related Issue(s)
N/A - internal improvement to release infrastructure
## Current Behavior
The Maven plugin version is `0.0.12` across all pom.xml files and the
versions.ts constant. The `bump-maven-version` generator does not update
the `batch-runner-adapters` pom files, causing version mismatches.
## Expected Behavior
The Maven plugin version is bumped to `0.0.13` in **all** pom.xml files
(including batch-runner-adapters), with a migration created for users
upgrading to Nx `22.5.0-beta.4`. The bump generator now includes the
batch-runner-adapters pom files so future bumps won't miss them.
### Changes
- Updated version from `0.0.12` to `0.0.13` in all pom.xml files (root,
maven, maven-plugin, shared, batch-runner, batch-runner-adapters,
maven3-adapter, maven4-adapter)
- Updated `mavenPluginVersion` constant in
`packages/maven/src/utils/versions.ts`
- Added `update-0-0-13` migration entry in
`packages/maven/migrations.json` targeting Nx `22.5.0-beta.4`
- Created migration file
`packages/maven/src/migrations/0-0-13/update-pom-xml-version.ts`
- Fixed `bump-maven-version` generator to include
`batch-runner-adapters` pom files
## Current Behavior
The FreeBSD build in CI can fail silently or with unclear error messages
when:
- Disk space runs low during the build process
- The build command fails without proper error propagation
- Unnecessary files consume valuable disk space
## Expected Behavior
With these changes:
- Additional disk space is freed by removing docs/astro-docs/nx-dev
directories before building
- Build exit codes are properly captured and propagated
- Disk usage is logged after the build completes for debugging purposes
- Build failures are clearly reported with explicit error messages
This improves reliability and makes it easier to diagnose issues when
they occur.
## Related Issue(s)
<!-- No specific issue, general CI improvement -->
We're getting requests to `favicon.svg.md` that are being tracked,
ignore these. Also for the server page views, we should only count them
if `text/html` is in the accept header. Browsers will send these, and AI
agents, curl, etc. do not. This allows us to compare browser traffic vs
AI/curl traffic more accurately.
## Current Behavior
When a client disconnects while the daemon is writing a response, a
`socket.write` call triggers an EPIPE error. The old error handler used
`console.error`, which caused the error to propagate through
`respondWithErrorAndExit` and crash the daemon process via
`process.exit(1)`. The client would then see an `internalDaemonError`
and permanently disable the daemon via `markDaemonAsDisabled`, requiring
`nx reset` to recover.
Additionally, disconnected sockets were not cleaned up from the file
watcher and project graph listener registries on socket error events,
only on `close` events. This left a window where the daemon could
attempt to write to dead sockets during notifications.
## Expected Behavior
When a client disconnects mid-response:
- The `socket.write` callback logs the error gracefully via
`serverLogger` instead of `console.error`
- The daemon process stays alive and continues serving other clients
- The `socket.on('error')` handler cleans up registered file watcher and
project graph listener sockets immediately, matching the existing
`close` handler behavior
- The daemon is never permanently disabled due to EPIPE errors
## Related Issue(s)
<!-- No linked issue -->
### Current Behavior
The nx configure-ai-agents command output is minimal - just "AI agents
set up successfully" with a
bullet list of agent names. Users don't understand what was actually
configured (plugin vs MCP,
skills, which files were created/modified).
### Expected Behavior
Clearer feedback about what gets configured for each agent:
Selection prompt improvements:
- Agents needing updates show (update available) tag
- Footer always shows result state: what will be configured
- Agent-specific descriptions (e.g., "Installs Nx plugin (MCP + skills +
agents). Updates
CLAUDE.md.")
Post-configuration output:
- Compact summary per agent showing what was set up
- Example: Claude Code: Nx plugin (MCP + skills + agents) + CLAUDE.md
Claude .mcp.json cleanup:
- When configuring Claude, removes nx-mcp from .mcp.json since it's now
handled by the plugin
- Deletes the file entirely if nx-mcp was the only entry
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
This PR fixes two issues:
1. When the README changes are amended, there's an edge case where we
don't have a commit to amend (e.g. `--skipGit`), and this fails the
entire CNW flow.
2. When user opts out of Cloud, we strip the entire `<!-- BEGIN:
nx-cloud -->` block in README rather than just the comments and leaving
the content.
Closes NXC-3812
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
There's not an easy to use service to track PIDs being registered to nx
tasks
## Expected Behavior
There's a service to track this stuff
## Related Issue(s)
## Current Behavior
The `getNpmPackageVersion` function in
`packages/workspace/src/generators/utils/get-npm-package-version.ts`
uses `execSync` with direct string interpolation of the `packageName`
parameter. When a user runs `create-nx-workspace` with a custom
`--preset` value that doesn't match a known preset, the value flows
unsanitized into a shell command:
```js
execSync(`npm view ${packageName}... version --json`)
```
This allows arbitrary command execution via shell metacharacters (e.g.,
`--preset='pkg$(malicious command)'`).
## Expected Behavior
User-supplied package names are validated against a strict npm package
name regex before being passed to any shell command. The function now
uses `execFileSync` with an args array instead of `execSync` with string
interpolation, providing defense in depth:
1. **Input validation** — rejects anything that isn't a valid npm
package name
2. **Safe execution** — arguments are passed as an array so Node.js
handles escaping, rather than concatenating into a raw shell string
## Current Behavior
Given a project name like `:foo`, you can run tasks like `nx test foo`
(note `foo` vs `:foo`), but passing --help throws an error
## Expected Behavior
`--help` works the same with the shortname vs full name
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
- `pom.xml` is only included as an input when a mojo uses default inputs
- Mojos with specific input configurations (like
`maven-compiler-plugin:compile`) don't get `pom.xml` in their inputs
- Parent `pom.xml` files aren't tracked as inputs
This can lead to stale cache hits when:
1. `pom.xml` changes but a mojo has specific input config
2. A parent `pom.xml` changes (affecting inherited properties,
dependency versions, plugin config)
## Expected Behavior
- Every target should include its own `pom.xml` as an input
- Every target should include ancestor `pom.xml` files (within the
workspace) as inputs
- Cache should invalidate when any relevant `pom.xml` changes
## Related Issue(s)
N/A - discovered during code review
## Changes
- **CacheConfig.kt**: Removed `pom.xml` from `defaultInputs` (now always
added explicitly)
- **MojoAnalyzer.kt**: Added `workspaceRoot` parameter and logic to walk
up the parent chain, adding all in-workspace ancestor `pom.xml` files as
inputs
- **NxProjectAnalyzerMojo.kt**: Pass `workspaceRoot` to `MojoAnalyzer`
## Current Behavior
When the daemon dies while processing a request, the reconnect logic
adds the retry back to the promise-based queue. However, the original
request is still blocked in the queue waiting for a response that will
never come (the socket is dead). This creates a deadlock:
1. Original request (`fn1`) is blocked awaiting a promise that will
never resolve
2. Retry request (`fn2`) is queued but can't execute until `fn1`
completes
3. `fn1` can't complete because it's waiting on the dead socket
## Expected Behavior
When reconnecting after daemon death, the retry should resolve the
pending promise that the original queue entry is waiting on, allowing
the queue to proceed normally.
## Related Issue(s)
<!-- No specific issue, discovered during development -->
## Solution
Instead of re-queuing the retry through `sendToDaemonViaQueue` (which
adds to the end of the queue), we now call `sendMessageToDaemon`
directly. This resolves the pending promise that `fn1` is waiting on,
allowing it to complete naturally and the queue to proceed.
Also removed the now-unused `decrementQueueCounter` method from
`PromisedBasedQueue`.
## Current Behavior
Only markdown and text file requests are tracked server-side via the
`track-asset-requests` edge function. HTML page views are not tracked on
the server, missing requests from AI tools and curl.
## Expected Behavior
Track all doc page views server-side with a new edge function that:
- Sends `server_page_view` events to GA4 with `content_type` param to
differentiate HTML/markdown/text
- Uses Netlify's `excludedPath` config for efficient path filtering
(zero compute for excluded paths)
- Skips non-HTML requests via Accept header check
### Changes
| File | Change |
|------|--------|
| `track-page-requests.ts` | **NEW** - Edge function for HTML page view
tracking on `/docs/*` |
| `track-asset-requests.ts` | Changed event name to `server_page_view`,
added `content_type` param |
| `add-link-headers.ts` | Refactored to use `excludedPath` config
instead of runtime path checks |
| `netlify.toml` | Added edge function declaration for
`track-page-requests` |
### GA Event Schema
```javascript
{
name: 'server_page_view',
params: {
content_type: 'text/html' | 'text/markdown' | 'text/plain',
file_extension: '.html' | '.md' | '.txt',
is_ai_tool: 'true' | 'false',
// ... other params
}
}
```
## Other Notes
This PR also removes the edge function entries from `netlify.toml` since
it's auto detected from `astro-docs/netlify/edge-functions`. This makes
all the configuration in the actual `.ts` file, not duplicated in the
`netlify.toml` file.
## Related Issue(s)
Closes DOC-395
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
The Gradle executor accepts a taskName option that *should not* contain
multiple space-separated tasks. When multiple tasks are provided, the
batch runner misinterprets the space-separated string as containing
project names rather than treating it as a single task argument, leading
to execution errors and confusion.
This only occurs if the taskName is manually overridden and should not
occur when task names are generated by the project graph plugin.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The Gradle executor now validates that taskName contains only a single
task without spaces. If multiple tasks are passed, it throws a clear
error message: "Task '[taskName]' contains spaces. Only a single Gradle
task is allowed per executor invocation." This prevents the batch runner
from misinterpreting the task name and provides immediate feedback to
users about the correct usage.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
When running Gradle tasks in batch mode with atomized targets, if the
same task appears multiple times in the output (which happens when tasks
are atomized and executed separately), the batch runner only captures
the output from the last execution. Previous executions' output gets
overwritten because the splitOutputPerTask function replaces the entire
output for each task name it encounters.
## Expected Behavior
All output from a task should be preserved, even when the task appears
multiple times in the batch output. When the same task name is
encountered multiple times, the outputs should be concatenated rather
than replaced, ensuring developers can see the complete execution
history for atomized targets.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Plan for fixing .NET incremental builds documentation
- [x] Update the "Target dependencies" section to remove `restore` from
the `dependsOn` array
- [x] Add explanation about why `restore` cannot be run through Nx for
solutions using custom frameworks
- [x] Improve explanation clarity based on review feedback
- [x] Verify the "Target configuration" section is consistent with the
changes
- [x] Complete code review and address feedback
- [x] Run security checks (no issues found)
- [x] Address PR feedback: Use JSX `<Aside>` component with import
statement instead of Markdoc tag
## Summary
Successfully fixed the documentation issue in the .NET incremental
builds guide. The changes made:
1. **Removed `restore` from the build target's `dependsOn` array** - The
documentation now correctly shows `"dependsOn": ["^build"]` instead of
`"dependsOn": ["restore", "^build"]`, matching the actual implementation
in the plugin code.
2. **Added a clear explanation** - Included an aside box explaining why
`restore` is not in the `dependsOn` array: because Nx requires NuGet
package restoration to be completed before running any tasks, and
including it would create a circular dependency.
3. **Verified consistency** - Checked that the "Target configuration"
section already showed the correct configuration, ensuring all
documentation is now consistent.
4. **Used correct Starlight component** - Changed from Markdoc `{% aside
%}` tag to JSX `<Aside>` component with proper import statement per
Starlight documentation standards.
The changes align with the actual implementation in
`packages/dotnet/analyzer/Utilities/TargetBuilder.Build.cs` where the
build target's `dependsOn` is set to `[$"^{targetName}"]` (line 56).
<!-- START COPILOT ORIGINAL PROMPT -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>docs(dotnet): implied conflict in dependsOn of inferred
build task</issue_title>
> <issue_description>### Documentation issue
>
> <!-- (Update "[ ]" to "[x]" to check a box) -->
>
> - [ ] Reporting a typo
> - [ ] Reporting a documentation bug
> - [ ] Documentation improvement
> - [x] Documentation feedback
>
> <!--
> If your issue is not regarding the documentation, please choose an
issue type:
> https://github.com/nrwl/nx/issues/new/choose
> -->
>
> ### Is there a specific documentation page you are reporting?
>
>
https://nx.dev/docs/technologies/dotnet/guides/incremental-builds#target-dependencies
>
> ### Additional context or description
>
> The code sample provides in this doc includes `"dependsOn":
["restore", "^build"]`, but the automatically inferred `build` target
from this plugin does not actually include the `restore` target in the
dependsOn array. I assume this is by design? The docs seem to confuse it
a bit.
> </issue_description>
>
> <agent_instructions>Remove the `restore` target from the dependsOn
block. Add a small explanation that we can't run restore through Nx
because Nx requires restore to have been completed prior to running
tasks if the solution uses a custom framework</agent_instructions>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
<!-- START COPILOT CODING AGENT SUFFIX -->
- Fixesnrwl/nx#34150
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
## Current Behavior
When socket data chunks split a multibyte UTF-8 character (e.g., CJK
characters like Korean, Chinese, Japanese) at an arbitrary byte
boundary, `Buffer.toString()` decodes incomplete byte sequences as
replacement characters (�), causing message corruption.
This can occur when:
- File paths contain non-ASCII characters
- Project names include multibyte characters
- Any JSON message contains international text
## Expected Behavior
Multibyte UTF-8 characters should be properly decoded even when split
across multiple socket data chunks. The fix uses Node.js `StringDecoder`
which buffers incomplete multibyte sequences until the remaining bytes
arrive.
## Related Issue(s)
Fixes socket message corruption for paths/names containing multibyte
characters.
- fix(nx-dev): always link headers regardless of mdoc or markdown
content source (generated vs static file)
- fix(nx-dev): make option/property columns in table linkable
- the table column header is matched on `options`, `option`,
`properties`, and property` (case insensitive)
https://github.com/user-attachments/assets/7250b9d5-1030-4ebc-9e21-0a05f295bbf5
Note bc mdoc and `renderMarkdown` go through 2 different rendering
pipelines, this logic must bc within the markdoc config and rehype
(markdown) processing logic. tried to shared logic where I could
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
After completing the CNW (Create Nx Workspace) flow with Nx Cloud, users
see a plain text completion message with a link to finish setup.
## Expected Behavior
Users now see one of four completion message variants controlled by
`NX_CNW_FLOW_VARIANT`:
- **Variant 0**: Plain link (control) - always used for enterprise URLs
- **Variant 1**: "Try the full Nx platform" decorative ASCII banner
- **Variant 2**: "Unlock 70% faster CI" decorative ASCII banner
- **Variant 3**: "Reclaim your team's focus" decorative ASCII banner
Key changes:
- Added enterprise URL detection (non-standard Nx Cloud URLs always get
variant 0)
- Locked the cloud prompt to always show "Try the full Nx platform?" (no
longer varies by flow variant)
- Flow variant now only affects the completion banner, not the prompt
- Added `snapshot.nx.app` to standard Nx Cloud hosts
- Removed variant 2 auto-connect behavior (all variants now prompt)
## Screenshots
Variant 0:
<img width="1392" height="1065" alt="variant0"
src="https://github.com/user-attachments/assets/0b18686e-1481-4fc0-995e-1577052887ff"
/>
Variant 1:
<img width="1392" height="1065" alt="variant1"
src="https://github.com/user-attachments/assets/e5909e2e-e1d8-4d04-9721-ba6186d06891"
/>
Variant 2:
<img width="1392" height="1065" alt="variant2"
src="https://github.com/user-attachments/assets/7e9f819f-e3c0-44d7-9760-0cab1d5dd9ac"
/>
Variant 3:
<img width="1392" height="1065" alt="variant3"
src="https://github.com/user-attachments/assets/83f0499f-d807-4dc8-9390-c7eec93590a9"
/>
## Related Issue(s)
Closes CLOUD-4147
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Enable Gradle executor to run tasks in batch mode in CI.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
We're showing over 8 GB of memory usage on Netlify, and 11+ GB on
Agents. Let's test out a few ways to reduce the memory footprint.
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Preload vitest/node ESM module early in
buildViteTargets/buildVitestTargets
functions before parallel processing occurs. This prevents the
ERR_INTERNAL_ASSERTION error that occurs when multiple vitest.config
files
are processed in parallel on Node 24+.
Fixes#34028Fixes#33091
## Current Behavior
The `runCommandUntil` e2e utility function waits indefinitely for the
expected output to appear. If the output never appears (e.g., server
fails to start, different output format, port conflict), the test hangs
forever, causing CI jobs to run for hours before being killed.
## Expected Behavior
The function should timeout after a configurable duration and fail with
a clear error message showing what output was received.
## Related Issue(s)
Fixes hanging e2e tests observed in CI (e.g.,
`e2e-node:e2e-ci--src/node-server.test.ts` hung for 1h 21m).
## Changes
- Added optional `timeout` parameter to `runCommandUntil` opts (default:
5 seconds)
- On timeout: kills the process, logs the collected output, and rejects
with a clear error
- Existing call sites work unchanged; tests needing more startup time
can pass `{ timeout: 30000 }`
---------
Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
Co-authored-by: FrozenPandaz <8104246+FrozenPandaz@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
1. The `check-links` task cache inputs only included `sitemap.xml` (the
index
file) and `sitemap-index.xml`, but not the actual `sitemap-0.xml` files
that
contain the URL data. This meant that when pages were added or removed,
the
cache wasn't properly invalidated - the check-links task would return a
cached "passing" result even when broken links existed.
2. The `/launch-nx` page was removed in #34183 but one link in
`astro-docs/src/content/docs/reference/Nx Cloud/release-notes.mdoc`
still
pointed to it. This link was masked by being in the `validate-links.ts`
ignore list.
## Expected Behavior
1. The `check-links` task cache is invalidated when sitemap URLs change
by
using glob patterns (`sitemap*.xml`) to include all sitemap files.
2. All links point to valid pages. The `/launch-nx` link now redirects
to
`/blog/launch-nx-week-recap`.
## Changes
- **astro-docs/release-notes.mdoc**: Updated `/launch-nx` link to
`/blog/launch-nx-week-recap`
- **astro-docs/validate-links.ts**: Removed `/launch-nx` from ignore
list (no longer needed)
- **nx-dev/project.json**: Fixed cache inputs to use `sitemap*.xml` glob
patterns
## Related Issue(s)
Fixes DOC-385
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
With Vite now providing additional options (environments etc) for
framework authors, vite.config files can be much more simple for the
user.
However, this often assumes that the `root` property will be set and
provided during `Vite CLI` invocation.
When we run `resolveConfig` to determine inputs and outputs, we do not
set this `root` and expect the user to have it in their vite config
file.
For some plugins/frameworks such as Tanstack Start - this causes the
plugin to error.
The `isBuildable` conditions is also not inclusive enough and can skip
projects that should be marked as buildable.
## Expected Behavior
Ensure that sophisticated vite plugins are supported with Nx
## Related Issue(s)
CLOSES NXC-3637
## Current Behavior
Template-generated workspaces use a generic link in the README instead
of a per-workspace short link for Nx Cloud setup.
## Expected Behavior
When users opt into Nx Cloud (or are auto-connected via variant 2), the
template README is updated with a personalized connect URL section that
helps them finish setting up their workspace.
---
BEFORE:
<img width="762" height="460" alt="image"
src="https://github.com/user-attachments/assets/58900071-1727-49d1-aa19-279c488b5037"
/>
AFTER:
<img width="1032" height="599" alt="image"
src="https://github.com/user-attachments/assets/a6e3a122-5807-4ba2-90dd-441e41a3280e"
/>
---
## Related Issue(s)
Closes NXC-3783
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
deno worker.stdout is a Readable/Writeable. To provide better deno
support an error should not be thrown
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
If `worker.stdout` or `worker.stderr` are not instanceof Socket then nx
throws an error. This is problematic in Deno where `stdout` and `stderr`
are Readable/Writable and not Socket.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
`startupPluginWorker` function should work in Deno runtime
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
- https://github.com/denoland/deno/issues/31961
- https://github.com/oven-sh/bun/issues/26505
---------
Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
## Current Behavior
Plugin workers occasionally fall over during the start up steps.
## Expected Behavior
Improves some issues with the error handling when loading plugin workers
and adds some more logs to help understand what's went wrong here.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Remove redundantly placed period and make error message construction
more readable when facing AggregateError
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes NXC-3766
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
--rerun is not tooling api compatible and therefore will break usage of
the batch executor. Replaced the flag with --rerun-tasks.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
The Maven batch runner bundles Maven 4 classes at compile time, which:
- Creates a large JAR file (~50+ MB)
- Only works with Maven 4
- Has classloader conflicts with Maven's own SLF4J
## Expected Behavior
The batch runner loads Maven classes at runtime from `MAVEN_HOME`,
which:
- Creates a small JAR (~2 MB) with no bundled Maven dependencies
- Works with both Maven 3.x and Maven 4.x
- Avoids classloader conflicts by isolating Maven in its own ClassRealm
- Outputs clean Maven-style logs (`[INFO]`, `[WARNING]`, etc.)
## Implementation
### Architecture
```
batch-runner.jar (NO Maven dependencies)
├── MavenClassRealm → Loads Maven JARs from MAVEN_HOME at runtime
├── ResidentMavenExecutor → Maven 4 executor (reflection-based)
├── CachingMaven3Invoker → Maven 3 executor (reflection-based)
└── nx-maven-adapters/ → Pre-compiled adapter JARs (embedded as resources)
├── batch-runner-adapters-maven3.jar
└── batch-runner-adapter-maven4.jar
```
### Key Changes
1. **Removed compile-time Maven dependencies** from batch-runner module
2. **Created batch-runner-adapters** modules for Maven 3 and Maven 4
specific code
3. **Implemented MavenClassRealm** to load Maven JARs from MAVEN_HOME at
runtime
4. **Implemented reflection-based executors** that load adapter JARs
into ClassRealm
5. **Fixed SLF4J logging** with System.out redirection for clean
Maven-style output
6. **Added shared module** for BuildStateManager, BuildStateApplier, and
BuildStateRecorder
### Benefits
- **Version agnostic**: Same JAR works with Maven 3.x and 4.x
- **Graph caching**: Project dependency graph built once, reused across
tasks
- **Build state persistence**: compile → package → install works
correctly
- **No classloader conflicts**: Maven's classes isolated in their own
ClassRealm
- **Clean output**: Standard Maven log format without SLF4J noise
## Related Issue(s)
N/A - Internal refactoring for better Maven version support
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
LLMs and CLI tools must explicitly request the `.md` URL suffix to get
raw markdown content from documentation pages.
## Expected Behavior
When a client requests a docs page with `Accept: text/markdown` header,
the edge function rewrites to serve the `.md` version directly (no
redirect). This enables LLM tools to get markdown content by requesting
the standard URL.
Behavior:
- `Accept: text/markdown` → serves .md content (via rewrite, no
redirect)
- Default (browsers) → serves HTML with Link headers (unchanged)
Examples:
```
curl -H 'Accept: text/markdown' https://deploy-preview-34239--nx-docs.netlify.app/docs/getting-started/intro
curl -H 'Accept: text/markdown' https://deploy-preview-34239--nx-docs.netlify.app/docs/getting-started/tutorials/angular-monorepo-tutorial
```
Uses Netlify Edge Function rewrite (returns URL object) instead of
redirect for single-request response that works with all HTTP clients.
## Related Issue(s)
Closes DOC-389
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
broken links
## Expected Behavior
links aren't broken any more and are updated to expected pages from docs
page.
## Related Issue(s)
Fixes DOC-391
This PR adds:
1. `llms-full.txt` that is a full copy of our docs in markdown.
2. HTTP `Link` headers to our docs HTML pages so that they point to the
`.md` (markdown) version, and also to `llms.txt` and `llms-full.txt`.
The `llms-full.txt` is currently at 2.7 MB, which is much less than
other sites that are up to 5MB or more.
<img width="569" height="35" alt="Screenshot 2026-01-27 at 12 11 10 PM"
src="https://github.com/user-attachments/assets/61be02b4-2813-4c39-951c-d831af83e823"
/>
First 100 lines of `llms-full.txt`:
````
# Nx Documentation
> Complete Nx documentation compiled into a single file for LLM consumption.
Nx is a powerful, open source, technology-agnostic build platform designed to efficiently manage codebases of any scale. From small single projects to large enterprise monorepos, Nx provides intelligent task execution, caching, and CI optimization.
This file was generated from 503 documentation pages.
Individual pages are available at: https://nx.dev/docs/{slug}.md
# Quickstart
---
<!-- source: https://nx.dev/docs/quickstart.md -->
## Quickstart with Nx
Get up and running with Nx in just a few minutes by following these simple steps.
{% steps %}
1. Install the Nx CLI
Installing Nx globally is **optional** - you can use `npx` to run Nx commands without installing it globally, especially if you're working with Node.js projects.
{% tabs syncKey="install-method" %}
{% tabitem label="npm" %}
```shell
npm add --global nx
```
**Note:** You can also use Yarn, pnpm, or Bun
{% /tabitem %}
{% tabitem label="Homebrew (macOS, Linux)" %}
```shell
brew install nx
```
{% /tabitem %}
{% tabitem label="Chocolatey (Windows)" %}
```shell
choco install nx
```
{% /tabitem %}
{% tabitem label="apt (Ubuntu)" %}
```shell
sudo add-apt-repository ppa:nrwl/nx
sudo apt update
sudo apt install nx
```
{% /tabitem %}
{% /tabs %}
2. Start fresh or add to existing project
For JavaScript-based projects you can **start with a new workspace** using the following command:
```shell
npx create-nx-workspace@latest
```
**Add to an existing project: (recommended also for non-JS projects)**
```shell
npx nx@latest init
```
**Get the complete experience:**
For a fully integrated development workflow with AI-powered CI features, [start directly from Nx Cloud](https://cloud.nx.app/get-started).
Learn more: [Start New Project](/docs/getting-started/start-new-project) • [Add to Existing](/docs/getting-started/start-with-existing-project) • [Complete Nx Experience](https://cloud.nx.app/get-started)
3. Run Your First Commands
Nx provides powerful task execution with built-in caching. Here are some essential commands:
**Run a task for a single project:**
```shell
nx build my-app
nx test my-lib
```
**Run tasks for multiple projects:**
```shell
nx run-many -t build test lint
```
Learn more: [Run Tasks](/docs/features/run-tasks) • [Cache Task Results](/docs/features/cache-task-results)
4. What's next?
Now that you've experienced the Nx basics, choose how you want to continue:
````
## Related Issue(s)
Closes DOC-236
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
This design refresh emphasizes the contrast variant aesthetic across all
hero sections, pricing cards, and primary call-to-actions.
- Change 47 instances of variant="primary" to variant="contrast"
- Update ui-courses to use variant="secondary" for GitHub link
- Prefer high-contrast inverted style for primary CTAs
- Maintain proper visual hierarchy with secondary actions
- Replace all slate-* classes with zinc-* equivalents (1,158 instances)
- Replace all sky-* classes with blue-* equivalents (210 instances)
- Update opacity variants, gradients, rings, and borders
- Maintain full dark mode compatibility
## Current Behavior
If something is in `package.json#dependencies`, we still suggest it to
be `nx add`-ed during `nx import`
## Expected Behavior
If a plugin is already installed, we don't suggest it anymore
`@nx/web:app` generator is incorrectly calling `createOrEditViteConfig`
when bundler != vite and unitTestRunner = vitest.
Ensure it is using the correct file
## Current Behavior
The migration for svgr requires using file-loader which is unmaintained.
## Expected Behavior
Use asset/resource instead of file-loader
## Related Issue(s)
CLOSES NXC-3667
## Summary
- When `/tmp` is mounted with `noexec`, loading native modules from the
cache fails silently and causes Nx to hang indefinitely
- This adds a fallback to load from `node_modules` when permission
errors occur
## Problem
Users with `/tmp` mounted with `noexec` (a common security hardening
practice) experience Nx hanging forever, even for simple commands like
`nx --version`.
The root cause:
1. Nx copies native `.node` files to `/tmp` to avoid Windows file
locking issues
2. On `noexec` mounts, execution fails with `EACCES`/`EPERM`
3. The error wasn't caught, leading to broken native bindings and
infinite loops
## Solution
Catch permission errors when loading from the cache and fall back to the
original `node_modules` location. This:
- Works automatically without user config
- Preserves Windows file locking fix (only falls back when needed)
- No error messages for users
Closes#33991
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Schema validation (done, for instance, when calling an executor) fails
when an option has value "null" and schema accepts null values. I had it
in a custom executor for `nx-release-publish`, that understands that
`nxReleaseVersionData` is implicitly passed, so I define its schema:
```json
"newVersion": {
"type": ["string", "null"],
"description": "The new version of the project, null if no changes detected"
}
```
My code calls `getReleaseClient().releaseVersion(options)`, which gets
me a `projectsVersionData` object with version info. It contains `null`
values (allowed). I then pass it, and ends up in:
```typescript
// nx/src/tasks-runner/task-orchestrator.ts:531-539
const combinedOptions = combineOptionsForExecutor(
task.overrides, // ← Contains nxReleaseVersionData with null values
task.target.configuration,
targetConfiguration,
schema, // ← Schema from executor
task.target.project,
relativeCwd,
isVerbose
);
```
which fails inside:
```typescript
// nx/src/utils/params.js:126-201
function validateObject(opts, schema, definitions) {
// Line 191-200: Iterate through all properties
Object.keys(opts).forEach((p) => {
validateProperty(
p, // "nxReleaseVersionData"
opts[p], // { foo: { newVersion: null, ... }}
(schema.properties ?? {})[p], // schema for nxReleaseVersionData
definitions
);
});
}
```
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR -->
`null` values should be considered, as they are valid in JSON schemas. It was probably not considered, because we never think that `typeof null === "object"`, but it's unfortunately the case.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is merged. -->
I will create one
Fixes https://github.com/nrwl/nx/issues/34169
Transpiling through SWC or ts-node is slow compared to the native type
stripping that Node.js provides.
This PR adds `NX_PREFER_NODE_STRIP_TYPES` to allow users to use Node.js
built-in TypeScript support. There are some features that need
transpilation that won't work with type stripping:
- Enum declarations
- namespace with runtime code
- legacy module with runtime code
- parameter properties
- path aliases
See: https://nodejs.org/api/typescript.html#full-typescript-support
The speed-up is significant. My test workspace went from 22s to ~2s to
compute from cold cache.
Demo: https://www.loom.com/share/ce1db29e501b46d58109ffeec8a7a649
In the future we should enable this by default, and users have to turn
it off to use SWC/ts-node.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
Right now GA only collects page views. This PR allow us to see which
`.md` files are being used. There are mostly useful for AI agents to
fetch without using too many tokens. We want to track usage so we can
see what techniques to guide agents actually work.
## Related Issue(s)
Closes DOC-386
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This PR makes it so Cloud commands like `npx nx record` and `npx nx
fix-ci` still work without `nxCloudId`. We'll log a warning so that
`ci.yml` using these commands will still work. The warning let's users
know that these do not work without being connected.
Closes #NXC-3753
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Commit linting does not mention requirement for commit message to be
lowercase.
<!-- This is the behavior we have today -->
## Expected Behavior
Hook message should instruct user to use all lowercase for commit
message.
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Self-healing docs only reference being supported for GitHub, Azure, and
GitLab.
<!-- This is the behavior we have today -->
## Expected Behavior
We should show instructions for all currently supported vcs providers,
including Bitbucket.
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
Resizing the TUI while in inline view kinda breaks things. Its
unfortunate, I'm not sure there's a ton to be done, but this PR explores
some solutions
## Expected Behavior
The TUI is less sensitive to resize events with inline mode
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
The create-nx-workspace (CNW) command includes A/B testing variant 1
which skips the cloud prompt under certain conditions.
## Expected Behavior
Revert to the previous behavior where the cloud prompt flow is
consistent without the A/B testing variant.
## Related Issue(s)
This reverts commit 2039a5e119 from PR
#34106.
## Current Behavior
The internal link checker reports 3 broken links pointing to
`/launch-nx`:
- `/blog/2024-02-05-nx-18-project-crystal.md`
- `/blog/2024-02-15-launch-week-recap.md`
- `/changelog/18_0_0.md`
The `/launch-nx` page was a temporary page for the Nx 18 launch event in
February 2024 and no longer exists.
## Expected Behavior
All internal links should point to valid pages. Links to the old launch
page now redirect to the Launch Nx Week recap blog post.
## Related Issue(s)
Fixes the internal link checker errors.
## Current Behavior
There's a hard to reproduce hang that happens occasionally when running
the TUI
## Expected Behavior
We think this should fix it
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
The `banner.json` was committed as a fallback if we're not using Framer
to control the banner yet on nx.dev. Now that it is verified we can
remove the committed file.
Closes DOC-381
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Previously, `nx reset --onlyDaemon` would only stop the daemon process
but not clean up the daemon files in `.nx/workspace-data/d`. This change
ensures the daemon workspace data directory is also removed when using
the `--onlyDaemon` flag, consistent with the behavior of a full reset.
Co-authored-by: MaxKless <MaxKless@users.noreply.github.com>
This PR updates the releases page so v22 is included.
Closes #DOC-382
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
1. When running a task with dependencies (e.g., `nx serve app` where app
depends on app2:serve), the initiating task might not be selected on
startup. Additionally, the auto-select logic could switch selection to
the initiating task at any time when it started running - even minutes
later - which felt "random" to the user.
2. When pressing Enter on an already-pinned task, it would unpin the
task, causing the pane to disappear while focus remained on it
(invisible-but-focused state).
## Expected Behavior
1. The initiating task (the one the user actually requested) should be
selected during init, and selection should never unexpectedly change
later when tasks start.
2. Pressing Enter on an already-pinned task should focus the pane, not
unpin it.
## Changes
- **Select initiating task during init**: Moved initiating task
selection to `init()` in app.rs. This only applies in `RunOne` mode
since in `RunMany` there's no single initiating task to prioritize.
Removed the "switch to initiating task" logic from `start_tasks()` in
tasks_list.rs.
- **Focus pane on Enter**: Changed behavior so pressing Enter on an
already-pinned task focuses the pane instead of unpinning it.
## Related Issue(s)
N/A - discovered during TUI testing
# Current Behavior
The `beforeCompile` hook is registered inside the `watchRun` hook,
causing a new handler to be added on every recompilation. This leads to
handler accumulation, where setup operations (building static remotes,
starting file server, starting proxies) are triggered multiple times
during watch mode.
# Expected Behavior
Hooks should be registered once, outside of other hooks, to prevent
accumulation. Setup operations should only run once, not on every
recompilation.
# Related Issue(s)
Fixes https://github.com/nrwl/nx/issues/34141
# Current Behavior
1. **Performance bottleneck**: `statsValue.toJson()` is called with no
options, causing full serialization of all stats data on every build.
This is expensive and unnecessary when only budget checking is needed.
2. **Redundant work**: Budget checking code runs even when no budgets
are configured or when targeting server platform.
3. **User stats config ignored**: Custom stats configuration provided
via `rspackConfigOverrides` is not respected by the stats logger.
4. **Double serialization**: `rspackStatsLogger` calls `stats.toJson()`
without passing the stats options, ignoring user preferences.
# Expected Behavior
1. Only serialize what's needed for budget checking (`assets` and
`chunks`), significantly reducing overhead.
2. Early exit when budgets are not configured or on server platform,
skipping expensive `toJson()` entirely.
3. User's stats configuration is merged with defaults and respected
throughout the build output.
4. `rspackStatsLogger` uses the provided `statOptions` when serializing
stats.
# Related Issue(s)
Fixes https://github.com/nrwl/nx/issues/34145
## Current Behavior
CNW always shows the "Try the full Nx platform?" prompt and connects to
Nx Cloud to generate an onboarding URL with a token.
## Expected Behavior
For A/B testing variant 1:
- Skip cloud prompt
- Skip connectToNxCloudForTemplate() - no nxCloudId in nx.json
- Skip readNxCloudToken() - no misleading spinner
- Use GitHub flow for URL generation (accessToken: null)
- Show github.com/new hint when user hasn't pushed
Also fixes:
- Expired cache file bug: now deletes with unlinkSync() instead of
ignoring, which caused 50-50 randomization after 1-week expiry
- Adds variant-X to short URL meta property for cloud analytics
## Related Issue(s)
Closes NXC-3628
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
`getNxRequirePaths` returns paths in the order `[root,
getNxInstallationPath(root)]`, which means the workspace root is checked
first when resolving modules.
## Expected Behavior
The nx installation path (`.nx/installation`) should be prioritized and
checked first before falling back to the workspace root. This ensures
that modules from the nx installation directory take precedence.
## Related Issue(s)
N/A
# Current Behavior
The Angular Rspack compiler's `ComponentStylesheetBundler` does not
receive Tailwind or PostCSS configuration. This means Tailwind
directives (like `@apply`, `@tailwind`) in component stylesheets are not
processed, resulting in broken styles.
# Expected Behavior
Component stylesheets should support Tailwind CSS and PostCSS
configurations, matching the behavior of the standard Angular CLI build
process.
# Related Issue(s)
https://github.com/nrwl/nx/issues/34098
# Current Behavior
1. **Handler accumulation**: The `compilation`, `beforeCompile`, and
`done` hooks are registered inside `watchRun`, causing new handlers to
be added on every rebuild cycle. This leads to performance degradation
and duplicate operations during watch mode.
2. **Double rebuilds**: Rapid filesystem events (e.g., editor
backup/swap files) trigger multiple rebuilds because there's no
aggregation timeout configured.
3. **No watchOptions configuration**: Users cannot customize watcher
behavior (aggregateTimeout, ignored patterns, etc.).
# Expected Behavior
1. Hooks should be registered once outside of `watchRun` to prevent
accumulation. Shared state is used to pass data between watch cycles and
compilation hooks.
2. A default `aggregateTimeout: 50` batches rapid filesystem events to
prevent double rebuilds.
3. Users can provide custom `watchOptions` to configure watcher
behavior, with user options taking precedence over defaults.
# Related Issue(s)
https://github.com/nrwl/nx/issues/34142#issuecomment-3767571208
## Current Behavior
New task processes show 0% CPU on their first measurement because no
baseline exists. Accurate readings only appear on the second collection
cycle (~1s later).
## Expected Behavior
New task processes get accurate CPU readings on their first measurement.
The collector establishes CPU baselines for newly registered processes
~250ms before collection, giving `sysinfo` enough time to calculate
accurate CPU deltas.
## Technical Details: Baselining & Collection Flow
The collection loop runs in 4 phases:
```
T=0ms T=750ms T=1000ms T=1750ms T=2000ms
| | | | |
v v v v v
Collect → Sleep(750ms) → Baseline → Sleep(250ms) → Collect → ...
```
1. **Collect**: Refresh all processes and gather metrics
2. **Post-collection sleep**: Wait until baseline time (interval -
250ms)
3. **Baseline**: Bulk CPU refresh for newly registered PIDs (if any)
4. **Pre-collection sleep**: Wait 250ms for accurate CPU delta
calculation
## Current Behavior
if inline tui init fails, we panic
## Expected Behavior
If inline tui init fails, inline mode is disabled. We show the reason
its disabled when someone tries to use it.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
When exiting the TUI (especially via Ctrl+C), escape sequences leak to
the terminal:
```
^[]11;rgb:2121/2121/2121^[\^[[55;1R^[[?62;22;52c
```
This happens because the TUI queries terminal background color via OSC
11 to detect dark/light mode. The terminal responds with an escape
sequence, but if the program exits before fully consuming the response,
it appears in the terminal output.
## Expected Behavior
Clean terminal state after TUI exits, with no escape sequence artifacts.
## Related Issue(s)
N/A - discovered during development
## Solution
Added `drain_stdin()` function that polls and consumes any pending
terminal events before disabling raw mode. This clears any lingering OSC
responses (like the background color query response) before the terminal
is restored.
```rust
fn drain_stdin() {
use std::time::Duration;
while crossterm::event::poll(Duration::from_millis(5)).unwrap_or(false) {
let _ = crossterm::event::read();
}
}
```
The 5ms timeout is long enough to catch pending responses but short
enough not to noticeably delay exit.
## Current Behavior
When the daemon encounters a project graph error during task hashing, it
extracts the partial project graph from the error and continues hashing
tasks. This can produce incorrect hashes since the graph is incomplete.
## Expected Behavior
The error should be thrown immediately, preventing any hashing attempts
with an invalid project graph. This ensures we don't produce incorrect
task hashes that could lead to cache issues.
## Related Issue(s)
N/A - Bug fix discovered during development
## Current Behavior
The `rollup-plugin-postcss` has not released a new version in 4 years.
The deps it depends on are outdated and starting to cause problems with
peer-dep conflicts.
## Expected Behavior
Recreate the plugin within the `@nx/rollup` package to maintain the
functionality/behaviour and manage dependencies ourselves.
## Related Issue(s)
Closes NXC-3644
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
Running `nx test` with Vitest browser mode fails with error:
> "The browser configuration must have a 'name' property"
Array configs like `browser.instances` and `reporters` get duplicated,
breaking tests.
## Expected Behavior
Vitest browser mode and array configurations work correctly without
duplication.
## Related Issue(s)
Fixes#33591
## Current Behavior
Nx's AI agent detection currently identifies Claude Code, Repl.it, and
Cursor AI agents via environment variables, but does not detect
OpenCode.
## Expected Behavior
Nx should also detect when running under OpenCode AI agent by checking
for the `OPENCODE` environment variable, which OpenCode sets to `1` when
active.
## Related Issue(s)
N/A - Feature addition to improve AI agent detection coverage.
## Changes
- Added `is_opencode_ai()` function in
`packages/nx/src/native/utils/ai.rs`
- Updated `is_ai_agent()` to include OpenCode detection
- Added corresponding unit tests
## Current Behavior
For optional packages that are not installed when using yarn, we
currently add the package version to the key for the hash. NPM and PNPM
do not do this.
The results in inconsistent hashes for package dependencies when running
in different environments. For example, trying to use the cache created
in CI on linux on a mac where native dependencies are used.
**yarn on arm mac**
_note how the key has the version in it for the linux and x64 versions
that are not installed_
```
$ nx test foo | grep @nx/nx-
...
"npm:@nx/nx-darwin-x64@22.3.3": "14042642002999097748",
"npm:@nx/nx-linux-x64-gnu@22.3.3": "12169496858981304476",
"npm:@nx/nx-darwin-arm64": "1683411334940043113",
```
**npm on arm mac**
```
$ nx test foo | grep @nx/nx-
...
"npm:@nx/nx-darwin-x64": "14042642002999097748",
"npm:@nx/nx-darwin-arm64": "1683411334940043113",
"9980946580833020728",
"npm:@nx/nx-linux-x64-gnu": "12169496858981304476",
```
**pnpm on arm mac**
```
$ nx test foo | grep @nx/nx-
...
"npm:@nx/nx-darwin-arm64": "1683411334940043113",
"npm:@nx/nx-darwin-x64": "14042642002999097748",
"npm:@nx/nx-linux-x64-gnu": "12169496858981304476",
```
## Expected Behavior
Optional dependencies should be handled the same way from a hashing
perspective as installed dependencies.
**yarn on arm mac**
```
$ nx test foo | grep @nx/nx-
...
"npm:@nx/nx-darwin-x64": "14042642002999097748",
"npm:@nx/nx-linux-x64-gnu": "12169496858981304476",
"npm:@nx/nx-darwin-arm64": "1683411334940043113",
```
On test repo reduces the
`nx/js/dependencies-and-lockfile:createDependencies`:
- from `10506ms`
- to `3665ms`
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
CPU metrics collection can report inaccurate values where:
- Individual processes show inflated CPU usage
- Total CPU aggregation across all processes exceeds the system's
maximum available CPU
- This leads to confusing and misleading metrics data
## Expected Behavior
CPU metrics accurately reflect actual resource usage:
- Process CPU values are accurate
- Total CPU aggregation stays within system limits
- Metrics data is reliable and trustworthy
### Additional Notes
- **Root cause**: When registering a new process, we established a CPU
baseline by refreshing only that single process via `sysinfo`.
Internally, `sysinfo` calculates CPU% as `(process_cpu_time_delta /
wall_time_delta) * 100`. Refreshing a single process updates the wall
time reference but leaves the CPU time baselines of other processes
unchanged. In the next metrics collection, these other processes appear
to have consumed their CPU time over a shorter wall time period (based
on the last baseline), resulting in inflated percentages (e.g., 200%+
for single-threaded processes).
- This PR also improves initialization performance by only loading
necessary system data (processes, CPU, memory) instead of all system
information
- Upgrades `sysinfo` dependency to v0.37.2, which includes upstream CPU
measurement improvements.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Marketing pages (homepage, /react, /java, etc.) do not track scroll
depth. Only docs pages have scroll tracking via the ScrollableContent
component.
## Expected Behavior
Marketing pages now track scroll depth and fire scroll_0, scroll_25,
scroll_50, scroll_75, scroll_90 events to Google Analytics, matching the
existing docs page behavior.
## Related Issue(s)
Closes DOC-376
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
The inline tui runs some terminal escape codes to check cursor position,
these break when stdin isn't a tty (like in a git hook)
## Expected Behavior
The inline tui is disabled if stdin isn't a tty
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
The `migrations.json` file in the `@nx/maven` package is not included in
the `files` array in `package.json`. This means when the package is
published to npm, the migrations file is not included, preventing users
from running migrations.
## Expected Behavior
The `migrations.json` file should be included in the published package
so that Nx can discover and run migrations when users upgrade.
## Related Issue(s)
N/A - discovered during development
Exclude some handwritten files from the native build outputs. When those
files are updated in isolation, the build can replace them with stale
cached outputs. This is because they are not inputs of the native
builds, but are incorrectly stored as outputs of the native builds.
## Current Behavior
When using pnpm aliases, the project graph may miss the actual
dependency node (the aliased package overwrites it), resulting in
incomplete or confusing dependency graphs.
## Expected Behavior
The project graph should include both the alias and the actual
dependency node, matching the behavior of other package managers.
## Current Behavior
No daemon info is provided in `nx report`, but some issues are
exasperated by the daemon or may only show if the daemon is disabled.
This is useful context that we currently lack.
## Expected Behavior
`nx report` includes if the daemon is available, enabled but not
started, or disabled.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Running `nx show project` without specifying a project name fails, even
when inside a project directory:
```bash
cd packages/my-lib
nx show project
# Error: requires projectName argument
```
## Expected Behavior
When run from within a project directory, `nx show project` infers the
project from the current working directory:
```bash
cd packages/my-lib
nx show project # Shows my-lib configuration and targets
nx show project --json # Outputs JSON for my-lib
```
Explicit project name still works:
```bash
nx show project other-project
```
If cwd is not within any project, shows a helpful error with usage
instructions.
### Changes
- `command-object.ts`: Make `projectName` positional arg optional
(`[projectName]`)
- `project.ts`: Infer project from cwd using `findProjectForPath` when
no project specified
- `project.spec.ts`: Add unit tests for cwd inference, nested
directories, root projects, and error cases
## Related Issue(s)
Fixes#31055
> [!WARNING]
>
> <details>
> <summary>Firewall rules blocked me from connecting to one or more
addresses (expand for details)</summary>
>
> #### I tried to connect to the following addresses, but was blocked by
firewall rules:
>
> - `repo.gradle.org`
> - Triggering command: `/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
/usr/lib/jvm/temurin-17-jdk-amd64/bin/java
--add-opens=java.base/java.lang=ALL-UNNAMED
--add-opens=java.base/java.lang.invoke=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED
--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED
--add-opens=java.base/java.util=ALL-UNNAMED
--add-opens=java.prefs/java.util.prefs=ALL-UNNAMED
--add-opens=java.base/java.nio.charset=ALL-UNNAMED
--add-opens=java.base/java.net=ALL-UNNAMED
--add-opens=java.base/java.util.concurrent.atomic=ALL-UNNAMED
--add-opens=java.xml/javax.xml.namespace=ALL-UNNAMED
-XX:MaxMetaspaceSize=384m -XX:+HeapDumpOnOutOfMemoryError -Xms256m
-Xmx512m -Dfile.encoding=UTF-8 -Duser.country -Duser.language=en` (dns
block)
> - `staging.nx.app`
> - Triggering command: `/usr/local/bin/node node ./bin/post-install`
(dns block)
> - Triggering command: `/usr/local/bin/node /usr/local/bin/node
/home/REDACTED/work/nx/nx/node_modules/.pnpm/nx@22.2.0-beta.1_@swc-node+register@1.9.1_@swc+core@1.5.7_@swc+helpers@0.5.11__@swc+typ_e0638a3d25d549ce0cdd3a7d8bad3b61/node_modules/nx/src/project-graph/plugins/isolation/plugin-worker
/tmp/plugin3517-16-424.353971.sock @nx/enterprise-cloud` (dns block)
> - Triggering command: `/usr/local/bin/node /usr/local/bin/node
/home/REDACTED/work/nx/nx/node_modules/.pnpm/nx@22.2.0-beta.1_@swc-node+register@1.9.1_@swc+core@1.5.7_@swc+helpers@0.5.11__@swc+typ_e0638a3d25d549ce0cdd3a7d8bad3b61/node_modules/nx/src/project-graph/plugins/isolation/plugin-worker
/tmp/plugin4274-16-431.526748.sock @nx/enterprise-cloud` (dns block)
>
> If you need me to access, download, or install something from one of
these locations, you can either:
>
> - Configure [Actions setup
steps](https://gh.io/copilot/actions-setup-steps) to set up my
environment, which run before the firewall is enabled
> - Add the appropriate URLs or hosts to the custom allowlist in this
repository's [Copilot coding agent
settings](https://github.com/nrwl/nx/settings/copilot/coding_agent)
(admins only)
>
> </details>
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
>
> ----
>
> *This section details on the original issue you should resolve*
>
> <issue_title>Feature: allow `nx show targets` to infer project from
the cwd</issue_title>
> <issue_description>### Description
> When I'm already working inside a project's folder (for example
`github/abapify/packages/adk` that has its own `project.json`), I would
love to ask Nx to list the targets that belong to that project without
having to remember or type the project name. Ideally `npx nx show
targets` could detect the `project.json` in the current working
directory and operate on that project automatically.
>
> ### Current behavior
> Running the command from inside a project directory fails because the
CLI insists on a `--project` argument:
>
> ```
> $ cd github/abapify/packages/adk
> $ npx nx show targets
> Please provide a project name via --project=<name>
> ```
>
> ### Expected behavior
> If the current directory (or one of its ancestors) contains a
`project.json`, Nx should infer the project from that file and list the
targets without extra flags. This would make it much easier to explore
available targets while staying focused on a single project, especially
in large workspaces with many similarly named packages.
>
> ### Environment
> - Nx: 21.6.3
> - Node: 24.10.0
> - Package manager: bun 1.3.1
> - OS: WSL2 (Linux 6.6.87.2-microsoft-standard-WSL2)
> </issue_description>
>
> ## Comments on the Issue (you are @copilot in this section)
>
> <comments>
> </comments>
>
</details>
- Fixesnrwl/nx#33503
<!-- START COPILOT CODING AGENT TIPS -->
---
✨ Let Copilot coding agent [set things up for
you](https://github.com/nrwl/nx/issues/new?title=✨+Set+up+Copilot+instructions&body=Configure%20instructions%20for%20this%20repository%20as%20documented%20in%20%5BBest%20practices%20for%20Copilot%20coding%20agent%20in%20your%20repository%5D%28https://gh.io/copilot-coding-agent-tips%29%2E%0A%0A%3COnboard%20this%20repo%3E&assignees=copilot)
— coding agent works faster and does higher quality work when set up for
your repo.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
The `prettier` module is being resolved twice during the `format`
command execution and using a mix of `import`/`require`.
## Expected Behavior
The `prettier` module should be resolved once and reused.
## Current Behavior
The `central-publishing-maven-plugin` with `extensions=true` does not
work with Maven 4. Running `./mvnw deploy -Prelease` completes the build
but never triggers the deploy/publish phase - it stops at install.
This is a known issue tracked as
[MNG-8584](https://issues.apache.org/jira/browse/MNG-8584).
## Expected Behavior
Running `./mvnw deploy -Prelease -pl packages/maven/maven-plugin -am`
should publish the nx-maven-plugin to Maven Central.
## Related Issue(s)
Related to Maven 4 compatibility:
https://issues.apache.org/jira/browse/MNG-8584
## Changes
- Add explicit execution binding for `central-publishing-maven-plugin`
to the deploy phase (workaround for broken extensions mechanism in Maven
4)
- Remove `extensions=true` that doesn't work with Maven 4
- Update `central-publishing-maven-plugin` from 0.9.0 to 0.10.0
- Skip standard `maven-deploy-plugin` for nx-maven-plugin module (we use
central-publishing instead)
## Current Behavior
the plugins are disabled on vercel and netlify but there's no easy way
to disable them otherwise.
## Expected Behavior
there's an env var to disable each of the plugins: `NX_GRADLE_DISABLE` /
`NX_MAVEN_DISABLE` just like there is one for dotnet.
## Current Behavior
Maven e2e tests fail with two issues:
1. Spring Initializr rejects Spring Boot 3.4.0 (now requires >=3.5.0)
2. Parent POMs (`nx-parent` and `nx-maven-parent`) aren't installed
locally, causing Maven to fail when resolving `nx-maven-plugin:0.0.12`
since it's not yet published to Maven Central
## Expected Behavior
Maven e2e tests pass successfully by:
1. Using Spring Boot 4.0.0 which is supported by Spring Initializr
2. Installing parent POMs to local Maven repository so the plugin can
resolve its dependencies
## Related Issue(s)
Fixes the CI failures in maven e2e tests after the 0.0.12 version bump.
## Current Behavior
The prebuild-banner script requires an `enabled` boolean field that the
Framer API does not return, causing validation failures.
## Expected Behavior
Validation matches the actual API response format which uses
`activeUntil` for determining banner visibility instead of `enabled`.
Closes #CLOUD-4071
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
After running commands which spawn plugin workers on the main process
(`nx show project`, or any command with the daemon disabled) some users
(and notably @FrozenPandaz) experienced terminal issues that resulted in
↑ / ↓ printing escape codes instead of scrolling command history.
## Expected Behavior
This pull request updates how plugin worker processes handle their
input/output streams to improve terminal behavior and debugging
capabilities. The main change is switching the worker's stdio from
`inherit` to `pipe`, and then manually piping the worker's stdout and
stderr to the main process. This avoids terminal state issues and
enables better debugging.
**Plugin worker process I/O handling:**
* Changed the worker process `stdio` option from `'inherit'` to `'pipe'`
in `startPluginWorker`, preventing terminal state issues (such as broken
arrow key functionality) after Nx execution.
* Added logic to pipe the worker's `stdout` and `stderr` to the main
process, making it easier to debug and allowing plugins to communicate
metrics. Increased the max listener count on `process.stdout` and
`process.stderr` to avoid warnings from multiple listeners.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
We dont validate the size of the native file cache after copying it,
which sometimes fails and corrupts the data. This failure results in a
different size, so we can detect it. In certain situations, the
corruption causes node to hang instead of throw.
## Expected Behavior
We detect the corruption
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#30653Fixes#31300
I found regression in `replaceOverride` behavior that isn't guarded
against. There is migration from v17
(https://github.com/nrwl/nx/blob/20.8.x/packages/next/src/migrations/update-17-2-7/remove-eslint-rules-patch.ts#L17)
that shows that when `update` function returns `undefined`, then that
override entry should be removed.
We had no other unit tests to cover this case previously, so it was
missed until I tried cherry-picking the fix to `20.8.x` branch.
There was also a bug with flat config in v20 and v21 where not passing
`update` function for flat config leads to an error due to
`update(data)` being called without checking if `update` exists (since
it's optional). We never actually skip on passing `update` (which makes
`replaceOverride` useless since it's noop), so I marked it as required
arg now.
## Current Behavior
When `replaceOverride` is called with an update function that returns
`undefined`, the override block is not removed. This is inconsistent
with the JSON code path which uses `splice` to remove the override.
## Expected Behavior
When the update function returns `undefined`, the entire override block
should be deleted from the flat config, matching the JSON path behavior.
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
When running a task graph with continuous tasks and one of them is
terminated, the reverse continuous task deps that have no other tasks
that depend on them are also automatically terminated. This is fine in a
non-DTE context, but when running in a DTE context, the DTE task runner
must own the lifecycle of the continuous tasks, and Nx shouldn't
automatically terminate them.
## Expected Behavior
Nx shouldn't automatically terminate continuous tasks when running in a
DTE context.
## Current Behavior
The `create-nx-workspace` incorrectly offers `Vitest & Angular` as a
valid unit test runner choice when the bundler is something other than
`esbuild`.
## Expected Behavior
The `create-nx-workspace` should only offer `Vitest & Angular` as a
valid unit test runner choice when the bundler is `esbuild`.
## Related Issue(s)
Fixes#34014
## Current Behavior
On systems under heavy load, plugin loading can fail with:
```bash
Plugin Worker exited because no plugin was loaded within 10 seconds of starting up.
```
The initialization of the process metrics collection could potentially
cause this by blocking the loading of the plugin.
## Expected Behavior
Process metrics initialization no longer blocks critical startup paths,
allowing plugin loading to succeed regardless of system load.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Shared running tasks (tasks running in another process) do not appear in
the In Progress section of the TUI. They show the throbber as being in
progress, but are located in the Pending/Completed section.
## Expected Behavior
Shared running tasks (tasks running in another process) should appear in
the In Progress section of the TUI.
## Current Behavior
package installation does not set `windowsHide` so it flashes a terminal
window
## Expected Behavior
there should be no flashing terminal window
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
Adds a sm utility script to ease quickly checking changes against local
repos. Not a replacement for local registry + install, but good for
quick checks
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Bump gradle project graph plugin version to 0.1.11
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
We have a hard coded list of task targets to not exclude depends on.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
We resolve a gradle task such that we can identify if there are provider
dependency relationships involved. If there are, then do not exclude
depends on since Gradle needs the dependsOn tasks to fulfill providers.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
When processing Kotlin Multiplatform (KMP) projects, the Nx Gradle
plugin encounters ConcurrentModificationException errors because KMP
dynamically modifies the Gradle project's task and configuration
containers during dependency resolution. The plugin was resolving
configuration dependencies before processing tasks, which triggered
KMP's hierarchy finalization and dynamic task creation while the plugin
was still iterating over these collections.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The Gradle plugin should handle Kotlin Multiplatform projects without
errors by:
1. Processing tasks before resolving configuration dependencies,
preventing KMP from modifying task containers during iteration
2. Creating immutable snapshots of task and configuration collections
before iteration to avoid concurrent modification issues
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes NXC-3633
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
The Nx Plugin uses Nx as the backing mechanism, but Gradle still does
some caching behind the scenes. When using Nx and Gradle's caching at
the same time, there can be times where Gradle does not recognize input
changes and will not execute tasks that it mistakenly deems unchanged.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Ensure that the batch executor always reruns tasks and is not impacted
by the Gradle build cache.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes NXC-3649
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Caleb Ukle <caleb@nrwl.io>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
For 0.x versions, shift semver bump types down to follow the common
convention where breaking changes bump minor, and new features bump
patch:
- major -> minor
- premajor -> preminor
- minor -> patch
- preminor -> prepatch
- patch -> patch (unchanged)
This ensures that `nx release` with a breaking change on a 0.x package
(e.g., 0.1.0) bumps to 0.2.0 instead of 1.0.0.
Fixes NXC-3638
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
The migration generator (`@nx/plugin:migration`) fails when due to
ESLint flat config not being parsed correctly, leading to an error.
This happens because `replaceOverride` uses `parseTextToJson` to parse
the config, which fails for non-JSON-serializable JavaScript
expressions.
This PR fixes the issue by using AST parsing, like we did for
`hasOverrides` here https://github.com/nrwl/nx/pull/33548.
Fixes#34010
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
When adding a non-buildable JS library (`bundler: 'none'`) to a
workspace with an existing `@nx/js/typescript` plugin registration that
has build options configured, a duplicate plugin entry is unnecessarily
created in `nx.json`.
## Expected Behavior
Non-buildable libraries reuse the existing plugin registration when
`skipBuildCheck: true` is not specified, thereby avoiding duplicate
entries in `nx.json`. The `@nx/js/typescript` plugin will infer the
project as non-buildable because the library's `package.json` will have
entry points pointing to source files, so there's no need for a separate
plugin registration.
## Related Issue(s)
Fixes#33981
## Current Behavior
Rspack 1.7.0 is failing to create factories for internals with Module
Federation.
## Expected Behavior
Pin Rspack to 1.6.8 for now to ensure continued functioning of Module
Federation
## Current Behavior
PR #32915 changed how conventional commits determine version, making
them rely on commit scope:
commits with types configured to bump minor / major version bumps only
patch if commit scope exists and it does not include project name
## Expected Behavior
In our project we do not use projectName as commit scope, so we would
like to bring back old behavior, this can be achieved by adding option
to opt-out such behavior
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
## Current Behavior
- The `skipTypeChecking` option is a simple boolean that only allows
enabling/disabling type checking
- Rspack executor is missing the `runtimeDependencies` option that
webpack has
- The `cache` configuration is hardcoded and cannot be overridden by
users
## Expected Behavior
- New `typeCheckOptions` option allows configuring type checking with `{
async: true }` to run type checking in a separate process without
blocking the build
- The deprecated `skipTypeChecking` option is maintained for backward
compatibility
- Rspack now supports `runtimeDependencies` option for adding runtime
dependencies to generated `package.json` (useful for Docker installs)
- New `cache` option allows users to override webpack/rspack caching
behavior while maintaining backward-compatible defaults
## Related Issue(s)
N/A - Standalone feature
## Changes Made
### typeCheckOptions (webpack & rspack)
- Added `TypeCheckOptions` interface with `async` property
- Added `typeCheckOptions` option to plugin options interfaces
- Updated `apply-base-config.ts` to normalize `typeCheckOptions` from
deprecated `skipTypeChecking` for backward compatibility
- Added schema definitions to `schema.json` and `schema.d.ts`
### runtimeDependencies (webpack & rspack)
- Added `runtimeDependencies` option to `NxAppRspackPluginOptions`
- Updated `GeneratePackageJsonPlugin` to resolve and include runtime
dependencies
- Added schema definitions to `schema.json` and `schema.d.ts`
### cache (webpack & rspack)
- Added `cache` option to plugin options interfaces
- Updated `apply-base-config.ts` to check `'cache' in options` before
applying defaults
- Allows explicit `cache: undefined` to force cache to be disabled
- Maintains backward-compatible defaults:
- Webpack: `{ type: 'memory' }` for Node targets in watch mode
- Rspack: `true` for Node targets in watch mode, `true` in dependent
config
## Files Changed
**Webpack:**
-
`packages/webpack/src/plugins/nx-webpack-plugin/nx-app-webpack-plugin-options.ts`
-
`packages/webpack/src/plugins/nx-webpack-plugin/lib/apply-base-config.ts`
- `packages/webpack/src/executors/webpack/schema.json`
- `packages/webpack/src/executors/webpack/schema.d.ts`
- `packages/webpack/src/plugins/generate-package-json-plugin.ts`
**Rspack:**
- `packages/rspack/src/plugins/utils/models.ts`
- `packages/rspack/src/plugins/utils/apply-base-config.ts`
-
`packages/rspack/src/plugins/utils/plugins/generate-package-json-plugin.ts`
- `packages/rspack/src/executors/rspack/schema.json`
- `packages/rspack/src/executors/rspack/schema.d.ts`
**Documentation:**
- `astro-docs/.../webpack/Guides/webpack-plugins.mdoc`
- `packages/webpack/docs/webpack-build-executor-examples.md`
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
When generating Cypress component testing in Angular workspaces, the
base tsconfig sets moduleResolution to 'bundler' which causes TS5095
errors because 'bundler' requires module to be 'preserve' or 'es2015+'.
Cypress runs in Node.js and should use Node.js module resolution
instead. This fix sets moduleResolution to 'node' for Cypress
tsconfig.json templates.
## Current Behavior
When generating Cypress component testing configuration in Angular
workspaces, the generated `cypress/tsconfig.json` inherits
`moduleResolution: "bundler"` from the workspace base config. Since
Cypress uses `module: "commonjs"` for Node.js runtime, this causes
TypeScript compiler error TS5095: "Option 'bundler' can only be used
when 'module' is set to 'preserve' or to 'es2015' or later."
## Expected Behavior
The generated `cypress/tsconfig.json` should explicitly set
`moduleResolution: "node"` to match the `module: "commonjs"` setting,
preventing TS5095 errors. This aligns with how NestJS applications
handle the same issue (see #33607).
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
## Summary
Adds comprehensive Docker development guidance to the Nx Daemon
documentation.
Related to #33263, #30359, #14126
## What's included
This PR expands the existing Nx Daemon docs with a new "Running Nx in
Docker" section that covers:
- **Why the daemon often fails in Docker** - ephemeral filesystems,
inode/mtime changes from volume mounts, container restarts, IPC issues
- **Recommended approach** - disable daemon with `NX_DAEMON=false`
- **Example docker-compose setup** - minimal reproducible configuration
for local development
- **CI/CD best practices** - when to prefer stateless builds over daemon
caching
## Context
Several issues have been opened around daemon behavior in containers,
but the existing docs only briefly mention socket location
customization. Users are left wondering:
- Why doesn't the daemon work reliably in Docker?
- What's the recommended workflow for containerized development?
- How should CI pipelines handle this?
Issue #33263 specifically describes daemon crashes when running nx
between Docker and non-docker environments - this PR documents the
recommended workaround (`NX_DAEMON=false`) and explains why.
## Preview
The new section appears under the existing "Customizing the socket
location" heading and includes:
- Explanation of Docker-specific challenges
- Code examples for Dockerfile, docker-compose, and CLI
- Rule of thumb callout for quick reference
Open to feedback on structure or placement.
---------
Co-authored-by: kazuki <kazuki@kazukinoMacBook-Air.local>
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
Adds a new peerDepsVersionStrategy option that allows configuring how
peer dependencies versions are set when auto-fixing. When set to
'workspace', peer dependencies will use 'workspace:*' instead of the
installed or root package version. Defaults to 'installed' to maintain
backward compatibility.
## Current Behavior
A concrete peer dependency version is being fixed.
## Expected Behavior
User can choose between `installed` and `workspace` version strategies.
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
## Plan to Fix Inputs Documentation
Based on the issue, I need to correct the inputs documentation at
`/astro-docs/src/content/docs/reference/inputs.mdoc`. The problems are:
- [x] Fix the invalid syntax in "Source Files" section - currently shows
inputs as an object instead of an array
- [x] Document the `{ input: someNamedInput, projects: [] }` format for
referencing named inputs from specific projects
- [x] Document the `{ input: someNamedInput, dependencies: true }`
format for referencing named inputs from dependencies
- [x] Document the object form for fileset inputs (e.g., `{ fileset:
string }`)
- [x] Ensure all documented formats match the TypeScript type definition
- [x] Fix typo found in code review (to to -> to)
- [x] Remove targetDefaults wrapper from examples (per review feedback)
- [x] Use string syntactic sugar forms in examples and explain
equivalence to object forms
- [x] Fix comment to show object form equivalence instead of repeating
string form
## Changes Made
1. **Fixed Source Files section syntax**:
- Changed from invalid object syntax to correct array syntax
- Removed unnecessary targetDefaults wrapper per review feedback
- Added documentation for the object format with fileset property
2. **Added new section "Named Inputs from Other Projects"**:
- Documents `{ input: "production", projects: "mylib" }` format
- Documents `{ input: "production", projects: ["mylib", "myapp"] }`
format for multiple projects
- Uses string syntactic sugar `"production"` and `"^production"` in
examples
- Explains equivalence: `"production"` is shorthand for `{ "input":
"production" }`, `"^production"` is shorthand for `{ "input":
"production", "dependencies": true }`
3. **Fixed typo**: Changed "to to not invalidate" to "to not invalidate"
All changes validated with prettier formatting checks.
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Issue Title: Docs: correct inputs syntax and document missing formats
> Issue Description: The inputs docs appear inaccurate at
[nx.dev/docs/reference/inputs#source-files](https://nx.dev/docs/reference/inputs#source-files).
>
> * The shown inputs syntax isn’t valid; it should be an array.
> * The page doesn’t mention the `{ input: someNamedInput, projects: [\]
}` format.
> * It also doesn’t cover the object form for `deps`/`self` inputs.
>
> Valid types reference:
[https://github.com/nrwl/nx/blob/master/packages/nx/src/config/workspace-json-project-json.ts#L206](https://github.com/nrwl/nx/blob/master/packages/nx/src/config/workspace-json-project-json.ts#L206)
>
> Working with \[GitHub
Copilot\](User:d484ef82-7f7d-4a95-be09-9d82ca3905dc) on this.
> Fixes
https://linear.app/nxdev/issue/NXC-3369/docs-correct-inputs-syntax-and-document-missing-formats
>
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> [https://github.com/nrwl/nx](https://github.com/nrwl/nx)
>
> Comment by User d484ef82-7f7d-4a95-be09-9d82ca3905dc:
> 📋 I wasn't able to determine which GitHub repository to work in.
>
> I think it's one of these, but can you tell me which one is right?
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> Side not, copilot assignment didn't work. Would have been neat 🙂
>
> Comment by User d484ef82-7f7d-4a95-be09-9d82ca3905dc:
> Waiting for https://linear.app/nxdev/profiles/craigory to link their
GitHub account. [Click to authorize
→](https://linear.business.githubcopilot.com/linear/auth)
>
> Comment by User :
> This thread is for an agent session with githubcopilot.
>
> Comment by User :
> Created issue
[NXC-3369](https://linear.app/nxdev/issue/NXC-3369/docs-correct-inputs-syntax-and-document-missing-formats)
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> This comment thread is synced to a corresponding [thread in
Slack](https://nrwl.slack.com/archives/CT3CQ2F0D/p1761762896195989?thread_ts=1761762896.195989&cid=CT3CQ2F0D).
All replies are displayed in both locations.
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> @Linear create a docs issue, assign it to me and copilot
>
> Comment by User f5ae6d50-28e9-4ee7-ad51-3da8208d5914:
> Send a PR? 🙏
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> See these valid types:
[https://github.com/nrwl/nx/blob/master/packages/nx/src/config/workspace-json-project-json.ts#L206](https://github.com/nrwl/nx/blob/master/packages/nx/src/config/workspace-json-project-json.ts#L206)
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> Also on the same page, I don't see any mention of the `{ input:
someNamedInput, projects: [] }` format, nor the object form for deps /
self inputs
>
>
</details>
<!-- START COPILOT CODING AGENT TIPS -->
---
💡 You can make Copilot smarter by setting up custom instructions,
customizing its development environment and configuring Model Context
Protocol (MCP) servers. Learn more [Copilot coding agent
tips](https://gh.io/copilot-coding-agent-tips) in the docs.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
## Current Behavior
The GitHub Actions DTE example includes a redundant conditional checkout
step that has separate configurations for pull request and default
branch events, both performing the same checkout operation.
## Expected Behavior
The GitHub Actions example should use a single, simpler checkout
configuration that works for both pull request and default branch
events, removing redundant code.
## Related Issue(s)
This change simplifies the documentation example by removing redundant
checkout steps while maintaining the same functionality.
Updated Turborepo section to include robust browser-based graph
visualizations and Graphviz image exports.
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
TypeScript’s module resolution stop at project's root when resolving
modules.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
TypeScript’s module resolution will walk up to the workspace root when
resolving modules
## Changes Made
Convert the filePath to an absolute path inside findProjectFromImport
before calling resolveImportWithTypescript, because TypeScript’s module
resolution will not correctly traverse up the directory tree toward the
workspace root when given a relative path.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#33985
When a vitest config file is at the workspace root and contains a
`projects` property in the test configuration, the plugin now skips
inferring test targets for that config. This is because root workspace
configs act as orchestrators - the actual tests live in the individual
project configs referenced by `projects`.
Fixes#32471
## Current Behavior
The dev-server builder throws an error about the "define" option not
being supported in Angular < 21, even when users don't configure it. The
validation uses a truthy check that treats empty objects `{}` as true.
## Expected Behavior
The error should only throw when users explicitly configure define with
actual keys.
## Related Issues
Fixes#33964
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: leosvelperez <12051310+leosvelperez@users.noreply.github.com>
## Current Behavior
There is no straight-forward way to use the cwd as part of a tasks hash
## Expected Behavior
You can use `{workingDirectory: 'absolute'}` to factor the working
directory into the hash
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#33684
On test repo, the
`package-json:createNodes:isInPackageManagerWorkspacesTime` takes:
- Before the PR: 2356ms
- With PR: 23ms
This is achieved by avoiding unnecessary use of `minimatch` when a
direct string comparison is sufficient.
It also makes creation and logging of entire graph come down from
`23.6s` down to `18.5s`
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: meeroslav <meeroslav@users.noreply.github.com>
Add support for ESLint's new bulk suppression features introduced in
v9.24.0.
- Add `suppressAll` option to suppress all existing violations
- Add `suppressRule` option to suppress specific rule(s)
- Added `suppressionsLocation` option to specify custom location for the
suppressions file (defaults to eslint-suppressions.json)
- Include proper version checking for ESLint v9.24.0+
- Add related tests and documentation
- Update schema and TypeScript types
This allows teams to incrementally adopt stricter lint rules without
being overwhelmed by legacy violations.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
The `@nx/eslint` package currently doesn't support ESLint's bulk
suppression features. When teams want to enable new lint rules, they
must fix all existing violations first, which can be a significant
barrier to adopting stricter linting standards.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The @nx/eslint package now supports ESLint v9.24.0+'s bulk suppression
features through new flags:
- `suppressAll`: Suppresses all existing violations
- `suppressRule`: Suppresses specific rules
- `suppressionsLocation`: specifies a custom location for the
suppressions file (defaults to eslint-suppressions.json)
```json
{
"lint": {
"executor": "@nx/eslint:lint",
"options": {
"suppressAll": true
}
}
}
```
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
https://github.com/nrwl/nx/discussions/30620
This PR removes the variant check for deciding whether to use GitHub
templates for CNW. Moving forward, the first-level options are all
`nrwl/*` templates. The `Custom` option allows users to go back to the
previous presets.
Explains how to configure Tailwind CSS so that classes used in remote
applications are properly compiled by the host application. Covers both
Tailwind v3 (content array) and v4 (@source directive) configurations.
This PR fixes the `/changelog` page.
With `getStaticProps`, files were read at build time when copy-docs had
already copied them. With `getServerSideProps`, files are read at
request time on serverless functions where those files don't exist.
This PR reverts the changes to use `getServerSideProps` and uses a
middleware instead. This also has the benefit of keeping the pages
static, so we do not need edge functions to run their server function.
Fixed: https://nx-dev-git-doc-372-nrwl.vercel.app/changelog
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
## Current Behavior
Cypress Component Testing for zoneless Angular projects is not
supported.
## Expected Behavior
Cypress Component Testing for zoneless Angular projects should be
supported.
## Current Behavior
When generating Angular apps/libs with `setParserOptionsProject`, the
ESLint flat config output did not include the project-level
`parserOptions.project`, so type-aware lint rules still fail unless
users edit the config manually.
## Expected Behavior
Enabling `setParserOptionsProject` produces the appropriate
project-level `parserOptions.project` configuration in both flat ESLint
config and legacy `.eslintrc.json`, so type-aware linting works out of
the box.
## Related Issue(s)
Fixes#33944
## Current Behavior
When migrating Angular packages the `@angular/cli` package is not
updated as part of the `nx migrate` initial package updates to the
`package.json` file. Instead, it's updated at a later stage with a
migration generator. This happens for a couple of reasons:
- Angular CLI package group will update all the packages using a `^`,
which can result in workspaces getting a minor version of the packages
installed before Nx adds support for that minor version.
- Angular CLI migrations can error due to some assumptions that are not
always correct in Nx workspaces.
- The `nx migrate` command currently doesn't have the ability to ignore
the package group or migrations of a given package.
This is why the `@angular/cli` package is migrated "manually" in a
migration generator.
## Expected Behavior
The `@angular/cli` package should be updated as part of the package
updates performed by the `nx migrate` command while ignoring its package
group and migrations. The `@nx/angular` package already provides the
same set of migrations and more.
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
## Current Behavior
Creating a new Angular workspace with Vitest results in no test setup
being generated. This happens because the `vitest` option is no longer
available, and instead, there are two options: `vitest-angular` and
`vitest-analog`.
## Expected Behavior
Creating a new Angular workspace should prompt for Vitest with Angular
or Vitest with Analog to set up the tests.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: leosvelperez <leosvelperez@users.noreply.github.com>
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
The getDependentPackagesForProject function was crashing when processing
projects with non-npm external nodes (e.g., cargo: prefixed nodes from
@monodon/rust plugin). The code only handled npm: prefixed externals and
treated everything else as workspace libraries, causing undefined access
errors when cargo externals were encountered.
This fix adds a check to skip external nodes that aren't npm-prefixed by
detecting the presence of a colon in the dependency target. Only npm:
prefixed externals are processed as npm packages, and other external
prefixes (cargo:, maven:, etc.) are now properly skipped.
Fixes#32819
## Current Behaviour
The ignorePatternsForPlanCheck configuration option in nx.json for
version plans lacks
documentation about the pattern syntax. Users attempting to use negation
patterns (e.g.,
["*", "!src/"]) may experience unexpected behavior because gitignore
semantics don't work
as intuitively expected with such patterns.
## Expected Behaviour
The documentation and JSDoc comments now clearly explain:
- That ignorePatternsForPlanCheck follows gitignore semantics
- Working patterns like ["**/*.spec.ts"] and ["**/*.ts", "!**/src/**"]
- Non-working patterns like ["*", "!src/"] and why they don't work as
expected
- Recommended approach of using file extension patterns instead of
wildcards when trying to
ignore all files except those in specific directories
## Related Issues
Fixes#30324
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
When running single tasks we have a "minimal" tui, but that minimal tui
still makes it really hard / impossible to use some of the terminals
built in features... like:
- Find (can only find what's currently rendered by tui)
- Text select + copy (can only select what's rendered to screen, copied
text includes the frame around the tui / scrollbar)
## Expected Behavior
When running single tasks we can use an inline viewport to render some
tui widgets at the bottom of the viewport, and terminal output can be
printed above.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Disabling Maven e2e tests since something with e2e setup breaks when we
try to update the spring boot version.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
make sure canonical always points to nx.dev and not a subdomain preview
incase they're index.
<img width="1728" height="863" alt="image"
src="https://github.com/user-attachments/assets/8e7d91c1-277b-4a2a-91ec-732f7f4f37ae"
/>
also confirm that robots.txt still has deny for non prod builds.
this is done via middleware since canonical url is controlled via astro
config 'site' property. which is used to control other aspects that we
do want to be preview URL domains (like navigation). so we have a
middleware to always override the url to match prod.
also nextjs side was already overriding this in `_app.tsx`
This PR adds the ability to consumer banner data for nx.dev (both astro
and next.js) from a remote JSON file. This is only enabled if
`BANNER_URL` environment variable is set.
The `banner-config.json` files are committed for both astro and next.js,
so before we consume banner JSON from Framer, we can use this as the
source of truth rather than update the component code.
Once we switch completely to Framer CMS, we can remove the committed
JSON files.
Note: A redeploy is required for banner changes to take effect. In the
future we may be able to do this dynamically in Astro.
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Maven plugin was complaining about Spring-boot version being behind 3.5
when running e2e suite. Also bumped down maven plugin version since
version 0.0.12 could not be found at the time of this PR.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
The inferred tasks documentation at
https://nx.dev/docs/concepts/inferred-tasks does not mention the
`include` or `exclude` options on plugins, even though this is a common
and useful feature for scoping plugins to specific projects.
## Expected Behavior
The inferred tasks documentation now includes a new section called
"Scope Plugins to Specific Projects" that explains:
- How to use `include` and `exclude` properties in plugin configuration
- What the glob patterns match against
- Use cases for this feature (scoping plugins, applying different
options to different projects)
This aligns with the existing documentation in the nx.json reference
guide.
## Related Issue(s)
Fixes DOC-367
## Current Behavior
When generating a React Module Federation remote with webpack bundler in
a TypeScript
Solution setup, the generator incorrectly sets the production webpack
config path in the
project configuration. Additionally, the sourceRoot property is not
being set in
package.json for TS Solution setups, which causes issues with module
federation's ability
to locate source files correctly.
## Expected Behavior
When using a TypeScript Solution setup:
- The production webpack config should not be explicitly set in the
build target's
production configuration (it will be inferred correctly)
- The sourceRoot property should be set in package.json under the nx
configuration to
properly identify the project's source directory
- The typecheck target should be added as a dependency for both build
and serve targets
## Related Issue(s)
Fixes#31029
## Current Behavior
The `replace-removed-matcher-aliases` migration from `@nx/jest` is not
run when migrating to Angular v21 (and updating Jest to v30). That
migration targets the original package update for Jest v30 (Nx 21.3.0),
which was incompatible with Angular < 21, so it wouldn't have run for
Angular workspaces at the time. Now that Angular is being updated to
v21, Jest is updated to v30, but the migration generator is not running.
## Expected Behavior
The `replace-removed-matcher-aliases` migration from `@nx/jest` should
run when migrating to Angular v21 (and updating Jest to v30).
## Current Behavior
The Maven version used for development dependencies is currently set to
3.9.11 in both pom.xml and mise.toml.
## Expected Behavior
The Maven version should be updated to 4.0.0-rc-5 to align with the
Maven 4 version already used in the batch-runner component.
## Related Issue(s)
N/A - This is a dependency version update to ensure consistency across
the Maven plugin ecosystem.
## Changes
- Updated `maven.version` property in pom.xml from 3.9.11 to 4.0.0-rc-5
- Updated maven tool version in mise.toml from 3.9.11 to 4.0.0-rc-5
This ensures that developers working on the Nx Maven plugin use the same
Maven 4.0.0-rc-5 version across all components.
## Current Behavior
The Maven plugin version is currently at 0.0.11.
## Expected Behavior
This PR bumps the Maven plugin version to 0.0.12 and creates a migration
for Nx 22.4.0-beta.0. This allows users to automatically update their
pom.xml files when they upgrade to the next version of Nx.
## Related Issue(s)
N/A - Version bump
## Current Behavior
The daemon currently depends on client requests failing with a
`LOCK_FILES_CHANGED` error to trigger a restart. This creates several
issues:
- The daemon may stay running with stale dependencies if no requests
come in
- The client must wait for a request to fail to trigger reconnection
- Special-case error handling is scattered across the client code
## Expected Behavior
The daemon should proactively restart itself when lock files change, and
the client should gracefully reconnect with exponential backoff for any
server shutdown scenario.
## Changes
### Client-Side: Exponential Backoff Reconnection
- Add `handleConnectionError()` method that retries with exponential
backoff (10ms → 5000ms, 30 attempts max)
- Preserve pending messages during reconnection and resend them once the
new daemon is available
- Remove special-case handling for `LOCK_FILES_CHANGED` and
`NX_VERSION_CHANGED` errors
- Remove `retryMessageAfterNewDaemonStarts()` method as it's no longer
needed
### Server-Side: Self-Restart on Lock File Changes
- Add `startNewDaemonInBackground()` to spawn a replacement daemon
before shutdown
- Add `handleServerProcessTerminationWithRestart()` for restartable
shutdown scenarios
- Detect lock file changes and proactively start a new daemon before
responding with an error
- Keep version change handling simple (just exit, no restart)
## Benefits
- **More Resilient**: Client recovers from any server shutdown, not just
specific errors
- **Cleaner Architecture**: Server manages its own lifecycle, client
doesn't need special cases
- **No Request Dependency**: Daemon doesn't wait for requests to detect
changes
- **Reduced Error Spam**: Exponential backoff prevents connection error
floods
- **Future-Proof**: Foundation for other restart scenarios (plugins,
config changes)
## Related Issue(s)
Fixes https://github.com/nrwl/nx/issues/30514
Fixes https://github.com/nrwl/nx/issues/29118
## Summary
Adds a batch executor for Nx Maven that enables parallel multi-task
execution with significant performance improvements. The batch runner
keeps Maven resident in memory, avoiding cold start overhead for each
task.
## Changes
### 1. Batch Runner JAR (`packages/maven/batch-runner`)
- **ResidentMavenExecutor**: Uses Maven 4.x's `ResidentMavenInvoker` to
keep Maven in memory
- **NxMaven**: Custom Maven wrapper that caches project graphs and
sessions across invocations
- **CachingResidentMavenInvoker**: Preserves session state so artifacts
from `jar:jar` are visible to `install:install`
- **BuildStateManager**: Applies/records build states for
cross-invocation caching
- Maven 4.x dependencies are shaded into the JAR for standalone
execution
### 2. TypeScript Executors (`packages/maven/src/executors/maven`)
- **maven.impl.ts**: Single-task executor using `mvnw`/`mvn`
- **maven-batch.impl.ts**: Batch executor that invokes the batch runner
JAR
- Automatic Maven version detection and executable resolution
### 3. Shared Utilities (`packages/maven/shared`)
- `BuildState`, `BuildStateApplier`, `BuildStateRecorder` for
cross-invocation state
- `MavenCommandResolver` for detecting Maven executable
- Reusable across batch-runner and maven-plugin modules
### 4. Maven Plugin Updates (`packages/maven/maven-plugin`)
- Updated to use `@nx/maven:maven` executor (batch-aware)
- Improved `GitIgnoreClassifier` for nested .gitignore handling
- Cache config tweaks for compiler inputs
## Performance
| Scenario | Before | After |
|----------|--------|-------|
| Cold start per task | 100-500ms | N/A (one-time init) |
| Per-task execution | 100-500ms | ~1.3ms (cached) |
| Improvement | - | **75-385x faster** |
## Version Support
- **Maven 4.x**: Full support with ResidentMavenExecutor (optimized)
- **Maven 3.x**: Falls back to ProcessBasedMavenExecutor (subprocess)
## Testing
- E2E tests for Maven 4.0.0-rc-4, 4.0.0-rc-5
- Unit tests for TypeScript executors
- Tests for GitIgnoreClassifier
## Current Behavior
Uses subprocess execution via `mvnw`/`mvn` for each task.
## Expected Behavior
Batch execution keeps Maven resident, dramatically reducing per-task
overhead.
## Related Issue(s)
Part of Maven integration improvements.
---------
Co-authored-by: Max Kless <maxk@nrwl.io>
## Current Behavior
The tui shouldn't show for single tasks
## Expected Behavior
The tui isn't shown for single tasks
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
Two issues with the .NET dependency graph:
1. Issue #33653: When a .NET project uses multi-targeting
(<TargetFrameworks> plural), its project reference dependencies
disappear from the Nx graph.
2. Issue #33397: Transitive dependencies are incorrectly shown as direct
dependencies. For example, if A → B → C, the graph shows A depending on
both B and C, when it should only show A → B.
## Expected Behavior
1. Multi-targeting projects should correctly show their dependencies in
the graph.
2. Only direct dependencies should be shown, not transitive ones. Nx
handles transitive dependencies through the dependency chain.
### Solution
Multi-targeting fix (#33653)
MSBuild creates multiple nodes for multi-targeting projects:
- An "outer build" with TargetFrameworks set but TargetFramework empty
- "Inner builds" for each target framework with TargetFramework set
The fix groups nodes by project file path and prefers inner builds
(which have properly resolved references) over outer builds.
### Transitive dependency fix (#33397)
Changed from using ProjectGraphNode.ProjectReferences (which includes
transitive dependencies in multi-targeting scenarios) to
ProjectInstance.GetItems("ProjectReference") which returns only direct
references defined in the project file.
## Related Issue(s)
Fixes#33653Fixes#33397
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
Templates use `"*"` for workspace dependencies in individual
package.json files. This works for npm but breaks pnpm, yarn, and bun
which require the `workspace:` protocol for proper symlinking.
For pnpm, yarn, and bun: automatically convert `"*"` dependencies to
`"workspace:*"` in all workspace package.json files. npm is left
unchanged since it handles `"*"` natively.
Also adds support for 2-level nested projects (e.g.,
`libs/shared/models/package.json`).
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
Sync generators are processed in the background by the daemon server.
Their results are cached and reprocessed when the project graph is
recomputed. There are currently two issues:
- The cache is only invalidated after the project graph finishes
recomputing, which means that there's an interval between files changed
(triggering the project graph recomputation) and the recomputation
finishes, where the cache is not invalidated, and it's stale. During
that interval, any request to get the sync generator changes will use
the stale cache.
- Sync generators are scheduled to be processed after the project graph
is recomputed, so a quick succession of recomputations can be coalesced.
The problem is that the scheduled closure uses the project graph from
the initial scheduling, rather than the latest available project graph
at the time it runs. This results in the usage of stale data to process
the sync generators.
## Expected Behavior
Getting sync generators changes should always return up-to-date
information.
## Current Behavior
When database initialization fails due to filesystem issues, permission
problems, or environment incompatibilities (like WAL mode not being
supported), Nx shows generic error messages that don't provide
actionable guidance to users. For example:
- "Unable to create db lock file: PermissionDenied"
- "Unable to set journal_mode: <sqlite error>"
This makes it difficult for users to diagnose and resolve issues,
especially in restricted environments like Docker containers, network
filesystems, or WSL1.
## Expected Behavior
With this PR, database initialization errors now provide:
1. **Context-specific error messages** - Different guidance based on the
error type:
- Permission denied: Instructions about file ownership, Docker volume
permissions, and read-only filesystems
- Storage full: Suggestions to free disk space
- Already exists: Guidance about stale files from crashed processes
2. **Automatic WAL mode fallback** - When WAL journal mode is not
supported by the filesystem, Nx now automatically falls back to DELETE
journal mode instead of failing. This improves compatibility with:
- Network filesystems (NFS, CIFS)
- Some Docker volume configurations
- Other environments with limited locking support
3. **WSL1 detection** - Proactively detects WSL1 environments (which
have known WAL incompatibilities) and uses DELETE mode from the start,
avoiding failed attempts and retries.
4. **Better cleanup on retry** - When database initialization fails and
needs to retry, all auxiliary files (WAL and SHM files) are also cleaned
up, not just the main database file.
5. **Actionable reporting instructions** - All error messages now
include:
- How to capture detailed logs
(`NX_NATIVE_FILE_LOGGING=nx::native::db=trace`)
- Link to create an issue
- Suggestion to run `nx reset`
## Current Behavior
When users press unhandled keys in the TUI (e.g., pressing `i` on a
completed task, or typing in a non-interactive terminal pane), nothing
happens and there's no feedback explaining why.
Similarly, when users press certain key bindings like `c` to copy
output, the action succeeds but there's no visual confirmation.
## Expected Behavior
### Hint Popups for Unhandled Keys
Users now see helpful hint popups when pressing keys that don't work in
the current context:
- Pressing `i`, `c`, or `Ctrl+A` in the dependency view (task hasn't
started yet)
- Pressing `i` on a task that doesn't support interactive mode
- Pressing character keys in a terminal pane that's not in interactive
mode
The hints explain what's happening and guide users on how to proceed.
### Status Messages for "Invisible" Actions
When users perform actions without obvious visual feedback, a status
message now appears in the terminal pane's bottom border:
- `Output copied` when pressing `c` to copy
- `Sent to assistant` when pressing `Ctrl+A`
### Configuration Option
Users who prefer not to see hint popups can disable them in `nx.json`:
```json
{
"tui": {
"suppressHints": true
}
}
```
Current Behavior
When using pnpm catalogs to manage dependency versions, the Storybook
utilities and ESLint version-utils read package.json directly using
readJson() or readJsonFile(). This approach doesn't resolve catalog
references like catalog:default, causing version detection to fail or
return incorrect values.
For example, if package.json contains:
{
"devDependencies": {
"storybook": "catalog:default"
}
}
The current code would return "catalog:default" as the version string
instead of resolving it to the actual version (e.g., "8.5.0").
Expected Behavior
Use the getDependencyVersionFromPackageJson() helper from @nx/devkit
which properly handles pnpm catalog resolution. This ensures that
version detection works correctly regardless of whether dependencies are
specified directly or via pnpm catalogs.
The helper:
- Resolves catalog: references to their actual versions
- Falls back gracefully when catalogs aren't in use
- Maintains consistent behavior across different package managers
Related Issue(s)
Fixes issues with pnpm catalog compatibility in Storybook generators and
ESLint utilities.
Related to #29772
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
Nx doesn't generate projects with Prettier v3.
## Expected Behavior
Nx should generate projects with Prettier v3.
## Related Issue(s)
Fixes#30801
## Current Behavior
There's a deadlock between the Angular and Jest package updates
requirements (`requires` and `incompatibleWith`) that prevents updating
Jest to v30 and `jest-preset-angular` to v16.
## Expected Behavior
Updating to Angular v21 should result in updating Jest to v30 and
`jest-preset-angular` to v16.
This is ensured by moving the `jest-preset-angular` package update
definition to the `@nx/jest` package and processing the `@nx/angular`
package updates before `@nx/jest`. That way, by the time `@nx/jest` is
processed, the migrator would have collected the Angular v21 updates,
and the requirements will be met.
## Current Behavior
The nx-dev Next.js app can only serve pages from its own codebase or
proxy to Astro docs.
## Expected Behavior
Support proxying specific pages to a Framer site via environment
variables:
- `NEXT_PUBLIC_FRAMER_URL`: Base URL of the Framer site
- `NEXT_PUBLIC_FRAMER_REWRITES`: Comma-separated paths for new pages
For existing pages like `/ai`, the proxy is handled in
`getServerSideProps`.
## Related Issue(s)
Closes DOC-349
Co-authored-by: Claude <noreply@anthropic.com>
Removed 'node_modules' from the ignore list for asset copying.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Updating Nx to v22 breaks my app. Some projects use generated Prisma
clients which, because of how Prisma binaries work, have to be generated
to `node_modules` in order to work both locally and in Docker context.
With Nx v22 Prisma client is not copied when project is built using
`@nx/esbuild:esbuild` (or any other executor supporting `assets`
property) without any error or warning. It took mi couple of hours to
pinpoint the exact line of code responsible for this. `node_modules` dir
is hardcoded there without any possibility to be overridden.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Prisma client can be copied from `node_modules` to project output
directory when building.
Ignoring `node_modules` is removed **or can be overridden**. I'm open to
any solution which will let me update Nx in my repository.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Jack Hsu <jack.hsu@gmail.com>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
This PR adds a validation to the directory prompt, so users should not
hit the error as often. Only possible now if they pass the arg from CLI
_and_ they are in non-interactive mode.
We also added some more data to help debug problems, such as node
version, template/preset chosen, etc. And updated the message in
"custom" preset prompt to align with the more effective "full platform"
prompt.
Note: Also update the error message (if it hits) to be the same in new
flow and old flow.
## Related Issue(s)
Closes NXC-3624
---------
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
The `argv` field was already implemented in `PreTasksExecutionContext`
and `PostTasksExecutionContext` but lacked tests and documentation for
plugin authors to discover and use it.
## Changes
- **Added unit tests**
(`packages/nx/src/daemon/server/handle-tasks-execution-hooks.spec.ts`)
validating that `argv` flows correctly through hook handlers for
different command patterns (direct, affected, run-many)
- **Enhanced existing documentation** in
`astro-docs/src/content/docs/extending-nx/task-running-lifecycle.mdoc`
with a new section covering:
- Context property definitions showing the `argv` field
- Examples showing how to detect command types (direct execution,
affected, run-many)
- Example demonstrating conditional analytics based on the original
command
- Common command patterns reference
- Best practices for defensive argv parsing
## Usage
```typescript
import type { NxPlugin, PostTasksExecutionContext } from '@nx/devkit';
export const myPlugin: NxPlugin = {
name: 'my-plugin',
postTasksExecution: async (options, context: PostTasksExecutionContext) => {
// Distinguish between nx build my-app vs nx affected -t build
if (context.argv.includes('affected')) {
console.log('Running in affected mode');
}
}
};
```
Fixes
https://linear.app/nxdev/issue/NXC-3382/add-contextargv-to-task-execution-hook-contexts
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Issue Title: Add context.argv to task execution hook contexts
> Issue Description: Expose the original CLI arguments on the plugin
worker so hooks can distinguish how execution was started (e.g., `nx
build nx-api` vs `nx affected -t build`). Proposal: include the invoking
argv on the hook context (e.g., `context.argv`).
> Fixes
https://linear.app/nxdev/issue/NXC-3382/add-contextargv-to-task-execution-hook-contexts
>
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> [https://github.com/nrwl/nx](https://github.com/nrwl/nx)
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> Aha! that worked - so you can tell it to assign to copilot instead of
"me and copilot"
>
> Comment by User d484ef82-7f7d-4a95-be09-9d82ca3905dc:
> 📋 I wasn't able to determine which GitHub repository to work in.
>
> I think it's one of these, but can you tell me which one is right?
>
> Comment by User :
> Created issue
[NXC-3382](https://linear.app/nxdev/issue/NXC-3382/add-contextargv-to-task-execution-hook-contexts)
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> This comment thread is synced to a corresponding [thread in
Slack](https://nrwl.slack.com/archives/C070BJ2JYLW/p1761928859857989?thread_ts=1761928859.857989&cid=C070BJ2JYLW).
All replies are displayed in both locations.
>
> Comment by User :
> This thread is for an agent session with githubcopilot.
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> @Linear make a ticket and assign it to copilot
>
> Comment by User f5ae6d50-28e9-4ee7-ad51-3da8208d5914:
> Makes sense to me
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> Sure, context.argv?
>
> Comment by User f5ae6d50-28e9-4ee7-ad51-3da8208d5914:
> We can add them as `argv`?
>
> Comment by User f5ae6d50-28e9-4ee7-ad51-3da8208d5914:
> Yeah they would run on the plugin worker so it's not there
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> @jason we could add `originalArgv` to the contexts?
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> Eh, probably not... they run on the plugin worker
>
> Comment by User 4215f3ef-50bd-4f09-85a0-b489c88057b6:
> Yeah, I don't think the hooks know.... I'd be curious if process.argv
would just have that info though
>
> Comment by User 439b15a6-827b-4258-971a-d86133ad59de:
> payfit does
>
> Comment by User 74901385-a023-4825-8470-fe68b1b55664:
> I can’t see anything about that in the docs - so I would assume the
hooks are agnostic to how the tasks were triggered?
>
> Comment by User 74901385-a023-4825-8470-fe68b1b55664:
> so they’re asking is there’s a way to tell the difference between `nx
build nx-api` or `nx affected -t build` in the task hook?
>
> Comment by User 74901385-a023-4825-8470-fe68b1b55664:
> > I’ve been playing around with the Task Execution Hooks, specifically
the postTasksExecution hook, and I think it will be really useful for me
to grab some detailed metrics for our specific use cases.
> > What I feel like it’s missing is a way to see what command actually
started the task execution, whether it was a specific target or an
affected command. As long as it was a specific target, I think the tasks
are sorted in order so the last taskResult will probably be the actual
target of the command but for affected it seems a bit more random what
the last result will be.
> > Is there a way to know exactly which command kicked off the ‘task
execution’?
>
>
</details>
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: AgentEnder <6933928+AgentEnder@users.noreply.github.com>
Co-authored-by: Craigory Coppola <craigorycoppola@gmail.com>
Co-authored-by: Caleb Ukle <caleb@nrwl.io>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Copilot <Copilot@users.noreply.github.com>
## Current Behavior
The same task can be pinned in multiple terminal panes of the TUI. This
causes one pane to scroll the other because they share the same data.
## Expected Behavior
The same task can only be pinned in a single terminal pane of the TUI.
## Current Behavior
The e2e test `should emit decorator metadata when using --compiler=swc`
fails because the regex `/Foo=.*?_decorate/` expects the old transpiled
output format where classes were assigned to variables.
## Expected Behavior
The test should pass by matching the current SWC output format which
uses native ES class syntax.
## Solution
Updated the regex from `/Foo=.*?_decorate/` to `/class
Foo.*_ts_metadata/` which:
- Matches `class Foo` (native ES class syntax)
- Verifies `_ts_metadata` is present (decorator metadata)
## Current Behavior
When `NX_NATIVE_COMMAND_RUNNER=false` is set, tasks running in the TUI
don't display any output in the terminal pane. The pane remains empty
even though the task is running.
## Expected Behavior
Task output is displayed in the TUI terminal pane regardless of the
`NX_NATIVE_COMMAND_RUNNER` setting.
## Related Issues
Fixes#32803
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
When upgrading to Angular 21 with Jest, users may encounter TypeScript
compilation issues because their `tsconfig.spec.json` files don't have
`isolatedModules: true` set, which is required for compatibility with
Jest and `jest-preset-angular`.
## Expected Behavior
After running `nx migrate`, Angular projects using Jest will
automatically have `isolatedModules: true` added to their
`tsconfig.spec.json` files (or custom test tsconfig files referenced by
`@nx/jest:jest` tasks) if not already set or inherited from a parent
tsconfig.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Update references to disablement variable for metrics collection for Nx
Cloud enterprise users.
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
When using `@nx/node:library` generator with `--compiler=swc`, the
generator
was incorrectly adding `tslib` as a dependency instead of
`@swc/helpers`.
This change fixes two issues:
1. Pass the correct bundler (matching the compiler) to
jsLibraryGenerator
so it adds the correct helper dependency to the project's package.json
2. Update ensureDependencies to only add tslib when compiler is tsc
Fixes#31202
Fixes#32069
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
The Azure Pipelines schema requires fetchDepth to be a string, but the
generator was outputting a number.
This fix changes the value to a string to match the official schema
specification.
## Current Behavior
The generator creates `azure-pipelines.yml` with `fetchDepth: 0`
(number), which causes YAML schema validation error because the Azure
Pipelines schema expects `fetchDepth` to be a string.
According to the [Azure Pipelines
schema](https://raw.githubusercontent.com/microsoft/azure-pipelines-vscode/master/service-schema.json),
`fetchDepth` is defined as:
```json
"fetchDepth": {
"description": "Depth of Git graph to fetch",
"$ref": "#/definitions/string"
}
```
## Expected Behavior
The generator should output `fetchDepth: '0'` (string) to match the
schema specification and prevent validation errors.
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
## Current Behavior
If a workspace uses pnpm and adds a local patch to a dependency (e.g.
`vitest`), this patch is not taken into account when computing that
dependency's hash for purposes of determining cache changes. In
practice, you could patch vitest locally, and tests would pull from the
cache.
## Expected Behavior
Patches can alter behavior in the same way that updating the version
could, it's just that the version is not created and the patch is
applied locally.
This updates the pnpm lockfile parsing functionality to read the patches
field into a map and then combine the patch hash with the integrity
hash. The integrity hash ONLY represents the remote / tarball
intergrity, so these have to be combined in order to create a proper
key.
## Related Issue(s)
(Could not find any, but saw this in my work today)
---------
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Due to this PR https://github.com/swc-project/pkgs/pull/53 at SWC, it is
not possible to use the latest version of @swc/cli in NX.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
stdout and stderr are now handled more precisely, allowing you to update
to the latest version of @swc/cli.
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
## Current Behavior
When a project has a `project.json` file but no `name` field, the
`addBuildAndWatchDepsTargets` function in
`packages/js/src/plugins/typescript/util.ts` returns early without
creating build and watch deps targets, even if the project has a valid
name in its `package.json`.
## Expected Behavior
The function should fall back to checking `package.json` for the project
name when `project.json` exists but has no `name` field, allowing the
build and watch deps targets to be created properly.
## Related Issue(s)
This fixes an issue where projects with `project.json` files missing the
`name` field would not get proper build and watch dependency targets
generated.
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Colum Ferry <cferry09@gmail.com>
## Current Behavior
`getProjectPathsAffectedByDependencyUpdates` in
`@packages/nx/src/plugins/js/project-graph/affected/lock-file-changes.ts`
doesn't return projects affected when updating `pnpm.overrides` or
`overrides` in package.json.
## Expected Behavior
When `overrides`, `resolutions`, or `pnpm.overrides` fields are changed
in package.json, the affected projects should be properly detected and
returned.
## Related Issue(s)
This addresses reports that affected project detection isn't working
properly when package manager override configurations are changed.
## Changes Made
- Enhanced `getTouchedNpmPackages` function to detect changes to
`overrides`, `resolutions`, and `pnpm.overrides` fields
- When a known package is changed in overrides, only that specific
package is marked as affected
- When an unknown package is changed in overrides, all projects are
marked as affected (since overrides can affect transitive dependencies)
- Added comprehensive tests for all override scenarios
🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
### Summary:
This PR updates the Nx documentation for the Storybook migration
generator to ensure clear and accurate guidance for migrating to
Storybook version 9. It replaces outdated references to version 8,
corrects migration links, and updates example configurations for Angular
and React (Vite) projects to reflect Storybook v9. These improvements
help users follow the correct steps and avoid confusion when upgrading
their workspace to the latest major release.
### Key Updates:
- Updated all migration documentation links and text to target Storybook
v9 resources.
- Corrected example .storybook/main.js|ts file descriptions for Angular
and React projects to reference version 9.
[[1]](diffhunk://#diff-2bd0403b5cc6e0c92d83a89400b36d55ad50eb0f82688aa976ecb3c93ff69eceL44-R44)
[[2]](diffhunk://#diff-2bd0403b5cc6e0c92d83a89400b36d55ad50eb0f82688aa976ecb3c93ff69eceL61-R61)
- Ensured users will be directed to the right guides and migration steps
for a smoother upgrade experience.
### Type of Change:
Documentation only; no changes to code or functionality.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
N/A - Docs update
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
N/A - Docs update
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
N/A
## Current Behavior
The `pageGenerator` has the option `fileName`, but it is not affecting
anything.
## Expected Behavior
The `pageGenerator` has the option `fileName`, it will define the page
file name.
## Current Behavior
The `recordStat` telemetry for `create-nx-workspace` and
`create-nx-plugin` completion events does not include the Nx Cloud
connect URL.
## Expected Behavior
The connect URL (e.g., `https://cloud.nx.app/connect/{shortlinkId}`) is
now included in the completion metadata sent to `/nx-cloud/stats`.
## Related Issue(s)
N/A - Internal telemetry enhancement
NODE_VERSION was set only on the mise-action step, so subsequent steps
defaulted to the wrong node version and corepack couldn't create the
pnpm shim.
Also update corepack first, otherwise you might run into intermittent
integrity check issues:
- https://github.com/nodejs/corepack/issues/612
- https://vercel.com/kb/guide/corepack-errors-github-actions
---
Before (NODE_VERSION at step-level):
1. mise-action runs with NODE_VERSION=20
- mise installs Node 20
- mise adds /home/runner/.local/share/mise/installs/node/20.x.x/bin/ to
PATH
2. corepack enable runs - NODE_VERSION is NOT set anymore (step env is
gone)
- corepack shim calls mise
- mise reads mise.toml template: node = "{{ env['NODE_VERSION'] |
default(value='24.11.0') }}"
- NODE_VERSION is unset → defaults to 24.11.0
- mise runs corepack from Node 24's install
- corepack creates pnpm shim in Node 24's bin directory
3. pnpm install runs
- PATH has Node 20's bin (from step 1)
- pnpm is in Node 24's bin (from step 2)
- pnpm not found!
After (NODE_VERSION at job-level):
1. mise-action runs with NODE_VERSION=20 (from job env)
- mise installs Node 20, adds its bin to PATH
2. corepack enable runs - NODE_VERSION=20 is still set
- corepack shim calls mise
- mise sees NODE_VERSION=20
- corepack runs from Node 20's install
- pnpm shim created in Node 20's bin
3. pnpm install runs
- PATH has Node 20's bin ✓
- pnpm is in Node 20's bin ✓
- Works!
---
Closes NXC-3620
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
The `linkTaskDetails` parameter was removed from the `NxCache`
constructor in #33843, which broke Nx Cloud since it still passes this
parameter.
## Expected Behavior
The `NxCache` constructor should accept the `linkTaskDetails` parameter
(even if unused) to maintain backwards compatibility with Nx Cloud.
## Related Issue(s)
Fixes
https://github.com/nrwl/nx/commit/ed09ee1daed597b7be60255f0cebe52efdd1ae69#r172894152
Updates CNW messages and removes `cancel` event from being recorded in
SIGINT handler, since it didn't work.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
When multiple MF dev servers run concurrently and share the same remote,
they would both attempt to start proxies on the same port, causing
EADDRINUSE errors.
This fix checks if a port is already in use before attempting to start
a proxy. If the port is occupied (likely by another MF dev server that
started earlier), the proxy is skipped for that remote since it's
already being served.
Uses the existing `waitForPortOpen` utility with retries: 0 to perform
an immediate check.
Fixes#33470
Update the programmatic API documentation to clarify that the dryRun
option for releasePublish does not prevent the underlying commands
from being executed. Instead, it forwards the flag to the executor
and sets the NX_DRY_RUN environment variable.
This makes it clear that:
- The built-in @nx/js:release-publish executor handles dryRun correctly
- Custom nx-release-publish executors must implement dryRun support
themselves
Fixes#33443
The publish workflow template was designed for fixed versioning strategy
(where all packages share the same version). This commit adds:
- A callout explaining that the template works best with fixed
versioning
- A new section covering considerations for independent versioning
- Documentation of GitHub's 3-tag event limitation
- Alternative approaches: workflow_dispatch, branch-based triggers, or
batch tag pushing
Fixes#33502
## Current Behavior
The `printTaskTerminalOutput` callback in the TUI summary life cycle
overwrites terminal output for all tasks when output is provided. This
causes the command line information (the actual command that was run) to
be lost for non-cached tasks because non-cached tasks stream their
output via `appendTaskOutput`, which includes the command information.
## Expected Behavior
For non-cached tasks (those with 'failure' or 'success' status), the
output should be preserved from the streaming via `appendTaskOutput`
which includes the complete command line that was executed. Only cached
tasks should have their output overwritten by `printTaskTerminalOutput`
since they don't go through the streaming path.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
## Current Behavior
NestJs libraries are generated with output path pointing to workspace
level dist folder. With TS Soln setups, we expect the dist folder to be
local to the project.
## Expected Behavior
Ensure the outputPath generated is correct
## Related Issue(s)
Fixes#32060
## Current Behavior
`nx format:write` fails with Prettier 4+ (and Prettier 3.6+ with the
experimental CLI enabled) with the error:
```bash
Incompatible options: "write" and "list-different" cannot be used together
```
## Expected Behavior
`nx format:write` works seamlessly across all Prettier versions (2.x,
3.x, and 4.x).
## Related Issue(s)
Fixes#33658Fixes#31951
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Root Maven and Gradle build files (pom.xml, build.gradle.kts,
settings.gradle.kts) are not explicitly assigned to the Java reviewers
in CODEOWNERS.
## Expected Behavior
With this PR, the Java reviewers (@FrozenPandaz @MaxKless @lourw) will
be automatically added as reviewers when changes are made to:
- `/pom.xml` - Root Maven build file
- `/build.gradle.kts` - Root Gradle build file
- `/settings.gradle.kts` - Gradle settings file
This ensures the Java team has visibility into changes affecting the
root Java build configuration.
## Related Issue(s)
N/A - Maintenance improvement to CODEOWNERS
## Current Behavior
The `/ci/recipes/enterprise/on-premise/auth-single-admin` and
`/ci/recipes/on-premise/auth-single-admin` paths redirect to
`https://github.com/nrwl/nx-cloud-helm`, but the documentation that
should exist at these paths no longer has a target location.
## Expected Behavior
These redirect rules are removed so the broken links don't mislead users
with incorrect redirects.
## Related Issue(s)
Fixes CLOUD-4007
#### Current Behavior
When creating a new Nx workspace with Angular v20 and selecting Vitest
as the unit test runner, the installation fails with an npm peer
dependency conflict:
```bash
npm error ERESOLVE could not resolve
npm error peerOptional vitest@"^3.1.1" from @angular/build@20.3.13
npm error Found: vitest@4.0.15
```
## Expected Behavior
Workspace creation completes successfully when selecting Angular with
Vitest as the unit test runner.
## Related Issue(s)
Fixes#33770
## Current Behavior
The publish workflow was installing `aarch64-apple-darwin` Rust target
but attempting to build for `x86_64-apple-darwin`, causing the build to
fail with:
```
error[E0463]: can't find crate for `core`
= note: the `x86_64-apple-darwin` target may not be installed
= help: consider downloading the target with `rustup target add x86_64-apple-darwin`
```
## Expected Behavior
The workflow should install the correct Rust target
(`x86_64-apple-darwin`) before attempting to build for it.
## Related Issue(s)
N/A - Bug found during publish workflow debugging
## Current Behavior
When running `nx g @nx/angular:cypress-component-configuration` on an
Angular project that uses esbuild (the default bundler since Angular
17), users receive a confusing error message:
```bash
Unable to find a valid build configuration. Try passing in a target for an Angular app.
```
This doesn't explain why the configuration fails or what the actual
limitation is.
## Expected Behavior
Users now receive a clear, informative error message that explains:
- Cypress Component Testing for Angular requires a webpack-based build
target
- Their project uses an esbuild-based executor (and which one)
- Cypress only supports webpack as the bundler for Angular component
testing
This helps users understand the limitation and make informed decisions
about how to proceed.
## Related Issue(s)
Fixes#33329
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
The `//` comment in the styled template [is not valid
css](https://stackoverflow.com/questions/12298890/is-it-bad-practice-to-prefix-single-lines-of-css-with-as-a-personal-comment-s/20192639#20192639)
and is causing [stylelint](https://stylelint.io/) to throw errors upon
creating new apps
## Expected Behavior
It should be valid css
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
https://github.com/nrwl/nx/issues/33579
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
## Current Behavior
When running `nx serve` with a NestJS project (and other node apps using
`runBuildTargetDependencies`), the node executor attempts to resolve the
`nx` binary using `require.resolve('nx')`. This fails with because
`nx/package.json` does no longer has a `main` field.
## Expected Behavior
The node executor should correctly resolve and use the `nx` binary from
the workspace where it's always installed.
This is fixed by using `nx/bin/nx.js` instead of just `nx` -- as we do
in other places.
## Related Issue(s)
Fixes#33776
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
## Current Behavior
<!-- This is the behavior we have today -->
When a workspace library has a `name` field set in its `nx`
configuration (e.g., `"nx": { "name": "buildable" }`), the
`@nx/js:prune-lockfile` executor fails to include transitive
dependencies from that library in the pruned lockfile.
The issue occurs because `addNodesAndDependencies` attempts to retrieve
workspace nodes using `graph.nodes[name]` where `name` is the package
name from `package.json`, but `graph.nodes` is keyed by the project name
(from `nx.name`). When these differ, the lookup fails and transitive
dependencies are not traversed.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The `@nx/js:prune-lockfile` executor should include all transitive
dependencies from workspace libraries regardless of whether the library
has a `name` field set in its `nx` configuration.
The fix uses the workspace node from the `workspacePackages` map (which
is keyed by package name) instead of attempting to look it up in
`graph.nodes` (which is keyed by project name).
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#33582
## Current Behavior
When terminating a task using the `@nx/js:swc` executor before it ever
got to execute its post-compilation logic, a `TypeError: disposeFn is
not a function` error is thrown.
## Expected Behavior
Terminating a task using the `@nx/js:swc` executor should not error.
## Related Issue(s)
Fixes#31938
## Current Behavior
The `update-21-2-0/update-module-resolution migration` doesn't process
any tsconfig files of non-buildable libraries.
## Expected Behavior
The `update-21-2-0/update-module-resolution migration` should process
common/known tsconfig files of non-buildable libraries.
## Related Issue(s)
Fixes#33705
Currently, when SWC compilation fails, Nx logs only a generic message:
"SWC compilation failed"
There is no `error.message`, no `stderr` and no `stdout` printed.
In many cases the actual cause of failure is completely hidden, which
makes debugging very difficult, especially in CI.
This PR improves the logging by printing:
- error.message (or the error itself)
- stderr if available
- stdout if available
This makes SWC failures visible and debuggable again.
## Current Behavior
Only a generic "SWC compilation failed" message is logged. No error
message or stdout are shown.
## Expected Behavior
Include error.message, stderr, and stdout (when available) so developers
can understand and debug failures.
We're missing messages and variant when errors happen during CNW. This
will help us track down potential problems.
We also want to know when CNW is cancelled in order to know that we're
not missing any events.
Description update for @berenddeboer/nx-aws-cdk plugin: this has become
self-inferring.
---------
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
## Current Behavior
The `getModuleFederationConfig` function is implemented separately in 4
places with 70-80% duplicate code:
- `with-module-federation/webpack/utils.ts` (161 lines)
- `with-module-federation/rspack/utils.ts` (150 lines)
- `with-module-federation/angular/utils.ts` - async version (~80 lines)
- `with-module-federation/angular/utils.ts` - sync version (~80 lines)
Each implementation repeats the same core logic:
1. Get project from graph
2. Get and filter dependencies
3. Share workspace libraries and npm packages
4. Apply eager packages
5. Map remotes
## Expected Behavior
A single shared implementation with framework-specific configuration via
a `FrameworkConfig` interface. Each bundler utility becomes a thin
wrapper that provides its specific configuration.
### Changes
| File | Before | After | Change |
|------|--------|-------|--------|
| `webpack/utils.ts` | 161 lines | 54 lines | -107 lines |
| `rspack/utils.ts` | 150 lines | 51 lines | -99 lines |
| `angular/utils.ts` | 273 lines | 119 lines | -154 lines |
| **NEW** `module-federation-config.ts` | - | 289 lines | +289 lines |
**Net reduction**: 41 lines, with significantly improved maintainability
### New Shared Utility
Created
`packages/module-federation/src/utils/module-federation-config.ts` with:
- `FrameworkConfig` interface for bundler-specific customization
- `ModuleFederationConfigResult` interface for type-safe return values
- `getModuleFederationConfigAsync()` - for webpack/angular async configs
- `getModuleFederationConfigSync()` - for rspack/angular sync configs
- `createDefaultRemoteUrlResolver()` - shared remote URL generation
- Caching for `NX_MF_DEV_SERVER_STATIC_REMOTES` env variable parsing
(performance)
### Benefits
1. **Single source of truth**: Bug fixes and improvements only need to
be made once
2. **Better maintainability**: Framework-specific behavior is clearly
separated via config
3. **Performance**: Added caching for env variable parsing
4. **Type safety**: New interfaces provide better IntelliSense and
compile-time checks
5. **Backward compatible**: All existing exports and behavior preserved
## Related Issue(s)
N/A - This is a refactoring for improved code maintainability and
performance.
## Merge Dependencies
**Must be merged AFTER:** #33734
---
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
With the new tsgo `baseUrl` has been completely removed, this breaks
compilation of plugins using swc when calling them with nx due to swc
needing the baseUrl. I patched my company workspace with this fix and it
did resolve it, not sure if its the right fix or what the ramifications
are so happy to discuss that more. Since `baseUrl` is removed in tsgo
(and recommended against in general), we need to find a way to provide
it to swc (potentially through an `.swcrc` alternatively, I tried adding
that to my workspace though and it didn't do anything).
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Expo CLI 54.0.12+ changed how originModulePath is determined in Metro
resolvers - from workspace root to project root. This caused the Nx
custom resolver to double-path modules when resolving workspace
libraries.
This fix:
- Adds projectRoot: workspaceRoot to the Metro config to ensure
originModulePath remains workspace-relative
- Adds defensive path normalization in pnpmResolver to handle edge cases
Fixes#33597
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Self-healing docs only reference being supported for GitHub.
<!-- This is the behavior we have today -->
## Expected Behavior
We should show instructions for all currently supported vcs providers,
including GitLab and Azure Devops.
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Replace process.exit(1) calls with typed CnwError exceptions for
structured error reporting and telemetry tracking. Update recordStat
meta to use typed JSON objects with named keys instead of arrays.
Examples of what's sent as `meta`.
```
{"type":"start","flowVariant":"1"}
{"type":"complete","flowVariant":"1","setupCIPrompt":"which-ci-provider","setupCloudPrompt":"cloud-v2-remote-cache-visit","nxCloudArg":"skip","nxCloudArgRaw":"","pushedToVcs":"SkippedGit","template":"nrwl/empty-template"}
{"type":"start","flowVariant":"1"}
{"type":"start","flowVariant":"0"}
{"type":"complete","flowVariant":"0","setupCIPrompt":"which-ci-provider","setupCloudPrompt":"enable-caching2","nxCloudArg":"skip","nxCloudArgRaw":"","pushedToVcs":"SkippedGit","template":"custom"}
{"type":"start","flowVariant":"1"}
{"type":"error","errorCode":"DIRECTORY_EXISTS"}
{"type":"start","flowVariant":"1"}
{"type":"error","errorCode":"DIRECTORY_EXISTS"}
{"type":"start","flowVariant":"1"}
{"type":"complete","flowVariant":"1","setupCIPrompt":"which-ci-provider","setupCloudPrompt":"cloud-v2-green-prs-visit","nxCloudArg":"yes","nxCloudArgRaw":"","pushedToVcs":"FailedToPushToVcs","template":"nrwl/empty-template"}
{"type":"start","flowVariant":"1"}
{"type":"complete","flowVariant":"1","setupCIPrompt":"which-ci-provider","setupCloudPrompt":"cloud-v2-fast-ci-visit","nxCloudArg":"yes","nxCloudArgRaw":"","pushedToVcs":"FailedToPushToVcs","template":"nrwl/empty-template"}
{"type":"start","flowVariant":"1"}
{"type":"start","flowVariant":"1"}
{"type":"complete","flowVariant":"1","setupCIPrompt":"which-ci-provider","setupCloudPrompt":"cloud-v2-green-prs-visit","nxCloudArg":"skip","nxCloudArgRaw":"","pushedToVcs":"SkippedGit","template":"nrwl/typescript-template"}
{"type":"start","flowVariant":"1"}
{"type":"error","errorCode":"WORKSPACE_CREATION_FAILED"}
```
Known errors like "directory exists" does not print stack trace:
<img width="1061" height="362" alt="image"
src="https://github.com/user-attachments/assets/8f29f303-3839-4297-b789-d23ac3af6d52"
/>
Another known error (invalid custom preset):
<img width="1091" height="391" alt="image"
src="https://github.com/user-attachments/assets/c7f6e586-42a8-493b-b595-f7d77743683f"
/>
Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
When using Nx React Module Federation with Rspack, running `nx run-many
-t e2e` before `nx run-many -t typecheck`, it causes typecheck to fail.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
`nx run-many -t typecheck` should succeed regardless of whether Rspack
(via `nx preview`) was executed before it.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes https://github.com/nrwl/nx/issues/33445
The CopyAssetsHandler was logging every copied file to the console,
causing noisy output when a project copies many files. This could
cause build errors to be cut off in terminals with scroll limits.
Change logger.log() to logger.verbose() so per-file logging only
appears when --verbose is passed or NX_VERBOSE_LOGGING=true.
Fixes#33521
The release-publish executor was only displaying npm-style errors
(error.summary
and error.detail), but pnpm returns errors with a different format
(error.code
and error.message). This caused pnpm publish errors to be invisible
unless users
passed the --verbose flag.
This fix adds handling for pnpm's error format so that error messages
are
properly displayed to users without requiring --verbose.
Fixes 33537
Adds a 'compiler' option to the @nx/js/typescript plugin configuration,
with options 'tsc' and 'tsgo'. Affects both typecheck and build targets.
## Current Behavior
The `@nx/js/typescript` plugin always uses `tsc` as the compiler, with
no way to use the native `tsgo` preview.
## Expected Behavior
The `@nx/js/typescript` plugin can be configured to use `tsgo` for
building and typechecking.
## Related Issue(s)
Related discussion #32591.
This pull request introduces a new option to the Nx Webpack plugin that
allows users to control whether the plugin should merge its external
dependencies configuration with any existing Webpack externals
configuration. This provides greater flexibility when customizing how
external dependencies are handled during the build process.
Configuration enhancements:
* Added a new `mergeExternals` boolean option to the
`NxAppWebpackPluginOptions` interface, allowing users to specify whether
to combine the plugin's externals configuration with the existing
Webpack config.
* Updated the logic in `apply-base-config.ts` so that the `externals`
array is set based on the new `mergeExternals` option, defaulting to not
merging unless specified.
---------
Co-authored-by: David Antoon <davidmantoon@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Currently the template flow will only set up `npm`, even if you run
`yarn create` or `pnpx create-nx-workspace`. This PR adds support back
for other package managers.
## Current Behavior
When we prepare ENVs for the DefinePlugin, we are creating the
`process.env` object.
For example:
```
// .env
NX_PUBLIC_VALUE1=1
NX_PUBLIC_VALUE2=2
NX_PUBLIC_VALUE3=3
```
As result we will have:
```js
{
'process.env': {
"NX_PUBLIC_VALUE1": "1",
"NX_PUBLIC_VALUE2": "2",
"NX_PUBLIC_VALUE3": "3"
}
}
```
As a result, in the final bundle, we will replace process.env with this
object.
The issue:
If I use all 3 values in my application DefinePlugin will inject this
object 3 times, instead of injecting it once.
It will look like that:
```js
const a = {
"NX_PUBLIC_VALUE1": "1",
"NX_PUBLIC_VALUE2": "2",
"NX_PUBLIC_VALUE3": "3"
}.NX_PUBLIC_VALUE1
const b = {
"NX_PUBLIC_VALUE1": "1",
"NX_PUBLIC_VALUE2": "2",
"NX_PUBLIC_VALUE3": "3"
}.NX_PUBLIC_VALUE2
const c = {
"NX_PUBLIC_VALUE1": "1",
"NX_PUBLIC_VALUE2": "2",
"NX_PUBLIC_VALUE3": "3"
}.NX_PUBLIC_VALUE3
```
## Expected Behavior
DefinePlugin injects values instead of env object in each place
```js
const a = "1"
const b = "2"
const c = "3"
```
## Fixes
- fixed this issue for webpack
- fixed this issue for storybook
- fixed this issue for rspack
TLDR:
now we have object like so:
```js
{
"process.env.NX_PUBLIC_VALUE1": "1",
"process.env.NX_PUBLIC_VALUE2": "2",
"process.env.NX_PUBLIC_VALUE3": "3"
}
```
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
NodeNext is not recognized as ESM. This causes this warning message to
be logged, even when you have `"type": "module",` in the `package.json`
file and are compile TypeScript to `"module": "NodeNext"`.
```
Package type is set to "module" but "cjs" format is included. Going to use "esm" format instead. You can change the package type to "commonjs" or remove type in the package.json file.
```
## Expected Behavior
Don't log this message. It is incorrect.
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
This pull request refactors the `dependsOn` configuration for Jest
targets in the Nx plugin to improve flexibility and maintainability. The
changes replace string-based dependencies with structured objects,
ensuring better alignment with Nx's target configuration standards.
This PR updates the `dependsOn` configuration for Jest `ciTarget` to
ensure that top-level args are passed on if the parent target has a
dependsOn for other targets.
For example if i pass `nx run-many e2e-ci -- --json
--outputFile=my-test-results.json` the options:
- `--json`
- `--outputFile`
Should be forwarded to the dependent targets.
---------
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
The check should be for `GITHUB_ACTIONS` since that is the intention.
The token may not be set due to Trusted Publisher flow.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
…new convention
## Current Behavior
Currently, the @nx/vite plugin generates a `vite.config.ts` file where
the worker configuration is commented out, but uses the old format:
```ts
// worker: {
// plugins: [ nxViteTsPaths() ],
// }
```
If uncomment, this format triggers a warning from Vite, as the worker
configuration should now be a function that returns an array of plugins.
While Vite automatically converts the old format for compatibility, it
is not ideal to rely on this behavior.
## Expected Behavior
With the changes in this PR, the @nx/vite plugin will generate a Vite
configuration where the worker configuration follows the new convention,
avoiding warnings and ensuring compatibility with future versions of
Vite. The updated configuration will look like this:
```ts
// worker: {
// plugins: () => [ nxViteTsPaths() ],
// }
```
This change ensures that the generated configuration aligns with Vite's
recommended practices and eliminates unnecessary warnings.
---------
Co-authored-by: Colum Ferry <cferry09@gmail.com>
The NxAppWebpackPlugin option 'verbose' should show chunk output during
webpack build when true, and hide them when false. It's currently the
reverse, causing a lot of console spam during dev, and the hiding the
info during ci/cd.
## Current Behavior
Setting the NxAppWebpackPlugin option 'verbose' to false shows chunk
output.
<img width="848" alt="chunky"
src="https://github.com/user-attachments/assets/4cd5502d-d059-4ace-9e42-28eb160bc1d0"
/>
## Expected Behavior
Setting the NxAppWebpackPlugin option 'verbose' to false hides chunk
output.
Resolve issue when
projectRoot was created from
join workspaceRoot and projectNode.data.root
but method createTmpTsConfig also make join
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
```
method withNx create
const projectRoot = join(workspaceRoot, projectNode.data.root);
```
method createTmpTsConfig
apply also join
```
const tmpTsConfigPath = join(
workspaceRoot,
'tmp',
projectRoot,
process.env.NX_TASK_TARGET_TARGET ?? 'build',
`tsconfig.generated.${randomUUID()}.json`
);
```
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#31522
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
No option to manage opening html report after run.
## Expected Behavior
Added option to manage opening html report after run.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
## Current Behavior
The nightly-2025-12-10 Rust version removed `mtim()` from the WASI
`MetadataExt` trait, causing the WASM build to fail with:
```
error[E0599]: no method named `mtim` found for reference `&std::fs::Metadata` in the current scope
```
## Expected Behavior
WASM builds should compile successfully.
## Solution
Revert to `nightly-2025-05-09` which still has the `mtim()` API
available in the WASI `MetadataExt` trait.
## Current Behavior
The `build:wasm` script uses `rustup override set nightly-2025-12-10` to
set the Rust toolchain. However, when mise is configured to manage Rust
(e.g., `rust = "1.90.0"` in `mise.toml`), it sets the `RUSTUP_TOOLCHAIN`
environment variable which has higher precedence than directory
overrides.
This causes the WASM build to fail with:
```
error[E0554]: `#![feature]` may not be used on the stable release channel
```
## Expected Behavior
WASM builds should use nightly Rust regardless of mise configuration.
## Solution
Set `RUSTUP_TOOLCHAIN=nightly-2025-12-10` directly in the script, which
overrides any existing env var from mise or other sources.
## Current Behavior
The Nx Console settings reference lacks explanation of VSCode's user vs
workspace settings and incorrectly states that Project Viewing Style is
unavailable in JetBrains IDEs.
## Expected Behavior
Nx consoles are documented for vscode/jetbrains editors
https://deploy-preview-33363--nx-docs.netlify.app/docs/reference/nx-console-settings
fixes: DOC-315
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
After the mise migration (#33772), the `publish.yml` workflow fails
during the "Build Wasm" step with:
```
error[E0554]: `#![feature]` may not be used on the stable release channel
--> packages/nx/src/lib.rs:2:33
|
2 | #![cfg_attr(target_os = "wasi", feature(wasi_ext))]
```
The WASM build requires nightly Rust because it uses the unstable
`wasi_ext` feature. The `build:wasm` script attempts to switch to
nightly via `rustup override set`, but after the mise migration, the
nightly toolchain is no longer pre-installed, causing the build to fail
with the stable compiler.
## Expected Behavior
The WASM build should successfully compile using nightly Rust with the
`wasi_ext` feature.
## Related Issue(s)
Fixes the publish workflow regression introduced in #33772
| | Before | After |
| ---- | ----- | ---- |
| Total createNodes | 812 | 104 |
| Total matchPropValue | 672 | 2 |
## Current Behavior
The `createNode` function is slow for pnpm due to suboptimal
`matchPropValue` function.
## Expected Behavior
The `createNode` function should be fast and not slowdown the graph
creation.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
When some tasks fail during execution, it can result in a cryptic:
```bash
Failed to convert JavaScript value 'Undefined' into rust type 'String'
```
This happens because the reported `terminalOutput` for the errored tasks
can be `undefined`, and it hides the actual error that occurred.
## Expected Behavior
Error handling paths should always provide a valid string for
`terminalOutput`, using the error stack/message, or an empty string as a
fallback.
## Related Issue(s)
Fixes#32675
## Current Behavior
The inline `mise_toml` config in `e2e-matrix.yml` was overwriting the
entire `mise.toml` file, causing rust, dotnet, bun, and java to NOT be
installed by mise. This resulted in slow package installs as these tools
were downloaded during `pnpm install` instead.
## Expected Behavior
All tools from `mise.toml` (rust, dotnet, bun, java) should be installed
by mise, with only the node version varying based on the matrix.
## Solution
Use mise's template syntax to make node version configurable via
`NODE_VERSION` env var while preserving all other tools from
`mise.toml`:
```toml
node = "{{ env['NODE_VERSION'] | default(value='24') }}"
```
Then in the workflow, set the env var instead of overriding the entire
config:
```yaml
- name: Setup dev tools with mise
uses: jdx/mise-action@v3
env:
NODE_VERSION: ${{ matrix.node_version }}
```
## Related Issue(s)
Fixes slow install times in nightly e2e-matrix workflow after #33772.
## Current Behavior
The mise vfox-dotnet plugin fails on Windows with:
```
mise ERROR Failed to install vfox:mise-plugins/vfox-dotnet@9:
0: error converting Lua table to PreInstall (no version returned from vfox plugin)
```
This prevents dotnet from being installed via mise on Windows CI
runners.
## Expected Behavior
Dotnet should install successfully on all platforms including Windows.
## Related Issue(s)
Related upstream issue: https://github.com/jdx/mise/discussions/4738
## Solution
1. **mise.toml** - Made dotnet installation conditional on Linux/macOS
only using the `os` option
2. **.github/workflows/publish.yml** - Added `winget install` to install
.NET SDK 9 on Windows CI runners
This approach works around the buggy vfox plugin by using the native
Windows package manager instead.
## Current Behavior
When building Angular libraries with `ng-packagr` >20.3.0, the build
fails with:
```bash
TypeError: Cannot read properties of undefined (reading 'outputCache')
```
This occurs because `ng-packagr` v20.3.1 introduced a memory
optimization
([ng-packagr#3172](https://github.com/ng-packagr/ng-packagr/pull/3172))
that calls `dispose()` on entry points after they're processed, setting
`entry.cache = undefined`.
Nx's custom `writeBundlesTransform` was iterating over **all** entries
in the graph, including already-disposed entry points, causing the crash
when accessing their cache.
## Expected Behavior
Angular library builds should succeed with `ng-packagr` >20.3.0,
including libraries with secondary entry points. Workspaces using lower
versions of `ng-packagr` should remain unaffected.
## Solution
Align with `ng-packagr`'s own pattern by using
`graph.find(isEntryPointInProgress())` to process only the currently
in-progress entry point, rather than iterating over all graph entries.
**Key changes:**
- Use `isEntryPointInProgress()` instead of iterating all entries with
`isEntryPoint()`
- Remove unused `BuildGraph` import (no longer creating a new graph)
- Update package node only when processing the primary entry point (more
efficient)
- Return nothing from the transform (original graph passes through, same
as ng-packagr)
This approach:
- Matches `ng-packagr`'s `writeBundlesTransform` implementation pattern
- Only accesses cache of the in-progress entry point (guaranteed not to
be disposed)
- Works with all supported `ng-packagr` versions (v19+) since
`isEntryPointInProgress()` has been available since v19
## Related Issue(s)
Fixes#33560
This PR fixes an issue with CNW where the initial `recordStat` call is
not working due to a logic error on passing `directory` that isn't
initialized yet.
## Current Behavior
If there are issues with values passed to generators via prompt, we
still see a green output and exit code 0.
A colleague found out about this by pressing `Ctrl+C` when being
prompted for parameters for a generator, and this led to the CLI simply
continuing execution and showing no issue.
## Expected Behavior
CLI fails.
Allows setting a default output style instead of having to include it on
every command
Closes#27490
## Current Behavior
We must specify --outputStyle on every command
## Expected Behavior
Should allow overriding the default with an environment variable
## Related Issue(s)
#27490Fixes#27490
When 8+ dependent tasks exist, each adds an `exit` listener to track
completion. This listener attaches to `process`. So we apply the same
fix that worked for `stdout` and `stderr`, and was merged through [PR
16693](https://github.com/nrwl/nx/pull/16993)
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
For `nx` targets with 8+ dependent targets, we encounter
`maxListenersExceededWarning`:
```
(node: 22553) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGINT listeners added to [process]. MaxListeners is 10. Use emitter.setMaxListeners() to increase limit.
(node: 22553) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGTERM listeners added to [process]. MaxListeners is 10. Use emitter.setMaxListeners() to increase limit.
(node: 22553) MaxListenersExceededWarning: Possible EventEmitter memory leak detected. 11 SIGHUP listeners added to [process]. MaxListeners is 10. Use emitter.setMaxListeners() to increase limit.
```
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
No `MaxListenersExceededWarning` should be thrown on account of the nx
run.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#32439
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
## Current Behavior
In `filterAffectedProjects`, a **new visited Set is created for each
touched project**:
```typescript
ctx.touchedProjects.forEach((p) => {
addAffectedNodes(p, reversed, result, new Set()); // NEW Set per project!
});
ctx.touchedProjects.forEach((p) => {
addAffectedDependencies(p, reversed, result, new Set()); // NEW Set per project!
});
```
This defeats the purpose of the visited Set for deduplication. If
projects A and B both depend on shared project C, then C gets visited
**twice**.
## Expected Behavior
Share a single visited Set across all touched projects:
```typescript
const visitedNodes = new Set<string>();
const visitedDeps = new Set<string>();
for (const p of ctx.touchedProjects) {
addAffectedNodes(p, reversed, result, visitedNodes); // SHARED Set
}
for (const p of ctx.touchedProjects) {
addAffectedDependencies(p, reversed, result, visitedDeps); // SHARED Set
}
```
## Performance Impact
```
Before (separate Sets): After (shared Sets):
┌─────────────────────────┐ ┌─────────────────────────┐
│ touchedProjects: [A,B] │ │ touchedProjects: [A,B] │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
┌───────┴───────┐ ┌───────┴───────┐
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────┐ ┌───────┐
│ A │ │ B │ │ A │ │ B │
│visited│ │visited│ │ │ │ │
│= {} │ │= {} │ │ shared visitedNodes │
└───┬───┘ └───┬───┘ └───┬───┘ └───┬───┘
│ │ │ │
▼ ▼ ▼ ▼
┌───────┐ ┌───────┐ ┌───────────────────────┐
│visit C│ │visit C│ │ visit C (ONCE) │
│(dup!) │ │(dup!) │ │ skip C from B │
└───────┘ └───────┘ └───────────────────────┘
Complexity: Complexity:
O(touched × shared_deps) O(total_nodes)
```
**Example**: With 50 touched projects sharing 100 common dependencies:
- Before: 50 × 100 = 5,000 node visits
- After: ~150 node visits (each node visited once)
## Why Accept This PR
1. **Bug-like behavior**: The current code defeats the purpose of the
visited Set
2. **Significant impact**: Affects every `nx affected` command
3. **Zero risk**: Same traversal logic, just shared deduplication
4. **Common scenario**: Monorepos often have shared dependencies (utils,
types, etc.)
## Related Issue(s)
Contributes to #32265
## Merge Dependencies
This PR has no dependencies and can be merged independently.
---
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Co-authored-by: khalilou88 <32600911+khalilou88@users.noreply.github.com>
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
## Summary
Migrates GitHub workflows to use [mise](https://mise.jdx.dev/) for
managing development tool installations instead of individual setup
actions.
## Changes
- **mise.toml**: Added pnpm@10.11.1 to tool configuration
- **ci.yml**: Replaced pnpm, node, rust, and java setup actions with
`mise-action@v3` in both Linux and macOS jobs
- **e2e-matrix.yml**: Replaced all tool setup actions with mise-action
in preinstall and e2e jobs
- **publish.yml**: Replaced tool setup actions with mise-action in build
and publish jobs
- **codeql workflows**: Updated to use `mise-action@v3`
## Benefits
- **Single source of truth**: All tool versions defined in `mise.toml`
- **Faster CI setup**: Mise provides better caching than individual
actions
- **Consistency**: Same tool versions across local dev and CI
- **Easier maintenance**: Update versions in one place
## Test Plan
- [ ] CI workflow passes on Linux
- [ ] CI workflow passes on macOS
- [ ] E2E matrix builds successfully
- [ ] Publish workflow can run (test with dry-run if possible)
- [ ] CodeQL scans complete successfully
Fixes #ISSUE_NUMBER
## Current Behavior
We do not have a guide showing how to use Vitest with custom conditions
## Expected Behavior
Add a guide showing how to use Vitest with custom conditions
The Plugin Registry page in astro-docs displays a static grid of plugins
without any search or filtering capabilities, making it hard to find
specific plugins.
Users can search plugins by name or description, and sort by release
date, npm downloads, GitHub stars, or Nx version compatibility.
<img width="975" height="1059" alt="image"
src="https://github.com/user-attachments/assets/a08e2a12-697e-4e3b-b9c0-2983d50fdad8"
/>
Closes DOC-343
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
## Current Behavior
The fileURLToPath and dirname imports are only used in the
getAbsolutePath function, which is only generated for non-Angular
Storybook projects.
## Expected Behavior
This change prevents unnecessary imports from being added to Angular
Storybook configurations.
## Current Behavior
When using pnpm with workspace protocol (`workspace:*`, `workspace:^`,
etc.), module federation sets `requiredVersion` to the raw protocol
string (e.g., `workspace:*`) instead of resolving it to the actual
semver version from the library's package.json.
This causes issues like:
- `requiredVersion: "workspace:*"` which is not a valid semver
- Module federation failing to properly share workspace libraries
- Warnings about unable to find required versions
Example of the broken output:
```json
{
"version": "*",
"singleton": true,
"requiredVersion": "^*"
}
```
## Expected Behavior
When a workspace protocol version is detected, it should be resolved to
the actual version from the library's package.json:
```json
{
"version": "2.0.0",
"singleton": true,
"requiredVersion": "2.0.0"
}
```
## Changes Made
1. **Added helper functions** in `share.ts`:
- `isWorkspaceProtocolVersion()` - Detects workspace protocol versions
(`workspace:*`, `workspace:^`, `*`, `file:`)
- `normalizeWorkspaceProtocolVersion()` - Resolves protocol versions to
actual semver by looking up the library's package.json
2. **Applied normalization in `shareWorkspaceLibraries()`**:
- After getting version from `getDependencyVersionFromPackageJson`,
normalize it if it's a workspace protocol
- Simplified the `workspaceLibrariesAsDeps` loop by using the helper
function (removed duplicated logic)
3. **Updated `getNpmPackageSharedConfig()`**:
- Added a check to warn and return undefined when workspace protocol
versions are passed
- Helps users understand that workspace libraries should be configured
properly
4. **Added comprehensive tests** (13 new tests):
- 6 tests for workspace protocol version normalization in
`shareWorkspaceLibraries`
- 7 tests for `getNpmPackageSharedConfig` handling workspace protocol
versions
## Related Issue(s)
Fixes#31397
## Merge Dependencies
This PR has no dependencies and can be merged independently.
**Must be merged BEFORE:** #33734
---
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
We would add the gradle project graph plugin to your build.gradle files
if we did not already detect it. However, this did mechanism did not
recognize aliases for the project graph plugin that came from version
catalogs.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
When adding the project graph plugin to build.gradle.kts, we check if a
version catalogue exists, and if it does we add the alias for the
project graph plugin.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
The `hasPath` function in `graph.ts` uses an array with `indexOf()` for
tracking visited nodes during recursive graph traversal:
```typescript
function hasPath(graph, target, node, visited: string[]) {
for (let d of graph.dependencies[node] || []) {
if (visited.indexOf(d.target) > -1) continue; // O(n) lookup
visited.push(d.target);
// recursive call...
}
}
```
This results in O(n) lookups per node visited, making worst-case
traversal O(n²).
## Expected Behavior
Use `Set` for O(1) visited node tracking:
```typescript
function hasPath(graph, target, node, visited: Set<string>) {
for (const d of graph.dependencies[node] || []) {
if (visited.has(d.target)) continue; // O(1) lookup
visited.add(d.target);
// recursive call...
}
}
```
## Performance Impact
```
Before (Array + indexOf): After (Set + has):
┌─────────────────────────┐ ┌─────────────────────────┐
│ hasPath() called │ │ hasPath() called │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ visited.indexOf(target) │ │ visited.has(target) │
│ O(n) lookup │ │ O(1) lookup │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
▼ ▼
┌─────────────────────────┐ ┌─────────────────────────┐
│ visited.push(target) │ │ visited.add(target) │
│ O(1) │ │ O(1) │
└───────────┬─────────────┘ └───────────┬─────────────┘
│ │
▼ ▼
Complexity: O(n²) Complexity: O(n)
for full traversal for full traversal
```
**Example with 500 nodes:**
- Before: 500 nodes × avg 250 indexOf lookups = ~125,000 comparisons
- After: 500 nodes × 1 Set lookup each = 500 operations
## Why Accept This PR
1. **Zero risk**: Same semantics, just faster data structure
2. **Standard pattern**: Set is the idiomatic choice for visited
tracking in graph algorithms
3. **Measurable impact**: Graph filtering with `--focus` flag will be
significantly faster on large monorepos
## Related Issue(s)
Contributes to #32265
## Merge Dependencies
This PR has no dependencies and can be merged independently.
---
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Correcting docs to mention that resource collection on Nx Cloud will be
availabe from 22.2 onwards.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
When using `nx release version --preid=alpha`, the version determination
now correctly considers both prerelease tags AND stable release tags to
determine the "latest" version. Previously, it would only look at
prerelease tags matching the preid, ignoring stable releases that should
have become the new baseline.
For example, with tags: 1.1.0, 1.1.0-alpha.0, 1.1.0-alpha.1, 1.1.1
- Before: Would return 1.1.0-alpha.1 → bump to 1.1.0-alpha.2
- After: Returns 1.1.1 (stable >= preid base) → bump to 1.1.2-alpha.0
Fixes#33343
## Current Behavior
The Maven plugin version is currently at 0.0.10 across all pom.xml files
in the repository.
## Expected Behavior
With this PR, the Maven plugin version will be updated to 0.0.11. This
includes:
- Updating the version in the root pom.xml
- Updating the version in packages/maven/maven-plugin/pom.xml
- Updating the mavenPluginVersion constant in
packages/maven/src/utils/versions.ts
- Adding a migration script to automatically update user pom.xml files
from 0.0.10 to 0.0.11
## Related Issue(s)
N/A - Version bump for the Maven plugin
Webpack e2e tests occasionally hang in CI without clear indication of
where the test gets stuck.
Debug logs will help identify which step the test hangs at, making it
easier to diagnose and fix the root cause.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Current gradle plugin version is at 0.1.9
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Take gradle plugin to 0.1.10
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Pressing Cmd+K (or Ctrl+K) on non-docs pages does nothing. The Pagefind
search is only accessible when already on the documentation pages.
Pressing Cmd+K on any non-docs page redirects to the docs and
automatically opens the search modal with focus on the input field.
https://www.loom.com/share/72fcee74620640cab28639e9ad33d962
Closes DOC-314
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
The `tools/update-repos/config/repos.json` configuration has the ocean
repository set to use `npm` as its package manager.
## Expected Behavior
The ocean repository should be configured to use `pnpm` as its package
manager, reflecting the actual package manager used by the repository.
## Related Issue(s)
N/A - Configuration update to reflect actual repository state.
This PR adds `SIGINT` handling when user kills the process via `Ctrl+C`
during CNW. This only prints when the workspace setup is complete, and
we also print the Cloud onboarding URL if it has been set up.
Also fixes an issue where `selectedRepositoryName` is never sent during
CNW.
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
you can mark some targets generated by gradle by specifying options.
## Expected Behavior
you can apply a prefix to all targets generated by gradle. This is
useful for targetDefaults, for example.
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Adds a Gradle option to prefix all generated Nx target names
(including dependencies and CI targets) with tests to avoid
double-prefixing.
>
> - **Gradle project graph**:
> - Apply optional `targetNamePrefix` to all target names and dependency
rewrites in `createNodeForProject`, `processTargetsForProject`, and
`getDependsOnForTask`.
> - Wire prefix through plugin/task: read in
`NxProjectGraphReportPlugin`, expose on `NxProjectReportTask`, and pass
to processing functions.
> - Ensure CI targets (`ciTestTargetName`, `check-ci`, `build-ci`) are
correctly prefixed and not double-prefixed; update dependency
replacement logic accordingly.
> - Add logging for prefix usage.
> - **Plugin options (TS)**:
> - Extend `GradlePluginOptions` with `targetNamePrefix` in
`packages/gradle/src/plugin/utils/gradle-plugin-options.ts`.
> - **E2E tests**:
> - Add tests validating prefixed targets exist and run, and that CI
test targets are not double-prefixed in `e2e/gradle/src/gradle.test.ts`.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
9a5160b8855a32d6c13c33c97379e7aa143a0737. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
Key optimisations:
1. Pre-computed PackageIndex - Built once during lockfile parsing:
- byName: Map from package name → array of versions (O(1) lookup)
- workspaceNames: Set of workspace package names (O(1) lookup)
- workspacePaths: Set of workspace paths (O(1) lookup)
- packagesWithWorkspaceVariants: Set of packages with workspace-specific
variants (O(1) lookup)
- patchedPackages: Set of patched package names (O(1) lookup)
2. findResolvedVersion: Changed from O(n) scan through all packages to
O(1) map lookup + O(k) where k = number of versions for that package
(typically 1-3)
3. isWorkspacePackage: Changed from O(n) scan to O(1) set lookup
4. hasWorkspaceSpecificVariant: Changed from O(n) scan to O(1) set
lookup
5. isNestedPackageKey: Now uses pre-computed workspace paths/names sets
instead of computing them each call
On my 40 project typescript monorepo my time goes from about 30 seconds
to 4.5s, a speed-up of 6-7x.
---------
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
This PR simplifies the CNW process so we only prompt for a starter (TS,
NPM Packages, React, Angular) and we clone a full example to showcase Nx
monorepo for the given starter. This speeds up CNW drastically and
allows users to get the workspace in 5-10 seconds vs 1-3 minutes.
Users can choose `Custom` to fall back to the previous prompts, which
will ask framework, unit test runner, e2e runner, etc.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Gradle multi-module projects have project names with colons (e.g.,
`:common:iam-client`)
which are invalid in git tag names. This adds a
`sanitizeProjectNameForGitTag()` function
that replaces colons with slashes and other invalid git ref characters
with hyphens.
The sanitization is applied when:
- Creating git tags in `createGitTagValues()`
- Creating the `ReleaseVersion` class gitTag property
- Matching existing tags in `getLatestGitTagForPattern()`
Fixes#33262
## Current Behavior
We only support Expo 53
## Expected Behavior
Add support for Expo 54
Allow existing workspaces wishing to remain on Expo 53 to continue to be
supported
Add migrations allowing LLMs to handle migrating from Expo 53 to Expo 54
## Related Issue(s)
Closes NXC-3526
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
Rebuild logs during serve of Angular Rspack applications are logged an
exponential number of times with each change.
## Expected Behavior
Log only once
## Current Behavior
We currently install an outdated version of `@emotion/styled` that
causes Typecheck issues.
## Expected Behavior
Use latest version of Emotion
## Related Issue(s)
Fixes#31252
## Current Behavior
Angular Rspack outputs ESM for build and serve. However, with serve, it
causes issue for HMR.
## Expected Behavior
Use CJS for serve to allow HMR to work correctly
## Related Issue(s)
Fixes#33106
## Expected Behavior
Generate only `vitest.config.mts` file when not bundling with Vite
Use `vite.config` file if it exists already
Add `testMode` option to the `@nx/vitest` Inference Plugin to allow
easier switching between `vitest` and `vitest run`.
## Related Issue(s)
Fixes NXC-3334
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- CURSOR_SUMMARY -->
---
> [!NOTE]
> Removes legacy additions of `.cursor/rules/nx-rules.mdc` and
`.github/instructions/nx.instructions.md` to `.gitignore` across code,
templates, and migrations.
>
> - **.gitignore behavior**:
> - Remove logic in
`packages/nx/src/command-line/init/implementation/utils.ts` that
appended `.cursor/rules/nx-rules.mdc` and
`.github/instructions/nx.instructions.md`.
> - Clean up root `.gitignore` to exclude those entries.
> - Update new workspace templates
(`packages/workspace/.../__dot__gitignore`) to omit those entries.
> - **Migrations**:
> - Remove migration `21-1-0-add-ignore-entries-for-nx-rule-files` from
`packages/nx/migrations.json` and delete its implementation and spec.
>
> <sup>Written by [Cursor
Bugbot](https://cursor.com/dashboard?tab=bugbot) for commit
7863fa5beee127777f819a5155ae17239c5b16cd. This will update automatically
on new commits. Configure
[here](https://cursor.com/dashboard?tab=bugbot).</sup>
<!-- /CURSOR_SUMMARY -->
## Current Behavior
Trying to create a new workspace is failing on npm peer dep conflicts
when trying to use Vitest with Angular.
The version of `@analogjs/vitest-angular` only supports Vitest <4.
## Expected Behavior
Update to latest version of `@analogjs/vitest-angular` to support Vitest
4
## Related Issue(s)
Fixes#33602
## Current Behavior
`buildLibsFromSource` defaults to true only in the `@nx/rollup:rollup`
executor.
In the normalize options helper for the executor, it is not handled at
all. Programmatic usage would therefore result in `undefined`.
For pure Inference Plugin usage, `buildLibsFromSource` is also not
handled in normalize options.
Therefore, it always defaults to `undefined`.
## Expected Behavior
To reduce breaking changes, force `buildLibsFromSource` to be false for
Inference Plugin usage.
Explicitly set it in executor's normalize options helper to true to
match the schema default.
## Related Issue(s)
Fixes NXC-3537
# Fix: Pass releaseGroupName to getLatestGitTagForPattern for proper tag
resolution
## Problem
When using `releaseTag.pattern: "{releaseGroupName}@{version}"`, Nx
fails to resolve versions from git tags because the `{releaseGroupName}`
placeholder is not interpolated.
For example, with git tag `my-group@2.9.0`:
- **Expected**: Extract version `2.9.0`
- **Actual**: Extracts `"my-group"` → Error: `Invalid semver version
'my-group' provided`
## Root Cause
In `release-graph.ts:627-631`, only `projectName` is passed to
`getLatestGitTagForPattern()`, missing `releaseGroupName` needed for
interpolation.
## Solution
Pass `releaseGroupName` to the interpolation data (1-line change at
`release-graph.ts:631`):
```typescript
latestMatchingGitTag = await getLatestGitTagForPattern(
releaseTagPattern,
{
projectName: projectGraphNode.name,
releaseGroupName: releaseGroupNode.group.name, // ✅ Added
},
{ ... }
);
```
## Backward Compatibility
✅ Fully backward compatible:
- `releaseGroupNode.group.name` is always defined (user-defined or
`"__default__"`)
- Unused interpolation data is safely ignored
- Existing patterns (`v{version}`, `{projectName}@{version}`) continue
to work
## Tests
Added test case in `git.spec.ts` for `{releaseGroupName}@{version}`
pattern that verifies correct tag matching and version extraction.
## Files Changed
- `packages/nx/src/command-line/release/utils/release-graph.ts` (1 line)
- `packages/nx/src/command-line/release/utils/git.spec.ts` (1 test case)
Co-authored-by: James Henry <james@henry.sc>
## Current Behavior
The arboard crate is used without the `wayland-data-control` feature,
which means clipboard operations may not work properly on Wayland-based
Linux systems.
## Expected Behavior
With the `wayland-data-control` feature enabled, arboard can interact
with the clipboard on Wayland systems using the wlr-data-control
protocol.
## Related Issue(s)
N/A - Enhancement for better Wayland support
## Current Behavior
The Maven plugin incorrectly maps Maven's `isThreadSafe` mojo property
to Nx's `parallelism` target property. Maven's `isThreadSafe` indicates
whether a mojo can safely run in parallel with other mojos of the same
type within the same Maven build (multi-threaded Maven builds).
## Expected Behavior
Nx's `parallelism` controls whether the target can run in parallel
alongside anything else - a fundamentally different concept. All Maven
targets now default to `parallelism: true`, letting Nx handle
parallelism based on its own task graph analysis rather than using
Maven's unrelated thread-safety concept.
## Related Issue(s)
N/A - Internal cleanup based on code review feedback.
## Current Behavior
On Node.js v24+, the `@nx/jest/plugin` sets
`--no-experimental-strip-types` in NODE_OPTIONS which causes an error:
"node: --no-experimental-strip-types is not allowed in NODE_OPTIONS".
Additionally, `jest.config.ts` files using ESM syntax (`export default`,
`import`) fail to load correctly under Node.js type-stripping when the
project is configured for CommonJS.
## Expected Behavior
- Remove the NODE_OPTIONS manipulation that adds
`--no-experimental-strip-types`
- Add a migration (22.2.0-beta.2) that converts `jest.config.ts` files
from ESM to CJS syntax for projects using `@nx/jest/plugin`
- The migration only runs when `@nx/jest/plugin` is registered in
`nx.json`
- Projects with `type: module` are warned as they're incompatible with
the plugin
- Files using ESM-only features (import.meta, top-level await) are
skipped with a warning for manual conversion
## Demo
https://www.loom.com/share/8a157a0b01d144ae8d6ae48b9b0cd0e4
## Related Issue(s)
Closes NXC-3541
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
We don't have a migration to migrate users to use the new @nx/vitest
package if they're currently using @nx/vite
Given that we have Vitest-related operations marked as deprecated when
used via @nx/vite, we should have a migration.
## Expected Behavior
Add a migration that:
1. Installs @nx/vitest
2. Switches @nx/vite:test executor usage to use @nx/vitest:test executor
usage
3. Splits `@nx/vite/plugin` in nx.json that sets up vitest test targets
to use `@nx/vitest` instead
## Current Behavior
The `@nx/vite:test` executor is not returning the async iterable. This
causes a destructuring issue.
## Expected Behavior
Ensure the `@nx/vite:test` executor returns the async iterable.
## Related Issue(s)
Fixes#33588
This PR updates the `workspace-rule` generator so use ESLint v9 by
default. It currently forces the unsupported ESLint v8.
In theory this is only useful if not using workspaces and you need
tsconfig paths to be mapped and resolved correctly. For workspaces, you
can easily just generate any library to be used to contain custom rules.
Closes NXC-3500
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Blog posts contain broken links pointing to old `/powerpack` and
`/docs/enterprise/powerpack/*` paths that no longer exist.
## Expected Behavior
Links should point to the new enterprise documentation paths:
- `/powerpack` → `/enterprise`
- `/docs/enterprise/powerpack/*` → `/docs/enterprise/*`
- `/docs/reference/powerpack/*` → `/docs/reference/*`
## Related Issue(s)
Closes DOC-354
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
When running `NX_PERF_LOGGING=true nx graph --file graph.json`, many
performance logs are missing (e.g., `create-project-graph-async`,
`retrieve-project-configurations`).
Only plugin-specific logs like `createDependencies` appear.
## Expected Behavior
All performance timing logs should appear, matching the output of
`NX_PERF_LOGGING=true nx show projects`.
## Related Issue(s)
N/A - Internal improvement for debugging/profiling.
## Solution
The `graph.ts` file had `process.exit(0)` calls that terminated the
process immediately, not giving the async `PerformanceObserver` callback
time to fire.
Added `await new Promise((res) => setImmediate(res))` before
`process.exit(0)` to give the event loop one tick to process pending
callbacks. This follows the existing
pattern in `show/projects.ts` and `show/project.ts`.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
The Nx Console installation prompt blocks commands when run in
non-interactive contexts such as:
- CI environments
- AI agents
- Piped commands
The prompt only checked `process.stdout.isTTY` but not
`process.stdin.isTTY`, causing it to wait indefinitely for input that
would never arrive.
## Expected Behavior
Commands should complete without prompting when run in non-interactive
environments.
## Related Issue(s)
Fixes#33552
## Solution
Updated the check to verify:
1. Both `stdin` and `stdout` are TTY (truly interactive terminal)
2. Not running in a CI environment (using existing `isCI()` utility)
This ensures the prompt only appears when the user can actually provide
input.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
Since Nx 21.6.1, running `nx graph` or other commands that calculate
affected projects prints git errors to stderr when the default branch is
not fetched:
```
fatal: ambiguous argument 'main': unknown revision or path not in the working tree.
```
This causes CI pipelines with strict stderr checking to fail, even
though the nx commands succeed.
## Expected Behavior
Git error messages should not be printed to stderr. The errors are
already caught and handled gracefully - they just shouldn't be visible
to the user.
## Related Issue(s)
Fixes#33330
## Solution
Added `stdio: 'pipe'` to the `execSync` call in `parseGitOutput()`. This
suppresses stderr output while still allowing the command to throw on
failure (which is already caught by the try-catch in `graph.ts`).
This matches the pattern used in `getMergeBase()` which already uses
`stdio: 'pipe'`.
## Current Behavior
When running `nx migrate latest`, the `create-nx-workspace` package is
not updated along with other Nx packages, even though it's a core part
of the Nx ecosystem that users may have as a dependency (especially when
extending the install package pattern).
## Expected Behavior
The `create-nx-workspace` package should be updated to the same version
as `nx` and other `@nx/*` packages when running migrations.
## Related Issue(s)
Fixes#33585
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
The nuxt preset test was checking for `apps/${name}/src/app.vue`, but
since the generator now defaults to Nuxt v4 which uses the app directory
structure, this file is no longer created at that path.
## Expected Behavior
Tests should pass on master.
## Solution
Updated the test to check for `apps/${name}/app/app.vue` which is the
correct path for Nuxt v4's app directory structure.
## Current Behavior
When Nx commands finish or receive termination signals (SIGINT, SIGTERM,
SIGHUP), child processes spawned by continuous tasks (such as `nx
serve`) can remain orphaned in certain scenarios. This happens because
only the direct child process is killed using `childProcess.kill()`,
leaving grandchild processes running.
## Expected Behavior
When Nx terminates, all processes in the spawned process tree should be
properly terminated and no orphaned processes should remain.
## Related Issue(s)
Fixes#32438Fixes#33460
## Changes
- Updated signal handlers in `RunningNodeProcess` to use `this.kill()`
instead of `this.childProcess.kill()`, leveraging the existing
`tree-kill` implementation
- Added `tree-kill` to `NodeChildProcessWithNonDirectOutput` and
`NodeChildProcessWithDirectOutput` kill methods to ensure entire process
trees are terminated
We missed a peer dep error in the Nuxt 4 PR since CI allowed install to
go through, but in a real repo it would have failed.
We _may_ need to still have the `prefer-frozen-lockfile=false` option,
but let's let CI run with this first.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
We currently do not support Nuxt 4. We still generate Nuxt 3.
## Expected Behavior
Support Nuxt 4.
New workspaces will get Nuxt 4.
Existing Workspaces that use Nuxt 3 intentionally will continue to use
Nuxt 3.
Add a migration to update users to Nuxt 4
Handle ESLint flat config
## Related Issue(s)
Closes NXC-3525
Closes NXC-3497
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
The base `eslint` config will ignore `**/dist` but not `**/out-tsc`.
This can cause issues if lint is run after a `typecheck` which has
placed `.d.ts` files into an `out-tsc` directory.
## Expected Behavior
Base eslint config should ignore `**/out-tsc`
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
## Current Behavior
Storybook support is not explicitly set to 10.1 which has just been
released.
## Expected Behavior
Explicitly set storybook version to 10.1 to ensure support for Angular
21
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
- E2E nightly tests only run on Node 20 and 22.
- E2E nightly tests now also run on Node 24, 22, and 20 for linux. For
Windows and Mac run only 24.
Did a test run from this branch, and Node 24 passes where other versions
pass, and fails where other versions fail. It shouldn't make any golden
tests fail just due to Node 24, but it's possible that things will flake
more since the matrix has expanded. We just have to make them more
robust.
<img width="920" height="1089" alt="image"
src="https://github.com/user-attachments/assets/90ee4d04-68d5-4d0d-9729-60cacfbc99db"
/>
Close NXC-3491
## Current Behavior
The Next 16 AI Migration Instructions are always created, regardless of
existing Next version
## Expected Behavior
Make the Next 16 Migration optional
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
There is no documentation on how to create and use custom ESLint rules
in Nx workspaces.
Users can follow a guide to create custom ESLint rules using either:
1. Package Manager Workspaces (npm/yarn/pnpm/bun) - create a dedicated
ESLint plugin package that's symlinked via the package manager
2. `loadWorkspaceRules` utility from `@nx/eslint-plugin` - load rules
from any directory with automatic TypeScript transpilation
The guide includes:
- Comparison table for choosing the right approach
- Step-by-step instructions for both approaches
- TypeScript execution options (build first, Node.js native support,
tsx)
- Rule testing with `@typescript-eslint/rule-tester`
- Best practices and troubleshooting tips
Page:
https://deploy-preview-33618--nx-docs.netlify.app/docs/technologies/eslint/guides/custom-workspace-rules
Closes DOC-339
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
Despite @nx/vite depending on @nx/vitest it only does so in the same
version that introduces the migration for Vitest 4.
This means the user does not get any migrations for Vitest 4
## Expected Behavior
Add the Vitest 4 migrations to the @nx/vite package to allow users to
migrate.
There's a problem when `@nx/rollup` is installed with yarn@1.22, and
typechecks.
This is caused by the transitive dependency chain:
```
rollup-plugin-copy@3.5.0 -> globby@10.0.1 -> @types/glob@7.2.0 -> @types/minimatch
```
When users run tsc without explicit `types` configuration, TypeScript
auto-discovers `@types/minimatch` from `node_modules` but can't properly
resolve it.
Note: This doesn't happen with NPM and PNPM, nor newer yarn versions.
Verified fix with this repro: https://github.com/jaysoo/rollup-251124Fixes#32398
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
## Current Behavior
- Storybook generator docs banner says "Nx uses Storybook 7"
- Separate storybook-9-setup.mdoc page exists
- No documentation for migrate-10 generator
## Expected Behavior
- Update banner to "Nx uses Storybook 10"
- Consolidate storybook-9-setup into upgrading-storybook guide
- Add migrate-10-generator-examples.md with AI-assisted migration docs
- Update all references to point to new consolidated guide
---
Main content is here:
https://deploy-preview-33619--nx-docs.netlify.app/docs/technologies/test-tools/storybook/guides/upgrading-storybook
Need to follow-up on the sidebar ordering as it doesn't seem to take it
into account for technologies section.
Fixes DOC-347
## Current Behavior
When a continuous task depends on another continuous task and the
dependent task exits with an error, the parent task continues running
indefinitely. The task execution never terminates, leaving processes
running in the background.
For example, if task `a` (continuous) depends on task `b` (continuous),
and task `b` exits with error code 1, task `a` will continue running
even though its dependency failed.
## Expected Behavior
When a continuous task exits (with any exit code), the failure should be
propagated to dependent tasks:
1. The failed continuous task should be marked as failed
2. Dependent continuous tasks should be marked as skipped
3. All affected continuous tasks should be killed
4. Task execution should terminate with an error
---
## Changes Made
### 1. Restore Error Handling in Continuous Task Exit Handlers
- Re-added the `cleaningUp` flag that was removed in a previous
TUI-related commit
- Modified `onExit` handlers for both regular and shared continuous
tasks to:
- Check if the task exited during normal cleanup vs. unexpectedly
- Call `complete()` with 'failure' status for unexpected exits
- Log error messages for debugging
### 2. Fix `cleanUpUnneededContinuousTasks()` Logic
The previous implementation always added `initializingTaskIds` to the
needed set, even when those tasks were already completed. This prevented
dependency tasks from being killed when the top-level task exited.
Fixed by:
- Only adding tasks from `initializingTaskIds` if they are still
incomplete
- Keeping dependencies of incomplete tasks alive
- This ensures continuous tasks are killed when no longer needed,
whether a dependency fails or a top-level task exits
### 3. Prevent Status Overwrites
Added a check in `onExit` handlers to only set status to `Stopped` if
the task hasn't already been completed. This prevents the async `onExit`
callback from overwriting the correct status (like 'skipped' or
'failure') with 'Stopped'.
### 4. Fix Signal Handling in `PseudoTtyProcess.kill()`
The Rust pseudo-terminal defaults to SIGINT when no signal is provided,
which does not reliably terminate child processes in PTY sessions.
Fixed by:
- Defaulting to SIGTERM in the JavaScript wrapper (rather than changing
the Rust default)
- The JS wrapper is the API boundary that should match Node.js
semantics, where `childProcess.kill(undefined)` defaults to SIGTERM
- The Rust default of SIGINT is appropriate for interactive use
(Ctrl-C), while programmatic cleanup needs SIGTERM
- This ensures child processes are properly killed when
`runningTask.kill()` is called
**File:** `packages/nx/src/tasks-runner/pseudo-terminal.ts`
## Technical Details
The fix leverages the existing task failure propagation mechanism in
`complete()` instead of using `process.exit(1)`, which:
- Allows proper cleanup through normal execution flow
- Respects the `--bail` flag configuration
- Works correctly with both TUI and non-TUI modes
- Maintains consistency with how other task failures are handled
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Older versions don't support the `nx mcp` command yet - but they CAN use
the `nx-mcp` package via npx
## Expected Behavior
We generatee the proper command into their MCP config by matching on
their version
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
When multiple versions of the `nx` package are installed in a workspace
(e.g., due to a third-party package incorrectly depending on nx), users
have no visibility into
this issue through `nx report`.
## Expected Behavior
The `nx report` command now detects when other packages depend on a
different version of nx than the workspace version and reports this
clearly:
⚠️ Multiple Nx versions detected
Your workspace uses nx@20.0.0, but other packages depend on a different
version:
- some-package → @scope/tool → nx@19.0.0
These packages should not have nx as a dependency. Please report this
issue to the package maintainers.
Run pnpm why nx@19.0.0 for more details.
This helps users identify and report problematic packages that bundle
their own version of nx.
## Related Issue(s)
N/A - This is a proactive improvement to help users diagnose workspace
issues.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
nightly tests fail on gradle because of gradle parsing
## Expected Behavior
nightly tests should pass
## Current Behavior
We do not generate AI Instructions to aid with upgrading from Next 15 to
Next 16
## Expected Behavior
Add a migration generator to create a file containing instructions for
an LLM to upgrade Next 15 to Next 16
## Related Issue(s)
Closes NXC-3418
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
In TS Solution setups, we generate webpack config with
`generatePackageJson: true`. This is confusing and unneeded.
It should be set to false in TS Solution repos.
## Expected Behavior
Set `generatePackageJson: false` in webpack config for TS Solution
Setups
Closes NXC-3521
When generating NestJS applications in Angular workspaces, the base
tsconfig sets moduleResolution to 'bundler' which causes TS5095 errors
because 'bundler' requires module to be 'preserve' or 'es2015+'.
NestJS applications should use Node.js module resolution instead. This
fix sets moduleResolution to 'node' for NestJS applications (except when
using TS solution setup, which uses 'nodenext').
Fixes#33589
## Current Behavior
The ⚠️ emoji at the beginning of bc commits is duplicated in the bc
section of the changelog.
This is unneeded.
## Expected Behavior
Ensure the ⚠️ is not repeated in the bc section of the changelog
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
Close NXC-3516
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
1. **Socket Race Condition**: All daemon servers listen on the same
socket path, causing a race condition where shutting down daemons remove
sockets that newly started
daemons are listening on.
2. **Daemon Console Check Blocks**: The daemon availability check runs
synchronously and blocks the main thread.
3. **Version Mismatch Issues**: Packages using a different nx version
than what's installed in the workspace could still use the daemon,
leading to potential issues.
## Expected Behavior
1. Each daemon server creates a unique socket path based on its process
ID, preventing race conditions.
2. The daemon console check runs in the background without blocking.
3. The daemon is disabled when there's a version mismatch between the
running nx and the workspace's installed version.
## Changes
### 1. Unique Daemon Socket Paths
- Include `process.pid` in the socket directory hash to make each
daemon's path unique
- Store the socket path in `server-process.json` so clients know where
to connect
- Clients read the socket path from the file instead of calculating it
### 2. Backgroundable Daemon Check
- Reapplied #33491 which makes the Nx Console install check run on the
daemon in the background
- This was previously reverted due to the socket race condition (now
fixed by change 1.)
- Running in background also allows pulling the latest check logic from
npm
### 3. Version Mismatch Check
- Added `isNxVersionMismatch()` check in `DaemonClient.enabled()`
- Created shared utility `is-nx-version-mismatch.ts` for version
comparison
- Refactored server.ts to use the shared utility
- Uses `require.resolve('nx/package.json', { paths: [workspaceRoot] })`
to properly resolve the workspace's installed nx version
## Related Issue(s)
Fixes daemon socket path race condition and improves daemon reliability.
## Current Behavior
`copy-workspace-modules` executor only copies workspace dependencies 1
level deep.
If that workspace library depends on another workspace library, it is
not copied correctly.
## Expected Behavior
Copy transitive workspace modules
## Related Issue(s)
Fixes NXC-3466
When adding Cypress to a library, the generated commands.ts causes
TS2669 error because declare global requires the file to be a module.
Changed to use declare namespace Cypress directly.
Fixes#32930
## Current Behavior
PR #33491 introduced a daemon call into every command and caused
unexpected issues...
## Expected Behavior
the change is reverted while we investigate a proper fix
## Changes
This reverts commit 9471207767 from PR
#33491.
## Related Issue(s)
Fixes#33472
## Current Behavior
The manual DTE workflow explicitly sets the `ref` parameter to `${{
github.event.pull_request.head.sha }}` to checkout the actual branch
HEAD instead of the merge commit.
## Expected Behavior
Use GitHub's default ref behavior instead of explicitly overriding it,
as the default behavior now handles this correctly.
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
When generating a React component with --style=tailwind, the component
template incorrectly includes `className={styles['container']}` and
attempts to import CSS modules.
## Expected Behavior
Components generated with --style=tailwind should not include CSS
modules imports or `styles['container']` references, since Tailwind
doesn't use CSS modules.
## Related Issue(s)
Closes NXC-3511
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Stats don't come along with versions which makes it hard to see if it
was specific changes that make a difference.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Stats are tagged with the version so we can compare stats between
versions
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
This PR fixes an issue where migrations can hang due to out invocation
of `storybook automigrate`. We are passing both `--config-dir` and
`STORYBOOK_PROJECT_ROOT`, the latter causes hanging with Storybook v9.
https://www.loom.com/share/39bbb350595c4a13aef86ec29f4b748f
## Current Behavior
Hangs
## Expected Behavior
Does not hang
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#32492
This PR cleans up the markdown files under `packages/`. We previously
had to support Next.js docs and translate it for astro docs with proper
markdown syntax. This applies to generators, executors, and migrations.
Also removes the function to do the translation in astro app since it's
no longer needed.
## Code block (migrations)
<img width="1086" height="800" alt="Screenshot 2025-11-20 at 1 23 53 PM"
src="https://github.com/user-attachments/assets/bd9acb9b-7960-4e41-9d26-22d29da6658e"
/>
## Aside (generators)
<img width="802" height="443" alt="Screenshot 2025-11-20 at 1 43 17 PM"
src="https://github.com/user-attachments/assets/e2999821-8783-46ed-a984-2193f6f8eafa"
/>
## Current Behavior
During createNodes, if a file is imported and a function in said file
invokes the Nx project graph creation process, there's an infinite loop
that results in all nx commands hanging with little feedback.
Theoretically this loop would terminate at around the 10 minute mark,
but throughout the loop we would be digging deeper and deeper into
recursive territory so its possible that the node process could become
overwhelmed and hang.
## Expected Behavior
If recursive graph creation is detected, Nx terminates and logs the call
stack so it can be investigated properly.
## Related Issue(s)
Fixes#29618
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: AgentEnder <AgentEnder@users.noreply.github.com>
This PR adds the ability for users to import ESLint rules from arbitrary
location in the workspace rather than storing them in
`tools/eslint-rules`. This is useful for monorepo not using
npm/yarn/pnpm workspaces and need a mechanism to load from any custom
rules location without them being installed/symlinked.
It also handles TS files automatically.
Demo: https://www.loom.com/share/3c32af4555614eeab4f81fce8db0c955
Example:
```js
import baseConfig from "../../eslint.config.mjs";
import { loadWorkspaceRules } from "@nx/eslint-plugin";
const customRules = await loadWorkspaceRules("foo/bar/eslint-rules");
export default [
...baseConfig,
{
ignores: ["**/out-tsc"],
},
{
files: ["**/*.ts", "**/*.tsx", "**/*.js", "**/*.jsx"],
plugins: {
custom: { rules: customRules },
},
rules: {
"custom/valid-command-object": "error",
},
},
];
```
---------
Co-authored-by: Leosvel Pérez Espinosa <leosvel.perez.espinosa@gmail.com>
## Current Behavior
Daemon command hangs at end instead of exiting
## Expected Behavior
Daemon command exits
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
There's some issues with the jest configs in the repo, CJS files having
`import` in them, etc.
## Expected Behavior
CJS files don't have `import`
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
`cache: true` is overridden if task name is dev
## Expected Behavior
`cache: true` has priority
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#32610
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Using .mts extension forces files to always be treated as ESM modules,
ensuring consistent behavior regardless of package.json or tsconfig
settings.
This matters for Node 24 because by default Node will strip types from
`.ts` files and then they are resolved through normal Node resolution.
In the past we can control CJS/ESM through tsconfig options, but now
only extension or `type` in `package.json` matters.
Changes:
- Updated all createOrEditViteConfig calls to pass useEsmExtension: true
- Updated normalizeViteConfigFilePathWithTree to check for .mts files
first
- Updated test files to expect .mts config files
- Updated snapshots to reflect new .mts extension
Closes NXC-3446
Flat config overrides util may fail when it isn't a plain JS object.
This PR makes the `hasOverrides` function more robust against these
cases.
Fixes#31796
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
the JSON parsing is broken because in verbose mode, the gradle plugin
returns more than just JSON.
## Expected Behavior
JSON parsing in the test should work
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
We naively mark WholeFileChange for commits when getting the relevant
commits for projects.
There is already logic to perform better diff checking for lock files,
especially in the case of pnpm catalog usage
## Expected Behavior
Reuse existing logic to determine file changes more accurately
## Related Issue(s)
Fixes#33413
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
If no inputs or named inputs are defined, this area of code was hit:
```
const DEFAULT_INPUTS: ReadonlyArray<InputDefinition> = [
{
fileset: '{projectRoot}/**/*',
},
{
dependencies: true,
input: 'default',
},
];
export function getNamedInputs(
nxJson: NxJsonConfiguration,
project: ProjectGraphProjectNode
) {
return {
default: [{ fileset: '{projectRoot}/**/*' }],
...nxJson.namedInputs,
...project.data.namedInputs,
};
}
```
This resulted in weird behavior when the user would define `default` in
named inputs, but it would seemingly only be applied to the project's
deps and not the project itself
## Expected Behavior
The `default` input is the default for both
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #https://github.com/nrwl/nx/issues/32924
## Current Behavior
Every time a daemon connection is opened, we create a new interval and
unref it. This results in the daemon checking its process termination at
an ever increasing rate, which presents as increased memory usage and
practically means the daemon is just doing a lot more work than it needs
to in this area.
## Expected Behavior
The interval is registered only on initial server startup.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#29836
This PR updates the guide here to also include type entries (which we
generate by default):
https://nx.dev/docs/technologies/typescript/guides/compile-multiple-formats
Update the content to account for the new inferred `@nx/rollup/plugin`
setup, but still mentions the executor. And also link to a tool that can
be used to check for types correctness.
Closes#33258
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: jaysoo <jaysoo@users.noreply.github.com>
if there is an error parsing a schema file for generators/executors then
we should fully error out to prevent caching a "bad" build even if the
site techincally works with missing plugin info.
## Current Behavior
Metrics collection is currently disabled in the CI workflow via the
`NX_CLOUD_ENABLE_METRICS_COLLECTION` environment variable set to
'false'.
## Expected Behavior
Metrics collection should be enabled to gather build and performance
data from CI runs.
## Related Issue(s)
Reverts the change from #33497
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
The `@nx/js:typescript-sync` generator never syncs external project
references to `tsconfig.json` files if a runtime tsconfig file exists.
## Expected Behavior
The `@nx/js:typescript-sync` generator should sync external project
references to `tsconfig.json` files if it includes any files or a
runtime tsconfig file doesn't exist.
## Summary
This PR fixes a critical deadlock issue in the metrics collector that
occurred due to inconsistent lock acquisition order between the
collection thread and registration threads. The fix involved
restructuring lock scopes across multiple functions to maintain a
consistent lock hierarchy.
## Changes
- Fixed lock acquisition order in 4 registration functions
(register_main_cli_process, register_main_cli_subprocess,
register_task_process, register_batch)
- Restructured collect_metrics() to minimize system lock scope and
release it before acquiring other locks
- Fixed collection helper methods to read PIDs in scoped blocks without
holding system lock
- Added comprehensive trace logging for debugging lock contentions
- Added concurrent test case to verify no deadlocks occur under stress
## Testing
- All 12 metrics tests pass
- Comprehensive concurrent stress test added:
test_concurrent_group_creation_with_subprocess_updates
- Lock ordering consistency test added:
test_lock_order_consistency_across_registration_threads
## Lock Ordering Rule
Established and enforced this hierarchy across all threads:
1. Acquire system lock first
2. Release system lock
3. Then acquire registration/PID locks
This prevents circular wait conditions (A→B / B→A) that cause deadlocks.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
When Storybook is installed with a version range like `^10.0.0` or
`~8.5.3`, the configuration generator fails with error:
```
NX Invalid Version: ^10.0.0
TypeError: Invalid Version: ^10.0.0
```
This occurs because `gte()` from semver doesn't accept version ranges on
the left-hand side - only valid semver versions are allowed there.
The Storybook configuration generator should work with version ranges by
extracting the actual version number before comparison.
Fixes#33514
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Env variables from the parent target are not propagated to the atomized
target e.g.
`.test-ci.env` will be only applied to **no-op** `test-ci` but not to
`test-ci--path/to/test/file`.
## Expected Behavior
Running an atomized target will load from the parent's env files.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
Gradle projects in Nx workspaces can only configure metadata through
Gradle's built-in mechanisms. There's no way to specify Nx-specific
project metadata (like tags) or customize task target configurations
other than overriding with `project.json`
## Expected Behavior
Developers can now configure Nx-specific metadata for both projects and
tasks using a type-safe Kotlin/Groovy DSL:
### Project-level metadata (in build.gradle.kts):
```
nx {
set("name", "my-service")
array("tags", "scope:backend", "type:api")
set("description", "Payment processing service")
}
```
### Task-level metadata (in build.gradle.kts):
```
tasks.named("integrationTest") {
nx {
set("cache", false)
array("tags", "integration", "slow")
}
}
```
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: MaxKless <MaxKless@users.noreply.github.com>
## Current Behavior
In certain scenarios, Nx commands would hang between command completion
and process exit. This was caused by inefficient message end detection
in the
daemon socket communication, where the check for `MESSAGE_END_SEQ` could
fail when TCP packets were fragmented.
## Expected Behavior
With this PR, the message end detection is more robust and handles TCP
packet fragmentation correctly, preventing the hanging issue. The
changes also
add better performance tracking and logging to help diagnose similar
issues in the future.
## Changes Made
- **Improved message end detection**
(`consume-messages-from-socket.ts`): Added a preliminary check of the
last character's code point before checking
the full MESSAGE_END_SEQ, which prevents false negatives when TCP
packets are fragmented
- **Enhanced performance tracking** (`daemon/client/client.ts`,
`daemon-socket-messenger.ts`): Added message-type-specific performance
marks and
measures for better debugging
- **Added server-side logging** (`daemon/server/server.ts`): Added
logging for message receipt, serialization, and response to help
diagnose
communication issues
## Related Issue(s)
This fix addresses hanging issues observed in daemon communication when
commands complete but the process doesn't exit.
Add a skipDefaultTag option to the DockerTargetOptions interface that
allows users to opt out of the automatic default tag that is prepended
to build targets.
This is useful for multi-platform builds that need to push during build
(e.g., using --platform linux/amd64,linux/arm64 --push), where the
default tag causes build failures because it attempts to push a tag that
was not configured.
- Add skipDefaultTag?: boolean to DockerTargetOptions interface
- Modify buildTargetOptions to conditionally skip default tag when
skipDefaultTag is true
- Inherit skipDefaultTag from parent target in configurations
- Add comprehensive unit tests for skipDefaultTag functionality
- Add e2e test to verify skipDefaultTag works end-to-end
- Maintains backward compatibility (default behavior unchanged when
option not specified)
Fixes#33477
## Current Behavior
Loading local plugins that are relative paths from workspace root, that
point to a JS file, still require preliminary data from default plugins
despite being resolvable. This is because we aren't passing `paths` to
`require.resolve`, so it is trying to resolve relative to the nx package
instead of the workspace.
## Expected Behavior
The straight JS path resolves
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
The metrics collector has several inefficiencies and architectural
issues:
- Complex hierarchical data structure (`ProcessTreeMetrics`) that
doesn't align with how the data is consumed
- Separate `MetadataStore` struct with unnecessary indirection
- Full metadata resent to all subscribers on every collection cycle
- Mutable parameters passed through collection functions instead of
functional return values
- Repeated allocations and clones across collection cycles
- `CollectionRunner` tightly coupled to NAPI, making it untestable in
pure Rust
## Expected Behavior
This PR restructures the metrics collector for better performance,
testability, and maintainability:
### Architectural Changes
1. **Flat Process Model**: Replaced hierarchical `ProcessTreeMetrics`
with a flat `Vec<ProcessMetrics>`, simplifying data flow
2. **Group-Based Organization**: Introduced `GroupInfo` and `GroupType`
to logically organize processes:
- `MainCLI` - Nx CLI process and its subprocesses
- `Daemon` - Nx daemon and its children
- `Task` - Individual task execution processes
- `Batch` - Batch execution with multiple tasks
3. **Incremental Metadata Updates**:
- Track which groups and processes have been sent using
`Arc<DashMap<String, GroupInfo>>` and `Arc<DashMap<String,
ProcessMetadata>>`
- Only send new metadata to subscribers instead of full state every
cycle
- New subscribers receive full metadata on first update via
`needs_full_metadata` flag
- Automatic cleanup of dead process/group metadata
4. **Shared State with Arc**:
- Metadata maps shared between `ProcessMetricsCollector` and
`CollectionRunner` using `Arc<DashMap>`
- Eliminated duplicate metadata storage
- Single source of truth for all metadata
5. **Functional Programming Pattern**:
- Collection functions now return `Result<MetricsCollectionResult>`
instead of mutating parameters
- Cleaner error handling with `inspect_err` and `map`
- Easier to reason about data flow
- Removed ~100 lines of code by consolidating logic
6. **Channel-Based Communication**:
- Decoupled `CollectionRunner` from NAPI using `crossbeam_channel`
- Collection thread sends metrics via channel to listener thread
- Listener thread receives metrics and notifies NAPI subscribers
- `CollectionRunner` is now NAPI-free and fully testable in pure Rust
- Non-blocking collection (subscriber callbacks don't block metrics
collection)
### Performance Optimizations
- Pre-allocated `Vec` capacity when combining metrics from different
sources
- Eliminated unnecessary `HashMap` clones during metadata updates
- Single-pass insertion into `DashMap` during string key conversion
- Reduced memory allocations in hot paths
- Collection thread never blocks on JavaScript callbacks
### Code Quality Improvements
- **Testability**: Added 7 pure Rust unit tests for `CollectionRunner`:
- Group creation with different registration types
- Incremental metadata updates
- Dead group cleanup
- All tests pass without requiring NAPI/Node.js runtime
- Clearer separation of concerns between collection and notification
- Better comments explaining incremental update strategy
- More idiomatic Rust patterns throughout
- Updated TypeScript type exports to match new structure
### Threading Model
**Before:**
```
CollectionRunner (mixed collection + NAPI notification)
```
**After:**
```
CollectionRunner (pure Rust, testable)
└─> Channel
└─> Listener Thread
└─> NAPI ThreadsafeFunction
└─> Subscribers
```
## Testing
- ✅ 241 Rust tests passing (including 7 new `CollectionRunner` tests)
- ✅ Native module builds successfully
- ✅ TypeScript types updated and exports verified
## Related Issue(s)
Part of ongoing metrics collector optimization work.
## Current Behavior
The Nx Console install check for the prompt happens in the main process,
adding some overhead to each invocation of nx.
## Expected Behavior
We want this check to happen on the daemon so that it's running in the
background. If it's still running when nx is invoked, we can just skip
the prompt since it's non-critical.
Running it in the background also allows us to pull the latest version
of the logic from npm when executing - that way we can keep the logic
older versions up-to-date even when ppl don't migrate to latest.
## Current Behavior
The Maven plugin is currently at version 0.0.9.
## Expected Behavior
This PR bumps the Maven plugin to version 0.0.10 and creates the
necessary migration for users to automatically update their pom.xml
files.
## Related Issue(s)
N/A - Routine version bump
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
https://www.loom.com/share/560ceccdad45462e9fd3e3f185fc9fa5
Node 24 has stricter readline behavior, and enquirer is not checking for
closed state when invoking operations, resulting in an
ERR_USE_AFTER_CLOSE error when users press Ctrl+C during interactive
prompts.
This commit fixes the issue by adding uncaughtException handler to
ignore ERR_USE_AFTER_CLOSE errors.
When users press Ctrl+C, the process now exits cleanly without showing
an ugly error stack trace.
Fixes NXC-3412
Co-authored-by: Claude <noreply@anthropic.com>
Updates the Nx Powerpack docs and marketing page to make it clear that
Powerpack packages are included with Nx Enterprise, and cannot be
purchased separately, and remove references to the Nx Powerpack trial.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Caleb Ukle <caleb@nrwl.io>
The recipe for switching to TS project references states "If you
reference a local library project with its own `build` task" which
caused confusion. Users thought only buildable libraries should be
included in devDependencies, leading them to create unnecessary path
aliases for non-buildable libraries.
Closes DOC-149
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
Currently, telemetry stats are only recorded when `create-nx-workspace`
completes successfully. This doesn't capture how many times the command
is invoked vs completed.
## Expected Behavior
Record a stat when `create-nx-workspace` is first invoked (before any
prompts), enabling analysis of drop-off between initial invocation and
workspace completion.
## Changes Made
### Telemetry
- Added `recordStat()` call in `normalizeArgsMiddleware()` immediately
after welcome message and before any user prompts
- Records with command name `create-nx-workspace` and metadata
`['start']` to distinguish from completion stat
- Allows correlation of invocation and completion events for drop-off
analysis
### AI Agents Prompt
- This is being temporarily disabled because we noticed a dip in
create-nx-workspace completions that lines up when this was released.
Disabling it temporarily to see if the dip is recovered by disabling the
prompt.
### React Framework Selection
- Added early returns in `determineReactFramework()` for cases where
framework is already provided or interactive mode is disabled
- Improves performance by avoiding unnecessary prompt interactions
### Code Quality
- Reorganized imports in alphabetical order for better maintainability
- Removed unused import (`printSocialInformation`)
## Related Issue(s)
WIP - Draft for discussion
## Current Behavior
When `nx add @nx/s3-cache` fails due to incompatible peer dependencies
or other installation errors, users see only a generic error message
without the actual error details from the package manager.
## Expected Behavior
The command should display complete error messages from the package
manager (both stdout and stderr), including peer dependency conflicts
and other important diagnostic information.
## Changes
Fixed the exec callback in the `installPackage` function to:
1. Capture the `stderr` parameter (was previously ignored)
2. Log both stdout and stderr with a newline separator for clarity
3. Ensure users see all error information from package managers
## Why It Matters
Package managers write installation errors and peer dependency warnings
to stderr. By ignoring stderr, users had no visibility into what
actually failed, making it difficult to diagnose and fix issues.
Fixes issue with `nx add` not showing proper error messages.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
The `remove-redundant-ts-project-references` migration fails with an
error when run on workspaces that don't have a root `tsconfig.json`
file, such as nx-examples.
## Expected Behavior
The migration should skip workspaces that are not using TypeScript
solution setup instead of throwing an error.
## Related Issue(s)
Fixes the issue encountered when running the migration on
nrwl/nx-examples repo.
## Changes
- Added check to skip migration if workspace is not using TS solution
setup
- Updated test setup to properly configure TS solution for existing
tests
- Added new test cases to verify skip behavior
The migration now uses `isUsingTsSolutionSetup()` to detect if:
- `tsconfig.base.json` exists
- `tsconfig.json` exists and extends the base
- Package manager workspaces are configured
- Proper TS solution structure is in place
Workspaces missing any of these requirements will have the migration
skip silently.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
The migration for removing redundant TypeScript project references is
set to version `22.1.0-beta.8`.
## Expected Behavior
The migration should be updated to version `22.1.0-rc.1` to align with
the release candidate version.
## Related Issue(s)
N/A - Version update as requested.
## Current Behavior
The `@nx/js:typescript-sync` generator adds project dependencies as
TypeScript project references to each project's `tsconfig.json` and
runtime tsconfig file (e.g., `tsconfig.app.json`, `tsconfig.lib.json`,
etc.). This is redundant since projects' `tsconfig.json` files already
reference the runtime tsconfig file, which would reference the
dependencies.
## Expected Behavior
The `@nx/js:typescript-sync` generator should add project dependencies
as TypeScript project references to each project's runtime tsconfig file
(e.g., `tsconfig.app.json`, `tsconfig.lib.json`, etc.). If the project
only has a `tsconfig.json` file, it should add them to it.
We've observed some performance improvement with this change while
running the `typecheck` tasks.
## Summary
This PR combines two critical performance optimizations for batch task
scheduling and task hashing:
### 1. Batch Scheduling Fix
Fixed a correctness bug in the batch scheduling optimization where the
`visitedInBatch` tracking happened too early. Now tasks are only marked
as visited AFTER all scheduling checks pass, ensuring tasks can be added
to the batch from any valid dependency path.
**Files Modified:**
- `packages/nx/src/tasks-runner/tasks-schedule.ts`
**Impact:**
- Prevents task splitting across unnecessary batch boundaries
- Maintains correctness while optimizing performance
- All batch scheduling tests pass
### 2. Task Output Hashing Optimization
Added a DashMap-based cache to the Rust TaskHasher to prevent redundant
hashing when multiple tasks depend on the same outputs.
**Files Modified:**
- `packages/nx/src/native/tasks/task_hasher.rs` - Added
task_output_cache field
- `packages/nx/src/native/tasks/hashers/hash_task_output.rs` - Implement
cache logic
## Root Cause of Issue #33366
Large project graphs with high dependency fanout exhibit slow
`hashMultipleTasks` because:
- 100+ tasks may depend on the same 10 build tasks' outputs
- This generates 1,000+ separate `TaskOutput` hash instructions
- Each instruction independently:
- Lists output files from disk (filesystem I/O)
- Builds glob patterns
- Hashes the same files
- Result: Same files hashed 100× redundantly
## Solution: Task Output Cache
The cache key combines glob pattern and sorted output paths. When
identical outputs are hashed with the same pattern:
- First task: computes hash (~milliseconds) and stores in cache
- Remaining 99 tasks: cache hits (~nanoseconds each)
### Cache Lifetime
- `TaskHasher` instantiated once per `hashMultipleTasks` call
- Cache persists for entire hashing session
- Discarded when `hashMultipleTasks` completes
- Optimal scope for cache hit maximization
## Performance Impact
**Expected Improvements:**
- Best case (100 tasks, 10 shared deps): 100× speedup
- Typical monorepo: 10-20× speedup
- No shared deps: No regression (cache lookup negligible)
**Issue #33366 Analysis:**
- Current: `Time for 'hashMultipleTasks' 49351.488518` (49 seconds)
- Expected with optimization: ~5-10 seconds (depending on actual
dependency structure)
## Testing
- ✅ All task scheduling tests pass (2262 passed, 0 new failures)
- ✅ Batch mode tests pass (6/6)
- ✅ Native build completed successfully
- ✅ No regressions in existing functionality
## Design Notes
- Task output cache follows same pattern as `workspace_files_cache`,
`external_cache`, `runtime_cache`
- Thread-safe using DashMap with Arc for Rayon parallel processing
- Instrumented with trace-level logging for cache hits/misses
- Cache automatically cleaned up when TaskHasher is dropped
Updates the `ng-packagr` executors to support a breaking change in v21.
This needs to be done in advance because we use the published
`@nx/angular` executors to build the `@nx/angular` source code. To
update to Angular v21, we need this change to be merged, released, and
installed in the Nx repository so that we can build the `@nx/angular`
package containing the support for Angular v21.
Users cannot import TypeScript schema definitions or schema.json files
from Nx packages due to strict package exports introduced in Nx 21.0.0.
Users can now import both TypeScript definitions and JSON schemas from
generator/executor/builder paths using wildcard export patterns. Both
first-level (`*`) and second-level (`*/*`) patterns are supported to
handle different import depths.
Note: For old plugins that had `src/...` deep imports we keep those in
`exports`, but for newer plugins that always used `exports` we skip
`src/` in the export path. So `@nx/nuxt/generators` instead of
`@nx/nuxt/src/generators`.
Fixes#33336
## Current Behavior
nx init is executed with whatever version is installed globally by npm
(might be outdated)
## Expected Behavior
we pull down the latest version from npm (if it has provenance) and run
that when executing.
Also introduced a new `NX_USE_LOCAL` env var that will be respected by
all commands that have this pulling-from-latest behaviour.
Update CI to Node 24. Note that the e2e-release changes are pulled from
the original PR.
Note: There are changes to NPM 11 (Node 24) to make it run slower than
NPM 10 (Node 20/22) for publish. (https://github.com/nrwl/nx/pull/31934)
e.g. https://github.com/npm/cli/releases/tag/v11.0.0-pre.1 (`Upon
publishing, in order to apply a default "latest" dist tag, the command
now retrieves all prior versions of the package.` which incurs more
network cost)
## Current Behavior
The typecheck target in graph/client/project.json only depends on
^typecheck targets from other projects.
## Expected Behavior
The typecheck target now includes nx:build-native as a dependency to
ensure native dependencies are built before type checking.
## Related Issue(s)
This fix resolves typecheck failures caused by missing native
dependencies.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: FrozenPandaz <FrozenPandaz@users.noreply.github.com>
## Current Behavior
there is no way to generally influence how maven goals/phases are
represented as targets in nx. This could be useful though for organizing
targets in nx, for example through nx.json `targetDefaults`
## Expected Behavior
There's a `targetNamePrefix` plugin option that can be passed.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: MaxKless <MaxKless@users.noreply.github.com>
After PR #33256 split lockfile parsing into separate node and dependency
caches, a regression occurred where dependencies could be regenerated
without nodes, leaving a shared module-level variable (`keyMap`) empty
and causing incorrect dependency resolution.
Changes:
- Serialize `keyMap` with nodes cache to maintain state between phases
- Remove module-level shared state from pnpm, npm, and yarn parsers
- Move `keyMap` creation inside `getNodes` functions for better
encapsulation
- Update `readCachedExternalNodes` to deserialize `keyMap` internally
Update from the macos-13 is in brownout and will be gone soon.
- macos-15-intel for x86_64-apple-darwin (Intel) builds
- macos-latest for aarch64-apple-darwin (ARM64) builds
Closes NXC-3444
## Current Behavior
We currently only generate vitest projects using Vitest 3
## Expected Behavior
Use Vitest 4 when generating new projects
## Related Issue(s)
Closes NXC-3343
Closes NXC-3379
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Clarifies some details of the Nx Cloud GitHub integration, such as which
features are available when you use the base integration vs a GitHub
powered organization.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
## Current Behavior
We do not render the commit title in the BC section of generated
changelogs.
## Expected Behavior
We should render the commit title in the BC section of generated
changelogs along with the Remote Release Client reference to the commit.
## Related Issue(s)
Closes NXC-3290
## Current Behavior
There may be a scenario when `cleanedAngularVersion` is of type `object`
rather than `string` which proceeds to error when passed to
`semver.major()`.
## Expected Behavior
If `cleanedAngularVersion` is not `string`, assume the latest version
will be installed. Similar to how no found angular version is handled.
## Related Issue(s)
Fixes#33347
- Fix for a bug with the external project references cache
- Add more caching for repeated operations
- Skip tsconfig files processing based on which targets should be
inferred
Fixes#33076
## Current Behavior
The library generator has an unused import and incorrect import pattern
for the vitest generator.
## Expected Behavior
Clean imports with the correct way to access the configurationGenerator
from @nx/vitest.
## Changes
- Removed unused imports (logger, readJson)
- Updated vitest generator import to use direct require instead of
ensurePackage pattern for accessing the generator
Fixes #
## Current Behavior
The Storybook 10 migration was originally intended to be optional.
## Expected Behavior
Make Storybook 10 migration add the migration generator to
migrations.json always. Users can remove it from here if they do not
want it, or they can use the Migrate UI from Nx Console to choose not to
run it.
Split entry point of `@nx/vitest` into `index.ts` for the Inference
Plugin, `generators.ts` for Generators, `executors.ts` for the
Executors.
Ensure the `README.md` is copied to the correct output directory
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
Split `vitest` out of `@nx/vite` and create a new `@nx/vitest`.
This allows for each plugin to have a single responsibility. One for
bundling, one for testing.
It should allow for lighter setups where Vite for Bundling is not
required, but users still want to use vitest for testing.
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Coly010 <Coly010@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Storybook was accidentally downgraded to 9.1.9
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Storybook is upgraded back to 10.0
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
Cypress v15 is not supported.
## Expected Behavior
Cypress v15 should be supported.
## Related Issue(s)
Fixes#33304
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: leosvelperez <leosvelperez@users.noreply.github.com>
CI and nightlies can flake out during expo test if cypress or playwright
times out waiting for webserver. This makes is to the `export` that
powers `static-serve` is run before running e2e.
This is not usually a problem in new workspaces with inference, but this
legacy test uses executors so continuous task dependency isn't set up.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Nx plugin for Gradle is at version 0.1.8
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Nx plugin for Gradle is at version 0.1.9
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
- Track relevant CPU and memory system metrics.
- Link plugins to workers when possible.
- Refactor collector code by splitting it into two separate structs.
## Current Behavior
Maven plugin is currently at version 0.0.8.
## Expected Behavior
Maven plugin should be bumped to version 0.0.9 with a corresponding
migration for users.
## Changes Made
- Updated parent POM version to 0.0.9
- Updated package.json version to 0.0.9
- Updated mavenPluginVersion constant to 0.0.9
- Added new migration (0-0-9) to update user pom.xml files from 0.0.8 to
0.0.9
- Scheduled migration for Nx v22.1.0-beta.6
## Testing
- ✅ Maven package tests pass
- ✅ Build succeeds
- ✅ Linting passes
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Because `./nx` is passing args with `$@`, args are being split by
spaces. Reference for this behaviour:
https://www.gnu.org/software/bash/manual/html_node/Special-Parameters.html#Special-Parameters-1
This results in this set of process args when running `./nx start-ci-run
--distribute-on="3 linux-medium-jvm"`
```
[
"<user path>/.nvm/versions/node/v22.19.0/bin/node",
"<user path>/Projects/OTW/mm-test/.nx/nxw.js",
"start-ci-run",
"--distribute-on=3",
"linux-medium-jvm",
]
```
## Expected Behavior
the arg with whitespace should not be split before being passed to nx:
```
[
"<user path>/.nvm/versions/node/v22.19.0/bin/node",
"<user path>/.nx/nxw.js",
"start-ci-run",
"--distribute-on=3 linux-medium-jvm",
]
```
This PR is just for the repo itself to use `.cts` to explicitly use CJS
for jest config. Node 24 strip types so having `.ts` files with ESM
syntax even though we're previously transpiling them to CJS is a
problem.
Make run-one task terminal outputs in the TUI non-interactive by
default. Most tasks don't need interactivity, and it causes TUI to
ignore all its key bindings because it forwards them to the underlying
program. If interactivity is needed, users can press `i` to enable it.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Currently we detect if inputs are found in the build directory to
determine if they are considered dependent task output files. We can use
a simpler heuristic instead.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
If an input is gitignored (and therefore not hashed by Nx), then we
consider it a dependant task output file. This gitignore classifier will
be a mirror of the class used within the Maven plugin. There will be
another PR to move this classifier into a shared kotlin project that can
be used between both projects.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
Maven target dependencies are defined as simple strings that reference
other targets. Currently, parameters are not forwarded through these
dependencies when Maven goals are executed.
## Expected Behavior
Target dependencies in Maven should forward parameters (args) to their
dependency targets, enabling better parameter propagation through the
build pipeline.
## Changes Made
Modified `NxTargetFactory.kt` to transform simple string dependency
references into structured dependency objects with explicit parameter
forwarding:
- Install dependencies now forward parameters
- Phase dependencies now forward parameters
- Test dependencies now forward parameters
- CI target dependencies now forward parameters
This ensures that when a Maven goal executes, any parameters passed to
it are properly forwarded to all transitive target dependencies.
## Related Issue(s)
This change enables parameter passing through Maven target dependencies
via the new dependency object format with `"params": "forward"`.
When using Jest 30 with SWC, users are seeing an error where `__dirname`
is not defined for ESM modules. This is because the `.ts` extension is
type-stripped by Node 22.17/24+ via checking for
[`process.features.typescript`](https://github.com/jestjs/jest/blob/fe7f28c9d1941f5c2726831cd9d9e479b401610e/packages/jest-config/src/readConfigFileAndSetRootDir.ts#L46).
This means that instead of using the `commonjs` we set for `ts-node`,
normal Node resolution kicks in, and is now treating `jest.config.ts` as
ESM.
This PR fixes this issue by using an explicit `.cts` extension, which
forces CommonJS that we assume for Jest configs.
Note: For Jest 29 or earlier we need to keep `jest.config.ts` since the
`.cts` extension is not supported prior to Jest 30.
There's also a fix for an existing issue where using `module.exports` of
anything else from `@types/node` will error out if `tsconfig.json` has a
`types` field but does not include `node`. See:
https://www.loom.com/share/7ebe3c90a70e4ec7bfa53cbcccaaea7dFixes#32236
---------
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
`@nx/vite` has a peerDep range of only `1 | 2 | 3` for `vitest`.
This will cause peer dep conflicts for using wishing to use Vitest 4.
## Expected Behavior
Add Vitest 4 to the peerDep range of `@nx/vite` to prevent conflicts.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
when trying to format with prettier while outside of the workspace (for
example in a `tmp` nx installation like is created during
`configure-ai-agents`), resolving prettier could fail even though it's
present in the actual workspace.
## Expected Behavior
resolving prettier works if it's available in either the proper
workspace or the tmp one by specifying `paths` in `require.resolve`
## Current Behavior
We currently support Next 14 and 15.
## Expected Behavior
Add support for Next 16, bringing support to 14, 15, 16.
Existing workspaces will continue to use the version they are on.
New workspaces will use Next 16.
Refer to Next 16 Migration Guide for migrating from Next 15 to 16
## Related Issue(s)
Fixes#33207
---------
Co-authored-by: Eric Büttner <eric.buettner@tuffz.com>
This pull request makes a minor update to the CI workflow configuration.
The change simplifies the `Start CI Run` step by removing the
`--fix-tasks="!*check-commit*"` option from the `npx nx-cloud@next
start-ci-run` command.
Updates @module-federation packages from 0.18.0 to 0.21.2 and
@module-federation/node from 2.7.11 to 2.7.21 to address Koa Open
Redirect vulnerability (CVE: GHSA-g8mr-fgfg-5qpc).
The vulnerability was in transitive dependencies:
@nx/react → @nx/module-federation → @module-federation/enhanced →
@module-federation/dts-plugin → koa@3.0.1-3.0.2
Changes:
- Updated package.json dependencies in @nx/module-federation and
@nx/rspack
- Updated version constants in Angular and React utils/versions.ts
- Added 22.2.0 migrations to all affected packages
Fixes#33285
This PR clarifies that Nx 22 removed SVGR support from Next.js and React
(Webpack/Rspack).
<img width="942" height="1185" alt="image"
src="https://github.com/user-attachments/assets/6ea8393f-b037-489f-804b-eb06d8d07e4c"
/>
Previously we had this option `svgr: true` but was configurable and
didn't align with current best practices like `import Logo from
'./logo.svg?react'`. We removed it from Nx 22, provided a migration, but
users will be confused by the docs.
Fixes DOC-326
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
`createVitest` is looking at the full workspace every time. It should
only look at the directory with the config file.
## Expected Behavior
Pass the root as the projectRoot of the config file found.
## Current Behavior
The Nx TUI doesn't provide any visual feedback about task progress
outside of the terminal window itself. Users need to keep the terminal
visible to see task completion status.
## Expected Behavior
With this PR, the TUI now displays real-time task completion progress in
the terminal window chrome (tabs, title bars, dock icons) using the OSC
9;4 escape sequence. This provides at-a-glance progress feedback even
when the terminal is minimized or in the background.
## Related Issue(s)
N/A - This is a new feature enhancement
## Implementation Details
### What is OSC 9;4?
OSC 9;4 is a terminal escape sequence for displaying progress
indicators, originally from ConEmu and now supported by multiple modern
terminals.
### Key Changes
- Added `update_ghostty_progress()` method to calculate and display task
completion percentage
- Added `clear_ghostty_progress()` method to hide progress when done
- Integrated progress updates into task lifecycle (start, status update,
exit)
- Uses ST terminator (`\x1b\\`) for maximum terminal compatibility
- Writes to stderr to avoid conflicts with TUI rendering on stdout
### Supported Terminals
- **Ghostty** - Full support
- **Windows Terminal** (v1.6+) - Full support
- **VTE-based terminals** (GNOME Terminal, Ptyxis) - Full support
- **Other terminals** - Gracefully ignore sequences (no errors)
### Terminal Compatibility Note
The implementation uses the ST (String Terminator) escape sequence
rather than BEL, as this is preferred by Ghostty and required by
VTE-based terminals, while remaining compatible with Windows Terminal.
## Testing
Tested with:
- Building the native module successfully
- Rust formatting and linting passes
- Running nx commands with the TUI active
The progress indicator updates in real-time as tasks complete and clears
automatically when the TUI exits.
## Current Behavior
When processing scheduled batches, tasks are hashed one at a time even
though the hasher has a `hashTasks` method for batch hashing.
Results from a batch with 109 tasks.
```
hash batch: 8.297s
```
## Expected Behavior
Tasks without custom hashers should be batch-hashed using the hasher's
`hashTasks` method for better performance.
Results from a batch with 109 tasks.
```
hash batch: 991.725ms
```
## Related Issue(s)
This is a performance optimization for task hashing.
---
**Changes:**
- Added a new `hashTasks` function that intelligently separates tasks
with custom hashers from those without
- Tasks with custom hashers are hashed individually using `Promise.all`
- Tasks without custom hashers are batch-hashed using the hasher's
`hashTasks` method
- The function automatically filters out tasks that already have a hash
- Updated `processScheduledBatch` in task-orchestrator to use this new
function
## Current Behavior
Vitest's `createVitest` can be over-eager and include other projects in
the workspace when finding relevant test specifications.
This leads atomizer to look at relative paths outside the project root.
## Expected Behavior
Ensure that the plugin does not look at projects outside the project
root.
## Current Behavior
The Maven migration version was incorrectly set to `0.0.8-beta.0` in the
migrations.json file.
## Expected Behavior
The migration version should be set to `22.1.0-beta.4` to align with the
Nx release version.
## Related Issue(s)
Fixes the migration version discrepancy in the Maven plugin.
Embeds videos about self-healing CI into the corresponding feature doc
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
The Maven plugin is at version 0.0.7 with no automated migration path
for users to upgrade their pom.xml files.
## Expected Behavior
Users can upgrade to Maven plugin 0.0.8 and have their pom.xml files
automatically updated via the Nx migration system.
## Changes Made
- Updated Maven plugin version from 0.0.7 to 0.0.8 in:
- `packages/maven/package.json`
- `packages/maven/src/utils/versions.ts`
- `packages/maven/maven-plugin/pom.xml`
- Created `updateNxMavenPluginVersion()` utility function with:
- Proper XML parsing using `@xmldom/xmldom` DOM API
- Targeted updates only for `dev.nx.maven:nx-maven-plugin` elements
- Safe handling of all other version elements (dependencies, parent,
project, etc.)
- Comprehensive error handling
- Added migration `0-0-8/update-pom-xml-version.ts` that:
- Automatically runs when users upgrade to 0.0.8
- Updates root pom.xml files via the utility function
- Logs status of migrations performed
- Registered migration in `migrations.json`
- Added comprehensive unit tests (9 test cases):
- Updates only the nx-maven-plugin version
- Does not update other plugin versions
- Handles missing files gracefully
- Preserves XML formatting and structure
- Handles multiple plugin references
- Handles whitespace correctly
- Only updates plugins, not parent/project versions
- All tests passing (27/27)
## Test Plan
- [x] Unit tests pass (27 passing tests)
- [x] XML parsing correctly identifies and updates only
`dev.nx.maven:nx-maven-plugin`
- [x] Other version elements remain untouched
- [x] Migration registration validated
## Current Behavior:
Tui is working, but only able to be enabled on windows via env vars or
explicit command line config
## Expected Behavior:
Tui is default on
## Current Behavior
Maven and .NET use a bespoke script to handle skipping an optional
native target in case a system is not setup on a dev's machine.
.NET isn't in codeowners
## Expected Behavior
This pull request introduces improvements to the build and formatting
workflows for the `.NET` and Maven plugins, streamlining the execution
of native targets and updating code ownership assignments. The changes
focus on refactoring build scripts to use a unified runner, adding new
formatting capabilities for .NET projects, and updating the CODEOWNERS
file for clearer team responsibilities.
**Build and Format Workflow Improvements**
* Refactored the `.NET` analyzer build command in
`packages/dotnet/project.json` to use the new `run-native-target.js`
script, replacing the previous direct script invocation.
[[1]](diffhunk://#diff-036c1a7f2e7d98f5a3207441f2ff1cb25b5b5a03343672ce473f4ff0189a5946L25-R25)
[[2]](diffhunk://#diff-42d990ddcbf8d3585553503097ee8b8d1fff8cb6e25e0cd545a87e11d64c03a8L1-L7)
* Added new `format-native` and `_format-native` targets to
`packages/dotnet/project.json`, enabling verification and fixing of code
formatting for the .NET analyzer using `dotnet format`.
**Unified Native Target Runner**
* Introduced the `scripts/run-native-target.js` script to standardize
running native build and install targets, controlled by environment
variables for skipping builds.
**Maven Plugin Build Refactor**
* Updated the Maven plugin's install workflow in
`packages/maven/maven-plugin/project.json` to use the new native target
runner, and removed the obsolete `scripts/build-maven-analyzer.js`
script.
[[1]](diffhunk://#diff-2763fe8a7c2989643f53370a14a08c06616e85c29340fd5bcfa1a67d0deaee7aL11-R11)
[[2]](diffhunk://#diff-972edab06956ad35145cbc20b8e250e7067fbb288b1f99c92661c24f64d3e69dL1-L7)
**Ownership Updates**
* Updated the `CODEOWNERS` file to assign `.NET`-related directories to
`@FrozenPandaz` and `@AgentEnder`, clarifying team responsibilities.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
We support Storybook 8 and 9
## Expected Behavior
Add support for Storybook 10, bringing Storybook support to 8, 9 and 10
## Related Issue(s)
Fixes#33141
## Current Behavior
Maven dependencies were not being resolved correctly from project roots,
which affected the dependency analysis in monorepos with Maven projects.
## Expected Behavior
Maven dependencies should be properly resolved from each project's root,
allowing Nx to correctly understand the project graph for Maven-based
projects.
## Changes Made
- Updated Maven plugin Kotlin code to properly resolve dependencies from
project roots
- Fixed devkit internal utilities to properly handle Maven dependency
resolution
- Updated TypeScript dependencies plugin to align with the new
resolution logic
## Files Changed
-
`packages/maven/maven-plugin/src/main/kotlin/dev/nx/maven/NxProjectAnalyzer.kt`
-
`packages/maven/maven-plugin/src/main/kotlin/dev/nx/maven/NxProjectAnalyzerMojo.kt`
- `packages/maven/src/plugins/dependencies.ts`
- `packages/dotnet/src/plugins/create-dependencies.ts`
- `packages/devkit/internal.ts`
- `packages/nx/src/devkit-internals.ts`
Fixes #XXXXX
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
CodeQL is not enabled for C#, but C# is in the nx repo
## Expected Behavior
CodeQL is enabled on C#
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: Claude <noreply@anthropic.com>
This PR primes the cache for `@vitejs/plugin-vue`, similar to how we
already do for `esbuild`. When `vite.config.ts` is compiled into CJS,
then doing `require('@vitejs/plugin-vue')` may error with a race
condition if an `import` of the same module is in progress.
Fixes #NXC-3289
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
there are recommendations for using the CIPE fixing tools but they are
being removed
## Expected Behavior
removed tools should not be mentioned anymore.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
Completed Maven documentation updates:
- [x] Add `nx show projects` command to display Maven projects after
initialization
- [x] Change example from `nx build` to `nx verify`
- [x] Simplify configuration section to use `plugins: ["@nx/maven"]`
with defaults
- [x] Update configuration description to accurately explain how targets
are created
## Summary
Successfully updated the Maven plugin documentation:
1. **Added `nx show projects` command** - Shows users how to list
discovered Maven projects after running `nx init`
2. **Changed example to `nx verify`** - Uses a more appropriate Maven
lifecycle phase that includes tests and verification
3. **Simplified configuration** - Updated the configuration section to
show the simpler string array syntax `plugins: ["@nx/maven"]`
4. **Corrected target creation description** - Updated the text to
accurately explain that `@nx/maven` automatically retrieves information
about projects from Maven and creates targets for each phase, goal, and
some additional targets for CI
<!-- START COPILOT CODING AGENT SUFFIX -->
<details>
<summary>Original prompt</summary>
> Expand this section
https://nx.dev/docs/technologies/java/maven/introduction#add-nx-to-a-maven-workspace
>
> With instructions to run the following
>
> nx show projects
>
> To see a list of Maven projects
>
> And change nx build Maven project to nx verify Maven project
>
</details>
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 We'd love your input! Share your thoughts on Copilot coding agent in
our [2 minute survey](https://gh.io/copilot-coding-agent-survey).
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: FrozenPandaz <8104246+FrozenPandaz@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
devcontainer wasn't working reliably
## Expected Behavior
devcontainer should work reliably and reuse the configuration setup we
have for all these different tools that are needed
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
in a `.nx` installation, `require.resolve` won't find the `extends`
preset nx.json file because there are no root `node_modules`
## Expected Behavior
in a `.nx` installation, the nested `.nx/installation/node_modules` are
also used to try and resolve the preset.
This PR builds on the previous fix that ensured `eslint-config-next` was
correctly installed when using Next.js 15. #30258
Now, the logic has been further refined to dynamically determine the
installed Next.js version and install the corresponding
`eslint-config-next` version accordingly.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
### Current Behavior
- `next@~15.1.4` is installed
- `eslint-config-next@14.2.16` is installed (incorrect for Next.js 15)
### Expected Behavior
If Next.js 15 is detected -> eslint-config-next@15.1.4 is installed
If Next.js 14 is detected -> eslint-config-next@14.2.16 is installed
### GitHub Repo
https://github.com/tuffz/new-nx-with-preset-nextjs
### Steps to Reproduce
1. Run the following command from the official documentation:
`npx create-nx-workspace@latest --preset=next`
3. Open `package.json` and check the installed dependencies
- `next@~15.1.4` is installed
- `eslint-config-next@14.2.16` is installed
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#30257 (& #30258)
guides couldn't be merged into one page w/ tabs and keep consistent
headers. so we're back to splitting them out. but all under a
source-control-integration parent route. so we don't need to do any
redirects and such as the index route will contain the links to each one
Removed duplicate information about installing Nx globally.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Duplicate line.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Removed duplicate line.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
the implementation is brittle and will fail if `contextFileName` is not
a string
## Expected Behavior
we should just not handle other things that folks are putting in there.
but not fail
---------
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Dogfoods the Pnpm Catalogs feature in the Nx repo. This is the first
step to move all dependencies to Pnpm Catalogs definitions. More work
will be done incrementally later as we consolidate package versions
across the repository.
The initial list of dependencies moved to Pnpm Catalogs is:
- Angular packages
- React packages
- TypeScript packages
- Jest packages
- Rspack packages
- Some common utilities
## Current Behavior
We have tried to enable v8 serialization again... but it still seems
problematic. We don't want to revert again... so we evaluated some
options:
1. Disable by default
2. Disable for the single client method we think may be problematic
3. Fall back to JSON if v8 fails
4. Disable by default and still fall back if JSON fails
## Expected Behavior
We decided to update Nx such that the default behavior will be a
combination of #4, and #2. So by default we use JSON, if that
serialization fails we'll try v8... but there's an exception so the
method we know to be an issue will never try v8.
If you opt in to v8 by default, the combo changes to #3 + #2. So, by
default we'd use v8... if it fails try json... never try v8 for
processInBackground
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
Docker plugin assumed `commitSha` was always non-null; when `null`,
`shortCommitSha.slice` caused a runtime error during target
interpolation.
## Expected Behavior
Plugin should succeed even if latest commit SHA cannot be resolved,
simply omitting shortCommitSha-based substitutions.
## Changes
- Added null guard: `shortCommitSha` now set to `commitSha ?
commitSha.slice(0,7) : null`.
- Added test "should not throw when commitSha is null" verifying node /
target creation succeeds.
- No breaking changes; only broadens safe input surface.
## Additional notes
Logic only executes when `commitSha` was previously null (error case);
normal paths unchanged. If consumers interpolate `{shortCommitSha}`,
they should handle possible null (unchanged if interpolation is already
optional).
This PR removes the need to check links during deploy and instead
enforces it in CI. This removes the need to build astro-docs when
building next.js app.
Reduces Vercel build from 10-11 mins to 6.5 mins.
<img width="1231" height="94" alt="image"
src="https://github.com/user-attachments/assets/ad5d4459-f917-4609-8c00-151f61dc29d6"
/>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Update release notes entry tor 2025.07.3 - short link support for DTE
summary
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
You can see the issue here:
https://staging.nx.app/cipes/68fba96042d3126ee8ec0d19/analysis?runGroup=18785923031-1-linux
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes BAC-1387
This PR wraps one of the exports of `@nx/webpack` within a dynamic
function that ultimately requires `tsquery`. This causes an issue in
yarn v1 where `typescript` cannot be resolved thus causing an error when
`@nx/webpack` is imported.
The errors happens on every new workspace that starts from empty:
```
npx create-nx-workspace --preset=ts --pm=yarn
nx add @nx/web
nx g @nx/web:app apps/demo --bundler=webpack
```
Results in:
```
NX Cannot find module 'typescript'
Require stack:
- /private/var/folders/p4/6tvkdn_11xlc_2j999ybhbkr0000gn/T/tmp-59809-4kedkj5a1XsO/node_modules/@phenomnomnominal/tsquery/dist/src/ast.js
- /private/var/folders/p4/6tvkdn_11xlc_2j999ybhbkr0000gn/T/tmp-59809-4kedkj5a1XsO/node_modules/@phenomnomnominal/tsquery/dist/src/index.js
- /private/var/folders/p4/6tvkdn_11xlc_2j999ybhbkr0000gn/T/tmp-59809-4kedkj5a1XsO/node_modules/@nx/webpack/src/generators/convert-config-to-webpack-plugin/lib/extract-webpack-options.js
- /private/var/folders/p4/6tvkdn_11xlc_2j999ybhbkr0000gn/T/tmp-59809-4kedkj5a1XsO/node_modules/@nx/webpack/src/generators/convert-config-to-webpack-plugin/convert-config-to-webpack-plugin.js
- /private/var/folders/p4/6tvkdn_11xlc_2j999ybhbkr0000gn/T/tmp-59809-4kedkj5a1XsO/node_modules/@nx/webpack/index.js
- /private/tmp/web4/node_modules/@nx/devkit/src/utils/package-json.js
- /private/tmp/web4/node_modules/@nx/devkit/src/generators/to-js.js
- /private/tmp/web4/node_modules/@nx/devkit/public-api.js
- /private/tmp/web4/node_modules/@nx/devkit/index.js
- /private/tmp/web4/node_modules/@nx/web/src/generators/application/application.js
- /private/tmp/web4/node_modules/nx/src/config/schema-utils.js
- /private/tmp/web4/node_modules/nx/src/command-line/run/executor-utils.js
- /private/tmp/web4/node_modules/nx/src/project-graph/utils/project-configuration-utils.js
- /private/tmp/web4/node_modules/nx/src/utils/package-json.js
- /private/tmp/web4/node_modules/nx/bin/nx.js
Pass --verbose to see the stacktrace.
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
```
Note: Other generators like React/Vue are fine since they have
dependency on tsquery, which installs typescript.
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Summary
This PR includes three performance and correctness improvements:
1. **Split lockfile cache into separate node and dependency caches** -
Previously, both createNodes and createDependencies would read/write the
entire cache. Now each manages its own cache independently:
- `parsed-lock-file.nodes.json` for external nodes
- `parsed-lock-file.dependencies.json` for dependencies
2. **Prevent duplicate plugin resolution calls with promise cache** -
Added a promise cache to prevent concurrent duplicate calls to
`retrieveProjectConfigurationsWithoutPluginInference` when multiple
plugins fail to resolve simultaneously
3. **Normalize targets in separate loop after validation** - Moved
target normalization out of the validation loop to ensure proper
sequencing
## Test plan
- [ ] Tests pass (currently failing in CI - needs investigation)
- [ ] Build succeeds
- [ ] Lint passes
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude <noreply@anthropic.com>
When stringifying a pnpm v9 lockfile with workspace packages, Nx crashes
with: "Cannot destructure property 'specifiers' of 'projectSnapshot' as
it is undefined."
This occurs when:
- The lockfile has a root importer with `link:` references to workspace
packages
- But the lockfile is missing the workspace package importer entries
- The code tries to access `importers[importerPath]` which returns
undefined
- This undefined value gets added to the output lockfile
- During serialization, it crashes when trying to destructure undefined
Workspace packages with missing importers are now silently skipped
during lockfile serialization. This prevents the crash and allows Nx to
continue operating with out-of-sync lockfiles.
The fix adds a null check before adding workspace dependency importers
to the output lockfile.
Closes NXC-3244
This reverts commit 54db861b72.
## Current Behavior
Daemon messaging is all done over JSON messages
## Expected Behavior
Daemon messages use v8 serialization to avoid string length issues
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
With the Accept header in place during the retrieval of cache, the
client always expects an octet-stream from the server.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
When the `Accept` header is missing, you might not get the correct data
depending on the underlying implementation of a self hosted cache
solution. We use AWS API Gateway which has a hard requirement for
`Accept` to determine how it should convert the data.
Fixes#33092
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
We search for the gradle wrapper of a project by first looking at the
project root, then traversing upwards to the workspace root. If a
workspace has a separate gradle project defined that does not contain a
wrapper, then Nx will error.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
Add a field to the gradle plugin that will allow users to specify a
custom gradle installation within their workspace. Nx will check for a
gradle wrapper that the specified location when executing gradle tasks.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes NXC-3147
## Current Behavior
When the Nx daemon returns a cached project graph from memory (without
recomputing), it does not write the graph to disk. This creates a
cache/daemon mismatch scenario:
1. Daemon has valid project graph in memory
2. A non-daemon process (fallback when daemon fails) encounters errors
and writes cache to disk with those errors
3. Parent process gets clean graph from daemon
4. Forked executor processes read from disk cache which contains errors
5. The errors cause `readProjectGraphCache()` to return `null` (when no
`minimumComputedAt` is provided)
6. This triggers a misleading "No cached ProjectGraph is available"
error instead of surfacing the actual errors
This issue manifests intermittently in CI environments, especially when:
- Daemon connection timeouts occur
- Multiple concurrent processes are running (DTE scenarios)
- File system latency is high
## Expected Behavior
The daemon should always write its current project graph to disk
whenever it returns it, ensuring the disk cache stays synchronized with
the daemon's in-memory cache. This prevents stale or errored caches from
persisting when the daemon has a valid graph.
## Related Issue(s)
Fixes NXC-3030
## Implementation Details
Modified `getCachedSerializedProjectGraphPromise()` in
`packages/nx/src/daemon/server/project-graph-incremental-recomputation.ts`
to write the project graph cache to disk after retrieving the result,
even when reusing the in-memory cached graph.
The fix ensures that:
- Any errored cache written by a non-daemon process gets overwritten by
the daemon's valid graph
- Forked executor processes always read a consistent cache that matches
what the daemon served to the parent process
- Real errors are properly surfaced instead of being hidden by a generic
"no cache available" message
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Local `tsconfig.app.json` is never picked up due to wrong resolved path.
## Expected Behavior
Local `tsconfig.app.json` is picked up and the path aliases are added to
Vite.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes#33231
Removed "Explain with AI" feature documentation and redirected all URLs
to Self-Healing CI. Added sunset notice to blog posts, updated
configuration files, and preserved historical content for reference.
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
## Current Behavior
When `Dockerfile` is at project root, we attempt to append `--tag .`
which is invalid for docker.
## Expected Behavior
Ensure that if `Dockerfile` is at project root, we use `workspaceRoot`
to determine the `--tag`.
Note, this tag is primarily used as a deterministic method for Nx to
find the correct docker image when calling `docker run` and `nx release`
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
When using `--output-style=stream-without-prefixes` nx incorrectly shows
the TUI instead of streaming
## Expected Behavior
When using `--output-style=stream-without-prefixes`, nx should stream
with no prefixes just like it does with `--output-style=stream`
## Related Issue(s)
Fixes#32535
Co-authored-by: Hugo Burton <hugo.burton@westpac.com.au>
## Current Behavior
`node_modules` are being copied during copy-local-native
## Expected Behavior
`node_modules` are not being copied during `copy-local-native`
## Current Behavior
Maven is installed as a global dependency for all e2e targets
(`e2e-local`, `e2e-ci--**/**`, and `e2e-macos-ci--**/*`), even when only
the Maven e2e tests need it.
## Expected Behavior
Maven should only be installed as a dependency for the Maven e2e tests
that actually use it, avoiding unnecessary installations for other e2e
test projects.
## Changes Made
- Removed `nx-maven-plugin:install` from the global e2e target defaults
in `nx.json`
- Added `nx-maven-plugin:install` as a specific dependency to the Maven
e2e project targets in `e2e/maven/project.json`
This optimization ensures Maven is only installed when needed, reducing
unnecessary build overhead for other e2e tests.
## Current Behavior
`nx init` does not search for `Dockerfile` patterns to suggest adding
the `@nx/docker` plugin.
## Expected Behavior
`nx init` finds and suggests `@nx/docker` plugin
Fixes NXC-3319
Fixes the order of the arguments in invocations to
`resolveCatalogReference` when resolving catalog references from the
filesystem (not using a `Tree`).
## Current Behavior
In some scenarios, when some processes terminate unexpectedly (e.g.
crashed due to OOM), the task runner will incorrectly determine their
exit code to be 0. This results in Nx storing the task results as a
success, which can cause cache hits with false positive successes.
## Expected Behavior
When processes terminate unexpectedly (e.g. crashed due to OOM), the
task runner should correctly determine their exit code from the signal,
and it should never be 0. The stored task result should not be marked as
successful.
## Related Issue(s)
Fixes#29204
## Current Behavior
When `@nx/docker` is registered via string only (`nxJson.plugins:
["@nx/docker"]`, project graph creation fails because we try to access
`options.buildTarget`.
## Expected Behavior
Handle undefined `options` gracefully, and still create the default
target.
## Related Issue(s)
Fixes NXC-3320
## Current Behavior
Dependencies are outdated and Rust tooling needs to be updated.
## Expected Behavior
Rust dependencies are updated to their latest compatible versions.
## Changes
- Updated Rust dependencies
- Rebased with latest `origin/master`
- Updated pnpm lock file
## Related Issue(s)
None
## Current Behavior
No docs describing migration path
## Expected Behavior
Docs describing migration path
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Caleb Ukle <caleb@nrwl.io>
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
.NET sometimes bails on a failed mutex in e2e
## Expected Behavior
it runs only 1 at a time
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
It was removed when the scripts were cleaned up during next.js->astro
migration. Adding this back since blog posts need to be synced first
before serving.
## Current Behavior
When project configuration errors occur due to invalid token usage
(e.g., `{workspaceRoot}` in the middle of a path), error messages don't
provide sufficient context about where the error occurred.
## Expected Behavior
Error messages should include:
- For project-level errors: the project and target context (e.g.,
"libs/my-app:build")
- For nx.json targetDefaults errors: the nx.json context (e.g.,
"nx.json[targetDefaults]:test")
This makes it much easier for users to locate and fix the configuration
issue.
## Changes
This PR adds comprehensive integration tests to verify the improved
error messaging:
- Test for project-level invalid token usage showing project:target
context
- Test for nx.json targetDefaults invalid token usage showing nx.json
context
Tests use mock plugins to simulate realistic scenarios where invalid
`{workspaceRoot}` token usage would occur, ensuring the error messages
contain the expected context information.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Jason Jean <jasonjean1993@gmail.com>
by default code blocks will get text as the lang if not set or the lang
is not supported
but we should be so I don't have to look at the warnings in the terminal
output 😅
also remove the frame=none since the team preferred to have the terminal
frame
Example of invalid codeblock messages

Also added conformance rule for validating image pages for public and
src/assets/ directory
examples of incorrect absolute path ref from "public" folder and
incorrect absolute path:

fixes DOC-242
fixes DOC-259
## Current Behavior
Currently, when configuring the `@nx/docker` plugin, we only set the
target name and a basic command.
The intention was that targetDefaults might be able to be used to
configure additional args, but this falls short in some places.
## Expected Behavior
Allow setting additional args when configuring the `@nx/docker` plugin
that supports interpolated values, similar to `versionSchemes`.
This will allow additional flexibility when setting up the docker build
command such as:
```json
{
"plugin": "@nx/docker",
"options": {
"buildTarget": {
"name": "docker:build",
"args": ["-t {projectName}"]
}
}
}
```
This means that we can use `nx run-many -t docker:build` and it will
successfully add the name of the projects into the tag.
This is one example, other examples include being able to set individual
Docker Layer Caching where each registry needs a unique name.
## Current Behavior
The Maven plugin currently checks if a path is absolute by using
`outputFile.startsWith("/")`. This only works on Unix-like systems and
fails on Windows where absolute paths start with a drive letter (e.g.,
`C:\`).
## Expected Behavior
The Maven plugin should correctly identify absolute paths on all
platforms (Windows, macOS, Linux) using the platform-agnostic
`File.isAbsolute()` method.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
N/A - This is a proactive bug fix for cross-platform compatibility.
---
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
## Current Behavior
When Nx Cloud is used, but the Nx Cloud client is unavailable, an error
is thrown and commands are not run.
## Expected Behavior
When Nx Cloud is used, but the client is unavailable, continue execution
without Nx Cloud.
## Related Issue(s)
Fixes NXC-3175
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
Tests either cause agents to run out of memory:
<img width="956" height="358" alt="image"
src="https://github.com/user-attachments/assets/e55bae05-7757-46e7-88ed-158f72411195"
/>
<img width="1278" height="336" alt="image"
src="https://github.com/user-attachments/assets/40dc8dd6-4409-461e-b75a-5c1c36551da5"
/>
Or setup tasks fail due to network flakiness:
https://staging.nx.app/runs/J1qWVZA7K5
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
A fully affected, cache busted task graph should run without any
failures.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
This pull request updates the documentation for configuring .NET target
types in the `nx.json` file to provide clearer instructions and
examples. The changes make it easier to understand how to customize
target names and configurations for the `@nx/dotnet` plugin.
Improvements to configuration documentation:
* Added a section describing how each target type can be configured,
including renaming targets, customizing options, disabling targets, and
specifying additional properties.
* Updated the example configuration to show how to rename targets (e.g.,
"build" to "compile"), add configurations (e.g., production
optimization), set dependencies between targets, and disable targets
(e.g., disabling "pack").
* Clarified that targets are created with the configuration specified in
the `nx.json` `plugins` array, rather than just with custom names.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
The first-class programmatic API of nx release is only documented within
the manage releases introduction and is incomplete (`ReleaseClient` is
not covered at all).
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
The programmatic API has its own in depth guide, which is then
cross-referenced from the manage releases guide. `ReleaseClient` is now
documented including its new Nx 22 features.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
## Current Behavior
`run`/`watch` are not mentioned in docs
## Expected Behavior
`run`/`watch` docs are accurate
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
## Current Behavior
Maven plugin targets are only created for goals explicitly bound to
executions in the POM. Goals defined in a plugin but not bound to any
execution are not available as Nx targets.
## Expected Behavior
All available Maven goals should be accessible as Nx targets, including:
- Goals bound to executions (existing behavior)
- Unbound goals defined in the plugin (new behavior)
## Changes Made
1. **Added unbound goal support**: The `NxTargetFactory` now creates
targets for goals defined in a plugin but not bound to any execution.
These targets are created with the format `goalPrefix:goalName` without
an execution ID.
2. **Added continuous build tracking**:
- Added `continuous` property to `NxTarget` data class to track whether
a goal supports continuous builds
- Updated `MojoAnalyzer` to detect continuous goals from the cache
configuration
- All targets now properly propagate continuous mode information
3. **Code improvements**:
- Improved formatting and indentation for consistency
- Made `execution` parameter optional in `createSimpleGoalTarget` to
support both bound and unbound goals
- Updated command generation to work with or without execution IDs
## Related Issue(s)
This change enables better Maven goal discovery and execution in Nx
monorepos.
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
<!-- This is the behavior we have today -->
When an invalid output exists we report:
```
NX The following outputs are invalid:
- foo.txt
Run `nx repair` to fix this.
```
Without specifying the reason, we tell to run `nx repair`.
## Expected Behavior
<!-- This is the behavior we should expect with the changes in this PR
-->
More feedback provided to the user as to the error with their output:
```
NX The following outputs are invalid:
- foo.txt
** Reason: Outputs must start with either "{workspaceRoot}/" or "{projectRoot}/".
Run `nx repair` to fix this.
```
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
This PR fixes some pages that don't use the proper markdoc syntax for
line lighting in code blocks. The `{% meta %}` tag is needed and it is
missing in some places.
Closes DOC-2790
## Current Behavior
When the daemon is disabled due to an error, the reason isn't captured,
making it harder to debug why the daemon was disabled.
## Expected Behavior
The error message/reason is now stored when marking the daemon as
disabled, allowing better visibility into what caused the daemon to be
disabled.
## Related Issue(s)
Node tool executions (non-watch) were exiting before completing. This
change ensures they complete before exit.
closes#32385
<!-- Please make sure you have read the submission guidelines before
posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
Node tool executions are not completing since #32356
## Expected Behavior
Node tool executions complete before exit
## Related Issue(s)
#32385Fixes#32385
## Current Behavior
When errors happen in earlier stages of compilation process, such as
processing global styles, these errors are not printed and the rspack
build process hangs at the Sealing phase.
## Expected Behavior
Ensure that errors that have occurred that would cause the process to
hang are printed and process exits correctly.
Part of this happens because the usual printing of errors happens in the
`afterDone` hook, which is never reached when the above occurs.
## Related Issue(s)
Fixes NXC-3268
## Current Behavior
Readme template files are being published to npm with inconsistent
naming conventions.
## Expected Behavior
Readme template files should be excluded from npm publication and
consistently named as `readme-template.md`.
## Changes
- Renamed all readme template files to `readme-template.md` across
angular-rspack-compiler, angular-rspack, dotnet, and maven packages
- Updated .npmignore files to exclude readme-template.md from npm
publication
- Updated package.json build commands to reference the new
readme-template.md paths
- Removed `!README.md__tpl__` exceptions from package.json files array
entries
add new page for the createNodes api compat
add callouts to extending project graph and tooling plugin page
fixes DOC-255
---------
Co-authored-by: graphite-app[bot] <96075541+graphite-app[bot]@users.noreply.github.com>
Fixes the pnpm caching setup for the `main-macos` job. It can currently
fail when the pnpm cache directory doesn't exist. We need to handle the
pnpm cache conditionally and separately from the node setup.
…as testing projects<!-- Please make sure you have read the submission
guidelines before posting an PR -->
<!--
https://github.com/nrwl/nx/blob/master/CONTRIBUTING.md#-submitting-a-pr
-->
<!-- Please make sure that your commit message follows our format -->
<!-- Example: `fix(nx): must begin with lowercase` -->
<!-- If this is a particularly complex change or feature addition, you
can request a dedicated Nx release for this pull request branch. Mention
someone from the Nx team or the `@nrwl/nx-pipelines-reviewers` and they
will confirm if the PR warrants its own release for testing purposes,
and generate it for you if appropriate. -->
## Current Behavior
- Microsoft.Testing.Platform projects are not detected as having a test
target
- `serve` does not have an equivalent
## Expected Behavior
- Test projects are properly detected
- `serve` has been split into 2 targets:
- `watch`
- `run`
The split of `serve` mirrors the`dotnet` cli in the same way that we
mirrored `vite` when adding `preview` and `dev` targets when we moved
with project crystal. `watch` can be used for a variety of cases, but
provides hot reload + run a 'la `dev` / `serve`. `run` is more of a fire
and forget target that starts up the app. Both targets would only really
be used in local dev.
## Related Issue(s)
<!-- Please link the issue being fixed so it gets closed when this is
merged. -->
Fixes #
…as testing projects
---------
Co-authored-by: nx-cloud[bot] <71083854+nx-cloud[bot]@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
2025-10-21 16:31:55 -04:00
3609 changed files with 161723 additions and 89814 deletions
description: Run Nx generators with prioritization for workspace-plugin generators. Use this when generating code, scaffolding new features, or automating repetitive tasks in the monorepo.
description: Polls Nx Cloud CI pipeline and self-healing status. Returns structured state when actionable. Spawned by /nx-cloud-ci-monitor command to monitor CI Attempt status.
model: fast
---
# CI Watcher Subagent
You are a CI monitoring subagent responsible for polling Nx Cloud CI Attempt status and self-healing state. You report status back to the main agent - you do NOT make apply/reject decisions.
## Your Responsibilities
1. Poll CI status using the `ci_information` MCP tool
2. Implement exponential backoff between polls
3. Return structured state when an actionable condition is reached
4. Track iteration count and elapsed time
5. Output status updates based on verbosity level
## Input Parameters (from Main Agent)
The main agent may provide these optional parameters in the prompt:
# Large content fields - fetch only when returning to main agent
```
## Initial Wait
Before first poll, wait based on context:
- **Fresh start (no expected CIPE):** Wait 60 seconds to allow CI to start
- **Expecting new CIPE:** Wait 30 seconds (action already triggered)
**IMPORTANT:** Always run sleep in foreground, NOT as background command.
```bash
sleep 60# or 30 if expecting new CIPE (FOREGROUND, not background)
```
## Two-Phase Operation
The subagent operates in one of two modes depending on input:
### Mode 1: Fresh Start (no `expectedCommitSha` or `previousCipeUrl`)
Normal polling - process whatever CIPE is returned by `ci_information`.
### Mode 2: Wait-for-New-CIPE (when `expectedCommitSha` or `previousCipeUrl` provided)
**CRITICAL**: When expecting a new CIPE, the subagent must **completely ignore** the old/stale CIPE. Do NOT process its status, do NOT return actionable states based on it.
#### Phase A: Wait Mode
1. Start a **new-CIPE timeout** timer (default: 30 minutes)
2. On each poll of `ci_information`:
- Check if CIPE is NEW:
-`cipeUrl` differs from `previousCipeUrl` → **new CIPE detected**
[CI Monitor] Still seeing previous CI Attempt (ignoring): <oldCipeUrl>
[CI Monitor] Polling... (elapsed: 1m 30s)
[CI Monitor] Still seeing previous CI Attempt (ignoring): <oldCipeUrl>
[CI Monitor] Polling... (elapsed: 2m 30s)
[CI Monitor] ✓ New CI Attempt detected! URL: <newCipeUrl>, SHA: <newCommitSha>
[CI Monitor] Switching to normal polling mode...
```
### Why This Matters (Context Preservation)
**The problem**: Stale CIPE data can be very large:
-`taskOutputSummary`: potentially thousands of characters of build/test output
-`suggestedFix`: entire patch files
-`suggestedFixReasoning`: detailed explanation
If subagent returns stale CIPE data to main agent, it **pollutes main agent's context** with useless information (we already processed that CIPE). This wastes valuable context window.
**Without wait mode:**
1. Poll `ci_information` → get old CIPE with huge data
2. Return to main agent with all that stale data
3. Main agent's context gets polluted with useless info
4. Main agent has to process/ignore it anyway
**With wait mode:**
1. Poll `ci_information` → get old CIPE → **ignore it, don't return**
2. Keep waiting internally (stale data stays in subagent)
3. New CIPE appears → switch to normal mode
4. Return to main agent with only the NEW, relevant CIPE data
## Polling Loop
### Subagent State Management
Maintain internal accumulated state across polls:
```
accumulated_state = {}
```
### Call `ci_information` MCP Tool
**Wait Mode (expecting new CI Attempt):**
```
ci_information({
branch: "<branch_name>",
select: "cipeUrl,commitSha,cipeStatus"
})
```
Only fetch minimal fields needed to detect CI Attempt change. Do NOT fetch heavy fields - stale data wastes context.
Merge response into `accumulated_state`, then return merged state to main agent.
**Pagination:** Heavy string fields return first page only. If `hasMore` indicated, include in return format so main agent knows more content available.
### Return to Main Agent When
Return immediately with structured state if ANY of these conditions are true:
| `fix_auto_applying` | `selfHealingStatus == 'COMPLETED'` AND `couldAutoApplyTasks == true` AND `verificationStatus == 'COMPLETED'` |
| `fix_available` | `selfHealingStatus == 'COMPLETED'` AND `suggestedFix != null` AND (`couldAutoApplyTasks != true` OR `verificationStatus` in (`FAILED`, `NOT_EXECUTABLE`)) |
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Monitor Nx Cloud CI pipeline and handle self-healing fixes automatically. Checks for Nx Cloud connection before starting.
---
# CI Monitor Command
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
Parse any overrides from `$ARGUMENTS` and merge with defaults.
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Generate code using nx generators. USE WHEN scaffolding code or transforming existing code - for example creating libraries or applications, or anything else that is boilerplate code or automates repetitive tasks. ALWAYS use this first when generating code with Nx instead of calling MCP tools or running nx generate immediately.
---
# Run Nx Generator
Nx generators are powerful tools that scaffold projects, make automated code migrations or automate repetitive tasks in a monorepo. They ensure consistency across the codebase and reduce boilerplate work.
This skill applies when the user wants to:
- Create new projects like libraries or applications
- Scaffold features or boilerplate code
- Run workspace-specific or custom generators
- Do anything else that an nx generator exists for
## Generator Discovery Flow
### Step 1: List Available Generators
Use the Nx CLI to discover available generators:
- List all generators for a plugin: `npx nx list @nx/react`
- Local workspace generators (defined in the repo's own plugins)
### Step 2: Match Generator to User Request
Based on the user's request, identify which generator(s) could fulfill their needs. Consider:
- What artifact type they want to create (library, application, etc.)
- Which framework or technology stack is relevant
- Whether they mentioned specific generator names
**IMPORTANT**: When both a local workspace generator and an external plugin generator could satisfy the request, **always prefer the local workspace generator**. Local generators are customized for the specific repo's patterns and conventions.
It's possible that the user request is something that no Nx generator exists for whatsoever. In this case, you can stop using this skill and try to help the user another way. HOWEVER, the burden of proof for this is high. Before aborting, carefully consider each and every generator that's available. Look into details for any that could be related in any way before making this decision.
## Pre-Execution Checklist
Before running any generator, complete these steps:
### 1. Fetch Generator Schema
Use the `--help` flag to understand all available options:
```bash
npx nx g @nx/react:library --help
```
Pay attention to:
- Required options that must be provided
- Optional options that may be relevant to the user's request
- Default values that might need to be overridden
### 2. Read Generator Source Code
Understanding what the generator actually does helps you:
- Know what files will be created/modified
- Understand any side effects (updating configs, installing deps, etc.)
- Identify options that might not be obvious from the schema
To find generator source code:
- For plugin generators: Use `node -e "console.log(require.resolve('@nx/<plugin>/generators.json'));"` to find the generators.json, then locate the source from there
- If that fails, read directly from `node_modules/<plugin>/generators.json`
- For local generators: They are typically in `tools/generators/` or a local plugin directory. You can search the repo for the generator name to find it.
### 2.5 Reevaluate if the generator is right
Once you have built up an understanding of what the selected generator does, reconsider: Is this the right generator to service the user request?
If not, it's okay to go back to the Generator Discovery Flow and select a different generator before proceeding. If you do, make sure to go through the entire pre-execution checklist once more.
### 3. Understand Repo Context
Before generating, examine the target area of the codebase:
- Look at similar existing artifacts (other libraries, applications, etc.)
- Identify patterns and conventions used in the repo
- Note naming conventions, file structures, and configuration patterns
- Try to match these patterns when configuring the generator
For example, if similar libraries are using a specific test runner, build tool or linter, try to match that if possible.
If projects or other artifacts are organized with a specific naming convention, try to match it.
### 4. Validate Required Options
Ensure all required options have values:
- Map the user's request to generator options
- Infer values from context where possible
- Ask the user for any critical missing information
## Execution
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally.
Many generators will behave differently based on where they are executed. For example, first-party nx library generators use the cwd to determine the directory that the library should be placed in. This is highly important.
### Consider Dry-Run (Optional)
Running with `--dry-run` first is strongly encouraged but not mandatory. Use your judgment:
- For complex generators or unfamiliar territory: do a dry-run first
- For simple, well-understood generators: may proceed directly
- Dry-run shows file names and created/deleted/modified markers, but not content
- There are cases where a generator does not support dry-run (for example if it had to install an npm package) - in that case --dry-run might fail. Don't be discouraged but simply move on to running the generator for real and iterating from there.
description: Find and add Nx plugins. USE WHEN user wants to discover available plugins, install a new plugin, or add support for a specific framework or technology to the workspace.
description: Helps with running tasks in an Nx workspace. USE WHEN the user wants to execute build, test, lint, serve, or run any other tasks defined in the workspace.
---
You can run tasks with Nx in the following way.
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally. Look at the package.json or lockfile to determine which package manager is in use.
For more details on any command, run it with `--help` (e.g. `nx run-many --help`, `nx affected --help`).
## Understand which tasks can be run
You can check those via `nx show project <projectname> --json`, for example `nx show project myapp --json`. It contains a `targets` section which has information about targets that can be run. You can also just look at the `package.json` scripts or `project.json` targets, but you might miss out on inferred tasks by Nx plugins.
## Run a single task
```
nx run <project>:<task>
```
where `project` is the project name defined in `package.json` or `project.json` (if present).
## Run multiple tasks
```
nx run-many -t build test lint typecheck
```
You can pass a `-p` flag to filter to specific projects, otherwise it runs on all projects. You can also use `--exclude` to exclude projects, and `--parallel` to control the number of parallel processes (default is 3).
Examples:
-`nx run-many -t test -p proj1 proj2` — test specific projects
-`nx run-many -t test --projects=*-app --exclude=excluded-app` — test projects matching a pattern
-`nx run-many -t test --projects=tag:api-*` — test projects by tag
## Run tasks for affected projects
Use `nx affected` to only run tasks on projects that have been changed and projects that depend on changed projects. This is especially useful in CI and for large workspaces.
```
nx affected -t build test lint
```
By default it compares against the base branch. You can customize this:
-`nx affected -t test --base=main --head=HEAD` — compare against a specific base and head
-`nx affected -t test --files=libs/mylib/src/index.ts` — specify changed files directly
## Useful flags
These flags work with `run`, `run-many`, and `affected`:
-`--skipNxCache` — rerun tasks even when results are cached
-`--verbose` — print additional information such as stack traces
-`--nxBail` — stop execution after the first failed task
-`--configuration=<name>` — use a specific configuration (e.g. `production`)
description: "Explore and understand Nx workspaces. USE WHEN answering any questions about the nx workspace, the projects in it or tasks to run. EXAMPLES: 'What projects are in this workspace?', 'How is project X configured?', 'What targets can I run?', 'What's affected by my changes?', 'Which projects depend on library Y?', or any questions about Nx workspace structure, project configuration, or available tasks."
---
# Nx Workspace Exploration
This skill provides read-only exploration of Nx workspaces. Use it to understand workspace structure, project configuration, available targets, and dependencies.
Keep in mind that you might have to prefix commands with `npx`/`pnpx`/`yarn` if nx isn't installed globally. Check the lockfile to determine the package manager in use.
## Listing Projects
Use `nx show projects` to list projects in the workspace.
```bash
# List all projects
nx show projects
# Filter by pattern (glob)
nx show projects --projects "apps/*"
nx show projects --projects "shared-*"
# Filter by project type
nx show projects --type app
nx show projects --type lib
nx show projects --type e2e
# Filter by target (projects that have a specific target)
nx show projects --withTarget build
nx show projects --withTarget e2e
# Find affected projects (changed since base branch)
nx show projects --affected
nx show projects --affected --base=main
nx show projects --affected --type app
# Combine filters
nx show projects --type lib --withTarget test
nx show projects --affected --exclude="*-e2e"
# Output as JSON
nx show projects --json
```
## Project Configuration
Use `nx show project <name> --json` to get the full resolved configuration for a project.
**Important**: Do NOT read `project.json` directly - it only contains partial configuration. The `nx show project` command returns the full resolved config including inferred targets from plugins.
You can read the full project schema at `node_modules/nx/schemas/project-schema.json` to understand nx project configuration options.
```bash
# Get full project configuration
nx show project my-app --json
# Extract specific parts from the JSON
nx show project my-app --json | jq '.targets'
nx show project my-app --json | jq '.targets.build'
nx show project my-app --json | jq '.targets | keys'
description="Monitor Nx Cloud CI pipeline and handle self-healing fixes automatically. Checks for Nx Cloud connection before starting."
prompt="""
# CI Monitor Command
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `ci_success` | Exit with success. Log "CIpassedsuccessfully!" |
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix:resolve<failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix:resolve<failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Monitor Nx Cloud CI pipeline and handle self-healing fixes automatically. Checks for Nx Cloud connection before starting.
---
# CI Monitor Command
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
Parse any overrides from `$ARGUMENTS` and merge with defaults.
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Generate code using nx generators. USE WHEN scaffolding code or transforming existing code - for example creating libraries or applications, or anything else that is boilerplate code or automates repetitive tasks. ALWAYS use this first when generating code with Nx instead of calling MCP tools or running nx generate immediately.
---
# Run Nx Generator
Nx generators are powerful tools that scaffold projects, make automated code migrations or automate repetitive tasks in a monorepo. They ensure consistency across the codebase and reduce boilerplate work.
This skill applies when the user wants to:
- Create new projects like libraries or applications
- Scaffold features or boilerplate code
- Run workspace-specific or custom generators
- Do anything else that an nx generator exists for
## Generator Discovery Flow
### Step 1: List Available Generators
Use the Nx CLI to discover available generators:
- List all generators for a plugin: `npx nx list @nx/react`
- Local workspace generators (defined in the repo's own plugins)
### Step 2: Match Generator to User Request
Based on the user's request, identify which generator(s) could fulfill their needs. Consider:
- What artifact type they want to create (library, application, etc.)
- Which framework or technology stack is relevant
- Whether they mentioned specific generator names
**IMPORTANT**: When both a local workspace generator and an external plugin generator could satisfy the request, **always prefer the local workspace generator**. Local generators are customized for the specific repo's patterns and conventions.
It's possible that the user request is something that no Nx generator exists for whatsoever. In this case, you can stop using this skill and try to help the user another way. HOWEVER, the burden of proof for this is high. Before aborting, carefully consider each and every generator that's available. Look into details for any that could be related in any way before making this decision.
## Pre-Execution Checklist
Before running any generator, complete these steps:
### 1. Fetch Generator Schema
Use the `--help` flag to understand all available options:
```bash
npx nx g @nx/react:library --help
```
Pay attention to:
- Required options that must be provided
- Optional options that may be relevant to the user's request
- Default values that might need to be overridden
### 2. Read Generator Source Code
Understanding what the generator actually does helps you:
- Know what files will be created/modified
- Understand any side effects (updating configs, installing deps, etc.)
- Identify options that might not be obvious from the schema
To find generator source code:
- For plugin generators: Use `node -e "console.log(require.resolve('@nx/<plugin>/generators.json'));"` to find the generators.json, then locate the source from there
- If that fails, read directly from `node_modules/<plugin>/generators.json`
- For local generators: They are typically in `tools/generators/` or a local plugin directory. You can search the repo for the generator name to find it.
### 2.5 Reevaluate if the generator is right
Once you have built up an understanding of what the selected generator does, reconsider: Is this the right generator to service the user request?
If not, it's okay to go back to the Generator Discovery Flow and select a different generator before proceeding. If you do, make sure to go through the entire pre-execution checklist once more.
### 3. Understand Repo Context
Before generating, examine the target area of the codebase:
- Look at similar existing artifacts (other libraries, applications, etc.)
- Identify patterns and conventions used in the repo
- Note naming conventions, file structures, and configuration patterns
- Try to match these patterns when configuring the generator
For example, if similar libraries are using a specific test runner, build tool or linter, try to match that if possible.
If projects or other artifacts are organized with a specific naming convention, try to match it.
### 4. Validate Required Options
Ensure all required options have values:
- Map the user's request to generator options
- Infer values from context where possible
- Ask the user for any critical missing information
## Execution
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally.
Many generators will behave differently based on where they are executed. For example, first-party nx library generators use the cwd to determine the directory that the library should be placed in. This is highly important.
### Consider Dry-Run (Optional)
Running with `--dry-run` first is strongly encouraged but not mandatory. Use your judgment:
- For complex generators or unfamiliar territory: do a dry-run first
- For simple, well-understood generators: may proceed directly
- Dry-run shows file names and created/deleted/modified markers, but not content
- There are cases where a generator does not support dry-run (for example if it had to install an npm package) - in that case --dry-run might fail. Don't be discouraged but simply move on to running the generator for real and iterating from there.
description: Find and add Nx plugins. USE WHEN user wants to discover available plugins, install a new plugin, or add support for a specific framework or technology to the workspace.
description: Helps with running tasks in an Nx workspace. USE WHEN the user wants to execute build, test, lint, serve, or run any other tasks defined in the workspace.
---
You can run tasks with Nx in the following way.
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally. Look at the package.json or lockfile to determine which package manager is in use.
For more details on any command, run it with `--help` (e.g. `nx run-many --help`, `nx affected --help`).
## Understand which tasks can be run
You can check those via `nx show project <projectname> --json`, for example `nx show project myapp --json`. It contains a `targets` section which has information about targets that can be run. You can also just look at the `package.json` scripts or `project.json` targets, but you might miss out on inferred tasks by Nx plugins.
## Run a single task
```
nx run <project>:<task>
```
where `project` is the project name defined in `package.json` or `project.json` (if present).
## Run multiple tasks
```
nx run-many -t build test lint typecheck
```
You can pass a `-p` flag to filter to specific projects, otherwise it runs on all projects. You can also use `--exclude` to exclude projects, and `--parallel` to control the number of parallel processes (default is 3).
Examples:
-`nx run-many -t test -p proj1 proj2` — test specific projects
-`nx run-many -t test --projects=*-app --exclude=excluded-app` — test projects matching a pattern
-`nx run-many -t test --projects=tag:api-*` — test projects by tag
## Run tasks for affected projects
Use `nx affected` to only run tasks on projects that have been changed and projects that depend on changed projects. This is especially useful in CI and for large workspaces.
```
nx affected -t build test lint
```
By default it compares against the base branch. You can customize this:
-`nx affected -t test --base=main --head=HEAD` — compare against a specific base and head
-`nx affected -t test --files=libs/mylib/src/index.ts` — specify changed files directly
## Useful flags
These flags work with `run`, `run-many`, and `affected`:
-`--skipNxCache` — rerun tasks even when results are cached
-`--verbose` — print additional information such as stack traces
-`--nxBail` — stop execution after the first failed task
-`--configuration=<name>` — use a specific configuration (e.g. `production`)
description: "Explore and understand Nx workspaces. USE WHEN answering any questions about the nx workspace, the projects in it or tasks to run. EXAMPLES: 'What projects are in this workspace?', 'How is project X configured?', 'What targets can I run?', 'What's affected by my changes?', 'Which projects depend on library Y?', or any questions about Nx workspace structure, project configuration, or available tasks."
---
# Nx Workspace Exploration
This skill provides read-only exploration of Nx workspaces. Use it to understand workspace structure, project configuration, available targets, and dependencies.
Keep in mind that you might have to prefix commands with `npx`/`pnpx`/`yarn` if nx isn't installed globally. Check the lockfile to determine the package manager in use.
## Listing Projects
Use `nx show projects` to list projects in the workspace.
```bash
# List all projects
nx show projects
# Filter by pattern (glob)
nx show projects --projects "apps/*"
nx show projects --projects "shared-*"
# Filter by project type
nx show projects --type app
nx show projects --type lib
nx show projects --type e2e
# Filter by target (projects that have a specific target)
nx show projects --withTarget build
nx show projects --withTarget e2e
# Find affected projects (changed since base branch)
nx show projects --affected
nx show projects --affected --base=main
nx show projects --affected --type app
# Combine filters
nx show projects --type lib --withTarget test
nx show projects --affected --exclude="*-e2e"
# Output as JSON
nx show projects --json
```
## Project Configuration
Use `nx show project <name> --json` to get the full resolved configuration for a project.
**Important**: Do NOT read `project.json` directly - it only contains partial configuration. The `nx show project` command returns the full resolved config including inferred targets from plugins.
You can read the full project schema at `node_modules/nx/schemas/project-schema.json` to understand nx project configuration options.
```bash
# Get full project configuration
nx show project my-app --json
# Extract specific parts from the JSON
nx show project my-app --json | jq '.targets'
nx show project my-app --json | jq '.targets.build'
nx show project my-app --json | jq '.targets | keys'
description: Polls Nx Cloud CI pipeline and self-healing status. Returns structured state when actionable. Spawned by /nx-cloud-ci-monitor command to monitor CI Attempt status.
---
# CI Watcher Subagent
You are a CI monitoring subagent responsible for polling Nx Cloud CI Attempt status and self-healing state. You report status back to the main agent - you do NOT make apply/reject decisions.
## Your Responsibilities
1. Poll CI status using the `ci_information` MCP tool
2. Implement exponential backoff between polls
3. Return structured state when an actionable condition is reached
4. Track iteration count and elapsed time
5. Output status updates based on verbosity level
## Input Parameters (from Main Agent)
The main agent may provide these optional parameters in the prompt:
# Large content fields - fetch only when returning to main agent
```
## Initial Wait
Before first poll, wait based on context:
- **Fresh start (no expected CIPE):** Wait 60 seconds to allow CI to start
- **Expecting new CIPE:** Wait 30 seconds (action already triggered)
**IMPORTANT:** Always run sleep in foreground, NOT as background command.
```bash
sleep 60# or 30 if expecting new CIPE (FOREGROUND, not background)
```
## Two-Phase Operation
The subagent operates in one of two modes depending on input:
### Mode 1: Fresh Start (no `expectedCommitSha` or `previousCipeUrl`)
Normal polling - process whatever CIPE is returned by `ci_information`.
### Mode 2: Wait-for-New-CIPE (when `expectedCommitSha` or `previousCipeUrl` provided)
**CRITICAL**: When expecting a new CIPE, the subagent must **completely ignore** the old/stale CIPE. Do NOT process its status, do NOT return actionable states based on it.
#### Phase A: Wait Mode
1. Start a **new-CIPE timeout** timer (default: 30 minutes)
2. On each poll of `ci_information`:
- Check if CIPE is NEW:
-`cipeUrl` differs from `previousCipeUrl` → **new CIPE detected**
[CI Monitor] Still seeing previous CI Attempt (ignoring): <oldCipeUrl>
[CI Monitor] Polling... (elapsed: 1m 30s)
[CI Monitor] Still seeing previous CI Attempt (ignoring): <oldCipeUrl>
[CI Monitor] Polling... (elapsed: 2m 30s)
[CI Monitor] ✓ New CI Attempt detected! URL: <newCipeUrl>, SHA: <newCommitSha>
[CI Monitor] Switching to normal polling mode...
```
### Why This Matters (Context Preservation)
**The problem**: Stale CIPE data can be very large:
-`taskOutputSummary`: potentially thousands of characters of build/test output
-`suggestedFix`: entire patch files
-`suggestedFixReasoning`: detailed explanation
If subagent returns stale CIPE data to main agent, it **pollutes main agent's context** with useless information (we already processed that CIPE). This wastes valuable context window.
**Without wait mode:**
1. Poll `ci_information` → get old CIPE with huge data
2. Return to main agent with all that stale data
3. Main agent's context gets polluted with useless info
4. Main agent has to process/ignore it anyway
**With wait mode:**
1. Poll `ci_information` → get old CIPE → **ignore it, don't return**
2. Keep waiting internally (stale data stays in subagent)
3. New CIPE appears → switch to normal mode
4. Return to main agent with only the NEW, relevant CIPE data
## Polling Loop
### Subagent State Management
Maintain internal accumulated state across polls:
```
accumulated_state = {}
```
### Call `ci_information` MCP Tool
**Wait Mode (expecting new CI Attempt):**
```
ci_information({
branch: "<branch_name>",
select: "cipeUrl,commitSha,cipeStatus"
})
```
Only fetch minimal fields needed to detect CI Attempt change. Do NOT fetch heavy fields - stale data wastes context.
Merge response into `accumulated_state`, then return merged state to main agent.
**Pagination:** Heavy string fields return first page only. If `hasMore` indicated, include in return format so main agent knows more content available.
### Return to Main Agent When
Return immediately with structured state if ANY of these conditions are true:
| `fix_auto_applying` | `selfHealingStatus == 'COMPLETED'` AND `couldAutoApplyTasks == true` AND `verificationStatus == 'COMPLETED'` |
| `fix_available` | `selfHealingStatus == 'COMPLETED'` AND `suggestedFix != null` AND (`couldAutoApplyTasks != true` OR `verificationStatus` in (`FAILED`, `NOT_EXECUTABLE`)) |
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
Parse any overrides from `${input:args}` and merge with defaults.
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Monitor Nx Cloud CI pipeline and handle self-healing fixes automatically. Checks for Nx Cloud connection before starting.
---
# CI Monitor Command
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
Parse any overrides from `$ARGUMENTS` and merge with defaults.
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Generate code using nx generators. USE WHEN scaffolding code or transforming existing code - for example creating libraries or applications, or anything else that is boilerplate code or automates repetitive tasks. ALWAYS use this first when generating code with Nx instead of calling MCP tools or running nx generate immediately.
---
# Run Nx Generator
Nx generators are powerful tools that scaffold projects, make automated code migrations or automate repetitive tasks in a monorepo. They ensure consistency across the codebase and reduce boilerplate work.
This skill applies when the user wants to:
- Create new projects like libraries or applications
- Scaffold features or boilerplate code
- Run workspace-specific or custom generators
- Do anything else that an nx generator exists for
## Generator Discovery Flow
### Step 1: List Available Generators
Use the Nx CLI to discover available generators:
- List all generators for a plugin: `npx nx list @nx/react`
- Local workspace generators (defined in the repo's own plugins)
### Step 2: Match Generator to User Request
Based on the user's request, identify which generator(s) could fulfill their needs. Consider:
- What artifact type they want to create (library, application, etc.)
- Which framework or technology stack is relevant
- Whether they mentioned specific generator names
**IMPORTANT**: When both a local workspace generator and an external plugin generator could satisfy the request, **always prefer the local workspace generator**. Local generators are customized for the specific repo's patterns and conventions.
It's possible that the user request is something that no Nx generator exists for whatsoever. In this case, you can stop using this skill and try to help the user another way. HOWEVER, the burden of proof for this is high. Before aborting, carefully consider each and every generator that's available. Look into details for any that could be related in any way before making this decision.
## Pre-Execution Checklist
Before running any generator, complete these steps:
### 1. Fetch Generator Schema
Use the `--help` flag to understand all available options:
```bash
npx nx g @nx/react:library --help
```
Pay attention to:
- Required options that must be provided
- Optional options that may be relevant to the user's request
- Default values that might need to be overridden
### 2. Read Generator Source Code
Understanding what the generator actually does helps you:
- Know what files will be created/modified
- Understand any side effects (updating configs, installing deps, etc.)
- Identify options that might not be obvious from the schema
To find generator source code:
- For plugin generators: Use `node -e "console.log(require.resolve('@nx/<plugin>/generators.json'));"` to find the generators.json, then locate the source from there
- If that fails, read directly from `node_modules/<plugin>/generators.json`
- For local generators: They are typically in `tools/generators/` or a local plugin directory. You can search the repo for the generator name to find it.
### 2.5 Reevaluate if the generator is right
Once you have built up an understanding of what the selected generator does, reconsider: Is this the right generator to service the user request?
If not, it's okay to go back to the Generator Discovery Flow and select a different generator before proceeding. If you do, make sure to go through the entire pre-execution checklist once more.
### 3. Understand Repo Context
Before generating, examine the target area of the codebase:
- Look at similar existing artifacts (other libraries, applications, etc.)
- Identify patterns and conventions used in the repo
- Note naming conventions, file structures, and configuration patterns
- Try to match these patterns when configuring the generator
For example, if similar libraries are using a specific test runner, build tool or linter, try to match that if possible.
If projects or other artifacts are organized with a specific naming convention, try to match it.
### 4. Validate Required Options
Ensure all required options have values:
- Map the user's request to generator options
- Infer values from context where possible
- Ask the user for any critical missing information
## Execution
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally.
Many generators will behave differently based on where they are executed. For example, first-party nx library generators use the cwd to determine the directory that the library should be placed in. This is highly important.
### Consider Dry-Run (Optional)
Running with `--dry-run` first is strongly encouraged but not mandatory. Use your judgment:
- For complex generators or unfamiliar territory: do a dry-run first
- For simple, well-understood generators: may proceed directly
- Dry-run shows file names and created/deleted/modified markers, but not content
- There are cases where a generator does not support dry-run (for example if it had to install an npm package) - in that case --dry-run might fail. Don't be discouraged but simply move on to running the generator for real and iterating from there.
description: Find and add Nx plugins. USE WHEN user wants to discover available plugins, install a new plugin, or add support for a specific framework or technology to the workspace.
description: Helps with running tasks in an Nx workspace. USE WHEN the user wants to execute build, test, lint, serve, or run any other tasks defined in the workspace.
---
You can run tasks with Nx in the following way.
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally. Look at the package.json or lockfile to determine which package manager is in use.
For more details on any command, run it with `--help` (e.g. `nx run-many --help`, `nx affected --help`).
## Understand which tasks can be run
You can check those via `nx show project <projectname> --json`, for example `nx show project myapp --json`. It contains a `targets` section which has information about targets that can be run. You can also just look at the `package.json` scripts or `project.json` targets, but you might miss out on inferred tasks by Nx plugins.
## Run a single task
```
nx run <project>:<task>
```
where `project` is the project name defined in `package.json` or `project.json` (if present).
## Run multiple tasks
```
nx run-many -t build test lint typecheck
```
You can pass a `-p` flag to filter to specific projects, otherwise it runs on all projects. You can also use `--exclude` to exclude projects, and `--parallel` to control the number of parallel processes (default is 3).
Examples:
-`nx run-many -t test -p proj1 proj2` — test specific projects
-`nx run-many -t test --projects=*-app --exclude=excluded-app` — test projects matching a pattern
-`nx run-many -t test --projects=tag:api-*` — test projects by tag
## Run tasks for affected projects
Use `nx affected` to only run tasks on projects that have been changed and projects that depend on changed projects. This is especially useful in CI and for large workspaces.
```
nx affected -t build test lint
```
By default it compares against the base branch. You can customize this:
-`nx affected -t test --base=main --head=HEAD` — compare against a specific base and head
-`nx affected -t test --files=libs/mylib/src/index.ts` — specify changed files directly
## Useful flags
These flags work with `run`, `run-many`, and `affected`:
-`--skipNxCache` — rerun tasks even when results are cached
-`--verbose` — print additional information such as stack traces
-`--nxBail` — stop execution after the first failed task
-`--configuration=<name>` — use a specific configuration (e.g. `production`)
description: "Explore and understand Nx workspaces. USE WHEN answering any questions about the nx workspace, the projects in it or tasks to run. EXAMPLES: 'What projects are in this workspace?', 'How is project X configured?', 'What targets can I run?', 'What's affected by my changes?', 'Which projects depend on library Y?', or any questions about Nx workspace structure, project configuration, or available tasks."
---
# Nx Workspace Exploration
This skill provides read-only exploration of Nx workspaces. Use it to understand workspace structure, project configuration, available targets, and dependencies.
Keep in mind that you might have to prefix commands with `npx`/`pnpx`/`yarn` if nx isn't installed globally. Check the lockfile to determine the package manager in use.
## Listing Projects
Use `nx show projects` to list projects in the workspace.
```bash
# List all projects
nx show projects
# Filter by pattern (glob)
nx show projects --projects "apps/*"
nx show projects --projects "shared-*"
# Filter by project type
nx show projects --type app
nx show projects --type lib
nx show projects --type e2e
# Filter by target (projects that have a specific target)
nx show projects --withTarget build
nx show projects --withTarget e2e
# Find affected projects (changed since base branch)
nx show projects --affected
nx show projects --affected --base=main
nx show projects --affected --type app
# Combine filters
nx show projects --type lib --withTarget test
nx show projects --affected --exclude="*-e2e"
# Output as JSON
nx show projects --json
```
## Project Configuration
Use `nx show project <name> --json` to get the full resolved configuration for a project.
**Important**: Do NOT read `project.json` directly - it only contains partial configuration. The `nx show project` command returns the full resolved config including inferred targets from plugins.
You can read the full project schema at `node_modules/nx/schemas/project-schema.json` to understand nx project configuration options.
```bash
# Get full project configuration
nx show project my-app --json
# Extract specific parts from the JSON
nx show project my-app --json | jq '.targets'
nx show project my-app --json | jq '.targets.build'
nx show project my-app --json | jq '.targets | keys'
// TODO (emily): Fix Windows support as gradle fails when running nx build https://staging.nx.app/runs/LgD4vxGn8w?utm_source=pull-request&utm_medium=comment
// TODO (Jack): Fix Windows support as gradle fails when running nx build https://staging.nx.app/runs/LgD4vxGn8w?utm_source=pull-request&utm_medium=comment
description: Polls Nx Cloud CI pipeline and self-healing status. Returns structured state when actionable. Spawned by /nx-cloud-ci-monitor command to monitor CI Attempt status.
mode: subagent
---
# CI Watcher Subagent
You are a CI monitoring subagent responsible for polling Nx Cloud CI Attempt status and self-healing state. You report status back to the main agent - you do NOT make apply/reject decisions.
## Your Responsibilities
1. Poll CI status using the `ci_information` MCP tool
2. Implement exponential backoff between polls
3. Return structured state when an actionable condition is reached
4. Track iteration count and elapsed time
5. Output status updates based on verbosity level
## Input Parameters (from Main Agent)
The main agent may provide these optional parameters in the prompt:
# Large content fields - fetch only when returning to main agent
```
## Initial Wait
Before first poll, wait based on context:
- **Fresh start (no expected CIPE):** Wait 60 seconds to allow CI to start
- **Expecting new CIPE:** Wait 30 seconds (action already triggered)
**IMPORTANT:** Always run sleep in foreground, NOT as background command.
```bash
sleep 60# or 30 if expecting new CIPE (FOREGROUND, not background)
```
## Two-Phase Operation
The subagent operates in one of two modes depending on input:
### Mode 1: Fresh Start (no `expectedCommitSha` or `previousCipeUrl`)
Normal polling - process whatever CIPE is returned by `ci_information`.
### Mode 2: Wait-for-New-CIPE (when `expectedCommitSha` or `previousCipeUrl` provided)
**CRITICAL**: When expecting a new CIPE, the subagent must **completely ignore** the old/stale CIPE. Do NOT process its status, do NOT return actionable states based on it.
#### Phase A: Wait Mode
1. Start a **new-CIPE timeout** timer (default: 30 minutes)
2. On each poll of `ci_information`:
- Check if CIPE is NEW:
-`cipeUrl` differs from `previousCipeUrl` → **new CIPE detected**
[CI Monitor] Still seeing previous CI Attempt (ignoring): <oldCipeUrl>
[CI Monitor] Polling... (elapsed: 1m 30s)
[CI Monitor] Still seeing previous CI Attempt (ignoring): <oldCipeUrl>
[CI Monitor] Polling... (elapsed: 2m 30s)
[CI Monitor] ✓ New CI Attempt detected! URL: <newCipeUrl>, SHA: <newCommitSha>
[CI Monitor] Switching to normal polling mode...
```
### Why This Matters (Context Preservation)
**The problem**: Stale CIPE data can be very large:
-`taskOutputSummary`: potentially thousands of characters of build/test output
-`suggestedFix`: entire patch files
-`suggestedFixReasoning`: detailed explanation
If subagent returns stale CIPE data to main agent, it **pollutes main agent's context** with useless information (we already processed that CIPE). This wastes valuable context window.
**Without wait mode:**
1. Poll `ci_information` → get old CIPE with huge data
2. Return to main agent with all that stale data
3. Main agent's context gets polluted with useless info
4. Main agent has to process/ignore it anyway
**With wait mode:**
1. Poll `ci_information` → get old CIPE → **ignore it, don't return**
2. Keep waiting internally (stale data stays in subagent)
3. New CIPE appears → switch to normal mode
4. Return to main agent with only the NEW, relevant CIPE data
## Polling Loop
### Subagent State Management
Maintain internal accumulated state across polls:
```
accumulated_state = {}
```
### Call `ci_information` MCP Tool
**Wait Mode (expecting new CI Attempt):**
```
ci_information({
branch: "<branch_name>",
select: "cipeUrl,commitSha,cipeStatus"
})
```
Only fetch minimal fields needed to detect CI Attempt change. Do NOT fetch heavy fields - stale data wastes context.
Merge response into `accumulated_state`, then return merged state to main agent.
**Pagination:** Heavy string fields return first page only. If `hasMore` indicated, include in return format so main agent knows more content available.
### Return to Main Agent When
Return immediately with structured state if ANY of these conditions are true:
| `fix_auto_applying` | `selfHealingStatus == 'COMPLETED'` AND `couldAutoApplyTasks == true` AND `verificationStatus == 'COMPLETED'` |
| `fix_available` | `selfHealingStatus == 'COMPLETED'` AND `suggestedFix != null` AND (`couldAutoApplyTasks != true` OR `verificationStatus` in (`FAILED`, `NOT_EXECUTABLE`)) |
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
Parse any overrides from `$ARGUMENTS` and merge with defaults.
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Monitor Nx Cloud CI pipeline and handle self-healing fixes automatically. Checks for Nx Cloud connection before starting.
---
# CI Monitor Command
You are the orchestrator for monitoring Nx Cloud CI pipeline executions and handling self-healing fixes. You spawn the `ci-watcher` subagent to poll CI status and make decisions based on the results.
| `--auto-fix-workflow` | false | Attempt common fixes for pre-CIPE failures (e.g., lockfile updates) |
| `--new-cipe-timeout` | 10 | Minutes to wait for new CIPE after action |
| `--local-verify-attempts` | 3 | Max local verification + enhance cycles before pushing to CI |
Parse any overrides from `$ARGUMENTS` and merge with defaults.
## Nx Cloud Connection Check
**CRITICAL**: Before starting the monitoring loop, verify the workspace is connected to Nx Cloud.
### Step 0: Verify Nx Cloud Connection
1.**Check `nx.json`** at workspace root for `nxCloudId` or `nxCloudAccessToken`
2.**If `nx.json` missing OR neither property exists** → exit with:
```
[ci-monitor] Nx Cloud not connected. Unlock 70% faster CI and auto-fix broken PRs with https://nx.dev/nx-cloud
```
3. **If connected** → continue to main loop
## Session Context Behavior
**Important:** Within a Claude Code session, conversation context persists. If you Ctrl+C to interrupt the monitor and re-run `/ci-monitor`, Claude remembers the previous state and may continue from where it left off.
- **To continue monitoring:** Just re-run `/ci-monitor` (context is preserved)
- **To start fresh:** Use `/ci-monitor --fresh` to ignore previous context
- **For a completely clean slate:** Exit Claude Code and restart `claude`
## Default Behaviors by Status
The subagent returns with one of the following statuses. This table defines the **default behavior** for each status. User instructions can override any of these.
| `fix_auto_applying` | Fix will be auto-applied by self-healing. Do NOT call MCP. Record `last_cipe_url`, spawn new subagent in wait mode to poll for new CIPE. |
| `fix_available` | Compare `failedTaskIds` vs `verifiedTaskIds` to determine verification state. See **Fix Available Decision Logic** section below. |
| `fix_failed` | Self-healing failed to generate fix. Attempt local fix based on `taskOutputSummary`. If successful → commit, push, loop. If not → exit with failure. |
| `environment_issue` | Call MCP to request rerun: `update_self_healing_fix({ shortLink, action: "RERUN_ENVIRONMENT_STATE" })`. New CIPE spawns automatically. Loop to poll for new CIPE. |
| `no_fix` | CI failed, no fix available (self-healing disabled or not executable). Attempt local fix if possible. Otherwise exit with failure. |
| `no_new_cipe` | Expected CIPE never spawned (CI workflow likely failed before Nx tasks). Report to user, attempt common fixes if configured, or exit with guidance. |
- If fix needs enhancement → use Apply Locally + Enhance Flow above
- If fix is wrong → reject via MCP, fix from scratch, commit, push
### Auto-Apply Eligibility
The `couldAutoApplyTasks` field indicates whether the fix is eligible for automatic application:
- **`true`**: Fix is eligible for auto-apply. Subagent keeps polling while verification is in progress. Returns `fix_auto_applying` when verified, or `fix_available` if verification fails.
- **`false`** or **`null`**: Fix requires manual action (apply via MCP, apply locally, or reject)
**Key point**: When subagent returns `fix_auto_applying`, do NOT call MCP to apply - self-healing handles it. Just spawn a new subagent in wait mode.
### Apply vs Reject vs Apply Locally
- **Apply via MCP**: Calls `update_self_healing_fix({ shortLink, action: "APPLY" })`. Self-healing agent applies the fix in CI and a new CIPE spawns automatically. No local git operations needed.
- **Apply Locally**: Runs `nx apply-locally <shortLink>`. Applies the patch to your local working directory and sets state to `APPLIED_LOCALLY`. Use this when you want to enhance the fix before pushing.
- **Reject via MCP**: Calls `update_self_healing_fix({ shortLink, action: "REJECT" })`. Marks fix as rejected. Use only when the fix is completely wrong and you'll fix from scratch.
### Apply Locally + Enhance Flow
When the fix needs enhancement (use `nx apply-locally`, NOT reject):
1. Apply the patch locally: `nx apply-locally <shortLink>` (this also updates state to `APPLIED_LOCALLY`)
2. Make additional changes as needed
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Reject + Fix From Scratch Flow
When the fix is completely wrong:
1. Call MCP to reject: `update_self_healing_fix({ shortLink, action: "REJECT" })`
2. Fix the issue from scratch locally
3. Commit and push:
```bash
git add -A
git commit -m "fix: resolve <failedTaskIds>"
git push origin $(git branch --show-current)
```
4. Loop to poll for new CIPE
### Environment Issue Handling
When `failureClassification == 'ENVIRONMENT_STATE'`:
**CRITICAL**: When passing `expectedCommitSha` or `last_cipe_url` to the subagent, it enters **wait mode**:
- Subagent will **completely ignore** the old/stale CIPE
- Subagent will only wait for new CIPE to appear
- Subagent will NOT return to main agent with stale CIPE data
- Once new CIPE detected, subagent switches to normal polling
**Why wait mode matters for context preservation**: Stale CIPE data can be very large (task output summaries, suggested fix patches, reasoning). If subagent returns this to main agent, it pollutes main agent's context with useless data since we already processed that CIPE. Wait mode keeps stale data in the subagent, never sending it to main agent.
### Step 4: Progress Tracking
After each action:
- If state changed significantly → reset `no_progress_count = 0`
- If state unchanged → `no_progress_count++`
- On new CI attempt detected → reset `local_verify_count = 0`
description: Generate code using nx generators. USE WHEN scaffolding code or transforming existing code - for example creating libraries or applications, or anything else that is boilerplate code or automates repetitive tasks. ALWAYS use this first when generating code with Nx instead of calling MCP tools or running nx generate immediately.
---
# Run Nx Generator
Nx generators are powerful tools that scaffold projects, make automated code migrations or automate repetitive tasks in a monorepo. They ensure consistency across the codebase and reduce boilerplate work.
This skill applies when the user wants to:
- Create new projects like libraries or applications
- Scaffold features or boilerplate code
- Run workspace-specific or custom generators
- Do anything else that an nx generator exists for
## Generator Discovery Flow
### Step 1: List Available Generators
Use the Nx CLI to discover available generators:
- List all generators for a plugin: `npx nx list @nx/react`
- Local workspace generators (defined in the repo's own plugins)
### Step 2: Match Generator to User Request
Based on the user's request, identify which generator(s) could fulfill their needs. Consider:
- What artifact type they want to create (library, application, etc.)
- Which framework or technology stack is relevant
- Whether they mentioned specific generator names
**IMPORTANT**: When both a local workspace generator and an external plugin generator could satisfy the request, **always prefer the local workspace generator**. Local generators are customized for the specific repo's patterns and conventions.
It's possible that the user request is something that no Nx generator exists for whatsoever. In this case, you can stop using this skill and try to help the user another way. HOWEVER, the burden of proof for this is high. Before aborting, carefully consider each and every generator that's available. Look into details for any that could be related in any way before making this decision.
## Pre-Execution Checklist
Before running any generator, complete these steps:
### 1. Fetch Generator Schema
Use the `--help` flag to understand all available options:
```bash
npx nx g @nx/react:library --help
```
Pay attention to:
- Required options that must be provided
- Optional options that may be relevant to the user's request
- Default values that might need to be overridden
### 2. Read Generator Source Code
Understanding what the generator actually does helps you:
- Know what files will be created/modified
- Understand any side effects (updating configs, installing deps, etc.)
- Identify options that might not be obvious from the schema
To find generator source code:
- For plugin generators: Use `node -e "console.log(require.resolve('@nx/<plugin>/generators.json'));"` to find the generators.json, then locate the source from there
- If that fails, read directly from `node_modules/<plugin>/generators.json`
- For local generators: They are typically in `tools/generators/` or a local plugin directory. You can search the repo for the generator name to find it.
### 2.5 Reevaluate if the generator is right
Once you have built up an understanding of what the selected generator does, reconsider: Is this the right generator to service the user request?
If not, it's okay to go back to the Generator Discovery Flow and select a different generator before proceeding. If you do, make sure to go through the entire pre-execution checklist once more.
### 3. Understand Repo Context
Before generating, examine the target area of the codebase:
- Look at similar existing artifacts (other libraries, applications, etc.)
- Identify patterns and conventions used in the repo
- Note naming conventions, file structures, and configuration patterns
- Try to match these patterns when configuring the generator
For example, if similar libraries are using a specific test runner, build tool or linter, try to match that if possible.
If projects or other artifacts are organized with a specific naming convention, try to match it.
### 4. Validate Required Options
Ensure all required options have values:
- Map the user's request to generator options
- Infer values from context where possible
- Ask the user for any critical missing information
## Execution
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally.
Many generators will behave differently based on where they are executed. For example, first-party nx library generators use the cwd to determine the directory that the library should be placed in. This is highly important.
### Consider Dry-Run (Optional)
Running with `--dry-run` first is strongly encouraged but not mandatory. Use your judgment:
- For complex generators or unfamiliar territory: do a dry-run first
- For simple, well-understood generators: may proceed directly
- Dry-run shows file names and created/deleted/modified markers, but not content
- There are cases where a generator does not support dry-run (for example if it had to install an npm package) - in that case --dry-run might fail. Don't be discouraged but simply move on to running the generator for real and iterating from there.
description: Find and add Nx plugins. USE WHEN user wants to discover available plugins, install a new plugin, or add support for a specific framework or technology to the workspace.
description: Helps with running tasks in an Nx workspace. USE WHEN the user wants to execute build, test, lint, serve, or run any other tasks defined in the workspace.
---
You can run tasks with Nx in the following way.
Keep in mind that you might have to prefix things with npx/pnpx/yarn if the user doesn't have nx installed globally. Look at the package.json or lockfile to determine which package manager is in use.
For more details on any command, run it with `--help` (e.g. `nx run-many --help`, `nx affected --help`).
## Understand which tasks can be run
You can check those via `nx show project <projectname> --json`, for example `nx show project myapp --json`. It contains a `targets` section which has information about targets that can be run. You can also just look at the `package.json` scripts or `project.json` targets, but you might miss out on inferred tasks by Nx plugins.
## Run a single task
```
nx run <project>:<task>
```
where `project` is the project name defined in `package.json` or `project.json` (if present).
## Run multiple tasks
```
nx run-many -t build test lint typecheck
```
You can pass a `-p` flag to filter to specific projects, otherwise it runs on all projects. You can also use `--exclude` to exclude projects, and `--parallel` to control the number of parallel processes (default is 3).
Examples:
-`nx run-many -t test -p proj1 proj2` — test specific projects
-`nx run-many -t test --projects=*-app --exclude=excluded-app` — test projects matching a pattern
-`nx run-many -t test --projects=tag:api-*` — test projects by tag
## Run tasks for affected projects
Use `nx affected` to only run tasks on projects that have been changed and projects that depend on changed projects. This is especially useful in CI and for large workspaces.
```
nx affected -t build test lint
```
By default it compares against the base branch. You can customize this:
-`nx affected -t test --base=main --head=HEAD` — compare against a specific base and head
-`nx affected -t test --files=libs/mylib/src/index.ts` — specify changed files directly
## Useful flags
These flags work with `run`, `run-many`, and `affected`:
-`--skipNxCache` — rerun tasks even when results are cached
-`--verbose` — print additional information such as stack traces
-`--nxBail` — stop execution after the first failed task
-`--configuration=<name>` — use a specific configuration (e.g. `production`)
description: "Explore and understand Nx workspaces. USE WHEN answering any questions about the nx workspace, the projects in it or tasks to run. EXAMPLES: 'What projects are in this workspace?', 'How is project X configured?', 'What targets can I run?', 'What's affected by my changes?', 'Which projects depend on library Y?', or any questions about Nx workspace structure, project configuration, or available tasks."
---
# Nx Workspace Exploration
This skill provides read-only exploration of Nx workspaces. Use it to understand workspace structure, project configuration, available targets, and dependencies.
Keep in mind that you might have to prefix commands with `npx`/`pnpx`/`yarn` if nx isn't installed globally. Check the lockfile to determine the package manager in use.
## Listing Projects
Use `nx show projects` to list projects in the workspace.
```bash
# List all projects
nx show projects
# Filter by pattern (glob)
nx show projects --projects "apps/*"
nx show projects --projects "shared-*"
# Filter by project type
nx show projects --type app
nx show projects --type lib
nx show projects --type e2e
# Filter by target (projects that have a specific target)
nx show projects --withTarget build
nx show projects --withTarget e2e
# Find affected projects (changed since base branch)
nx show projects --affected
nx show projects --affected --base=main
nx show projects --affected --type app
# Combine filters
nx show projects --type lib --withTarget test
nx show projects --affected --exclude="*-e2e"
# Output as JSON
nx show projects --json
```
## Project Configuration
Use `nx show project <name> --json` to get the full resolved configuration for a project.
**Important**: Do NOT read `project.json` directly - it only contains partial configuration. The `nx show project` command returns the full resolved config including inferred targets from plugins.
You can read the full project schema at `node_modules/nx/schemas/project-schema.json` to understand nx project configuration options.
```bash
# Get full project configuration
nx show project my-app --json
# Extract specific parts from the JSON
nx show project my-app --json | jq '.targets'
nx show project my-app --json | jq '.targets.build'
nx show project my-app --json | jq '.targets | keys'
@@ -9,6 +9,25 @@ When responding to queries about this repository:
Always strive to provide accurate, helpful responses that align with the best practices and workflows described in this
file.
## Documentation Contributions
When working on Nx documentation, all documentation content lives in the `astro-docs/` folder. This is the new Astro-based documentation site built with Starlight.
**Important**: Before making any documentation changes, read the `astro-docs/README.md` file for detailed guidance on:
- Use `.mdoc` (Markdoc) or `.mdx` format for documentation files
- Run `nx serve astro-docs` to start the local dev server
- Sidebar structure is defined in `astro-docs/sidebar.mts`
## GitHub Issue Response Mode
When responding to GitHub issues, determine your approach based on how the request is phrased:
@@ -183,22 +202,23 @@ Fixes #ISSUE_NUMBER
<!-- nx configuration start-->
<!-- Leave the start & end comments to automatically receive updates. -->
# General Guidelines for working with Nx
## General Guidelines for working with Nx
- For navigating/exploring the workspace, invoke the `nx-workspace` skill first - it has patterns for querying projects, targets, and dependencies
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
- Prefix nx commands with the workspace's package manager (e.g., `pnpm nx build`, `npm exec nx test`) - avoids using globally installed CLI
- You have access to the Nx MCP server and its tools, use them to help the user
-When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable.
-When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
-For Nx plugin best practices, check `node_modules/@nx/<plugin>/PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable.
-NEVER guess CLI flags - always check nx_docs or `--help` first when unsure
# CI Error Guidelines
## Scaffolding & Generators
If the user wants help with fixing an error in their CI pipeline, use the following flow:
- For scaffolding tasks (creating apps, libs, project structure, setup), ALWAYS invoke the `nx-generate` skill FIRST before exploring or calling MCP tools
- Retrieve the list of current CI Pipeline Executions (CIPEs) using the `nx_cloud_cipe_details` tool
- If there are any errors, use the `nx_cloud_fix_cipe_failure` tool to retrieve the logs for a specific task
- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary
-Make sure that the problem is fixed by running the task that you passed into the `nx_cloud_fix_cipe_failure` tool
@@ -9,6 +9,25 @@ When responding to queries about this repository:
Always strive to provide accurate, helpful responses that align with the best practices and workflows described in this
file.
## Documentation Contributions
When working on Nx documentation, all documentation content lives in the `astro-docs/` folder. This is the new Astro-based documentation site built with Starlight.
**Important**: Before making any documentation changes, read the `astro-docs/README.md` file for detailed guidance on:
- Use `.mdoc` (Markdoc) or `.mdx` format for documentation files
- Run `nx serve astro-docs` to start the local dev server
- Sidebar structure is defined in `astro-docs/sidebar.mts`
## GitHub Issue Response Mode
When responding to GitHub issues, determine your approach based on how the request is phrased:
@@ -183,22 +202,23 @@ Fixes #ISSUE_NUMBER
<!-- nx configuration start-->
<!-- Leave the start & end comments to automatically receive updates. -->
# General Guidelines for working with Nx
## General Guidelines for working with Nx
- For navigating/exploring the workspace, invoke the `nx-workspace` skill first - it has patterns for querying projects, targets, and dependencies
- When running tasks (for example build, lint, test, e2e, etc.), always prefer running the task through `nx` (i.e. `nx run`, `nx run-many`, `nx affected`) instead of using the underlying tooling directly
- Prefix nx commands with the workspace's package manager (e.g., `pnpm nx build`, `npm exec nx test`) - avoids using globally installed CLI
- You have access to the Nx MCP server and its tools, use them to help the user
-When answering questions about the repository, use the `nx_workspace` tool first to gain an understanding of the workspace architecture where applicable.
-When working in individual projects, use the `nx_project_details` mcp tool to analyze and understand the specific project structure and dependencies
- For questions around nx configuration, best practices or if you're unsure, use the `nx_docs` tool to get relevant, up-to-date docs. Always use this instead of assuming things about nx configuration
- If the user needs help with an Nx configuration or project graph error, use the `nx_workspace` tool to get any errors
-For Nx plugin best practices, check `node_modules/@nx/<plugin>/PLUGIN.md`. Not all plugins have this file - proceed without it if unavailable.
-NEVER guess CLI flags - always check nx_docs or `--help` first when unsure
# CI Error Guidelines
## Scaffolding & Generators
If the user wants help with fixing an error in their CI pipeline, use the following flow:
- For scaffolding tasks (creating apps, libs, project structure, setup), ALWAYS invoke the `nx-generate` skill FIRST before exploring or calling MCP tools
- Retrieve the list of current CI Pipeline Executions (CIPEs) using the `nx_cloud_cipe_details` tool
- If there are any errors, use the `nx_cloud_fix_cipe_failure` tool to retrieve the logs for a specific task
- Use the task logs to see what's wrong and help the user fix their problem. Use the appropriate tools if necessary
-Make sure that the problem is fixed by running the task that you passed into the `nx_cloud_fix_cipe_failure` tool
<p style="text-align: center;"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/how-to-contribute.png" width="600" alt="Nx - How to contribute"></p>
</a>
## Got a Question?
We are trying to keep GitHub issues for bug reports and feature requests. Using the `nrwl` tag
on [Stack Overflow](https://stackoverflow.com/questions/tagged/nrwl) is a much better place to ask general questions
about how to use Nx.
We are trying to keep GitHub issues for bug reports and feature requests.
You can join our [Discord](https://go.nx.dev/community) for general questions and seeking help from others.
[](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
[](https://go.nx.dev/community)
<h1 align="center">Smart Monorepos · Fast Builds</h1>
Nx is a monorepo solution for TypeScript and polyglot codebases. Built with Rust for performance, extensible via TypeScript. Caches what didn't change, runs only what's affected, and comes with an integrated CI solution. Start simple, scale as you grow.
# Smart Repos · Fast Builds
## Quick Start
Get to green PRs in half the time. Nx optimizes your builds, scales your CI, and fixes failed PRs. Built for developers and AI agents.
Visit the [Nx quickstart docs](https://nx.dev/docs/quickstart) to get started.
Create a new Nx workspace with
## Why Nx?
```shell
npx create-nx-workspace
```
- **Incremental by design -** Run `npx nx init` in any npm/pnpm/yarn workspace. Nx picks up your existing `package.json` scripts, caches their outputs, and runs only what's
affected. No changes to your setup required.
- **AI-native tooling -** The Nx CLI is optimized for autonomous AI agents so they get the context they need and can operate just like a human. [Learn more »](https://github.com/nrwl/nx-ai-agents-config)
- **Polyglot plugin system -** Optional plugins auto-discover tasks, configure cache inputs/outputs, and scaffold code based on your actual tooling. Works with Vite, Webpack, Jest, Vitest, ESLint, Gradle, Maven, .NET, Go, and [more](https://nx.dev/technologies).
- **Integrated CI solution -** [Connect Nx to your CI provider](https://nx.dev/ci/intro/ci-with-nx) (GitHub Actions, GitLab, Azure, etc.) to enable remote caching, task distribution across machines, affected-only runs, and automatic e2e test splitting. [Learn more »](https://nx.dev/ci/intro/ci-with-nx)
- **Self-healing CI -** An AI agent on your CI pipeline that detects failures, analyzes root cause, proposes a fix, and verifies it automatically. Local agents connect to CI via MCP to autonomously detect and fix failures. [Learn more »](https://nx.dev/ci/features/self-healing)
...or run
## Who uses Nx?
```
npx nx init
```
to add Nx to your existing workspace to get faster task scheduling, caching and more. More [in the docs](https://nx.dev/getting-started/intro).
## Learn about CI with Nx Cloud
[Nx Cloud](https://nx.dev/nx-cloud) connects directly to your existing CI setup, helping you scale your monorepos on CI by leveraging [remote caching](https://nx.dev/ci/features/remote-cache?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo), [task distribution across multiple machines](https://nx.dev/ci/features/distribute-task-execution?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo), [automated e2e test splitting](https://nx.dev/ci/features/split-e2e-tasks?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo) and [automated task flakiness detection](https://nx.dev/ci/features/flaky-tasks?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo)
Connect your existing Nx workspace with
```
npx nx connect
```
Learn more in the [Nx CI docs »](https://nx.dev/ci/getting-started/intro?utm_source=nxrepo&utm_medium=readme&utm_campaign=nxrepo)
## Useful links
- [Our docs](https://nx.dev/docs)
- [Our blog](https://nx.dev/blog)
- [Our community discord, live stream,...](https://nx.dev/community)
@@ -13,3 +13,15 @@ Instead, please report them to the Security Team at security@nrwl.io.
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message.
Nx follows the principle of Coordinated Vulnerability Disclosure.
## What Should Be Reported
The security email is for **demonstrable, verified vulnerabilities within the Nx codebase itself**.
**Please do not use the security email for:**
- Reports about outdated dependencies (e.g., "package X has a newer version available")
- Reports about dependencies with known CVEs that do not directly affect Nx functionality
- General vulnerability scanner output
If you have a concern about an outdated dependency that you believe impacts Nx users, please open a [GitHub issue](https://github.com/nrwl/nx/issues/new/choose) instead.
2.**Technologies** - Framework and tool-specific guides (React, Angular, Node, build tools, test tools)
3.**Knowledge Base** - Recipes, troubleshooting, and topic-specific guides
4.**Reference** - Exhaustive facts, no narrative (CLI commands, configuration, API docs)
## The Nx voice
Nx documentation is **direct, practical, and confident**. We write like a knowledgeable colleague pairing with you — not like a textbook, not like a marketing page, and not like a chatbot.
The voice should be:
- **Conversational but efficient.** Use contractions. Get to the point. Don't pad sentences.
- **Second person.** Write "you" — address the reader directly.
- **Action-oriented.** Lead with what the reader can _do_, not what Nx _is_.
- **Honest about tradeoffs.** Don't oversell. If something has limitations, say so.
| "You can speed up builds by enabling remote caching." | "Nx allows you to speed up builds." |
| "Run `nx build` to build your project." | "In order to build your project, you can run the `nx build` command." |
| "This works best with fewer than 50 projects." | "This feature can easily scale to any number of projects." |
| "Nx reads your `vite.config.ts` and infers build targets automatically." | "Nx provides a robust and comprehensive mechanism for inferring build targets." |
| "If the cache is stale, delete `.nx/cache` and retry." | "Should you encounter issues with caching, you may want to consider clearing your cache directory." |
### Anti-AI language
Documentation must not read like it was generated by an AI assistant. Even when AI tools are used in the writing process, the output must be edited to sound like a human wrote it.
**Never use these phrases:**
- "It's important to note that..."
- "It's worth noting that..." / "It should be noted that..."
- "In this section, we will explore..."
- "Let's dive into..." / "Let's take a closer look at..."
- "Whether you're a beginner or an experienced developer..."
- "In today's fast-paced development environment..."
- "Unlock the power of..." / "Harness the power of..."
- "Take your workspace to the next level"
- "Streamline your workflow" (as a generic claim without specifics)
- "This comprehensive guide will..."
- "Without further ado..."
- "In conclusion..." / "To summarize..." / "As we've seen..."
- "Seamless" / "Seamlessly" (unless describing an actual integration)
**Avoid hedging words unless genuinely needed:**
- "Essentially" / "Basically" / "Effectively"
- "Generally speaking"
- "It is worth mentioning"
- "Arguably"
- "Needless to say"
- "As a matter of fact"
**Watch for AI-style sentence patterns:**
- Sentences that start with "This allows you to..." or "This enables you to..." — rewrite to lead with the reader's action.
- Paragraphs that start with a general claim and then restate it slightly differently. Say it once.
- Excessive use of "robust", "leverage", "utilize", "facilitate", "comprehensive", "aforementioned."
- Lists where every item starts with the same grammatical structure repeated 5+ times with slight variation. Vary your phrasing.
### Self-referential writing
Don't write about the document itself.
Do:
- "Nx uses a project graph to determine task dependencies."
Don't:
- "This page explains how Nx uses a project graph."
- "In this guide, we'll walk through..."
- "This document covers..."
Get right to the point. The reader already knows they're on a page — they want the information.
### Building trust
Don't use filler words that undermine the reader's trust.
- Don't use "easily", "simply", "just", or "straightforward" — if something were truly simple, you wouldn't need to document it. These words also make readers feel bad when they struggle.
- Don't use marketing language: "This feature will save you hours" or "Nx makes CI effortless."
- Be specific instead: "Remote caching can reduce CI times from 45 minutes to under 5 minutes for cache-hit builds."
### Customer perspective
Focus on what the reader can do, not what Nx does.
Do:
- "Use `nx affected` to run tasks only for projects impacted by your changes."
Don't:
- "Nx allows you to run affected tasks."
- "Nx provides the ability to run tasks selectively."
Words like "allow" and "enable" are signals you're writing from the product's perspective instead of the reader's.
## Language
Write in US English.
### Active voice
Use active voice in most cases.
Do: "Nx caches the build output."
Don't: "The build output is cached by Nx."
Exception: When "Nx" as the subject sounds awkward, passive voice is fine. "The output is stored in `.nx/cache`" is better than "Nx stores the output in `.nx/cache`" if Nx isn't the focus of the sentence.
### Contractions
Use contractions. They make the text feel natural.
- "You'll need to configure..." not "You will need to configure..."
- "It doesn't support..." not "It does not support..."
Don't contract for emphasis in warnings or error descriptions:
- "**Do not** delete the `nx.json` file."
- "Requests to localhost **are not** allowed."
Don't contract proper nouns: "the Vite plugin is..." not "Vite's a plugin..."
### Capitalization
Use sentence case for headings. Capitalize proper nouns only.
-`# Use remote caching to speed up CI`
-`## Configure the Vite plugin`
Feature names are lowercase unless they are a proper product name:
| Correct | Incorrect |
| -------------- | -------------- |
| remote caching | Remote Caching |
| task pipeline | Task Pipeline |
| project graph | Project Graph |
| Nx Cloud | nx cloud |
| Nx Console | nx console |
| Nx Agents | nx agents |
| Nx Replay | nx replay |
### Acronyms
Spell out acronyms on first use per page. Don't spell out widely-known ones: CI, CD, API, URL, CLI, PR, IDE.
Don't make acronyms plural with apostrophes. Use `APIs`, not `API's`.
### Numbers
Spell out zero through nine. Use numerals for 10 and above. Always use numerals with units: "5 minutes", "3 projects."
### Possessives
Don't use possessives on product names. "the Docker CLI", not "Docker's CLI." "the Nx configuration", not "Nx's configuration."
## Text
### Headings
- Don't skip heading levels (e.g., `##` to `####`).
- Don't use code in headings unless it's essential (like a CLI command).
- Don't use bold text in headings.
- Keep headings short and scannable. Lead with keywords.
### Line length
- Wrap lines at approximately 100 characters for readability in diffs.
- Start each new sentence on a new line.
- Exception: Don't break links across lines.
### Punctuation
- Use serial (Oxford) commas: "React, Angular, and Vue."
- Use one space between sentences.
- Don't use semicolons. Use two sentences instead.
- Don't use em dashes or en dashes. Use commas or separate sentences.
### Placeholder text
Use `<` and `>` for values the reader must replace:
```shell
nx run <project-name>:build
```
If the placeholder is inline, wrap it in a single backtick: `<your-project>`.
### Bold
Use bold for:
- UI elements: "Select **Add Connection**."
- Navigation paths: "Go to **Settings** > **Workspace**."
Don't use bold for emphasis or keywords. If you need emphasis, rewrite the sentence to be clearer.
### Inline code
Use inline code (single backticks) for:
- Commands and CLI arguments: `nx build`, `--parallel`
- Short outputs and values: `true`, `false`, `success`
### Code blocks
Use triple backticks with a language identifier:
````markdown
```json
{
"targetDefaults": {
"build": {
"cache": true
}
}
}
```
````
- Always specify a syntax language. Use `plaintext` if nothing else fits.
- Add a blank line before and after code blocks.
- For long config files, show only the relevant section and use comments to indicate omitted parts:
```json
{
// ... other config
"targetDefaults": {
"build": {
"cache": true
}
}
}
```
## Links
Links help readers find related information, but too many links make text hard to read.
### General rules
- Don't duplicate links. If you link to a page once, don't link to it again on the same page.
- Don't use links in headings.
- Avoid more than 15 links to other pages on any single page.
- Avoid multiple links in a single paragraph when possible.
### Link text
Use descriptive text, not "here" or "this page."
Do:
- "For more information, see [remote caching](/features/cache)."
- "To configure task pipelines, see [task pipeline configuration](/concepts/task-pipeline-configuration)."
Don't:
- "For more information, see [this page](/features/cache)."
- "Click [here](/features/cache) to learn more."
- "For more information, see the [Remote Caching](/features/cache) documentation."
Standard patterns:
- `For more information, see [link text](url).`
- `To <do this thing>, see [link text](url).`
### External links
Minimize external links. They break over time and are hard to maintain. When you must link externally, prefer official documentation (e.g., Vite docs, Webpack docs) over blog posts or third-party guides.
## Lists
- Use ordered lists for sequences of steps.
- Use unordered lists when order doesn't matter.
- Use dashes (`-`) for unordered lists.
- Start ordered list items with `1.` (Markdown auto-increments).
- Make list items parallel in structure.
- Add a colon after the introductory phrase.
- Don't use list items to complete an introductory sentence.
Do:
```markdown
You can clear the cache in the following ways:
- Delete the `.nx/cache` directory manually.
- Run `nx reset` to clear all cached results.
```
Don't:
```markdown
You can clear the cache by:
- Deleting the `.nx/cache` directory manually.
- Running `nx reset`.
```
## Tables
Use tables for structured data that benefits from a matrix layout. For simple lists of items with descriptions, use a regular list instead.
- Don't leave cells empty. Use "N/A" or "None."
- Use sentence case for headers.
- Keep the header and delimiter rows the same length.
## Nx-specific terminology
Use these terms consistently. When writing about Nx concepts, use the exact term from this list.
"comment":"package.json#scripts runs in the project root directory with astro assumes is where the node_modules is. which fails. so run the scripts in project.json#targets with --root command instead",
Some files were not shown because too many files have changed in this diff
Show More
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.