From da3a0efeefacabdc335f80c414c8a268ffc52329 Mon Sep 17 00:00:00 2001 From: Hunter Bown Date: Wed, 27 May 2026 00:05:02 -0500 Subject: [PATCH] fix(tui): clear stale tool failures from sidebar (#1884) Deduplicate failures per tool name, clear stale failures when the same tool succeeds, and cap visible failures at 2 so old failures don't crowd the sidebar after the task moves on. --- crates/tui/src/tui/sidebar.rs | 44 ++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/crates/tui/src/tui/sidebar.rs b/crates/tui/src/tui/sidebar.rs index 2ebd58dd..c28c5a83 100644 --- a/crates/tui/src/tui/sidebar.rs +++ b/crates/tui/src/tui/sidebar.rs @@ -1155,9 +1155,21 @@ fn editorial_tool_rows(rows: Vec, limit: usize) -> Vec = Vec::new(); let mut shell_wait_groups: Vec<(usize, SidebarToolRow, usize, String)> = Vec::new(); let mut seen_success: Vec = Vec::new(); + let mut seen_tool_names_succeeded: Vec = Vec::new(); + let mut seen_failures: Vec = Vec::new(); + let mut visible_failure_count: usize = 0; + const MAX_VISIBLE_FAILURES: usize = 2; for (order, mut row) in rows.into_iter().enumerate() { if row.status == ToolStatus::Failed { + // Deduplicate failures for the same tool name: keep only the most + // recent failure per tool. Fixes #1884 — stale failures from + // tools that have since succeeded no longer crowd the sidebar. + let fail_key = row.name.trim().to_ascii_lowercase(); + if seen_failures.contains(&fail_key) { + continue; + } + seen_failures.push(fail_key); row.summary = failure_summary_with_hint(&row.summary); } @@ -1213,10 +1225,40 @@ fn editorial_tool_rows(rows: Vec, limit: usize) -> Vec= MAX_VISIBLE_FAILURES { + visible_failure_count += 1; + 3 + } else { + visible_failure_count += 1; + 0 + } + } else { + tool_row_rank(&row) + }; + candidates.push(Candidate { - rank: tool_row_rank(&row), + rank, order, row, });