anomalyco / anomalyco/opencode

Safari: CJK IME composition is aborted mid-input in web app prompt input

Open
#38,674 1 comment 0 reactions 1 assignee View on GitHub

@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()) return fails because Safari fires the first input event before compositionstart, so composing() is still false at that point (Chrome fires them in the opposite order).
  • The mirror.input flag only skips one write-back round; when isNormalizedEditor() 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
  1. Open the opencode web app in Safari on macOS.
  2. Focus the prompt input and enable a Chinese pinyin or Japanese IME.
  3. Type a long phrase continuously, e.g. zhongwenshurufaceshi or きょうはいいてんきですね.
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.