tui

package
v0.0.26 Latest Latest
Warning

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

Go to latest
Published: Apr 23, 2026 License: MIT Imports: 47 Imported by: 0

Documentation

Overview

Package tui implements the interactive terminal UI using Bubble Tea v2.

Index

Constants

View Source
const DefaultThemeName = "tokyo-night"

DefaultThemeName is the default theme when none is configured.

View Source
const SidebarWidth = 30

SidebarWidth is the fixed width of the right sidebar.

Variables

This section is empty.

Functions

func GenerateCommitMsgFunc

func GenerateCommitMsgFunc(llm llmmodel.LLM) func(ctx context.Context, diffs string) (string, error)

GenerateCommitMsgFunc creates a function that generates commit messages using the given LLM.

func RenderSidebar added in v0.0.11

func RenderSidebar(in SidebarRenderInput) string

RenderSidebar renders the right sidebar panel.

func Run

func Run(ctx context.Context, cfg Config) error

Run starts the interactive TUI.

Types

type AgentMood added in v0.0.11

type AgentMood int

AgentMood represents the current emotional state of the agent.

const (
	MoodIdle       AgentMood = iota // Default waiting state
	MoodThinking                    // Processing/reasoning
	MoodProcessing                  // Tool execution
	MoodToolCall                    // About to call a tool
	MoodSpeaking                    // Producing text output
	MoodHappy                       // Task completed successfully
	MoodSad                         // Error or task failed
)

func (AgentMood) Eyes added in v0.0.11

func (m AgentMood) Eyes() string

Eyes returns the eyes string for this mood.

func (AgentMood) Mascot added in v0.0.17

func (m AgentMood) Mascot() string

Mascot returns the full mascot face for this mood.

func (AgentMood) String added in v0.0.11

func (m AgentMood) String() string

String returns a human-readable name for the mood.

type AgentSubEvent

type AgentSubEvent struct {
	AgentID    string
	Kind       string // "tool_call", "tool_result", "text_delta", etc.
	Content    string
	PipelineID string // groups agents in same call
	Mode       string // "single", "parallel", "chain"
	Step       int    // 1-based position in pipeline
	Total      int    // total agents in pipeline
}

AgentSubEvent carries a subagent event from the agent tool to the TUI.

type Breakpoint added in v0.0.10

type Breakpoint int

Breakpoint represents terminal width categories.

const (
	BreakpointNarrow Breakpoint = iota // < 60 cols
	BreakpointNormal                   // 60-100 cols
	BreakpointWide                     // > 100 cols
)

type ChatModel added in v0.0.10

type ChatModel struct {
	Messages    []message
	Scroll      int // scroll offset from bottom
	Streaming   string
	Thinking    string
	Renderer    *glamour.TermRenderer
	TraceLog    []traceEntry
	Width       int
	ToolDisplay ToolDisplayModel
}

ChatModel manages the conversation message display, scrolling, and markdown rendering.

func NewChatModel added in v0.0.10

func NewChatModel(renderer *glamour.TermRenderer) ChatModel

NewChatModel creates a ChatModel with the given markdown renderer.

func (*ChatModel) AppendWarning added in v0.0.11

func (c *ChatModel) AppendWarning(text string)

AppendWarning adds a warning message styled with yellow text.

func (*ChatModel) Clear added in v0.0.10

func (c *ChatModel) Clear()

Clear removes all messages and resets scroll.

func (*ChatModel) MaxScroll added in v0.0.10

func (c *ChatModel) MaxScroll(height int) int

MaxScroll returns the maximum scroll offset for the given terminal height.

func (*ChatModel) RenderMarkdown added in v0.0.10

func (c *ChatModel) RenderMarkdown(text string) string

RenderMarkdown renders text as markdown using the glamour renderer. It first expands markdown links (like [text](url)) into inline format when the link has both a display name and an actual file:// or http:// URL.

func (*ChatModel) RenderMessages added in v0.0.10

func (c *ChatModel) RenderMessages(running bool) string

RenderMessages renders all messages into a string for display.

func (*ChatModel) ResetScroll added in v0.0.10

func (c *ChatModel) ResetScroll()

ResetScroll resets the scroll offset to bottom.

func (*ChatModel) ScrollDown added in v0.0.10

func (c *ChatModel) ScrollDown(n int)

ScrollDown scrolls down by n lines, clamped to 0.

func (*ChatModel) ScrollUp added in v0.0.10

func (c *ChatModel) ScrollUp(n, height int)

ScrollUp scrolls up by n lines, clamped to max.

func (*ChatModel) UpdateRenderer added in v0.0.10

func (c *ChatModel) UpdateRenderer(width int)

