ollama/ollama
TUI selectors and sign-in
The bubbletea-based UI used by the launcher, by interactive ollama run, and by sign-in. Lives under cmd/tui/.
Purpose
Give the CLI a consistent, navigable picker UI when the user runs in an interactive terminal. Single-select lists, multi-select lists, sign-in flows, and confirm prompts share the same look (driven by charmbracelet/lipgloss) and the same behavior on cancellation.
Directory layout
cmd/tui/
├── selector.go # bubbletea single/multi selector models
├── confirm.go # confirm prompts
├── signin.go # sign-in flow with browser handoff
├── tui.go # shared helpers and types
└── *_test.goKey abstractions
| Symbol | Location | Purpose |
|---|---|---|
tui.SelectSingle(title, items, current) |
cmd/tui/selector.go |
One-of selection. Returns the chosen value or tui.ErrCancelled. |
tui.SelectMultiple(title, items, preChecked) |
cmd/tui/selector.go |
Multi-select. Returns the chosen values. |
tui.RunSignIn(modelName, signInURL) |
cmd/tui/signin.go |
Browser-handoff sign-in: prints the URL, opens it, waits for the user to confirm. |
tui.RunConfirmWithOptions(...) |
cmd/tui/confirm.go |
Confirm prompt with custom labels. |
tui.ConvertItems, tui.ReorderItems |
cmd/tui/selector.go |
Bridge between the launcher's ModelItem slice and the TUI's internal item type, plus a stable reorder. |
tui.ErrCancelled |
cmd/tui/tui.go |
Returned when the user presses q or Ctrl+C. The launcher maps this to launch.ErrCancelled. |
Wiring
cmd.init() (cmd/cmd.go) replaces the launcher's selector and sign-in defaults with these implementations:
launch.DefaultSingleSelector = func(title string, items []launch.ModelItem, current string) (string, error) {
if !term.IsTerminal(int(os.Stdin.Fd())) || !term.IsTerminal(int(os.Stdout.Fd())) {
return "", fmt.Errorf("model selection requires an interactive terminal; ...")
}
...
return tui.SelectSingle(title, tuiItems, current)
}The non-TTY guard is what lets ollama launch ... --model X --yes work in scripts: when stdin/stdout aren't TTYs the selector errors out rather than block on input the user can't provide.
Headless behavior
--model Xlets the user skip selection.--yesswitches the launch policy fromprompttoauto-approve(LaunchPolicy.confirmPolicyincmd/launch/launch.go).- Without an interactive TTY, the policy degrades to
require-yes: the launcher refuses to proceed without--yesand refuses to pull missing models withoutOLLAMA_AUTO_PULL(seeenvconfig/config.go).
Browser handoff for sign-in
tui.RunSignIn prints the canonical https://ollama.com/connect?... URL produced by signinURL (server/routes.go), opens it with pkg/browser, and waits for the user to return after authorizing. The TUI shows a spinner; on cancel it returns ErrCancelled.
Tests
Each TUI piece has a paired _test.go (selector_test.go, confirm_test.go, signin_test.go). They drive the bubbletea models with simulated key events and assert on the resulting state.
Integration points
- Launcher: see launch integrations.
- Interactive
ollama run: usesreadline/for the line editor, but borrows the same lipgloss styles. - Desktop app: shares the sign-in URL but uses its native dialogs to display it.
Entry points for modification
- New picker variant → add it next to
selector.goand expose a wrapper that mapsErrCancelledto the caller's idiom. - New confirm style → extend
tui.RunConfirmWithOptions.
Key source files
| File | Purpose |
|---|---|
cmd/tui/selector.go |
Single/multi-select pickers. |
cmd/tui/confirm.go |
Confirm prompts. |
cmd/tui/signin.go |
Browser-handoff sign-in. |
cmd/tui/tui.go |
Shared types and ErrCancelled. |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.