78c054918f0b7164dad3f952b5a58c7dbf39e645
SpawnScreen kept its own `loading` flag and `error` string, the third mechanism in this app for a state two screens already share. That was not just untidy: on a failed fetch it set the error, left `providers` and `hosts` at the empty lists they started as, and rendered the form anyway -- so "couldn't reach the server" arrived as a Provider row with no providers in it, which is what a server offering nothing would also look like. The error sat below both empty pickers. It now holds `LoadState<SpawnOptions>` like the others: loading shows the spinner, a failure reports and stops, and the form exists only where there is something to fill it with. The spawn action keeps its own error, renamed `spawnError` so the two can't be confused again. They are different in kind and the distinction is the one the session list just learned: a fetch that never answered leaves no form worth showing, while a spawn the server refused leaves a filled-in form the user still wants, so that one stays beside the button that produced it. Verified on the emulator: the form loading with both providers, the Claude fields appearing when claude-cli is selected (which also exercises the snake_case kind the phone now compares against), and the failure state with the server stopped -- reporting alone, with Cancel still working. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_017xn8nHw1tw1R6PtiY1eEtw
Languages
Rust
54%
Kotlin
43.6%
Shell
2.4%