fix: truncate long lines in streaming tool output to prevent terminal wrapping

When shell commands output very long lines (e.g., JSON content from
tail -c 10000), the lines would wrap in the terminal. The cursor-up
escape code (\x1b[1A) only moves up one visual line, not the entire
wrapped content, causing the display to fill with uncleared text.

This fix truncates lines to 120 characters in update_tool_output_line()
before displaying them, preventing the wrapping issue.
This commit is contained in:
Dhanji R. Prasanna
2026-01-09 13:35:58 +11:00
parent 67be0f20c7
commit 49b27b0cbc

View File

@@ -186,6 +186,9 @@ impl UiWriter for ConsoleUiWriter {
} }
fn update_tool_output_line(&self, line: &str) { fn update_tool_output_line(&self, line: &str) {
// Truncate long lines to prevent terminal wrapping issues
// When lines wrap, the cursor-up escape code only moves up one visual line
const MAX_LINE_WIDTH: usize = 120;
let mut current_line = self.current_output_line.lock().unwrap(); let mut current_line = self.current_output_line.lock().unwrap();
let mut line_printed = self.output_line_printed.lock().unwrap(); let mut line_printed = self.output_line_printed.lock().unwrap();
@@ -195,8 +198,15 @@ impl UiWriter for ConsoleUiWriter {
print!("\x1b[1A\x1b[2K"); print!("\x1b[1A\x1b[2K");
} }
// Print the new line // Truncate line if needed to prevent wrapping
println!("\x1b[2m{}\x1b[0m", line); let display_line = if line.chars().count() > MAX_LINE_WIDTH {
let truncated: String = line.chars().take(MAX_LINE_WIDTH - 3).collect();
format!("{}...", truncated)
} else {
line.to_string()
};
println!("\x1b[2m{}\x1b[0m", display_line);
let _ = io::stdout().flush(); let _ = io::stdout().flush();
// Update state // Update state