Documentation
¶
Overview ¶
Package setupui is the interactive terminal front-end for the `setup` command. On a TTY, instead of printing a registration link and exiting, setup stays live: it shows the link (width-wrapped and clickable, with ^Y to copy it and ^R to show it as a scannable QR code), prompts for the API key id the developers portal issues, and — once the user pastes it — binds the key and runs the health check in the same session.
This package is purely the UI. It knows nothing about keys, signing, or the Korbit API: the caller passes the guidance lines and registration URL to display and a Submit callback that performs the bind + health check and returns the lines. That keeps the whole interactive layer isolated behind two function types, so the non-interactive setup path (and the MCP server, which drives setup with a buffer-backed IO) never touches Bubble Tea.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var ErrInterrupted = errors.New("setup canceled")
ErrInterrupted is returned by Run when the user aborts with Ctrl-C. The caller treats it as a deliberate cancel — emit nothing (mirroring the non-interactive SIGINT abort, which prints no result) and exit 0. Any key already bound stays; re-running setup is idempotent.
Functions ¶
func Run ¶
Run starts the interactive session and blocks until it exits. A deliberate quit (the user pressed Esc/Ctrl-C without finishing) returns nil — whether setup was completed is observed by the caller through its Submit closure, not through this return value. Only a Bubble Tea runtime failure is returned as an error.
Types ¶
type ClaimUpdate ¶
ClaimUpdate is one message from the background auto-claim poll. A non-terminal update carries only Status (the live line to show). A terminal update sets exactly one of Done (success: Result holds the lines to display before the session ends) or Stop (polling stopped without a claim; the prompt stays open and Status explains why).
type Config ¶
type Config struct {
// In/Out are the terminal streams the program runs on. setup renders the UI
// on stderr (Out) and keeps stdout for the final result document, so the
// machine-readable contract holds even in interactive mode.
In io.Reader
Out io.Writer
// Intro is the static guidance shown above the prompt — the lead-in prose, the
// public key fallback, and what to paste. Rendered one entry per line, each
// hard-wrapped to the terminal width so a long line is never clipped.
Intro []string
// RegistrationURL is the developers-portal deep link the user opens to register
// the generated key. When non-empty it is rendered as a dedicated block right
// below Intro: width-wrapped so the (space-less, often 200+ char) URL is never
// truncated and stays copyable, and wrapped in an OSC 8 hyperlink so terminals
// that support it make it clickable regardless of how it wraps. It also enables
// the ^Y "copy link" and ^R "show QR" shortcuts. Empty when no link could be
// built (Intro then carries the manual public-key fallback and no block, copy,
// or QR is offered).
RegistrationURL string
// Prompt labels the input field (e.g. "Paste the issued API key id").
Prompt string
// Submit binds the entered token (the issued API key id) and runs the health
// check. It performs network I/O, so the model runs it off the UI loop behind
// a spinner. It returns the lines to display, done=true when setup is
// complete (the session then ends), or a non-nil error to show as a retryable
// message while keeping the prompt open.
Submit func(token string) (result []string, done bool, err error)
// AutoClaim, when non-nil, runs concurrently with the paste prompt: a
// background poll that detects the registered key, binds it, and runs the
// health check without the user pasting anything. The model starts it once
// (passing a context canceled when the session ends, so the poll stops on
// paste/Esc/Ctrl-C), renders each ClaimUpdate.Status as a live line beneath
// the prompt, and on a terminal update either ends the session showing Result
// (Done — the key was found, bound, and checked) or stops the poll and keeps
// the prompt open for manual paste (Stop — a conflict or hard error; Status
// says why). nil disables auto-claim (a pipe, no TTY, the MCP server).
AutoClaim func(ctx context.Context) <-chan ClaimUpdate
// contains filtered or unexported fields
}
Config drives one interactive setup session.