fix: ensure status indicator present earlier in exec path (#10700)

ensure status indicator present in all classifications of exec tool.
fixes indicator disappearing after preambles, will look into using
`phase` to avoid this class of error in a few hours.

commands parsed as unknown faced this issue

tested locally, added test for specific failure flow
This commit is contained in:
sayan-oai 2026-02-04 19:56:50 -08:00 committed by GitHub
parent d876f3b94f
commit 4ed8d74aab
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 56 additions and 0 deletions

View file

@ -1528,6 +1528,8 @@ impl ChatWidget {
fn on_exec_command_begin(&mut self, ev: ExecCommandBeginEvent) {
self.flush_answer_stream_with_separator();
if is_unified_exec_source(ev.source) {
// Unified exec may be parsed as Unknown; keep the working indicator visible regardless.
self.bottom_pane.ensure_status_indicator();
self.track_unified_exec_process_begin(&ev);
if !is_standard_tool_call(&ev.parsed_cmd) {
return;

View file

@ -0,0 +1,12 @@
---
source: tui/src/chatwidget/tests.rs
expression: terminal.backend()
---
" "
"• Working (0s • esc to interrupt) "
" 1 background terminal running · /ps to view "
" "
" "
" Ask Codex to do anything "
" "
" ? for shortcuts 100% context left "

View file

@ -1871,6 +1871,48 @@ async fn preamble_keeps_working_status_snapshot() {
assert_snapshot!("preamble_keeps_working_status", terminal.backend());
}
#[tokio::test]
async fn unified_exec_begin_restores_status_indicator_after_preamble() {
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(None).await;
chat.on_task_started();
assert_eq!(chat.bottom_pane.status_indicator_visible(), true);
// Simulate a hidden status row during an active turn.
chat.bottom_pane.hide_status_indicator();
assert_eq!(chat.bottom_pane.status_indicator_visible(), false);
assert_eq!(chat.bottom_pane.is_task_running(), true);
begin_unified_exec_startup(&mut chat, "call-1", "proc-1", "sleep 2");
assert_eq!(chat.bottom_pane.status_indicator_visible(), true);
}
#[tokio::test]
async fn unified_exec_begin_restores_working_status_snapshot() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;
chat.on_task_started();
chat.on_agent_message_delta("Preamble line\n".to_string());
chat.on_commit_tick();
drain_insert_history(&mut rx);
begin_unified_exec_startup(&mut chat, "call-1", "proc-1", "sleep 2");
let width: u16 = 80;
let height = chat.desired_height(width);
let mut terminal = ratatui::Terminal::new(ratatui::backend::TestBackend::new(width, height))
.expect("create terminal");
terminal.set_viewport_area(Rect::new(0, 0, width, height));
terminal
.draw(|f| chat.render(f.area(), f.buffer_mut()))
.expect("draw chatwidget");
assert_snapshot!(
"unified_exec_begin_restores_working_status",
terminal.backend()
);
}
#[tokio::test]
async fn ctrl_c_shutdown_works_with_caps_lock() {
let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;