ui

package
v0.0.32 Latest Latest
Warning

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

Go to latest
Published: Jan 16, 2026 License: MIT Imports: 29 Imported by: 0

Documentation

Index

Constants

View Source
const (
	EnabledIcon  = "●"
	DisabledIcon = "○"
	SuccessIcon  = "✓"
	FailIcon     = "✗"
)

Status indicators

View Source
const SomethingElse = "__something_else__"

Variables

View Source
var PresetThemeNames = []string{
	"gruvbox",
	"dracula",
	"nord",
	"solarized",
	"monokai",
	"classic",
}

PresetThemeNames defines the display order of themes

View Source
var PresetThemes = map[string]ThemePreset{
	"classic": {
		Name:        "classic",
		Description: "Classic green terminal style",
		Config: ThemeConfig{
			Primary:   "10",
			Secondary: "4",
			Success:   "10",
			Error:     "9",
			Warning:   "11",
			Muted:     "245",
			Text:      "15",
			Spinner:   "205",
		},
	},
	"dracula": {
		Name:        "dracula",
		Description: "Popular dark theme with purple accents",
		Config: ThemeConfig{
			Primary:   "#bd93f9",
			Secondary: "#8be9fd",
			Success:   "#50fa7b",
			Error:     "#ff5555",
			Warning:   "#f1fa8c",
			Muted:     "#6272a4",
			Text:      "#f8f8f2",
			Spinner:   "#ff79c6",
		},
	},
	"nord": {
		Name:        "nord",
		Description: "Arctic, north-bluish color palette",
		Config: ThemeConfig{
			Primary:   "#88c0d0",
			Secondary: "#81a1c1",
			Success:   "#a3be8c",
			Error:     "#bf616a",
			Warning:   "#ebcb8b",
			Muted:     "#4c566a",
			Text:      "#eceff4",
			Spinner:   "#b48ead",
		},
	},
	"solarized": {
		Name:        "solarized",
		Description: "Precision colors for machines and people",
		Config: ThemeConfig{
			Primary:   "#268bd2",
			Secondary: "#2aa198",
			Success:   "#859900",
			Error:     "#dc322f",
			Warning:   "#b58900",
			Muted:     "#586e75",
			Text:      "#839496",
			Spinner:   "#d33682",
		},
	},
	"monokai": {
		Name:        "monokai",
		Description: "Vibrant colors inspired by Sublime Text",
		Config: ThemeConfig{
			Primary:   "#a6e22e",
			Secondary: "#66d9ef",
			Success:   "#a6e22e",
			Error:     "#f92672",
			Warning:   "#e6db74",
			Muted:     "#75715e",
			Text:      "#f8f8f2",
			Spinner:   "#ae81ff",
		},
	},
	"gruvbox": {
		Name:        "gruvbox",
		Description: "Retro groove color scheme (default)",
		Config: ThemeConfig{
			Primary:   "#b8bb26",
			Secondary: "#83a598",
			Success:   "#b8bb26",
			Error:     "#fb4934",
			Warning:   "#fabd2f",
			Muted:     "#928374",
			Text:      "#ebdbb2",
			Spinner:   "#d3869b",
		},
	},
}

PresetThemes contains all predefined themes

Functions

func ANSILen added in v0.0.6

func ANSILen(s string) int

ANSILen returns the display width of a string, ignoring ANSI codes

func CalcDiffWidth added in v0.0.5

func CalcDiffWidth(oldContent, newContent string) int

CalcDiffWidth calculates the required padding width for a diff The result is capped to the terminal-aware max content width

func ErrorCircle added in v0.0.26

func ErrorCircle() string

ErrorCircle returns the error status indicator

func GetPendingToolTextLen added in v0.0.26

func GetPendingToolTextLen(segments []Segment) int

GetPendingToolTextLen returns the text length of the first pending tool (for wave animation)

func GetRefinement

func GetRefinement() (string, error)

GetRefinement prompts the user for additional guidance

func GlamourStyle added in v0.0.31

func GlamourStyle() ansi.StyleConfig

GlamourStyle returns a glamour StyleConfig based on the current theme

func GlamourStyleFromTheme added in v0.0.31

func GlamourStyleFromTheme(theme *Theme) ansi.StyleConfig

GlamourStyleFromTheme creates a glamour StyleConfig from the given theme

func HasDiff added in v0.0.10

func HasDiff(oldContent, newContent string) bool

HasDiff returns true if old and new content are different

