Skip to content

fix: isolate plugin test helpers from sdk exports#87120

Merged
RomneyDa merged 1 commit into
mainfrom
vitest-dev-dep-import-issue
May 27, 2026
Merged

fix: isolate plugin test helpers from sdk exports#87120
RomneyDa merged 1 commit into
mainfrom
vitest-dev-dep-import-issue

Conversation

@RomneyDa

@RomneyDa RomneyDa commented May 27, 2026

Copy link
Copy Markdown
Member

If you're here because your custom scripting that imports type file broke, sorry, I thought the tradeoff was worth it.

AI Stuff:

Package audit repro this fixes

This PR fixes the package-boundary failure found while validating openclaw@beta: a clean installed package exposed Vitest-backed Plugin SDK test-helper subpaths as public openclaw/plugin-sdk/* exports.

The audit found that clean consumers could import test-helper subpaths such as openclaw/plugin-sdk/plugin-test-contracts and openclaw/plugin-sdk/provider-test-contracts, and those imports then crashed with ERR_MODULE_NOT_FOUND: Cannot find package 'vitest'. The package exported repo-only test helpers even though vitest is a dev-only dependency.

Breaking change

The following accidental public package exports are removed from openclaw: openclaw/plugin-sdk/agent-runtime-test-contracts, openclaw/plugin-sdk/channel-contract-testing, openclaw/plugin-sdk/channel-target-testing, openclaw/plugin-sdk/channel-test-helpers, openclaw/plugin-sdk/plugin-test-api, openclaw/plugin-sdk/plugin-test-contracts, openclaw/plugin-sdk/plugin-test-runtime, openclaw/plugin-sdk/provider-http-test-mocks, openclaw/plugin-sdk/provider-test-contracts, openclaw/plugin-sdk/test-env, openclaw/plugin-sdk/test-fixtures, openclaw/plugin-sdk/test-node-mocks, and openclaw/plugin-sdk/testing.

This is a breaking package-boundary cleanup, but the removed surface is the Vitest-backed helper layer that should not have been a published runtime contract. Clean package consumers now get package subpath-not-exported for those helpers instead of a later missing-vitest crash. The public Plugin SDK package exports stay focused on plugin runtime/API entrypoints.

Bundle / download size

Measured against clean origin/main at 05ff771010 after pnpm build and npm pack --dry-run --ignore-scripts --json.

Metric Before After Delta
npm tarball/download size 17,658,326 bytes 17,603,764 bytes -54,562 bytes
unpacked package size 78,345,858 bytes 78,101,717 bytes -244,141 bytes
packed entries 12,576 12,470 -106
leaked helper dist bytes 179,615 bytes 0 bytes -179,615 bytes
all dist/plugin-sdk bytes 7,233,082 bytes 6,990,145 bytes -242,937 bytes
all dist/plugin-sdk files 4,711 4,605 -106

Summary

  • Mark the Vitest-backed Plugin SDK test-helper subpaths as private/local-only and remove their public package exports.
  • Exclude the built helper JS/d.ts files and source helper folders from the published openclaw package.
  • Keep release-check's critical Plugin SDK size/import smoke on still-public SDK entrypoints.
  • Add a compact contract guard that the audited Vitest-backed helper subpaths stay local-only.
  • Update SDK docs/tests to document that these helpers are repo-local test surfaces, not published package exports.

Re-export compatibility note

There is no new re-export compatibility layer in this version. The earlier shim/package approach kept the old subpaths importable, but it added a lot of code to preserve an accidental test-helper export surface. This version treats the helper subpaths as non-contract repo internals and removes them from the package boundary.

Verification

  • pnpm docs:list
  • node scripts/run-vitest.mjs test/release-check.test.ts src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts src/plugins/contracts/plugin-sdk-subpaths.test.ts src/plugins/contracts/plugin-sdk-index.test.ts
  • node scripts/run-vitest.mjs src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts
  • pnpm build
  • npm pack --dry-run --ignore-scripts --json before/after measurement against origin/main
  • Built package export import smoke: imported 303 plugin SDK package exports; leaked test-helper exports=0
  • git diff --check
  • ./scripts/release-check.ts

Real behavior proof

Behavior addressed: public Plugin SDK test-helper package exports could require dev-only vitest from a clean installed openclaw@beta package.
Real environment tested: local source checkout after patch with built package artifacts from pnpm build and npm dry-run package contents.
Exact steps or command run after this patch: focused Vitest contract tests, pnpm build, npm dry-run pack size measurement, import smoke for every openclaw/plugin-sdk* package export, and full ./scripts/release-check.ts.
Evidence after fix: focused tests passed; build passed; release-check passed; package export smoke imported 303 Plugin SDK exports and found 0 leaked test-helper exports.
Observed result after fix: clean package consumers no longer see the Vitest-backed helper subpaths as public package exports, and OpenClaw repo tests still resolve the helpers as local-only test surfaces.
What was not tested: the full external validation run was not rerun in this session; the local package-boundary proof covers the reported missing-vitest failure mode directly.

@RomneyDa RomneyDa requested review from a team as code owners May 27, 2026 02:19
@github-actions

github-actions Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Dependency Changes Detected

This PR changes dependency-related files. Maintainers should confirm these changes are intentional.

Changed files:

  • package.json

Maintainer follow-up:

  • Review whether the dependency changes are intentional.
  • Inspect resolved package deltas when lockfile, shrinkwrap, or workspace dependency policy changes are present.
  • Treat package-lock.json and npm-shrinkwrap.json diffs as security-review surfaces.
  • Run pnpm deps:changes:report -- --base-ref origin/main --markdown /tmp/dependency-changes.md --json /tmp/dependency-changes.json locally for detailed release-style evidence.

@github-actions github-actions Bot added the dependencies-changed PR changes dependency-related files label May 27, 2026
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: googlechat Channel integration: googlechat channel: imessage Channel integration: imessage channel: line Channel integration: line channel: matrix Channel integration: matrix channel: mattermost Channel integration: mattermost channel: msteams Channel integration: msteams channel: nextcloud-talk Channel integration: nextcloud-talk channel: nostr Channel integration: nostr channel: signal Channel integration: signal channel: slack Channel integration: slack channel: telegram Channel integration: telegram channel: tlon Channel integration: tlon channel: voice-call Channel integration: voice-call channel: whatsapp-web Channel integration: whatsapp-web channel: zalo Channel integration: zalo channel: zalouser Channel integration: zalouser app: web-ui App: web-ui gateway Gateway runtime extensions: diagnostics-otel Extension: diagnostics-otel extensions: lobster Extension: lobster extensions: memory-core Extension: memory-core cli CLI command changes scripts Repository scripts commands Command implementations labels May 27, 2026
@socket-security

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn Medium
Low adoption: npm fast-wrap-ansi

Location: Package overview

From: pnpm-lock.yamlnpm/@clack/prompts@1.4.0npm/@clack/core@1.3.1npm/fast-wrap-ansi@0.2.2

ℹ Read more on: This package | This alert | What are unpopular packages?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Unpopular packages may have less maintenance and contain other problems.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/fast-wrap-ansi@0.2.2. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs maintainer review before merge. Reviewed May 27, 2026, 2:02 AM ET / 06:02 UTC.

Summary
The PR removes Vitest-backed Plugin SDK test-helper subpaths from public package exports and packed artifacts, marks them private/local-only, and updates release checks, docs, and guardrail tests.

PR surface: Source +2, Tests +10, Docs +5, Config -22, Other -1. Total -6 across 11 files.

Reproducibility: yes. Source inspection shows current main exports repo-only Plugin SDK helper subpaths while those helper surfaces reach Vitest-backed test utilities; the PR body also reports the clean-package import crash that this fixes.

Review metrics: 1 noteworthy metric.

  • Public SDK subpath removals: 13 package exports removed. Removing shipped package specifiers is compatibility-sensitive even when the old specifiers were accidental test-helper leaks.

Merge readiness
Overall: 🐚 platinum hermit
Proof: 🦞 diamond lobster
Patch quality: 🐚 platinum hermit
Result: ready for maintainer review.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

Risk before merge

  • If any external or third-party test package was importing the accidentally shipped helper subpaths, merging this PR changes the failure mode from a later missing-vitest crash to immediate package subpath-not-exported resolution failure.
  • The compatibility decision is intentional and probably correct for repo-only Vitest helpers, but automation should not decide whether a shipped Plugin SDK subpath can be removed without a maintainer sign-off.

Maintainer options:

  1. Accept the helper-export removal (recommended)
    If maintainers agree these Vitest-backed helper subpaths were accidental package surface, land with the existing release-note context and package-audit proof.
  2. Add a compatibility/deprecation path
    If shipped consumers depend on these subpaths, preserve a tested compatibility path or deprecation plan before removing the public exports.

Next step before merge
Manual review is the right lane because the remaining blocker is whether to accept a breaking Plugin SDK package export removal, not a narrow automated repair.

Security
Cleared: No concrete security or supply-chain regression was found; the package.json diff changes files/exports only, with no lockfile, lifecycle-script, or dependency-version changes in the reviewed patch.

Review details

Best possible solution:

Land the package-boundary cleanup only after maintainers explicitly accept the helper-export removal tradeoff; if real consumers exist, add a named deprecation or compatibility plan instead.

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

Yes. Source inspection shows current main exports repo-only Plugin SDK helper subpaths while those helper surfaces reach Vitest-backed test utilities; the PR body also reports the clean-package import crash that this fixes.

Is this the best way to solve the issue?

Yes, if maintainers accept the compatibility break. The patch uses the existing privateLocalOnly/public entrypoint split instead of adding another shim, but the exported-subpath removal is a maintainer compatibility decision.

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 798691779bee.

Label changes

Label justifications:

  • P2: This is a bounded package-boundary bugfix with meaningful Plugin SDK compatibility impact but no evidence of a live core outage.
  • merge-risk: 🚨 compatibility: The diff intentionally removes public package export specifiers, which can break existing imports during upgrade.
  • rating: 🐚 platinum hermit: Overall readiness is 🐚 platinum hermit; proof is 🦞 diamond lobster and patch quality is 🐚 platinum hermit.
  • status: 👀 ready for maintainer look: ClawSweeper has no concrete contributor-facing blocker left for this PR. Sufficient (live_output): The PR body includes exact real behavior proof fields and reports build, release-check, npm pack measurement, and an import smoke over 303 Plugin SDK exports with 0 leaked helper exports; I did not rerun commands in this read-only review.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes exact real behavior proof fields and reports build, release-check, npm pack measurement, and an import smoke over 303 Plugin SDK exports with 0 leaked helper exports; I did not rerun commands in this read-only review.
Evidence reviewed

PR surface:

Source +2, Tests +10, Docs +5, Config -22, Other -1. Total -6 across 11 files.

View PR surface stats
Area Files Added Removed Net
Source 2 4 2 +2
Tests 2 16 6 +10
Docs 2 14 9 +5
Config 1 30 52 -22
Generated 0 0 0 0
Other 4 20 21 -1
Total 11 84 90 -6

What I checked:

  • Current main still exports the affected helper subpaths: Current main package.json still exposes Vitest-backed helper subpaths such as ./plugin-sdk/agent-runtime-test-contracts, ./plugin-sdk/plugin-test-contracts, ./plugin-sdk/provider-test-contracts, and ./plugin-sdk/testing as package exports. (package.json:573, 798691779bee)
  • PR removes public exports and excludes helper artifacts: At the PR head, package.json adds file exclusions for the helper JS/d.ts outputs and the export block no longer includes the removed helper subpaths. (package.json:35, a907668ba889)
  • PR uses the existing private/public SDK entrypoint split: The PR marks the helper subpaths as private local-only and changes listPluginSdkDistArtifacts to iterate publicPluginSdkEntrypoints, aligning package artifacts with public exports. (src/plugin-sdk/entrypoints.ts:111, a907668ba889)
  • Guardrail coverage was added: The PR adds a focused contract guard that plugin-test-contracts, provider-test-contracts, and testing stay in the private local-only SDK entrypoint set. (src/plugins/contracts/plugin-sdk-package-contract-guardrails.test.ts:695, a907668ba889)
  • Source inspection supports the reported Vitest dependency failure: Current helper surfaces reach repo-only Vitest-backed utilities while current package.json exports those helper subpaths, making the reported clean-package missing-vitest failure source-reproducible. (src/plugin-sdk/plugin-test-runtime.ts:52, 798691779bee)
  • Compatibility policy applies: The root and scoped Plugin SDK policy treat plugin SDK public API changes and breaking removals as compatibility-sensitive, so this package-export removal needs explicit maintainer review even with green tests. (src/plugin-sdk/AGENTS.md:1, 798691779bee)

Likely related people:

  • Steady-ai: Current-main blame and git log tie the package.json helper exports, SDK entrypoint helper generation, and package guardrail files to commit eb8f9b4. (role: current package-surface introducer; confidence: high; commits: eb8f9b46da39; files: package.json, src/plugin-sdk/entrypoints.ts, scripts/lib/plugin-sdk-entries.mjs)
  • Vincent Koc: Current main already contains the same sessions-send-tool error-cause change at HEAD, so the PR's small agents hunk is adjacent to his recent fallback-error preservation work rather than the central SDK export cleanup. (role: recent adjacent owner; confidence: medium; commits: 798691779bee; files: src/agents/tools/sessions-send-tool.ts)
  • Andy Ye: Blame shows the surrounding sessions_send fallback branch came from commit 81e7e8e, which explains the context for the small overlapping agents hunk. (role: introduced adjacent fallback path; confidence: medium; commits: 81e7e8ef24de; files: src/agents/tools/sessions-send-tool.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper PR egg

✨ Hatched: 🥚 common Velvet Signal Puff

Hatch command

Comment @clawsweeper hatch when this PR is hatchable.

Hatchability rules:

  • Merged PRs are hatchable.
  • Open PRs are hatchable when they are status: 👀 ready for maintainer look, status: 🚀 automerge armed, or labeled clawsweeper:automerge.
  • Closed unmerged PRs are hatchable only when one of those hatchable labels is still present in the durable record.

Rarity: 🥚 common.
Trait: purrs at green checks.
Image traits: location diff observatory; accessory tiny test log scroll; palette moss green and polished brass; mood mischievous; pose holding its accessory up for inspection; shell smooth pearl shell; lighting calm overcast light; background subtle branch markers.
Share on X: post this hatch
Copy: My PR egg hatched a 🥚 common Velvet Signal Puff in ClawSweeper.

What is this egg doing here?
  • Eggs appear after the PR passes real-behavior proof. It is here for vibes, not verdicts: it does not change labels, ratings, merge decisions, or automation.
  • The shell reacts to review momentum: open follow-up work warms it up, re-review makes it wobble, and a clean final review lets it hatch.
  • Hatchability usually comes from sufficient real-behavior proof, no blocking P0/P1/P2 findings, no security attention needed, and clean correctness. A merged PR is already final, so merge makes the egg hatchable independently.
  • The hatch is seeded from this repository and PR number, so the same PR keeps the same creature; the reviewed head SHA can only change safe visual details.
  • Rarity is just collectible sparkle: 🥚 common, 🌱 uncommon, 💎 rare, ✨ glimmer, and 🌈 legendary.

@RomneyDa

Copy link
Copy Markdown
Member Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

@RomneyDa

Copy link
Copy Markdown
Member Author

@clawsweeper re-review

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

🦞👀
ClawSweeper picked this up.

Command router queued. I will update this comment with the next step.

@clawsweeper

clawsweeper Bot commented May 27, 2026

Copy link
Copy Markdown
Contributor

🦞🧹
ClawSweeper re-review requested.

I asked ClawSweeper to review this item again.
Action: item re-review queued (workflow sweep.yml, event repository_dispatch).
Result: the existing ClawSweeper review comment will be edited in place when the review finishes.

Re-review progress:

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

Labels

agents Agent runtime and tooling dependencies-changed PR changes dependency-related files docs Improvements or additions to documentation maintainer Maintainer-authored PR merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P2 Normal backlog priority with limited blast radius. proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🐚 platinum hermit Good normal PR readiness with ordinary maintainer review expected. scripts Repository scripts size: S status: 👀 ready for maintainer look ClawSweeper has no concrete contributor-facing blocker left for this PR.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant