Zoltan Kochan 2c8f8ad60c feat(package-manager): wire nodeLinker=hoisted into install pipeline (#438 slice 6) (#518)
* feat(package-manager): wire node_linker hoisted into install pipeline (#438 slice 6)

Branches `Install::run` / `InstallFrozenLockfile::run` on
`config.node_linker == Hoisted`. Threads the slice 4
`lockfile_to_hoisted_dep_graph` walker output and the per-package CAS
index produced by `CreateVirtualStore` (slot writes skipped under
hoisted) into the slice 5 `link_hoisted_modules` linker. Persists the
walker's `hoisted_locations` into `.modules.yaml` for rebuild and
follow-up installs to consume.

Pipeline changes under hoisted:
- `CreateVirtualStore` skips `CreateVirtualDirBySnapshot` for both warm
  and cold batches, collects each snapshot's CAS file index keyed by
  `PkgIdWithPatchHash` into a new `cas_paths_by_pkg_id` output field.
- `InstallPackageBySnapshot::run` returns the per-package CAS map
  unconditionally and skips the virtual-store-slot write when its new
  `node_linker` field is `Hoisted`.
- `InstallFrozenLockfile::run` skips `SymlinkDirectDependencies`,
  `LinkVirtualStoreBins`, the isolated hoist pass, and `BuildModules`
  under hoisted; runs `lockfile_to_hoisted_dep_graph` +
  `link_hoisted_modules` in their place. Folds the walker's augmented
  skip set back into the install-time `SkippedSnapshots` so
  `.modules.yaml.skipped` reflects the union.
- `Install::run`'s `build_modules_manifest` now takes the walker's
  `hoisted_locations` and writes it through `Modules.hoisted_locations`
  (only when non-empty so the isolated path doesn't produce a
  hoisted-only key).

The build phase under hoisted (rebuild over `hoistedLocations` with
ancestor-`.bin` lookup, `MISSING_HOISTED_LOCATIONS`) is slice 7's
scope and is intentionally left as a no-op here. Workspace and
`hoistingLimits` / `externalDependencies` knobs are slices 9-10.

Mirrors upstream's hoisted branch in `headlessInstall` at
https://github.com/pnpm/pnpm/blob/94240bc046/installing/deps-restorer/src/index.ts#L369-L425.

---
Written by an agent (Claude Code, claude-opus-4-7).

* fix(package-manager): docs intra-link disambiguation + skip-set merge fix (#438 slice 6)

Docs CI was failing because `[`crate::link_hoisted_modules`]` is
ambiguous between the function and the module of the same name.
Disambiguate by switching to the function form
`[`crate::link_hoisted_modules()`]` everywhere.

Slice 6's hoisted-walker skip-set merge previously folded every entry
in `walker_result.skipped` into `SkippedSnapshots::insert_installability`,
which would promote pre-existing transient skips
(`fetch_failed` / `optional_excluded`) into the persisted-on-disk
`.modules.yaml.skipped` set. Diff against the input `walker_skipped`
so only walker-discovered (genuinely-new) installability skips flow
into the persisted subset.
2026-05-14 08:16:35 +02:00
Description
No description provided
MIT 280 MiB
Languages
Rust 56.5%
TypeScript 43%
JavaScript 0.4%