Repository navigation
fix(type-text): force clipboard-paste for non-ASCII text - #660
Merged
Merged
Conversation
AppleScript's `keystroke "..."` routes characters through virtual-key codes that can't represent anything outside basic ASCII. Emoji (🤖), em-dashes (—), curly quotes — all get corrupted: UTF-8 bytes get reinterpreted as Mac Roman (e.g. em-dash bytes E2 80 94 → "‚Äî", robot emoji 4-byte F0 9F A4 96 → garble). Add a `hasNonAscii` check (/[^\x00-\x7f]/) to the same conditional that already routes multi-line / long text through the clipboard-paste branch. The paste branch round-trips through pbcopy → System Events Cmd-V, which preserves bytes losslessly. Per Chi 2026-05-13: typed the Mini DeepMind X-post draft into Cursor via voice, em-dashes got mojibaked, then 🤖 got garbled. Workaround of "I'll put it in your clipboard manually" wasn't a fix — this is. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
4 tasks
sonichi
added a commit
that referenced
this pull request
May 13, 2026
Follow-up to #660. The first fix routed emoji + non-ASCII text to the paste branch, but pbcopy still corrupted multi-byte UTF-8 in the voice-agent's launchd context — Chi reported 🤖 still didn't make it to Cursor after restart. Root cause: voice-agent runs under launchd which doesn't inherit the terminal's LANG/LC_CTYPE. The child shell that ran `pbcopy < tmpClip` defaulted to POSIX/C locale; pbcopy in that locale doesn't pass multi-byte sequences through cleanly — they end up as "??" on the pasteboard. Two changes: 1. Set `LANG=en_US.UTF-8` + `LC_ALL=en_US.UTF-8` on every execSync call in the paste branch via the `env:` option. 2. Switch from `writeFileSync` + `pbcopy < file` to `execSync('pbcopy', { input: pasteText })` — bypasses the shell redirect entirely and pipes bytes directly to pbcopy's stdin. Same approach for the clipboard restore step. Eliminates a class of locale/encoding bugs. Side benefit: no /tmp files leaked, no unlinkSync needed. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219
pushed a commit
to liususan091219/sutando-fork
that referenced
this pull request
May 28, 2026
AppleScript's `keystroke "..."` routes characters through virtual-key codes that can't represent anything outside basic ASCII. Emoji (🤖), em-dashes (—), curly quotes — all get corrupted: UTF-8 bytes get reinterpreted as Mac Roman (e.g. em-dash bytes E2 80 94 → "‚Äî", robot emoji 4-byte F0 9F A4 96 → garble). Add a `hasNonAscii` check (/[^\x00-\x7f]/) to the same conditional that already routes multi-line / long text through the clipboard-paste branch. The paste branch round-trips through pbcopy → System Events Cmd-V, which preserves bytes losslessly. Per Chi 2026-05-13: typed the Mini DeepMind X-post draft into Cursor via voice, em-dashes got mojibaked, then 🤖 got garbled. Workaround of "I'll put it in your clipboard manually" wasn't a fix — this is. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
liususan091219
pushed a commit
to liususan091219/sutando-fork
that referenced
this pull request
May 28, 2026
Follow-up to sonichi#660. The first fix routed emoji + non-ASCII text to the paste branch, but pbcopy still corrupted multi-byte UTF-8 in the voice-agent's launchd context — Chi reported 🤖 still didn't make it to Cursor after restart. Root cause: voice-agent runs under launchd which doesn't inherit the terminal's LANG/LC_CTYPE. The child shell that ran `pbcopy < tmpClip` defaulted to POSIX/C locale; pbcopy in that locale doesn't pass multi-byte sequences through cleanly — they end up as "??" on the pasteboard. Two changes: 1. Set `LANG=en_US.UTF-8` + `LC_ALL=en_US.UTF-8` on every execSync call in the paste branch via the `env:` option. 2. Switch from `writeFileSync` + `pbcopy < file` to `execSync('pbcopy', { input: pasteText })` — bypasses the shell redirect entirely and pipes bytes directly to pbcopy's stdin. Same approach for the clipboard restore step. Eliminates a class of locale/encoding bugs. Side benefit: no /tmp files leaked, no unlinkSync needed. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
type_textwas corrupting any non-ASCII char (emoji, em-dashes, curly quotes) because AppleScript'skeystroke "..."routes through virtual-key codes that can't represent characters outside basic ASCII typing rangehasNonAscii = /[^\x00-\x7f]/.test(text)to the existing conditional that already routes multi-line / long text through the clipboard-paste branch (which preserves bytes)Root cause (from
src/inline-tools.ts:268)Before this PR,
type_textonly used the clipboard-paste branch when text had newlines orlength > 80. Single-line short text fell to:This works for ASCII but butchers multi-byte UTF-8. Real failures Chi hit today:
—(em-dash, U+2014, UTF-8E2 80 94) → reinterpreted as Mac Roman‚Äî🤖(robot emoji, UTF-8F0 9F A4 96) → garbled output'→ also got escape-leaked through Cursor's auto-pair, but that's a Cursor-side artifact (not in this PR's scope)Test plan
Why the fix is minimal
The clipboard-paste branch already exists (lines 270-291 of inline-tools.ts) and is well-tested. This PR only widens the entry condition. Zero new code paths; zero behavior change for ASCII inputs.
🤖 Generated with Claude Code