* chore(release): 11.28.7, pacquet 12.15.0, pnpr 0.1.0-alpha.16
* docs(release): curate 11.28.7, pacquet 12.15.0, and pnpr 0.1.0-alpha.16 release notes
Add lead paragraphs and group the patch entries by what the reader was
doing, with security fixes first on each page.
- v11: lead with the registry metadata name check, pinned pnpm
trustPolicy check, maxTarballUnpackedSize, and the removal of registry
revisions; merge overlapping entries for minimumReleaseAge metadata
revalidation, frozen-lockfile directory dependency checks,
syncInjectedDepsAfterScripts, verifyDepsBeforeRun, pnpm sbom, and
unreadable config settings.
- v12: order minor highlights from config includes and
lockfile.integrityTarget down to interactive update styling; drop the
pnpr-only distribution note from the CLI changelog; merge overlapping
entries for workspace and pnpr install speedups, minimumReleaseAge and
If-Modified-Since revalidation, frozen-lockfile and injected package
checks, verifyDepsBeforeRun, pnpm prune, pnpm pack, pnpm licenses
list, pnpm self-update, pinned pnpm flag forwarding, and WebContainer
fixes.
- pnpr: lead the minor section with the breaking ecosystem URL prefix,
hosted storage layout, artifacts.orgs, and strict config schema
changes; fold dist.pnpr tarball metadata into one entry and drop the
redundant /metrics note; lead the patch section with reserved-username
and auth security fixes.
- Use one issue-link label style across the release pages.
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
* chore(release): 11.28.6, pacquet 12.14.0
* docs(release): curate 11.28.6 and pacquet 12.14.0 release notes
Add lead paragraphs and group the patch entries by what the reader was
doing, with security first on the v11 page.
- v11: lead with the NPM_ID_TOKEN audience check and the invalid file
name warning as security fixes; say the `pnpm setup` message was
printed, since v11 reports it as a warning.
- v12: merge the stdout and stderr broken-pipe entries and the two
optional-peer entries; say the Windows Rust toolchain change undoes
the MinGW fallback a MinGW-built pnpm used since 12.13.0; correct the
`browser` packing claim; drop the reference to another release line.
- Use one issue-link label style on both pages.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(release): smooth two sentences in the 11.28.6 and 12.14.0 notes
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(release): say sideEffectsCache.exclude covers the local and remote cache
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs: give sideEffectsCache.exclude an example a cache key cannot cover
An environment variable such as JAVA_HOME could be added to the cache
key, so it does not justify excluding a package. Name the system
libraries a native addon links against instead.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore(release): 11.28.5, pacquet 12.10.0
* docs(release): curate the 11.28.5 and 12.10.0 release notes
Add a lead paragraph to each page and group the patch entries under
subject headings, with the security fixes first.
- Merge the unpublish path-boundary fix into the unpublish entry, the
legacy metadata cache prune into the metadata cache entry, the two
binary size entries, and the two 64 MiB archive limits on the v11 page.
- Drop the manifest-utils saveType entry from the CLI page: the CLI
only passes saveType values derived from its own flags, so no CLI user
can reach the fixed path.
- Rewrite mechanism-only entries (PAX header validation, bundled
dependency symlinks, custom resolutions under name@version keys, proxy
setting validation) in terms of what the user sees.
- Use one link style for pnpm/pnpm issues.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Validate bundled dependency names with isSafeBundleName to prevent path traversal in bundleDependencies.
Ensure files resolving through directory symlinks do not escape the package root in @pnpm/fs.packlist and @pnpm/store.cafs.
Closes https://github.com/pnpm/tasks/issues/83
Closes https://github.com/pnpm/tasks/issues/93
Reject git repository values that are empty, start with '-', or contain
null bytes, and pass '--' before the repository argument in git clone and
git remote add. This prevents git option injection when fetching
git-hosted dependencies from unvalidated lockfile resolutions, matching
pnpm v12.
The INVALID_GIT_REPOSITORY message now lists every rejected form in both
CLIs, and pnpm v12 reports it as ERR_PNPM_INVALID_GIT_REPOSITORY. The v11
INVALID_GIT_COMMIT message redacts credentials and strips control
characters.
Fixes https://github.com/pnpm/tasks/issues/84
* chore(release): 11.28.4, pacquet 12.9.1
* docs(release): curate 11.28.4 and pacquet 12.9.1 release notes
Add a lead paragraph to both pages. Move the two credential-leak fixes
in 11.28.4 to the top and group the remaining 27 entries by what the
reader was doing. Merge entries that described one change: the two
INVALID_SETTING validations, the two metadata revalidation fixes, the
two hoisted filtered-install fixes, and, in pacquet 12.9.1, the two
[<since>] selector fixes. Order pacquet 12.9.1 so the `@pnpm/wasm` move,
which WebContainer users must act on, comes first.
Normalize issue links to the [#N] form and link the ETag fix to
pnpm/pnpm#16506.
Every fix was checked against the code released in 11.28.3 and
pacquet 12.9.0; none fixes a defect that never shipped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(release): describe the frozen-lockfile fixes accurately in the 11.28.4 lead
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore(release): 11.28.3
* docs(changelog): curate the 11.28.3 release notes
Merge the eleven entries about names such as `constructor` into one,
group the patch changes by what the reader was doing, and add a lead
paragraph.
Drop the zlib-rs entry: that change only touched Cargo.toml, and the
TypeScript CLI does not use the Rust engine. It belongs to the next
pacquet release.
Rewrite the store index entry for CLI users. `ReadOnlyStoreIndex` and
`ImmutableStoreIndex` are library API documented in the
`@pnpm/store.index` changelog.
Say what the store prune mark-phase fix changes for the user.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Add TypeScript ports of the perfectionist rules that the Rust workspace
enforces through dylint.toml to @pnpm/eslint-config, with the same limits,
and fix every finding that needs no refactor.
The size and shape rules (function length, cognitive complexity, nesting,
local bindings, file length) are enforced for packages that already meet
them. The packages that do not are listed in PENDING_SIZE_AND_SHAPE_REFACTOR
in eslint.config.mjs and are refactored in follow-up changes.
The custom rules mirror perfectionist's semantics rather than reusing
sonarjs or max-lines-per-function, so that one limit means the same thing
in both codebases: a closure is a level of the body that contains it, a
nested function declaration is measured on its own, and a test-framework
callback plays the role of a #[test] function.
Bugs found and fixed along the way:
- a registry error body cut at exactly 64 KiB lost its truncation marker
- removing a dependency could leave dangling .bin shims
- constructor/__proto__ names crashed the projects graph, were skipped by
the injected-deps syncer, and were dropped from writeWantedLockfile's
returned lockfile
The CI chunk runner learns to run the node:test suite of the ESLint
config package.
* chore(release): 11.28.1, pacquet 12.8.0, pnpr 0.1.0-alpha.14
* docs(release): park Rust changelogs and curate release notes
The release bump ran with pnpm 12.7.0, which since pnpm/pnpm#14934
writes the changelog of every private project to a committed
CHANGELOG.md. pacquet, `@pnpm/napi` and `@pnpm/pnpr` are private
in-repo but published, and release.yml and the publish-time changelog
composer both read their parked section. Move the three sections back
to .changeset/changelogs so the GitHub release bodies and the npm
tarball changelogs are not empty. The tooling follow-up is recorded
on pnpm/tasks#38.
Curate the pnpm 11.28.1, pnpm 12.8.0 and pnpr 0.1.0-alpha.14 pages:
add lead paragraphs, group patch entries by subject, merge entries
describing one change, drop internals no CLI user sees, and fix
"instead of" tails, implementation names and link placement. This
addresses both Qodo findings on the catalog entry.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
StackBlitz WebContainers reject asynchronous fs calls with errors that
inherit from Error but were not created by the native constructor, so
util.types.isNativeError() returns false for them. pnpm used that check
to recognize ENOENT and other codes, so a missing pnpm-lock.yaml was
rethrown and pnpm install failed on any project without a lockfile.
Add isError() to @pnpm/error, which accepts a native error or any
instanceof Error, and use it at every non-test call site. The native
check alone is still needed for Jest, where errors from another realm
fail instanceof. Update the AGENTS.md guidance to match.
Closespnpm/pnpm#15649
Fetching a git dependency locked to an SSH remote now says to load a key
with ssh-add when git reports a publickey refusal, and still explains how
to re-record a pre-v11.21 entry with pnpm update.
Resolving an SSH URL that fails the same way shows that advice plus a
local HTTPS insteadOf rewrite when the remote logs in as git. The
rewrite uses a shell-safe host and no userinfo, so a password or a
hostile host cannot reach the command.
Closespnpm/pnpm#13743
---------
Co-authored-by: Cursor Agent <cursoragent@cursor.com>
Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
* chore(release): 11.28.0, pacquet 12.7.0, pnpr 0.1.0-alpha.13
* docs(release): curate the 11.28.0 and 12.7.0 release pages
Group both pages under subject headings with a lead paragraph that
names the headline changes and the security fixes, and move the
security entries to the top of the patch section.
Merge entries that describe one change: the node shim version files,
ranged selectors without a package.json, SemVer build metadata,
completion injection, custom modulesDir command lookup,
list --only-projects, store status, npm_execpath, catalog and npm-alias
workspace edges, the macOS CA fallback, and the prepare/devPreinstall
skips.
Drop entries that describe no change a published version could show:
the test-only --no-optional entry on both pages, the exported
CreateNewStoreControllerOptions type, the publish availability-probe
fix for a flag first shipping in 12.7.0, and the executable-bit check
the Rust CLI never had wrong.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
* docs(release): describe the bin shim part of the modulesDir entry accurately
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
---------
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Initialize committed Git submodules after checkout, with the same noninteractive protocol safeguards used for Git dependency fetches. Closespnpm/pnpm#1470.
---------
Co-authored-by: Zoltan Kochan <z@kochan.io>
The default reporter repaints the terminal over anything git or ssh
prints, so when a git dependency's SSH remote needs a key passphrase or
a host key confirmation the prompt is invisible and `pnpm install` looks
hung. `GIT_TERMINAL_PROMPT=0` already made git's own credential prompts
fail fast; ssh prompts on the terminal directly, so it needs
`BatchMode=yes` through `GIT_SSH_COMMAND` to fail the same way.
Both the git resolver's `ls-remote` and every git invocation of the git
fetcher now go through one helper, `nonInteractiveGitEnv` in
`@pnpm/network.git-utils` and `disable_git_prompts` in
`pnpm-git-utils`, that sets both variables. The ssh override is skipped
when the user already selected the ssh command through
`GIT_SSH_COMMAND`, `GIT_SSH`, or the `core.sshCommand` git setting, so
a custom key or a plink setup keeps working, and setting
`GIT_SSH_COMMAND=ssh` opts back into prompting.
Closespnpm/pnpm#2227
Distinguish an explicit denial from an undecided Git dependency build.
Install source files when preparation is denied, while retaining the
approval error for dependencies without a recorded decision.
Carry skipped-preparation state through the fetchers and in-memory cache.
Select the existing unprepared store key for denied builds so subsequent
approvals prepare the dependency and denials do not reuse prepared output.
Apply the behavior to both CLI versions and to cloned Git repositories
and Git-hosted tarballs. Cover explicit denials, policy transitions,
shared-store approval enforcement, and initially unknown package names.
Closespnpm/pnpm#10522.
Git preparation was gated only while fetching a package. Once an approved project placed prepared files in the shared store, a different project could link those files without consulting its own allowBuilds policy.
Persist whether preparation was required in each git package's store-index row and check the active project policy before warm-store reuse. Legacy rows without the marker are reused only with explicit approval; otherwise they go through the existing cold fetch and preparation gate. Revalidate in-process git fetch results as well so a long-lived store controller cannot carry approval across policy changes.
Pass the canonical lockfile resolution ID into both git fetch paths so the allowBuilds identity and suggested key stay byte-for-byte exact. Mirror the marker and warm-reuse gate in pacquet using the shared msgpackr-compatible store format.
Closespnpm/pnpm#13965.
[ERR_PNPM_GIT_FETCH_FAILED] Failed to fetch "@logux/core" from the git repository
"git@github.com:logux/core.git": fatal: Could not read from remote repository.
...
The lockfile records an SSH remote for this dependency, so fetching it needs an SSH key
for github.com.
If its specifier does not ask for SSH (for example "github:owner/repo"), the lockfile
entry was written before pnpm v11.21 and can be re-recorded over HTTPS:
pnpm update @logux/core
"pnpm install --force" and "pnpm install --resolution-only" do not re-resolve git
dependencies, so neither clears it.
Both utilities lived in the pnpm/components Bit workspace, where their
component names collide with same-named components elsewhere in the Bit
registry. Move the code here and publish it under new names:
`@pnpm/util.lex-comparator` -> `@pnpm/text.ordinal-comparator`
`@pnpm/config.nerf-dart` -> `@pnpm/config.registry-auth-key`
The new names describe what the utilities do: the comparator is ordinal
rather than locale-aware, and the mapped URL is the key that registry
settings are stored under in `.npmrc`. The exported functions keep their
names, so consumers only change their import specifiers.
Implementations and tests are carried over unchanged. The rationale from
the components' docs pages moves into doc comments: why `localeCompare`
cannot be used for values compared across machines, and where `nerfDart`
originates.
No pacquet counterpart is needed. The Rust stack has its own
implementations of both and no user-visible behavior changes.
Remove the legacy repository changelog files now that release changelog storage defaults to the registry. The publish path composes and injects CHANGELOG.md into release tarballs, so keeping historical copies in source control duplicates generated release data.
Update adm-zip to the patched 0.6 release and override vulnerable transitive versions after the dependency audit began rejecting versions below 0.6.0.
The TypeScript pnpm CLI freezes at v11; pnpm 12 will be the Rust pacquet
port. To make that split legible, all TypeScript source, test, and build
directories move under a new top-level pnpm11/ directory. The name states
the version boundary rather than implying a behavioral fork, since the two
stacks are meant to behave identically.
Scope is source-only: the shared workspace root stays at the repo root.
pnpm-workspace.yaml, package.json, pnpm-lock.yaml, .pnpmfile.cjs,
.meta-updater, __patches__, .changeset, .husky, and the lint/spell configs
remain in place, so one pnpm workspace and one Cargo workspace still span
all three products. pnpr/client and pacquet/tasks/registry-mock stay as
cross-product workspace members.
Rewiring the move required:
- pnpm-workspace.yaml globs prefixed with pnpm11/
- root package.json script paths, eslint.config.mjs, tsconfig.lint.json,
.gitignore, and CODEOWNERS updated
- .meta-updater/src/index.ts literals repointed (pnpm11/pnpm/package.json,
pnpm11/__utils__, pnpm11/__typings__, and the main package directory)
- regenerated every moved package's repository/homepage URL via meta-updater
- pnpm11/pnpm/bundle-deps.ts and __utils__/scripts/src/typecheck-only.ts
climb one more level to reach the repo root
.meta-updater stays at the repo root because @pnpm/meta-updater resolves
its config at <cwd>/.meta-updater/main.mjs.
TS CI (.github/workflows/ci.yml) now only runs when pnpm11/-relevant paths
change, via a dorny/paths-filter changes job plus a TS CI / Success
aggregate gate; branch protection should require only that gate.