func HasPendingTool added in v0.0.26

func HasPendingTool(segments []Segment) bool

HasPendingTool returns true if any segment has a pending tool

func InitTheme

func InitTheme(cfg ThemeConfig)

InitTheme initializes the theme from config

func MatchPresetTheme added in v0.0.31

func MatchPresetTheme(cfg ThemeConfig) string

MatchPresetTheme finds a preset that matches the given config, or returns empty string

func PendingCircle added in v0.0.26

func PendingCircle() string

PendingCircle returns the pending status indicator

func PrintCompactDiff added in v0.0.5

func PrintCompactDiff(filePath, oldContent, newContent string, padWidth int)

PrintCompactDiff prints a compact diff with 2 lines of context and line numbers padWidth specifies the total line width for consistent backgrounds across diffs

func PrintUnifiedDiff added in v0.0.10

func PrintUnifiedDiff(filePath, oldContent, newContent string)

PrintUnifiedDiff prints a clean unified diff between old and new content If multiFile is true, shows the filename header (for multi-file diffs)

func PrintUnifiedDiffMulti added in v0.0.10

func PrintUnifiedDiffMulti(filePath, oldContent, newContent string)

PrintUnifiedDiffMulti prints a diff with filename header (for multi-file edits)

func PromptApplyEdit added in v0.0.5

func PromptApplyEdit() bool

PromptApplyEdit asks the user whether to apply an edit Returns true if user wants to apply (Enter or y), false to skip (n)

func RenderSegments added in v0.0.26

func RenderSegments(segments []Segment, width int, wavePos int, renderMarkdown func(string, int) string) string

RenderSegments renders a list of segments with proper spacing. This is the main entry point for rendering the stream content. renderMarkdown should be a function that renders markdown content.

func RenderToolSegment added in v0.0.26

func RenderToolSegment(seg *Segment, wavePos int) string

RenderToolSegment renders a tool segment with its status indicator. For pending tools, wavePos controls the wave animation (-1 = paused/all dim). Tool name is rendered normally, params are rendered in slightly muted gray.

func RenderWaveText added in v0.0.26

func RenderWaveText(text string, wavePos int) string

RenderWaveText renders text with a wave animation effect using bold highlighting. wavePos is the position of the bright "peak" traveling through the text. If wavePos < 0, we're in the pause phase - show all dim.

func RunSetupWizard

func RunSetupWizard() (*config.Config, error)

RunSetupWizard runs the first-time setup wizard and returns the config

func RunWithSpinner

func RunWithSpinner(ctx context.Context, debug bool, run func(context.Context) (any, error)) (any, error)

RunWithSpinner shows a spinner while executing the provided function.

func RunWithSpinnerProgress added in v0.0.11

func RunWithSpinnerProgress(ctx context.Context, debug bool, progress <-chan ProgressUpdate, run func(context.Context) (any, error)) (any, error)

RunWithSpinnerProgress shows a spinner with progress updates while executing the provided function. The progress channel can receive updates with token counts, status messages, and milestones.

func RunWithSpinnerProgressAndHooks added in v0.0.26

func RunWithSpinnerProgressAndHooks(ctx context.Context, debug bool, progress <-chan ProgressUpdate, run func(context.Context) (any, error), setupHooks ApprovalHookSetup) (any, error)

RunWithSpinnerProgressAndHooks is like RunWithSpinnerProgress but also sets up approval hooks. The setupHooks function is called with pause/resume functions that should be used to set up tools.SetApprovalHooks() so the spinner pauses during tool approval prompts.

func SelectCommand

func SelectCommand(suggestions []llm.CommandSuggestion, shell string, engine *llm.Engine, allowNonTTY bool) (selected string, refinement string, err error)

SelectCommand presents the user with a list of command suggestions and returns the selected one. Returns the selected command or SomethingElse if user wants to refine their request. When SomethingElse is returned, the second return value contains the user's refinement text. If engine is non-nil and user presses 'i', shows help for the highlighted command. allowNonTTY permits a non-interactive fallback when no TTY is available.

func SetTheme

func SetTheme(t *Theme)

SetTheme sets the current active theme

func ShowCommand

func ShowCommand(cmd string)

ShowCommand displays the command that will be executed (to stderr, keeping stdout clean)

func ShowCommandHelp

func ShowCommandHelp(command, shell string, engine *llm.Engine) error

ShowCommandHelp renders scrollable help for a command

func ShowEditInfo added in v0.0.10

