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
163
164
165
166
167
168
169
170
171
172
173
174
175
//! Transport abstraction for communicating with Claude Code CLI
//!
//! This module provides the `Transport` trait, which defines an async interface for
//! establishing connections, sending messages, and receiving responses from the Claude CLI.
//!
//! # Overview
//!
//! The transport layer handles:
//! - CLI discovery and version validation
//! - Process lifecycle management (spawning, monitoring, shutdown)
//! - Bidirectional communication (stdin writes, stdout reads)
//! - NDJSON message framing and parsing
//! - Error handling and recovery
//!
//! # Default Implementation
//!
//! `SubprocessCLITransport` is the default implementation that spawns the `claude` CLI
//! as a subprocess and communicates over stdin/stdout pipes.
//!
//! # Custom Transports
//!
//! The `Transport` trait can be implemented for custom transports (e.g., remote connections,
//! mock transports for testing, or alternative CLI implementations).
//!
//! # Example
//!
//! ```ignore
//! use rusty_claw::transport::{Transport, SubprocessCLITransport};
//!
//! // Create transport with automatic CLI discovery
//! let mut transport = SubprocessCLITransport::new(
//! None, // Will auto-discover 'claude' in PATH
//! vec!["--output-format=stream-json".to_string()]
//! );
//!
//! // Establish connection (discovers and validates CLI version)
//! transport.connect().await?;
//!
//! // Get message receiver
//! let mut messages = transport.messages();
//!
//! // Send a message
//! transport.write(b"{\"type\":\"user\",\"message\":\"Hello\"}\n").await?;
//!
//! // Receive messages
//! while let Some(result) = messages.recv().await {
//! match result {
//! Ok(msg) => println!("Received: {:?}", msg),
//! Err(e) => eprintln!("Error: {}", e),
//! }
//! }
//!
//! // Clean shutdown
//! transport.close().await?;
//! ```
use async_trait;
use Value;
use mpsc;
use crateClawError;
pub use CliDiscovery;
pub use SubprocessCLITransport;
/// Abstract transport for communicating with Claude Code CLI.
///
/// The default implementation ([`SubprocessCLITransport`]) spawns a subprocess,
/// but this trait enables custom transports (remote connections, mock for testing).
///
/// # Lifecycle
///
/// 1. **Create** - Construct transport with configuration
/// 2. **Connect** - Call [`connect()`](Transport::connect) to establish connection
/// 3. **Communicate** - Use [`write()`](Transport::write) and [`messages()`](Transport::messages)
/// 4. **Shutdown** - Call [`close()`](Transport::close) for graceful cleanup
///
/// # Thread Safety
///
/// All methods can be called from multiple tasks concurrently (`Send + Sync`).
/// The transport implementation handles internal synchronization.
///
/// # Message Channel
///
/// [`messages()`](Transport::messages) returns an [`UnboundedReceiver`](mpsc::UnboundedReceiver)
/// for incoming NDJSON messages. This method can only be called **once** per connection -
/// subsequent calls will panic. Store the receiver and pass it to consumers.