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.
This commit is contained in:
LaZzyMan 2026-07-09 16:22:46 +08:00
parent 257d83b94b
commit 78a40eaf7d

View file

@ -1256,13 +1256,16 @@ export function KeypressProvider({
const pasteModePrefixBuf = Buffer.from(PASTE_MODE_PREFIX); const pasteModePrefixBuf = Buffer.from(PASTE_MODE_PREFIX);
const pasteModeSuffixBuf = Buffer.from(PASTE_MODE_SUFFIX); const pasteModeSuffixBuf = Buffer.from(PASTE_MODE_SUFFIX);
function partialMarkerTailLength(chunk: Buffer, marker: Buffer): number { function partialMarkerTailLength(
// Start from min(chunk.length, marker.length - 1) down to 2. chunk: Buffer,
// We skip length 1 because a lone ESC (0x1b) is the start of ALL marker: Buffer,
// ANSI escape sequences, not just paste markers — holding it back minLen: number = 2,
// would swallow ESC keypresses and break readline's CSI parsing. ): 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); 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); const tail = chunk.subarray(chunk.length - len);
if (marker.subarray(0, len).equals(tail)) { if (marker.subarray(0, len).equals(tail)) {
return len; return len;
@ -1368,6 +1371,7 @@ export function KeypressProvider({
const tailLen = partialMarkerTailLength( const tailLen = partialMarkerTailLength(
remaining, remaining,
pasteModeSuffixBuf, pasteModeSuffixBuf,
1,
); );
const contentEnd = remaining.length - tailLen; const contentEnd = remaining.length - tailLen;
if (contentEnd > 0) { if (contentEnd > 0) {