func ShowEditInfo(aboutText string)

ShowEditInfo displays the about/info text in a fullscreen pager

func ShowEditSkipped added in v0.0.5

func ShowEditSkipped(filePath string, reason string)

ShowEditSkipped shows that an edit was skipped

func ShowError

func ShowError(msg string)

ShowError displays an error message

func StripANSI added in v0.0.6

func StripANSI(s string) string

StripANSI removes all ANSI escape codes from a string

func SuccessCircle added in v0.0.26

func SuccessCircle() string

SuccessCircle returns the success status indicator

func Truncate

func Truncate(s string, maxLen int) string

Truncate shortens a string to maxLen with ellipsis

func WorkingCircle added in v0.0.29

func WorkingCircle() string

WorkingCircle returns the working status indicator

Types

type ApprovalHookSetup added in v0.0.26

type ApprovalHookSetup func(pause, resume func())

ApprovalHookSetup is called with functions to pause/resume the spinner. It should set up approval hooks that call these functions.

type EditApprovalResult added in v0.0.10

type EditApprovalResult int

EditApprovalResult represents the result of batch approval prompt

const (
	EditApprovalYes  EditApprovalResult = iota // Apply all changes
	EditApprovalNo                             // Skip all changes
	EditApprovalInfo                           // Show info/about text
)

func PromptBatchApproval added in v0.0.10

func PromptBatchApproval(hasInfo bool, reprompt bool) EditApprovalResult

PromptBatchApproval asks user to approve all changes with option to see info Returns EditApprovalYes, EditApprovalNo, or EditApprovalInfo If reprompt is true, clears the line before showing prompt (used after returning from info)

type Highlighter added in v0.0.6

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

Highlighter handles syntax highlighting for diff display

func NewHighlighter added in v0.0.6

func NewHighlighter(filePath string) *Highlighter

NewHighlighter creates a highlighter for the given file path. Returns nil if the language is not recognized.

func (*Highlighter) HighlightLine added in v0.0.6

func (h *Highlighter) HighlightLine(line string) string

HighlightLine applies syntax highlighting to a line without a background color.

func (*Highlighter) HighlightLineWithBg added in v0.0.6

func (h *Highlighter) HighlightLineWithBg(line string, bg [3]int) string

HighlightLineWithBg applies syntax highlighting to a line with a specific background color. bg is an RGB array [r, g, b] for true color background.

type ProgressUpdate added in v0.0.11

type ProgressUpdate struct {
	// OutputTokens is the number of tokens generated so far.
	OutputTokens int

	// Status is the current status text (e.g., "editing main.go").
	Status string

	// Milestone is a completed milestone to print above the spinner
	// (e.g., "✓ Found edit for main.go").
	Milestone string

	// Phase is the current phase of the operation (e.g., "Thinking", "Responding").
	// Used to show state transitions in the spinner.
	Phase string
}

ProgressUpdate represents a progress update during long-running operations.

type Segment added in v0.0.26

type Segment struct {
	Type       SegmentType
	Text       string     // For text segments: markdown content
	Rendered   string     // For text segments: cached rendered markdown
	ToolName   string     // For tool segments
	ToolInfo   string     // For tool segments: additional context
	ToolStatus ToolStatus // For tool segments
	Complete   bool       // For text segments: whether streaming is complete
}

Segment represents a discrete unit in the response stream (text or tool)

func UpdateToolStatus added in v0.0.26

func UpdateToolStatus(segments []Segment, toolName, toolInfo string, success bool) []Segment

UpdateToolStatus updates the status of a pending tool matching the given name. We match by name only (not info) because a single tool execution may have multiple events with different info values (e.g., during permission approvals).

type SegmentType added in v0.0.26

type SegmentType int

SegmentType identifies the type of stream segment

const (
	SegmentText SegmentType = iota
	SegmentTool
)

type SessionStats added in v0.0.19

type SessionStats struct {
	StartTime         time.Time
	InputTokens       int
	OutputTokens      int
	CachedInputTokens int // Tokens read from cache
	ToolCallCount     int
	TurnCount         int // For multi-turn sessions (chat)

	// Time tracking
	LLMTime  time.Duration
	ToolTime time.Duration
	// contains filtered or unexported fields
}

SessionStats tracks statistics for a session.

func NewSessionStats added in v0.0.19

func NewSessionStats() *SessionStats

NewSessionStats creates a new SessionStats with StartTime set to now.

func (*SessionStats) AddTurn added in v0.0.19

