diff --git a/codex-rs/core/src/unified_exec/session_manager.rs b/codex-rs/core/src/unified_exec/session_manager.rs index 7efa3a90b5..7dbdd14326 100644 --- a/codex-rs/core/src/unified_exec/session_manager.rs +++ b/codex-rs/core/src/unified_exec/session_manager.rs @@ -62,16 +62,57 @@ const UNIFIED_EXEC_ENV: [(&str, &str); 8] = [ ("GIT_PAGER", "cat"), ]; +fn strip_ansi_escape_sequences(raw: &str) -> String { + let mut result = String::with_capacity(raw.len()); + let mut chars = raw.chars().peekable(); + + while let Some(ch) = chars.next() { + if ch == '\u{1b}' { + match chars.peek() { + Some('[') => { + chars.next(); + for c in chars.by_ref() { + if ('@'..='~').contains(&c) { + break; + } + } + } + Some(']') => { + chars.next(); + let mut prev = '\0'; + for c in chars.by_ref() { + if c == '\u{7}' { + break; + } + if prev == '\u{1b}' && c == '\\' { + break; + } + prev = c; + } + } + Some(_) => { + let _ = chars.next(); + } + None => {} + } + continue; + } + + result.push(ch); + } + + result +} + fn normalize_unified_exec_text(raw: &str) -> String { if cfg!(target_os = "windows") { - let rows: u16 = 40; - let cols: u16 = 120; - let mut parser = vt100::Parser::new(rows, cols, 0); + let mut parser = vt100::Parser::new(40, 120, 1_024); parser.process(raw.as_bytes()); - parser.screen().contents() - } else { - raw.to_string() + parser.screen_mut().set_scrollback(usize::MAX); + return parser.screen().contents(); } + + raw.to_string() } fn apply_unified_exec_env(mut env: HashMap) -> HashMap {