tui

package
v0.0.1-alpha.2 Latest Latest
Warning

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

Go to latest
Published: Jul 25, 2026 License: Apache-2.0 Imports: 12 Imported by: 0

Documentation

Overview

Package tui is the Bubble Tea front-end (ADR-0001, T-030/T-031). It renders streamed Events and tool results (including edit diffs) and drives the permission prompt when the policy gate returns Ask. The agent runs in a goroutine; its OnEvent/OnToolResult callbacks push messages into the program via program.Send, and the Prompter blocks its goroutine on an answer channel until the user responds.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func ContrastRatio

func ContrastRatio(a, b string) float64

ContrastRatio is the WCAG 2.x relative-luminance contrast ratio between two hex colors ("#rrggbb"), order-independent. It returns the ratio (1.0 = identical, 21.0 = black/white), or a negative sentinel if a color cannot be parsed — callers gate palettes on a floor of 4.5:1 (WCAG AA for normal text).

func PaletteNames

func PaletteNames() []string

PaletteNames lists every shipped palette in presentation order: the default first (it is the one a user gets without choosing), then the rest as declared.

func SendNoOp

func SendNoOp() func(tea.Msg)

SendNoOp is a send function that discards messages — useful for tests that only exercise the answer/timeout path.

Types

type Dispatcher

type Dispatcher interface {
	Dispatch(ctx context.Context, input string) (output string, handled bool, err error)
}

Dispatcher routes slash commands locally, without a model round-trip. A Runner that also implements it gets command handling; one that does not behaves exactly as before, so the seam is additive.

handled is false for input the front-end should run as a normal turn.

type Model

type Model struct {
	// contains filtered or unexported fields
}

Model is the Bubble Tea model.

func New

func New(r Runner, system string) Model

New builds a Model driven by a Runner. The caller pushes StreamMsg and ToolResultMsg via program.Send, and calls WithAnswer to wire the permission-prompt reply channel.

func (Model) Init

func (m Model) Init() tea.Cmd

Init has nothing to start — the program.Send bridge drives all messages.

func (Model) Update

func (m Model) Update(msg tea.Msg) (tea.Model, tea.Cmd)

Update handles streamed events, tool results, prompts, keys, and sizing.

func (Model) View

func (m Model) View() string

View renders the transcript, an optional permission prompt, and the input.

func (Model) WithAnswer

func (m Model) WithAnswer(ch chan bool) Model

WithAnswer returns a copy of the model with the permission-prompt reply channel set (shared with the Prompter).

func (Model) WithTheme

func (m Model) WithTheme(p Palette) Model

WithTheme returns a copy of the model using the given palette (functional, like WithAnswer). The initial theme comes from config in New; this is the runtime switch path (T-1715).

type NoticeMsg

type NoticeMsg struct {
	Text string
}

NoticeMsg is a session-level event the user needs to see but that is not conversation: context was compacted, a checkpoint failed. Sent via program.Send so it lands in the transcript in order.

type Palette

type Palette struct {
	Name       string
	Background string // base background
	Text       string // default body text
	Prompt     string // permission / prompt line
	Working    string // busy indicator (dim; NOT contrast-gated — secondary text)
	User       string // user input echo
	Assistant  string // assistant text
	Error      string // errors
	Accent     string // accents
}

Palette is a set of semantic color roles. The model references roles, never raw literals; a palette maps roles to hex colors. Adding a role is one field here.

func Default

func Default() Palette

Default is the universal colorblind-safe palette: bright pastels on a dark ground, distinguishable by luminance as well as hue, with NO red/green pair (the deutan/protan collapse). Active on a fresh session (T-1711).

func PaletteByName

func PaletteByName(name string) (Palette, bool)

PaletteByName returns the named palette and ok=false if unknown.

func Palettes

func Palettes() []Palette

Palettes returns every shipped palette.

func ResolveTheme

func ResolveTheme(name string) (Palette, string)

ResolveTheme maps a configured theme name to a palette. An empty name selects the default silently. An unknown name also selects the default but returns a non-empty warning naming it and listing the valid ones — appearance is never worth failing a session over, but a typo must not be swallowed either.

func (Palette) PromptStyle

func (p Palette) PromptStyle() lipgloss.Style

PromptStyle renders the permission / prompt line.

func (Palette) WorkingStyle

func (p Palette) WorkingStyle() lipgloss.Style

WorkingStyle renders the busy indicator (dim). Working is the only role allowed to drop below the AA floor — it is secondary text.

type Prompter

type Prompter struct {
	// contains filtered or unexported fields
}

Prompter implements policy.Prompter for the TUI. On Ask it pushes a promptMsg into the program (via send) and blocks on the answer channel until the user presses y/n, or until ctx is done (the forced-ask timeout).

func NewPrompter

func NewPrompter(send func(tea.Msg), answer <-chan bool) *Prompter

NewPrompter builds a Prompter. send is typically the *tea.Program's Send; answer is the channel shared with the model (via WithAnswer).

func (*Prompter) Ask

func (p *Prompter) Ask(ctx context.Context, call ports.ToolCall) (bool, error)

Ask surfaces the call as a prompt and blocks for the user's decision.

type Runner

type Runner interface {
	Run(ctx context.Context, input string, history []ports.Message) ([]ports.Message, error)
}

Runner drives one turn to completion. The runtime's Session implements it; the TUI depends on this seam rather than on the agent loop, so context assembly (memory, skills, budgeting) stays outside the front-end.

type StreamMsg

type StreamMsg ports.Event

StreamMsg wraps one streamed ports.Event (sent via program.Send).

type ThemeControl

type ThemeControl struct {
	// contains filtered or unexported fields
}

ThemeControl is the front-end side of the runtime's theme seam (T-1718). The palette itself lives in the Bubble Tea model, which only the program's own goroutine may touch, so switching is a message send; ThemeControl keeps the active name so a command can report it without reaching into the model.

It is safe for concurrent use: /theme runs on the command goroutine while the program renders on its own.

func NewThemeControl

func NewThemeControl(send func(tea.Msg), initial string) *ThemeControl

NewThemeControl returns a control that switches the theme by sending into the program (pass program.Send). initial is the palette the model started with.

func (*ThemeControl) SetTheme

func (c *ThemeControl) SetTheme(name string) error

SetTheme validates the name and sends the switch into the program. An unknown name is refused without sending, so a typo cannot blank the screen.

func (*ThemeControl) Theme

func (c *ThemeControl) Theme() string

Theme reports the active palette's name.

func (*ThemeControl) ThemeNames

func (c *ThemeControl) ThemeNames() []string

ThemeNames lists the selectable palettes.

type ToolResultMsg

type ToolResultMsg struct {
	Call   ports.ToolCall
	Result ports.Block
}

ToolResultMsg carries a tool call + its neutral result block (sent via program.Send from the agent's OnToolResult hook).

Jump to

Keyboard shortcuts

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