func (s *SessionStats) AddTurn()

AddTurn increments the turn count.

func (*SessionStats) AddUsage added in v0.0.19

func (s *SessionStats) AddUsage(input, output, cached int)

AddUsage adds token usage to the stats.

func (*SessionStats) Finalize added in v0.0.19

func (s *SessionStats) Finalize()

Finalize records any remaining time.

func (SessionStats) Render added in v0.0.19

func (s SessionStats) Render() string

Render returns the stats as a compact single-line string.

func (*SessionStats) ToolEnd added in v0.0.19

func (s *SessionStats) ToolEnd()

ToolEnd marks the end of tool execution (back to LLM).

func (*SessionStats) ToolStart added in v0.0.19

func (s *SessionStats) ToolStart()

ToolStart marks the start of a tool execution.

type StreamingIndicator added in v0.0.15

type StreamingIndicator struct {
	Spinner        string // spinner.View() output
	Phase          string // "Thinking", "Searching", etc.
	Elapsed        time.Duration
	Tokens         int                      // 0 = don't show
	Status         string                   // optional status (e.g., "editing main.go")
	ShowCancel     bool                     // show "(esc to cancel)"
	Segments       []Segment                // active tool segments for wave animation
	WavePos        int                      // current wave position
	Width          int                      // terminal width for markdown rendering
	RenderMarkdown func(string, int) string // markdown renderer for text segments
}

StreamingIndicator renders a consistent streaming status line

func (StreamingIndicator) Render added in v0.0.15

func (s StreamingIndicator) Render(styles *Styles) string

Render returns the formatted streaming indicator string

type Styles

type Styles struct {

	// Text styles
	Title       lipgloss.Style
	Subtitle    lipgloss.Style
	Success     lipgloss.Style
	Error       lipgloss.Style
	Muted       lipgloss.Style
	Bold        lipgloss.Style
	Highlighted lipgloss.Style

	// Table styles
	TableHeader lipgloss.Style
	TableCell   lipgloss.Style
	TableBorder lipgloss.Style

	// UI element styles
	Spinner lipgloss.Style
	Command lipgloss.Style
	Footer  lipgloss.Style

	// Diff styles
	DiffAdd     lipgloss.Style // Added lines (+)
	DiffRemove  lipgloss.Style // Removed lines (-)
	DiffContext lipgloss.Style // Context lines (unchanged)
	DiffHeader  lipgloss.Style // Diff header (@@ ... @@)
	// contains filtered or unexported fields
}

Styles returns styled text helpers bound to a renderer

func DefaultStyles

func DefaultStyles() *Styles

DefaultStyles returns styles for stderr (default TUI output)

func NewStyledWithTheme

func NewStyledWithTheme(output *os.File, theme *Theme) *Styles

NewStyledWithTheme creates styles with a specific theme

func NewStyles

func NewStyles(output *os.File) *Styles

NewStyles creates a new Styles instance for the given output

func (*Styles) FormatEnabled

func (s *Styles) FormatEnabled(enabled bool) string

FormatEnabled returns a styled enabled/disabled indicator

func (*Styles) FormatResult

func (s *Styles) FormatResult(success bool, msg string) string

FormatResult returns a styled success/fail result

func (*Styles) Theme

func (s *Styles) Theme() *Theme

Theme returns the theme used by these styles

type Theme

type Theme struct {
	// Primary colors
	Primary   lipgloss.Color // main accent color (commands, highlights)
	Secondary lipgloss.Color // secondary accent (headers, borders)

	// Semantic colors
	Success lipgloss.Color // success states, enabled
	Error   lipgloss.Color // error states, disabled
	Warning lipgloss.Color // warnings
	Muted   lipgloss.Color // dimmed/secondary text
	Text    lipgloss.Color // primary text

	// UI element colors
	Spinner    lipgloss.Color // loading spinner
	Border     lipgloss.Color // borders and dividers
	Background lipgloss.Color // background (if needed)

	// Diff backgrounds
	DiffAddBg     lipgloss.Color // background for added lines
	DiffRemoveBg  lipgloss.Color // background for removed lines
	DiffContextBg lipgloss.Color // background for context lines
}

Theme defines the color palette for the UI

func DefaultTheme

func DefaultTheme() *Theme

DefaultTheme returns the default color theme (gruvbox)

func GetTheme

func GetTheme() *Theme

GetTheme returns the current active theme

func ThemeFromConfig

func ThemeFromConfig(cfg ThemeConfig) *Theme

