feat: codex exec writes only the final message to stdout (#4644)

This updates `codex exec` so that, by default, most of the agent's
activity is written to stderr so that only the final agent message is
written to stdout. This makes it easier to pipe `codex exec` into
another tool without extra filtering.

I introduced `#![deny(clippy::print_stdout)]` to help enforce this
change and renamed the `ts_println!()` macro to `ts_msg()` because (1)
it no longer calls `println!()` and (2), `ts_eprintln!()` seemed too
long of a name.

While here, this also adds `-o` as an alias for `--output-last-message`.

Fixes https://github.com/openai/codex/issues/1670
This commit is contained in:
Michael Bolin
2025-10-03 09:22:12 -07:00
committed by GitHub
parent 5af08e0719
commit 042d4d55d9
6 changed files with 99 additions and 67 deletions

View File

@@ -229,14 +229,14 @@ fn exec_resume_preserves_cli_configuration_overrides() -> anyhow::Result<()> {
assert!(output.status.success(), "resume run failed: {output:?}");
let stdout = String::from_utf8(output.stdout)?;
let stderr = String::from_utf8(output.stderr)?;
assert!(
stdout.contains("model: gpt-5-high"),
"stdout missing model override: {stdout}"
stderr.contains("model: gpt-5-high"),
"stderr missing model override: {stderr}"
);
assert!(
stdout.contains("sandbox: workspace-write"),
"stdout missing sandbox override: {stdout}"
stderr.contains("sandbox: workspace-write"),
"stderr missing sandbox override: {stderr}"
);
let resumed_path = find_session_file_containing_marker(&sessions_dir, &marker2)