From 16882cfded90b8c41ff18000c56a84d7f17628b7 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Sat, 30 May 2026 00:33:14 -0700 Subject: [PATCH] refactor(tui): simplify base64 clipboard write to a stdin flag The per-entry psScript callback was identical for every PowerShell entry, so the function-valued union member added structure without behavior. Collapse WriteCmd to a plain stdin boolean and apply the one shared base64 script in the write loop. Document the CP936 root cause inline. Co-authored-by: BROCCOLO1D <279959838+BROCCOLO1D@users.noreply.github.com> --- ui-tui/src/lib/clipboard.ts | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/ui-tui/src/lib/clipboard.ts b/ui-tui/src/lib/clipboard.ts index 93472de7d5d..4a5387ae2d2 100644 --- a/ui-tui/src/lib/clipboard.ts +++ b/ui-tui/src/lib/clipboard.ts @@ -91,10 +91,13 @@ export async function readClipboardText( return null } -type WriteCmd = { args: readonly string[]; cmd: string } & ( - | { stdin: true } - | { stdin: false; psScript: (b64: string) => string } -) +// PowerShell on Windows/WSL decodes piped stdin with the system ANSI code +// page (e.g. CP936), not UTF-8, so $input-based writes mangle CJK/emoji. We +// instead base64-encode the UTF-8 bytes and pass them as a -Command argument, +// decoding with UTF8.GetString — this removes the stdin-encoding variable +// entirely (also immune to BOM injection on redirect). PowerShell entries set +// stdin=false; every other backend reads UTF-8 stdin natively. +type WriteCmd = { args: readonly string[]; cmd: string; stdin: boolean } function _powershellWriteScript(b64: string): string { return `Set-Clipboard -Value ([System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String('${b64}')))` @@ -109,18 +112,13 @@ function writeClipboardCommands( } if (platform === 'win32') { - return [{ cmd: 'powershell', args: ['-NoProfile', '-NonInteractive'], stdin: false, psScript: _powershellWriteScript }] + return [{ cmd: 'powershell', args: ['-NoProfile', '-NonInteractive'], stdin: false }] } const attempts: WriteCmd[] = [] if (env.WSL_INTEROP || env.WSL_DISTRO_NAME) { - attempts.push({ - cmd: 'powershell.exe', - args: ['-NoProfile', '-NonInteractive'], - stdin: false, - psScript: _powershellWriteScript - }) + attempts.push({ cmd: 'powershell.exe', args: ['-NoProfile', '-NonInteractive'], stdin: false }) } if (env.WAYLAND_DISPLAY) { @@ -165,7 +163,7 @@ export async function writeClipboardText( child.stdin?.end(text) } else { const b64 = Buffer.from(text, 'utf8').toString('base64') - const script = cmdEntry.psScript(b64) + const script = _powershellWriteScript(b64) const child = start(cmdEntry.cmd, [...cmdEntry.args, '-Command', script], { stdio: ['ignore', 'ignore', 'ignore'], windowsHide: true }) child.once('error', () => resolve(false)) child.once('close', (code: number | null) => resolve(code === 0))