fix(arborist): surface undeclared workspaces under the linked strategy (#9657)
In continuation of our exploration of using `install-strategy=linked` in the [Gutenberg monorepo](https://github.com/WordPress/gutenberg/pull/75814), which powers the WordPress Block Editor. Under `install-strategy=linked`, a declared workspace that the root does not depend on is installed on disk but was invisible to `npm ls --all`, `npm ls --workspaces`, and `npm query ':root > *'`, all of which reported an empty tree. The hoisted strategy lists every workspace. Undeclared workspaces are intentionally not symlinked into the root `node_modules` under the linked strategy, so when `loadActual` rebuilds the actual tree (from the filesystem scan or the hidden lockfile, neither of which records a `node_modules/<ws>` entry) the root's `workspace` edges resolve to nothing and the workspaces drop out of the tree that `ls` and `query` traverse. `npm ls` then hid those missing edges entirely to avoid a false `UNMET DEPENDENCY`. The fix adds `loadActual` post-processing that, for the linked strategy, synthesizes an in-memory `Link` at `node_modules/<ws>` for each undeclared workspace so its root edge resolves, matching the logical layout the regular `package-lock.json` already records. This is introspection-only and writes nothing to disk. A declared workspace whose root link is genuinely missing is left alone so it still reports `UNMET`, an existing root child of the same name is never replaced, and a workspace that was not loaded is skipped. With the edges now resolving, the workspace-skip branch that `npm ls` used to suppress them is removed. ## References Fixes #9618
M
Manzoor Wani committed
ae6dbeb12a6f4b313a28c99068e34ba834ae91d1
Parent: 0c33947
Committed by GitHub <noreply@github.com>
on 6/25/2026, 8:14:07 PM