fix(cli): unblock Publish Package — mock @agent-relay/sdk boundary in MCP startup test
Problem
The Publish Package workflow (run 27598076243) fails its Run tests step with a single failure:
RelayError: Route not found
❯ relayErrorFromApi packages/sdk/node_modules/@relaycast/sdk/src/errors.ts:101:9
❯ Object.list packages/sdk/src/messaging/relaycast.ts:984:8
❯ agent-relay-mcp.ts:1237 (query_nodes handler)
❯ agent-relay-mcp.startup.test.ts:352
This is release-blocking: npm test runs in the publish job, so the failure aborts the release.
Root cause
The query_nodes MCP tool constructs new AgentRelay(...) from @agent-relay/sdk and calls .nodes.list(). AgentRelay wraps @relaycast/sdk internally, but the test only mocks @relaycast/sdk — so the path works only when packages/cli and packages/sdk resolve the same physical @relaycast/sdk copy.
- On
main,@relaycast/sdk@4.0.0hoists to a single root copy → the mock applies → green. - The publish job regenerates the lockfile (
rm -rf package-lock.json && npm install) at the freshly-bumped version. The tree's pre-existing@relaycast/sdkskew (a stray transitive1.2.0, plus@relayflows/corepinning^1.1.0) tips the resolver into nesting a duplicate@relaycast/sdkunderpackages/sdk.AgentRelay's internal client is then the real, unmocked copy → live HTTP request →Route not found.
The stack confirms it: the unmocked client resolves from packages/sdk/node_modules/@relaycast/sdk, not the hoisted root copy.
This is a monorepo publish-time artifact, not a production bug — a real end-user install dedupes @relaycast/sdk@^4.0.0 to one copy, so AgentRelay works fine. Production code is therefore untouched.
Fix
Mock the direct boundary the handler uses (@agent-relay/sdk's AgentRelay) instead of the transitive @relaycast/sdk, via importActual + override so the real token-helper exports stay intact. The query_nodes path is now independent of node_modules hoisting — aligning with the repo convention to "mock the boundary, not internal modules".
Verification
Forced the nested-duplicate scenario locally (cp the root @relaycast/sdk into packages/sdk/node_modules):
| nested duplicate present | |
|---|---|
| pre-fix | ❌ reproduces RelayError: Route not found |
| post-fix | ✅ 16/16 pass |
- Full
packages/clisuite: 362 passed, 5 skipped. - No production code changed.
Follow-up (not in this PR)
The underlying dep skew (@relaycast/sdk@1.2.0 / @relayflows/core@^1.1.0) is the same version-hygiene fragility tracked in #1134. This PR makes the test resilient; tightening the dep tree is separate.
🤖 Generated with Claude Code