feat: add pnpm peers check command#11061
Conversation
There was a problem hiding this comment.
Pull request overview
This PR introduces a new pnpm peers command (defaulting to pnpm peers check) to detect unmet/missing peer dependency issues by analyzing existing lockfile data (without forcing a full resolution), with support for --json and --recursive.
Changes:
- Registers a new
peersinspection command in the pnpm CLI and adds apeers checksubcommand implementation. - Adds a new
@pnpm/deps.inspection.peers-checkerpackage that reads lockfiles and reports peer dependency issues, with unit tests + fixtures. - Wires new workspace dependencies (including
render-peer-issues) and adds a Changeset entry for release notes.
Reviewed changes
Copilot reviewed 14 out of 17 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm/src/cmd/index.ts | Registers the new peers command in the pnpm CLI command list. |
| deps/inspection/commands/src/peers.ts | Implements pnpm peers check (human + JSON output, recursive support). |
| deps/inspection/commands/src/index.ts | Exports the new peers command namespace from inspection commands. |
| deps/inspection/commands/package.json | Adds dependencies required for the new command (peers-checker, render-peer-issues). |
| deps/inspection/commands/tsconfig.json | Adds TS project references for new dependencies used by the command. |
| deps/inspection/peers-checker/src/checkPeerDependencies.ts | Core lockfile-walking and peer issue detection/filtering logic. |
| deps/inspection/peers-checker/src/index.ts | Public entrypoint export for the peers-checker package. |
| deps/inspection/peers-checker/package.json | New package metadata/scripts/deps for peers-checker. |
| deps/inspection/peers-checker/tsconfig*.json | New TS configs for building/linting the peers-checker package. |
| deps/inspection/peers-checker/test/checkPeerDependencies.test.ts | Unit tests for peer issue detection + rule filtering basics. |
| deps/inspection/peers-checker/test/fixtures/** | Fixture lockfiles/manifests for test scenarios (unmet/missing/etc.). |
| pnpm-lock.yaml | Adds workspace links for the new package and new internal dependencies. |
| .changeset/list-check-peers.md | Declares minor bumps and release note for pnpm peers check. |
Files not reviewed (3)
- deps/inspection/peers-checker/test/fixtures/with-missing-peer/pnpm-lock.yaml: Language not supported
- deps/inspection/peers-checker/test/fixtures/with-unmet-peers/pnpm-lock.yaml: Language not supported
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
e77eb73 to
e95948f
Compare
Adds a `--check-peers` flag to `pnpm list` that detects unmet and missing peer dependency issues by reading the lockfile. This allows users to check for peer dependency problems without triggering a full resolution, which is especially useful in CI or after pulling a lockfile from another developer. Closes #7087 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Introduces `pnpm peers check` as a standalone subcommand instead of a flag on `pnpm list`. The command checks for unmet and missing peer dependency issues by reading the lockfile and exits with a non-zero exit code when issues are found. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Running `pnpm peers` without a subcommand now defaults to `check`. Unknown subcommands show help and exit with a non-zero exit code. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ers-checker Move peer dependency checking logic from @pnpm/deps.inspection.list into a dedicated @pnpm/deps.inspection.peers-checker package. This better separates concerns — the list package is for listing dependencies, not checking peer issues. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
These fixtures belong in the peers-checker package now. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use semver-range-intersect for proper intersection/conflict detection instead of picking the first range for missing peers - Remove silent error swallowing in parseOverrides — invalid peerDependencyRules.allowedVersions now surfaces the error - Support parent-scoped allowedVersions selectors (e.g. parent>peer) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Also add recursiveByDefault to list, ll, and why commands. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
e95948f to
f23596e
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 14 out of 17 changed files in this pull request and generated 4 comments.
Files not reviewed (3)
- deps/inspection/peers-checker/test/fixtures/with-missing-peer/pnpm-lock.yaml: Language not supported
- deps/inspection/peers-checker/test/fixtures/with-unmet-peers/pnpm-lock.yaml: Language not supported
- pnpm-lock.yaml: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Check only the declaring parent (last in parents chain) for parent-scoped allowedVersions, matching install-time behavior - Wrap parseOverrides errors with INVALID_ALLOWED_VERSION_SELECTOR code and mention pnpm.peerDependencyRules.allowedVersions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Show peer issues grouped by the peer dependency (like pnpm why) instead of grouped by the depending package. This makes it easier to see at a glance which peers need attention and all the packages requesting them. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Build a proper nested tree from parent chains instead of flat strings, so shared prefixes are merged and each package appears only once. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each peer dependency gets its own top-level tree separated by blank lines, similar to how pnpm why groups results by searched package. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Replace tree rendering with a simple flat list grouped by peer name. Each peer issue shows a header line and a "Required by:" line listing the parent chains. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
For readability, each package requiring the peer gets its own indented line. Transitive chains show the declaring package with a "(via ...)" note indicating the direct dependency that pulls it in. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Each requester line now shows the specific range it wants, which is more useful than showing the transitive dependency chain. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Packages requiring the same range are listed together on one line, making it easy to see which groups of packages share a requirement. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Blank lines between peer groups - Each package on its own indented line - When all packages want the same range, skip the "Wants" label - When multiple ranges exist, group under "Wants <range>:" headers Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Peer name bold white, issue type yellow/red (already there) - Range headers in cyan - Package names dimmed to keep focus on the peer and range Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Missing peers with incompatible ranges (conflicts) are now shown as "✕ conflicting peer" with the per-range grouping making the conflict visible. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When all packages want the same range, include it in the header line (e.g. "✕ missing peer ajv@^6.9.1") instead of only listing packages. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Always use the "Wants <range>:" format with indented packages, regardless of how many range groups there are. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Use "Installed: <version>" as a parallel label to "Wants <range>:" for better readability of unmet peer issues. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Group all ranges under a single "Wanted:" label, with each range on its own line and packages indented below it. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
950d716 to
58e07ae
Compare
Replace the custom walkDependency function with the existing lockfileWalkerGroupImporterSteps from @pnpm/lockfile.walker, which already handles dep resolution, visited tracking, and link handling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Just wondering if there's any chance this would make it into a 10.x release? or is it only targeted for 11? thanks :) |
Summary
Adds a
pnpm peers checkcommand that detects unmet, missing, and conflicting peer dependency issues by reading the lockfile. No full resolution needed — it walks the lockfile directly using@pnpm/lockfile.walker.@pnpm/deps.inspection.peers-checker— lockfile-based peer dependency checkerpnpm peers check(also runs as default forpnpm peers)recursiveByDefault)peerDependencyRules(ignoreMissing, allowAny, allowedVersions with parent-scoped selectors)--jsonfor CI/automation--lockfile-onlyto skip reading node_modulesExample output
Closes #7087
Test plan
checkPeerDependenciesfunction (6 tests, all passing)--jsonoutput format--helpshows the new command🤖 Generated with Claude Code