From adbaeca61d8eb0cd683302eda3bc51362953f47b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugues=20Clou=C3=A2tre?= Date: Fri, 12 Dec 2025 17:21:38 -0500 Subject: [PATCH] fix: display shell output as static text instead of spinner MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Shell command output (like device codes from 'gh auth login') was being displayed as spinner messages, causing critical information to be hidden. This fix extracts the notification type and prints shell_output directly as static text, following the same pattern as task_execution notifications. The conditional logic was simplified to avoid duplicate println calls between interactive and non-interactive modes. Partial fix for #3196 Signed-off-by: Hugues Clouâtre --- crates/goose-cli/src/session/mod.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/crates/goose-cli/src/session/mod.rs b/crates/goose-cli/src/session/mod.rs index 6c206a9a74b4..5c9ea253b12f 100644 --- a/crates/goose-cli/src/session/mod.rs +++ b/crates/goose-cli/src/session/mod.rs @@ -1085,8 +1085,12 @@ impl CliSession { }; (formatted, subagent_id.map(str::to_string), notification_type.map(str::to_string)) } else if let Some(Value::String(output)) = o.get("output") { - // Fallback for other MCP notification types - (output.to_owned(), None, None) + // Extract type if present (e.g., "shell_output") + let notification_type = o.get("type") + .and_then(|v| v.as_str()) + .map(str::to_string); + + (output.to_owned(), None, notification_type) } else if let Some(result) = format_task_execution_notification(data) { result } else { @@ -1121,6 +1125,14 @@ impl CliSession { print!("{}", formatted_message); std::io::stdout().flush().unwrap(); } + } else if notification_type == "shell_output" { + // Hide spinner, print shell output, spinner will resume + if interactive { + let _ = progress_bars.hide(); + } + if !is_json_mode { + println!("{}", formatted_message); + } } } else if output::is_showing_thinking() {