--- title: internal/onboard description: Go API reference for the onboard package. --- # onboard ```go import "github.com/jbcom/radioactive-ralph/internal/onboard" ``` Package onboard implements the guided first\-run wizard: when a user runs the client cold on an interactive terminal and no supervisor is reachable, it OFFERS \(with explicit consent\) to install and start the background service, falling back to a foreground supervisor or the plain print\-the\-commands path. See docs/superpowers/specs/2026\-07\-17\-guided\-first\-run\-onboarding\-design.md. The wizard is pure orchestration: every side effect \(prompting, installing the service, discovering the supervisor\) is an injected dependency, so the whole decision tree is unit\-testable without touching the real system. ## Index - [Variables](<#variables>) - [type Deps](<#Deps>) - [type Outcome](<#Outcome>) - [func Run\(d Deps\) \(Outcome, error\)](<#Run>) - [type Plan](<#Plan>) - [type Prompter](<#Prompter>) - [type StdinPrompter](<#StdinPrompter>) - [func NewStdinPrompter\(in io.Reader, out io.Writer\) \*StdinPrompter](<#NewStdinPrompter>) - [func \(p \*StdinPrompter\) Confirm\(question string, defaultYes bool\) \(bool, error\)](<#StdinPrompter.Confirm>) ## Variables ErrQuit is returned by a Prompter when the user asks to quit the wizard. ```go var ErrQuit = errors.New("onboard: user quit") ``` ## type [Deps]() Deps are the injected dependencies. Every field is required. ```go type Deps struct { // Out receives the wizard's human-facing output. Out io.Writer // Prompt drives the yes/no questions. Prompt Prompter // Plan describes what installing the service will create. Plan Plan // InstallService installs AND (best-effort) starts the background service. InstallService func() error // WaitReachable blocks until a supervisor answers or the timeout elapses, // returning true when one became reachable. WaitReachable func(timeout time.Duration) bool // ForegroundHint is the exact command a user runs to start a foreground // supervisor (printed on the fallback path). ForegroundCmd string // ManualCommands is the multi-line fallback text (the pre-wizard message). ManualCommands string } ``` ## type [Outcome]() Outcome reports how the wizard ended so the caller knows whether to proceed to the TUI. ```go type Outcome int ``` ```go const ( // SupervisorReady means a supervisor is now reachable — proceed to the TUI. SupervisorReady Outcome = iota // PrintedForegroundHint means the wizard printed the `--supervisor` // command for the user to run themselves; the caller should exit cleanly. PrintedForegroundHint // PrintedCommands means the wizard fell back to printing the manual // commands; the caller returns its usual no-supervisor error. PrintedCommands ) ``` ### func [Run]() ```go func Run(d Deps) (Outcome, error) ``` Run drives the first\-run flow. It assumes the caller already confirmed the session is interactive and no supervisor is currently reachable. ## type [Plan]() Plan is the "what will be created" summary shown before any outward\-facing action, so the user consents to concrete paths, not a vague promise. ```go type Plan struct { StateDir string DBPath string ServiceUnit string ServiceUnitPath string } ``` ## type [Prompter]() Prompter asks the user a yes/no question. Confirm returns \(true, nil\) for yes, \(false, nil\) for no, and a non\-nil error to abort the whole wizard \(e.g. the user typed 'q' to quit, or stdin closed\). ```go type Prompter interface { Confirm(question string, defaultYes bool) (bool, error) } ``` ## type [StdinPrompter]() StdinPrompter is the real Prompter: it writes the question to Out and reads one line from In, interpreting y/yes → true, n/no → false, q/quit → ErrQuit, and an empty line → the supplied default. Any other input re\-asks \(bounded, so a closed stdin doesn't loop forever\). ```go type StdinPrompter struct { In io.Reader Out io.Writer // contains filtered or unexported fields } ``` ### func [NewStdinPrompter]() ```go func NewStdinPrompter(in io.Reader, out io.Writer) *StdinPrompter ``` NewStdinPrompter builds a StdinPrompter over in/out. ### func \(\*StdinPrompter\) [Confirm]() ```go func (p *StdinPrompter) Confirm(question string, defaultYes bool) (bool, error) ``` Confirm implements Prompter. Generated by [gomarkdoc]()