The `WARN` and `ERR_PNPM_*` labels in pnpm's output relied entirely on a colored background to stand out from the surrounding text. In terminals without color — `NO_COLOR` set, output piped, dumb terminals — the badge collapsed into bare `WARN` / `ERR_PNPM_FOO` and became hard to spot inside the message.
This PR wraps each label in brackets (`[WARN]`, `[ERR_PNPM_FOO]`, `[ERROR]`). The bracket characters are painted in the same color as the badge background, so in a color-capable terminal they appear as plain padding inside the colored badge — the rendering matches what we had before. When ANSI is stripped the brackets reappear as ordinary text, giving the label a clear delimiter.
Fixes#11439.
When `strictPeerDependencies: true` causes `ERR_PNPM_PEER_DEP_ISSUES`, the peer dependency issues are again rendered inline — using the **same format as `pnpm peers check`** — so users (and CI tools like Renovate) can see what failed without running another command.
The non-strict warning path is unchanged: it still emits the short "Run `pnpm peers check`" hint.
### Behavior
`strictPeerDependencies: true`:
```
ERR_PNPM_PEER_DEP_ISSUES Unmet peer dependencies
✕ unmet peer react
Installed: 17.0.2
Wanted:
^18.2.0:
react-dom@18.2.0
hint: To disable failing on peer dependency issues, add the following to pnpm-workspace.yaml in your project root:
strictPeerDependencies: false
```
`strictPeerDependencies: false` (unchanged):
```
WARN Issues with peer dependencies found. Run "pnpm peers check" to list them.
```
### Implementation
- Added a new `@pnpm/deps.inspection.peers-issues-renderer` package at `deps/inspection/peers-issues-renderer/`, alongside its data producer `@pnpm/deps.inspection.peers-checker`. It exposes a single `renderPeerIssues()` that emits the flat issue list previously inlined in `pnpm peers check`.
- Removed the duplicated formatter from `deps/inspection/commands/src/peers.ts` and made the `pnpm peers check` command consume the new renderer.
- `cli/default-reporter/src/reportError.ts`: `reportPeerDependencyIssuesError` now calls the shared `renderPeerIssues()` and prefixes the hint block with the rendered output. Tests strip ANSI escapes before substring assertions so they stay correct under `FORCE_COLOR=1`.
Result: a single renderer is shared between the install error and the `pnpm peers check` command — output is identical between the two paths.
Major cleanup of the config system after migrating settings from `.npmrc` to `pnpm-workspace.yaml`.
### Config reader simplification
- Remove `checkUnknownSetting` (dead code, always `false`)
- Trim `npmConfigTypes` from ~127 to ~67 keys (remove unused npm config keys)
- Replace `rcOptions` iteration over all type keys with direct construction from defaults + auth overlay
- Remove `rcOptionsTypes` parameter from `getConfig()` and its assembly chain
### Rename `rawConfig` to `authConfig`
- `rawConfig` was a confusing mix of auth data and general settings
- Non-auth settings are already on the typed `Config` object — stop duplicating them in `rawConfig`
- Rename `rawConfig` → `authConfig` across the codebase to clarify it only contains auth/registry data from `.npmrc`
### Remove `rawConfig` from non-auth consumers
- **Lifecycle hooks**: replace `rawConfig: object` with `userAgent?: string` — only user-agent was read
- **Fetchers**: remove unused `rawConfig` from git fetcher, binary fetcher, tarball fetcher, prepare-package
- **Update command**: use `opts.production/dev/optional` instead of `rawConfig.*`
- **`pnpm init`**: accept typed init properties instead of parsing `rawConfig`
### Add `nodeDownloadMirrors` setting
- New `nodeDownloadMirrors?: Record<string, string>` on `PnpmSettings` and `Config`
- Replaces the `node-mirror:<channel>` pattern that was stored in `rawConfig`
- Configured in `pnpm-workspace.yaml`:
```yaml
nodeDownloadMirrors:
release: https://my-mirror.example.com/download/release/
```
- Remove unused `rawConfig` from deno-resolver and bun-resolver
### Refactor `pnpm config get/list`
- New `configToRecord()` builds display data from typed Config properties on the fly
- Excludes sensitive internals (`authInfos`, `sslConfigs`, etc.)
- Non-types keys (e.g., `package-extensions`) resolve through `configToRecord` instead of direct property access
- Delete `processConfig.ts` (replaced by `configToRecord.ts`)
### Pre-push hook improvement
- Add `compile-only` (`tsgo --build`) to pre-push hook to catch type errors before push
Instead of rendering the full peer dependency issues tree during installation,
suggest users run "pnpm peers check" to view the issues. Remove the now-unused
@pnpm/installing.render-peer-issues package.
* chore: update all dependencies to latest versions
Update all outdated dependencies across the monorepo catalog and fix
breaking changes from major version bumps.
Notable updates:
- ESLint 9 → 10 (fix custom rule API, disable new no-useless-assignment)
- @stylistic/eslint-plugin 4 → 5 (auto-fixed indent changes)
- @cyclonedx/cyclonedx-library 9 → 10 (adapt to removed SPDX API)
- esbuild 0.25 → 0.27
- TypeScript 5.9.2 → 5.9.3
- Various @types packages, test utilities, and build tools
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update unified/remark/mdast imports for v11/v4 API changes
Update imports in get-release-text for the new ESM named exports:
- mdast-util-to-string: default → { toString }
- unified: default → { unified }
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: resolve typecheck errors from dependency updates
- isexe v4: use named import { sync } instead of default export
- remark-parse/remark-stringify v11: add vfile as packageExtension
dependency so TypeScript can resolve type declarations
- get-release-text: remove unused @ts-expect-error directives
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: revert runtime dependency major version bumps
Revert major version bumps for runtime dependencies that are bundled
into pnpm to fix test failures where pnpm add silently fails:
- bin-links: keep ^5.0.0 (was ^6.0.0)
- cli-truncate: keep ^4.0.0 (was ^5.2.0)
- delay: keep ^6.0.0 (was ^7.0.0)
- filenamify: keep ^6.0.0 (was ^7.0.1)
- find-up: keep ^7.0.0 (was ^8.0.0)
- isexe: keep 2.0.0 (was 4.0.0)
- normalize-newline: keep 4.1.0 (was 5.0.0)
- p-queue: keep ^8.1.0 (was ^9.1.0)
- ps-list: keep ^8.1.1 (was ^9.0.0)
- string-length: keep ^6.0.0 (was ^7.0.1)
- symlink-dir: keep ^7.0.0 (was ^9.0.0)
- terminal-link: keep ^4.0.0 (was ^5.0.0)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: restore runtime dependency major version bumps
Re-apply all runtime dependency major version bumps that were
previously reverted. All packages maintain their default exports
except isexe v4 which needs named imports.
Updated runtime deps:
- bin-links: ^5.0.0 → ^6.0.0
- cli-truncate: ^4.0.0 → ^5.2.0
- delay: ^6.0.0 → ^7.0.0
- filenamify: ^6.0.0 → ^7.0.1
- find-up: ^7.0.0 → ^8.0.0
- isexe: 2.0.0 → 4.0.0 (fix: use named import { sync })
- normalize-newline: 4.1.0 → 5.0.0
- p-queue: ^8.1.0 → ^9.1.0
- ps-list: ^8.1.1 → ^9.0.0
- string-length: ^6.0.0 → ^7.0.1
- symlink-dir: ^7.0.0 → ^9.0.0
- terminal-link: ^4.0.0 → ^5.0.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: revert tempy to 3.0.0 to fix bundle hang
tempy 3.2.0 pulls in temp-dir 3.0.0 which uses async fs.realpath()
inside its module init. When bundled by esbuild into the __esm lazy
init pattern, this causes a deadlock during module initialization,
making the pnpm binary hang silently on startup.
Keeping tempy at 3.0.0 which uses temp-dir 2.x (sync fs.realpathSync).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: add comment explaining why tempy cannot be upgraded
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: revert nock to 13.3.4 for node-fetch compatibility
nock 14 changed its HTTP interception mechanism in a way that doesn't
properly intercept node-fetch requests, causing audit tests to hang
waiting for responses that are never intercepted.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* docs: add comment explaining why nock cannot be upgraded
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: update symlink-dir imports for v10 ESM named exports
symlink-dir v10 removed the default export and switched to named
exports: { symlinkDir, symlinkDirSync }.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: revert @typescript/native-preview to working version
Newer tsgo dev builds (>= 20260318) have a regression where
@types/node cannot be resolved, breaking all node built-in types.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: vulnerabilities
* fix: align comment indentation in runLifecycleHook
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
* fix: pin msgpackr to 1.11.8 for TypeScript 5.9 compatibility
msgpackr 1.11.9 has broken type definitions that use Iterable/Iterator
without required type arguments, causing compile errors with TS 5.9.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add eslint-plugin-simple-import-sort to enforce consistent import ordering:
- Node.js builtins first
- External packages second
- Relative imports last
- Named imports sorted alphabetically within each statement
* test: use sha512 integrity in fixtures to fix ci break
* test: update snapshots for sha512 fixture change
* chore(deps): remove unneeded peer dependency exception
The `peerDependencyRules.allowedVersions` exception on
`@typescript-eslint/eslint-plugin` no longer seems to be necessary.
Removing it does not introduce any new peer dependency errors on
`pnpm install`.
I suspect this was needed for the
`eslint-config-standard-with-typescript` dependency in the past, but a
@typescript-eslint/eslint-plugin upgrade made it no longer necessary.
* chore(deps): update @typescript-eslint dependencies 5.62.0 -> 6.5.0
@typescript-eslint 6.5.0 is the first version to introduce support for
TypeScript 5.2.
https://github.com/typescript-eslint/typescript-eslint/releases/tag/v6.5.0
```
=============
WARNING: You are currently running a version of TypeScript which is not officially supported by @typescript-eslint/typescript-estree.
You may find that it works just fine, or you may not.
SUPPORTED TYPESCRIPT VERSIONS: >=3.3.1 <5.2.0
YOUR TYPESCRIPT VERSION: 5.2.2
Please only submit bug reports when using the officially supported version.
```
* chore(deps): update eslint-config-standard-with-typescript 37.0.0 -> 39.0.0
Version 38.0.0 is the first version to support @typescript-eslint v6.
https://github.com/standard/eslint-config-standard-with-typescript/releases/tag/v38.0.0
Otherwise the following error appears.
```
> eslint "src/**/*.ts" "test/**/*.ts" "--fix"
Oops! Something went wrong! :(
ESLint: 8.47.0
Error: ../../.eslintrc.json » @pnpm/eslint-config » eslint-config-standard-with-typescript:
Configuration for rule "@typescript-eslint/restrict-plus-operands" is invalid:
Value {"checkCompoundAssignments":true} should NOT have additional properties.
at ConfigValidator.validateRuleOptions (/Users/gluxon/Developer/pnpm/node_modules/.pnpm/@eslint+eslintrc@2.1.2/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2039:23)
at /Users/gluxon/Developer/pnpm/node_modules/.pnpm/@eslint+eslintrc@2.1.2/node_modules/@eslint/eslintrc/dist/eslintrc.cjs:2094:18
```
* chore: remove unnecessary disables for restrict-template-expressions
The `@typescript-eslint/restrict-template-expressions` rule relaxed
what types are allowed in template expressions.
c13ce0b4f7 (diff-b852e1e199d2976eee1183fc84ac12a5d42fc61f0ae4b1c290dd54d621546db0)
Many of these disables were for interpolated values that had an `any`
type.
* chore: remove unnecessary disables for restrict-plus-operands
The original error was:
```
Invalid operand for a '+' operation. Operands must each be a number or string. Got `any`. eslint@typescript-eslint/restrict-plus-operands
```
It look like the newer version now allows `any`.
* style: fix errors of prefer-optional-chain and prefer-nullish-coalescing
The `@typescript-eslint/prefer-optional-chain` and
`@typescript-eslint/prefer-nullish-coalescing` rules got a bit
smarter. This commit applies autofixes. I believe the changes should be
equivalent to what existed before.
Example of the new `@typescript-eslint/prefer-optional-chain` lints.
```
pnpm/pkg-manifest/exportable-manifest/src/index.ts
71:10 error Prefer using an optional chain expression instead, as it's more concise and easier to read @typescript-eslint/prefer-optional-chain
87:10 error Prefer using an optional chain expression instead, as it's more concise and easier to read @typescript-eslint/prefer-optional-chain
```
Example of the new `@typescript-eslint/prefer-nullish-coalescing` lints.
```
pnpm/fs/find-packages/src/index.ts
32:38 error Prefer using nullish coalescing operator (`??`) instead of a ternary expression, as it is simpler to read @typescript-eslint/prefer-nullish-coalescing
```
* chore(deps): update TypeScript 5.1.6 -> 5.2.2
* chore(deps): update @yarnpkg/core->@types/lodash override to 4.14.197
This fixes a compilation error that appears on TypeScript 5.2.2. This
error was fixed in a later version of `@types/lodash`.
https://github.com/DefinitelyTyped/DefinitelyTyped/pull/66123
```
../node_modules/.pnpm/@types+lodash@4.14.181/node_modules/@types/lodash/index.d.ts:45:15 - error TS2428: All declarations of 'WeakMap' must have identical type parameters.
45 interface WeakMap<K extends object, V> { }
~~~~~~~
Found 4 errors.
```