From 44ce98cfe5b8e89844a3e6d5d3de6ff4e6369924 Mon Sep 17 00:00:00 2001 From: cpacker Date: Mon, 29 Dec 2025 01:24:26 -0800 Subject: [PATCH] fix: prevent rendering artifacts when approval dialogs close MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clear screen and force Static component remount when approval state is cleared. This fixes "streaking" where fragments of approval dialogs would appear mixed with transcript content. The issue was caused by Ink's line count tracking getting confused when large UI components (approval dialogs, plan preview) disappear abruptly. Applied fix in: - sendAllResults (normal approval flow) - sendAllResults early return (cancelled flow) - handleInterrupt (Ctrl+C during approvals) - handleCancelApprovals (cancel all approvals) 🤖 Generated with [Letta Code](https://letta.com) Co-Authored-By: Letta --- src/cli/App.tsx | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/cli/App.tsx b/src/cli/App.tsx index 0250ce0..2d04341 100644 --- a/src/cli/App.tsx +++ b/src/cli/App.tsx @@ -1833,6 +1833,12 @@ export default function App({ setAutoHandledResults([]); setAutoDeniedApprovals([]); + // Force clean re-render to avoid streaking artifacts + if (process.stdout.isTTY) { + process.stdout.write(CLEAR_SCREEN_AND_HOME); + } + setStaticRenderEpoch((e) => e + 1); + // Send cancel request to backend asynchronously (fire-and-forget) // Don't wait for it or show errors since user already got feedback getClient() @@ -4237,6 +4243,11 @@ DO NOT respond to these messages or otherwise consider them in your response unl setApprovalResults([]); setAutoHandledResults([]); setAutoDeniedApprovals([]); + // Force clean re-render to avoid streaking artifacts + if (process.stdout.isTTY) { + process.stdout.write(CLEAR_SCREEN_AND_HOME); + } + setStaticRenderEpoch((e) => e + 1); return; } @@ -4253,6 +4264,13 @@ DO NOT respond to these messages or otherwise consider them in your response unl setAutoHandledResults([]); setAutoDeniedApprovals([]); + // Force clean re-render to avoid streaking artifacts + // The large approval dialog disappearing causes line count mismatch in Ink + if (process.stdout.isTTY) { + process.stdout.write(CLEAR_SCREEN_AND_HOME); + } + setStaticRenderEpoch((e) => e + 1); + // Show "thinking" state and lock input while executing approved tools client-side setStreaming(true); // Ensure interrupted flag is cleared for this execution @@ -4554,6 +4572,12 @@ DO NOT respond to these messages or otherwise consider them in your response unl setApprovalResults([]); setAutoHandledResults([]); setAutoDeniedApprovals([]); + + // Force clean re-render to avoid streaking artifacts + if (process.stdout.isTTY) { + process.stdout.write(CLEAR_SCREEN_AND_HOME); + } + setStaticRenderEpoch((e) => e + 1); }, [pendingApprovals, refreshDerived]); const handleModelSelect = useCallback(