* docs: split AGENTS.md into shared + pacquet-specific
Before: root AGENTS.md and pacquet/AGENTS.md each maintained their own
copy of the GitHub PR workflow, agent-footer rule, "never ignore test
failures," Conventional Commits list, and code-reuse philosophy.
Drift waiting to happen.
After:
- Root AGENTS.md owns the shared conventions (PR workflow, agent
footer, conventional commits, code reuse, never-ignore-tests,
PR-conflict script) and marks TS-only sections explicitly
(setup/build, testing, linting, changesets, Standard Style, Jest
gotchas).
- pacquet/AGENTS.md opens with "Read ../AGENTS.md first" and keeps
only pacquet-specific rules (cardinal rule, branded types, just
recipes, insta snapshots, miette diagnostics, Rust style notes,
the `bench:` commit type, things-not-to-do that are Rust-flavored).
- Root adds a one-line entry for `pacquet/` in the repo structure
list so first-time readers find the cross-link.
CLAUDE.md and pacquet/{CLAUDE,GEMINI}.md are unchanged — they're
symlinks to AGENTS.md and follow automatically.
* docs(agents): require parity between pnpm and pacquet
Add a "Keep pnpm and pacquet in sync" section to root AGENTS.md spelling
out the bidirectional obligation: any user-visible change (CLI surface,
lockfile/manifest format, error codes, defaults, env-var handling, log
emissions, store layout) must land in both stacks in the same PR, or
the originating PR must spawn a tracking issue. Pure refactors / perf
wins / TS-only test cleanups don't need mirroring.
Cross-link from pacquet/AGENTS.md's "cardinal rule" so a pacquet-side
reader knows the obligation goes both ways and where the pnpm-side
version lives.
* docs(agents): restore Rust-specific dependency-level guidance
The root "Keep the dependency on the right level" bullet uses npm
vocabulary ("package," "shared package"). For a Rust reader that
required mentally translating "package" → "crate" and made the
workspace-vs-crate distinction less obvious. Restore the pacquet
phrasing alongside the existing pacquet-specific notes.
* docs(agents): hand off cross-stack porting via the same PR
Drop the "open a tracking issue" fallback — it lets one side drift
behind while the issue sits in the backlog. Instead, the PR author
opens the PR with their side and flags in the description what still
needs porting; someone else pushes the matching commits to the same
PR before it lands. Both sides land together or not at all.
* docs(agents): drop external-repo framing from the cardinal rule
pacquet now lives in the same repo as pnpm, so the cardinal rule no
longer needs the "fetch pnpm/pnpm main, compare ls-remote SHAs, watch
your local clone for drift" mechanics. The reference TypeScript code
is just a few directories over (`pnpm/`, `pkg-manager/`, `resolving/`,
`lockfile/`, `store/`, etc.), and pnpm is the source of truth by
position in the repo, not by branch tracking.
Updates:
- Root `AGENTS.md`: rephrase the cross-link line to drop the "follow
pnpm's main" framing.
- `pacquet/AGENTS.md` cardinal rule: redirect "find the equivalent
code" from `https://github.com/pnpm/pnpm` to the in-repo
TypeScript workspaces, drop the "confirm you're on the freshest
main" paragraph, and reword the source-of-truth wording.
- Permalink citation rule: generalize from "upstream pnpm" to "any
GitHub repository, including this one" — citation SHAs now usually
point at this repo's history.
* docs(agents): note pacquet's current scope is install-only
Without this caveat the parity rule reads as if every command needs
porting today. pacquet only implements `install` right now; resolution
and other commands (`update`, `add`, `remove`, `publish`, `exec`,
`run`, `dlx`, `audit`, etc.) live only in TypeScript, so changes there
don't need a pacquet-side port. The caveat also flags that the parity
rule's scope will widen as pacquet ports more commands.
Add a "Working with GitHub PRs, Issues, and Comments" section to AGENTS.md covering three rules:
Keep PR title and description current when pushing new changes.
Reply to resolved review comments with the resolution + commit hash and close the conversation.
Sign all agent-authored comments, issues, and PRs with a footer that names the agent and model.
* fix: respect frozen-lockfile flag when migrating config dependencies
* fix: throw FROZEN_LOCKFILE_WITH_OUTDATED_LOCKFILE when installing config deps with --frozen-lockfile
* fix: correct changeset package name and clean up minor issues
- Fix changeset referencing non-existent @pnpm/config.deps-installer
(should be @pnpm/installing.env-installer)
- Fix merge artifact in AGENTS.md
- Revert unnecessary Promise.all refactoring in migrateConfigDeps.ts
- Remove extra blank line in test file
* fix: move frozenLockfile check to call site and add missing tests
Move the frozenLockfile check from migrateConfigDepsToLockfile() to
normalizeForInstall() to minimize the number of check points.
Add unit tests for all frozenLockfile code paths:
- installConfigDeps: migration fails with frozenLockfile
- resolveAndInstallConfigDeps: old-format migration, new-format
resolution, and up-to-date lockfile success
- resolveConfigDeps: fails with frozenLockfile
* refactor: consolidate duplicate frozenLockfile checks in resolveAndInstallConfigDeps
Merge two identical frozenLockfile throw statements into a single check
covering both lockfileChanged and depsToResolve conditions.
* Delete respect-frozen-lockfile.md
* refactor: order fields
---------
Co-authored-by: Zoltan Kochan <z@kochan.io>
Add a "Resolving Conflicts in GitHub PRs" section to AGENTS.md with
step-by-step instructions for force-fetching refs, rebasing, resolving
lockfile conflicts, and verifying mergeability.
Add shell/resolve-pr-conflicts.sh that automates the workflow: fetches
metadata, force-updates the base ref, rebases, auto-resolves lockfile
conflicts via pnpm install, force-pushes, and verifies the result.
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