From 704d21992504c64a2482ba24e073b6f74f3577bb Mon Sep 17 00:00:00 2001 From: Ahmed Ibrahim Date: Tue, 27 Jan 2026 12:15:04 -0800 Subject: [PATCH] TUI: mark running for task-spawning ops --- codex-rs/tui/src/chatwidget.rs | 11 +++++++++-- codex-rs/tui/src/chatwidget/tests.rs | 20 ++++++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index bd1014b2f4..f4ef5a9d3f 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -5187,8 +5187,15 @@ impl ChatWidget { pub(crate) fn submit_op(&mut self, op: Op) { // Record outbound operation for session replay fidelity. crate::session_log::log_outbound_op(&op); - if matches!(&op, Op::Review { .. }) && !self.bottom_pane.is_task_running() { - self.bottom_pane.set_task_running(true); + let spawns_task = matches!( + &op, + Op::Review { .. } | Op::Undo | Op::Compact | Op::RunUserShellCommand { .. } + ); + if spawns_task && !self.bottom_pane.is_task_running() { + self.agent_turn_running = true; + self.update_task_running_state(); + self.bottom_pane.set_interrupt_hint_visible(true); + self.request_redraw(); } if let Err(e) = self.codex_op_tx.send(op) { tracing::error!("failed to submit op: {e}"); diff --git a/codex-rs/tui/src/chatwidget/tests.rs b/codex-rs/tui/src/chatwidget/tests.rs index 76d5600010..74df0c0c10 100644 --- a/codex-rs/tui/src/chatwidget/tests.rs +++ b/codex-rs/tui/src/chatwidget/tests.rs @@ -1694,6 +1694,26 @@ async fn streaming_final_answer_keeps_task_running_state() { assert!(!chat.bottom_pane.quit_shortcut_hint_visible()); } +#[tokio::test] +async fn task_spawning_ops_mark_running_optimistically() { + let (mut chat, _rx, mut op_rx) = make_chatwidget_manual(None).await; + + assert!(!chat.bottom_pane.is_task_running()); + + chat.submit_op(Op::Undo); + let saw_undo = loop { + match op_rx.try_recv() { + Ok(Op::Undo) => break true, + Ok(_) => continue, + Err(TryRecvError::Empty) => break false, + Err(TryRecvError::Disconnected) => panic!("expected op but channel closed"), + } + }; + assert!(saw_undo, "expected Op::Undo to be forwarded"); + + assert!(chat.bottom_pane.is_task_running()); +} + #[tokio::test] async fn ctrl_c_shutdown_works_with_caps_lock() { let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(None).await;