Skip to content

feat(core): bump claude-agent-sdk ^0.1.0 → ^0.3.x (fixes #303)#304

Merged
edspencer merged 1 commit into
mainfrom
feat/bump-claude-agent-sdk-0.3
Jul 9, 2026
Merged

feat(core): bump claude-agent-sdk ^0.1.0 → ^0.3.x (fixes #303)#304
edspencer merged 1 commit into
mainfrom
feat/bump-claude-agent-sdk-0.3

Conversation

@edspencer

@edspencer edspencer commented Jul 8, 2026

Copy link
Copy Markdown
Owner

Summary

Bumps @anthropic-ai/claude-agent-sdk in packages/core from ^0.1.0
(resolved 0.1.77) to ^0.3.0 (resolves 0.3.205), closing #303.

The pinned ^0.1.0 range cannot cross a 0.x minor, so herdctl was frozen on a
stale SDK line whose bundled JS harness lacks the current agentic toolset
(ScheduleWakeup, ToolSearch, Cron*, Monitor, …). 0.3.x drops the
bundled 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 schedules
ScheduleWakeup and is re-invoked when it fires).

Changes

  • packages/core/package.json: @anthropic-ai/claude-agent-sdk ^0.1.0^0.3.0; pnpm-lock.yaml updated.
  • sdk-runtime.ts adapter fixes for 0.3.x type changes (the only two type breaks across the SDK surface used by sdk-adapter / sdk-runtime / message-queue):
    • Query.interrupt() now resolves to an optional interrupt-receipt object instead of void. RuntimeSession.interrupt() awaits and discards it to preserve its fire-and-forget Promise<void> contract.
    • The SDK's tool() handler return type now uses a literal-typed MCP CallToolResult. The injected-MCP adapter casts InjectedMcpToolDef.handler at that boundary, keeping the transport-agnostic tool definition SDK-free (no public-type change).
  • Changeset added (@herdctl/core: minor).

Verification

  • pnpm typecheck11/11 pass
  • pnpm build7/7 pass
  • pnpm lint6/6 pass
  • Core tests — 3190 pass, 29 skipped. The single failure (directory.test.ts "throws … when parent directory is not writable") is a pre-existing, environment-only failure that also fails on clean main when the test runner is root (root bypasses chmod); CI runs non-root, where it passes.
  • No @herdctl/core public API changes. query(), createSdkMcpServer(), tool(), streaming-input AsyncIterable<SDKUserMessage>, and the Query control methods (interrupt, supportedCommands, setModel) all remain compatible.
  • Cross-turn-autonomy repro (per the issue): a persistent openSession() agent calling ScheduleWakeup(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

  • The SDK now peer-depends on zod@^4 while core stays on zod@^3 (pnpm emits a peer warning). The Zod schemas built for injected MCP tools remain structurally compatible with tool(), and typecheck/build/tests are green. Migrating core to zod v4 is out of scope for this bump.
  • Packaging changed between 0.1.x (bundled cli.js) and 0.3.x (bridge.mjs + native-binary manifest.json extracted at runtime); executable resolution/startup differs but the imported API surface is unchanged.

Closes #303.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Chores
    • Updated the bundled AI SDK to a newer version, aligning the app with the latest supported runtime behavior.
    • Improved compatibility with external tool handling and session interruption flows.
    • No public API changes for end users, and existing type/build/test checks continue to pass.

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>
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Bumps the @anthropic-ai/claude-agent-sdk dependency from ^0.1.0 to ^0.3.0 in packages/core/package.json. Updates sdk-runtime.ts to cast tool handlers to the new SDK type and wraps interrupt() as async to discard the optional interrupt receipt. Adds a changeset documenting the bump.

Changes

SDK dependency bump and adapter type adjustments

Layer / File(s) Summary
Dependency version bump
packages/core/package.json
Updates @anthropic-ai/claude-agent-sdk version range from ^0.1.0 to ^0.3.0.
SDK adapter type adjustments
packages/core/src/runner/runtime/sdk-runtime.ts
Casts injected tool handler to the SDK tool() handler parameter type in defToSdkMcpServer, and changes RuntimeSession.interrupt to an async function that awaits q.interrupt() and discards the returned optional interrupt receipt to keep the Promise<void> contract.
Changeset documentation
.changeset/bump-claude-agent-sdk-0.3.md
Documents the version bump rationale, native-binary harness change, and the adapter type adjustments, asserting no @herdctl/core public API changes.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

  • edspencer/herdctl#286: Modifies the same SDKRuntime.openSession and interrupt() handling logic in sdk-runtime.ts.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Linked Issues check ❓ Inconclusive The PR matches the upgrade and adapter updates, but the lockfile is hidden and the persistent ScheduleWakeup repro is not verifiable here. Provide evidence for the wakeup re-invocation test and confirm the lockfile update outside the filtered path.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly states the core SDK bump and matches the main change in the PR.
Out of Scope Changes check ✅ Passed The changes stay within the SDK upgrade, adapter fixes, and release metadata required by the issue.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bump-claude-agent-sdk-0.3

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@cloudflare-workers-and-pages

Copy link
Copy Markdown

Deploying herdctl with  Cloudflare Pages  Cloudflare Pages

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

View logs

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

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

📥 Commits

Reviewing files that changed from the base of the PR and between c52a762 and 4eec7f3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (3)
  • .changeset/bump-claude-agent-sdk-0.3.md
  • packages/core/package.json
  • packages/core/src/runner/runtime/sdk-runtime.ts

},
"dependencies": {
"@anthropic-ai/claude-agent-sdk": "^0.1.0",
"@anthropic-ai/claude-agent-sdk": "^0.3.0",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🔒 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
fi

Repository: 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])
PY

