diff --git a/codex-rs/exec-server/README.md b/codex-rs/exec-server/README.md index af21dc568a..23e9dacfbf 100644 --- a/codex-rs/exec-server/README.md +++ b/codex-rs/exec-server/README.md @@ -1,6 +1,6 @@ # codex-exec-server -`codex-exec-server` is a small standalone stdio JSON-RPC server for spawning +`codex-exec-server` is a small standalone WebSocket JSON-RPC server for spawning and controlling subprocesses through `codex-utils-pty`. This PR intentionally lands only the standalone binary, client, wire protocol, @@ -18,11 +18,7 @@ unified-exec in this PR; it is only the standalone transport layer. ## Transport -The server speaks newline-delimited JSON-RPC 2.0 over stdio. - -- `stdin`: one JSON-RPC message per line -- `stdout`: one JSON-RPC message per line -- `stderr`: reserved for logs / process errors +The server speaks JSON-RPC 2.0 over WebSockets. Like the app-server transport, messages on the wire omit the `"jsonrpc":"2.0"` field and use the shared `codex-app-server-protocol` envelope types. @@ -249,7 +245,7 @@ The crate exports: - protocol structs such as `ExecParams`, `ExecResponse`, `WriteParams`, `TerminateParams`, `ExecOutputDeltaNotification`, and `ExecExitedNotification` -- `run_main()` for embedding the stdio server in a binary +- `run_main()` for embedding the WebSocket server in a binary ## Example session diff --git a/codex-rs/exec-server/src/client.rs b/codex-rs/exec-server/src/client.rs index 2f314f3db3..a7680e73e8 100644 --- a/codex-rs/exec-server/src/client.rs +++ b/codex-rs/exec-server/src/client.rs @@ -17,8 +17,6 @@ use codex_app_server_protocol::FsWriteFileParams; use codex_app_server_protocol::FsWriteFileResponse; use codex_app_server_protocol::JSONRPCNotification; use serde_json::Value; -use tokio::io::AsyncRead; -use tokio::io::AsyncWrite; use tokio::sync::broadcast; use tokio::sync::mpsc; use tokio::time::timeout; @@ -203,22 +201,6 @@ impl ExecServerClient { Ok(client) } - pub async fn connect_stdio( - stdin: W, - stdout: R, - options: ExecServerClientConnectOptions, - ) -> Result - where - R: AsyncRead + Unpin + Send + 'static, - W: AsyncWrite + Unpin + Send + 'static, - { - Self::connect( - JsonRpcConnection::from_stdio(stdout, stdin, "exec-server stdio".to_string()), - options, - ) - .await - } - pub async fn connect_websocket( args: RemoteExecServerConnectArgs, ) -> Result { diff --git a/codex-rs/exec-server/src/connection.rs b/codex-rs/exec-server/src/connection.rs index af03fc0686..c17803b33f 100644 --- a/codex-rs/exec-server/src/connection.rs +++ b/codex-rs/exec-server/src/connection.rs @@ -1,11 +1,15 @@ use codex_app_server_protocol::JSONRPCMessage; use futures::SinkExt; use futures::StreamExt; +#[cfg(test)] use tokio::io::AsyncBufReadExt; use tokio::io::AsyncRead; use tokio::io::AsyncWrite; +#[cfg(test)] use tokio::io::AsyncWriteExt; +#[cfg(test)] use tokio::io::BufReader; +#[cfg(test)] use tokio::io::BufWriter; use tokio::sync::mpsc; use tokio_tungstenite::WebSocketStream; @@ -27,6 +31,7 @@ pub(crate) struct JsonRpcConnection { } impl JsonRpcConnection { + #[cfg(test)] pub(crate) fn from_stdio(reader: R, writer: W, connection_label: String) -> Self where R: AsyncRead + Unpin + Send + 'static, @@ -256,6 +261,7 @@ async fn send_malformed_message( .await; } +#[cfg(test)] async fn write_jsonrpc_line_message( writer: &mut BufWriter, message: &JSONRPCMessage,