#20055: fix(plugins): strip workspace:* dev-deps before npm install
size: XS
## Summary
This PR fixes a long-standing issue where installing any OpenClaw extension or hook from the official NPM registry fails. The failure is caused by `devDependencies` in the published `package.json` files containing `pnpm`'s `workspace:*` protocol, which `npm` cannot parse.
Even though `npm install` is run with `--omit=dev`, `npm` still parses the entire `package.json` before handling that flag, leading to a fatal `EUNSUPPORTEDPROTOCOL` error.
This fix introduces a helper function, `stripWorkspaceDevDeps`, which is called right before `npm install` inside the generic `installPackageDir` utility. This function reads the `package.json` of the package being installed, removes any `devDependencies` that use the `workspace:` protocol, and writes the cleaned `package.json` back to disk. The subsequent `npm install` can then proceed without parsing errors.
## Test Plan
This change was manually verified:
1. Created a test package with a `workspace:*` devDependency.
2. Confirmed that `npm install --omit=dev` fails with `EUNSUPPORTEDPROTOCOL`.
3. Programmatically removed the `workspace:*` dependency from `package.json`.
4. Confirmed that `npm install --omit=dev` then succeeds.
The fix is safe as it only modifies `devDependencies`, which are never installed anyway due to the `--omit=dev` flag. It correctly handles packages with no `devDependencies` or no `workspace:` specifiers.
Fixes #5780, #5292, #1839, #6879, #8145, #8492
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
This PR fixes a bug where installing OpenClaw extensions/hooks from the npm registry fails with `EUNSUPPORTEDPROTOCOL` because published `package.json` files contain pnpm `workspace:*` specifiers in `devDependencies` that `npm` cannot parse.
- Adds a `stripWorkspaceDevDeps` helper in `src/infra/install-package-dir.ts` that removes `workspace:` protocol entries from `devDependencies` before running `npm install`
- The fix is minimal and safe: it only modifies `devDependencies` (never installed due to `--omit=dev`), and only touches the target directory copy — not the source
- Confirmed that all 31 extension `package.json` files in the repo contain `"openclaw": "workspace:*"` in `devDependencies`, validating the real-world need for this fix
- The function correctly handles packages with no `devDependencies`, no `workspace:` specifiers, and mixed devDeps (only strips `workspace:` entries, keeps the rest)
<h3>Confidence Score: 4/5</h3>
- This PR is safe to merge — it makes a targeted, well-scoped fix that only modifies dev dependencies in a copied package directory before npm install.
- The change is small, well-documented, and addresses a real issue affecting all 31 extensions in the repo. The logic is straightforward with proper early-returns and guards. The only minor observation is that `stripWorkspaceDevDeps` is not wrapped in a try-catch (unlike the adjacent `afterCopy` call), but since the file was already validated by callers and just copied, failure is extremely unlikely in practice.
- No files require special attention
<sub>Last reviewed commit: fdb4a38</sub>
<!-- greptile_other_comments_section -->
<!-- /greptile_comment -->
Most Similar PRs
#11454: fix(plugins): remove workspace:* from extension dependencies
by AnonO6 · 2026-02-07
86.1%
#19941: fix(nostr): move openclaw from devDependencies to peerDependencies
by AustinEral · 2026-02-18
86.1%
#8500: fix: Remove workspace:* from devDependencies in voice-call plugin
by ImBIOS · 2026-02-04
85.9%
#20360: fix(feishu): remove workspace protocol from published package metadata
by tanujbhaud · 2026-02-18
82.0%
#16140: fix: convert installable extension deps from workspace:* to peerDep...
by battman21 · 2026-02-14
81.1%
#2556: fix(plugin-install): handle existing plugins and filter workspace deps
by longmaba · 2026-01-27
78.5%
#21039: Fix npm-spec plugin installs when npm pack output is empty
by graysurf · 2026-02-19
77.3%
#20424: Fix plugin extension path traversal in discovery/install
by markmusson · 2026-02-18
77.1%
#23337: fix: move @discordjs/opus to optionalDependencies [AI-assisted 🤖]
by davidmckenzie · 2026-02-22
77.0%
#22692: fix(memory-lancedb): [P1] add missing runtime deps — plugin broken ...
by mahsumaktas · 2026-02-21
76.4%