anomalyco / anomalyco/opencode
Safari: CJK IME composition is aborted mid-input in web app prompt input
@Brendonovich is already working on this.
Since Jul 24, 2026.
- Dominant language
- TypeScript
- Stars
- 209k
- Forks
- 27.5k
- PR merge metrics
- PR metrics pending
Description
Description
In the web app prompt input (packages/app/src/components/prompt-input.tsx), typing with a CJK IME in Safari gets cut off mid-composition: after a few keystrokes the half-composed text (raw pinyin / kana) is committed as plain text and the composition ends.
Root cause: the prompt input is a contenteditable that round-trips DOM -> state -> DOM on every input event (handleInput -> prompt.set(...) -> effect -> renderEditorWithCursor()). Safari aborts an active IME composition whenever the DOM or selection is mutated programmatically, and the existing guards don't hold there:
- The effect guard
if (composing()) returnfails because Safari fires the firstinputevent beforecompositionstart, socomposing()is stillfalseat that point (Chrome fires them in the opposite order). - The
mirror.inputflag only skips one write-back round; whenisNormalizedEditor()is false (common mid-composition)renderEditorWithCursor()still rewrites the DOM.
Japanese IMEs that confirm bunsetsu-by-bunsetsu also fire compositionend + a new compositionstart mid-sentence; a rewrite landing in that gap cuts off the remaining segments the same way.
Related: #35746 covers the confirm-Enter mis-submit side. The same Safari event order breaks the isImeComposing guard in this input too: Safari fires compositionend before the confirming Enter keydown, so that event has isComposing === false and keyCode === 13 and none of the guard conditions match.
The standard approach (ProseMirror / CodeMirror / Lexical) is to freeze DOM->state->DOM syncing entirely during composition and do a single sync on compositionend. I have a patch for both problems and would like to submit a PR.
Plugins
No response
OpenCode version
v1.18.4 (code paths verified on main @ c9db6e9)
Steps to reproduce
- Open the opencode web app in Safari on macOS.
- Focus the prompt input and enable a Chinese pinyin or Japanese IME.
- Type a long phrase continuously, e.g.
zhongwenshurufaceshiorきょうはいいてんきですね. - The composition is aborted partway and half-composed text is committed. Pressing Enter to confirm a candidate also submits the message.
Not reproducible in Chrome (there compositionstart precedes the first input, and the confirming Enter keydown arrives with isComposing=true / keyCode=229 before compositionend).
Screenshot and/or share link
No response
Operating System
macOS (Safari)
Terminal
No response
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.