From c6c1422a193e3c295d9db6f5b53f9cf53c09b4cd Mon Sep 17 00:00:00 2001 From: Armando Fernandez Date: Wed, 15 Jul 2026 19:07:53 -0700 Subject: [PATCH] Fix approval notification toast: placement, coverage, and wording MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The cross-agent "Approval required" toast (shown when an agent you're not looking at needs approval) was unreliable and unclear. Three fixes: - Placement: the toast spanned only the rail + the collapsible Snapshots column, so it was clipped to the rail's edge unless the Snapshots panel happened to be open (making it look attached to Snapshots). It now spans the full window and anchors to the true top-right, visible on every screen. - Coverage: an approval in the SELECTED agent while you were on Settings/MCP/ Appearance raised no toast (the toast only targeted non-selected tabs) and the chat — and the approval — is collapsed on those screens, so you saw nothing. The toast now fires for any approval you can't currently see, and page changes re-evaluate it. - Wording: the toast echoed the modal's question ("Apply these changes?", "What would you like to do?"). It now shows a specific, third-person summary of what's waiting — "Wants to edit Program.cs", "Wants to run a proposed plan", "Wants to run: ", "Wants to delete ", "Wants to run tool " — via a new ApprovalRequest.ToastSummary. Covers diff, command, delete, MCP, and plan approvals. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/MandoCode.Desktop/Controls/ChatTabView.xaml.cs | 11 ++++++++--- src/MandoCode.Desktop/MainWindow.xaml | 5 ++++- src/MandoCode.Desktop/MainWindow.xaml.cs | 10 +++++++++- src/MandoCode.Desktop/Services/ApprovalModels.cs | 5 +++++ .../Services/WinUiApprovalService.cs | 6 ++++++ src/MandoCode.Desktop/ViewModels/ChatController.cs | 1 + 6 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/MandoCode.Desktop/Controls/ChatTabView.xaml.cs b/src/MandoCode.Desktop/Controls/ChatTabView.xaml.cs index 42dc7f3..0a5f9ca 100644 --- a/src/MandoCode.Desktop/Controls/ChatTabView.xaml.cs +++ b/src/MandoCode.Desktop/Controls/ChatTabView.xaml.cs @@ -63,9 +63,10 @@ private enum SuggestMode { None, Command, File } public bool IsApprovalOpen => ApprovalOverlay.Visibility == Visibility.Visible || PlanApprovalBar.Visibility == Visibility.Visible; - /// The pending approval's headline — MainWindow shows it in the cross-tab toast. - public string ApprovalHeadline => PlanApprovalBar.Visibility == Visibility.Visible - ? PlanApprovalTitle.Text : ApprovalTitle.Text; + /// The pending approval's toast summary — what's waiting (e.g. "Wants to edit + /// Program.cs"), set when the approval is shown. MainWindow shows it in the cross-tab toast. + public string ApprovalHeadline => _approvalSummary; + private string _approvalSummary = ""; /// Set by MainWindow when this tab is selected. Only a background tab badges. public bool IsSelected { get; set; } @@ -878,6 +879,10 @@ public Task ShowApprovalAsync(ApprovalRequest request, CancellationToken OnUi(() => { + // What the cross-tab toast will say — a specific "what's waiting" line, not the modal's + // question. Set for both the bottom-bar and modal paths. + _approvalSummary = string.IsNullOrEmpty(request.ToastSummary) ? request.Title : request.ToastSummary; + // Plan approvals render as a non-covering bottom bar so the plan card stays readable. if (request.BottomBar) { diff --git a/src/MandoCode.Desktop/MainWindow.xaml b/src/MandoCode.Desktop/MainWindow.xaml index 81b3f42..46a91b5 100644 --- a/src/MandoCode.Desktop/MainWindow.xaml +++ b/src/MandoCode.Desktop/MainWindow.xaml @@ -561,7 +561,10 @@ - + Render as a non-covering bottom bar rather than the centered modal. Used for plan /// approval so the plan card stays readable in the transcript while the user decides. public bool BottomBar { get; init; } + + /// Short, specific line for the cross-agent "Approval required" toast — describes WHAT + /// is waiting (e.g. "Wants to edit Program.cs"), not the modal's question. Falls back to + /// when unset. + public string? ToastSummary { get; init; } } /// diff --git a/src/MandoCode.Desktop/Services/WinUiApprovalService.cs b/src/MandoCode.Desktop/Services/WinUiApprovalService.cs index 016f923..4d69eab 100644 --- a/src/MandoCode.Desktop/Services/WinUiApprovalService.cs +++ b/src/MandoCode.Desktop/Services/WinUiApprovalService.cs @@ -99,6 +99,7 @@ public async Task HandleWriteApprovalAsync(string relativePa Subtitle = relativePath, DiffLines = displayLines, DiffSummary = summary, + ToastSummary = isNewFile ? $"Wants to create {fileName}" : $"Wants to edit {fileName}", Options = options }; @@ -176,6 +177,7 @@ public async Task HandleCommandApprovalAsync(string command) { Title = "Run this command?", CommandText = command, + ToastSummary = $"Wants to run: {(command.Length > 48 ? command[..48] + "…" : command)}", Options = options }; @@ -276,6 +278,9 @@ public async Task HandleDeleteApprovalAsync(string relativeP Subtitle = relativePath, Detail = warning, DiffLines = displayLines, + ToastSummary = isFolder + ? $"Wants to delete folder {Path.GetFileName(relativePath)}/" + : $"Wants to delete {Path.GetFileName(relativePath)}", Options = options }; @@ -345,6 +350,7 @@ public async Task HandleMcpApprovalAsync(string serverName, { Title = $"Allow MCP tool \"{toolName}\" from \"{serverName}\"?", Detail = description, + ToastSummary = $"Wants to run tool \"{toolName}\"", Options = options }; diff --git a/src/MandoCode.Desktop/ViewModels/ChatController.cs b/src/MandoCode.Desktop/ViewModels/ChatController.cs index 1c6f343..9a5d3c0 100644 --- a/src/MandoCode.Desktop/ViewModels/ChatController.cs +++ b/src/MandoCode.Desktop/ViewModels/ChatController.cs @@ -672,6 +672,7 @@ private async Task HandleProposedPlanAsync(TaskPlan plan, CancellationTo Title = "The assistant proposes this plan. What would you like to do?", // Bottom bar, not the centered modal — the plan card above stays readable. BottomBar = true, + ToastSummary = "Wants to run a proposed plan", Options = new[] { new ApprovalOption(ExecutePlanLabel, ApprovalOptionKind.Proceed),