UpdateRenderer recreates the glamour renderer for the given terminal width.

type ChecklistStep added in v0.0.14

type ChecklistStep struct {
	Title string
	Done  bool
}

ChecklistStep represents a single step from the plan.md checklist.

type CompactStatsProvider added in v0.0.4

type CompactStatsProvider interface {
	FormatStats() string
}

CompactStatsProvider provides compaction statistics for TUI display.

type CompleteResult

type CompleteResult struct {
	Candidates []CompletionCandidate
	Selected   int
	Type       CompletionType
}

CompleteResult holds all completion results.

func Complete

func Complete(input string, skills []extension.Skill, workDir string) *CompleteResult

Complete returns completion candidates for the given input. It analyzes the input and returns all matching options for commands, skills, and specs.

func CompleteMention added in v0.0.10

func CompleteMention(prefix string, workDir string) *CompleteResult

CompleteMention returns file completion candidates for the given prefix.

func (*CompleteResult) ApplySelection

func (r *CompleteResult) ApplySelection(index int) string

ApplySelection returns the text of the candidate at the given index.

func (*CompleteResult) CycleSelection

func (r *CompleteResult) CycleSelection(dir int)

CycleSelection moves the selection index in the given direction. dir should be 1 for next, -1 for previous.

func (*CompleteResult) SelectedCandidate

func (r *CompleteResult) SelectedCandidate() *CompletionCandidate

SelectedCandidate returns the currently selected candidate.

type CompletionCandidate

type CompletionCandidate struct {
	Text        string
	Description string
	Type        CompletionType
}

CompletionCandidate represents a single completion option.

type CompletionType

type CompletionType int

CompletionType identifies what kind of completion to perform.

const (
	CompletionTypeNone CompletionType = iota
	CompletionTypeCommand
	CompletionTypeSkill
	CompletionTypeSpec
	CompletionTypeFile
)

type Config

type Config struct {
	Agent          *agent.Agent
	LLM            llmmodel.LLM // The active LLM, used by /ping.
	SessionID      string
	ModelName      string
	ProviderName   string
	ActiveRole     string
	Roles          map[string]config.RoleConfig
	SessionService *pisession.FileService
	WorkDir        string
	Orchestrator   *subagent.Orchestrator
	// GenerateCommitMsg is called by /commit to generate a conventional commit message from diffs.
	// If nil, /commit is disabled.
	GenerateCommitMsg func(ctx context.Context, diffs string) (string, error)
	// Logger is the session logger. If nil, logging is disabled.
	Logger *logger.Logger
	// Skills is loaded from skill directories for command completion.
	Skills []extension.Skill
	// SkillDirs are the directories to re-scan for skills on each completion.
	SkillDirs []string
	// AgentEventCh receives subagent events from the agent tool for live display.
	AgentEventCh <-chan AgentSubEvent
	// TokenTracker tracks daily token usage and enforces limits. May be nil.
	TokenTracker TokenTracker
	// CompactMetrics tracks output compaction statistics. May be nil.
	CompactMetrics CompactStatsProvider
	// ThemeName is the configured theme name from config. Empty or "default" uses tokyo-night.
	ThemeName string

	// DeferredInit, if non-nil, is a channel of InitEvent messages.
	// When set, the TUI starts immediately in loading state and receives
	// initialization progress updates. The final event carries the fully
	// initialized subsystems in its Result field.
	DeferredInit <-chan InitEvent

	// MCPToolsets holds the live MCP toolsets, used by /mcp to show status.
	MCPToolsets []adktool.Toolset
	// MCPServers holds the configured MCP server definitions.
	MCPServers []extension.MCPServerConfig
}

Config holds configuration for the TUI.

type FaceRenderer added in v0.0.11

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

FaceRenderer tracks the agent's current mood (thread-safe).

func NewFaceRenderer added in v0.0.11

func NewFaceRenderer() *FaceRenderer

NewFaceRenderer creates a new face renderer with default idle mood.

func (*FaceRenderer) Eyes added in v0.0.11

func (f *FaceRenderer) Eyes() string

Eyes returns the eyes string for the current mood.

func (*FaceRenderer) GetMood added in v0.0.11

func (f *FaceRenderer) GetMood() AgentMood

GetMood returns the current mood.

func (*FaceRenderer) Mascot added in v0.0.17

func (f *FaceRenderer) Mascot() string

Mascot returns the full mascot face for the current mood.

func (*FaceRenderer) SetMood added in v0.0.11

func (f *FaceRenderer) SetMood(mood AgentMood)

SetMood changes the agent's current mood.

type Gate

type Gate struct {
	Name    string
	Command string
}

