setup_screen
setup_screen
¶
Verdict + decision modal for the first-run / re-run host setup flow.
Renders the current terok_sandbox.SetupVerdict with a
contextual blurb and a Run / Skip choice — no subprocess plumbing here.
The actual terok setup invocation rides on top of
WorkerLogScreen, pushed by the
TUI's first-run flow worker after this screen dismisses with
SetupOutcome.SHOULD_RUN.
The verdict probe (terok_sandbox.needs_setup) is the same one
terok task run enforces in
terok.cli.commands.task._setup_verdict_or_exit — so a verdict
of OK short-circuits with a banner instead of nudging the user
toward a slow re-run, and a STALE_AFTER_DOWNGRADE refuses outright
with the same wording the CLI uses.
SetupOutcome
¶
Bases: Enum
User's decision on SetupScreen.
The screen does not run setup itself; it only collects intent. Translating the outcome to host-state changes is the caller's job:
SHOULD_RUN— user clicked Run; caller should dispatchterok setupto the console-log registry and push aWorkerLogScreenview over the returned entry.SKIPPED— user dismissed before running; the caller leaves the host alone.REFUSED— verdict isSTALE_AFTER_DOWNGRADE; the only available exit, mirroring the CLI exit-4 contract.CANCELLED— Esc on the pre-run screen; treated as a soft skip but distinguishable for telemetry.
SetupScreen(verdict=None)
¶
Bases: ModalScreen[SetupOutcome]
Modal that surfaces the current setup verdict and asks whether to run it.
Two button layouts:
- Healthy / non-OK verdict — Skip + Run buttons. Clicking Run
dismisses with
SetupOutcome.SHOULD_RUNso the parent can dispatchterok setupto the console-log registry and open aWorkerLogScreenview of its streaming output. - Downgrade verdict — Run is hidden; the only exit dismisses
with
SetupOutcome.REFUSED. The CLI refuses with exit code 4 here; this mirrors that contract by not offering an option that would make the contract meaningless.
Build the screen with an optional pre-fetched verdict.
Verdict probing is normally done on the main thread before the screen is pushed (so the caller can decide whether to show it at all). Falling back to a fresh probe inside the screen keeps direct invocations from the command palette working when no caller pre-fetched it.
Source code in src/terok/tui/setup_screen.py
BINDINGS = [Binding('escape', 'close', 'Close')]
class-attribute
instance-attribute
¶
CSS = '\n SetupScreen {\n align: center middle;\n }\n\n #setup-dialog {\n width: 80;\n max-width: 100%;\n height: auto;\n max-height: 80%;\n border: heavy $primary;\n border-title-align: right;\n background: $surface;\n padding: 1 2;\n }\n\n #setup-headline {\n height: auto;\n margin-bottom: 1;\n }\n\n #setup-blurb {\n color: $text-muted;\n height: auto;\n margin-bottom: 1;\n }\n\n #setup-buttons {\n height: auto;\n align-horizontal: right;\n }\n\n #setup-buttons Button {\n margin-left: 1;\n }\n '
class-attribute
instance-attribute
¶
compose()
¶
Build the dialog: headline, blurb, action buttons.
Source code in src/terok/tui/setup_screen.py
action_close()
¶
Esc dismisses with SetupOutcome.CANCELLED (or REFUSED on a downgrade).
on_button_pressed(event)
¶
Route the three button IDs to their dismissal outcomes.