On Windows, temporaryDirectory() may return 8.3 short paths (e.g.,
RUNNER~1) but getBinNodePaths resolves via fs.realpath, returning long
paths (e.g., runneradmin). Use realpathSync to normalize expected paths.
Fixed "input line too long" error on Windows when running lifecycle scripts with the
global virtual store enabled. The `NODE_PATH` in command shims no longer includes all
paths from `Module._nodeModulePaths()`. Instead, it includes only the package's
bundled dependencies directory (e.g., `.pnpm/pkg@version/node_modules/pkg/node_modules`),
the package's sibling dependencies directory (e.g., `.pnpm/pkg@version/node_modules`),
and the hoisted `node_modules` directory. These paths are needed so that tools like
`import-local` (used by jest, eslint, etc.) which resolve from CWD can find the correct
dependency versions.
Revert the workaround that forced `pnpm self-update` to always install
the `pnpm` package for v11+. Since `@pnpm/exe` works again from
v11.0.0-alpha.7, `getCurrentPackageName()` now simply returns
`@pnpm/exe` when running as an executable, without platform-specific
package names.
* fix: respect peer dep range in hoistPeers when preferred versions exist
Previously, hoistPeers used semver.maxSatisfying(versions, '*') which
picked the highest preferred version from the lockfile regardless of the
peer dep range. This caused overrides that narrow a peer dep range to be
ignored when a stale version existed in the lockfile.
Now hoistPeers first tries semver.maxSatisfying(versions, range) to find
a preferred version that satisfies the actual peer dep range. If none
satisfies it and autoInstallPeers is enabled, it falls back to the range
itself so pnpm resolves a matching version from the registry.
* fix: only fall back to exact-version range for overrides, handle workspace: protocol
- When no preferred version satisfies the peer dep range, only use the
range directly if it is an exact version (e.g. "4.3.0" from an override).
For semver ranges (e.g. "1", "^2.0.0"), fall back to the old behavior
of picking the highest preferred version for deduplication.
- Guard against workspace: protocol ranges that would cause
semver.maxSatisfying to throw.
- Add unit tests for hoisting deduplication and workspace: ranges.
* fix: only apply range-constrained peer selection for exact versions
The previous approach used semver.maxSatisfying(versions, range) for all
peer dep ranges, which broke aliased-dependency deduplication — e.g. when
three aliases of @pnpm.e2e/peer-c existed at 1.0.0, 1.0.1, and 2.0.0,
range ^1.0.0 would pick 1.0.1 instead of 2.0.0.
Now the range-aware logic only activates when the range is an exact
version (semver.valid), which is the override case (e.g. "4.3.0").
Regular semver ranges fall back to picking the highest preferred version.
* fix(audit): fallback to quick audit endpoint
Fallback to /audits/quick when /audits fails with non-200, avoiding 5xx hard failures.
Close#10649
* refactor(audit): reuse request options for fallback
Share request options between primary and quick audit endpoints. Use POST for consistency.
* fix(audit): use quick audit endpoint as primary, full as fallback
---------
Co-authored-by: Zoltan Kochan <z@kochan.io>
Allow consumers (e.g. Bit CLI) to provide a nameFormatter callback that
reads the package manifest and returns a custom display name. The resolved
displayName is carried through the DependentsTree/DependentNode data model
and used by all render functions (tree, JSON, parseable).
- **`pnpm why` now shows a reverse dependency tree.** The searched package appears at the root with its dependants as branches, walking back to workspace roots. This replaces the previous forward-tree output which was noisy and hard to read for deeply nested dependencies.
- **Replaced `archy` with a new `@pnpm/text.tree-renderer` package** that renders trees using box-drawing characters (├──, └──, │) and supports grouped sections, dim connectors, and deduplication markers.
- **Show peer dependency hash suffixes** in `pnpm list` and `pnpm why` output to distinguish between different peer-dep variants of the same package.
- **Improved `pnpm list` visual output:** bold importer nodes, dimmed workspace paths, dependency grouping, package count summary, and deterministic sort order.
- **Added `--long` support to `pnpm why`** and the ability to read package manifests from the CAS store.
- **Deduplicated shared code** between `list` and `why` commands into a common module, and reused `getPkgInfo` in the why tree builder.
Instead of manually iterating over top-level dependencies, calling
getPkgInfo/getTreeNodeChildId/getTree per dependency, and handling
dedup/search logic in parallel with materializeChildren, delegate
entirely to a single getTree call with the importer as root.
The returned PackageNode[] are then post-categorized into their
dependency fields (dependencies, devDependencies, optionalDependencies)
using a fieldMap built from the lockfile importer snapshot.
This eliminates the duplicated dedup/search handling between
dependenciesHierarchyForPackage and materializeChildren, and removes
the GetTreeResult wrapper type from getTree (now returns PackageNode[]
directly). The materializeChildren cache is now the sole mechanism for
cross-importer deduplication.
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>