mirror of
https://github.com/openai/codex.git
synced 2026-04-28 18:32:04 +03:00
202 lines
6.8 KiB
Markdown
202 lines
6.8 KiB
Markdown
# 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:
|
|
|
|
<img width="243" height="119" alt="image" src="https://github.com/user-attachments/assets/13d5608e-3b66-4b8d-8fe7-ce464310d85d" />
|
|
|
|
## 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<Line<'static>> = 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<Line<'static>> = 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<Line<'static>> = 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`. |