pnpm 12.0.0-beta.4 → 12.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,97 @@
1
1
  # pnpm
2
2
 
3
+ ## 12.0.0-rc.1
4
+
5
+ ### Major Changes
6
+
7
+ - Git dependencies on known hosts (GitHub, GitLab, Bitbucket) are now treated as identities rather than transport choices. Every representation of the same repository — `github:owner/repo`, `owner/repo`, `git+https://…`, `git+ssh://git@…` — resolves through the host's canonical HTTPS URL, and the lockfile never records an SSH URL for them. Repositories whose archive endpoint is anonymously reachable resolve to the host's archive (fast tarball download); all others resolve to a `git` clone of the canonical HTTPS URL, which every machine with access to the repository can fetch.
8
+
9
+ To reach a private hosted repository over SSH, configure the machine (not the project) with git's own URL rewriting, for example:
10
+
11
+ ```sh
12
+ git config --global url."git@github.com:".insteadOf https://github.com/
13
+ ```
14
+
15
+ pnpm shells out to `git`, so the rewrite applies to all of pnpm's git operations automatically. URLs of unknown hosts (self-hosted servers) are unaffected and keep their exact URL, including SSH. URLs with embedded credentials are also kept verbatim and never resolve to a host archive.
16
+
17
+ This removes the network probing that previously decided between HTTPS and SSH at resolution time, which could record a transport that only worked on the machine that happened to run the resolution (e.g. an SSH URL that broke CI runners without SSH keys).
18
+
19
+ ### Minor Changes
20
+
21
+ - Added interactive group selection to `pnpm update --global --interactive`.
22
+
23
+ - `pnpm root -g` and `pnpm bin -g` now print warnings to stderr instead of stdout, so their stdout stays a clean, machine-readable path. Previously, running either command with `--global` in a project that pins a package manager (e.g. via the `packageManager` field) printed a warning like `[WARN] Using --global skips the package manager check for this project` ahead of the path, breaking programs that capture the output as a path [#13672](https://github.com/pnpm/pnpm/issues/13672).
24
+
25
+ In pnpm 12, `pnpm root -g` and `pnpm prefix -g` are now supported (they previously failed with `ERR_PNPM_CLI_ROOT_GLOBAL_UNSUPPORTED` / `ERR_PNPM_CLI_PREFIX_GLOBAL_UNSUPPORTED`), and the reporter output of `dlx`, `create`, `config`, `sbom`, `with`, `store`, `prefix`, `root`, and `bin` goes to stderr, matching pnpm 11.
26
+
27
+ ### Patch Changes
28
+
29
+ - Fixed `minimumReleaseAge` fallback for custom dist-tags so the selected version does not exceed the registry’s original tag target.
30
+
31
+ - Removing a dependency from `package.json` and reinstalling no longer re-resolves the dependency graph. The importer's entry is dropped from `pnpm-lock.yaml`, anything it made unreachable is pruned, and a catalog entry that loses its last referent is removed — all without registry access. Installs still fall back to a full resolution when a package that stays resolves a peer dependency through the removed one, since that would change the surviving package's entry rather than only prune.
32
+
33
+ - Dependencies declared with an empty version range (`"adler-32": ""`) install again instead of failing with `ERR_PNPM_NO_MATCHING_VERSION` [#13673](https://github.com/pnpm/pnpm/issues/13673). An omitted range means "any version", as it does in npm and pnpm v11, so packages that publish one — such as `js-xlsx`, `codepage`, and `ssf` — no longer need an `overrides` entry to install.
34
+
35
+ - Changing a catalog entry to a different exact version no longer re-resolves the dependency graph. The package is replaced in `pnpm-lock.yaml` directly, reusing the same check the `pnpm.overrides` fast path applies: every locked dependency of the package must still satisfy the new version's manifest. Installs fall back to a full resolution when anything other than the catalog reaches the package — an importer that depends on it directly, or another package that depends on it — since the graph would then need both versions.
36
+
37
+ - Fixed installs under `enableGlobalVirtualStore` failing with `failed to remove existing directory ... prior to swap: Directory not empty` (or `No such file or directory`) when peer variants of an injected `file:` dependency hash to the same slot. The link pass now materializes each unique slot directory once instead of racing one force-mode import per peer variant against the same path.
38
+
39
+ - The held-back-update warning printed by `pnpm update` no longer fires when `minimumReleaseAge` is the actual reason a newer version was not picked. The warning's baseline now applies the same maturity cutoff as the pick itself, so it no longer wrongly attributes the hold-back to "your manifests and already installed dependencies" or recommends an override that would defeat the age gate. See pnpm/pnpm#13071.
40
+
41
+ - Changing `autoInstallPeers`, `dedupePeers`, `peersSuffixMaxLength`, `excludeLinksFromLockfile`, or `injectWorkspacePackages` no longer re-resolves the dependency graph when the lockfile proves the setting cannot affect it: no package or project declares a peer dependency for the peer settings, and no project depends on a directory or on another workspace project for the link and injection settings. The new setting is recorded in `pnpm-lock.yaml` and the install proceeds from the existing resolution. Every other case still falls back to a full resolution.
42
+
43
+ - Adding, editing, or removing an entry in `patchedDependencies` no longer re-resolves the dependency graph. Resolution never reads a patch — it only records the patch file's hash against the package it matches — so the install now rewrites the affected entries in `pnpm-lock.yaml` and materializes the patched package from the store instead. Installs still fall back to a full resolution when the patched package is reachable as a peer dependency, and when the new configuration would leave a patch unused while `allowUnusedPatches` is off, so `ERR_PNPM_UNUSED_PATCH` is still reported.
44
+
45
+ - `pnpm install` again records immature versions picked under `minimumReleaseAge` (when `minimumReleaseAgeStrict` is off) in `minimumReleaseAgeExclude` in `pnpm-workspace.yaml`, so a later frozen install of the same lockfile passes verification [#13687](https://github.com/pnpm/pnpm/issues/13687).
46
+
47
+ - Reduced peak install memory: cached registry metadata is now read on demand from the on-disk metadata cache instead of being held in memory for the whole resolution. Resolving a large peer-heavy graph (`@teambit/bit`) peaks at about 1.3 GB instead of 3.2 GB, and a full cold install of it stays under 2 GB [#13681](https://github.com/pnpm/pnpm/issues/13681).
48
+
49
+ - Lockfile verification now honors offline mode by using cached registry metadata instead of reaching the registry. When the required metadata is not available locally, verification reports the same `ERR_PNPM_NO_OFFLINE_META` condition used by offline resolution.
50
+
51
+ - POSIX shell shims now follow symbolic links before computing `basedir`, preventing execution failures when a shim is invoked via an external symlink on `PATH` [#13405](https://github.com/pnpm/pnpm/issues/13405).
52
+
53
+ - Speed up installs after adding `ignoredOptionalDependencies` patterns by removing newly ignored optional dependencies and pruning packages that are no longer reachable without resolving the dependency graph again.
54
+
55
+ - `pnpm self-update` no longer fails with `the installed pnpm wrapper is missing` when the global packages directory carries a `pnpm-workspace.yaml` of global settings (written there when a global install persists an `allowBuilds` decision). The engine install stays anchored to its own install directory instead of walking up and adopting that file as its workspace root. The `pnpm dlx` cache install gets the same anchoring, so a stray `pnpm-workspace.yaml` above the cache directory can no longer break it [#13697](https://github.com/pnpm/pnpm/issues/13697).
56
+
57
+ - Reduced peak memory usage and allocation churn during peer dependency resolution on workspaces with many peer-dependency issue occurrences [#13681](https://github.com/pnpm/pnpm/issues/13681).
58
+
59
+ - `pnpm update` without saving no longer records a version that the manifest's range excludes. The kept range stays authoritative: a requested version outside it is skipped with a warning, and a requested range, a dist tag, or `--latest` resolves within it instead of past it. Previously each of these could write a lockfile entry that contradicted its own specifier, which the next `pnpm install --frozen-lockfile` rejected with `ERR_PNPM_OUTDATED_LOCKFILE` [#12764](https://github.com/pnpm/pnpm/issues/12764).
60
+
61
+ - `pnpm version -r --json` now outputs `[]` instead of human-readable text when no pending changes exist [`pnpm/pnpm#13217`](https://github.com/pnpm/pnpm/issues/13217).
62
+
63
+ - On Windows, installation no longer fails with "A required privilege is not held by the client. (os error 1314)" when symlink creation requires elevation (e.g. Developer Mode is off) — pnpm now falls back to NTFS junctions in that case. Additionally, `pnpm clean` and `pnpm deploy --force` no longer fail with "Access is denied. (os error 5)" when removing the package links inside `node_modules` [#13694](https://github.com/pnpm/pnpm/issues/13694).
64
+
65
+ ## 12.0.0-rc.0
66
+
67
+ ### Minor Changes
68
+
69
+ - Running `pnpm setup`, `pnpm self-update`, or a command that modifies the global installation (such as `pnpm add --global`) through `sudo` now fails with `ERR_PNPM_SUDO_NOT_SUPPORTED` instead of silently operating on the root user's home directory. pnpm keeps global packages and configuration in the invoking user's home directory, so these commands never need root permissions. Read-only global commands (such as `pnpm bin --global`) still work under sudo.
70
+
71
+ ### Patch Changes
72
+
73
+ - Archive entries whose paths use `\` as a separator are now read the same way pnpm reads them. A nested path spelled `bin\tool.js` by Windows publishing tooling resolves to `bin/tool.js`, and a path traversal spelled with backslashes is rejected instead of being stored verbatim.
74
+
75
+ - Fixed `file:` dependencies not being re-copied when their source directory changed. A `file:` dependency is copied into the store at install time rather than symlinked, so editing the local package's files and running `pnpm install` again left the previous copy in place — the lockfile is unchanged by such an edit, so the install treated the tree as up to date.
76
+
77
+ - Write blocked-build approval scaffolding to the discovered workspace manifest when using per-project lockfiles.
78
+
79
+ - Concurrent installs sharing a global virtual store no longer fail with `failed to remove existing directory ... prior to swap: Directory not empty`, and no longer briefly remove a package directory another process is reading.
80
+
81
+ - Fixed `link:` dependencies under `enableGlobalVirtualStore` so linked children are materialized and slots remain isolated by their resolved link targets.
82
+
83
+ - A headless install (`--frozen-lockfile`) now creates the command shims for a publicly hoisted workspace package's `bin`, matching what a normal install already did and what pnpm's own headless install does. Previously those shims were missing until the next non-frozen install.
84
+
85
+ - `pnpm fetch`, and any install run with `virtualStoreOnly`, no longer writes a `.pnp.cjs` loader under `nodeLinker: pnp`. These installs populate the virtual store without linking the project, so the loader would have claimed the project resolves out of a store it was never linked into. The importer links and `node_modules/.package-map.json` were already skipped; the PnP loader now follows the same rule.
86
+
87
+ - Prevent pnpm from removing project files when `modulesDir` resolves to the project root.
88
+
89
+ - Fixed `pnpm install` ignoring a `pnpm-lock.yaml` that carries a leading env lockfile document when the file has CRLF line endings or a UTF-8 byte order mark, as a `core.autocrlf` checkout on Windows produces. The lockfile was reported as broken with `multiple YAML documents detected` and every dependency was re-resolved from the registry [#13606](https://github.com/pnpm/pnpm/issues/13606).
90
+
91
+ - When no directory above the project accepts a hard link — inside an AI agent sandbox that only grants write access to the project, or a container with just the project mounted writable — the default store is now created at `<project>/node_modules/.pnpm-store` instead of in the pnpm home directory. In those environments the home store is either read-only or on another volume, which forces every package to be copied instead of hard linked [#13525](https://github.com/pnpm/pnpm/issues/13525).
92
+
93
+ - A stray non-directory entry in `node_modules` no longer fails an install. Files placed next to the installed dependencies are skipped rather than reported as an unreadable manifest.
94
+
3
95
  ## 12.0.0-beta.4
4
96
 
5
97
  ### Minor Changes
@@ -1,9 +1,9 @@
1
1
  {
2
- "lastValidatedTimestamp": 1785765243753,
2
+ "lastValidatedTimestamp": 1786112368832,
3
3
  "projects": {
4
4
  "/home/runner/_work/pnpm/pnpm/pnpm/npm/pnpm/temp-deploy": {
5
5
  "name": "pacquet",
6
- "version": "12.0.0-beta.4"
6
+ "version": "12.0.0-rc.1"
7
7
  }
8
8
  },
9
9
  "pnpmfiles": [],
@@ -77,7 +77,7 @@
77
77
  "@types/qrcode-terminal": "^0.12.2",
78
78
  "@types/ramda": "0.32.0",
79
79
  "@types/retry": "^0.12.5",
80
- "@types/semver": "7.7.1",
80
+ "@types/semver": "7.8.0",
81
81
  "@types/ssri": "^7.1.5",
82
82
  "@types/tar-stream": "^3.1.4",
83
83
  "@types/touch": "^3.1.5",
@@ -86,14 +86,14 @@
86
86
  "@types/write-file-atomic": "^4.0.3",
87
87
  "@types/yarnpkg__lockfile": "^1.1.9",
88
88
  "@types/zkochan__table": "npm:@types/table@6.3.2",
89
- "@typescript-eslint/utils": "^8.65.0",
89
+ "@typescript-eslint/utils": "^8.66.0",
90
90
  "@typescript/native-preview": "7.0.0-dev.20260707.2",
91
91
  "@yarnpkg/core": "4.9.1",
92
92
  "@yarnpkg/extensions": "2.0.7",
93
93
  "@yarnpkg/lockfile": "^1.1.0",
94
94
  "@yarnpkg/nm": "4.1.1",
95
95
  "@yarnpkg/pnp": "^4.1.7",
96
- "@zkochan/cmd-shim": "^9.0.6",
96
+ "@zkochan/cmd-shim": "^9.0.7",
97
97
  "@zkochan/retry": "^0.2.0",
98
98
  "@zkochan/rimraf": "^4.0.0",
99
99
  "@zkochan/table": "^2.0.1",
@@ -145,7 +145,6 @@
145
145
  "get-port": "^7.2.0",
146
146
  "ghooks": "2.0.4",
147
147
  "graceful-fs": "^4.2.11",
148
- "graceful-git": "^5.0.0",
149
148
  "graph-cycles": "3.0.0",
150
149
  "hosted-git-info": "npm:@pnpm/hosted-git-info@1.0.0",
151
150
  "https-proxy-server-express": "0.1.2",
@@ -248,7 +247,7 @@
248
247
  "tree-kill": "^1.2.2",
249
248
  "ts-jest-resolver": "2.0.1",
250
249
  "typescript": "6.0.3",
251
- "typescript-eslint": "^8.65.0",
250
+ "typescript-eslint": "^8.66.0",
252
251
  "undici": "^7.27.2",
253
252
  "unified": "^11.0.5",
254
253
  "validate-npm-package-name": "7.0.2",
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "./dist/node_modules/node-gyp/gyp/gyp"
10
10
  ]
11
11
  },
12
- "version": "12.0.0-beta.4",
12
+ "version": "12.0.0-rc.1",
13
13
  "description": "Fast, disk space efficient package manager",
14
14
  "keywords": [
15
15
  "pnpm",
@@ -43,14 +43,14 @@
43
43
  "dist/"
44
44
  ],
45
45
  "optionalDependencies": {
46
- "@pnpm/exe.win32-x64": "12.0.0-beta.4",
47
- "@pnpm/exe.win32-arm64": "12.0.0-beta.4",
48
- "@pnpm/exe.darwin-x64": "12.0.0-beta.4",
49
- "@pnpm/exe.darwin-arm64": "12.0.0-beta.4",
50
- "@pnpm/exe.linux-x64": "12.0.0-beta.4",
51
- "@pnpm/exe.linux-arm64": "12.0.0-beta.4",
52
- "@pnpm/exe.linux-x64-musl": "12.0.0-beta.4",
53
- "@pnpm/exe.linux-arm64-musl": "12.0.0-beta.4"
46
+ "@pnpm/exe.win32-x64": "12.0.0-rc.1",
47
+ "@pnpm/exe.win32-arm64": "12.0.0-rc.1",
48
+ "@pnpm/exe.darwin-x64": "12.0.0-rc.1",
49
+ "@pnpm/exe.darwin-arm64": "12.0.0-rc.1",
50
+ "@pnpm/exe.linux-x64": "12.0.0-rc.1",
51
+ "@pnpm/exe.linux-arm64": "12.0.0-rc.1",
52
+ "@pnpm/exe.linux-x64-musl": "12.0.0-rc.1",
53
+ "@pnpm/exe.linux-arm64-musl": "12.0.0-rc.1"
54
54
  },
55
55
  "scripts": {
56
56
  "preinstall": "node install.js",