|  | 
| 2 | 2 | mod event_processor; | 
| 3 | 3 | 
 | 
| 4 | 4 | use std::io::IsTerminal; | 
|  | 5 | +use std::io::Read; | 
| 5 | 6 | use std::path::Path; | 
| 6 | 7 | use std::path::PathBuf; | 
| 7 | 8 | use std::sync::Arc; | 
| @@ -40,6 +41,41 @@ pub async fn run_main(cli: Cli, codex_linux_sandbox_exe: Option<PathBuf>) -> any | 
| 40 | 41 |         config_overrides, | 
| 41 | 42 |     } = cli; | 
| 42 | 43 | 
 | 
|  | 44 | +    // Determine the prompt based on CLI arg and/or stdin. | 
|  | 45 | +    let prompt = match prompt { | 
|  | 46 | +        Some(p) if p != "-" => p, | 
|  | 47 | +        // Either `-` was passed or no positional arg. | 
|  | 48 | +        maybe_dash => { | 
|  | 49 | +            // When no arg (None) **and** stdin is a TTY, bail out early – unless the | 
|  | 50 | +            // user explicitly forced reading via `-`. | 
|  | 51 | +            let force_stdin = matches!(maybe_dash.as_deref(), Some("-")); | 
|  | 52 | + | 
|  | 53 | +            if std::io::stdin().is_terminal() && !force_stdin { | 
|  | 54 | +                eprintln!( | 
|  | 55 | +                    "No prompt provided. Either specify one, use '-' to read from stdin, or pipe the prompt into stdin." | 
|  | 56 | +                ); | 
|  | 57 | +                std::process::exit(1); | 
|  | 58 | +            } | 
|  | 59 | + | 
|  | 60 | +            // Ensure the user knows we are waiting on stdin, as they may | 
|  | 61 | +            // have gotten into this state by mistake. If so, and they are not | 
|  | 62 | +            // writing to stdin, Codex will hang indefinitely, so this should | 
|  | 63 | +            // help them debug in that case. | 
|  | 64 | +            if !force_stdin { | 
|  | 65 | +                eprintln!("Reading prompt from stdin..."); | 
|  | 66 | +            } | 
|  | 67 | +            let mut buffer = String::new(); | 
|  | 68 | +            if let Err(e) = std::io::stdin().read_to_string(&mut buffer) { | 
|  | 69 | +                eprintln!("Failed to read prompt from stdin: {e}"); | 
|  | 70 | +                std::process::exit(1); | 
|  | 71 | +            } else if buffer.trim().is_empty() { | 
|  | 72 | +                eprintln!("No prompt provided via stdin."); | 
|  | 73 | +                std::process::exit(1); | 
|  | 74 | +            } | 
|  | 75 | +            buffer | 
|  | 76 | +        } | 
|  | 77 | +    }; | 
|  | 78 | + | 
| 43 | 79 |     let (stdout_with_ansi, stderr_with_ansi) = match color { | 
| 44 | 80 |         cli::Color::Always => (true, true), | 
| 45 | 81 |         cli::Color::Never => (false, false), | 
|  | 
0 commit comments