fix(tui/history): render exec status row separately

This commit is contained in:
James Peter
2025-09-17 00:32:58 +10:00
parent 0f254d9ec8
commit 2ec5e6552f
5 changed files with 578 additions and 229 deletions
+28 -5
View File
@@ -54,6 +54,7 @@ use codex_core::protocol::EventMsg;
use codex_core::protocol::ExecApprovalRequestEvent;
use codex_core::protocol::ExecCommandBeginEvent;
use codex_core::protocol::ExecCommandEndEvent;
use codex_core::protocol::ExecOutputStream;
use codex_core::protocol::InputItem;
use codex_core::protocol::SessionConfiguredEvent;
// MCP tool call handlers moved into chatwidget::tools
@@ -153,6 +154,8 @@ struct RunningCommand {
history_index: Option<usize>,
// Aggregated exploration entry (history index, entry index) when grouped
explore_entry: Option<(usize, usize)>,
stdout: String,
stderr: String,
}
pub(crate) struct ChatWidget<'a> {
@@ -3864,8 +3867,28 @@ impl ChatWidget<'_> {
},
);
}
EventMsg::ExecCommandOutputDelta(_) => {
// TODO
EventMsg::ExecCommandOutputDelta(ev) => {
let call_id = ExecCallId(ev.call_id.clone());
if let Some(running) = self.exec.running_commands.get_mut(&call_id) {
let chunk = String::from_utf8_lossy(&ev.chunk).to_string();
match ev.stream {
ExecOutputStream::Stdout => running.stdout.push_str(&chunk),
ExecOutputStream::Stderr => running.stderr.push_str(&chunk),
}
if let Some(idx) = running.history_index {
if idx < self.history_cells.len() {
if let Some(exec) = self.history_cells[idx]
.as_any_mut()
.downcast_mut::<history_cell::ExecCell>()
{
exec.update_stream_preview(&running.stdout, &running.stderr);
}
}
}
self.invalidate_height_cache();
self.autoscroll_if_near_bottom();
self.request_redraw();
}
}
EventMsg::PatchApplyBegin(PatchApplyBeginEvent {
call_id: _,
@@ -11491,7 +11514,7 @@ impl WidgetRef for &ChatWidget<'_> {
.downcast_ref::<crate::history_cell::ExecCell>()
{
match &exec.output {
None => crate::colors::info(), // Running...
None => crate::colors::text(), // Running...
// On successful completion, turn the gutter arrow solid black
Some(o) if o.exit_code == 0 => ratatui::style::Color::Black, // Ran
Some(_) => crate::colors::error(),
@@ -11508,9 +11531,9 @@ impl WidgetRef for &ChatWidget<'_> {
status: crate::history_cell::ExecStatus::Error,
} => crate::colors::error(),
crate::history_cell::HistoryCellType::Exec { .. } => {
crate::colors::info()
crate::colors::text()
}
_ => crate::colors::info(),
_ => crate::colors::text(),
}
}
} else if symbol == "↯" {
+14 -3
View File
@@ -385,6 +385,8 @@ pub(super) fn handle_exec_begin_now(chat: &mut ChatWidget<'_>, ev: ExecCommandBe
parsed: parsed_command.clone(),
history_index: None,
explore_entry: Some((idx, entry_idx)),
stdout: String::new(),
stderr: String::new(),
},
);
chat.invalidate_height_cache();
@@ -414,6 +416,8 @@ pub(super) fn handle_exec_begin_now(chat: &mut ChatWidget<'_>, ev: ExecCommandBe
parsed: parsed_command,
history_index: Some(idx),
explore_entry: None,
stdout: String::new(),
stderr: String::new(),
},
);
if !chat.tools_state.running_web_search.is_empty() {
@@ -451,9 +455,16 @@ pub(super) fn handle_exec_end_now(chat: &mut ChatWidget<'_>, ev: ExecCommandEndE
let ExecCommandEndEvent { call_id, exit_code, duration: _, stdout, stderr } = ev;
let cmd = chat.exec.running_commands.remove(&super::ExecCallId(call_id.clone()));
chat.height_manager.borrow_mut().record_event(HeightEvent::RunEnd);
let (command, parsed, history_index, explore_entry) = cmd
.map(|cmd| (cmd.command, cmd.parsed, cmd.history_index, cmd.explore_entry))
.unwrap_or_else(|| (vec![call_id.clone()], vec![], None, None));
let (command, parsed, history_index, explore_entry) = match cmd {
Some(super::RunningCommand {
command,
parsed,
history_index,
explore_entry,
..
}) => (command, parsed, history_index, explore_entry),
None => (vec![call_id.clone()], vec![], None, None),
};
if let Some((agg_idx, entry_idx)) = explore_entry {
let action = history_cell::action_enum_from_parsed(&parsed);
File diff suppressed because it is too large Load Diff
@@ -2,4 +2,4 @@
source: tui/src/history_cell.rs
expression: rendered
---
• Ran echo ok
• echo ok
@@ -2,7 +2,7 @@
source: tui/src/history_cell.rs
expression: rendered
---
• Ran seq 1 10 1>&2 && false
• seq 1 10 1>&2 && false
└ 1
2
3