Skip to content

fix(plugins): repair managed npm openclaw peers#78291

Merged
steipete merged 1 commit into
mainfrom
fix-managed-npm-peer-links
May 6, 2026
Merged

fix(plugins): repair managed npm openclaw peers#78291
steipete merged 1 commit into
mainfrom
fix-managed-npm-peer-links

Conversation

@steipete

@steipete steipete commented May 6, 2026

Copy link
Copy Markdown
Contributor

Summary

  • remove stale managed-root openclaw manifest, lockfile, hidden lock, installed package state, and fallback bin shims before and after npm plugin installs, carrying forward fix(plugins): repair stale managed openclaw peers #78251 and fix(plugins): clear hidden npm lock during peer repair #78265 without globally omitting peers
  • reassert plugin-local node_modules/openclaw peer links after shared-root npm install, rollback, update, and uninstall mutations, so one plugin operation does not break already-installed SDK-using plugins
  • force safe npm commands out of inherited legacy/strict peer-dependency modes, document the managed npm peer contract, and add real npm e2e coverage for optional and required OpenClaw peers in the same managed npm root

Fixes #77959.
Supersedes #78251.
Supersedes #78265.
Related: #77412, #77544.

Real behavior proof

  • Behavior or issue addressed: managed npm plugin installs could leave or recreate root-level node_modules/openclaw, and later npm mutations could prune plugin-local node_modules/openclaw SDK peer links.
  • Real environment tested: Crabbox Blacksmith Linux Testbox tbx_01kqxzepj0hyhgz0aep7s41v0m, Node v24.13.0, npm 11.6.2, synced PR branch.
  • Exact steps or command run after this patch: pnpm crabbox:run -- --provider blacksmith-testbox --blacksmith-org openclaw --blacksmith-workflow .github/workflows/ci-check-testbox.yml --blacksmith-job check --blacksmith-ref main --idle-timeout 90m --ttl 240m --timing-json --shell -- "...default suite... && ...inherited legacy/strict peer-deps suite... && git diff --check"
  • Evidence after fix: terminal transcript excerpt from the Crabbox run:
provider=blacksmith-testbox id=tbx_01kqxzepj0hyhgz0aep7s41v0m sync=delegated auth=blacksmith
node=v24.13.0
npm=11.6.2
src/plugins/install.npm-spec.e2e.test.ts (3 tests)
  ✓ scrubs root openclaw materialized by required npm peers
  ✓ relinks managed npm sibling openclaw peers after later plugin installs
  ✓ pins a mutable npm tag to the version resolved before install
[test] passed 4 Vitest shards in 9.21s
[test] passed 3 Vitest shards in 6.74s
blacksmith run summary sync=delegated command=1m5.057s total=1m7.228s exit=0
  • Observed result after fix: both normal npm behavior and inherited legacy-peer-deps=true / strict-peer-deps=true environments passed; required peer root materialization was scrubbed, sibling peer links were relinked after later installs, stale root state/bin/hidden lock cleanup passed, and rollback/update/uninstall relink coverage passed.
  • What was not tested: no known gaps.

Verification

  • pnpm exec oxfmt --check --threads=1 src/plugins/install.ts src/plugins/install.npm-spec.e2e.test.ts src/plugins/install.npm-spec.test.ts
  • pnpm exec oxlint src/plugins/install.ts src/plugins/install.npm-spec.e2e.test.ts src/plugins/install.npm-spec.test.ts
  • pnpm test src/plugins/install.npm-spec.test.ts src/plugins/install.npm-spec.e2e.test.ts src/infra/npm-managed-root.test.ts src/plugins/uninstall.test.ts
  • pnpm test src/infra/safe-package-install.test.ts src/plugins/update.test.ts src/plugins/install.npm-spec.test.ts src/plugins/install.npm-spec.e2e.test.ts src/infra/npm-managed-root.test.ts src/plugins/uninstall.test.ts
  • git diff --check
  • Crabbox/Testbox tbx_01kqxytnvc6na979wskbmxx4cz: env NODE_OPTIONS=--max-old-space-size=4096 OPENCLAW_VITEST_MAX_WORKERS=1 pnpm check:changed
  • Crabbox/Testbox tbx_01kqxzepj0hyhgz0aep7s41v0m: default + inherited legacy-peer-deps=true/strict-peer-deps=true all-conditions suite passed, including stale root scrub, bin/hidden-lock cleanup, required peer root materialization scrub, sibling peer relink after later install, rollback, update, uninstall, safe npm env, and git diff --check

