tui

package
v0.32.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 24, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Overview

Package tui hosts the shared Bubble Tea / Bubbles / Lip Gloss foundation used by Traceary's interactive CLI surfaces.

The package intentionally keeps a small, opinionated public surface so the upcoming `memory inbox review` UI and the redesigned `top` dashboard share the same key conventions, color palette, and lifecycle (terminal restore, non-TTY guard, Ctrl-C handling).

Callers should treat Model/Update/View as the testable seam: build Bubble Tea models against tui.KeyMap and tui.Styles, then pass them to Run for production use. Tests should drive the model directly without going through a real terminal.

Index

Constants

This section is empty.

Variables

View Source
var ErrNotInteractive = errors.New("tui: stdin/stdout is not a terminal")

ErrNotInteractive is returned when Run is invoked without a TTY-backed input/output pair. Callers should detect this and fall back to a non-interactive snapshot rendering.

Functions

func Interactive

func Interactive(in, out *os.File) bool

Interactive reports whether the given input/output pair is suitable for an interactive Bubble Tea program. Both must be TTYs; otherwise callers should fall back to a non-interactive snapshot.

func IsTerminal

func IsTerminal(w io.Writer) bool

IsTerminal reports whether w is backed by a *os.File that points at a TTY. Non-file writers (in-memory buffers, pipes captured in tests) always report false so test runs stay deterministic.

func IsTerminalFile

func IsTerminalFile(f *os.File) bool

IsTerminalFile reports whether the given file handle points at a TTY. nil returns false so callers can pass os.Stdin/os.Stdout without nil checks in test contexts where the stream may be replaced.

func Run

func Run(model Model, opts RunOptions) error

Run launches model under a Bubble Tea program with Traceary's standard safety net:

  • The runner refuses to start when stdin/stdout are not TTYs and returns ErrNotInteractive so the caller can render a snapshot instead.
  • Bubble Tea installs its own SIGINT/SIGTERM handler which restores the terminal before exiting; we keep that behavior on so Ctrl-C never leaves the user in a broken raw-mode shell.
  • tea.Program.Run guarantees terminal restoration on every return path, including panics inside the model. We surface any restore-time error up to the caller wrapped with xerrors so the stack is preserved.

Types

type Cmd

type Cmd = tea.Cmd

Cmd is a thin re-export of tea.Cmd for the same reason as Model.

type KeyMap

type KeyMap struct {
	Up       key.Binding
	Down     key.Binding
	PageUp   key.Binding
	PageDown key.Binding
	Home     key.Binding
	End      key.Binding
	Select   key.Binding
	Search   key.Binding
	Refresh  key.Binding
	Help     key.Binding
	Quit     key.Binding
}

KeyMap is the canonical set of bindings shared across Traceary TUIs.

Both `memory inbox review` and the redesigned `top` dashboard navigate a list-like surface with optional secondary actions, so the bindings cover movement, paging, selection, refresh, help, and quit. Concrete screens extend KeyMap with their own action keys (Accept/Reject/Defer for inbox, Filter/Toggle for top) — the shared bindings stay identical so muscle memory transfers between screens.

func DefaultKeyMap

func DefaultKeyMap() KeyMap

DefaultKeyMap returns the canonical bindings.

Quit binds both `q` and `ctrl+c`; Run also installs a hard signal guard so callers do not have to special-case Ctrl-C.

func (KeyMap) FullHelp

func (k KeyMap) FullHelp() [][]key.Binding

FullHelp returns the bindings shown in the expanded help screen.

func (KeyMap) ShortHelp

func (k KeyMap) ShortHelp() []key.Binding

ShortHelp returns the bindings shown in the always-visible help line.

type Model

type Model = tea.Model

Model is a thin re-export of tea.Model so callers in package cli can build against tui without importing bubbletea directly. Tests that exercise the model/update/view seam can instantiate concrete types and drive them without spawning a Program.

func RunModel

func RunModel(model Model, opts RunOptions) (Model, error)

RunModel is the variant of Run that returns the final model after the Bubble Tea program exits. Screens that accumulate state inside the model (e.g. memory inbox review queues operator decisions) need the post-quit snapshot so they can apply the queued work; Run remains for screens that are pure renderers and only care about the run-time error.

type Msg

type Msg = tea.Msg

Msg is a thin re-export of tea.Msg.

func Quit

func Quit() Msg

Quit is the canonical quit command. Re-exported so screens that satisfy KeyMap.Quit can return tui.Quit without importing bubbletea.

type RunOptions

type RunOptions struct {
	Input           *os.File
	Output          *os.File
	AltScreen       bool
	ExtraTeaOptions []tea.ProgramOption
}

RunOptions configures Run.

Input/Output default to os.Stdin/os.Stdout when nil. AltScreen toggles the alternate-screen buffer (top dashboard wants it; an inline review prompt may not). ExtraTeaOptions are appended after the runner's own options so callers can layer Bubble Tea features (mouse, focus reporting, etc.).

type Styles

type Styles struct {
	// Title styles a single-line screen header.
	Title lipgloss.Style
	// Subtle styles secondary text such as filters, counts, and meta lines.
	Subtle lipgloss.Style
	// Active highlights the currently focused row or selection.
	Active lipgloss.Style
	// Idle dims rows that are not the current selection.
	Idle lipgloss.Style
	// Success styles positive state (active sessions, accepted candidates).
	Success lipgloss.Style
	// Warning styles cautionary state (stale rows, soft validation).
	Warning lipgloss.Style
	// Error styles failure states such as load errors or rejected items.
	Error lipgloss.Style
	// Help styles the bottom-of-screen key hints.
	Help lipgloss.Style
	// Border wraps a panel; reused by both inbox preview and top tree panes.
	Border lipgloss.Style
}

Styles bundles the Lip Gloss styles shared across Traceary TUIs.

Keep the palette small: every interactive screen should pick from these styles so the inbox-review UI and the top dashboard stay visually consistent. Add a new field here only when an existing style cannot be reused without distortion.

func DefaultStyles

func DefaultStyles() Styles

DefaultStyles returns the canonical Traceary TUI palette.

The colors deliberately match the ANSI hints used elsewhere in the CLI (see read_color.go) so output between interactive and non-interactive modes stays readable.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL