Files
orca/mobile/src
Brennan Benson 12fa5ff79e fix(mobile): heal an orphaned native-chat image paste across screen unmounts (#10480)
* fix(mobile): heal an orphaned native-chat image paste across screen unmounts

The stale-input marker lived in a per-screen `useRef`, but the condition it
tracks — a bracketed image paste sitting unsubmitted on the agent's composer
line — lives on the host and outlives the screen. Backing out of a session and
returning remounted the hook with an empty Set, so the next message submitted
on top of the orphaned paste and the agent received `<image path><text>`.

Move the marker to a module-level store keyed by terminal handle, and consult
and consume it from every write path that can submit the composer: the image
hook's text-only send, the controller send (which the chat overlay's question
card reaches directly, bypassing the image hook), and the ask-answer send.

Permission choices and the Escape cancel deliberately do NOT heal: they are
`enter: false` keys for an active overlay that swallows the clear, so healing
there would consume the marker without clearing the line and leave the next
real message corrupted. Desktop scopes its Ctrl+U the same way.

* fix(mobile): stop the ask heal from burning the marker on selector answers

The heal ran on every ask answer, but Claude's and Codex's selector shapes
cannot submit the composer: a single-select answer is a bare option digit and
every stepping group is written `enter: false` (the host coerces it), so the
clear is swallowed by the live overlay while the host still acks the write.
That consumed the one-shot marker and left the orphaned paste to corrupt the
next real message — the same failure this PR exists to fix, through a new door
that main did not have.

Scope the heal to the pasted-label shape, which does commit the composer.
Desktop splits it the same way: use-native-chat-interactive-send.ts routes only
the non-stepping answer through the clearing sender and never pre-clears
sendNativeChatAskAnswer.

Also pin the three deliberate skips (selector answer, permission choice, Escape
cancel) with tests, so the PR's central design argument is an invariant rather
than a comment, and guard the failed-heal toast with the generation check every
other error surface in answerAsk already uses.
2026-07-24 23:10:13 -07:00
..