feat(#17): TUI Bifrost-bind trigger (slice 3b of the INV-008 lockstep)
Slice 3b of issue #17 — the TUI surface of the bind trigger (web is 3c). The TUI consumes the same ParsedArgs the cli already parses (--bifrost-plane / --bifrost-url / consumer key from RATATOSKR_BIFROST_CONSUMER_KEY), so this wires the bind into _resolve_then_run's pre-flight create_session: - bifrost + consumer_key threaded into create_session at the pre-alt-screen resolution layer, so bind failures land on the operator's REAL stderr BEFORE the Textual alt-screen opens (INV-002, mirrors issue #6's pre-alt-screen routing) — never eaten by the alt-screen teardown. - BifrostConsumerKeyMissing -> exit 22; BifrostHandshakeFailed -> exit 23 with the same 401-scoping hint, keyed on bifrost_error == bifrost.auth_rejected. Exit codes + label vocabulary match cli._amain exactly (INV-006). - Bound-state indicator on success (pre-alt-screen): ". bifrost: status=bound plane=... endpoint=...". 3 new TUI bind tests (handshake-fail / consumer-key-missing / bound-create carries binding + indicator, run_async stubbed). Full suite 465 green; added lines ruff + mypy clean (pre-existing tui.py lint/type backlog untouched per surgical-changes).
This commit is contained in: