fix: prevent rendering artifacts when approval dialogs close

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 <noreply@letta.com>
This commit is contained in:
cpacker
2025-12-29 01:24:26 -08:00
parent a5b0c9f1c9
commit 44ce98cfe5

View File

@@ -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(