ThemeFromConfig creates a theme with config overrides applied

type ThemeConfig

type ThemeConfig struct {
	Primary   string
	Secondary string
	Success   string
	Error     string
	Warning   string
	Muted     string
	Text      string
	Spinner   string
}

ThemeConfig mirrors the config.ThemeConfig for applying overrides

type ThemePreset added in v0.0.31

type ThemePreset struct {
	Name        string
	Description string
	Config      ThemeConfig
}

ThemePreset represents a predefined color theme

func GetPresetTheme added in v0.0.31

func GetPresetTheme(name string) *ThemePreset

GetPresetTheme returns a preset by name, or nil if not found

type ToolPhase added in v0.0.25

type ToolPhase struct {
	// Active is the phase text shown during execution (e.g., "web_search(cats)")
	Active string
	// Completed is the text shown after completion (e.g., "web_search(cats)")
	Completed string
}

ToolPhase contains display strings for a tool execution phase.

func FormatToolPhase added in v0.0.25

func FormatToolPhase(name, info string) ToolPhase

FormatToolPhase returns display strings for a tool based on name and preview info. Uses unified format: name + info (where info contains parenthesized args). Example: web_search(cats), read_file(/src/main.go)

type ToolStatus added in v0.0.26

type ToolStatus int

ToolStatus represents the execution state of a tool

const (
	ToolPending ToolStatus = iota
	ToolSuccess
	ToolError
)

type ToolTracker added in v0.0.30

type ToolTracker struct {
	Segments   []Segment
	WavePos    int
	WavePaused bool
}

ToolTracker manages tool segment state and wave animation. Designed to be embedded in larger models (ask, chat) for consistent tool tracking.

func NewToolTracker added in v0.0.30

func NewToolTracker() *ToolTracker

NewToolTracker creates a new ToolTracker

func (*ToolTracker) ActiveSegments added in v0.0.30

func (t *ToolTracker) ActiveSegments() []Segment

ActiveSegments returns only the pending tool segments (for rendering).

func (*ToolTracker) AddTextSegment added in v0.0.30

func (t *ToolTracker) AddTextSegment(text string) bool

AddTextSegment adds or appends to a text segment. Returns true if this created a new segment.

func (*ToolTracker) CompleteTextSegments added in v0.0.30

func (t *ToolTracker) CompleteTextSegments(renderFunc func(string) string)

CompleteTextSegments marks all incomplete text segments as complete.

func (*ToolTracker) CompletedSegments added in v0.0.30

func (t *ToolTracker) CompletedSegments() []Segment

CompletedSegments returns all non-pending segments (for rendering).

func (*ToolTracker) HandleToolEnd added in v0.0.30

func (t *ToolTracker) HandleToolEnd(toolName string, success bool)

HandleToolEnd updates the status of a pending tool.

func (*ToolTracker) HandleToolStart added in v0.0.30

func (t *ToolTracker) HandleToolStart(toolName, toolInfo string) bool

HandleToolStart adds a pending segment if none exists for this tool name. Returns true if a new segment was added (caller should start wave animation).

func (*ToolTracker) HandleWavePause added in v0.0.30

func (t *ToolTracker) HandleWavePause() tea.Cmd

HandleWavePause handles the end of a wave pause. Returns the next tick command if there are still pending tools.

func (*ToolTracker) HandleWaveTick added in v0.0.30

func (t *ToolTracker) HandleWaveTick() tea.Cmd

HandleWaveTick advances the wave animation. Returns the next command (tick, pause, or nil if no pending tools).

func (*ToolTracker) HasPending added in v0.0.30

func (t *ToolTracker) HasPending() bool

HasPending returns true if there are any pending tool segments.

func (*ToolTracker) MarkCurrentTextComplete added in v0.0.30

func (t *ToolTracker) MarkCurrentTextComplete(renderFunc func(string) string)

MarkCurrentTextComplete marks the current text segment as complete before a tool starts.

func (*ToolTracker) StartWave added in v0.0.30

func (t *ToolTracker) StartWave() tea.Cmd

StartWave initializes and starts the wave animation. Returns the command to start the tick cycle.

type WavePauseMsg added in v0.0.30

type WavePauseMsg struct{}

WavePauseMsg is sent when wave pause ends

type WaveTickMsg added in v0.0.30

type WaveTickMsg struct{}

WaveTickMsg is sent to advance the wave animation

Jump to

Keyboard shortcuts

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