Skip to main content

claude_codes/
lib.rs

1//! A tightly typed Rust interface for the Claude Code JSON protocol
2//!
3//! This crate provides type-safe bindings for interacting with the Claude CLI
4//! through its JSON Lines protocol. It handles the complexity of message serialization,
5//! deserialization, and streaming communication with Claude.
6//!
7//! # Quick Start
8//!
9//! Add this crate to your project:
10//! ```bash
11//! cargo add claude-codes
12//! ```
13//!
14//! ## Using the Async Client (Recommended)
15//!
16//! ```ignore
17//! use claude_codes::AsyncClient;
18//!
19//! #[tokio::main]
20//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
21//!     // Create a client with automatic version checking
22//!     let mut client = AsyncClient::with_defaults().await?;
23//!
24//!     // Send a query and stream responses
25//!     let mut stream = client.query_stream("What is 2 + 2?").await?;
26//!
27//!     while let Some(response) = stream.next().await {
28//!         match response {
29//!             Ok(output) => {
30//!                 println!("Received: {}", output.message_type());
31//!                 // Handle different message types
32//!             }
33//!             Err(e) => eprintln!("Error: {}", e),
34//!         }
35//!     }
36//!
37//!     Ok(())
38//! }
39//! ```
40//!
41//! ## Using the Sync Client
42//!
43//! ```ignore
44//! use claude_codes::{SyncClient, ClaudeInput};
45//!
46//! fn main() -> Result<(), Box<dyn std::error::Error>> {
47//!     // Create a synchronous client
48//!     let mut client = SyncClient::with_defaults()?;
49//!
50//!     // Build a structured input message
51//!     let input = ClaudeInput::user_message("What is 2 + 2?", uuid::Uuid::new_v4());
52//!
53//!     // Send and collect all responses
54//!     let responses = client.query(input)?;
55//!
56//!     for response in responses {
57//!         println!("Received: {}", response.message_type());
58//!     }
59//!
60//!     Ok(())
61//! }
62//! ```
63//!
64//! # Architecture
65//!
66//! The crate is organized into several key modules:
67//!
68//! - [`client`] - High-level async and sync clients for easy interaction
69//! - [`protocol`] - Core JSON Lines protocol implementation
70//! - [`io`] - Top-level message types (`ClaudeInput`, `ClaudeOutput`)
71//! - [`messages`] - Detailed message structures for requests and responses
72//! - [`cli`] - Builder for configuring Claude CLI invocation
73//! - [`error`] - Error types and result aliases
74//! - [`version`] - Version compatibility checking
75//!
76//! # Version Compatibility
77//!
78//! ⚠️ **Important**: The Claude CLI protocol is unstable and evolving. This crate
79//! automatically checks your Claude CLI version and warns if it's newer than tested.
80//!
81//! Current tested version: **2.1.220**
82//!
83//! Report compatibility issues at: <https://github.com/meawoppl/rust-claude-codes/pulls>
84//!
85//! # Message Types
86//!
87//! The protocol uses several message types:
88//!
89//! - **System** - Initialization and metadata messages
90//! - **User** - Input messages from the user
91//! - **Assistant** - Claude's responses
92//! - **Result** - Session completion with timing and cost info
93//!
94//! # Examples
95//!
96//! See the `examples/` directory for complete working examples:
97//! - `async_client.rs` - Simple async client usage
98//! - `sync_client.rs` - Synchronous client usage
99//! - `basic_repl.rs` - Interactive REPL implementation
100
101// Core modules always available
102pub mod error;
103pub mod io;
104pub mod messages;
105pub mod models;
106pub mod protocol;
107pub mod tool_inputs;
108pub mod types;
109
110// Client modules
111#[cfg(feature = "async-client")]
112pub mod client_async;
113#[cfg(feature = "async-client")]
114pub mod client_raw_async;
115#[cfg(feature = "sync-client")]
116pub mod client_sync;
117
118// Client-related modules
119#[cfg(any(feature = "sync-client", feature = "async-client"))]
120pub mod cli;
121#[cfg(any(feature = "sync-client", feature = "async-client"))]
122pub mod version;
123
124#[cfg(any(feature = "sync-client", feature = "async-client"))]
125mod process;
126
127// Core exports always available
128pub use error::{Error, Result};
129pub use io::{
130    AnthropicError, AnthropicErrorDetails, ApiErrorType, AssistantMessageContent, ClaudeInput,
131    ClaudeOutput, ParseError, TranscriptMessage,
132};
133pub use messages::*;
134pub use models::ClaudeModel;
135pub use protocol::{MessageEnvelope, Protocol};
136pub use types::*;
137
138// Content block types for message parsing
139pub use io::{
140    CodeExecutionToolResultBlock, ContainerUploadBlock, ContentBlock, FallbackBlock, FallbackModel,
141    ImageBlock, ImageSource, ImageSourceType, McpToolResultBlock, McpToolUseBlock, MediaType,
142    ServerToolUseBlock, TextBlock, ThinkingBlock, ToolResultBlock, ToolResultContent,
143    WebSearchToolResultBlock,
144};
145
146// Control protocol types for tool permission handling
147pub use io::{
148    AskUserQuestionResponseError, ControlRequest, ControlRequestMessage, ControlRequestPayload,
149    ControlResponse, ControlResponseMessage, ControlResponsePayload, GetUsageResponse,
150    HookCallbackRequest, InitializeRequest, McpMessageRequest, ModelScopedRateLimit, Permission,
151    PermissionBehavior, PermissionDenial, PermissionDestination, PermissionModeName,
152    PermissionResult, PermissionRule, PermissionSuggestion, PermissionType, ToolCaller,
153    ToolPermissionRequest, ToolUseBlock, UsageBehavior, UsageBehaviors, UsageModelUsage,
154    UsageRateLimitWindow, UsageRateLimits, UsageSession,
155};
156
157// System message and assistant message types
158pub use io::{
159    ApiKeySource, ApiRetryMessage, AssistantErrorKind, BackgroundTaskInfo,
160    BackgroundTasksChangedMessage, CodeChangePublishedMessage, CommandInfo, CommandsChangedMessage,
161    CompactBoundaryMessage, CompactMetadata, CompactionTrigger, ControlRequestProgressMessage,
162    ElicitationCompleteMessage, FailedPersistedFile, FilesPersistedMessage, HookProgressMessage,
163    HookResponseMessage, HookStartedMessage, InformationalMessage, InitMessage, InitPermissionMode,
164    KnownSystemEvent, LocalCommandOutputMessage, McpMeta, McpServerError, MemoryPaths,
165    MemoryRecallItem, MemoryRecallMessage, MessageOrigin, MessageRole, MirrorErrorKey,
166    MirrorErrorMessage, ModelRefusalFallbackMessage, ModelRefusalNoFallbackMessage,
167    NotificationMessage, OutputStyle, PermissionDeniedMessage, PersistedFile, PluginDiagnostic,
168    PluginInfo, PluginInstallMessage, PreservedMessages, PreservedSegment, StatusMessage,
169    StatusMessageStatus, StopReason, SummarizeMetadata, SystemMessage, SystemSubtype,
170    TaskNotificationMessage, TaskPatch, TaskProgressMessage, TaskStartedMessage, TaskStatus,
171    TaskType, TaskUpdatedMessage, TaskUsage, ThinkingTokensMessage, ToolResultMeta, ToolUseMeta,
172    VcsMutationKind, VcsStateChangedMessage, WorkerShuttingDownMessage,
173};
174
175// Additional top-level output message wrappers
176pub use io::{
177    AuthStatusMessage, CommandLifecycleMessage, CommandLifecycleState, ConversationResetMessage,
178    PromptSuggestionMessage, StreamEventMessage, SubagentRetry, ToolProgressMessage,
179    ToolUseSummaryMessage,
180};
181
182// Wire-fidelity audit for verifying frames are fully typed
183pub use io::{assert_fully_wrapped, audit_frame, FrameAudit};
184
185// Rate limit types
186pub use io::{
187    OverageDisabledReason, OveragePeriodUtilization, OverageStatus, RateLimitErrorCode,
188    RateLimitEvent, RateLimitInfo, RateLimitStatus, RateLimitWindow,
189};
190
191// Usage types
192pub use io::{
193    AssistantUsage, CacheCreationDetails, DeferredToolUse, FastModeDisabledReason, ServerToolUse,
194    SubagentResult, SubagentToolStats, SubagentUsageRollup, UsageInfo,
195};
196
197// Typed tool input types
198pub use tool_inputs::{
199    AllowedPrompt, AskUserQuestionInput, BashInput, EditInput, EnterPlanModeInput,
200    ExitPlanModeInput, GlobInput, GrepInput, GrepOutputMode, KillShellInput, LsInput,
201    MultiEditInput, MultiEditOperation, NotebookCellType, NotebookEditInput, NotebookEditMode,
202    NotebookReadInput, Question, QuestionMetadata, QuestionOption, ReadInput, ScheduleWakeupInput,
203    SkillInput, SubagentType, TaskInput, TaskOutputInput, TodoItem, TodoStatus, TodoWriteInput,
204    ToolInput, ToolSearchInput, WebFetchInput, WebSearchInput, WriteInput,
205};
206
207// Client exports
208#[cfg(feature = "async-client")]
209pub use client_async::{AsyncClient, AsyncStreamProcessor};
210#[cfg(feature = "async-client")]
211pub use client_raw_async::RawAsyncClient;
212#[cfg(feature = "sync-client")]
213pub use client_sync::{StreamProcessor, SyncClient};
214
215// Client-related exports
216#[cfg(any(feature = "sync-client", feature = "async-client"))]
217pub use cli::{ClaudeCliBuilder, CliFlag, InputFormat, OutputFormat, PermissionMode};
218
219#[cfg(test)]
220mod tests {
221    #[test]
222    fn it_works() {
223        assert_eq!(2 + 2, 4);
224    }
225}