Two P1 fixes from the round 8 reviewer pass:
1. _stream_thread_run no longer replays a Codex turn that fired
non-visible events before crashing.
The replay guard only tracked `emitted_any` (visible text). A
Codex turn that emitted, say, a command.delta or file.delta event
first -- both filtered to "" by _coerce_text -- and THEN crashed
would leave emitted_any=False and fall through to the buffered
`thread.run(prompt)` fallback, re-executing the same turn and
duplicating its side effects (shell commands, file writes,
tool calls). This is exactly the case the guard was added to
prevent in earlier rounds; the missing bit was tracking
"the turn ran at all", not just "the turn yielded text".
Fix: add a separate turn_started flag that flips True the moment
we ask the SDK for a turn handle or observe any event from a
streaming helper. When the buffered fallback is gated on
turn_started instead of emitted_any, a partial-turn crash
correctly stops without replaying. Regression test reproduces
the bug against the pre-fix code (assertion catches the extra
thread.run call) and locks the fix in.
2. openAddProvider now mirrors the providerType-change effect's
Codex pre-check.
The first-run UX fix from `26799d9a` pre-checked every Codex
default model in the providerType-change effect, but
openAddProvider() calls resetForm() (which clears
selectedModelIds) and then only restores availableModels, not
selectedModelIds. If the user closes the Add connection form
and re-opens it while Codex is still the current providerType,
the effect does not re-run, so the form opens with Codex
defaults available but none selected -- the "Add at least one
model ID" save guard then blocks the Save click.
Fix: openAddProvider now seeds selectedModelIds with the full
default-models list when the provider is Codex, matching the
providerType-change effect so the two entry paths produce the
same first-run state.