Gate represents a validation command parsed from the ## Gates section of PROMPT.md.

type GateResult

type GateResult struct {
	Name    string
	Command string
	Passed  bool
	Output  string
}

GateResult holds the result of running a single gate command.

type HistoryEntry added in v0.0.10

type HistoryEntry struct {
	Text     string   `json:"text"`
	Mentions []string `json:"mentions,omitempty"`
}

HistoryEntry stores a single prompt with its full input state.

type InitEvent added in v0.0.11

type InitEvent struct {
	Item   string      // subsystem name (e.g. "lsp", "memory", "mcp")
	Done   bool        // true when this item finished loading
	Result *InitResult // set on the final event when all init is complete
	Err    error       // fatal initialization error
}

InitEvent reports progress from deferred initialization.

type InitResult added in v0.0.11

type InitResult struct {
	Agent             *agent.Agent
	SessionID         string
	SessionService    *pisession.FileService
	Orchestrator      *subagent.Orchestrator
	Logger            *logger.Logger
	Skills            []extension.Skill
	SkillDirs         []string
	GenerateCommitMsg func(context.Context, string) (string, error)
	AgentEventCh      <-chan AgentSubEvent
	TokenTracker      TokenTracker
	CompactMetrics    CompactStatsProvider
	GitBranch         string
	DiffAdded         int
	DiffRemoved       int
	// MCPToolsets holds the live MCP toolsets for /mcp status display.
	MCPToolsets []adktool.Toolset
	// MCPServers holds the configured MCP server definitions.
	MCPServers []extension.MCPServerConfig
}

InitResult holds the fully initialized subsystems delivered by deferred init.

type InputModel added in v0.0.10

type InputModel struct {
	Text       string
	CursorPos  int // character position (not byte offset)
	History    []HistoryEntry
	HistoryIdx int

	// Ghost autocomplete suggestion.
	Completion string

	// Enhanced completion state.
	CompletionResult *CompleteResult
	CompletionMode   bool
	SelectedIndex    int

	// Command cycling state.
	CyclingIdx int

	// File @mention completion state.
	MentionMode          bool
	MentionStart         int // cursor position of the '@' character
	MentionResult        *CompleteResult
	MentionSelectedIndex int

	// Dependencies (set by root model).
	Skills    []extension.Skill
	SkillDirs []string
	WorkDir   string
}

InputModel manages the text input area: cursor, history, and completion.

func NewInputModel added in v0.0.10

func NewInputModel(history []HistoryEntry, skills []extension.Skill, skillDirs []string, workDir string) InputModel

NewInputModel creates an InputModel with initial state.

func (*InputModel) AllCommandNames added in v0.0.10

func (im *InputModel) AllCommandNames() []string

AllCommandNames returns a sorted list of all command names: built-in + skills.

func (*InputModel) Clear added in v0.0.10

func (im *InputModel) Clear()

Clear resets the input text and cursor.

func (*InputModel) DismissCompletion added in v0.0.10

func (im *InputModel) DismissCompletion()

DismissCompletion clears completion/cycling/mention state and input.

func (*InputModel) HandleKey added in v0.0.10

func (im *InputModel) HandleKey(msg tea.KeyPressMsg) tea.Cmd

HandleKey processes a key press for the input area. Returns a tea.Cmd (InputSubmitMsg on submit, nil otherwise).

func (*InputModel) InCompletionMode added in v0.0.10

func (im *InputModel) InCompletionMode() bool

InCompletionMode returns true if the input is showing a completion, cycling, or mention menu.

func (*InputModel) InsertText added in v0.0.10

func (im *InputModel) InsertText(text string)

InsertText inserts pasted or programmatic text at cursor position.

func (*InputModel) ReloadSkills added in v0.0.10

func (im *InputModel) ReloadSkills()

ReloadSkills re-scans skill directories from disk and updates the cached list.

func (*InputModel) View added in v0.0.10

func (im *InputModel) View(running bool) string

View renders the input area.

type InputSubmitMsg added in v0.0.10

type InputSubmitMsg struct {
	Text     string
	Mentions []string // file paths referenced via @path
}

InputSubmitMsg is emitted when the user presses Enter with non-empty input.

type Layout added in v0.0.10

type Layout struct {
	Width      int
	Height     int
	Breakpoint Breakpoint
}

Layout holds terminal dimensions and the computed breakpoint.

func NewLayout added in v0.0.10

func NewLayout(w, h int) Layout

NewLayout creates a Layout from terminal dimensions.

func (Layout) ChatWidth added in v0.0.10

func (l Layout) ChatWidth() int

ChatWidth returns the available width for chat message content.

