From 78a40eaf7d13cce204fe54aaf7083ec1f9753fc9 Mon Sep 17 00:00:00 2001 From: LaZzyMan Date: Thu, 9 Jul 2026 16:22:46 +0800 Subject: [PATCH] fix(cli): use minLen=1 for partial marker detection in paste-accumulating path In paste-accumulating mode, a lone ESC at a chunk boundary is the start of paste-end marker, not a user keypress. Use minLen=1 so the ESC byte is held back for reassembly with the next chunk. --- packages/cli/src/ui/contexts/KeypressContext.tsx | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/packages/cli/src/ui/contexts/KeypressContext.tsx b/packages/cli/src/ui/contexts/KeypressContext.tsx index ba62caf3d8..988503a8d0 100644 --- a/packages/cli/src/ui/contexts/KeypressContext.tsx +++ b/packages/cli/src/ui/contexts/KeypressContext.tsx @@ -1256,13 +1256,16 @@ export function KeypressProvider({ const pasteModePrefixBuf = Buffer.from(PASTE_MODE_PREFIX); const pasteModeSuffixBuf = Buffer.from(PASTE_MODE_SUFFIX); - function partialMarkerTailLength(chunk: Buffer, marker: Buffer): number { - // Start from min(chunk.length, marker.length - 1) down to 2. - // We skip length 1 because a lone ESC (0x1b) is the start of ALL - // ANSI escape sequences, not just paste markers — holding it back - // would swallow ESC keypresses and break readline's CSI parsing. + function partialMarkerTailLength( + chunk: Buffer, + marker: Buffer, + minLen: number = 2, + ): number { + // Default minLen=2 skips lone ESC (0x1b) which starts ALL ANSI + // sequences. In the paste-accumulating path, use minLen=1 since + // ESC there is most likely the start of paste-end, not a keypress. const maxCheck = Math.min(chunk.length, marker.length - 1); - for (let len = maxCheck; len >= 2; len--) { + for (let len = maxCheck; len >= minLen; len--) { const tail = chunk.subarray(chunk.length - len); if (marker.subarray(0, len).equals(tail)) { return len; @@ -1368,6 +1371,7 @@ export function KeypressProvider({ const tailLen = partialMarkerTailLength( remaining, pasteModeSuffixBuf, + 1, ); const contentEnd = remaining.length - tailLen; if (contentEnd > 0) {