From dc4c258b95eb624f969fdd7a6f0eac800625c0a7 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Fri, 29 May 2026 11:43:48 +0100 Subject: [PATCH] Remove debug client entrypoint --- codex-rs/debug-client/src/main.rs | 310 ------------------------------ 1 file changed, 310 deletions(-) delete mode 100644 codex-rs/debug-client/src/main.rs diff --git a/codex-rs/debug-client/src/main.rs b/codex-rs/debug-client/src/main.rs deleted file mode 100644 index a09d9d04f524..000000000000 --- a/codex-rs/debug-client/src/main.rs +++ /dev/null @@ -1,310 +0,0 @@ -mod client; -mod commands; -mod output; -mod reader; -mod state; - -use std::fs::File; -use std::io; -use std::io::BufRead; -use std::path::PathBuf; -use std::sync::mpsc; - -use anyhow::Context; -use anyhow::Result; -use clap::ArgAction; -use clap::Parser; -use codex_app_server_protocol::AskForApproval; - -use crate::client::AppServerClient; -use crate::client::build_thread_resume_params; -use crate::client::build_thread_start_params; -use crate::commands::InputAction; -use crate::commands::UserCommand; -use crate::commands::parse_input; -use crate::output::Output; -use crate::state::ReaderEvent; - -#[derive(Parser)] -#[command(author = "Codex", version, about = "Minimal app-server client")] -struct Cli { - /// Path to the `codex` CLI binary. - #[arg(long, default_value = "codex")] - codex_bin: String, - - /// Forwarded to the `codex` CLI as `--config key=value`. Repeatable. - #[arg(short = 'c', long = "config", value_name = "key=value", action = ArgAction::Append)] - config_overrides: Vec, - - /// Resume an existing thread instead of starting a new one. - #[arg(long)] - thread_id: Option, - - /// Set the approval policy for the thread. - #[arg(long, default_value = "on-request")] - approval_policy: String, - - /// Auto-approve command/file-change approvals. - #[arg(long, default_value_t = false)] - auto_approve: bool, - - /// Only show final assistant messages and tool calls. - #[arg(long, default_value_t = false)] - final_only: bool, - - /// Write raw server JSONL to this file instead of stdout. - #[arg(long, value_name = "PATH")] - output_file: Option, - - /// Optional model override when starting/resuming a thread. - #[arg(long)] - model: Option, - - /// Optional model provider override when starting/resuming a thread. - #[arg(long)] - model_provider: Option, - - /// Optional working directory override when starting/resuming a thread. - #[arg(long)] - cwd: Option, -} - -fn main() -> Result<()> { - let cli = Cli::parse(); - let jsonl_file = cli - .output_file - .as_ref() - .map(File::create) - .transpose() - .with_context(|| { - let Some(path) = cli.output_file.as_ref() else { - return "open output file".to_string(); - }; - format!("open output file {}", path.display()) - })?; - let output = Output::new(jsonl_file); - let approval_policy = parse_approval_policy(&cli.approval_policy)?; - - let mut client = AppServerClient::spawn( - &cli.codex_bin, - &cli.config_overrides, - output.clone(), - cli.final_only, - )?; - client.initialize()?; - - let thread_id = if let Some(thread_id) = cli.thread_id.as_ref() { - client.resume_thread(build_thread_resume_params( - thread_id.clone(), - approval_policy, - cli.model.clone(), - cli.model_provider.clone(), - cli.cwd.clone(), - ))? - } else { - client.start_thread(build_thread_start_params( - approval_policy, - cli.model.clone(), - cli.model_provider.clone(), - cli.cwd.clone(), - ))? - }; - - output - .client_line(&format!("connected to thread {thread_id}")) - .ok(); - output.set_prompt(&thread_id); - - let (event_tx, event_rx) = mpsc::channel(); - client.start_reader(event_tx, cli.auto_approve, cli.final_only)?; - - print_help(&output); - - let stdin = io::stdin(); - let mut lines = stdin.lock().lines(); - - loop { - drain_events(&event_rx, &output); - let prompt_thread = client - .thread_id() - .unwrap_or_else(|| "no-thread".to_string()); - output.prompt(&prompt_thread).ok(); - - let Some(line) = lines.next() else { - break; - }; - let line = line.context("read stdin")?; - - match parse_input(&line) { - Ok(None) => continue, - Ok(Some(InputAction::Message(message))) => { - let Some(active_thread) = client.thread_id() else { - output - .client_line("no active thread; use :new or :resume ") - .ok(); - continue; - }; - if let Err(err) = client.send_turn(&active_thread, message) { - output - .client_line(&format!("failed to send turn: {err}")) - .ok(); - } - } - Ok(Some(InputAction::Command(command))) => { - if !handle_command(command, &client, &output, approval_policy, &cli) { - break; - } - } - Err(err) => { - output.client_line(&err.message()).ok(); - } - } - } - - client.shutdown(); - Ok(()) -} - -fn handle_command( - command: UserCommand, - client: &AppServerClient, - output: &Output, - approval_policy: AskForApproval, - cli: &Cli, -) -> bool { - match command { - UserCommand::Help => { - print_help(output); - true - } - UserCommand::Quit => false, - UserCommand::NewThread => { - match client.request_thread_start(build_thread_start_params( - approval_policy, - cli.model.clone(), - cli.model_provider.clone(), - cli.cwd.clone(), - )) { - Ok(request_id) => { - output - .client_line(&format!("requested new thread ({request_id:?})")) - .ok(); - } - Err(err) => { - output - .client_line(&format!("failed to start thread: {err}")) - .ok(); - } - } - true - } - UserCommand::Resume(thread_id) => { - match client.request_thread_resume(build_thread_resume_params( - thread_id, - approval_policy, - cli.model.clone(), - cli.model_provider.clone(), - cli.cwd.clone(), - )) { - Ok(request_id) => { - output - .client_line(&format!("requested thread resume ({request_id:?})")) - .ok(); - } - Err(err) => { - output - .client_line(&format!("failed to resume thread: {err}")) - .ok(); - } - } - true - } - UserCommand::Use(thread_id) => { - let known = client.use_thread(thread_id.clone()); - output.set_prompt(&thread_id); - if known { - output - .client_line(&format!("switched active thread to {thread_id}")) - .ok(); - } else { - output - .client_line(&format!( - "switched active thread to {thread_id} (unknown; use :resume to load)" - )) - .ok(); - } - true - } - UserCommand::RefreshThread => { - match client.request_thread_list(/*cursor*/ None) { - Ok(request_id) => { - output - .client_line(&format!("requested thread list ({request_id:?})")) - .ok(); - } - Err(err) => { - output - .client_line(&format!("failed to list threads: {err}")) - .ok(); - } - } - true - } - } -} - -fn parse_approval_policy(value: &str) -> Result { - match value { - "untrusted" | "unless-trusted" | "unlessTrusted" => Ok(AskForApproval::UnlessTrusted), - "on-failure" | "onFailure" => Ok(AskForApproval::OnFailure), - "on-request" | "onRequest" => Ok(AskForApproval::OnRequest), - "never" => Ok(AskForApproval::Never), - _ => anyhow::bail!( - "unknown approval policy: {value}. Expected one of: untrusted, on-failure, on-request, never" - ), - } -} - -fn drain_events(event_rx: &mpsc::Receiver, output: &Output) { - while let Ok(event) = event_rx.try_recv() { - match event { - ReaderEvent::ThreadReady { thread_id } => { - output - .client_line(&format!("active thread is now {thread_id}")) - .ok(); - output.set_prompt(&thread_id); - } - ReaderEvent::ThreadList { - thread_ids, - next_cursor, - } => { - if thread_ids.is_empty() { - output.client_line("threads: (none)").ok(); - } else { - output.client_line("threads:").ok(); - for thread_id in thread_ids { - output.client_line(&format!(" {thread_id}")).ok(); - } - } - if let Some(next_cursor) = next_cursor { - output - .client_line(&format!( - "more threads available, next cursor: {next_cursor}" - )) - .ok(); - } - } - } - } -} - -fn print_help(output: &Output) { - let _ = output.client_line("commands:"); - let _ = output.client_line(" :help show this help"); - let _ = output.client_line(" :new start a new thread"); - let _ = output.client_line(" :resume resume an existing thread"); - let _ = output.client_line(" :use switch the active thread"); - let _ = output.client_line(" :refresh-thread list available threads"); - let _ = output.client_line(" :quit exit"); - let _ = output.client_line("type a message to send it as a new turn"); -}