feat(core): bump claude-agent-sdk ^0.1.0 → ^0.3.x (fixes #303)#304
Conversation
The pinned `^0.1.0` range cannot cross a 0.x minor, freezing herdctl on a stale SDK (0.1.77) whose bundled JS harness lacks the current agentic toolset (ScheduleWakeup, ToolSearch, Cron*, Monitor). 0.3.x drops the bundled harness and runs the native Claude Code binary that carries those tools, unblocking cross-turn autonomy for persistent openSession() agents. Adapt the SDK adapter surface to 0.3.x types: - Query.interrupt() now resolves to an optional interrupt-receipt object; RuntimeSession.interrupt() awaits and discards it to keep Promise<void>. - tool() handler return type now uses a literal-typed MCP CallToolResult; cast InjectedMcpToolDef.handler at the adapter boundary. No @herdctl/core public API changes. typecheck/build/tests green. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
📝 WalkthroughWalkthroughBumps the ChangesSDK dependency bump and adapter type adjustments
Estimated code review effort: 2 (Simple) | ~10 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Deploying herdctl with
|
| Latest commit: |
4eec7f3
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://168afaed.herdctl.pages.dev |
| Branch Preview URL: | https://feat-bump-claude-agent-sdk-0.herdctl.pages.dev |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@packages/core/package.json`:
- Line 21: The core package is still pinning zod 3 while
`@anthropic-ai/claude-agent-sdk` expects zod ^4.0.0, so update the dependency in
packages/core/package.json to a zod 4-compatible version or switch the SDK
version to one that supports zod 3. Make sure the package.json entry for zod
matches the peer range required by the Claude agent SDK and keep the existing
`@anthropic-ai/claude-agent-sdk` dependency aligned with that choice.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: c9db99c2-a817-48bc-8fb4-cac1880694b8
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (3)
.changeset/bump-claude-agent-sdk-0.3.mdpackages/core/package.jsonpackages/core/src/runner/runtime/sdk-runtime.ts
| }, | ||
| "dependencies": { | ||
| "@anthropic-ai/claude-agent-sdk": "^0.1.0", | ||
| "@anthropic-ai/claude-agent-sdk": "^0.3.0", |
There was a problem hiding this comment.
🔒 Security & Privacy | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Check if the SDK declares zod as a peer dependency or regular dependency.
# Also check core's zod version.
# Core's zod version
echo "=== Core zod dependency ==="
cat packages/core/package.json | jq '{dependencies: .dependencies.zod, devDependencies: .devDependencies.zod, peerDependencies: .peerDependencies.zod} | del(..|nulls)'
# SDK's zod declaration (if installed)
SDK_PKG="node_modules/@anthropic-ai/claude-agent-sdk/package.json"
if [ -f "$SDK_PKG" ]; then
echo "=== SDK zod declarations ==="
cat "$SDK_PKG" | jq '{peerDependencies: .peerDependencies, dependencies: .dependencies} | del(..|nulls)'
else
echo "=== SDK package.json not found in node_modules — checking lockfile ==="
if [ -f "package-lock.json" ]; then
jq '.packages | to_entries[] | select(.key | contains("`@anthropic-ai/claude-agent-sdk`")) | {key: .key, version: .value.version, peerDependencies: .value.peerDependencies, dependencies: .value.dependencies}' package-lock.json 2>/dev/null | head -40
elif [ -f "pnpm-lock.yaml" ]; then
echo "pnpm lockfile found — check manually for SDK zod peer deps"
else
echo "No lockfile found"
fi
fi
# Check for multiple zod versions in the dependency tree
echo "=== zod versions in lockfile ==="
if [ -f "package-lock.json" ]; then
jq -r '.packages | to_entries[] | select(.key | test("zod")) | "\(.key) -> \(.value.version)"' package-lock.json 2>/dev/null | head -20
fiRepository: edspencer/herdctl
Length of output: 378
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== repo files of interest ==="
git ls-files | rg '(^|/)(package\.json|pnpm-lock\.yaml|changeset|CHANGELOG|README\.md)$|claude-agent-sdk|zod' || true
echo
echo "=== references to `@anthropic-ai/claude-agent-sdk` ==="
rg -n '`@anthropic-ai/claude-agent-sdk`|zod@\^4|zod@\^3|peerDependencies|dependencies' packages pnpm-lock.yaml package.json .changeset -g '!**/node_modules/**' || true
echo
echo "=== package manifests mentioning zod ==="
for f in packages/core/package.json package.json; do
if [ -f "$f" ]; then
echo "--- $f"
jq '{name, dependencies: .dependencies.zod, devDependencies: .devDependencies.zod, peerDependencies: .peerDependencies.zod, packageManager}' "$f" 2>/dev/null || cat "$f"
fi
done
echo
echo "=== lockfile entries for claude-agent-sdk ==="
python3 - <<'PY'
import yaml, json, os, sys
path = "pnpm-lock.yaml"
if not os.path.exists(path):
print("pnpm-lock.yaml not found")
raise SystemExit(0)
try:
with open(path, "r", encoding="utf-8") as f:
data = yaml.safe_load(f)
except Exception as e:
print(f"failed to parse pnpm-lock.yaml: {e}")
raise SystemExit(0)
for section in ("packages", "snapshots", "importers"):
obj = data.get(section)
if isinstance(obj, dict):
print(f"--- {section} matches ---")
for k, v in obj.items():
if "claude-agent-sdk" in str(k) or (isinstance(v, dict) and any("claude-agent-sdk" in str(x) for x in v.keys())):
print(json.dumps({str(k): v}, indent=2)[:4000])
PYRepository: edspencer/herdctl
Length of output: 50373
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "=== pnpm-lock.yaml stanza for claude-agent-sdk ==="
sed -n '352,375p' pnpm-lock.yaml
echo
echo "=== packages/core/package.json ==="
cat -n packages/core/package.json | sed -n '1,80p'
echo
echo "=== packages/core/src/sdk-runtime.ts around tool() ==="
cat -n packages/core/src/sdk-runtime.ts | sed -n '70,120p'
echo
echo "=== changeset note ==="
cat -n .changeset/bump-claude-agent-sdk-0.3.md | sed -n '20,40p'Repository: edspencer/herdctl
Length of output: 2852
Align zod with the SDK peer range packages/core/package.json:21-28
@anthropic-ai/claude-agent-sdk@0.3.205 requires zod@^4.0.0, but core still provides zod@^3.22.0. This leaves the package outside the SDK’s declared peer range and will trigger peer-dependency warnings; update core to zod 4 or use an SDK release that accepts zod 3.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@packages/core/package.json` at line 21, The core package is still pinning zod
3 while `@anthropic-ai/claude-agent-sdk` expects zod ^4.0.0, so update the
dependency in packages/core/package.json to a zod 4-compatible version or switch
the SDK version to one that supports zod 3. Make sure the package.json entry for
zod matches the peer range required by the Claude agent SDK and keep the
existing `@anthropic-ai/claude-agent-sdk` dependency aligned with that choice.
Acknowledged — this is intentional and scoped out of this PR. The peer warning is cosmetic here (the zod schemas passed to the SDK's It's handled in the stacked follow-up #305, which upgrades core + chat to |
|
Tip For best results, initiate chat on the files or code changes.
✏️ Learnings added
|
Summary
Bumps
@anthropic-ai/claude-agent-sdkinpackages/corefrom^0.1.0(resolved 0.1.77) to
^0.3.0(resolves 0.3.205), closing #303.The pinned
^0.1.0range cannot cross a0.xminor, so herdctl was frozen on astale SDK line whose bundled JS harness lacks the current agentic toolset
(
ScheduleWakeup,ToolSearch,Cron*,Monitor, …).0.3.xdrops thebundled harness and instead extracts/runs the native Claude Code binary,
which carries those tools — unblocking cross-turn autonomy for consumers driving
a persistent
openSession()agent (e.g. an agent that schedulesScheduleWakeupand is re-invoked when it fires).Changes
packages/core/package.json:@anthropic-ai/claude-agent-sdk^0.1.0→^0.3.0;pnpm-lock.yamlupdated.sdk-runtime.tsadapter fixes for 0.3.x type changes (the only two type breaks across the SDK surface used bysdk-adapter/sdk-runtime/message-queue):Query.interrupt()now resolves to an optional interrupt-receipt object instead ofvoid.RuntimeSession.interrupt()awaits and discards it to preserve its fire-and-forgetPromise<void>contract.tool()handler return type now uses a literal-typed MCPCallToolResult. The injected-MCP adapter castsInjectedMcpToolDef.handlerat that boundary, keeping the transport-agnostic tool definition SDK-free (no public-type change).@herdctl/core: minor).Verification
pnpm typecheck— 11/11 passpnpm build— 7/7 passpnpm lint— 6/6 passdirectory.test.ts"throws … when parent directory is not writable") is a pre-existing, environment-only failure that also fails on cleanmainwhen the test runner isroot(root bypasseschmod); CI runs non-root, where it passes.@herdctl/corepublic API changes.query(),createSdkMcpServer(),tool(), streaming-inputAsyncIterable<SDKUserMessage>, and theQuerycontrol methods (interrupt,supportedCommands,setModel) all remain compatible.openSession()agent callingScheduleWakeup(delaySeconds: 60)and held idle is re-invoked in the same session at fire time under 0.3.205 — behavior absent on 0.1.77. Full reproduction steps are documented in Bump claude-agent-sdk ^0.1.0 → ^0.3.x (unlocks native agentic harness; fixes cross-turn ScheduleWakeup/background) #303.Notes / caveats
zod@^4while core stays onzod@^3(pnpm emits a peer warning). The Zod schemas built for injected MCP tools remain structurally compatible withtool(), and typecheck/build/tests are green. Migrating core to zod v4 is out of scope for this bump.0.1.x(bundledcli.js) and0.3.x(bridge.mjs+ native-binarymanifest.jsonextracted at runtime); executable resolution/startup differs but the imported API surface is unchanged.Closes #303.
🤖 Generated with Claude Code
Summary by CodeRabbit