Commit Graph

327 Commits

Author SHA1 Message Date
Zoltan Kochan
2c36c4e3e1 Merge branch 'release/11.0' 2026-04-30 23:19:31 +02:00
Zoltan Kochan
6ef34b7a11 chore(release): 11.0.3 2026-04-30 23:03:46 +02:00
Charlie Croom
a99ffe0893 fix: also preserve relative symlinks in copy-artifacts.ts (release tarballs) (#11408)
#11399 fixed the fs.cpSync call in pnpm/artifacts/exe/scripts/build-artifacts.ts,
which controls the dist/ shipped inside the npm-published @pnpm/exe package.

But the GitHub release tarballs (pnpm-{darwin,linux}-{x64,arm64}.tar.gz) are
produced by a different script — __utils__/scripts/src/copy-artifacts.ts, run
via 'pn copy-artifacts' in the release workflow. That script has the same
fs.cpSync(...) call without verbatimSymlinks: true, so the broken absolute
symlinks under dist/node_modules/.bin/ pointing at /home/runner/work/pnpm/
pnpm/... still made it into the v11.0.2 GitHub release tarballs.

Apply the same one-line fix to that script so the next release ships clean
relative symlinks.

Follow-up to #11398.

🤖 Generated with [Amp](https://ampcode.com)

Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff

Co-authored-by: Amp <amp@ampcode.com>
2026-04-30 22:59:07 +02:00
Charlie Croom
b2c7489a01 fix: also preserve relative symlinks in copy-artifacts.ts (release tarballs) (#11408)
#11399 fixed the fs.cpSync call in pnpm/artifacts/exe/scripts/build-artifacts.ts,
which controls the dist/ shipped inside the npm-published @pnpm/exe package.

But the GitHub release tarballs (pnpm-{darwin,linux}-{x64,arm64}.tar.gz) are
produced by a different script — __utils__/scripts/src/copy-artifacts.ts, run
via 'pn copy-artifacts' in the release workflow. That script has the same
fs.cpSync(...) call without verbatimSymlinks: true, so the broken absolute
symlinks under dist/node_modules/.bin/ pointing at /home/runner/work/pnpm/
pnpm/... still made it into the v11.0.2 GitHub release tarballs.

Apply the same one-line fix to that script so the next release ships clean
relative symlinks.

Follow-up to #11398.

🤖 Generated with [Amp](https://ampcode.com)

Amp-Thread-ID: https://ampcode.com/threads/T-019dda79-b947-742f-8711-b6f83bcda9ff

Co-authored-by: Amp <amp@ampcode.com>
2026-04-30 18:22:29 +02:00
Zoltan Kochan
1ee8de4aea Merge branch 'release/11.0' 2026-04-30 17:23:30 +02:00
Zoltan Kochan
a53f78b111 chore(release): 11.0.2 2026-04-30 17:16:34 +02:00
Zoltan Kochan
d00b4952cd Merge branch 'release/11.0' into main 2026-04-29 23:05:17 +02:00
Zoltan Kochan
38ffda2a18 chore(release): 11.0.1 2026-04-29 23:00:21 +02:00
Zoltan Kochan
890efaf472 chore: use @zkochan/git-wt package for worktree creation (#11359)
* chore: use @zkochan/git-wt package for worktree creation

Replace the in-repo `worktree:new` script and `shell/wt.*` helpers with
the published `@zkochan/git-wt` package. Contributors now install it
globally (`pnpm add -g @zkochan/git-wt`) and enable the `wt` shell
function via `git-wt init <shell>`, which also makes `git wt <branch>`
available as a native git subcommand.

* chore: remove shell/cleanup-worktrees.sh

Its functionality is now available as `git-wt cleanup` in the
@zkochan/git-wt package, which contributors are already being directed
to install in CONTRIBUTING.md.

* docs: give copy-paste install commands for the wt shell function

Previously CONTRIBUTING.md said "add this line to your config" and showed
the snippet, making contributors open the rc file themselves. Replace with
a one-liner per shell that appends to the rc file and activates `wt` in the
current session in one go.
2026-04-24 09:09:18 +02:00
Zoltan Kochan
4d7cd56ccc chore: upgrade @typescript/native-preview to 7.0.0-dev.20260421.2 (#11332)
* chore: upgrade @typescript/native-preview to 7.0.0-dev.20260421.2

- Add explicit `types: ["node"]` to the shared tsconfig because tsgo
  20260421 no longer auto-acquires `@types/*` from `node_modules`.
- Refactor test files to explicitly import jest globals (`describe`,
  `it`, `test`, `expect`, `beforeEach`, etc.) from `@jest/globals`
  instead of relying on `@types/jest` ambient declarations. Under the
  new tsgo build, `import { jest } from '@jest/globals'` shadows the
  ambient `jest` namespace, breaking `@types/jest`'s `declare var
  describe: jest.Describe;` globals.
- Add `@jest/globals` to each package's devDependencies where tests
  now import from it, and add `@types/node` to packages that need it
  but were relying on hoisted resolution.
- Replace `fail()` calls with `throw new Error(...)` since `fail` is
  no longer globally available.

* chore: fix remaining tsgo type-strictness errors

- Strip `as <PnpmType>` casts on objects passed to toMatchObject /
  toStrictEqual / toEqual; @jest/globals rejects the typed objects
  (which include AsymmetricMatchers) vs. the repo-specific type.
- Type `jest.fn<...>()` explicitly where the mock's signature matters
  for toHaveBeenCalledWith.
- Replace `beforeEach(() => X)` with `beforeEach(() => { X })` so the
  return value is void, as the stricter jest typing requires.
- Use `expect.objectContaining({...})` in one place where the full
  expected object triggered stricter type resolution.
- Cast `prompt.mock.calls` arg through `as unknown as Record<...>[]`
  for patch.test.ts's nested-array matchers.
- Fix off-by-one `<reference path>` in pnpm/test/getConfig.test.ts
  that only surfaced now.
- Move `@jest/globals` from devDependencies to dependencies in the
  two `__utils__` packages that import it from `src/`.
- Clean up unused imports from the @jest/globals migration.

* chore: address Copilot review on #11332

- Move misplaced `@jest/globals` imports to the top import block in
  checkEngine, run.ts, and workspace/root-finder tests where the
  script dropped them below executable code.
- Replace `try { await x(); throw new Error('should have thrown') } catch`
  in bins/linker, lockfile/fs, and resolving/local-resolver tests with
  `await expect(x()).rejects.toMatchObject({...})`. The old pattern
  swallowed an unrelated `throw` if the under-test call silently
  succeeded, which would fail on the catch-block assertion with a
  misleading message.
2026-04-21 23:21:52 +02:00
Zoltan Kochan
187049055f chore: upgrade @typescript/native-preview to 7.0.0-dev.20260421.2 (#11332)
* chore: upgrade @typescript/native-preview to 7.0.0-dev.20260421.2

- Add explicit `types: ["node"]` to the shared tsconfig because tsgo
  20260421 no longer auto-acquires `@types/*` from `node_modules`.
- Refactor test files to explicitly import jest globals (`describe`,
  `it`, `test`, `expect`, `beforeEach`, etc.) from `@jest/globals`
  instead of relying on `@types/jest` ambient declarations. Under the
  new tsgo build, `import { jest } from '@jest/globals'` shadows the
  ambient `jest` namespace, breaking `@types/jest`'s `declare var
  describe: jest.Describe;` globals.
- Add `@jest/globals` to each package's devDependencies where tests
  now import from it, and add `@types/node` to packages that need it
  but were relying on hoisted resolution.
- Replace `fail()` calls with `throw new Error(...)` since `fail` is
  no longer globally available.

* chore: fix remaining tsgo type-strictness errors

- Strip `as <PnpmType>` casts on objects passed to toMatchObject /
  toStrictEqual / toEqual; @jest/globals rejects the typed objects
  (which include AsymmetricMatchers) vs. the repo-specific type.
- Type `jest.fn<...>()` explicitly where the mock's signature matters
  for toHaveBeenCalledWith.
- Replace `beforeEach(() => X)` with `beforeEach(() => { X })` so the
  return value is void, as the stricter jest typing requires.
- Use `expect.objectContaining({...})` in one place where the full
  expected object triggered stricter type resolution.
- Cast `prompt.mock.calls` arg through `as unknown as Record<...>[]`
  for patch.test.ts's nested-array matchers.
- Fix off-by-one `<reference path>` in pnpm/test/getConfig.test.ts
  that only surfaced now.
- Move `@jest/globals` from devDependencies to dependencies in the
  two `__utils__` packages that import it from `src/`.
- Clean up unused imports from the @jest/globals migration.

* chore: address Copilot review on #11332

- Move misplaced `@jest/globals` imports to the top import block in
  checkEngine, run.ts, and workspace/root-finder tests where the
  script dropped them below executable code.
- Replace `try { await x(); throw new Error('should have thrown') } catch`
  in bins/linker, lockfile/fs, and resolving/local-resolver tests with
  `await expect(x()).rejects.toMatchObject({...})`. The old pattern
  swallowed an unrelated `throw` if the under-test call silently
  succeeded, which would fail on the catch-block assertion with a
  misleading message.
2026-04-21 22:50:40 +02:00
Zoltan Kochan
fd437ded13 chore(release): 11.0.0-rc.4 2026-04-21 15:03:02 +02:00
Zoltan Kochan
21fa098e36 chore(release): always build artifacts 2026-04-21 00:57:19 +02:00
Zoltan Kochan
fcdd50aaa7 chore(release): 11.0.0-rc.3 2026-04-21 00:17:38 +02:00
Zoltan Kochan
5a293d250c refactor: rename @pnpm/exe platform packages to @pnpm/exe.<platform>-<arch>[-musl] (#11316)
* refactor: rename @pnpm/exe platform packages to @pnpm/exe.<platform>-<arch>[-musl]

Aligns pnpm's own published platform artifacts with the one naming
convention the rest of the codebase already uses (`process.platform`
values plus an explicit `-musl` libc suffix), matching what `pnpm
pack-app`, `pnpm add --os/--cpu/--libc`, `supportedArchitectures.os`,
and Node.js tarball names all already settled on.

Package renames:
- @pnpm/linux-x64          -> @pnpm/exe.linux-x64
- @pnpm/linux-arm64        -> @pnpm/exe.linux-arm64
- @pnpm/linuxstatic-x64    -> @pnpm/exe.linux-x64-musl   (new dir)
- @pnpm/linuxstatic-arm64  -> @pnpm/exe.linux-arm64-musl
- @pnpm/macos-x64          -> @pnpm/exe.darwin-x64
- @pnpm/macos-arm64        -> @pnpm/exe.darwin-arm64
- @pnpm/win-x64            -> @pnpm/exe.win32-x64
- @pnpm/win-arm64          -> @pnpm/exe.win32-arm64

GitHub release asset names follow suit (`pnpm-linuxstatic-x64.tar.gz`
-> `pnpm-linux-x64-musl.tar.gz`, `pnpm-macos-*` -> `pnpm-darwin-*`,
`pnpm-win-*` -> `pnpm-win32-*`). Internal artifact directories under
`pnpm/artifacts/` renamed to match, which drops the awkward mixed
naming between target and directory.

The umbrella package `@pnpm/exe` keeps its name so that `pnpm
self-update` from v10 and any `npm i -g @pnpm/exe` scripts continue to
resolve. Platform children can be renamed freely because npm/pnpm
filter optional deps by each child's `os`/`cpu`/`libc` manifest
fields, not by package names.

Also updates:
- `@pnpm/exe`'s `setup.js` (preinstall) and the self-updater's
  `linkExePlatformBinary` to look up the platform package by the new
  scheme, using `detect-libc` to append `-musl` on musl Linux hosts.
- `.meta-updater` optional-dependency list for @pnpm/exe.
- `copy-artifacts.ts` target list and Windows detection prefix.
- cspell wordlist (drops `linuxstatic`; it's no longer used anywhere).

Final transition publishes of the old package names (pointing at the
new ones so direct pins keep resolving) are a release-engineering step
handled separately.

Refs #11314.

* chore: keep "linuxstatic" in cspell wordlist for changeset references

* test(pack-app rename): cover the musl branch of platform-package-name lookup

Copilot flagged that the musl -> -musl suffix logic in setup.js's preinstall
and self-updater's linkExePlatformBinary had no regression coverage. Extract
the name-computation from both into small pure helpers and unit-test all
four matrix cases (linux+musl, linux+glibc, darwin, win32) plus the
win32 ia32->x86 arch normalization:

- pnpm/artifacts/exe/platform-pkg-name.js exposes `exePlatformPkgName`
  (returns `@pnpm/exe.<platform>-<arch>[-musl]`). setup.js imports it
  instead of inlining the logic; the new setup.test.ts block covers the
  four-case matrix without having to mock detect-libc or patch
  process.platform.
- engine/pm/commands/src/self-updater/installPnpm.ts exports a new
  `exePlatformPkgDirName` returning `exe.<platform>-<arch>[-musl]` (the
  scope-local dir). linkExePlatformBinary calls it; the new
  selfUpdate.test.ts block covers the same matrix.

Both helpers are deliberately pure so the non-musl CI host can still
exercise the musl code path.
2026-04-20 15:42:04 +02:00
Zoltan Kochan
96ece9d736 chore(release): 11.0.0-rc.2 2026-04-17 18:21:35 +02:00
Zoltan Kochan
f7c23231a9 chore(release): 11.0.0-rc.1 2026-04-16 01:18:55 +02:00
Zoltan Kochan
06d6c2d405 chore(release): 11.0.0-rc.0 2026-04-10 18:30:33 +02:00
Zoltan Kochan
fb58648b00 test: update registry-mock to v6 and fix test fixtures (#11223)
- Update `@pnpm/registry-mock` from 5.2.4 to 6.0.0-6
- Fix auth tests to use bearer token from `globalSetup` instead of hardcoding credentials
- Replace hardcoded integrity checksums with `getIntegrity()` from registry-mock in `customResolvers` tests
- Add `prepareFixtureWithIntegrity()` helper in deps-restorer tests to dynamically patch `@pnpm.e2e` integrity values in fixture lockfiles at runtime, so they don't go stale when registry-mock is updated
- Fix `workspace-external-depends-deep` fixture's current lockfile (was missing `packages/f` and `packages/g` importers)
- Remove unnecessary credentials from `gitChecks` tests (they reject before any registry interaction)
2026-04-08 11:45:38 +02:00
Zoltan Kochan
d6b8e281b6 chore: use pn instead of pnpm (#11124) 2026-03-28 11:55:51 +01:00
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
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
Brandon Cheng
659bb13793 test: wait for Verdaccio to come online before running tests (#11037) 2026-03-21 11:56:09 +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
Brandon Cheng
b3c2b6c1ff build: use stripTypeScriptTypes transform mode for source map support (#11024) 2026-03-19 10:45:50 +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
Zoltan Kochan
4a36b9a110 refactor: rename internal packages to @pnpm/<domain>.<leaf> convention (#10997)
## Summary

Rename all internal packages so their npm names follow the `@pnpm/<domain>.<leaf>` convention, matching their directory structure. Also rename directories to remove redundancy and improve clarity.

### Bulk rename (94 packages)

All `@pnpm/` packages now derive their name from their directory path using dot-separated segments. Exceptions: `packages/`, `__utils__/`, and `pnpm/artifacts/` keep leaf names only.

### Directory renames (removing redundant prefixes)

- `cli/cli-meta` → `cli/meta`, `cli/cli-utils` → `cli/utils`
- `config/config` → `config/reader`, `config/config-writer` → `config/writer`
- `fetching/fetching-types` → `fetching/types`
- `lockfile/lockfile-to-pnp` → `lockfile/to-pnp`
- `store/store-connection-manager` → `store/connection-manager`
- `store/store-controller-types` → `store/controller-types`
- `store/store-path` → `store/path`

### Targeted renames (clarity improvements)

- `deps/dependency-path` → `deps/path` (`@pnpm/deps.path`)
- `deps/calc-dep-state` → `deps/graph-hasher` (`@pnpm/deps.graph-hasher`)
- `deps/inspection/dependencies-hierarchy` → `deps/inspection/tree-builder` (`@pnpm/deps.inspection.tree-builder`)
- `bins/link-bins` → `bins/linker`, `bins/remove-bins` → `bins/remover`, `bins/package-bins` → `bins/resolver`
- `installing/get-context` → `installing/context`
- `store/package-store` → `store/controller`
- `pkg-manifest/manifest-utils` → `pkg-manifest/utils`

### Manifest reader/writer renames

- `workspace/read-project-manifest` → `workspace/project-manifest-reader` (`@pnpm/workspace.project-manifest-reader`)
- `workspace/write-project-manifest` → `workspace/project-manifest-writer` (`@pnpm/workspace.project-manifest-writer`)
- `workspace/read-manifest` → `workspace/workspace-manifest-reader` (`@pnpm/workspace.workspace-manifest-reader`)
- `workspace/manifest-writer` → `workspace/workspace-manifest-writer` (`@pnpm/workspace.workspace-manifest-writer`)

### Workspace package renames

- `workspace/find-packages` → `workspace/projects-reader`
- `workspace/find-workspace-dir` → `workspace/root-finder`
- `workspace/resolve-workspace-range` → `workspace/range-resolver`
- `workspace/filter-packages-from-dir` merged into `workspace/filter-workspace-packages` → `workspace/projects-filter`

### Domain moves

- `pkg-manifest/read-project-manifest` → `workspace/project-manifest-reader`
- `pkg-manifest/write-project-manifest` → `workspace/project-manifest-writer`
- `pkg-manifest/exportable-manifest` → `releasing/exportable-manifest`

### Scope

- 1206 files changed
- Updated: package.json names/deps, TypeScript imports, tsconfig references, changeset files, renovate.json, test fixtures, import ordering
2026-03-17 21:50:40 +01:00
Zoltan Kochan
7a304b17c4 refactor: rename directories and unify command packages per domain (#10993)
- Rename `installing/core` → `installing/deps-installer` and `installing/headless` → `installing/deps-restorer` for clearer naming
- Rename all `plugin-commands-*` directories to use `-commands` suffix convention
- Merge multiple command packages per domain into a single `commands/` directory (one commands package per domain rule):
  - `building/{build-commands,policy-commands}` → `building/commands`
  - `deps/compliance/{audit-commands,licenses-commands,sbom-commands}` → `deps/compliance/commands`
  - `deps/inspection/{listing-commands,outdated-commands}` → `deps/inspection/commands`
  - `store/{store-commands,inspecting-commands}` → `store/commands`
  - `releasing/{publish-commands,deploy-commands}` → `releasing/commands`
  - `cli/{completion-commands,doctor-commands}` → `cli/commands`
  - `engine/pm/{self-updater-commands,setup-commands}` → `engine/pm/commands`
  - `engine/runtime/{runtime-commands,env-commands}` → `engine/runtime/commands`
  - `cache/cache-commands` → `cache/commands`
- Fix relative paths in merged test files (pnpmBin, __typings__ references)
- Update jest config to ignore `utils/` dirs at any nesting depth under `test/`
- Fix stale package names in changeset files
2026-03-17 17:42:20 +01:00
Zoltan Kochan
f47ef4b125 refactor: reorganize monorepo domain structure (#10987)
Reorganize the monorepo's top-level domain directories for clarity:

- pkg-manager/ split into:
  - installing/ (core, headless, client, resolve-dependencies, etc.)
  - installing/linking/ (hoist, direct-dep-linker, modules-cleaner, etc.)
  - bins/ (link-bins, package-bins, remove-bins)
- completion/ merged into cli/
- dedupe/ moved to installing/dedupe/
- env/ renamed to engine/ with subdomains:
  - engine/runtime/ (node.fetcher, node.resolver, plugin-commands-env, etc.)
  - engine/pm/ (plugin-commands-setup, plugin-commands-self-updater)
- env.path moved to shell/
- tools/ and runtime/ dissolved
- reviewing/ and lockfile audit packages moved to deps/:
  - deps/inspection/ (list, outdated, dependencies-hierarchy)
  - deps/compliance/ (audit, licenses, sbom)
- registry/ moved to resolving/registry/
- semver/peer-range moved to deps/
- network/fetching-types moved to fetching/
- packages/ slimmed down, moving packages to proper domains:
  - calc-dep-state, dependency-path -> deps/
  - parse-wanted-dependency -> resolving/
  - git-utils -> network/
  - naming-cases -> text/
  - make-dedicated-lockfile -> lockfile/
  - render-peer-issues -> installing/
  - plugin-commands-doctor -> cli/
  - plugin-commands-init -> workspace/

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-17 13:45:54 +01:00
Zoltan Kochan
31858c544b refactor: merge env lockfile into pnpm-lock.yaml (#10964)
Instead of a separate pnpm-lock.env.yaml file, the env lockfile
(configDependencies and packageManagerDependencies) is now stored as
the first YAML document in pnpm-lock.yaml, separated by `---`.

The combined file starts with `---\n` when an env document is present,
allowing pnpm to check just the first 4 bytes to know whether
the file contains an env document. Reading uses streaming I/O that
stops as soon as the document separator is found, avoiding parsing
of the full lockfile.

Writing preserves both documents: when the env lockfile is updated
the main lockfile portion is kept, and vice versa.
2026-03-15 01:44:20 +01:00
Zoltan Kochan
251f8a3cfc chore: set up remote tracking for fork PRs in worktree helper (#10952)
When creating a worktree from a PR number, use `gh pr view` to get the
fork owner/repo and branch name, add the fork as a remote, and set the
upstream tracking branch. This makes `git push` work out of the box for
PRs from forks, matching the behavior of `gh pr checkout`.

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 13:13:35 +01:00
Zoltan Kochan
5d5818e44f style: enforce node: protocol for builtin imports (#10951)
Add n/prefer-node-protocol rule and autofix all bare builtin imports
to use the node: prefix. Simplify the simple-import-sort builtins
pattern to just ^node: since all imports now use the prefix.
2026-03-13 07:59:51 +01:00
Zoltan Kochan
1c8c4e49f5 style: add eslint-plugin-simple-import-sort (#10947)
Add eslint-plugin-simple-import-sort to enforce consistent import ordering:
- Node.js builtins first
- External packages second
- Relative imports last
- Named imports sorted alphabetically within each statement
2026-03-13 02:02:38 +01:00
Zoltan Kochan
39afb24ce6 chore: add worktree helper script and shell functions (#10938)
Adds a `pnpm worktree:new <branch>` script that creates a git worktree
as a sibling directory of the repo root, with branch slashes replaced by
dashes (e.g. `feat/foo` → `../feat-foo`). Shell helpers in `shell/wt.fish`
and `shell/wt.sh` wrap the script to also `cd` into the new worktree.
Documents setup and usage in CONTRIBUTING.md.
2026-03-11 22:59:42 +01:00
Zoltan Kochan
178f2210e3 fix: don't run pnpm install in the fixture dir, use a temp copy instead (#10936) 2026-03-11 20:09:57 +01:00
Zoltan Kochan
0fda5eaf0b fix: skip entries that disappear between readdirSync and lstatSync on Windows CI
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 19:41:40 +01:00
Zoltan Kochan
3a5bfaa94f chore: update zkochan packages to latest versions (#10930)
Update all packages from zkochan/packages to their latest major versions
and exclude them from minimumReleaseAge requirement. This includes
updating catalog entries, adapting to breaking API changes (default
exports replaced with named exports, sync functions renamed with Sync
suffix), and updating type declarations.
2026-03-11 13:47:46 +01:00
Brandon Cheng
01914345d5 build: enable @typescript-eslint/no-import-type-side-effects (#10630)
* build: enable `@typescript-eslint/no-import-type-side-effects`

* build: disable `@typescript-eslint/consistent-type-imports`

* chore: apply fixes for `no-import-type-side-effects`

pnpm exec eslint "**/src/**/*.ts" "**/test/**/*.ts" --fix
2026-03-08 00:02:48 +01:00
Zoltan Kochan
b7f0f21582 feat: use SQLite for storing package index in the content-addressable store (#10827)
## Summary

Replace individual `.mpk` (MessagePack) files under `$STORE/index/` with a single SQLite database at `$STORE/index.db` using Node.js 22's built-in `node:sqlite` module. This reduces filesystem syscall overhead and improves space efficiency for small metadata entries.

Closes #10826

## Design

### New package: `@pnpm/store.index`

A new `StoreIndex` class wraps a SQLite database with a simple key-value API (`get`, `set`, `delete`, `has`, `entries`). Data is serialized with msgpackr and stored as BLOBs. The table uses `WITHOUT ROWID` for compact storage.

Key design decisions:

- **WAL mode** enables concurrent reads from workers while the main process writes.
- **`busy_timeout=5000`** plus a retry loop with `Atomics.wait`-based `sleepSync` handles `SQLITE_BUSY` errors from concurrent access.
- **Performance PRAGMAs**: `synchronous=NORMAL`, `mmap_size=512MB`, `cache_size=32MB`, `temp_store=MEMORY`, `wal_autocheckpoint=10000`.
- **Write batching**: `queueWrites()` batches pre-packed entries from tarball extraction and flushes them in a single transaction on `process.nextTick`. `setRawMany()` writes immediate batches (e.g. from `addFilesFromDir`).
- **Lifecycle**: `close()` auto-flushes pending writes, runs `PRAGMA optimize`, and closes the DB. A `process.on('exit')` handler ensures cleanup even on unexpected exits.
- **`VACUUM` after `deleteMany`** (used by `pnpm store prune`) to reclaim disk space.

### Key format

Keys are `integrity\tpkgId` (tab-separated). Git-hosted packages use `pkgId\tbuilt` or `pkgId\tnot-built`.

### Shared StoreIndex instance

A single `StoreIndex` instance is threaded through the entire install lifecycle — from `createNewStoreController` through the fetcher chain, package requester, license scanner, SBOM collector, and dependencies hierarchy. This replaces the previous pattern of each component creating its own file-based index access.

### Worker architecture

Index writes are performed in the main process, not in worker threads. Workers send pre-packed `{ key, buffer }` pairs back to the main process via `postMessage`, where they are batched and flushed to SQLite. This avoids SQLite write contention between threads.

### SQLite ExperimentalWarning suppression

`node:sqlite` emits an `ExperimentalWarning` on first load. This is suppressed via a `process.emitWarning` override injected through esbuild's `banner` option, which runs on line 1 of both `dist/pnpm.mjs` and `dist/worker.js` — before any module that loads `node:sqlite`.

### No migration from `.mpk` files

Old `.mpk` index files are not migrated. Packages missing from the new SQLite index are re-fetched on demand (the same behavior as a fresh store).

## Changed packages

121 files changed across these areas:

- **`store/index/`** — New `@pnpm/store.index` package
- **`worker/`** — Write batching moved from worker module into `StoreIndex` class; workers send pre-packed buffers to main process
- **`store/package-store/`** — StoreIndex creation and lifecycle management
- **`store/cafs/`** — Removed `getFilePathInCafs` index-file utilities (no longer needed)
- **`store/pkg-finder/`** — Reads from StoreIndex instead of `.mpk` files
- **`store/plugin-commands-store/`** — `store status` uses StoreIndex
- **`store/plugin-commands-store-inspecting/`** — `cat-index` and `find-hash` use StoreIndex
- **`fetching/tarball-fetcher/`** — Threads StoreIndex through fetchers; git-hosted fetcher flushes before reading
- **`fetching/git-fetcher/`, `binary-fetcher/`, `pick-fetcher/`** — Accept StoreIndex parameter
- **`pkg-manager/`** — `client`, `core`, `headless`, `package-requester` thread StoreIndex
- **`reviewing/`** — `license-scanner`, `sbom`, `dependencies-hierarchy` accept StoreIndex
- **`cache/api/`** — Cache view uses StoreIndex
- **`pnpm/bundle.ts`** — esbuild banner for ExperimentalWarning suppression

## Test plan

- [x] `pnpm --filter @pnpm/store.index test` — Unit tests for StoreIndex CRUD and batching
- [x] `pnpm --filter @pnpm/package-store test` — Store controller lifecycle
- [x] `pnpm --filter @pnpm/package-requester test` — Package requester reads from SQLite index
- [x] `pnpm --filter @pnpm/tarball-fetcher test` — Tarball and git-hosted fetcher writes
- [x] `pnpm --filter @pnpm/headless test` — Headless install
- [x] `pnpm --filter @pnpm/core test` — Core install, side effects, patching
- [x] `pnpm --filter @pnpm/plugin-commands-rebuild test` — Rebuild reads from index
- [x] `pnpm --filter @pnpm/license-scanner test` — License scanning
- [x] e2e tests pass

🤖 Generated with [Claude Code](https://claude.com/claude-code)
2026-03-06 12:59:04 +01:00
Brandon Cheng
0bf7051fb3 build: enable TypeScript verbatimModuleSyntax compiler option (#10628)
* build: enable TypeScript `verbatimModuleSyntax`

* fix: use `import type` to elide import errors during bundling

```
> pnpm dlx node@runtime:24.6.0 bundle.ts

Error: R] Could not resolve "@npm/types"

    ../pkg-manifest/exportable-manifest/lib/transform/index.js:1:15:
      1 │ import {} from '@npm/types';
        ╵                ~~~~~~~~~~~~

  You can mark the path "@npm/types" as external to exclude it from the bundle, which will remove this error and leave the unresolved path in the bundle.

Error: Build failed with 1 error:
../pkg-manifest/exportable-manifest/lib/transform/index.js:1:15: ERROR: Could not resolve "@npm/types"
    at failureErrorWithLog (/home/runner/work/pnpm/pnpm/node_modules/.pnpm/esbuild@0.25.12/node_modules/esbuild/lib/main.js:1467:15)
```

* fix: use `import type` to elide import errors in tests
2026-03-05 12:07:28 +01:00
Zoltan Kochan
e91ced5c88 docs: update sponsors 2026-03-03 17:34:17 +01:00
Zoltan Kochan
e3ec45421b fix(assert-project): check for .exe when .cmd does not exist on Windows
After hardlinking node.exe directly instead of creating a cmd-shim,
the isExecutable utility needs to also accept .exe files on Windows.
2026-02-23 17:26:43 +01:00
Zoltan Kochan
f54347e415 feat: replace pkg with Node.js SEA for standalone executables (#10661)
* feat: switch from pkg to Node.js SEA for creating standalone executables

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

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

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

* refactor: externalize @reflink/reflink in esbuild bundle

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

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

* chore: update cspell list

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

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

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

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

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

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

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

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

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


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


* fix: propagate errors in copy-artifacts script

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


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

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

This eliminates reflink-utils.ts, its tests, and the code duplication with
copy-artifacts.ts.
2026-02-22 12:45:50 +01:00
Zoltan Kochan
f2a6d0684b docs: update sponsors 2026-02-10 21:22:23 +01:00
Brandon Cheng
1a5b5beea2 build: replace ts-jest with simple transformer (#10579)
* test: use `import type` in more places

Several tests are failing because a module isn't being mocked. This is
due to the mocked module being imported before the mock being set up.

Switching to `import type` should elide the import fully.

* build: replace ts-jest with simple transformer

* chore: remove `ts-jest`

* chore: remove babel dependencies from root project

* ci: use Node.js 22.13.0 (instead of 22.12.0)

Node.js 22.13.0 introduces the `stripTypeScriptTypes` function

* fix: copilot feedback
2026-02-09 11:35:22 +01:00
btea
623634537d fix: audit (#10475)
* fix: audit

* fix: update

* fix: update
2026-01-17 12:14:02 +01:00
Zoltan Kochan
e3b35b6f37 style: update eslint to v9 (#10474) 2026-01-17 12:01:23 +01:00