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//! ```no_run
17//! # #[cfg(feature = "async-client")]
18//! # {
19//! use claude_codes::AsyncClient;
20//!
21//! #[tokio::main]
22//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
23//!     // Create a client with automatic version checking
24//!     let mut client = AsyncClient::with_defaults().await?;
25//!     
26//!     // Send a query and stream responses
27//!     let mut stream = client.query_stream("What is 2 + 2?").await?;
28//!     
29//!     while let Some(response) = stream.next().await {
30//!         match response {
31//!             Ok(output) => {
32//!                 println!("Received: {}", output.message_type());
33//!                 // Handle different message types
34//!             }
35//!             Err(e) => eprintln!("Error: {}", e),
36//!         }
37//!     }
38//!     
39//!     Ok(())
40//! }
41//! # }
42//! # #[cfg(not(feature = "async-client"))]
43//! # fn main() {}
44//! ```
45//!
46//! ## Using the Sync Client
47//!
48//! ```no_run
49//! # #[cfg(feature = "sync-client")]
50//! # {
51//! use claude_codes::{SyncClient, ClaudeInput};
52//!
53//! fn main() -> Result<(), Box<dyn std::error::Error>> {
54//!     // Create a synchronous client
55//!     let mut client = SyncClient::with_defaults()?;
56//!     
57//!     // Build a structured input message  
58//!     let input = ClaudeInput::user_message("What is 2 + 2?", uuid::Uuid::new_v4());
59//!     
60//!     // Send and collect all responses
61//!     let responses = client.query(input)?;
62//!     
63//!     for response in responses {
64//!         println!("Received: {}", response.message_type());
65//!     }
66//!     
67//!     Ok(())
68//! }
69//! # }
70//! # #[cfg(not(feature = "sync-client"))]
71//! # fn main() {}
72//! ```
73//!
74//! # Architecture
75//!
76//! The crate is organized into several key modules:
77//!
78//! - [`client`] - High-level async and sync clients for easy interaction
79//! - [`protocol`] - Core JSON Lines protocol implementation
80//! - [`io`] - Top-level message types (`ClaudeInput`, `ClaudeOutput`)
81//! - [`messages`] - Detailed message structures for requests and responses
82//! - [`cli`] - Builder for configuring Claude CLI invocation
83//! - [`error`] - Error types and result aliases
84//! - [`version`] - Version compatibility checking
85//!
86//! # Version Compatibility
87//!
88//! ⚠️ **Important**: The Claude CLI protocol is unstable and evolving. This crate
89//! automatically checks your Claude CLI version and warns if it's newer than tested.
90//!
91//! Current tested version: **1.0.89**
92//!
93//! Report compatibility issues at: <https://github.com/meawoppl/rust-claude-codes/pulls>
94//!
95//! # Message Types
96//!
97//! The protocol uses several message types:
98//!
99//! - **System** - Initialization and metadata messages
100//! - **User** - Input messages from the user
101//! - **Assistant** - Claude's responses
102//! - **Result** - Session completion with timing and cost info
103//!
104//! # Examples
105//!
106//! See the `examples/` directory for complete working examples:
107//! - `async_client.rs` - Simple async client usage
108//! - `sync_client.rs` - Synchronous client usage
109//! - `basic_repl.rs` - Interactive REPL implementation
110
111// Core modules always available
112pub mod error;
113pub mod io;
114pub mod messages;
115pub mod protocol;
116pub mod types;
117
118// Client modules
119#[cfg(feature = "async-client")]
120pub mod client_async;
121#[cfg(feature = "sync-client")]
122pub mod client_sync;
123
124// Client-related modules
125#[cfg(any(feature = "sync-client", feature = "async-client"))]
126pub mod cli;
127#[cfg(any(feature = "sync-client", feature = "async-client"))]
128pub mod version;
129
130// Core exports always available
131pub use error::{Error, Result};
132pub use io::{AssistantMessageContent, ClaudeInput, ClaudeOutput, ParseError};
133pub use messages::*;
134pub use protocol::{MessageEnvelope, Protocol};
135pub use types::*;
136
137// Client exports
138#[cfg(feature = "async-client")]
139pub use client_async::{AsyncClient, AsyncStreamProcessor};
140#[cfg(feature = "sync-client")]
141pub use client_sync::{StreamProcessor, SyncClient};
142
143// Client-related exports
144#[cfg(any(feature = "sync-client", feature = "async-client"))]
145pub use cli::{ClaudeCliBuilder, PermissionMode};
146
147#[cfg(test)]
148mod tests {
149    #[test]
150    fn it_works() {
151        assert_eq!(2 + 2, 4);
152    }
153}