This commit is contained in:
jif-oai
2025-12-08 16:41:04 +00:00
parent 65ad87a39a
commit 18909f0aef
2 changed files with 61 additions and 2 deletions

View File

@@ -62,6 +62,53 @@ const UNIFIED_EXEC_ENV: [(&str, &str); 8] = [
("GIT_PAGER", "cat"),
];
fn normalize_unified_exec_text(raw: &str) -> String {
let with_unix_newlines = raw.replace("\r\n", "\n");
let with_unix_newlines = with_unix_newlines.replace('\r', "\n");
strip_ansi_escape_sequences(&with_unix_newlines)
}
fn strip_ansi_escape_sequences(input: &str) -> String {
let mut result = String::with_capacity(input.len());
let mut iter = input.chars().peekable();
while let Some(ch) = iter.next() {
if ch == '\u{1b}' {
match iter.peek().copied() {
Some('[') => {
let _ = iter.next();
for c in iter.by_ref() {
if ('@'..='~').contains(&c) {
break;
}
}
}
Some(']') => {
let _ = iter.next();
while let Some(c) = iter.next() {
if c == '\u{7}' {
break;
}
if c == '\u{1b}'
&& let Some('\\') = iter.peek().copied() {
let _ = iter.next();
break;
}
}
}
Some(_) => {
let _ = iter.next();
}
None => {}
}
} else {
result.push(ch);
}
}
result
}
fn apply_unified_exec_env(mut env: HashMap<String, String>) -> HashMap<String, String> {
for (key, value) in UNIFIED_EXEC_ENV {
env.insert(key.to_string(), value.to_string());
@@ -163,7 +210,8 @@ impl UnifiedExecSessionManager {
.await;
let wall_time = Instant::now().saturating_duration_since(start);
let text = String::from_utf8_lossy(&collected).to_string();
let raw_text = String::from_utf8_lossy(&collected).to_string();
let text = normalize_unified_exec_text(&raw_text);
let output = formatted_truncate_text(&text, TruncationPolicy::Tokens(max_tokens));
let has_exited = session.has_exited();
let exit_code = session.exit_code();
@@ -285,7 +333,8 @@ impl UnifiedExecSessionManager {
.await;
let wall_time = Instant::now().saturating_duration_since(start);
let text = String::from_utf8_lossy(&collected).to_string();
let raw_text = String::from_utf8_lossy(&collected).to_string();
let text = normalize_unified_exec_text(&raw_text);
let output = formatted_truncate_text(&text, TruncationPolicy::Tokens(max_tokens));
let original_token_count = approx_token_count(&text);
let chunk_id = generate_chunk_id();

View File

@@ -2390,6 +2390,15 @@ async fn windows_unified_exec_escape_output_snapshot() -> Result<()> {
let raw_output = parsed.output.as_str();
// assert!(
// raw_output.contains("UEXEC-WINDOWS-ESCAPES"),
// "expected marker string in unified_exec output, got {raw_output:?}"
// );
// assert!(
// !raw_output.contains('\u{1b}'),
// "expected unified_exec output to be stripped of ANSI escape sequences on Windows, got {raw_output:?}"
// );
// Intentionally failing assertion so CI logs show the raw PTY output,
// including any escape sequences produced by ConPTY / PowerShell.
let expected = "UEXEC-WINDOWS-ESCAPES\n";
@@ -2397,6 +2406,7 @@ async fn windows_unified_exec_escape_output_snapshot() -> Result<()> {
raw_output, expected,
"raw unified_exec PTY output on Windows (expected simple marker, got full stream)"
);
assert!(false);
Ok(())
}