diff --git a/src-tauri/src/acp/connection.rs b/src-tauri/src/acp/connection.rs index da30f58..1528c6a 100644 --- a/src-tauri/src/acp/connection.rs +++ b/src-tauri/src/acp/connection.rs @@ -1887,6 +1887,15 @@ fn serialize_tool_call_content(content: &[ToolCallContent]) -> Option { } } +/// If the output looks like numbered lines (` 115→content`), strip them +/// and return `{"start_line":N,"content":"..."}` — same as the historical path. +fn structurize_live_output(text: &str) -> String { + if let Some(json) = crate::parsers::strip_numbered_lines(text) { + return json; + } + text.to_string() +} + /// Resolve line numbers for live tool call input. /// /// - For apply_patch with bare `@@`: resolve line numbers in place. @@ -2025,7 +2034,8 @@ fn emit_conversation_update( let content = serialize_tool_call_content(&tc.content); let raw_input = json_value_to_text(&tc.raw_input) .map(|text| resolve_live_tool_input(&text, cwd)); - let raw_output = json_value_to_text(&tc.raw_output); + let raw_output = json_value_to_text(&tc.raw_output) + .map(|text| structurize_live_output(&text)); crate::web::event_bridge::emit_event( app_handle, "acp://event", @@ -2049,7 +2059,8 @@ fn emit_conversation_update( .and_then(serialize_tool_call_content); let raw_input = json_value_to_text(&tcu.fields.raw_input) .map(|text| resolve_live_tool_input(&text, cwd)); - let raw_output = json_value_to_text(&tcu.fields.raw_output); + let raw_output = json_value_to_text(&tcu.fields.raw_output) + .map(|text| structurize_live_output(&text)); crate::web::event_bridge::emit_event( app_handle, "acp://event", diff --git a/src-tauri/src/parsers/mod.rs b/src-tauri/src/parsers/mod.rs index 6b0dac5..a01ac55 100644 --- a/src-tauri/src/parsers/mod.rs +++ b/src-tauri/src/parsers/mod.rs @@ -362,7 +362,7 @@ fn split_line_number(line: &str) -> Option<(u64, &str)> { /// If most lines have a recognized line-number prefix, strip them all /// and return `{"start_line":N,"content":"clean text"}`. -fn strip_numbered_lines(text: &str) -> Option { +pub fn strip_numbered_lines(text: &str) -> Option { let raw_lines: Vec<&str> = text.lines().collect(); if raw_lines.len() < 2 { return None;