Korean input (CJK IME) broken on iOS Termius SSH: DEL handler drops composed characters
Preflight Checklist
- [x] I have searched existing issues and this hasn't been reported yet
- [x] This is a single bug report (please file separate reports for different bugs)
- [x] I am using the latest version of Claude Code
What's Wrong?
Re-filing #15705 which was auto-closed by bot as NOT_PLANNED while still unresolved.
Summary
Korean (CJK) input is completely broken when using Claude Code over SSH from iOS Termius. Characters disappear during IME composition.
iOS Termius emulates IME composition via delete + re-insert: ㄱ → DEL(0x7f) → 가. Claude Code's DEL handler discards the composed character.
Root Cause (traced from source)
The source code isn't publicly available, so this analysis is based on the leaked/decompiled Claude Code source:
src/hooks/useTextInput.ts:442-465 — the DEL filtering logic (added for Issue #1853) is the direct cause.
When \x7f and 가 arrive in the same input chunk (\x7f가):
Bug trace step by step
| Step | Location | Input | Result |
|------|----------|-------|--------|
| Tokenizer | tokenize.ts:139 | \x7f가 | \x7f is not ESC → stays in ground state → single text token '\x7f가' |
| Key parsing | parse-keypress.ts:711 | s = '\x7f가' | s === '\x7f' is false (length ≠ 1) → key.name = '', backspace not set |
| Input event | input-event.ts:58 | | input = '\x7f가', key.backspace = false |
| Text input | useTextInput.ts:444 | | !backspace && !delete && includes('\x7f') → true → enters DEL handler |
| DEL handler | useTextInput.ts:450-464 | | performs 1 backspace then return → 가 is never inserted |
// src/hooks/useTextInput.ts:442-465
if (!key.backspace && !key.delete && input.includes('\x7f')) {
const delCount = (input.match(/\x7f/g) || []).length
for (let i = 0; i < delCount; i++) {
currentCursor = currentCursor.deleteTokenBefore() ?? currentCursor.backspace()
}
// ...
return // ← BUG: early return drops non-DEL characters ('가')
}
Suggested Fix (two options)
Option A — Tokenizer level (recommended):
Split \x7f as a separate token boundary in tokenize.ts, so ㄱ, \x7f, 가 become three independent key events. This is how other CLI tools (Gemini CLI, Codex CLI) effectively handle this — control characters are processed individually.
Option B — DEL handler level:
After processing DEL as backspace, strip \x7f from input and continue processing remaining characters instead of returning early.
Environment
- Client: iOS + Termius (SSH)
- Server: macOS / Linux
- Works correctly: Android Termius, macOS Terminal, iTerm2, Gemini CLI, Codex CLI
A note on process
The fact that community members have to reverse-engineer leaked source code to diagnose bugs like this is not ideal. If issues aren't going to be fixed in a timely manner, consider open-sourcing the codebase and accepting community contributions. The code is already out there anyway. Letting the community help would be a win-win.
What Should Happen?
Korean input should compose and render correctly (가, 나, 다, etc.) regardless of whether the terminal uses delete + re-insert IME emulation.
Steps to Reproduce
- SSH into a server using Termius on iOS
- Run
claude - Type Korean text (e.g.,
가)
ㄱappears briefly- Type
ㅏ→ character disappears
Claude Model
None
Is this a regression?
Yes, this worked in a previous version
Claude Code Version
2.1.87
Platform
Anthropic API
Operating System
Other
Terminal/Shell
Other
Additional Information
Previous issue: #15705 (auto-closed by bot while unresolved, root cause analysis was posted after closure)
This issue has 3 comments on GitHub. Read the full discussion on GitHub ↗