Skip to content

feat: Update to Claude Agent SDK 0.2.22#9

Merged
arcaputo3 merged 1 commit intomainfrom
feat/sdk-0.2.22-update
Jan 28, 2026
Merged

feat: Update to Claude Agent SDK 0.2.22#9
arcaputo3 merged 1 commit intomainfrom
feat/sdk-0.2.22-update

Conversation

@arcaputo3
Copy link
Contributor

Updates Scalagent to support Claude Agent SDK 0.2.22 with the following changes:

New Message Types:

  • TaskNotification: Task/subagent completion notifications with status, outputFile, summary
  • ToolUseSummary: Aggregate tool use info with summary and preceding tool use IDs
  • TaskStatus enum: Completed, Failed, Stopped, Custom

New System Events:

  • HookStarted: Hook execution started notification
  • HookProgress: Hook execution progress with stdout/stderr/output
  • Enhanced HookResponse: Added hookId, output, outcome fields
  • HookOutcome enum: Success, Error, Cancelled, Custom

New QueryStream Methods:

  • close(): Abort running query
  • reconnectMcpServer(): Reconnect a specific MCP server
  • toggleMcpServer(): Enable/disable MCP server
  • rewindFiles(): Restore files to previous state
  • setMcpServers(): Configure MCP servers dynamically

Other Enhancements:

  • PermissionMode.Delegate for delegated permission handling
  • McpConnectionStatus.Disabled for disabled servers
  • Enhanced McpServerStatus with error, scope, tools fields
  • McpToolInfo and McpToolAnnotations types
  • AgentOptions.withMainAgent() for main thread agent config

Dependencies:

  • @anthropic-ai/claude-code-sdk: 0.2.22
  • zod: 4.0.0

@claude
Copy link

claude bot commented Jan 28, 2026

Pull Request Review: Update to Claude Agent SDK 0.2.22

Summary

This PR successfully updates Scalagent to support Claude Agent SDK 0.2.22, adding comprehensive support for new message types, system events, and QueryStream methods. The implementation is well-structured with strong type safety and good test coverage.


✅ Strengths

1. Excellent Type Safety

  • Proper use of Scala enums for TaskStatus, HookOutcome, and McpConnectionStatus
  • Custom case for forward compatibility (Custom(value: String)) ensures graceful handling of unknown values
  • Strong typing throughout with Option types for optional fields

2. Comprehensive Test Coverage

  • All new message types have corresponding test fixtures (TestFixtures.scala)
  • Thorough unit tests for new functionality (AgentMessageSpec.scala, AgentOptionsSpec.scala)
  • Tests cover both success and failure cases (e.g., taskNotification and taskNotificationFailed)
  • Extension method tests ensure list operations work correctly

3. Good Code Organization

  • Clear separation of concerns across files
  • Consistent naming conventions
  • Well-documented public APIs with ScalaDoc comments

4. Backward Compatibility

  • Legacy format support for needs_authneeds-auth transition (line 343 in SystemEvent.scala)
  • Safe use of js.UndefOr with getOrElse defaults prevents runtime errors

🔍 Potential Issues & Recommendations

1. Error Handling in MessageConverter (Medium Priority)

// src/com/tjclp/scalagent/streaming/MessageConverter.scala:430
precedingToolUseIds = obj.preceding_tool_use_ids.asInstanceOf[js.Array[String]].toList.map(ToolUseId.apply)

Issue: If preceding_tool_use_ids is undefined or null, this will throw a runtime error.

Recommendation:

precedingToolUseIds = obj.preceding_tool_use_ids
  .asInstanceOf[js.UndefOr[js.Array[String]]]
  .toOption
  .map(_.toList.map(ToolUseId.apply))
  .getOrElse(List.empty)

2. Inconsistent Field Handling in parseHookResponseEvent (Low Priority)

// src/com/tjclp/scalagent/streaming/MessageConverter.scala:445-447
stdout = obj.stdout.asInstanceOf[js.UndefOr[String]].getOrElse(""),
stderr = obj.stderr.asInstanceOf[js.UndefOr[String]].getOrElse(""),
output = obj.output.asInstanceOf[js.UndefOr[String]].getOrElse(""),

Observation: These fields use getOrElse(""), but the old implementation expected them to always be present. This is actually an improvement, but ensure the SDK can indeed return undefined for these fields.

3. Missing Documentation for withMainAgent (Low Priority)

The ScalaDoc at line 104-117 in AgentOptions.scala is excellent, but consider adding:

  • What happens if the agent name doesn't exist in agents or settings?
  • Runtime behavior vs. compile-time safety

4. Zod Version Bump (Review Required)

"zod": "^4.0.0"

Concern: Zod v4.0.0 is a major version update from 3.24.1. This could introduce breaking changes.

Recommendation:

  • Verify that the Claude Agent SDK 0.2.22 requires Zod 4.x (appears to be the case from peer dependency)
  • Consider documenting any Zod API changes that might affect users

