diff --git a/crates/chat-cli/src/cli/chat/mod.rs b/crates/chat-cli/src/cli/chat/mod.rs index 099c0c876..ebb1c2aca 100644 --- a/crates/chat-cli/src/cli/chat/mod.rs +++ b/crates/chat-cli/src/cli/chat/mod.rs @@ -2150,8 +2150,11 @@ impl ChatSession { ) .await; - if matches!(chat_state, ChatState::Exit) - || matches!(chat_state, ChatState::HandleResponseStream(_)) + if matches!(chat_state, ChatState::Exit) { + std::process::exit(0); + } + + if matches!(chat_state, ChatState::HandleResponseStream(_)) || matches!(chat_state, ChatState::HandleInput { input: _ }) // TODO(bskiser): this is just a hotfix for handling state changes // from manually running /compact, without impacting behavior of diff --git a/crates/chat-cli/src/cli/chat/prompt.rs b/crates/chat-cli/src/cli/chat/prompt.rs index e58879c93..f2e7afc8f 100644 --- a/crates/chat-cli/src/cli/chat/prompt.rs +++ b/crates/chat-cli/src/cli/chat/prompt.rs @@ -587,10 +587,27 @@ pub fn rl( rl.set_helper(Some(h)); // Load history from CLI bash history file - if let Err(e) = rl.load_history(&rl.helper().unwrap().get_history_path()) { - if !matches!(e, ReadlineError::Io(ref io_err) if io_err.kind() == std::io::ErrorKind::NotFound) { + // Use a separate thread to prevent indefinite blocking on corrupted files + let history_path = rl.helper().unwrap().get_history_path(); + let history_path_clone = history_path.clone(); + + let load_handle = std::thread::spawn(move || { + std::fs::read_to_string(&history_path_clone) + }); + + match load_handle.join() { + Ok(Ok(contents)) => { + for line in contents.lines() { + let _ = rl.add_history_entry(line); + } + } + Ok(Err(e)) if e.kind() != std::io::ErrorKind::NotFound => { eprintln!("Warning: Failed to load history: {}", e); } + Err(_) => { + eprintln!("Warning: History loading failed unexpectedly"); + } + _ => {} // NotFound is expected on first run } // Add custom keybinding for Ctrl+D to open delegate command (configurable)