From 78fa047cf1318bb3d4ec3f5182038acfa0f9c9fa Mon Sep 17 00:00:00 2001 From: movix chen Date: Sun, 9 Nov 2025 06:32:33 +0000 Subject: [PATCH] fix: prevent ANSI escape sequence corruption in clear command Race condition between display rendering and user input caused corrupted terminal output where ANSI escape sequences appeared in the prompt. - Add bandaid synchronization fix using MetaEvent after execute! macro - Wait for UI acknowledgment before reading user input via conduit system --- crates/chat-cli/src/cli/chat/cli/clear.rs | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/crates/chat-cli/src/cli/chat/cli/clear.rs b/crates/chat-cli/src/cli/chat/cli/clear.rs index b706bbbdb8..7ca525d8ea 100644 --- a/crates/chat-cli/src/cli/chat/cli/clear.rs +++ b/crates/chat-cli/src/cli/chat/cli/clear.rs @@ -1,3 +1,4 @@ +use chat_cli_ui::protocol::Event; use clap::Args; use crossterm::style::{ self, @@ -7,6 +8,7 @@ use crossterm::{ cursor, execute, }; +use tracing::error; use crate::cli::chat::{ ChatError, @@ -41,6 +43,26 @@ impl ClearArgs { cursor::Show, )?; + // BANDAID FIX: Prevent race condition between display and user input + // Without this synchronization, user input can start before the confirmation prompt + // is fully rendered, causing corrupted ANSI escape sequences and malformed output. + // As a bandaid fix (to hold us until we move to the new event loop where everything is in + // their rightful place), we signal to the UI layer that display is complete and wait for + // acknowledgment through the conduit system before reading user input. + session + .stderr + .send(Event::MetaEvent(chat_cli_ui::protocol::MetaEvent { + meta_type: "timing".to_string(), + payload: serde_json::Value::String("prompt_user".to_string()), + })) + .map_err(|_e| ChatError::Custom("Error sending timing event for prompting user".into()))?; + + // Wait for UI acknowledgment with timeout to ensure display is flushed before user input + if let Err(e) = session.prompt_ack_rx.recv_timeout(std::time::Duration::from_secs(10)) { + error!("Failed to receive user prompting acknowledgement from UI: {:?}", e); + } + + // Now safe to read user input - display is guaranteed to be complete // Setting `exit_on_single_ctrl_c` for better ux: exit the confirmation dialog rather than the CLI let user_input = match session.read_user_input("> ".yellow().to_string().as_str(), true) { Some(input) => input,