diff --git a/codex-rs/tui/src/chatwidget/slash_dispatch.rs b/codex-rs/tui/src/chatwidget/slash_dispatch.rs index 56d9bc42cd..92c06357db 100644 --- a/codex-rs/tui/src/chatwidget/slash_dispatch.rs +++ b/codex-rs/tui/src/chatwidget/slash_dispatch.rs @@ -142,6 +142,7 @@ impl ChatWidget { let mcp_startup_is_only_task = self.mcp_startup_status.is_some() && !self.turn_lifecycle.agent_turn_running && !self.input_queue.user_turn_pending_start + && !self.has_queued_follow_up_messages() && !self.review.is_review_mode; return self.bottom_pane.is_task_running() && !mcp_startup_is_only_task; } diff --git a/codex-rs/tui/src/chatwidget/tests/mcp_startup.rs b/codex-rs/tui/src/chatwidget/tests/mcp_startup.rs index 19bfc85376..9eb4ebca4a 100644 --- a/codex-rs/tui/src/chatwidget/tests/mcp_startup.rs +++ b/codex-rs/tui/src/chatwidget/tests/mcp_startup.rs @@ -280,6 +280,26 @@ async fn bare_review_submission_during_agent_turn_preserves_draft() { assert_eq!(chat.bottom_pane.composer_text(), "/review"); } +#[tokio::test] +async fn queued_prompt_blocks_review_during_mcp_startup() { + let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await; + notify_mcp_status(&mut chat, "alpha", McpServerStartupState::Starting); + chat.queue_user_message("queued prompt".into()); + + chat.bottom_pane + .set_composer_text("/review".to_string(), Vec::new(), Vec::new()); + chat.handle_key_event(KeyEvent::new(KeyCode::Esc, KeyModifiers::NONE)); + chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)); + chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)); + + let error = drain_insert_history(&mut rx) + .into_iter() + .map(|lines| lines_to_single_string(&lines)) + .collect::(); + assert!(error.contains("'/review' is disabled while a task is in progress.")); + assert_eq!(chat.bottom_pane.composer_text(), "/review"); +} + #[tokio::test] async fn mcp_startup_dedupes_same_round_duplicate_failure_warning() { let (mut chat, mut rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;