Commit Graph

10552 Commits

Author SHA1 Message Date
Zoltan Kochan
421ceac0b3 chore: compile pnpm CLI bundle before tests that use it (#11059)
Packages whose tests spawn the local pnpm CLI (pnpm/bin/pnpm.mjs) need
the bundle (pnpm/dist/pnpm.mjs) to exist. Add `pnpm --filter pnpm run
compile` to their test scripts so the bundle is built before tests run.
2026-03-22 10:56:36 +01:00
Brandon Cheng
6557dc09f9 fix: clearCache function in @pnpm/resolving.npm-resolver (#11050)
* test: add test for `clearCache` function in `@pnpm/resolving.npm-resolver`

* fix: clear pMemoize when clearing NPM resolver `clearCache` function
2026-03-22 01:48:25 +01:00
Brandon Cheng
f98a2db373 fix: invalid specifiers for peers on all non-exact version selectors (#11049)
* test: add test for hoist peers when given all range version selectors

* fix: invalid specifiers for peers on non-string version selectors

In tests, the bare specifier for the `@pnpm.e2e/peer-a` dependency
became ` || 1.0.0`. This was because the `versions` array could be
empty, causing the `.join(' || ')` operation to execute on a holey
array.

This caused a test in `installing/commands/test/update/update.ts` to
fail.
2026-03-22 01:47:12 +01:00
Brandon Cheng
831f574330 fix: propagate error cause when throwing PnpmError in @pnpm/npm-resolver (#10990)
* fix: show error cause when failing to read metadata

* fix: correct changeset package name and add cause assertion tests

- Fix changeset to reference @pnpm/resolving.npm-resolver (not @pnpm/npm-resolver)
- Add PnpmError cause unit tests in @pnpm/error
- Fix npm-resolver tests to actually verify cause on thrown errors
  (.toThrow() only checks message, not cause/hint/code properties)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-22 00:59:52 +01:00
Zoltan Kochan
6586604b19 refactor: remove hardcoded runtime bin workaround from linker (#11058)
Since v11 uses a new store version, all runtime packages (node, deno, bun)
have a generated package.json with bin fields. The hardcoded switch block
in the linker is no longer needed.

Also moves getNodeBinsForCurrentOS, getDenoBinLocationForCurrentOS, and
getBunBinLocationForCurrentOS out of @pnpm/constants into their respective
resolver packages, since each is only used in one place.
2026-03-22 00:21:55 +01:00
Khải
2e9101d724 chore(typescript): make typecheck threading configurable (#11057)
* feat: make tsgo --singleThreaded configurable via env var

Set PNPM_TYPECHECK_SINGLE_THREADED=false to allow tsgo to use multiple
threads during typechecking. Defaults to true (preserving current
behavior) for environments where memory is constrained.

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* feat: replace binary PNPM_TYPECHECK_SINGLE_THREADED with configurable PNPM_TYPECHECK_THREADING

Replace the binary on/off env var with PNPM_TYPECHECK_THREADING that
accepts three modes: auto, single-threaded, multi-threaded.

Resolution order:
1. PNPM_TYPECHECK_THREADING env var
2. .pnpm-typecheck.json config file (git-ignored, per-developer)
3. Default: "auto"

Auto mode checks system memory: <8GB uses single-threaded, >=8GB uses
multi-threaded.

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* refactor: simplify threading mode resolution

Move validation into the default branch of the switch, removing the
ThreadingMode type and VALID_THREADING_MODES set. readThreadingMode now
returns { mode: string, source: string } so error messages indicate
where the invalid value came from.

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* refactor: error on invalid threading mode instead of warning

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* refactor: remove auto-detect log message

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* refactor: use string literal union type for threading source

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* revert: revert source type back to string

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* refactor: remove try-catch, let parse errors propagate to user

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* refactor: simplify auto case to return directly

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* fix: normalize and validate threading mode input

Trim whitespace and lowercase env var and config file values so that
empty/whitespace-only strings fall through to the default, and
case-insensitive values like "Auto" or "SINGLE-THREADED" are accepted.

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* style: use single quotes for string without interpolation

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

* feat: support .local-settings dir for typecheck config shared across worktrees

Read pnpm-typecheck.json from .local-settings/ directory (with fallback
to the old .pnpm-typecheck.json location). The worktree-new script now
symlinks .local-settings alongside .claude so the config is shared
across all worktrees without manual copying.

https://claude.ai/code/session_01MRhydwHLce7vwZDkf1yvzE

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-03-22 00:14:40 +01:00
Trevor Burnham
d0aea45b28 feat: warn when optimistic-repeat-install skips shouldRefreshResolution hooks (#10995)
* feat: warn when optimistic-repeat-install skips shouldRefreshResolution hooks

* Fix log message for optimistic repeat install

---------

Co-authored-by: Zoltan Kochan <z@kochan.io>
2026-03-21 23:52:01 +01:00
Brandon Cheng
41dc031a67 test: use resolution-mode=highest in tests (#10989)
* fix: configure default resolution-mode to highest in pkg-manager/core

* test: update catalog tests for resolution-mode=highest

* test: fix `--fix-lockfile` test for new resolution-mode default

```
  ● fix broken lockfile with --fix-lockfile

    expect(received).toBeTruthy()

    Received: undefined

      55 |   const lockfile: LockfileFile = readYamlFileSync(WANTED_LOCKFILE)
      56 |   expect(Object.keys(lockfile.packages as PackageSnapshots)).toHaveLength(2)
    > 57 |   expect(lockfile.packages?.['@types/semver@5.3.31']).toBeTruthy()
         |                                                       ^
      58 |   expect(lockfile.packages?.['@types/semver@5.3.31']?.resolution).toEqual({
      59 |     integrity: 'sha512-WBv5F9HrWTyG800cB9M3veCVkFahqXN7KA7c3VUCYZm/xhNzzIFiXiq+rZmj75j7GvWelN3YNrLX7FjtqBvhMw==',
      60 |   })

      at Object.<anonymous> (test/install/fixLockfile.ts:57:55)
```

* test: fix lockfile conflict test

  ● a lockfile v6 with merge conflicts is autofixed

    expect(received).toHaveProperty(path, value)

    Expected path: "version"

    Expected value: "100.1.0"
    Received value: "101.0.0"

      1284 |
      1285 |   const lockfile = project.readLockfile()
    > 1286 |   expect(lockfile.importers?.['.'].dependencies?.['@pnpm.e2e/dep-of-pkg-with-1-dep']).toHaveProperty('version', '100.1.0')
           |                                                                                       ^
      1287 | })
      1288 |
      1289 | test('a lockfile with duplicate keys is fixed', async () => {

      at Object.<anonymous> (test/lockfile.ts:1286:87)

* test: fix deploy shared lockfile test

  ● deploy with a shared lockfile that has peer dependencies suffix in workspace package dependency paths

    expect(received).toMatchObject(expected)

    - Expected  - 6
    + Received  + 1

    @@ -1,11 +1,11 @@
      Object {
        "importers": Object {
          "packages/project-0": Object {
            "dependencies": Object {
              "project-1": Object {
    -           "version": "file:packages/project-1(is-negative@1.0.0)(project-2@file:packages/project-2(is-positive@1.0.0))",
    +           "version": "file:packages/project-1(is-negative@2.1.0)(project-2@file:packages/project-2(is-positive@1.0.0))",
              },
              "project-2": Object {
                "version": "file:packages/project-2(is-positive@1.0.0)",
              },
            },
    @@ -31,13 +31,8 @@
              "type": "directory",
            },
          },
        },
        "snapshots": Object {
    -     "project-1@file:packages/project-1(is-negative@1.0.0)(project-2@file:packages/project-2(is-positive@1.0.0))": Object {
    -       "dependencies": Object {
    -         "project-2": "file:packages/project-2(is-positive@1.0.0)",
    -       },
    -     },
          "project-2@file:packages/project-2(is-positive@1.0.0)": Object {},
        },
      }

      950 |     workspaceDir: process.cwd(),
      951 |   })
    > 952 |   expect(assertProject('.').readLockfile()).toMatchObject({
          |                                             ^
      953 |     importers: {
      954 |       'packages/project-0': {
      955 |         dependencies: {

      at Object.<anonymous> (test/shared-lockfile.test.ts:952:45)

* test: fix injectLocalPackages test
2026-03-21 23:21:04 +01:00
Brandon Cheng
021f70d0b0 fix: handle non-string version selectors in hoistPeers (#11048)
* test: add test for version selector with weight in hoistPeers

* fix: handle non-string version selectors in hoistPeers
2026-03-21 23:17:24 +01:00
Zoltan Kochan
8d4119608d feat: add pn and pnx short aliases (#11052)
- `pn` is an alias for `pnpm`
- `pnx` is an alias for `pnpx` (i.e. `pnpm dlx`)

Supported across all installation methods:
- npm install: via bin field in package.json
- @pnpm/exe: hardlink (pn) + shell scripts (pnpx, pnx) created by setup.js
- pnpm setup: shell scripts for pn, pnpx, pnx
- Corepack: via bin field (same as npm install)
- curl install: via pnpm setup
2026-03-21 22:11:37 +01:00
Zoltan Kochan
c296d17c78 fix: revert some not needed info messages
reverts some logs added via https://github.com/pnpm/pnpm/pull/11039
2026-03-21 22:09:48 +01:00
btea
2f98ec84f4 feat: store prune displays the total size of removed files (#11047)
* feat: store prune displays the total size of removed files

* test: update
2026-03-21 20:01:58 +01:00
Zoltan Kochan
cd2dc7d481 refactor: prefix internal scripts with . to hide them (#11051)
* fix: ensure PNPM_HOME/bin is in PATH during pnpm setup

When upgrading from old pnpm (global bin = PNPM_HOME) to new pnpm
(global bin = PNPM_HOME/bin), `pnpm setup` would fail because the
spawned `pnpm add -g` checks that the global bin dir is in PATH.
Prepend PNPM_HOME/bin to PATH in the spawned process env so the
check passes during the transition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: update pnpm to v11 beta 2

* chore: update pnpm to v11 beta 2

* chore: update pnpm to v11 beta 2

* chore: update pnpm to v11 beta 2

* fix: lint

* refactor: rename _-prefixed scripts to .-prefixed scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update root package.json to use .test instead of _test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* ci: update action-setup

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 14:30:56 +01:00
Zoltan Kochan
0fedb7a7ef revert: "chore: update pnpm to v11 beta 2"
This reverts commit b3b6e348e0.
2026-03-21 13:40:53 +01:00
Zoltan Kochan
b3b6e348e0 chore: update pnpm to v11 beta 2 2026-03-21 13:39:26 +01:00
Zoltan Kochan
8b2ded30d9 chore(release): 11.0.0-beta.2 v11.0.0-beta.2 2026-03-21 13:32:00 +01:00
Zoltan Kochan
bb9226cd98 fix: ensure PNPM_HOME/bin is in PATH during pnpm setup
When upgrading from old pnpm (global bin = PNPM_HOME) to new pnpm
(global bin = PNPM_HOME/bin), `pnpm setup` would fail because the
spawned `pnpm add -g` checks that the global bin dir is in PATH.
Prepend PNPM_HOME/bin to PATH in the spawned process env so the
check passes during the transition.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 13:30:07 +01:00
Zoltan Kochan
0ba71da576 chore(release): 11.0.0-beta.1 v11.0.0-beta.1 2026-03-21 12:57:49 +01:00
Zoltan Kochan
9b801c888d fix: check allowBuild for packages with cached side-effects (#11039)
Closes #11035

## Summary

### Root cause fix: don't apply cached side-effects for unapproved packages
When importing packages from the store, side-effects cache was applied for any package not explicitly denied (`allowBuild !== false`). This meant unapproved packages (`allowBuild === undefined`) got cached build artifacts, setting `isBuilt: true` and bypassing the `allowBuild` check in `buildModules`.

**Fix:** Only apply side-effects cache when `allowBuild` returns `true` (explicitly approved). Changed in three locations:
- `installing/deps-restorer/src/index.ts` (isolated linker)
- `installing/deps-restorer/src/linkHoistedModules.ts` (hoisted linker)
- `installing/deps-installer/src/install/link.ts` (non-headless install)

### Revocation detection
When a package's build approval is revoked between installs (was `true` in `.modules.yaml`, now undefined), detect it in `mutateModules` and add to `ignoredBuilds` so `strictDepBuilds` fails.

### Status messages in `_rebuild`
Users now see what happened to each package during rebuild:
- `pkg@version: built successfully`
- `pkg@version: skipped (no build scripts)`
- `pkg@version: skipped (not allowed)`
- `pkg@version: reused from store cache`

And during install:
- `pkg@version: reused from store (side effects cache)`

### `buildSelectedPkgs` fixes
- Preserve `storeDir`, `virtualStoreDir`, `virtualStoreDirMaxLength` from existing `.modules.yaml` instead of overwriting with config-derived values (which caused "reinstall from scratch" prompt)
- Write `allowBuilds` to `.modules.yaml` so GVS doesn't detect a mismatch on next install
- Merge `ignoredBuilds` with existing entries for packages not being rebuilt
2026-03-21 12:51:24 +01:00
Zoltan Kochan
9fc552d37a fix: update GVS symlinks after approve-builds by running install (#11043)
Fixes #11042

- **Root cause**: When `enableGlobalVirtualStore` is true and `allowBuilds` is not configured, `createAllowBuildFunction()` returned `undefined`, causing all GVS hashes to include `ENGINE_NAME`. When `approve-builds` later configured `allowBuilds`, the hash didn't change because the engine was already included.
- **Fix**: Default `allowBuilds` to `{}` in GVS mode so hashes are engine-agnostic by default, and have `approve-builds` call `install.handler()` in GVS mode instead of the low-level `install()` function, so it properly handles workspaces and updates symlinks.
- **Refactor**: Broke circular dependencies between `building/commands`, `installing/commands`, and `global/commands` using dependency injection via a `commands` map passed as the third argument to command handlers. Added `CommandHandler` and `CommandHandlerMap` types to `@pnpm/cli.command`.

## Changes

### Architecture
- Command handlers now receive a `commands` map as an optional third argument `(opts, params, commands?)`
- The CLI dispatcher in `main.ts` passes the full commands map to every handler
- Handlers that need other commands (e.g., `globalAdd` needs `approve-builds`, `recursive` needs `rebuild`) access them from this map
- This replaces direct cross-package imports that would create circular dependencies

### Packages changed
- `@pnpm/cli.command` — new `CommandHandler` and `CommandHandlerMap` types
- `@pnpm/building.commands` — `approve-builds` uses `install.handler` for GVS
- `@pnpm/global.commands` — removed `building/commands` dependency; receives `approve-builds` via commands map
- `@pnpm/installing.commands` — receives `rebuild` via commands map instead of direct import
- `@pnpm/installing.deps-installer` / `@pnpm/installing.deps-restorer` — default `allowBuilds` to `{}` in GVS mode
- `pnpm` CLI — dispatcher passes commands map to all handlers
2026-03-21 12:50:46 +01:00
Brandon Cheng
659bb13793 test: wait for Verdaccio to come online before running tests (#11037) 2026-03-21 11:56:09 +01:00
Zoltan Kochan
f0ae1b97d7 fix: store global binaries in PNPM_HOME/bin subdirectory (#11038)
Previously, globally installed binaries were placed directly in
PNPM_HOME, which also contains internal directories (global/, store/).
This polluted shell autocompletion with non-executable entries.

Now binaries are stored in PNPM_HOME/bin, keeping the PATH clean.

Closes #10986
2026-03-20 18:16:52 +01:00
Zoltan Kochan
0407e36ab2 feat: support hidden scripts starting with '.' (#11041)
Scripts starting with '.' are hidden:
- Cannot be run directly via 'pnpm run .script' (throws HIDDEN_SCRIPT error)
- Can only be called from other scripts (detected via npm_lifecycle_event)
- Omitted from 'pnpm run' listing

This allows packages to have internal scripts that are implementation
details, preventing accidental direct execution. Similar to how
dotfiles are hidden in file systems.
2026-03-20 17:59:11 +01:00
Zoltan Kochan
996284f8cc feat(approve-builds): positional args, !pkg deny syntax, and auto-populate allowBuilds (#11030)
### `pnpm approve-builds` positional arguments
- `pnpm approve-builds foo` — approves `foo`, leaves everything else untouched
- `pnpm approve-builds !bar` — denies `bar`, leaves everything else untouched
- `pnpm approve-builds foo !bar` — approves `foo`, denies `bar`
- Only mentioned packages are modified; unmentioned packages remain pending
- `--all` cannot be combined with positional arguments
- Contradictory arguments (`pkg !pkg`) are rejected

### Auto-populate `allowBuilds` during install
- When `pnpm install` encounters packages with build scripts that aren't yet in `allowBuilds`, they are automatically written to `pnpm-workspace.yaml` with a `'set this to true or false'` placeholder
- Users can then edit the config directly instead of running `approve-builds`
- The placeholder behaves like a missing entry: builds are skipped and `strictDepBuilds` still fails
- Existing `allowBuilds` entries are preserved (only new packages get placeholders)
2026-03-20 14:58:56 +01:00
Rohan Santhosh Kumar
f7960244ea docs(contributing): fix commit message guideline wording (#11036)
Co-authored-by: rohan436 <rohan.santhoshkumar@googlemail.com>
2026-03-20 11:23:09 +01:00
Zoltan Kochan
cd0e887db3 refactor: remove unused @pnpm/fs.msgpack-file package and lockfile-directory setting (#11033)
Remove the @pnpm/fs.msgpack-file package which was never imported in
source code (only in its own tests). Also remove the deprecated
lockfile-directory CLI option alias — users should use lockfile-dir.
2026-03-20 00:38:02 +01:00
Zoltan Kochan
a4a691a801 chore: update symlink-dir 2026-03-19 23:34:53 +01:00
Zoltan Kochan
0d88df854f chore: update all dependencies to latest versions (#11032)
* chore: update all dependencies to latest versions

Update all outdated dependencies across the monorepo catalog and fix
breaking changes from major version bumps.

Notable updates:
- ESLint 9 → 10 (fix custom rule API, disable new no-useless-assignment)
- @stylistic/eslint-plugin 4 → 5 (auto-fixed indent changes)
- @cyclonedx/cyclonedx-library 9 → 10 (adapt to removed SPDX API)
- esbuild 0.25 → 0.27
- TypeScript 5.9.2 → 5.9.3
- Various @types packages, test utilities, and build tools

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update unified/remark/mdast imports for v11/v4 API changes

Update imports in get-release-text for the new ESM named exports:
- mdast-util-to-string: default → { toString }
- unified: default → { unified }

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: resolve typecheck errors from dependency updates

- isexe v4: use named import { sync } instead of default export
- remark-parse/remark-stringify v11: add vfile as packageExtension
  dependency so TypeScript can resolve type declarations
- get-release-text: remove unused @ts-expect-error directives

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: revert runtime dependency major version bumps

Revert major version bumps for runtime dependencies that are bundled
into pnpm to fix test failures where pnpm add silently fails:
- bin-links: keep ^5.0.0 (was ^6.0.0)
- cli-truncate: keep ^4.0.0 (was ^5.2.0)
- delay: keep ^6.0.0 (was ^7.0.0)
- filenamify: keep ^6.0.0 (was ^7.0.1)
- find-up: keep ^7.0.0 (was ^8.0.0)
- isexe: keep 2.0.0 (was 4.0.0)
- normalize-newline: keep 4.1.0 (was 5.0.0)
- p-queue: keep ^8.1.0 (was ^9.1.0)
- ps-list: keep ^8.1.1 (was ^9.0.0)
- string-length: keep ^6.0.0 (was ^7.0.1)
- symlink-dir: keep ^7.0.0 (was ^9.0.0)
- terminal-link: keep ^4.0.0 (was ^5.0.0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: restore runtime dependency major version bumps

Re-apply all runtime dependency major version bumps that were
previously reverted. All packages maintain their default exports
except isexe v4 which needs named imports.

Updated runtime deps:
- bin-links: ^5.0.0 → ^6.0.0
- cli-truncate: ^4.0.0 → ^5.2.0
- delay: ^6.0.0 → ^7.0.0
- filenamify: ^6.0.0 → ^7.0.1
- find-up: ^7.0.0 → ^8.0.0
- isexe: 2.0.0 → 4.0.0 (fix: use named import { sync })
- normalize-newline: 4.1.0 → 5.0.0
- p-queue: ^8.1.0 → ^9.1.0
- ps-list: ^8.1.1 → ^9.0.0
- string-length: ^6.0.0 → ^7.0.1
- symlink-dir: ^7.0.0 → ^9.0.0
- terminal-link: ^4.0.0 → ^5.0.0

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: revert tempy to 3.0.0 to fix bundle hang

tempy 3.2.0 pulls in temp-dir 3.0.0 which uses async fs.realpath()
inside its module init. When bundled by esbuild into the __esm lazy
init pattern, this causes a deadlock during module initialization,
making the pnpm binary hang silently on startup.

Keeping tempy at 3.0.0 which uses temp-dir 2.x (sync fs.realpathSync).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add comment explaining why tempy cannot be upgraded

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: revert nock to 13.3.4 for node-fetch compatibility

nock 14 changed its HTTP interception mechanism in a way that doesn't
properly intercept node-fetch requests, causing audit tests to hang
waiting for responses that are never intercepted.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* docs: add comment explaining why nock cannot be upgraded

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: update symlink-dir imports for v10 ESM named exports

symlink-dir v10 removed the default export and switched to named
exports: { symlinkDir, symlinkDirSync }.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: revert @typescript/native-preview to working version

Newer tsgo dev builds (>= 20260318) have a regression where
@types/node cannot be resolved, breaking all node built-in types.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: vulnerabilities

* fix: align comment indentation in runLifecycleHook

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: pin msgpackr to 1.11.8 for TypeScript 5.9 compatibility

msgpackr 1.11.9 has broken type definitions that use Iterable/Iterator
without required type arguments, causing compile errors with TS 5.9.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 23:28:53 +01:00
Zoltan Kochan
812cae93d6 test(releasing): fix 2026-03-19 19:02:17 +01:00
Zoltan Kochan
6d0eeeeafb chore: remove npm_config_verify_deps_before_run from extraEnv (#11029)
This was marked for removal in v11. Only the pnpm_config_ prefixed
version is kept.

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:53:42 +01:00
Zoltan Kochan
f1dbe4edf8 feat!: stop falling back to npm CLI for unimplemented commands (#10642)
* feat!: stop falling back to npm CLI

* chore: update pnpm-lock.yaml

* fix: resolve conflicts

* revert: keep falling back to npm CLI for config get/set

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: lint errors in notImplemented.ts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: update changeset description

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* feat: suggest using npm CLI in not-implemented error message

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: address review comments

- Check combined stdout+stderr in test for ERR_PNPM_NOT_IMPLEMENTED
- Skip unknown options validation for not-implemented commands
- Mention aliases (s, se, v) in changeset

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 15:46:00 +01:00
zybo
194d36856e feat(ci): implement pnpm ci command (#11003)
* feat(ci): implement pnpm ci command

This implements the `pnpm ci` (clean-install) command, which is similar
to `npm ci`. The command:

- Removes `node_modules` before installation (clean install)
- Installs dependencies from the lockfile with `--frozen-lockfile`
- Fails if the lockfile is missing or out of sync with `package.json`
- Supports workspaces (removes `node_modules` from all workspace projects)

This is useful for CI/CD environments where you want to ensure
reproducible builds.

Aliases: `pnpm clean-install`, `pnpm ic`, `pnpm install-clean`

Closes #6100

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

* chore: update tsconfig.json references

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

* refactor(ci): simplify pnpm ci to compose clean + install --frozen-lockfile

Per maintainer feedback, simplify the ci command to just call
`clean.handler()` then `install.handler()` with frozenLockfile: true,
following the same composition pattern as installTest.

Moved ci command from installing/commands to pnpm/src/cmd/ where it
can import both clean and install handlers directly.

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

* refactor(ci): remove ci stub from installing/commands

The ci command now lives entirely in pnpm/src/cmd/ci.ts,
so the old stub in installing/commands is no longer needed.

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

* refactor(ci): rename ci.ts to cleanInstall.ts

Per reviewer feedback, use the full command name for the file.

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

* fix(ci): use non-dotfile marker in ci test

The clean command preserves dotfiles in node_modules (except pnpm's
own .bin, .modules.yaml, .pnpm), so the test marker starting with "."
was not being removed. Renamed to a regular file name.

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

---------

Co-authored-by: zubeyralmaho <zubeyralmaho@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-19 14:43:05 +01:00
Zoltan Kochan
94ca54e20b fix: reuse sortLockfileKeys for env lockfile sorting (#11026)
Replace the custom sortEnvLockfile function with the shared
sortLockfileKeys, ensuring env lockfile fields are sorted
consistently with the main lockfile document.
2026-03-19 13:27:29 +01:00
Zoltan Kochan
1a09015839 chore: update pnpm to v11 beta 0 2026-03-19 11:49:56 +01:00
Zoltan Kochan
a798efeb4d chore(release): 11.0.0-beta.0 v11.0.0-beta.0 2026-03-19 11:19:27 +01:00
Rohan Santhosh Kumar
4d1cb4749f docs: fix --force help text grammar (#11023)
Co-authored-by: rohan436 <rohan.santhoshkumar@googlemail.com>
2026-03-19 10:46:49 +01:00
Brandon Cheng
b3c2b6c1ff build: use stripTypeScriptTypes transform mode for source map support (#11024) 2026-03-19 10:45:50 +01:00
Zoltan Kochan
1701a65845 chore: reduce noisy warnings in test output (#11022)
* chore: reduce noisy warnings in test output

- Suppress ExperimentalWarning and DEP0169 via --disable-warning in NODE_OPTIONS
- Fix MaxListenersExceededWarning by raising limit in StoreIndex when adding exit listeners
- Update meta-updater to generate the new _test scripts

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: stop streaming pnpm subprocess output during CLI tests

Buffer stdout/stderr from execPnpm instead of writing to the parent
process in real time. Output is still included in the error message on
failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: pipe all subprocess output in CLI tests

Use stdio: 'pipe' for all pnpm/pnpx spawn helpers so subprocess output
is buffered instead of printed. Output is still included in error
messages on failure.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove duplicate @pnpm/installing.env-installer in pnpm/package.json

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* chore: use pipe stdio in dlx and errorHandler tests

Replace stdio: 'inherit' and [null, 'pipe', 'inherit'] with 'pipe' to
prevent subprocess output from leaking into test output.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: skip maxListeners adjustment when set to unlimited (0)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 10:43:12 +01:00
Zoltan Kochan
0b33718dbe refactor: merge @pnpm/fs.find-packages into @pnpm/workspace.projects-reader (#11021)
* refactor: merge @pnpm/fs.find-packages into @pnpm/workspace.projects-reader

The find-packages package had only one production consumer (projects-reader).
Inlining it removes a separate published package with minimal value as a
standalone utility.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: sort devDependencies and add tsconfig reference for meta-updater

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: remove circular tsconfig reference

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: exclude circular tsconfig reference in meta-updater

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* refactor: move getConfig from cli/utils to pnpm CLI package

getConfig and installConfigDepsAndLoadHooks were the only functions in
cli/utils that pulled in heavy deps (env-installer, store.connection-manager,
hooks.pnpmfile, default-reporter). Moving them to the pnpm CLI package
(their only consumer) dramatically reduces the dependency weight of
cli/utils, breaking the circular tsconfig reference chain that previously
required fs.find-packages to be a separate package.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* fix: sort imports

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 01:45:24 +01:00
Zoltan Kochan
4d2afef9be fix: don't exclude workspace root from recursive
It's a fix because it fixes a regression introduced by 2e55dcf130,
and it's a patch-level change since it's a bug
  fix.
2026-03-19 01:44:13 +01:00
Dasa Paddock
2e55dcf130 fix: default to ['.'] for workspacePackagePatterns when packages field is missing (#10996)
Commit 6eedf828b removed the ['.'] fallback for workspacePackagePatterns
when pnpm-workspace.yaml has no packages field. This caused findPackages
to default to ['.', '**'], discovering ALL directories with package.json
as workspace projects. This is the same regression that was previously
reverted in 595cd414f (close #10571), reintroduced by #10127.

Projects like cdxgen that use pnpm-workspace.yaml only for settings
(e.g. minimumReleaseAge) without a packages field were broken because
test data directories were picked up as workspace projects.

close #10909
2026-03-19 00:59:19 +01:00
Zoltan Kochan
0c8ac8201e docs: update sponsors 2026-03-18 23:17:12 +01:00
Zoltan Kochan
88ad21dff8 feat(publish): handle OTP and web-based authentication flows (#11019)
* feat(publish): handle OTP and web-based authentication flows (#10834)

Add OTP handling to `pnpm publish` with support for:
- Classic OTP prompt (manual code entry)
- Web-based authentication flow with QR code display and doneUrl polling
- `npm-auth-type: web` header to signal web auth support to the registry

Extract OTP logic into a dedicated `otp.ts` module with dependency
injection for testability. Consolidate shared context for OIDC and OTP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

* Potential fix for pull request finding

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-03-18 23:11:17 +01:00
Zoltan Kochan
d52f25d18c feat: auto-start Claude to review PRs in wt.fish (#11018)
When `wt` is called with a PR number, automatically launch Claude Code
to analyze the PR diff, read review comments, resolve merge conflicts
with the base branch, fix issues, and run tests.
2026-03-18 22:40:11 +01:00
Copilot
af4cba7e4a chore: add .devcontainer for GitHub Codespaces (#11015)
* Initial plan

* chore: add .devcontainer for GitHub Codespaces support

Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>

* docs: remove comments

* fix: chown pnpm home to node user in onCreateCommand to fix EACCES on volume mount

Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>

* fix: consolidate devcontainer setup into updateContentCommand

Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>

* fix: replace corepack with pnpm install script in devcontainer

Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>

* chore: remove error-prone `PNPM_VERSION` expression

* fix: add pnpm to PATH via remoteEnv in devcontainer

Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>

* fix: removing copilot's bullshit

* chore(git): revert erroneous change

I don't understand why it didn't work

This reverts commit eb01873dbd.

* chore(git): revert erroneous change

I don't understand why it didn't work

This reverts commit 4ebbb6467d.

* chore(git): revert erroneous change

I don't understand why it didn't work

This reverts commit 468848e4da.

* chore(git): revert erroneous change

I don't understand why it didn't work

This reverts commit c4f9e64402.

---------

Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: KSXGitHub <11488886+KSXGitHub@users.noreply.github.com>
Co-authored-by: Khải <hvksmr1996@gmail.com>
2026-03-18 21:57:53 +01:00
Zoltan Kochan
8acf2708c9 refactor: rename deps-resolver and env-installer packages (#11013)
Rename @pnpm/installing.resolve-dependencies to @pnpm/installing.deps-resolver
for consistency with the <domain>.<leaf> naming convention.
2026-03-18 21:52:01 +01:00
Zoltan Kochan
303ca410f5 feat!: stop reading settings from the pnpm field of package.json (#10086)
Settings should be read from pnpm-workspace.yaml
2026-03-18 14:46:07 +01:00
Zoltan Kochan
07304b9282 fix: set worktree upstream via git-config to avoid missing remote-tracking ref
The targeted fetch refspec doesn't create a remote-tracking branch,
causing `git branch --set-upstream-to` to fail. Use `git config` to
set branch.remote and branch.merge directly instead.
2026-03-18 12:04:09 +01:00
Zoltan Kochan
d0ae78821a refactor: rename workspace functions from packages to projects (#11002)
Align function, type, and file names with the packages-to-projects
rename in workspace packages (projects-filter, projects-reader,
projects-sorter).
2026-03-18 11:38:02 +01:00
Zoltan Kochan
dba4153767 refactor: rename packages and consolidate runtime resolvers (#10999)
* refactor: rename workspace.sort-packages and workspace.pkgs-graph

- workspace.sort-packages -> workspace.projects-sorter
- workspace.pkgs-graph -> workspace.projects-graph

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

* refactor: rename packages/ to core/ and pkg-manifest.read-package-json to reader

- Rename packages/ directory to core/ for clarity
- Rename pkg-manifest/read-package-json to pkg-manifest/reader (@pnpm/pkg-manifest.reader)
- Update all tsconfig, package.json, and lockfile references

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

* refactor: consolidate runtime resolvers under engine/runtime domain

- Remove unused @pnpm/engine.runtime.node.fetcher package
- Rename engine/runtime/node.resolver to node-resolver (dash convention)
- Move resolving/bun-resolver to engine/runtime/bun-resolver
- Move resolving/deno-resolver to engine/runtime/deno-resolver
- Update all package names, tsconfig paths, and lockfile references

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

* chore: update lockfile after removing node.fetcher

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

* fix: sort tsconfig references and package.json deps alphabetically

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

* fix: auto-fix import sorting

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

* fix: update __typings__ paths in tsconfig.lint.json for moved resolvers

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

* fix: remove deno-resolver from deps of bun-resolver

---------

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-18 00:19:58 +01:00