@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation size: L maintainer Maintainer-authored PR labels May 6, 2026
@clawsweeper

clawsweeper Bot commented May 6, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge.

Summary
The PR repairs managed npm openclaw peer cleanup/relinking across plugin install, rollback, and uninstall paths, hardens npm peer-dependency env defaults, updates docs/changelog, and adds unit/e2e coverage.

Reproducibility: yes. source-reproducible with high confidence from #77959 logs plus current-main code: the reported ERR_MODULE_NOT_FOUND occurs when an SDK-using npm plugin lacks a reachable node_modules/openclaw, and current main only repairs update-path links, not shared-root install/uninstall mutations.

Real behavior proof
Needs real behavior proof before merge: The PR currently has tests and Testbox commands only; it needs after-fix real setup output such as terminal logs, copied live output, a recording, or a linked artifact showing the repaired SDK-peer resolution path. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, ask a maintainer to comment @clawsweeper re-review.

Next step before merge
Manual review is needed because the PR has a protected maintainer label, lacks required real behavior proof, and the remaining cleanup gap should be addressed on the PR branch before merge.

Security
Cleared: The diff changes local managed npm cleanup/relinking and safe npm env defaults without adding dependencies, workflows, permissions, or new external code sources.

Review findings

  • [P2] Scrub openclaw from all manifest dependency fields — src/infra/npm-managed-root.ts:96-97
Review details

Best possible solution:

Keep the lifecycle repair, but scrub every root manifest dependency field that can name openclaw, preserve the green CI state, and add real affected-install proof before merge.

Do we have a high-confidence way to reproduce the issue?

Yes, source-reproducible with high confidence from #77959 logs plus current-main code: the reported ERR_MODULE_NOT_FOUND occurs when an SDK-using npm plugin lacks a reachable node_modules/openclaw, and current main only repairs update-path links, not shared-root install/uninstall mutations.

Is this the best way to solve the issue?

No, not yet. The lifecycle location is the right narrow fix, but the implementation should cover all stale root manifest fields and the PR still needs real behavior proof before it is the best merge candidate.

Full review comments:

  • [P2] Scrub openclaw from all manifest dependency fields — src/infra/npm-managed-root.ts:96-97
    repairManagedNpmRootOpenClawPeer only reads manifest.dependencies to decide whether to uninstall and the scrub path only removes dependencies.openclaw. If a legacy managed root has openclaw in optionalDependencies or peerDependencies, which the related repair context explicitly called out, this leaves the stale manifest entry behind so the next npm mutation can keep or recreate the root host package state.
    Confidence: 0.86

Overall correctness: patch is incorrect
Overall confidence: 0.84

What I checked:

  • Current-main install gap: Current main installs npm plugins by upserting a managed-root dependency and running npm install, with no stale root-level openclaw cleanup or sibling peer relink around that install path. (src/plugins/install.ts:1337, 98cbf7f11c35)
  • Current-main update repair exists: Current main already repairs missing openclaw peer links for recorded npm installs during update, so the PR is extending an existing lifecycle repair pattern. (src/plugins/update.ts:763, 98cbf7f11c35)
  • Latest head cleanup scope: The PR head only detects manifest.dependencies.openclaw before choosing uninstall vs prune, and later only scrubs dependencies.openclaw from package.json. (src/infra/npm-managed-root.ts:96, 0668a238c369)
  • Related repair context: The superseded managed-root repair PR explicitly listed stale root openclaw in dependencies, optionalDependencies, and peerDependencies as covered non-happy paths, which this PR says it carries forward. (5468e9ba2ea0)
  • Latest head fixed prior lint blocker: The latest PR head uses toSorted(...) in the managed-root package directory listing, so the earlier ClawSweeper Array#sort() finding no longer applies. (src/plugins/plugin-peer-link.ts:77, 0668a238c369)
  • CI status: Public check-runs for the latest head show the main check, lint, docs, build, security, and selected node shards completed successfully; skipped matrix shards are expected non-selected lanes. (0668a238c369)