5. QueryStream Resource Management (Low Priority)

// src/com/tjclp/scalagent/streaming/QueryStream.scala:533
def close(): UIO[Unit] =
  ZIO.succeed(rawQuery.close())

Observation: The close() method wraps a potentially side-effecting operation in ZIO.succeed. While this is likely correct (JS close() returns void), consider if error handling is needed here.


🔒 Security Assessment

No security concerns identified. The changes:

  • Don't introduce any credential handling
  • Don't add new file system operations beyond existing patterns
  • Properly handle user input through type-safe interfaces
  • Use appropriate error handling with Option types

⚡ Performance Considerations

  1. Efficient List Operations: Extension methods like taskNotifications and toolUseSummaries use collect, which is appropriately efficient for filtering typed messages.

  2. No N+1 Issues: The MCP tool parsing at lines 480-493 in MessageConverter.scala processes arrays inline without multiple iterations.


📊 Code Quality

  • Consistent Style: Follows Scala 3 idioms (enums, extension methods, optional braces)
  • No Code Smell: No duplicated code or overly complex methods
  • Good Naming: Clear, descriptive names throughout (McpToolAnnotations, RewindFilesResult, etc.)

🧪 Test Coverage Verification

The PR adds comprehensive tests:

  • ✅ New message types (TaskNotification, ToolUseSummary)
  • ✅ New enums (TaskStatus, HookOutcome)
  • ✅ Extension methods for message lists
  • ✅ AgentOptions.withMainAgent functionality
  • ✅ PermissionMode.Delegate

Suggestion: Consider adding integration tests that verify the JS interop layer with the actual SDK (if not already present in CI).


📝 Minor Suggestions

  1. Consider Optional Fields for HookProgress: Lines 265-271 in SystemEvent.scala - are stdout, stderr, and output always present during progress updates?

  2. Version Consistency: The PR updates the version in both build.mill (0.2.2-SNAPSHOT) and package.json (0.2.2-SNAPSHOT), which is correct. Ensure CI builds use the PUBLISH_VERSION env var appropriately.


✅ Approval Recommendation

This PR is well-implemented and ready to merge with one minor fix recommended for error handling in MessageConverter.parseToolUseSummary.

Before Merging:

  1. ✅ Fix the precedingToolUseIds null safety issue (high confidence this could cause runtime errors)
  2. ✅ Run ./mill agent.test to ensure all tests pass
  3. ⚠️ Verify Zod 4.x compatibility if not already tested

Overall Rating: 8.5/10

  • Strong type safety and test coverage
  • Clean, maintainable code
  • One minor bug that should be fixed
  • Excellent alignment with SDK 0.2.22 features

Great work! 🚀

Updates Scalagent to support Claude Agent SDK 0.2.22 with the following changes:

**New Message Types:**
- TaskNotification: Task/subagent completion notifications with status, outputFile, summary
- ToolUseSummary: Aggregate tool use info with summary and preceding tool use IDs
- TaskStatus enum: Completed, Failed, Stopped, Custom

**New System Events:**
- HookStarted: Hook execution started notification
- HookProgress: Hook execution progress with stdout/stderr/output
- Enhanced HookResponse: Added hookId, output, outcome fields
- HookOutcome enum: Success, Error, Cancelled, Custom

**New QueryStream Methods:**
- close(): Abort running query
- reconnectMcpServer(): Reconnect a specific MCP server
- toggleMcpServer(): Enable/disable MCP server
- rewindFiles(): Restore files to previous state
- setMcpServers(): Configure MCP servers dynamically

**Other Enhancements:**
- PermissionMode.Delegate for delegated permission handling
- McpConnectionStatus.Disabled for disabled servers
- Enhanced McpServerStatus with error, scope, tools fields
- McpToolInfo and McpToolAnnotations types
- AgentOptions.withMainAgent() for main thread agent config

**Dependencies:**
- @anthropic-ai/claude-code-sdk: 0.2.22
- zod: 4.0.0

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@arcaputo3 arcaputo3 force-pushed the feat/sdk-0.2.22-update branch from a842ae9 to 0345704 Compare January 28, 2026 16:49
@claude
Copy link

claude bot commented Jan 28, 2026

Pull Request Review: SDK 0.2.22 Update

This PR updates Scalagent to support Claude Agent SDK 0.2.22 with comprehensive new features. The implementation is well-structured and maintains excellent code quality.

✅ Strengths

Code Quality

  • Excellent type safety: All new enums (TaskStatus, HookOutcome, McpConnectionStatus.Disabled) follow the consistent pattern with Custom cases for forward compatibility
  • Comprehensive test coverage: New test fixtures and test cases cover all new message types and enums (TaskNotification, ToolUseSummary, HookStarted, HookProgress)
  • Consistent API design: The withMainAgent method follows the established fluent builder pattern
  • Proper documentation: All new methods have clear ScalaDoc comments with examples

