1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! A typed Rust interface for the [OpenAI Codex CLI](https://github.com/openai/codex) protocol.
//!
//! This crate provides type-safe bindings for communicating with the Codex CLI's
//! app-server via its JSON-RPC protocol. It handles message framing, request/response
//! correlation, approval flows, and streaming notifications for multi-turn agent
//! conversations.
//!
//! # Quick Start
//!
//! ```bash
//! cargo add codex-codes
//! ```
//!
//! See `examples/async_client.rs` and `examples/sync_client.rs` for runnable
//! versions of the usage patterns below. The high-level shape:
//!
//! ```ignore
//! let mut client = AsyncClient::start().await?;
//! let thread = client
//! .thread_start(&serde_json::from_value(serde_json::json!({}))?)
//! .await?;
//! client.turn_start(&TurnStartParams {
//! thread_id: thread.thread.id.clone(),
//! input: vec![UserInput::Text {
//! text: "What is 2 + 2?".into(),
//! text_elements: None,
//! }],
//! // All other fields default to None — populate when overriding
//! // model / approval / sandbox / etc. for this turn.
//! ..serde_json::from_value(serde_json::json!({"threadId": thread.thread.id, "input": []}))?
//! }).await?;
//! ```
//!
//! # Architecture
//!
//! The crate is organized into several key modules:
//!
//! - [`client_async`] / [`client_sync`] — High-level clients that manage the
//! app-server process, request/response correlation, and message buffering
//! - [`protocol`] — App-server v2 request params, response types, and notification
//! bodies (thread/turn lifecycle, approvals, deltas)
//! - [`jsonrpc`] — Low-level JSON-RPC message types (request, response, error,
//! notification) matching the app-server's wire format
//! - [`cli`] — Builder for spawning `codex app-server --listen stdio://`
//! - [`error`] — Error types and result aliases
//! - [`version`] — Version compatibility checking against the installed CLI
//!
//! # Protocol Overview
//!
//! The Codex app-server communicates via newline-delimited JSON-RPC 2.0 over stdio
//! (without the standard `"jsonrpc":"2.0"` field). The conversation lifecycle is:
//!
//! 1. **Initialize** — `initialize` + `initialized` handshake (handled automatically by `start()`)
//! 2. **Start a thread** — `thread/start` creates a conversation session
//! 3. **Start a turn** — `turn/start` sends user input, triggering agent work
//! 4. **Stream notifications** — The server emits `item/agentMessage/delta`,
//! `item/commandExecution/outputDelta`, etc. as the agent works
//! 5. **Handle approvals** — The server may send requests like
//! `item/commandExecution/requestApproval` that require a response
//! 6. **Turn completes** — `turn/completed` signals the agent is done
//! 7. **Repeat** — Send another `turn/start` for follow-up questions
//!
//! # Feature Flags
//!
//! | Feature | Description | WASM-compatible |
//! |---------|-------------|-----------------|
//! | `types` | Core message types and protocol structs only | Yes |
//! | `sync-client` | Synchronous client with blocking I/O | No |
//! | `async-client` | Asynchronous client using tokio | No |
//!
//! All features are enabled by default. For WASM or type-sharing use cases:
//!
//! ```toml
//! [dependencies]
//! codex-codes = { version = "0.128", default-features = false, features = ["types"] }
//! ```
//!
//! # Version Compatibility
//!
//! The Codex CLI protocol is evolving. This crate automatically checks your
//! installed CLI version and warns if it's newer than tested. Current tested
//! version: **0.130.0**
//!
//! Report compatibility issues at: <https://github.com/meawoppl/rust-code-agent-sdks/issues>
//!
//! # Examples
//!
//! See the `examples/` directory for complete working examples:
//! - `async_client.rs` — Single-turn async query with streaming deltas
//! - `sync_client.rs` — Single-turn synchronous query
//! - `basic_repl.rs` — Interactive REPL with multi-turn conversation and approval handling
//!
//! # Parsing Raw Protocol Messages
//!
//! ```
//! use codex_codes::{ThreadEvent, ThreadItem, JsonRpcMessage};
//!
//! // Parse exec-format JSONL events
//! let json = r#"{"type":"thread.started","thread_id":"th_abc"}"#;
//! let event: ThreadEvent = serde_json::from_str(json).unwrap();
//!
//! // Parse app-server JSON-RPC messages
//! let rpc = r#"{"id":1,"result":{"threadId":"th_abc"}}"#;
//! let msg: JsonRpcMessage = serde_json::from_str(rpc).unwrap();
//! ```
// Exec-level event types (JSONL protocol)
pub use ;
// Error types (always available)
pub use ;
// JSON-RPC types (always available)
pub use ;
// App-server protocol types — generated from the upstream JSON Schema and
// re-exported through `protocol::*`.
pub use *;
// Typed message dispatch (notifications + server-to-client requests)
pub use ;
// CLI builder (feature-gated)
pub use AppServerBuilder;
// Sync client
pub use ;
// Async client
pub use ;