Commit Graph
49 Commits
Author SHA1 Message Date
6b5b8ac53a chore(release): 11.28.9, pacquet 12.16.0, pnpr 0.1.0-alpha.17, get-pnpm 0.0.10 (#17406)
* chore(release): 11.28.9, pacquet 12.16.0, pnpr 0.1.0-alpha.17, get-pnpm 0.0.10

* docs(release): curate the 11.28.9, 12.16.0, and pnpr alpha.17 release notes

- Add a lead line to each page and group the patch entries by what the
  reader was doing, with security fixes first.
- Merge the duplicate strictSsl/localAddress entries and the repeat-install
  setting entries into one list per page.
- pnpr: split the removals into commands, flag aliases, and camelCase
  config keys, and say that pnpr no longer serves PUT /-/pnpm/v1/publish,
  so batch publishing needs pnpm 11.28.9 or 12.16.0.
- Drop the "Updated dependencies: get-pnpm" line from the pnpm v12 page
  and list the get-pnpm credential fix first.

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>
2026-10-27 00:08:12 +01:00
Zoltan Kochanandgithub-actions[bot] 91774e72a0 chore(release): 11.28.7, pacquet 12.15.0, pnpr 0.1.0-alpha.16 (#17187)
* 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>
2026-10-21 12:15:12 +02:00
Zoltan Kochan a7fb3f069d fix: sync only the package files into injected copies after scripts (#17033)
An injected copy is built by the install from the package files only
(the files field and .npmignore) unless deployAllFiles is set. Every
refresh that runs after a project's own scripts read the source with
every file instead, so the copy gained files the install had left out:
- v12: the sync after lifecycle scripts during install, after `pnpm run`
  and task-pipeline scripts named in syncInjectedDepsAfterScripts, and
  the edit watcher that publishes while such a script runs.
- v11: the same `pnpm run` sync and watcher, and the re-import after
  lifecycle scripts during install.

pnpm/pnpm#16684 fixed the same thing for the dedicated-lockfile sync.
These paths now read the source with includeOnlyPackageFiles set to
!deployAllFiles too, so every writer of an injected copy selects the
same files (pnpm/tasks#145, property B).

The packlist lists a symlinked directory as one entry, where the walk
of every file lists the files under it. The syncers expand such an
entry, so a symlinked directory still reaches the copy as its files.

v12 groups the bin-linking settings of SyncInjectedDeps into
BinLinkSettings to stay under the struct field limit.
2026-10-17 14:48:24 +02:00
Zain QureshiandClaude Opus 5.5 7162c6f5ec docs: fix stale usage examples in six package READMEs (#16959)
* docs: fix stale usage examples in six package READMEs

The usage examples imported default exports these packages no longer
have. They now import the named exports, call the current function
names, and pass the options the current signatures accept.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: import path in the lifecycle example, drop @pnpm/logger from the changeset

@pnpm/logger is in versioning.ignore, so a changeset entry for it fails
pnpm change check. The lifecycle example used path without importing it
and require in an ES module.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs: single backslashes in the store path output, plain changeset wording

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-16 14:19:38 +02:00
fe4a0c2323 chore(release): 11.28.6, pacquet 12.14.0 (#16952)
* 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>
2026-10-15 14:35:42 +02:00
68112bada4 chore(release): 11.28.5, pacquet 12.10.0 (#16637)
* 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>
2026-10-06 02:00:03 +02:00
5dafb09800 chore(release): 11.28.4, pacquet 12.9.1 (#16567)
* 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>
2026-10-03 22:13:02 +02:00
Zoltan Kochan 9179ae3339 refactor(ts): meet size and shape limits in 15 packages (#16456)
* refactor(ts): meet size and shape limits in 5 packages

Refactor 5 TypeScript packages to satisfy strict size and shape lint limits
(function length, nesting, cognitive complexity, local declarations):
- `@pnpm/installing.linking.modules-cleaner`
- `@pnpm/installing.linking.real-hoist`
- `@pnpm/lockfile.utils`
- `@pnpm/modules-mounter.daemon`
- `@pnpm/releasing.exportable-manifest`

Remove them from PENDING_SIZE_AND_SHAPE_REFACTOR in eslint.config.mjs.

* refactor(ts): meet size and shape limits in 10 packages

Refactor 10 TypeScript packages to satisfy strict size and shape lint limits
(function length, nesting, cognitive complexity, local declarations):
- `@pnpm/bins.cmd-shim`
- `@pnpm/engine.runtime.commands`
- `@pnpm/exec.lifecycle`
- `@pnpm/fetching.git-fetcher`
- `@pnpm/fetching.tarball-fetcher`
- `@pnpm/fs.indexed-pkg-importer`
- `@pnpm/hooks.pnpmfile`
- `@pnpm/installing.context`
- `@pnpm/resolving.git-resolver`
- `@pnpm/store.commands`

Graduate them from PENDING_SIZE_AND_SHAPE_REFACTOR in eslint.config.mjs.

* fix(ts): address review feedback on shims and lockfile comments

* test(cmd-shim): add regression test for isShimBasedirAnchorCurrent with absolute targets
2026-10-01 04:53:20 +02:00
de9611cf28 chore(release): 11.28.3 (#16444)
* 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>
2026-09-30 16:56:44 +02:00
Zoltan Kochan 4edeef9176 style(ts): port the perfectionist lint rules to ESLint (#16415)
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.
2026-09-30 15:10:08 +02:00
9ce8c2e734 chore(release): 11.28.1, pacquet 12.8.0, pnpr 0.1.0-alpha.14 (#16312)
* 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>
2026-09-28 08:57:31 +02:00
Zoltan Kochan 266cbd9615 fix(run): pass script arguments through cmd unchanged on Windows (#16262)
`pnpm run` appended the arguments after the script name with JSON string
quoting when cmd parsed the script. cmd then expanded `%VAR%`, and the
target program's C runtime received doubled backslashes and `\t` for a tab.

Both CLIs now quote each argument the way npm does: quoted for the C
runtime, then with every cmd metacharacter escaped with `^`. When the
script's first word resolves to a .cmd or .bat file on the script's PATH,
such as a node_modules/.bin shim, the arguments are escaped a second time
because the batch file parses them again. The command that receives the
arguments is the last one of a chain, and the lookup searches the script
directory before PATH, as cmd does. Line breaks, which cmd cannot carry,
are still passed as the two characters `\n` / `\r`.

pnpm prints the script with its arguments quoted the POSIX way on every
platform, so the `^` escapes stay out of the `$` line, the lifecycle log
event and error messages. npm_lifecycle_script keeps the command that
runs.

Closes pnpm/pnpm#16257
2026-09-27 13:57:54 +02:00
16f56b91be fix: honor scriptShell when shellEmulator is set (#15865)
A configured scriptShell is spawned for pnpm run and lifecycle scripts even when shellEmulator is also enabled. The built-in emulator does not implement bash export or relative script paths the way Git Bash does, and the reported config sets both options, so the emulator was hiding the shell the user configured.

shellEmulator still selects the built-in shell when scriptShell is unset. A blank scriptShell is unset on both runners, so the fallback shell and the extra-argument quoting match. The shell is still selected first, so a .bat or .cmd scriptShell is rejected before anything runs.

Extra arguments are JSON-quoted only when cmd will parse the script (windowsVerbatimArguments). A non-cmd scriptShell, including a path such as C:\Program Files\Git\bin\bash.exe, gets POSIX quoting and is spawned without verbatim arguments, so the path stays one argument.

PATH, bin lookup, and auth are not changed.

Closes pnpm/pnpm#14719

---------

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>
2026-09-27 11:23:16 +02:00
deca7295a4 fix: build an injected workspace dependency's publish directory before relying on it (#15702)
* **Bug Fixes**
  * Fixed installation of injected workspace dependencies whose configured publish directory is created by a `prepare` script. Built files are copied from the publish directory to the expected package location.
  * Explicit `file:` dependencies retain their project-root layout, with built files remaining in the configured subdirectory.
  * Reinstalling after a publish directory is removed preserves an existing injected copy.
  * Frozen installs no longer report these dependencies as outdated before the publish directory is built.
  * Workspace packages publishing from a configured directory are recognized during installation and lockfile freshness checks.
  * Updated injected package command links to remove stale entries and reflect rebuilt packages.

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-09-26 01:35:50 +02:00
b341f5ada2 chore(release): 11.28.0, pacquet 12.7.0, pnpr 0.1.0-alpha.13 (#15647)
* 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>
2026-09-25 12:01:04 +02:00
Zoltan KochanandClaude Opus 5.5 16af1b1665 fix(store): tighten the gypfile recheck of stored requiresBuild (#15635)
Follow-up to the review of pnpm/pnpm#14900.

- The v11 worker parsed the store's package.json with a bare
  JSON.parse, so a manifest starting with a byte-order mark failed to
  parse and kept the stale `requiresBuild: true`. It now uses
  `parseJsonBufferSync`, which strips the mark, as store ingestion does.
- Both stacks answer from the manifest's install scripts before
  scanning the file index, and the TypeScript check no longer copies
  the index.
- The predicate is renamed to `stored_requires_build_needs_manifest_check`
  / `storedRequiresBuildNeedsManifestCheck`, and its docs state the
  current contract.
- `checkBindingGyp`'s JSDoc states that its caller decides whether the
  synthesized script applies.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 10:48:32 +02:00
d44a0978a6 fix: read gypfile: false as an opt-out of the implicit node-gyp build (#14900)
pnpm synthesizes a `node-gyp rebuild` install script for a package that ships a `binding.gyp` and declares no `install` or `preinstall` script. npm reads `gypfile: false` as that package's opt-out from the synthesized script (https://docs.npmjs.com/cli/v12/configuring-npm/package-json#gypfile). This commit implements that feature in pnpm so such a dependency needs no `allowBuilds` entry and is no longer listed under "Ignored build scripts". 

`better-sqlite3` v13 sets `gypfile: false` because it ships prebuilts on every supported platform. It's trying to avoid install script policy errors, and the dependencies required by node-gyp (python, c++). On pnpm, without this change, it triggers the script policy.

Because everything keyed off `requiresBuild` is decided before the build phase applies a patch, the patch preview answers for the whole patched package rather than for the paths the patch writes: a patch that drops `gypfile: false` puts the `binding.gyp` the package already shipped back in scope, and a patch that deletes the `binding.gyp` or the manifest takes the trigger, or the opt-out, away with it.

Store-index rows written before this change recorded a lone `binding.gyp` as build work, and their bundled manifest dropped `gypfile`. A stored `requiresBuild: true` whose only trigger is a `binding.gyp` and whose bundled manifest has no `gypfile` is rechecked against the package's `package.json` in the store, so a warm store picks up the opt-out without a refetch.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-25 08:22:34 +02:00
Zoltan Kochan 5128432e72 fix(deploy): skip prepare scripts of deployed project (#15322)
Do not run prepare scripts of the deployed project during deploy.
In both pnpm v11 and v12, deploy does not execute prepare
lifecycle scripts of the target project, preventing failures
when devDependencies are omitted (e.g. with --prod).

Closes pnpm/pnpm#7282.
2026-09-23 13:16:42 +02:00
Zoltan Kochan b9f75adca2 fix(install): do not run prepare script when installing without devDependencies (pnpm/pnpm#7068) (#15320)
Do not run `prepare` (along with `preprepare` and `postprepare`) scripts when `pnpm install` is invoked without devDependencies (such as with `--prod` or `--production`) or when package arguments are provided.

Closes pnpm/pnpm#7068
2026-09-23 07:22:23 +02:00
AltayandZoltan Kochan 719f466c39 fix(remove): run the project's uninstall lifecycle scripts (#15255)
`pnpm remove` ran none of the edited project's `preuninstall`,
`uninstall`, or `postuninstall` scripts on either stack. The project
lifecycle machinery only knew the install stages, and both the
resolution path (`projectsToBeBuilt`, `projects_running_own_scripts`)
and the headless path (`projectDirsRunningScripts`) excluded the
`uninstallSome` importer outright, so a removal was silent.

Both stacks now run the uninstall stages around the removal. The
edited projects run `preuninstall` and `uninstall` right after
`pnpm:devPreinstall`, before the lockfile freshness check, resolution,
or any unlinking, so the scripts still see the dependencies they are
about to lose and a failure aborts with the manifest, lockfile, and
`node_modules` untouched. `postuninstall` runs in the post-link slot in
place of the install stages. `ignoreScripts`, `--lockfile-only`, and
`virtualStoreOnly` skip all three, as they skip the install stages.
The install stages of a removed-from project keep not running, and no
other project in the workspace runs anything it did not before.

Only the project's own scripts run. The removed package's scripts stay
unrun: npm 7 dropped them for lack of context on why a package is
going away, and running them would need the same build-approval gate
as its install scripts.

A recursive removal marks every selected importer `uninstallSome`, so
both stacks record which selected projects listed a removed name,
in a regular field or in `peerDependencies`, before the manifests
are edited and run the stages only there. A removal whose selected
projects define an uninstall stage stays off the pnpr server
shortcut, which materializes without the stages.

The TypeScript CLI carries that set as `projectDirsRemovingDeps`,
threads it into the headless install as
`projectDirsRunningUninstallScripts` and as a per-importer stage list
on the resolution path; the stage lists live in `@pnpm/exec.lifecycle`.
Pacquet carries it on the workspace selection as `edited_dirs`,
threads a stage list through `ProjectScriptRunner`, adds the
pre-removal hook to the install dispatch, and selects the edited
projects for `postuninstall` in `projects_running_own_scripts`.

Closes pnpm/pnpm#3276

Written by an agent (Antigravity, gemini-3.8-flash).

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-09-22 17:51:23 +02:00
AltayandZoltan Kochan 1d4bdd1f44 fix(install): run the root project's preinstall before dependencies are installed (#15213)
The root project's `preinstall` ran with the other project lifecycle
stages, after the dependencies were resolved and linked, so a guard such
as `npx only-allow yarn` failed with `node_modules` already populated.

Both stacks now run the root's `preinstall` right after
`pnpm:devPreinstall`, ahead of the lockfile freshness check and
resolution, and drop it from the root's post-link stage list. The
decision whether it runs is unchanged: the same `--ignore-scripts`,
`ignorePackageManifest`, `virtualStoreOnly`, lockfile-only, and
rebuild gates apply, and it runs only when the root would have run its
own scripts after linking, so `pnpm add` and `pnpm remove` behave as
before. Other workspace projects keep their existing ordering, as do
dependency build scripts. A failing `preinstall` aborts before the
lockfile is written.

The TypeScript CLI carries the fact that it ran the hook through the
install as `rootProjectPreinstallRan`, so the headless path skips only
what already ran, and hands it to a delegated pacquet install as
`PNPM_INTERNAL_ROOT_PREINSTALL_ALREADY_RAN`. Pacquet skips its early
copy and the post-link stage on that marker, or when it ran the early
copy itself; a frozen delegation without the marker runs it ahead of
linking. A check-only install skips the hook like every other project
script.

Closes pnpm/pnpm#3760
Closes pnpm/pnpm#3836

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-09-22 14:30:25 +02:00
Efe Baran DurmazandZoltan Kochan 6b2a1056d4 fix: honor modulesDir for commands and CommonJS plugins (#15211)
Include the custom project modules directory in command shim NODE_PATH.
For symlinked tools, prepare each project's environment when pnpm runs
run/exec, install lifecycle scripts, and version hooks. Preserve symlinks,
project dependency isolation,
default layouts, and extendNodePath false.

Use the configured bin directory for bin/run/exec and install/version
hooks, including packageConfigs with separate lockfiles. Compare both
canonical paths when deciding whether a modules directory is the default.
Include development preinstall hooks and pnpr materialization. Reject
custom NODE_PATH entries containing path-list separators and parse
package configuration once per command.

Related to pnpm/pnpm#3604. ESM resolution remains outside this change.

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-09-22 07:25:27 +02:00
Zoltan Kochan 0c1aed71e3 fix(run): suppress recursive failures after Ctrl+C (#15209)
Concurrent lifecycle scripts each raised their death signal on pnpm as soon as they exited. The first synthetic SIGINT reached the remaining scripts' relay handlers like a second Ctrl-C, escalated them to SIGTERM, and let recursive run report ordinary lifecycle failures before pnpm exited.

Group overlapping signal relays and raise a child's death signal once, after the whole group has settled. Delay lifecycle error reporting until that signal has had a chance to end pnpm.
2026-09-21 15:31:14 +02:00
Zoltan Kochanandgithub-actions[bot] 201f9fc51f chore(release): 11.27.1 (#15185)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-20 23:11:14 +02:00
Zoltan Kochan 4eb09c84e5 refactor: move npm-lifecycle into the pnpm monorepo (#15113)
Import the lifecycle runner from pnpm/npm-lifecycle at 178f3d5 as
@pnpm/exec.npm-lifecycle, so it is maintained alongside its consumer
and a fix no longer needs a separate release.

The source is converted to TypeScript with typed options, package
data, log and child-process interfaces, which replaces the any-typed
declaration in __typings__/local.d.ts. The legacy pkg._data unwrapping
and the unused opts.config are dropped. The tests are ported to jest.

The node-gyp wrappers ship with the package; the runner finds them
beside lib in the package and in dist once the CLI bundle has
flattened the module, where the CLI ships its own copy. The manifest
updater keeps node-gyp-bin in the package's files. @yarnpkg/shell's
declarations import micromatch's, so a packageExtensions entry gives
it @types/micromatch. The Artistic-2.0 license is preserved.

The imported code includes the fix for the terminal SIGINT being
relayed to a script that already had it (pnpm/npm-lifecycle#62), which
this brings to pnpm v11; a pseudo-terminal test covers it in the
package and in the CLI.

Related to pnpm/pnpm#7374
2026-09-19 13:01:50 +02:00
Zoltan Kochanandgithub-actions[bot] b62f5b004f chore(release): 11.27.0 (#14856)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-12 12:01:04 +02:00
Zoltan Kochan f00e7680aa chore(release): 11.26.0 (#14638) 2026-09-07 01:30:44 +02:00
Zoltan Kochan 9a0918ceb3 test(executor): cover the emulator quoting branch off Windows (#14623)
The rule that the shell emulator takes POSIX quoting on every platform was
only observable on Windows. Both stacks gated it behind a platform check
that is constant for a given run, so a Linux or macOS job could not tell
`windows && !shell_emulator` from `windows` alone.

Take the platform as a value in `parsed_by_windows_shell` and give
`build_command` the shell family it should quote for. Both quoting branches
and the emulator rule are now asserted on any host, which also retires the
`build_command` case that was ignored on Windows and leaves the JSON branch
covered for the first time off Windows.

Mock `is-windows` in a lifecycle test so the same rule is exercised through
`runLifecycleHook` on any host. Each assertion was confirmed to fail when
its half of the rule is removed.

Related to pnpm/pnpm#14548
2026-09-06 20:30:39 +02:00
zhsama d426763b60 fix(executor): preserve emulated script arguments (#14576)
Select POSIX argument quoting whenever the shell emulator parses a script,
including on Windows. Keep native Windows shell quoting unchanged and
apply the same selection in the TypeScript lifecycle implementation.

Cover literal arguments through the direct and recursive CLI paths and the
TypeScript lifecycle boundary.

Replace the cancellation regression's startup-sensitive four-second
assertion with a completion marker, distinct exit code and bounded watchdog.
The existing timing assertion failed under full-suite startup load.

Fixes pnpm/pnpm#14548
2026-09-06 18:47:24 +02:00
Zoltan Kochan 6d90c71efd chore(release): 11.25.0, pacquet 12.1.0, pnpr 0.1.0-alpha.9 (#14306) 2026-08-29 15:50:36 +02:00
Zoltan Kochan a22206394e fix(run): clean up lifecycle process trees on failure (#14244)
On Windows, pnpm's error handler cannot rely on descendant enumeration because modern systems may lack wmic and the PowerShell fallback can exceed its time budget. Recursive exec children already register their PIDs for the taskkill fallback, but lifecycle children spawned by recursive run did not.

Use the spawn observer added in `@pnpm/npm-lifecycle` 1100.1.0 to register lifecycle children with the existing tracker. Reuse the process-tree fixture to verify recursive run cleanup with the process-enumeration paths removed from PATH.

Also disable Git checks in the publish error test so a dirty contributor worktree cannot mask the missing-version error that test exercises.

Related to pnpm/pnpm#14211.
2026-08-27 21:27:50 +02:00
Zoltan Kochan 9f3f18905e perf: retire chunk-based workspace execution loops (#14221)
Move the remaining workspace command pipelines from topological chunks to the shared dependency-ready scheduler. Recursive rebuild, per-project install-family commands, pack, publish, stage approval, dependency builds, and project lifecycle scripts can now dispatch each node as soon as its own prerequisites settle instead of waiting at a workspace-wide layer barrier.

Keep concurrency inside the scheduler so ready work cannot over-dispatch, retain the existing command-specific bail and no-bail policies, and wait for already-dispatched command work where the old Promise.all and scoped-thread paths did. Ignored cycles remain deterministic by dropping backward edges in the graph sequencer's flat order.

With all execution consumers migrated, simplify graph sequencing to order plus cycles, replace grouped project sorting with dependency maps, and remove the obsolete run-groups dependency and chunk helpers.

Implements item 2 of pnpm/pnpm#14211.
2026-08-27 15:03:46 +02:00
Zoltan Kochanandgithub-actions[bot] 726d6b4a04 chore(release): 11.23.0 (#14111)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-23 15:47:36 +02:00
Zoltan Kochanandgithub-actions[bot] 93fcba4224 chore(release): 11.22.0, pacquet 12.0.0-rc.6 (#13926)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-15 18:50:30 +02:00
Zoltan Kochanandgithub-actions[bot] 8adb97ed05 chore(release): 11.21.0, pacquet 12.0.0-rc.2 (#13742)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-09 16:02:53 +02:00
Zoltan Kochanandgithub-actions[bot] ebc48abdc5 chore(release): 11.20.0, pacquet 12.0.0-beta.4 (#13608)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-08-03 15:48:54 +02:00
Zoltan Kochan 536b7a2c8a chore(release): 11.19.0 (#13524) 2026-07-31 10:46:26 +02:00
Zoltan Kochanandgithub-actions[bot] 925c33d780 chore(release): 11.18.0, pacquet 12.0.0-beta.0 (#13481)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-29 09:29:53 +02:00
Zoltan Kochanandgithub-actions[bot] 454e7d62b3 chore(release): 11.17.0, pacquet 12.0.0-alpha.19, pnpr 0.1.0-alpha.5 (#13237)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-23 17:07:05 +02:00
Zoltan Kochanandgithub-actions[bot] d1edab423e chore(release): 11.16.0, pacquet 12.0.0-alpha.18 (#13216)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-22 21:58:38 +02:00
Zoltan Kochanandgithub-actions[bot] 331c26aa4b chore(release): 11.15.1, pacquet 12.0.0-alpha.16 (#13162)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-20 00:19:20 +02:00
Zoltan Kochan f4948525df chore: remove repository changelogs (#13119)
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.
2026-07-18 13:10:25 +02:00
Zoltan Kochanandgithub-actions[bot] f8b08ea63f chore(release): 11.14.0, pacquet 12.0.0-alpha.14 (#13113)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-18 00:01:20 +02:00
Zoltan Kochanandgithub-actions[bot] ca66b76fb2 chore(release): 11.13.1 (#13058)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-16 00:36:19 +02:00
Zoltan Kochanandgithub-actions[bot] 682f57e773 chore(release): 11.13.0, pacquet 12.0.0-alpha.9, pnpr 0.1.0-alpha.1 (#12986)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-13 22:19:04 +02:00
armanandZoltan Kochan b46f96165f fix: kill spawned process trees with taskkill on Windows error exits (#12925)
Main thread panicked: begin > end (105 > 28) when slicing
`@pnpm/npm-lifecycle@1100.0.0(patch_hash=e3541c…)(supports-color@10.2.2)`
at pacquet/crates/resolving-deps-resolver/src/resolve_peers.rs:2490:51

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-07-13 16:30:01 +02:00
Zoltan Kochanandgithub-actions[bot] 7cd1e4f4f6 chore(release): 11.10.0 (#12799)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-04 21:05:03 +02:00
Zoltan Kochanandgithub-actions[bot] 9671d9aeed chore(release): 11.9.0 (#12611)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-06-23 17:16:24 +02:00
Zoltan Kochan fc2f33912e refactor: move the TypeScript pnpm CLI into a pnpm11/ directory (#12537)
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.
2026-06-20 14:36:25 +02:00