Architecture

  • Clean separation: MessageConverter properly handles new message types ("task_notification", "tool_use_summary") in the discriminated union pattern
  • ZIO integration: New QueryStream methods (close, reconnectMcpServer, toggleMcpServer, rewindFiles, setMcpServers) maintain the Task/UIO pattern
  • Backward compatibility: Legacy "needs_auth" format is supported alongside new "needs-auth" format (line 192 in SystemEvent.scala)

New Features Implementation

Message Types (AgentMessage.scala):

  • TaskNotification: Properly structured with taskId, status, outputFile, summary
  • ToolUseSummary: Includes precedingToolUseIds list for tracking related tool uses
  • Extension methods taskNotifications and toolUseSummaries for easy filtering

System Events (SystemEvent.scala):

  • HookStarted, HookProgress, HookResponse enhanced with hookId field
  • HookOutcome enum (Success, Error, Cancelled) with proper JSON codecs
  • McpServerStatus enhanced with error, scope, tools fields
  • McpToolInfo and McpToolAnnotations for detailed tool metadata

QueryStream Methods (QueryStream.scala:167-226):

  • close(): Proper UIO[Unit] for cleanup
  • reconnectMcpServer, toggleMcpServer: Task[Unit] with proper error handling
  • rewindFiles: Returns structured RewindFilesResult with file stats
  • setMcpServers: Returns McpSetServersResult with added/removed/errors tracking

Agent Configuration (AgentOptions.scala:87-89, 551-569):

  • agent: Option[String] field added to case class
  • withMainAgent(agentName: String) method with excellent documentation
  • Properly serialized to raw JS object (line 162)

📋 Areas for Consideration

1. Version Management

The version was bumped to 0.2.2-SNAPSHOT in both build.mill and package.json. Consider:

  • Is this the correct semantic versioning increment? (minor version bump is appropriate for new features)
  • The README shows version 0.2.2 without -SNAPSHOT suffix (lines 23, 30, 39) - ensure this is intentional

2. Error Handling

The new QueryStream methods use Task which can fail. Consider documenting common failure scenarios:

  • What happens if you call reconnectMcpServer with a non-existent server name?
  • What errors can rewindFiles throw if checkpointing isn't enabled?

3. HookResponse Breaking Change

The HookResponse signature changed significantly (added hookId, output, outcome fields). This is technically a breaking change. Consider:

  • Documenting this as a breaking change if users have pattern matching on SystemEvent
  • The change is properly handled in MessageConverter with safe defaults

4. Test Coverage

While test coverage is good, consider adding tests for:

  • Edge cases: empty precedingToolUseIds in ToolUseSummary
  • Error scenarios: TaskStatus.Failed and HookOutcome.Error flows
  • New QueryStream methods (would require integration tests)

5. Documentation

Consider enhancing documentation for:

  • When to use agent field vs agents map (one is for main thread, other for subagents)
  • The relationship between PermissionMode.Delegate and subagent execution
  • Examples of using the new hook progress tracking features

🔒 Security

No security concerns identified:

  • All new fields properly validate input (e.g., TaskStatus.fromString returns Custom for unknown values)
  • No unsafe JS interop patterns
  • Proper null handling with js.UndefOr and getOrElse

🚀 Performance

No performance concerns:

  • Efficient parsing with safe defaults (getOrElse("") for optional strings)
  • No unnecessary allocations
  • Proper use of Option.map for optional transformations

📝 Minor Suggestions

  1. MessageConverter.scala:179: Consider extracting "needs-auth" / "needs_auth" logic into McpConnectionStatus.fromString to centralize the legacy format handling

  2. QueryStream.scala:204-208: The rewindFiles method could benefit from a default parameter doc comment explaining when dryRun=true is useful

  3. Test organization: Consider grouping hook-related tests (HookStarted, HookProgress, HookResponse) in a separate test class for better organization

🎯 Recommendation

APPROVE - This is a high-quality implementation that:

  • ✅ Maintains the project's excellent code quality standards
  • ✅ Provides comprehensive test coverage
  • ✅ Follows established architectural patterns
  • ✅ Includes proper documentation
  • ✅ Handles backward compatibility concerns

The minor suggestions above are optional improvements that don't block merging.

📊 Files Changed Summary

  • build.mill: Version bump to 0.2.2-SNAPSHOT ✅
  • package.json, bun.lock: Dependency updates (zod 4.0.0, SDK 0.2.22) ✅
  • AgentMessage.scala: New message types with proper codecs ✅
  • SystemEvent.scala: Enhanced hook events and MCP status ✅
  • MessageConverter.scala: Proper parsing for all new types ✅
  • QueryStream.scala: New control methods with ZIO integration ✅
  • AgentOptions.scala: Main agent configuration support ✅
  • Test files: Comprehensive coverage for new features ✅

Great work on this update! The implementation demonstrates strong attention to detail and maintains the high quality bar of the project.

@arcaputo3 arcaputo3 merged commit c117d47 into main Jan 28, 2026
3 checks passed
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.

1 participant