From 813466feb10a9706d37c85c0975c152cc829c898 Mon Sep 17 00:00:00 2001 From: Sri Pasumarthi Date: Tue, 17 Mar 2026 17:54:55 -0700 Subject: [PATCH] fix: prevent duplicate tool confirmations and fragmented UI boxes - Process tool validations sequentially rather than concurrently in the scheduler. This resolves a race condition where parallel tool calls evaluated policy simultaneously, causing subsequent tools to ignore global `AUTO_EDIT` mode switches triggered by earlier confirmations. - Conditionally render result display containers in `ToolMessage` and `ShellToolMessage`. Empty padded boxes are now hidden when a tool is pending or executing with no output, preventing overlapping disjointed borders from fragmenting the interactive queue. --- .../ConfigInitDisplay.test.tsx.snap | 12 --- .../components/messages/ShellToolMessage.tsx | 64 +++++++------- .../ui/components/messages/ToolMessage.tsx | 87 ++++++++++--------- packages/core/src/scheduler/scheduler.ts | 6 +- 4 files changed, 82 insertions(+), 87 deletions(-) diff --git a/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap index 28929deee5..8d03baaa49 100644 --- a/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/ConfigInitDisplay.test.tsx.snap @@ -18,20 +18,8 @@ Spinner Connecting to MCP servers... (0/5) - Waiting for: s1, s2, s3, +2 more " `; -exports[`ConfigInitDisplay > truncates list of waiting servers if too many 2`] = ` -" -Spinner Connecting to MCP servers... (0/5) - Waiting for: s1, s2, s3, +2 more -" -`; - exports[`ConfigInitDisplay > updates message on McpClientUpdate event 1`] = ` " Spinner Connecting to MCP servers... (1/2) - Waiting for: server2 " `; - -exports[`ConfigInitDisplay > updates message on McpClientUpdate event 2`] = ` -" -Spinner Connecting to MCP servers... (1/2) - Waiting for: server2 -" -`; diff --git a/packages/cli/src/ui/components/messages/ShellToolMessage.tsx b/packages/cli/src/ui/components/messages/ShellToolMessage.tsx index f34aa08bfb..5287c93b1b 100644 --- a/packages/cli/src/ui/components/messages/ShellToolMessage.tsx +++ b/packages/cli/src/ui/components/messages/ShellToolMessage.tsx @@ -64,12 +64,10 @@ export const ShellToolMessage: React.FC = ({ isFirst, borderColor, - borderDimColor, - isExpandable, - originalRequestName, + progress, }) => { const { activePtyId: activeShellPtyId, @@ -196,35 +194,39 @@ export const ShellToolMessage: React.FC = ({ {emphasis === 'high' && } - - - {isThisShellFocused && config && ( - + - )} - + {isThisShellFocused && config && ( + + )} + + )} ); }; diff --git a/packages/cli/src/ui/components/messages/ToolMessage.tsx b/packages/cli/src/ui/components/messages/ToolMessage.tsx index 5747f7677f..18946563b6 100644 --- a/packages/cli/src/ui/components/messages/ToolMessage.tsx +++ b/packages/cli/src/ui/components/messages/ToolMessage.tsx @@ -109,48 +109,53 @@ export const ToolMessage: React.FC = ({ /> {emphasis === 'high' && } - - {status === CoreToolCallStatus.Executing && progress !== undefined && ( - + {status === CoreToolCallStatus.Executing && + progress !== undefined && ( + + )} + - )} - - {isThisShellFocused && config && ( - - - - )} - + {isThisShellFocused && config && ( + + + + )} + + )} ); }; diff --git a/packages/core/src/scheduler/scheduler.ts b/packages/core/src/scheduler/scheduler.ts index 4a92617e6d..c1f021d698 100644 --- a/packages/core/src/scheduler/scheduler.ts +++ b/packages/core/src/scheduler/scheduler.ts @@ -455,9 +455,9 @@ export class Scheduler { c.status === CoreToolCallStatus.Validating, ); if (validatingCalls.length > 0) { - await Promise.all( - validatingCalls.map((c) => this._processValidatingCall(c, signal)), - ); + for (const c of validatingCalls) { + await this._processValidatingCall(c, signal); + } } // 2. Execute scheduled calls