Documentation
¶
Index ¶
- Constants
- Variables
- func FormatUserMessage(text string) string
- func New(ctx context.Context, cfg Config) appModel
- func ParseCommand(text string) (string, bool)
- func RebuildStyles()
- func RebuildUI()
- func RegisterLayout(name string, l Layout) error
- func SetLayout(name string) error
- func SetLayoutDirect(l Layout) error
- type Config
- type FlatLayout
- func (FlatLayout) RenderAssistantText(glamourRendered string, _ int) string
- func (FlatLayout) RenderError(text string, _ int, theme Theme) string
- func (FlatLayout) RenderLiveNotice(text string, width int, theme Theme) string
- func (FlatLayout) RenderStatus(text string, _ int, theme Theme) string
- func (FlatLayout) RenderThinking(text string, width int, theme Theme) string
- func (FlatLayout) RenderToolBlock(block ToolBlockData, width int, theme Theme) string
- func (FlatLayout) RenderUserMessage(text string, width int, theme Theme) string
- type Layout
- type PinnedModelChange
- type Segment
- type SplitLayout
- func (SplitLayout) RenderAssistantText(glamourRendered string, _ int) string
- func (SplitLayout) RenderError(text string, _ int, theme Theme) string
- func (SplitLayout) RenderLiveNotice(text string, width int, theme Theme) string
- func (SplitLayout) RenderStatus(text string, _ int, theme Theme) string
- func (SplitLayout) RenderThinking(text string, width int, theme Theme) string
- func (SplitLayout) RenderToolBlock(block ToolBlockData, width int, theme Theme) string
- func (SplitLayout) RenderUserMessage(text string, width int, theme Theme) string
- type StatusLine
- func (sl *StatusLine) Clear()
- func (sl *StatusLine) IsEmpty() bool
- func (sl *StatusLine) Remove(key string)
- func (sl *StatusLine) Set(key, text string, priority int)
- func (sl *StatusLine) UpdateCacheColdSegment(show bool)
- func (sl *StatusLine) UpdateCacheSegment(pct int)
- func (sl *StatusLine) UpdateContextSegment(pct int)
- func (sl *StatusLine) UpdateCostSegment(cost float64)
- func (sl *StatusLine) UpdateGoalSegment(label string)
- func (sl *StatusLine) UpdateMCPSegment(total, unhealthy, disabled int)
- func (sl *StatusLine) UpdateModelSegment(name string)
- func (sl *StatusLine) UpdateOverageSegment(onOverage bool)
- func (sl *StatusLine) UpdatePathScopeSegment(scope string)
- func (sl *StatusLine) UpdatePermissionsSegment(mode string)
- func (sl *StatusLine) UpdatePlanSegment(mode string)
- func (sl *StatusLine) UpdateQuotaSegment(labels []string, pcts []int)
- func (sl *StatusLine) UpdateTasksSegment(done, total int)
- func (sl *StatusLine) UpdateThinkingSegment(level string)
- func (sl *StatusLine) UpdateUsageExtraSegment(used float64, symbol string, enabled bool)
- func (sl *StatusLine) UpdateUsageMoneySegments(buckets []UsageMoney)
- func (sl *StatusLine) UpdateUsageSegment(fiveHPct, weekPct int)
- func (sl *StatusLine) UpdateUsageUnavailable(reason string)
- func (sl *StatusLine) UpdateVersionSegment(current, latest string)
- func (sl *StatusLine) View(width int) string
- type Theme
- type ToolBlockData
- type UsageMoney
Constants ¶
const ( SegmentModel = "model" SegmentThinking = "thinking" SegmentPermissions = "permissions" SegmentPathScope = "pathscope" SegmentPlan = "plan" SegmentGoal = "goal" SegmentTasks = "tasks" SegmentCost = "cost" SegmentCache = "cache" SegmentCacheCold = "cache_cold" // prompt cache has gone cold since last run SegmentContext = "context" SegmentMCP = "mcp" // configured MCP servers; red only when one really failed SegmentUsage = "usage" // plan quota (5h + weekly windows) SegmentUsageExtra = "usage_extra" // pay-as-you-go spend alert SegmentOverage = "overage" // this session is drawing on extra usage NOW SegmentVersion = "version" )
Segment keys for built-in segments. Extensions should use their own unique keys.
const ( PriorityModel = 10 PriorityThinking = 20 PriorityPermissions = 30 PriorityPathScope = 35 PriorityPlan = 40 PriorityGoal = 42 PriorityTasks = 45 PriorityUsageExtra = 33 // prominent: near permissions, since it means real spend PriorityOverage = 34 // right after extra spend: "you're on extra right now" PriorityCost = 80 PriorityCache = 85 PriorityCacheCold = 86 // right after the cache-hit meter it replaces PriorityUsage = 87 // grouped with the other meters PriorityContext = 90 // rightmost of the built-ins PriorityMCP = 88 // grouped with the meters, before context PriorityVersion = 100 )
Segment priorities (lower = further left).
Variables ¶
var ActiveTheme = CatppuccinMocha
ActiveTheme is the current color palette used by all TUI styles. Change this and call RebuildUI() to apply a new theme.
var CatppuccinMocha = Theme{ Base: lipgloss.Color("#1e1e2e"), Mantle: lipgloss.Color("#181825"), Crust: lipgloss.Color("#11111b"), Surface0: lipgloss.Color("#313244"), Surface1: lipgloss.Color("#45475a"), Surface2: lipgloss.Color("#585b70"), Text: lipgloss.Color("#cdd6f4"), Subtext1: lipgloss.Color("#bac2de"), Subtext0: lipgloss.Color("#a6adc8"), Overlay2: lipgloss.Color("#9399b2"), Overlay1: lipgloss.Color("#7f849c"), Overlay0: lipgloss.Color("#6c7086"), Rosewater: lipgloss.Color("#f5e0dc"), Flamingo: lipgloss.Color("#f2cdcd"), Pink: lipgloss.Color("#f5c2e7"), Mauve: lipgloss.Color("#cba6f7"), Red: lipgloss.Color("#f38ba8"), Maroon: lipgloss.Color("#eba0ac"), Peach: lipgloss.Color("#fab387"), Yellow: lipgloss.Color("#f9e2af"), Green: lipgloss.Color("#a6e3a1"), Teal: lipgloss.Color("#94e2d5"), Sky: lipgloss.Color("#89dceb"), Sapphire: lipgloss.Color("#74c7ec"), Blue: lipgloss.Color("#89b4fa"), Lavender: lipgloss.Color("#b4befe"), }
CatppuccinMocha is the default dark theme.
Functions ¶
func FormatUserMessage ¶
FormatUserMessage renders a user message using the active layout. Kept as a compatibility shim for external callers.
func ParseCommand ¶
ParseCommand returns (command string with args, true) only if text starts with a known /command. The returned string includes any arguments (e.g., "/model sonnet" → "model sonnet").
func RebuildStyles ¶
func RebuildStyles()
RebuildStyles is a backward-compatible alias for RebuildUI.
func RebuildUI ¶
func RebuildUI()
RebuildUI derives all styles from ActiveTheme. Called once at init; call again after swapping ActiveTheme at startup.
func RegisterLayout ¶
RegisterLayout adds a layout to the registry. Returns error on name collision.
func SetLayoutDirect ¶
SetLayoutDirect activates a layout instance directly (for extensions providing custom layouts). Returns error if l is nil.
Types ¶
type Config ¶
type Config struct {
Runtime *bus.SessionRuntime // required — the session bus runtime
SessionStore session.SessionStore // persistence backend (nil = no persistence)
Session *session.Session // session to resume (nil = fresh start)
StartInSessionBrowser bool // open the session browser before entering chat
CWD string // working directory for session metadata
PinnedModels []string // model IDs pre-pinned for Ctrl+P cycling
LoadPinnedModels func() []string // loads the current global pinned model IDs
OnPinnedModelsChange func([]PinnedModelChange) error // atomically applies pinned-model add/remove changes
PromptTemplates []promptpkg.Template // available prompt templates
Transcriber core.Transcriber // speech-to-text for voice input (nil = disabled)
STTLanguage string // ISO-639-1 language hint for STT ("" = auto-detect)
STTModel string // STT model id ("" = provider default)
STTVocabulary []string // words the transcriber tends to get wrong (names, jargon)
CacheTTL time.Duration // prompt-cache retention (Anthropic); drives the "cache cold" hint
UsagePoller *usage.MultiPoller // plan usage poller (nil = usage tracking disabled)
ProviderFactory func(core.Model) (core.Provider, error) // one-shot LLM calls (auto-titling); nil disables
AutoTitleModel core.Model // resolved auto-title model
AutoTitleEnabled bool // false disables automatic titles
ReleaseInfo release.Info // build metadata shown immediately in the status line
UpdateChecker *release.Checker // optional stable-release checker
UpdateCheckEnabled bool // false disables the asynchronous check
MCPController *mcp.Controller // shared MCP controller (nil = no MCP servers / picker hidden)
}
Config configures the TUI. All fields are optional except Runtime.
type FlatLayout ¶
type FlatLayout struct{}
FlatLayout renders a flat design with single-tone tool blocks and an inline "running…" indicator.
func (FlatLayout) RenderAssistantText ¶
func (FlatLayout) RenderAssistantText(glamourRendered string, _ int) string
func (FlatLayout) RenderError ¶
func (FlatLayout) RenderError(text string, _ int, theme Theme) string
func (FlatLayout) RenderLiveNotice ¶
func (FlatLayout) RenderLiveNotice(text string, width int, theme Theme) string
func (FlatLayout) RenderStatus ¶
func (FlatLayout) RenderStatus(text string, _ int, theme Theme) string
func (FlatLayout) RenderThinking ¶
func (FlatLayout) RenderThinking(text string, width int, theme Theme) string
func (FlatLayout) RenderToolBlock ¶
func (FlatLayout) RenderToolBlock(block ToolBlockData, width int, theme Theme) string
func (FlatLayout) RenderUserMessage ¶
func (FlatLayout) RenderUserMessage(text string, width int, theme Theme) string
type Layout ¶
type Layout interface {
RenderUserMessage(text string, width int, theme Theme) string
RenderThinking(text string, width int, theme Theme) string
RenderAssistantText(glamourRendered string, width int) string
RenderToolBlock(block ToolBlockData, width int, theme Theme) string
RenderError(text string, width int, theme Theme) string
RenderStatus(text string, width int, theme Theme) string
RenderLiveNotice(text string, width int, theme Theme) string
}
Layout controls how each block type is rendered to a string. Implementations receive the active Theme so they can build styles on demand. All methods receive width for consistent line-filling behavior.
Startup-time only: set the active layout before the TUI starts.
func GetActiveLayout ¶
func GetActiveLayout() Layout
GetActiveLayout returns the current layout. Never nil after init.
type PinnedModelChange ¶ added in v0.26.0
PinnedModelChange is one ordered add/remove operation for the global pin set.
type Segment ¶
type Segment struct {
Key string // stable segment identifier, used for special rendering rules
Text string // rendered text (may include ANSI via lipgloss)
Priority int // sort order: lower = further left
}
Segment is a single piece of the status line, rendered at a given priority. Lower priority values render further left.
type SplitLayout ¶
type SplitLayout struct{}
SplitLayout renders the split design with per-verb accent colors, right-aligned status badges, and generous spacing.
Tool blocks use a single Surface0 background (matching the HTML mockup).
func (SplitLayout) RenderAssistantText ¶
func (SplitLayout) RenderAssistantText(glamourRendered string, _ int) string
func (SplitLayout) RenderError ¶
func (SplitLayout) RenderError(text string, _ int, theme Theme) string
func (SplitLayout) RenderLiveNotice ¶
func (SplitLayout) RenderLiveNotice(text string, width int, theme Theme) string
func (SplitLayout) RenderStatus ¶
func (SplitLayout) RenderStatus(text string, _ int, theme Theme) string
func (SplitLayout) RenderThinking ¶
func (SplitLayout) RenderThinking(text string, width int, theme Theme) string
func (SplitLayout) RenderToolBlock ¶
func (SplitLayout) RenderToolBlock(block ToolBlockData, width int, theme Theme) string
func (SplitLayout) RenderUserMessage ¶
func (SplitLayout) RenderUserMessage(text string, width int, theme Theme) string
type StatusLine ¶
type StatusLine struct {
// contains filtered or unexported fields
}
StatusLine renders a horizontal bar composed of ordered segments. Designed for extensibility: segments can be added/removed/replaced by key.
Thread-safe: segments can be updated from any goroutine (e.g., agent event subscribers). The View renders a consistent snapshot.
func NewStatusLine ¶
func NewStatusLine(style lipgloss.Style) *StatusLine
NewStatusLine creates an empty status line with the given base style.
func (*StatusLine) IsEmpty ¶
func (sl *StatusLine) IsEmpty() bool
IsEmpty returns true if no segments are set.
func (*StatusLine) Remove ¶
func (sl *StatusLine) Remove(key string)
Remove deletes a segment by key.
func (*StatusLine) Set ¶
func (sl *StatusLine) Set(key, text string, priority int)
Set adds or replaces a segment by key.
func (*StatusLine) UpdateCacheColdSegment ¶
func (sl *StatusLine) UpdateCacheColdSegment(show bool)
UpdateCacheColdSegment shows a hint that the prompt cache has gone cold, so the next message pays a fresh cache-write. When shown it replaces the normal cache-hit meter (they share the same slot conceptually); the next run's accumulateCacheStats repopulates the hit meter. Uses the "medium" warning color.
func (*StatusLine) UpdateCacheSegment ¶
func (sl *StatusLine) UpdateCacheSegment(pct int)
UpdateCacheSegment sets the cache hit rate segment. pct is 0-100. Only shown when > 0.
func (*StatusLine) UpdateContextSegment ¶
func (sl *StatusLine) UpdateContextSegment(pct int)
UpdateContextSegment sets the context usage segment. pct is 0-100. Color changes based on usage level.
func (*StatusLine) UpdateCostSegment ¶
func (sl *StatusLine) UpdateCostSegment(cost float64)
UpdateCostSegment sets the session cost segment.
func (*StatusLine) UpdateGoalSegment ¶
func (sl *StatusLine) UpdateGoalSegment(label string)
UpdateGoalSegment sets the goal-mode segment. Pass "" to remove.
func (*StatusLine) UpdateMCPSegment ¶
func (sl *StatusLine) UpdateMCPSegment(total, unhealthy, disabled int)
UpdateMCPSegment sets the MCP servers segment: a plain count, turning red only when a server that should be running actually failed/exited (unhealthy > 0). A deliberately disabled server is neutral — it never reddens the status line. total == 0 removes the segment (no servers configured).
func (*StatusLine) UpdateModelSegment ¶
func (sl *StatusLine) UpdateModelSegment(name string)
UpdateModelSegment sets the model segment.
func (*StatusLine) UpdateOverageSegment ¶
func (sl *StatusLine) UpdateOverageSegment(onOverage bool)
UpdateOverageSegment flags that the current request was served from extra usage (drawing on pay-as-you-go). Shown only while active, in red; removed otherwise so it never clutters the normal state.
func (*StatusLine) UpdatePathScopeSegment ¶
func (sl *StatusLine) UpdatePathScopeSegment(scope string)
UpdatePathScopeSegment sets the filesystem path scope segment. scope should be "workspace", "ws+N", or "unrestricted".
func (*StatusLine) UpdatePermissionsSegment ¶
func (sl *StatusLine) UpdatePermissionsSegment(mode string)
UpdatePermissionsSegment sets the permissions mode segment.
func (*StatusLine) UpdatePlanSegment ¶
func (sl *StatusLine) UpdatePlanSegment(mode string)
UpdatePlanSegment sets the plan mode segment. Pass "" to remove.
func (*StatusLine) UpdateQuotaSegment ¶ added in v0.26.0
func (sl *StatusLine) UpdateQuotaSegment(labels []string, pcts []int)
UpdateQuotaSegment renders up to two provider-neutral quota meters.
func (*StatusLine) UpdateTasksSegment ¶
func (sl *StatusLine) UpdateTasksSegment(done, total int)
UpdateTasksSegment sets the task progress segment.
func (*StatusLine) UpdateThinkingSegment ¶
func (sl *StatusLine) UpdateThinkingSegment(level string)
UpdateThinkingSegment sets the thinking level segment.
func (*StatusLine) UpdateUsageExtraSegment ¶
func (sl *StatusLine) UpdateUsageExtraSegment(used float64, symbol string, enabled bool)
UpdateUsageExtraSegment sets the pay-as-you-go spend segment. used is in major currency units and symbol is the currency symbol. Removed when extra usage is disabled; shown muted at zero and in red once credits are spent.
func (*StatusLine) UpdateUsageMoneySegments ¶ added in v0.26.0
func (sl *StatusLine) UpdateUsageMoneySegments(buckets []UsageMoney)
UpdateUsageMoneySegments renders every reported provider credit bucket.
func (*StatusLine) UpdateUsageSegment ¶
func (sl *StatusLine) UpdateUsageSegment(fiveHPct, weekPct int)
UpdateUsageSegment sets the plan quota segment (5h + weekly windows). Pass -1 for a window that is not reported. Removed when neither is reported.
func (*StatusLine) UpdateUsageUnavailable ¶ added in v0.26.0
func (sl *StatusLine) UpdateUsageUnavailable(reason string)
UpdateUsageUnavailable explains why a provider has no consumer-plan meter.
func (*StatusLine) UpdateVersionSegment ¶
func (sl *StatusLine) UpdateVersionSegment(current, latest string)
UpdateVersionSegment shows the build version, optionally with a newer stable release indicator. The check itself is performed asynchronously by appModel.
func (*StatusLine) View ¶
func (sl *StatusLine) View(width int) string
View renders the status line. Returns empty string if no segments.
type Theme ¶
type Theme struct {
// Backgrounds (darkest → lightest)
Base lipgloss.Color
Mantle lipgloss.Color
Crust lipgloss.Color
Surface0 lipgloss.Color
Surface1 lipgloss.Color
Surface2 lipgloss.Color
// Text hierarchy (brightest → dimmest)
Text lipgloss.Color
Subtext1 lipgloss.Color
Subtext0 lipgloss.Color
Overlay2 lipgloss.Color
Overlay1 lipgloss.Color
Overlay0 lipgloss.Color
// Accents
Rosewater lipgloss.Color
Flamingo lipgloss.Color
Pink lipgloss.Color
Mauve lipgloss.Color
Red lipgloss.Color
Maroon lipgloss.Color
Peach lipgloss.Color
Yellow lipgloss.Color
Green lipgloss.Color
Teal lipgloss.Color
Sky lipgloss.Color
Sapphire lipgloss.Color
Blue lipgloss.Color
Lavender lipgloss.Color
}
Theme defines the color palette for the TUI. Follows the Catppuccin naming convention: base/surface for backgrounds, text/subtext/overlay for text hierarchy, and named accents.
Set ActiveTheme and call RebuildUI() before the TUI starts to apply a new theme.
type ToolBlockData ¶
type ToolBlockData struct {
ToolName string
Action string // verb: "write", "bash", "read", "edit", "search", "fetch"
Target string // path, command, query
Header string // tail-truncation notice (above body) — may be empty
Body string // content — may be empty (e.g. running tool with no output yet)
IsDiff bool // true when Body contains unified diff (color +/- lines)
Done bool
IsError bool
IsRejected bool
Note string // optional note shown in footer area (feedback/reason)
Generating bool // true while LLM is streaming args (before execution)
}
ToolBlockData is the layout-facing view of a tool block. All content is pre-processed (truncated/extracted). Layout only arranges it.
type UsageMoney ¶ added in v0.26.0
UsageMoney is one provider-reported money bucket for the status line.
Source Files
¶
- activity.go
- app.go
- app_agent.go
- app_commands.go
- app_goal.go
- app_mcp.go
- app_plan.go
- app_session.go
- app_viewport.go
- askprompt.go
- branchpicker.go
- cmdpalette.go
- expand.go
- filepicker.go
- glamour_style.go
- input.go
- layout.go
- layout_flat.go
- layout_split.go
- mcppicker.go
- messages.go
- permission.go
- picker.go
- planmenu.go
- render.go
- sanitize.go
- sessionbrowser.go
- settings.go
- status.go
- statusline.go
- styles.go
- subagentview.go
- taskwidget.go
- theme.go
- thinkingpicker.go
- truncate.go
- voice.go