From 33f4b4d299e9aef992bd39254c6203c628569ae1 Mon Sep 17 00:00:00 2001 From: jnjpng Date: Mon, 23 Feb 2026 11:06:18 -0800 Subject: [PATCH] fix: prevent last-char clipping on deferred-wrap terminals (#1079) Co-authored-by: Letta --- vendor/ink/build/log-update.js | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/vendor/ink/build/log-update.js b/vendor/ink/build/log-update.js index 78d9ab5..b7e271b 100644 --- a/vendor/ink/build/log-update.js +++ b/vendor/ink/build/log-update.js @@ -1,5 +1,6 @@ import ansiEscapes from 'ansi-escapes'; import cliCursor from 'cli-cursor'; +import stringWidth from 'string-width'; const create = (stream, { showCursor = false } = {}) => { let previousLineCount = 0; @@ -7,8 +8,17 @@ const create = (stream, { showCursor = false } = {}) => { let hasHiddenCursor = false; const renderWithClearedLineEnds = (output) => { + // On some terminals, writing to the last column leaves the cursor in a + // deferred-wrap state where CSI K (Erase in Line) erases the character + // at the final column instead of being a no-op. Skip the erase for + // lines that already fill the terminal width — there is nothing beyond + // them to clean up. + const cols = stream.columns || 80; const lines = output.split('\n'); - return lines.map((line) => line + ansiEscapes.eraseEndLine).join('\n'); + return lines.map((line) => { + if (stringWidth(line) >= cols) return line; + return line + ansiEscapes.eraseEndLine; + }).join('\n'); }; const render = (str) => { @@ -60,4 +70,3 @@ const create = (stream, { showCursor = false } = {}) => { const logUpdate = { create }; export default logUpdate; -