func (Layout) IsNarrow added in v0.0.10

func (l Layout) IsNarrow() bool

IsNarrow returns true if the terminal is in narrow mode.

func (Layout) MaxPathLen added in v0.0.10

func (l Layout) MaxPathLen() int

MaxPathLen returns the maximum path display length for the current breakpoint.

func (Layout) SeparatorWidth added in v0.0.10

func (l Layout) SeparatorWidth() int

SeparatorWidth returns the width for horizontal separators.

func (Layout) StatusWidth added in v0.0.10

func (l Layout) StatusWidth() int

StatusWidth returns the available width for the status bar content.

func (Layout) TruncatePath added in v0.0.10

func (l Layout) TruncatePath(path string, max int) string

TruncatePath shortens a file path to fit within max characters. It preserves the filename and as much of the leading path as possible, inserting "..." when truncation is needed.

type SidebarRenderInput added in v0.0.11

type SidebarRenderInput struct {
	Width        int
	Height       int
	Eyes         string
	Mascot       string // full 3-line mascot face (mutually exclusive with Eyes)
	Mode         string
	ProviderName string
	ModelName    string
	GitBranch    string
	DiffAdded    int
	DiffRemoved  int
	Running      bool
	TokenTracker TokenTracker
	Messages     []message
	ActiveTool   string
	LoadingItems map[string]bool
	RunChecklist []ChecklistStep          // steps from plan.md during /run
	RunPhase     string                   // current /run phase (empty if not running)
	RunSpec      string                   // spec name during /run
	RunCycle     int                      // current retry cycle
	RunMaxCycle  int                      // max retries
	MatrixLines  string                   // pre-rendered matrix rain (2 lines)
	StatusLine   string                   // status text shown above matrix
	Orchestrator *subagent.Orchestrator   // may be nil — for agents section
	MCPTools     []extension.MCPToolEntry // MCP tools section; nil = hidden
	OTELEnabled  bool                     // OTEL tracing is active
}

SidebarRenderInput provides data needed by the sidebar.

type StatusModel added in v0.0.10

type StatusModel struct {
	// GitBranch is the current git branch (detected at startup).
	GitBranch string
	// ActiveTool is the name of the currently executing tool (single).
	ActiveTool string
	// ActiveTools tracks parallel tool execution: name → start time.
	ActiveTools map[string]time.Time
	// ToolStart is when the current single tool started.
	ToolStart time.Time
	// Width is the terminal width for rendering.
	Width int
}

StatusModel manages the status bar display at the bottom of the TUI.

func (*StatusModel) Render added in v0.0.10

func (s *StatusModel) Render(in StatusRenderInput) string

Render renders the status bar string.

type StatusRenderInput added in v0.0.10

type StatusRenderInput struct {
	ProviderName string
	ModelName    string
	Running      bool
	Mode         string       // "chat" or "plan"
	Eyes         string       // mood eyes e.g. "◕ ◕"
	Messages     []message    // for context estimate
	TokenTracker TokenTracker // may be nil
	DiffAdded    int
	DiffRemoved  int
	RunCycle     *runCycleInfo   // may be nil
	LoadingItems map[string]bool // item -> done; nil means not loading
}

StatusRenderInput provides data from other models needed by the status bar.

type Theme added in v0.0.10

type Theme struct {
	Name        string      `json:"name"`
	DisplayName string      `json:"displayName"`
	ThemeType   string      `json:"themeType"`
	Colors      ThemeColors `json:"colors"`
}

Theme represents a loaded color theme.

type ThemeColors added in v0.0.10

type ThemeColors struct {
	Text            string `json:"text"`
	Base            string `json:"base"`
	Primary         string `json:"primary"`
	Tool            string `json:"tool"`
	Success         string `json:"success"`
	Error           string `json:"error"`
	Secondary       string `json:"secondary"`
	Info            string `json:"info"`
	Warning         string `json:"warning"`
	DiffAdded       string `json:"diffAdded"`
	DiffRemoved     string `json:"diffRemoved"`
	DiffAddedText   string `json:"diffAddedText"`
	DiffRemovedText string `json:"diffRemovedText"`
}

ThemeColors holds the 13 color roles used throughout the TUI. Colors are stored as hex strings and converted to color.Color via lipgloss.Color().

func (ThemeColors) BaseColor added in v0.0.10

func (c ThemeColors) BaseColor() color.Color

func (ThemeColors) DiffAddedColor added in v0.0.10

func (c ThemeColors) DiffAddedColor() color.Color

func (ThemeColors) DiffAddedTextColor added in v0.0.10

func (c ThemeColors) DiffAddedTextColor() color.Color

