SIGN IN SIGN UP

fix(link): scope `npm link <path> --workspace` to the workspace, not the root (#9592)

`npm link <path> --workspace=<ws>` did not scope the operation to the
target workspace.
The linked dependency was attached to the root project instead, and with
`--save` (or `--save-dev`/`--save-optional`/etc.) the `file:` spec was
written to the root `package.json` rather than `<ws>/package.json`.
`npm install <path> --workspace=<ws> --save` behaved correctly, so only
`npm link` was affected.

The cause is in `Link.linkInstall()` in `lib/commands/link.js`, which
built the local Arborist without the `workspaces` option and passed
`workspaces` only to `reify()`.
Arborist decides which node receives the `add` request from
`this.options.workspaces`, which is captured at construction time, not
from the reify-time option.
`buildIdealTree` merges reify options into a local variable and
`#parseSettings` never copies `options.workspaces` into `this.options`,
so the reify-time value never reached `#applyUserRequests`.
With `this.options.workspaces` left empty, the `add` and the save were
applied to the root node.

The fix passes `workspaces: this.workspaceNames` to the local Arborist
constructor, matching how `lib/commands/install.js` already does it.
Physical placement is unchanged: under the default `hoisted` strategy
the symlink still hoists to the root `node_modules`, identical to `npm
install --workspace`.

## References

<!-- List any relevant issues, pull requests, or external references -->
Fixes #9590
Related #9589
M
Manzoor Wani committed
1a9ce8e3f56ec26dd283b8957119f721d8d3fe5f
Parent: 00b9f9f
Committed by GitHub <noreply@github.com> on 6/22/2026, 4:11:33 PM