Repository: 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.

@edspencer

Copy link
Copy Markdown
Owner Author

@coderabbitai flagged: core pins zod@^3 while @anthropic-ai/claude-agent-sdk@0.3.205 peer-depends on zod@^4.

Acknowledged — this is intentional and scoped out of this PR. The peer warning is cosmetic here (the zod schemas passed to the SDK's tool() are structurally compatible, and typecheck/build/tests are all green on zod 3), and bumping zod 3→4 is a non-trivial migration in its own right (v4 changed .default() semantics, which silently affects nested config defaults).

It's handled in the stacked follow-up #305, which upgrades core + chat to zod@^4 and clears the peer mismatch. Suggested merge order: this PR first, then #305.

@coderabbitai

coderabbitai Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Tip

For best results, initiate chat on the files or code changes.

@edspencer Thanks for the context — that makes sense. Deferring the zod@^3^4 migration to the stacked PR #305 rather than bundling a non-trivial .default() semantics change into this SDK bump is a reasonable scoping decision, especially since typecheck/build/tests are green here and the peer mismatch is cosmetic in practice. Noted the suggested merge order (#304 then #305).


✏️ Learnings added
Learnt from: edspencer
URL: https://github.com/edspencer/herdctl/pull/304

Timestamp: 2026-07-09T02:20:36.346Z
Learning: In the herdctl repository, `packages/core` intentionally pins `zod@^3` even though `anthropic-ai/claude-agent-sdk0.3.205` peer-depends on `zod@^4`. This is a known, intentional scoping decision (per edspencer): the zod 3→4 migration is handled separately in the stacked follow-up PR `#305`, because zod v4 changed `.default()` semantics which silently affects nested config defaults, making it a non-trivial migration. Suggested merge order is `#304` (SDK bump) first, then `#305` (zod v4 bump).

Note: Learnings are effective only in the context of similar code segments. To apply general coding guidelines, please configure review instructions. You can manage existing learnings in the app.

@edspencer edspencer merged commit 40893c3 into main Jul 9, 2026
8 checks passed
@github-actions github-actions Bot mentioned this pull request Jul 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bump claude-agent-sdk ^0.1.0 → ^0.3.x (unlocks native agentic harness; fixes cross-turn ScheduleWakeup/background)

1 participant