func (ThemeColors) DiffRemovedColor added in v0.0.10

func (c ThemeColors) DiffRemovedColor() color.Color

func (ThemeColors) DiffRemovedTextColor added in v0.0.10

func (c ThemeColors) DiffRemovedTextColor() color.Color

func (ThemeColors) ErrorColor added in v0.0.10

func (c ThemeColors) ErrorColor() color.Color

func (ThemeColors) InfoColor added in v0.0.10

func (c ThemeColors) InfoColor() color.Color

func (ThemeColors) PrimaryColor added in v0.0.10

func (c ThemeColors) PrimaryColor() color.Color

func (ThemeColors) SecondaryColor added in v0.0.10

func (c ThemeColors) SecondaryColor() color.Color

func (ThemeColors) SuccessColor added in v0.0.10

func (c ThemeColors) SuccessColor() color.Color

func (ThemeColors) TextColor added in v0.0.10

func (c ThemeColors) TextColor() color.Color

func (ThemeColors) ToolColor added in v0.0.10

func (c ThemeColors) ToolColor() color.Color

func (ThemeColors) WarningColor added in v0.0.10

func (c ThemeColors) WarningColor() color.Color

type ThemeManager added in v0.0.10

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

ThemeManager manages theme loading, selection, and color access.

func NewThemeManager added in v0.0.10

func NewThemeManager() *ThemeManager

NewThemeManager creates a ThemeManager with all embedded themes loaded. Falls back to pi-classic if the embedded JSON is corrupt.

func NewThemeManagerFromJSON added in v0.0.10

func NewThemeManagerFromJSON(data []byte) (*ThemeManager, error)

NewThemeManagerFromJSON creates a ThemeManager from custom JSON data.

func (*ThemeManager) ClosestMatches added in v0.0.10

func (tm *ThemeManager) ClosestMatches(query string, max int) []string

ClosestMatches returns theme names that contain the given substring, useful for suggesting alternatives when a theme isn't found.

func (*ThemeManager) Colors added in v0.0.10

func (tm *ThemeManager) Colors() ThemeColors

Colors returns the current theme's color palette.

func (*ThemeManager) Current added in v0.0.10

func (tm *ThemeManager) Current() Theme

Current returns the active theme.

func (*ThemeManager) CurrentName added in v0.0.10

func (tm *ThemeManager) CurrentName() string

CurrentName returns the name of the active theme.

func (*ThemeManager) HasTheme added in v0.0.10

func (tm *ThemeManager) HasTheme(name string) bool

HasTheme returns true if a theme with the given name exists.

func (*ThemeManager) IsDark added in v0.0.10

func (tm *ThemeManager) IsDark() bool

IsDark returns true if the current theme is a dark theme.

func (*ThemeManager) List added in v0.0.10

func (tm *ThemeManager) List() []Theme

List returns all available themes sorted by name.

func (*ThemeManager) SetTheme added in v0.0.10

func (tm *ThemeManager) SetTheme(name string) error

SetTheme changes the active theme. Returns an error if the theme doesn't exist.

func (*ThemeManager) ThemeCount added in v0.0.10

func (tm *ThemeManager) ThemeCount() int

ThemeCount returns the number of loaded themes.

type TokenTracker added in v0.0.4

type TokenTracker interface {
	Limit() int64
	Remaining() int64     // -1 if unlimited
	PercentUsed() float64 // 0-100+
	TotalUsed() int64     // total tokens consumed today

	// Session context window tracking.
	LastPromptTokens() int64     // most recent prompt tokens from LLM response
	ContextWindowSize() int64    // model's context window size (0 = unknown)
	ContextPercentUsed() float64 // context window usage 0-100+
}

TokenTracker provides read access to daily token usage for the status bar.

type ToolDisplayModel added in v0.0.10

type ToolDisplayModel struct {
	// Width is the terminal width for rendering.
	Width int
	// CompactTools when true shows one-line summaries instead of full output.
	CompactTools bool
}

ToolDisplayModel manages the formatting and rendering of tool call/result messages in the chat view. It owns per-tool formatters, syntax highlighting, and summary generation.

func (*ToolDisplayModel) RenderToolMessage added in v0.0.10

func (t *ToolDisplayModel) RenderToolMessage(msg message) string

RenderToolMessage renders a tool message (role=="tool") into a styled string. It handles both agent/subagent tools (with event streams) and regular tools (with syntax-highlighted output). When CompactTools is true, renders a one-line summary instead of full output.

Directories

Path Synopsis
Package refs implements context reference expansion for the TUI.
Package refs implements context reference expansion for the TUI.

Jump to

Keyboard shortcuts

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