Likely related people:

  • @ProspectOre: Authored the merged update-path peer-link repair that this PR extends into broader managed npm lifecycle handling. (role: introduced adjacent behavior; confidence: high; commits: fb42c722f0f5, d221d7b6a989; files: src/plugins/update.ts, src/plugins/update.test.ts)
  • @vincentkoc: Recent related work and current checkout history are tied to managed npm plugin install/update behavior and the peer-link helper surface. (role: adjacent owner; confidence: medium; commits: 4ee234f8ee48, d7dbf1150432; files: src/plugins/install.ts, src/plugins/plugin-peer-link.ts, src/infra/npm-managed-root.ts)
  • @steipete: Recent current-main work touches the same plugin/file-access area, and this PR is maintainer-labeled with this author carrying the replacement branch. (role: recent maintainer; confidence: medium; commits: b85b1c68d175; files: src/plugins/install.ts, src/plugins/plugin-peer-link.ts, src/infra/npm-managed-root.ts)
  • @Patrick-Erichsen: Authored the related hidden-lock cleanup PR stacked on the managed-root repair work that this PR says it supersedes. (role: adjacent maintainer; confidence: medium; commits: ff10c4716d63; files: src/infra/npm-managed-root.ts, src/plugins/install.npm-spec.test.ts)

Remaining risk / open question:

  • No after-fix real setup proof shows an SDK-peer plugin resolving openclaw/plugin-sdk/* after a later managed npm install/update/uninstall mutation.
  • The managed-root scrub path appears to leave stale openclaw entries in optionalDependencies or peerDependencies, which can let npm keep or recreate the root host package state this PR is meant to remove.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 98cbf7f11c35.

@steipete steipete force-pushed the fix-managed-npm-peer-links branch from 8258ed8 to ddd8c4a Compare May 6, 2026 05:20
@steipete steipete force-pushed the fix-managed-npm-peer-links branch 2 times, most recently from cae1401 to 0668a23 Compare May 6, 2026 05:57
@steipete steipete force-pushed the fix-managed-npm-peer-links branch from 0668a23 to b083d85 Compare May 6, 2026 06:19
Remove stale managed-root openclaw manifests, locks, hidden locks, and installed copies before npm plugin installs.

Relink plugin-local openclaw peer symlinks after shared-root npm install, rollback, update, and uninstall mutations so SDK-using plugins keep resolving openclaw/plugin-sdk/*.

Force safe npm commands out of inherited legacy/strict peer-dependency modes.

Co-authored-by: Vincent Koc <vincentkoc@ieee.org>

Co-authored-by: Patrick Erichsen <patrick.a.erichsen@gmail.com>
@steipete steipete force-pushed the fix-managed-npm-peer-links branch from b083d85 to 21abcc9 Compare May 6, 2026 06:24

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 21abcc9a07

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/plugins/install.ts
Comment on lines +1389 to 1395
await rollbackManagedNpmPluginInstall({
npmRoot,
packageName: parsedSpec.name,
targetDir: installRoot,
timeoutMs,
logger,
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep existing plugin files when npm update install fails

Calling rollbackManagedNpmPluginInstall on a non-zero npm install now removes targetDir and runs npm uninstall, which deletes the currently installed package when this path is hit during mode: "update" failures (for example, transient registry/network errors). In update.ts, failed installs are treated as “update failed, keep existing record,” so deleting the existing on-disk package turns a failed update into an unintended uninstall and leaves the recorded install path broken.

Useful? React with 👍 / 👎.

@steipete steipete merged commit 8e53349 into main May 6, 2026
122 of 124 checks passed
@steipete steipete deleted the fix-managed-npm-peer-links branch May 6, 2026 06:32
@steipete

steipete commented May 6, 2026

Copy link
Copy Markdown
Contributor Author

Landed via squash onto main.

  • Gate: Crabbox/Testbox tbx_01kqxzepj0hyhgz0aep7s41v0m all-conditions proof passed; CI check, check-lint, check-prod-types, check-test-types, check-docs, and related shards passed on the exact head.
  • Source head: 21abcc9
  • Squash commit: 8e53349

Thanks @vincentkoc and @Patrick-Erichsen for the original repair direction and coverage.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Improvements or additions to documentation maintainer Maintainer-authored PR size: L

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: @openclaw/codex peerDependency link not created on install — gateway lanes crash with ERR_MODULE_NOT_FOUND for openclaw/plugin-sdk/*

1 participant