From 9c02e7f4eb992b86d797b3056c3f35cbf07659d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E5=91=98=E9=98=BF=E6=B1=9F=28Relakkes?= =?UTF-8?q?=29?= Date: Tue, 23 Jun 2026 17:11:09 +0800 Subject: [PATCH] fix(desktop): hide empty rejected plan previews MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ExitPlanMode can be interrupted while a real plan approval preview is still rendered elsewhere. In that path the tool result had no plan input and displayed an extra empty plan card, which made plan mode look duplicated. Render the plan preview in rejected tool cards only when real plan, file path, or permission data exists. Tested: cd desktop && bun run test PlanModePermissionDialog.test.tsx Tested: bun run check:desktop Tested: Computer Use dev Electron smoke via desktop/scripts/electron-dev.ts; original #869 repro no longer showed the empty '暂无计划内容' card after HMR. Not-tested: release build post-install retest; GitHub issue remains open until release. Confidence: high Scope-risk: narrow --- .../chat/PlanModePermissionDialog.test.tsx | 18 ++++++++++++++ desktop/src/components/chat/ToolCallBlock.tsx | 24 ++++++++++++------- 2 files changed, 34 insertions(+), 8 deletions(-) diff --git a/desktop/src/components/chat/PlanModePermissionDialog.test.tsx b/desktop/src/components/chat/PlanModePermissionDialog.test.tsx index 1ea8781d..77ec9cd2 100644 --- a/desktop/src/components/chat/PlanModePermissionDialog.test.tsx +++ b/desktop/src/components/chat/PlanModePermissionDialog.test.tsx @@ -189,6 +189,24 @@ describe('plan mode permission UI', () => { expect(container.textContent).not.toContain('Tool Output') }) + it('does not render an empty plan preview for interrupted ExitPlanMode results', () => { + const { container } = render( + , + ) + + expect(container.textContent).toContain('Plan rejected') + expect(container.textContent).toContain('Tool permission request failed: AbortError') + expect(container.textContent).not.toContain("Claude's plan") + expect(container.textContent).not.toContain('No plan content available.') + }) + it('renders EnterPlanMode as a compact status instead of raw model instructions', () => { const { container } = render( 0, + ) + const showPlanPreview = hasPlanPreview || !result?.isError const title = result?.isError ? t('permission.planRejected') : result @@ -287,14 +293,16 @@ function PlanToolCallBlock({ {expanded ? (
- + {showPlanPreview ? ( + + ) : null} {result?.isError && hasRawResult ? ( renderResultOutput(result, extractTextContent(result.content) ?? '', t) ) : null}