Commit Graph

10667 Commits

Author SHA1 Message Date
Zoltan Kochan
1b611b21aa chore(release): 11.0.0-alpha.8 v11.0.0-alpha.8 2026-02-23 04:21:05 +01:00
Zoltan Kochan
cb228c900c fix(link-bins): stop prepending redundant paths to NODE_PATH in command shims (#10673)
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.
2026-02-23 04:19:32 +01:00
Zoltan Kochan
1549743b36 revert: "chore: use standalone pnpm and bump packageManager to 11.0.0-alpha.7"
This reverts commit fd739d41fe.
2026-02-23 00:02:09 +01:00
Zoltan Kochan
fd739d41fe chore: use standalone pnpm and bump packageManager to 11.0.0-alpha.7
Switch CI workflows to use standalone pnpm installation and update
the packageManager field to match the latest alpha release.
2026-02-22 23:36:05 +01:00
Zoltan Kochan
8fc4e93435 fix(exe): use import.meta.dirname instead of process.cwd() in setup script
process.cwd() is not guaranteed to be the package directory when the
package manager runs lifecycle scripts. import.meta.dirname always
resolves to the directory containing setup.js itself.
2026-02-22 23:31:37 +01:00
Zoltan Kochan
8d882e1815 chore(release): 11.0.0-alpha.7 v11.0.0-alpha.7 2026-02-22 22:49:51 +01:00
Zoltan Kochan
336303a6f5 fix: resolve SEA import path relative to executable, not build-time path
The SEA binary recorded the CI build-time absolute path for pnpm.cjs,
causing `import('./dist/pnpm.mjs')` to resolve to a non-existent path
on the user's machine. Use process.execPath to resolve at runtime instead.
2026-02-22 22:49:08 +01:00
Zoltan Kochan
b450156a25 chore(release): 11.0.0-alpha.6 v11.0.0-alpha.6 2026-02-22 22:14:43 +01:00
Zoltan Kochan
54c4fc4fb4 fix: respect peer dep range in hoistPeers when preferred versions exist (#10655)
* 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.
2026-02-22 22:04:35 +01:00
Zoltan Kochan
23eb4a6141 refactor(env): unify node version specifier parsing into parseNodeSpecifier in node.resolver (#10668)
* refactor(env): unify node version specifier parsing into parseNodeSpecifier in node.resolver

Move parseNodeSpecifier from @pnpm/plugin-commands-env to @pnpm/node.resolver and
replace the simpler parseEnvSpecifier with an enhanced version that supports all
Node.js version specifier formats: standalone release channels (nightly, rc, test,
v8-canary, release), well-known aliases (lts, latest), LTS codenames (argon, iron),
semver ranges (18, ^18), and channel/version combos (rc/18, nightly/latest).

* fix(env): address parseNodeSpecifier review feedback

- Remove overly strict release/X.Y.Z-only validation; release/latest,
  release/lts, and release/<range> are now accepted
- Validate unknown release channels (e.g. foo/18) with a clear error
  instead of letting them fall through to a confusing network failure
- Add test cases for release/latest, release/lts, and release/18
2026-02-22 14:34:02 +01:00
Zoltan Kochan
895af70320 fix: update @zkochan/yaml to v0.0.11 2026-02-22 13:02:48 +01:00
Zoltan Kochan
f54347e415 feat: replace pkg with Node.js SEA for standalone executables (#10661)
* feat: switch from pkg to Node.js SEA for creating standalone executables

Replace @yao-pkg/pkg with Node.js native Single Executable Applications
(--build-sea, Node.js 25.5+). The SEA binary embeds only pnpm.cjs (CJS
bootstrap), while pnpm.mjs and all assets live in a dist/ directory
shipped alongside the binary in platform-specific tarballs.

* refactor: move dist/ from platform packages to @pnpm/exe

The dist/ directory (pnpm.mjs, worker.js, templates, etc.) is identical
across all platforms, so ship it once in @pnpm/exe instead of duplicating
it in each platform package. Platform packages now only contain the
binary. The self-updater installs @pnpm/exe (not the platform package)
so it gets both dist/ and the binary via optionalDependencies.

* refactor: externalize @reflink/reflink in esbuild bundle

Make @reflink/reflink external in both the main and worker esbuild
bundles so the require() calls resolve at runtime from dist/node_modules
instead of being inlined. Add @reflink/reflink as a production dependency
of both pnpm (bundled into dist/node_modules by bundle-deps.ts) and
@pnpm/exe (installed by npm alongside the binary).

For GitHub release tarballs, only the target platform's reflink package
is kept. For @pnpm/exe npm publishing, all reflink platform packages
are stripped from dist/ since npm installs the right one automatically.

* chore: update cspell list

* test: update system-node-version tests for SEA detection

Mock @pnpm/cli-meta's detectIfCurrentPkgIsExecutable instead of
setting process.pkg, which is no longer used for SEA detection.

* test: improve cli-meta test coverage for SEA migration

Add tests for detectIfCurrentPkgIsExecutable() (non-SEA path) and
isExecutedByCorepack() which were previously untested. The SEA=true
path of detectIfCurrentPkgIsExecutable() cannot be unit tested since
node:sea is unavailable in an ESM test environment.

* refactor: move GitHub tarball assembly to copy-artifacts.ts

build-artifacts.ts (prepublishOnly of @pnpm/exe) now only builds the
SEA executables and prepares the exe npm dist/. The per-target dist/
assembly for GitHub release tarballs moves to copy-artifacts.ts, which
is the natural owner of that concern.

Other changes:
- Extract getReflinkKeepPackages/stripReflinkPackages to reflink-utils.ts
  with tests using node:test
- Move --force from top-level pnpm install in release.yml to the pnpm
  deploy in bundle-deps.ts, where it is actually needed to install all
  @reflink/reflink-* platform packages into dist/node_modules
- Change @pnpm/exe prepublishOnly to run pnpm's full prepublishOnly
  (compile + bundle-deps) so dist/node_modules is populated before
  build-artifacts.ts and copy-artifacts.ts read from pnpm/dist

* fix: copy dist/ alongside binary when running pnpm setup for SEA

When the pnpm CLI is a Node.js SEA binary, it requires a dist/ directory
adjacent to the executable at runtime (containing pnpm.mjs and bundled
node_modules). The copyCli function in plugin-commands-setup now copies
dist/ from alongside the current binary into the tools directory so that
the installed pnpm works correctly after `pnpm setup`.


* fix: avoid argument list too long when creating Windows zip archives


* fix: propagate errors in copy-artifacts script

Previously errors in createArtifactTarball were swallowed, causing the
script to exit 0 even when artifact creation failed. Now errors are
re-thrown with a descriptive message, and the top-level IIFE has a
.catch() handler that sets a non-zero exit code.


* refactor: remove reflink-utils.ts from @pnpm/exe

The stripReflinkPackages call in build-artifacts.ts stripped all platform
packages while keeping @reflink/reflink. Instead, just remove the entire
@reflink directory from dist/ — @pnpm/exe already declares @reflink/reflink
as a runtime dependency, so npm installs it (along with the right platform
package via optionalDependencies) automatically.

This eliminates reflink-utils.ts, its tests, and the code duplication with
copy-artifacts.ts.
2026-02-22 12:45:50 +01:00
Zoltan Kochan
50fbecae7d refactor(env): pnpm env use now delegates to pnpm add --global (#10666)
This PR overhauls `pnpm env` use to route through pnpm's own install machinery instead of maintaining a parallel code path with manual symlink/shim/hardlink logic.

```
pnpm env use -g <version>
```

now runs:

```
pnpm add --global node@runtime:<version>
```

via `@pnpm/exec.pnpm-cli-runner`. All manual symlink, hardlink, and cmd-shim code in `envUse.ts` is gone (~1000 lines removed across the package).

### Changes

**npm and npx shims on all platforms**

Added `getNodeBinsForCurrentOS(platform)` to `@pnpm/constants`, returning a `Record<string, string>` with the correct relative paths for `node`, `npm`, and `npx` inside a Node.js distribution. `BinaryResolution.bin` is widened from `string` to `string | Record<string, string>` in `@pnpm/resolver-base` and `@pnpm/lockfile.types`, so the node resolver can set all three entries and pnpm's bin-linker creates shims for each automatically.

**Windows npm/npx fix**

`addFilesFromDir` was skipping root-level `node_modules/` (to avoid storing a package's own dependencies), which stripped the bundled `npm` from Node.js Windows zip archives. Added an `includeNodeModules` option and enabled it from the binary fetcher so Windows distributions keep their full contents.

**Removed subcommands**

`pnpm env add` and `pnpm env remove` are removed. `pnpm env use` handles both installing and activating a version. `pnpm env list` now always lists remote versions (the `--remote` flag is no longer required, though it is kept for backwards compatibility).

**musl support**

On Alpine Linux and other musl-based systems, the musl variant of Node.js is automatically downloaded from [unofficial-builds.nodejs.org](https://unofficial-builds.nodejs.org).
2026-02-22 12:06:34 +01:00
Zoltan Kochan
9065f491f0 feat: add musl support to node runtime (#10664)
The lockfile now includes musl Linux builds (sourced from
unofficial-builds.nodejs.org) alongside the standard glibc variants,
so that `node@runtime:` works out of the box on Alpine Linux and other
musl-based distributions.

`env use` can download node.js artifacts for systems that use musl.
2026-02-21 21:29:05 +01:00
Jason Paulos
8b4a811fd6 test: fix several flaky tests in pkg-manager (#10644)
* test: fix flaky tests & add retries for failed tests during CI testing

* fix: import jest in setupFilesAfterEnv & reduce retries to 2

* test: remove global retries
2026-02-20 23:35:45 +01:00
Zoltan Kochan
ad07a4c203 ci: consolidate test scope logic into a single step
Replaces separate conditional steps with a unified "Determine test scope"
step that selects the test script and a descriptive label. The step name
now shows the scope (all, all — pnpm-workspace.yaml modified, or
affected packages) in the GitHub Actions UI.
2026-02-20 14:28:35 +01:00
Zoltan Kochan
6598867040 ci: run all tests if pnpm-workspace.yaml changes (#10659) 2026-02-20 14:15:36 +01:00
Zoltan Kochan
03c502c1a0 fix: detect overrides and other lockfile-affecting setting changes in optimisticRepeatInstall (#10654)
* fix: detect overrides and other lockfile-affecting setting changes in optimisticRepeatInstall

When optimisticRepeatInstall was enabled, changing overrides,
packageExtensions, ignoredOptionalDependencies, patchedDependencies,
or peersSuffixMaxLength would not trigger a reinstall because these
settings were not tracked in the workspace state file.

* refactor: extract WORKSPACE_STATE_SETTING_KEYS to prevent type/runtime drift

The settings key list in createWorkspaceState's pick() call must stay
in sync with the WorkspaceStateSettings type. Extract a shared const
array so both the type and runtime pick are derived from a single
source, preventing the class of bug fixed in the previous commit.
2026-02-20 14:00:25 +01:00
Zoltan Kochan
7f979f5fdc revert: "fix: update minimatch (#10657)"
This reverts commit 3fa7477af5.
2026-02-20 13:40:54 +01:00
btea
3fa7477af5 fix: update minimatch (#10657) 2026-02-20 13:21:45 +01:00
Zoltan Kochan
98d4485145 test: fix running tests on branch 2026-02-20 13:19:56 +01:00
Zoltan Kochan
e562c42439 chore: update @rushstack/worker-pool 2026-02-20 13:17:08 +01:00
Zoltan Kochan
6d900bf798 chore: update commitlint dependencies 2026-02-20 09:00:17 +01:00
mitchell amihod
a969839845 fix(audit): help text for --ignore-registry-errors was missing a "not" (#10656)
Signed-off-by: meeech <4623+meeech@users.noreply.github.com>
2026-02-20 01:21:18 +01:00
Carey Janecka
315cae83f8 fix(audit): fallback to quick audit endpoint (#10652)
* 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>
2026-02-20 00:53:01 +01:00
Zoltan Kochan
e18a879d72 feat!: drop Node.js 22.12 support 2026-02-18 14:54:09 +01:00
Zoltan Kochan
1d6a0c98f8 fix: ignore unrelevant vulnerability 2026-02-18 14:54:09 +01:00
Zoltan Kochan
59d92ca58f chore: update pnpm-lock.yaml 2026-02-18 14:54:09 +01:00
Zoltan Kochan
fd0cc63964 ci(benchmark): fix reported pnpm version 2026-02-17 15:35:30 +01:00
Zoltan Kochan
01d5de08e9 fix(benchmarks): fall back to pnpm.cjs when pnpm.mjs is not present 2026-02-17 15:03:13 +01:00
Zoltan Kochan
ede26ac773 chore: update pnpm to v11 alpha 5 2026-02-17 14:55:43 +01:00
Zoltan Kochan
ea81d07cc8 chore(release): 11.0.0-alpha.5 v11.0.0-alpha.5 2026-02-17 14:48:13 +01:00
Zoltan Kochan
7db6629485 fix: retry existence check in global virtual store race condition handler (#10636)
When 3+ threads/processes concurrently import the same package to the
global virtual store, a third party can rimraf the target between another
thread's failed rename and its existence check. Retry the check up to 4
times with 50ms delays to let the competing operation complete.
2026-02-17 14:46:43 +01:00
Zoltan Kochan
05710b0496 fix: show warning instead of crashing when running on Node.js 20 (#10637) 2026-02-17 14:40:28 +01:00
Zoltan Kochan
d8f3fe0ccf ci: downgrade pnpm to v11 alpha 3 2026-02-17 13:41:30 +01:00
Zoltan Kochan
9cdc94794c chore: update pnpm to v11 alpha 4 2026-02-17 13:19:22 +01:00
Zoltan Kochan
e6c835cc1e chore: update tsgo v11.0.0-alpha.4 2026-02-17 12:58:43 +01:00
Zoltan Kochan
8c4450d064 chore(release): 11.0.0-alpha.4 2026-02-17 12:34:44 +01:00
Zoltan Kochan
d0c6f59285 docs: fix changeset 2026-02-17 12:09:50 +01:00
Zoltan Kochan
56a59df674 perf: persist bundled manifest in store index to avoid reading package.json from CAFS (#10473)
close #10461
2026-02-17 12:03:08 +01:00
Zoltan Kochan
3846366bb0 ci: add job for running benchmarks 2026-02-17 01:47:00 +01:00
Zoltan Kochan
9ae2e03450 chore: add benchmark script for comparing install performance against main (#10632) 2026-02-16 23:55:53 +01:00
Zoltan Kochan
7116f35027 feat: add nameFormatter option to buildDependentsTree for custom display names (#10629)
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).
2026-02-15 22:25:41 +01:00
Zoltan Kochan
892b985db2 feat: add --depth option to pnpm why to limit display depth (#10627) 2026-02-15 22:25:41 +01:00
Zoltan Kochan
cc7da5dc95 refactor: re-export dependents rendering functions from reviewing/list
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-15 22:25:40 +01:00
Brandon Cheng
0e9c559068 fix: remove misleading maxAge argument to pMemoize (#10620) 2026-02-15 22:07:29 +01:00
Zoltan Kochan
7d5ada0701 feat: reverse pnpm why tree and improve list/why output (#10615)
- **`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.
2026-02-15 14:38:43 +01:00
Brandon Cheng
5ff0e16864 build: rework bundled dist/node_modules (#10508)
* build: bundle `dist/node_modules` using pnpm deploy

* chore: remove copied `pnpm.overrides` for publish-packed

* chore: remove `catalog:` protocol ban in `pnpm/package.json`

* chore: remove `publish-packed` dependency

* build: move `node-gyp` from `optionalDependencies` to `dependencies`

The `node-gyp` dependency is bundled into the `pnpm` package before it's
published. The dependency declaration itself is then removed from the
published package manifest.

This means there's not a point to declaring `node-gyp` as an optional
dependency. It'll always be bundled and the published manifest doesn't
contain the dependency declaration.

https://github.com/pnpm/pnpm/pull/10508#discussion_r2782257620

* build: throw if peerDependencies or optionalDependencies are declared

* build: use meta-updater instead of Jest test for dep kind check
2026-02-14 22:36:27 +01:00
Zoltan Kochan
a7cca3f361 docs(AGENTS): add code reuse and function argument guidelines 2026-02-14 20:44:30 +01:00
Zoltan Kochan
491813fc14 refactor: simplify dependenciesHierarchyForPackage by delegating to getTree (#10616)
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>
2026-02-13 22:08:36 +01:00