# PR #1897: Run command UI - URL: https://github.com/openai/codex/pull/1897 - Author: aibrahim-oai - Created: 2025-08-06 21:37:53 UTC - Updated: 2025-08-07 00:11:07 UTC - Changes: +27/-24, Files changed: 2, Commits: 7 ## Description Edit how commands show: image ## Full Diff ```diff diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index 128e1ae8c1..50fa776ec3 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -485,7 +485,7 @@ impl ChatWidget<'_> { EventMsg::ExecCommandEnd(ExecCommandEndEvent { call_id, exit_code, - duration, + duration: _, stdout, stderr, }) => { @@ -498,7 +498,6 @@ impl ChatWidget<'_> { exit_code, stdout, stderr, - duration, }, )); } diff --git a/codex-rs/tui/src/history_cell.rs b/codex-rs/tui/src/history_cell.rs index c577ce17a0..5caedf98ab 100644 --- a/codex-rs/tui/src/history_cell.rs +++ b/codex-rs/tui/src/history_cell.rs @@ -38,7 +38,6 @@ pub(crate) struct CommandOutput { pub(crate) exit_code: i32, pub(crate) stdout: String, pub(crate) stderr: String, - pub(crate) duration: Duration, } pub(crate) enum PatchEventType { @@ -122,7 +121,7 @@ pub(crate) enum HistoryCell { PatchApplyResult { view: TextBlock }, } -const TOOL_CALL_MAX_LINES: usize = 5; +const TOOL_CALL_MAX_LINES: usize = 3; impl HistoryCell { /// Return a cloned, plain representation of the cell's lines suitable for @@ -232,8 +231,11 @@ impl HistoryCell { let command_escaped = strip_bash_lc_and_escape(&command); let lines: Vec> = vec![ - Line::from(vec!["command".magenta(), " running...".dim()]), - Line::from(format!("$ {command_escaped}")), + Line::from(vec![ + "▌ ".cyan(), + "Running command ".magenta(), + command_escaped.into(), + ]), Line::from(""), ]; @@ -247,34 +249,36 @@ impl HistoryCell { exit_code, stdout, stderr, - duration, } = output; let mut lines: Vec> = Vec::new(); - - // Title depends on whether we have output yet. - let title_line = Line::from(vec![ - "command".magenta(), - format!( - " (code: {}, duration: {})", - exit_code, - format_duration(duration) - ) - .dim(), - ]); - lines.push(title_line); + let command_escaped = strip_bash_lc_and_escape(&command); + lines.push(Line::from(vec![ + "⚡Ran command ".magenta(), + command_escaped.into(), + ])); let src = if exit_code == 0 { stdout } else { stderr }; - let cmdline = strip_bash_lc_and_escape(&command); - lines.push(Line::from(format!("$ {cmdline}"))); let mut lines_iter = src.lines(); - for raw in lines_iter.by_ref().take(TOOL_CALL_MAX_LINES) { - lines.push(ansi_escape_line(raw).dim()); + for (idx, raw) in lines_iter.by_ref().take(TOOL_CALL_MAX_LINES).enumerate() { + let mut line = ansi_escape_line(raw); + let prefix = if idx == 0 { " ⎿ " } else { " " }; + line.spans.insert(0, prefix.into()); + line.spans.iter_mut().for_each(|span| { + span.style = span.style.add_modifier(Modifier::DIM); + }); + lines.push(line); } let remaining = lines_iter.count(); if remaining > 0 { - lines.push(Line::from(format!("... {remaining} additional lines")).dim()); + let mut more = Line::from(format!("... +{remaining} lines")); + // Continuation/ellipsis is treated as a subsequent line for prefixing + more.spans.insert(0, " ".into()); + more.spans.iter_mut().for_each(|span| { + span.style = span.style.add_modifier(Modifier::DIM); + }); + lines.push(more); } lines.push(Line::from("")); ``` ## Review Comments ### codex-rs/tui/src/history_cell.rs - Created: 2025-08-06 22:38:09 UTC | Link: https://github.com/openai/codex/pull/1897#discussion_r2258456321 ```diff @@ -36,6 +36,7 @@ pub(crate) struct CommandOutput { pub(crate) exit_code: i32, pub(crate) stdout: String, pub(crate) stderr: String, + #[allow(dead_code)] ``` > Let's just delete this if we aren't going to use it. - Created: 2025-08-06 22:39:59 UTC | Link: https://github.com/openai/codex/pull/1897#discussion_r2258458477 ```diff @@ -120,7 +121,7 @@ pub(crate) enum HistoryCell { PatchApplyResult { view: TextBlock }, } -const TOOL_CALL_MAX_LINES: usize = 5; +const TOOL_CALL_MAX_LINES: usize = 3; ``` > In a separate PR, it might be nice to make this overridable via `Config`. > > I thought this had been requested in the past, though it seems it was the number of lines available to the model rather than in the UI: https://github.com/openai/codex/pull/575 - Created: 2025-08-06 22:53:09 UTC | Link: https://github.com/openai/codex/pull/1897#discussion_r2258473587 ```diff @@ -242,34 +246,39 @@ impl HistoryCell { exit_code, stdout, stderr, - duration, + duration: _, } = output; let mut lines: Vec> = Vec::new(); - - // Title depends on whether we have output yet. - let title_line = Line::from(vec![ - "command".magenta(), - format!( - " (code: {}, duration: {})", - exit_code, - format_duration(duration) - ) - .dim(), - ]); - lines.push(title_line); + let command_escaped = strip_bash_lc_and_escape(&command); + lines.push(Line::from(vec![ + "⚡Ran command ".magenta(), + command_escaped.into(), + ])); let src = if exit_code == 0 { stdout } else { stderr }; - let cmdline = strip_bash_lc_and_escape(&command); - lines.push(Line::from(format!("$ {cmdline}"))); let mut lines_iter = src.lines(); + let mut is_first = true; for raw in lines_iter.by_ref().take(TOOL_CALL_MAX_LINES) { - lines.push(ansi_escape_line(raw).dim()); + let mut line = ansi_escape_line(raw); ``` > Note you can also use `enumerate()` to get the `index` in addition to the value and then you can check `index == 0` instead of maintaining this `mut is_first`.