Found by seeded network-chaos property testing with opencode-drive (seeds 1, 7, and 99 of the network-properties probe all reduced to this).
The prompt component clears the composer only after the awaited session.prompt POST resolves (packages/tui/src/component/prompt/index.tsx, submit handler: POST is awaited, then history.append({...store.prompt}), setStore("prompt", emptyPrompt()), input.clear()). Anything typed during that in-flight window:
- is appended to the still-visible previous prompt text,
- has its enter dropped,
- is destroyed by the post-await
input.clear(),
- and is recorded in prompt history as a merged entry that was never sent (
history.append reads the live store.prompt, not the captured inputText the POST actually used).
Deterministic repro (drive script test/manual/tui-regressions/type-during-submit.ts in opencode-drive): add 800ms latency between TUI and server, submit FIRST probe, type and enter SECOND probe 250ms later. Result: SECOND never reaches the server, is not in the composer, and no error is shown, while prompt-history.jsonl contains "FIRST probeSECOND probe" as one entry:

Real-life shape: type-ahead on a slow connection. The first prompt of a new session has the widest window (session create + model switch + the 50ms navigate hack all happen inside the await), so typing your next message right after enter on a slow link eats it with no feedback.
Steers on a fast connection are fine (probed 0-1800ms offsets into a streaming reply, all admitted); the loss needs the POST itself to still be in flight.
A likely fix is to clear the composer synchronously at submit and restore the captured text on failure (the failure path already restores today), but that is a product call about optimistic clearing, so filing rather than PRing.
Found by seeded network-chaos property testing with opencode-drive (seeds 1, 7, and 99 of the network-properties probe all reduced to this).
The prompt component clears the composer only after the awaited
session.promptPOST resolves (packages/tui/src/component/prompt/index.tsx, submit handler: POST is awaited, thenhistory.append({...store.prompt}),setStore("prompt", emptyPrompt()),input.clear()). Anything typed during that in-flight window:input.clear(),history.appendreads the livestore.prompt, not the capturedinputTextthe POST actually used).Deterministic repro (drive script
test/manual/tui-regressions/type-during-submit.tsin opencode-drive): add 800ms latency between TUI and server, submitFIRST probe, type and enterSECOND probe250ms later. Result:SECONDnever reaches the server, is not in the composer, and no error is shown, whileprompt-history.jsonlcontains"FIRST probeSECOND probe"as one entry:Real-life shape: type-ahead on a slow connection. The first prompt of a new session has the widest window (session create + model switch + the 50ms navigate hack all happen inside the await), so typing your next message right after enter on a slow link eats it with no feedback.
Steers on a fast connection are fine (probed 0-1800ms offsets into a streaming reply, all admitted); the loss needs the POST itself to still be in flight.
A likely fix is to clear the composer synchronously at submit and restore the captured text on failure (the failure path already restores today), but that is a product call about optimistic clearing, so filing rather than PRing.