Documentation
¶
Index ¶
- Constants
- Variables
- func ApplyTheme(theme *Theme)
- func ChromaStyle() *chroma.Style
- func GetPersistedThemeRef() string
- func InvalidateThemeCache(ref string)
- func IsBuiltinTheme(ref string) bool
- func ListThemeRefs() ([]string, error)
- func MarkdownStyle() ansi.StyleConfig
- func RenderComposite(style lipgloss.Style, content string) string
- func SaveThemeToUserConfig(themeRef string) error
- func StarIndicator(starred bool) string
- func ThemesDir() string
- func UserThemeExists(ref string) bool
- type ChromaColors
- type MarkdownTheme
- type Theme
- type ThemeColors
- type ThemeWatcher
Constants ¶
const ( AppPaddingLeft = 1 // Keep in sync with AppStyle padding // DoubleClickThreshold is the maximum time between clicks to register as a double-click DoubleClickThreshold = 400 * time.Millisecond )
Base Styles
const DefaultThemeRef = "default"
DefaultThemeRef is the reference for the built-in default theme.
const UserThemePrefix = "user:"
UserThemePrefix is used to distinguish user themes from built-in themes when they have the same base name. A ref like "user:nord" refers to the user's custom nord theme, while "nord" refers to the built-in.
Variables ¶
var ( // Background colors Background color.Color BackgroundAlt color.Color // Primary accent colors White color.Color MobyBlue color.Color Accent color.Color // Status colors Success color.Color Error color.Color Warning color.Color Info color.Color Highlight color.Color // Text hierarchy TextPrimary color.Color TextSecondary color.Color TextMuted color.Color TextMutedGray color.Color // Border colors BorderPrimary color.Color BorderSecondary color.Color BorderMuted color.Color BorderWarning color.Color // Diff colors DiffAddBg color.Color DiffRemoveBg color.Color DiffAddFg color.Color DiffRemoveFg color.Color // UI element colors LineNumber color.Color Separator color.Color // Interactive element colors Selected color.Color SelectedFg color.Color PlaceholderColor color.Color // Badge colors AgentBadgeFg color.Color AgentBadgeBg color.Color BadgePurple color.Color BadgeCyan color.Color BadgeGreen color.Color // Error colors (extended) ErrorStrong color.Color ErrorDark color.Color // Additional muted colors FadedGray color.Color // Tabs TabBg color.Color TabPrimaryFg color.Color TabAccentFg color.Color )
Color variables - initialized by ApplyTheme() before TUI starts. These are set from the theme's YAML values (see themes/default.yaml for defaults).
var ( NoStyle = lipgloss.NewStyle() BaseStyle = NoStyle.Foreground(TextPrimary) AppStyle = BaseStyle.Padding(0, 1, 0, AppPaddingLeft) )
var ( HighlightWhiteStyle = BaseStyle.Foreground(White).Bold(true) MutedStyle = BaseStyle.Foreground(TextMutedGray) SecondaryStyle = BaseStyle.Foreground(TextSecondary) BoldStyle = BaseStyle.Bold(true) FadingStyle = NoStyle.Foreground(FadedGray) // Very dim for fade-out animations (rebuilt by ApplyTheme) )
Text Styles
var ( SuccessStyle = BaseStyle.Foreground(Success) ErrorStyle = BaseStyle.Foreground(Error) WarningStyle = BaseStyle.Foreground(Warning) InfoStyle = BaseStyle.Foreground(Info) ActiveStyle = BaseStyle.Foreground(Success) ToBeDoneStyle = BaseStyle.Foreground(TextPrimary) InProgressStyle = BaseStyle.Foreground(Highlight) CompletedStyle = BaseStyle.Foreground(TextMutedGray) )
Status Styles
var ( BaseMessageStyle = BaseStyle. Padding(1, 1). BorderLeft(true). BorderStyle(lipgloss.HiddenBorder()). BorderForeground(BorderPrimary) UserMessageStyle = BaseMessageStyle. BorderStyle(lipgloss.ThickBorder()). BorderForeground(BorderPrimary). Foreground(TextPrimary). Background(BackgroundAlt). Bold(true) AssistantMessageStyle = BaseMessageStyle. Padding(0, 1) WelcomeMessageStyle = BaseMessageStyle. BorderStyle(lipgloss.DoubleBorder()). Bold(true) ErrorMessageStyle = BaseMessageStyle. BorderStyle(lipgloss.ThickBorder()). Foreground(Error) SelectedMessageStyle = AssistantMessageStyle. BorderStyle(lipgloss.NormalBorder()). BorderForeground(Success) )
Border Styles
var ( DialogStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(BorderSecondary). Foreground(TextPrimary). Padding(1, 2). Align(lipgloss.Left) DialogWarningStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(BorderWarning). Foreground(TextPrimary). Padding(1, 2). Align(lipgloss.Left) DialogTitleStyle = BaseStyle. Bold(true). Foreground(TextSecondary). Align(lipgloss.Center) DialogTitleWarningStyle = BaseStyle. Bold(true). Foreground(Warning). Align(lipgloss.Center) DialogTitleInfoStyle = BaseStyle. Bold(true). Foreground(Info). Align(lipgloss.Center) DialogContentStyle = BaseStyle. Foreground(TextPrimary) DialogSeparatorStyle = BaseStyle. Foreground(BorderMuted) DialogQuestionStyle = BaseStyle. Bold(true). Foreground(TextPrimary). Align(lipgloss.Center) DialogOptionsStyle = BaseStyle. Foreground(TextMuted). Align(lipgloss.Center) DialogHelpStyle = BaseStyle. Foreground(TextMuted). Italic(true) TabTitleStyle = BaseStyle. Foreground(TabPrimaryFg) TabPrimaryStyle = BaseStyle. Foreground(TextPrimary) TabStyle = TabPrimaryStyle. Padding(1, 0) TabAccentStyle = BaseStyle. Foreground(TabAccentFg) )
Dialog Styles
var ( PaletteCategoryStyle = BaseStyle. Bold(true). Foreground(White). MarginTop(1) PaletteUnselectedActionStyle = BaseStyle. Foreground(TextPrimary). Bold(true) PaletteSelectedActionStyle = PaletteUnselectedActionStyle. Background(MobyBlue). Foreground(White) PaletteUnselectedDescStyle = BaseStyle. Foreground(TextSecondary) PaletteSelectedDescStyle = PaletteUnselectedDescStyle. Background(MobyBlue). Foreground(White) // Badge styles for model picker - use color vars set by ApplyTheme() BadgeAlloyStyle = BaseStyle. Foreground(BadgePurple) BadgeDefaultStyle = BaseStyle. Foreground(BadgeCyan) BadgeCurrentStyle = BaseStyle. Foreground(BadgeGreen) )
Command Palette Styles - rebuilt by ApplyTheme()
var ( StarredStyle = BaseStyle.Foreground(Success) UnstarredStyle = BaseStyle.Foreground(TextMuted) )
Star Styles for session browser and sidebar
var ( DiffAddStyle = BaseStyle. Background(DiffAddBg). Foreground(DiffAddFg) DiffRemoveStyle = BaseStyle. Background(DiffRemoveBg). Foreground(DiffRemoveFg) DiffUnchangedStyle = BaseStyle.Background(BackgroundAlt) )
Diff Styles (matching glamour markdown theme)
var ( LineNumberStyle = BaseStyle.Foreground(LineNumber).Background(BackgroundAlt) SeparatorStyle = BaseStyle.Foreground(Separator).Background(BackgroundAlt) )
Syntax highlighting UI element styles
var ( ToolMessageStyle = BaseStyle. Foreground(TextMutedGray) ToolErrorMessageStyle = BaseStyle. Foreground(ErrorStrong) ToolName = ToolMessageStyle. Foreground(TextMutedGray). Padding(0, 1) ToolNameError = ToolName. Foreground(ErrorStrong). Background(ErrorDark) ToolNameDim = ToolMessageStyle. Foreground(TextMutedGray). Italic(true) ToolDescription = ToolMessageStyle. Foreground(TextPrimary) ToolCompletedIcon = BaseStyle. MarginLeft(2). Foreground(TextMutedGray) ToolErrorIcon = ToolCompletedIcon. Background(ErrorStrong) ToolPendingIcon = ToolCompletedIcon. Background(Warning) ToolCallArgs = ToolMessageStyle. Padding(0, 0, 0, 2) ToolCallResult = ToolMessageStyle. Padding(0, 0, 0, 2) )
Tool Call Styles
var ( InputStyle = textarea.Styles{ Focused: textarea.StyleState{ Base: BaseStyle, Placeholder: BaseStyle.Foreground(PlaceholderColor), }, Blurred: textarea.StyleState{ Base: BaseStyle, Placeholder: BaseStyle.Foreground(PlaceholderColor), }, Cursor: textarea.CursorStyle{ Color: Accent, }, } // DialogInputStyle is the style for textinput fields in dialogs, // matching the main editor's look (cursor color, text color). DialogInputStyle = textinput.Styles{ Focused: textinput.StyleState{ Text: BaseStyle, Placeholder: BaseStyle.Foreground(PlaceholderColor), }, Blurred: textinput.StyleState{ Text: BaseStyle, Placeholder: BaseStyle.Foreground(PlaceholderColor), }, Cursor: textinput.CursorStyle{ Color: Accent, }, } EditorStyle = BaseStyle.Padding(1, 0, 0, 0) // SuggestionGhostStyle renders inline auto-complete hints in a muted tone. // Use a distinct grey so suggestion text is visually separate from the user's input. // NOTE: Rebuilt by ApplyTheme() using theme's suggestion_ghost color. SuggestionGhostStyle = BaseStyle.Foreground(TextMutedGray) // SuggestionCursorStyle renders the first character of a suggestion inside the cursor. // Uses the same blue accent background as the normal cursor, with ghost-colored foreground text. // NOTE: Rebuilt by ApplyTheme(). SuggestionCursorStyle = BaseStyle.Background(Accent).Foreground(TextMutedGray) // Attachment banner styles - polished look with subtle border AttachmentBannerStyle = BaseStyle. Foreground(TextSecondary) AttachmentBadgeStyle = BaseStyle. Foreground(Info). Bold(true) AttachmentSizeStyle = BaseStyle. Foreground(TextMuted). Italic(true) AttachmentIconStyle = BaseStyle. Foreground(Info) )
Input Styles
var ( TrackStyle = lipgloss.NewStyle().Foreground(BorderSecondary) ThumbStyle = lipgloss.NewStyle().Foreground(Info).Background(BackgroundAlt).Bold(true) ThumbActiveStyle = lipgloss.NewStyle().Foreground(White).Background(BackgroundAlt).Bold(true) )
Scrollbar
var ( ResizeHandleStyle = BaseStyle. Foreground(BorderSecondary) ResizeHandleHoverStyle = BaseStyle. Foreground(Info). Bold(true) ResizeHandleActiveStyle = BaseStyle. Foreground(White). Bold(true) )
Resize Handle Style
var ( NotificationStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(Success). Padding(0, 1) NotificationInfoStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(Info). Padding(0, 1) NotificationWarningStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(Warning). Padding(0, 1) NotificationErrorStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(Error). Padding(0, 1) )
Notification Styles
var ( CompletionBoxStyle = BaseStyle. Border(lipgloss.RoundedBorder()). BorderForeground(BorderSecondary). Padding(0, 1) CompletionNormalStyle = BaseStyle. Foreground(TextPrimary). Bold(true) CompletionSelectedStyle = CompletionNormalStyle. Foreground(White). Background(MobyBlue) CompletionDescStyle = BaseStyle. Foreground(TextSecondary) CompletionSelectedDescStyle = CompletionDescStyle. Foreground(White). Background(MobyBlue) CompletionNoResultsStyle = BaseStyle. Foreground(TextMuted). Italic(true). Align(lipgloss.Center) )
Completion Styles
var ( AgentBadgeStyle = BaseStyle. Foreground(AgentBadgeFg). Background(AgentBadgeBg). Padding(0, 1) ThinkingBadgeStyle = BaseStyle. Foreground(TextMuted). Bold(true). Italic(true) )
Agent and transfer badge styles
var ( SpinnerDotsAccentStyle = BaseStyle.Foreground(Accent) SpinnerDotsHighlightStyle = BaseStyle.Foreground(TabAccentFg) SpinnerTextBrightestStyle = BaseStyle.Foreground(Accent) SpinnerTextBrightStyle = BaseStyle.Foreground(Accent) SpinnerTextDimStyle = BaseStyle.Foreground(Accent) SpinnerTextDimmestStyle = BaseStyle.Foreground(Accent) )
Spinner Styles - rebuilt by ApplyTheme() with actual spinner colors from theme
Layout Styles
var (
ChatStyle = BaseStyle
)
Deprecated styles (kept for backward compatibility)
var ( SelectionStyle = BaseStyle. Background(Selected). Foreground(SelectedFg) )
Selection Styles
Functions ¶
func ApplyTheme ¶ added in v1.20.0
func ApplyTheme(theme *Theme)
ApplyTheme applies the given theme to all style variables. This updates all exported color and style variables in the styles package. After calling this, send ThemeChangedMsg to invalidate all TUI caches.
func ChromaStyle ¶ added in v1.8.2
func GetPersistedThemeRef ¶ added in v1.20.0
func GetPersistedThemeRef() string
GetPersistedThemeRef returns the theme reference persisted in user config. Returns DefaultThemeRef if no theme is set or if loading fails.
func InvalidateThemeCache ¶ added in v1.20.0
func InvalidateThemeCache(ref string)
InvalidateThemeCache clears the theme cache for a specific ref, or all if ref is empty. This is primarily for testing; the cache is mtime-aware so it auto-invalidates on file changes.
func IsBuiltinTheme ¶ added in v1.20.0
IsBuiltinTheme returns true if the given theme reference is a built-in theme. Refs prefixed with "user:" are always considered user themes, not built-in.
func ListThemeRefs ¶ added in v1.20.0
ListThemeRefs returns the list of available theme references. It includes all built-in themes (including "default") and user themes from ~/.cagent/themes/. User themes with names matching built-in themes are prefixed with "user:" to distinguish them. The "default" theme is always listed first for UX purposes.
func MarkdownStyle ¶ added in v1.8.2
func MarkdownStyle() ansi.StyleConfig
MarkdownStyle returns the markdown style configuration, deriving colors from the current theme.
func RenderComposite ¶ added in v1.8.2
RenderComposite renders the content with the given style, but ensures that any ANSI reset codes in the content are replaced with the style's active sequences, preventing the style's background/foreground from being interrupted.
func SaveThemeToUserConfig ¶ added in v1.20.0
SaveThemeToUserConfig persists the theme reference to the user config file. If themeRef equals DefaultThemeRef, the setting is cleared (empty string).
func StarIndicator ¶ added in v1.18.4
StarIndicator returns the styled star indicator for a given starred status
func ThemesDir ¶ added in v1.20.0
func ThemesDir() string
ThemesDir returns the directory where user themes are stored.
func UserThemeExists ¶ added in v1.20.0
UserThemeExists returns true if a user theme file exists for the given ref in the user themes directory (typically ~/.cagent/themes/).
This handles the "user:" prefix - "user:nord" checks for ~/.cagent/themes/nord.yaml.
Types ¶
type ChromaColors ¶ added in v1.20.0
type ChromaColors struct {
ErrorFg string `yaml:"error_fg,omitempty"`
ErrorBg string `yaml:"error_bg,omitempty"`
Success string `yaml:"success,omitempty"`
Comment string `yaml:"comment,omitempty"`
CommentPreproc string `yaml:"comment_preproc,omitempty"`
Keyword string `yaml:"keyword,omitempty"`
KeywordReserved string `yaml:"keyword_reserved,omitempty"`
KeywordNamespace string `yaml:"keyword_namespace,omitempty"`
KeywordType string `yaml:"keyword_type,omitempty"`
Operator string `yaml:"operator,omitempty"`
Punctuation string `yaml:"punctuation,omitempty"`
NameBuiltin string `yaml:"name_builtin,omitempty"`
NameTag string `yaml:"name_tag,omitempty"`
NameAttribute string `yaml:"name_attribute,omitempty"`
NameDecorator string `yaml:"name_decorator,omitempty"`
LiteralNumber string `yaml:"literal_number,omitempty"`
LiteralString string `yaml:"literal_string,omitempty"`
LiteralStringEscape string `yaml:"literal_string_escape,omitempty"`
GenericDeleted string `yaml:"generic_deleted,omitempty"`
GenericSubheading string `yaml:"generic_subheading,omitempty"`
Background string `yaml:"background,omitempty"`
}
ChromaColors contains syntax highlighting colors (for code blocks).
type MarkdownTheme ¶ added in v1.20.0
type MarkdownTheme struct {
Heading string `yaml:"heading,omitempty"`
Link string `yaml:"link,omitempty"`
Strong string `yaml:"strong,omitempty"`
Code string `yaml:"code,omitempty"`
CodeBg string `yaml:"code_bg,omitempty"`
Blockquote string `yaml:"blockquote,omitempty"`
List string `yaml:"list,omitempty"`
HR string `yaml:"hr,omitempty"`
}
MarkdownTheme contains markdown-specific color overrides.
type Theme ¶ added in v1.20.0
type Theme struct {
Version int `yaml:"version,omitempty"`
Name string `yaml:"name,omitempty"`
Ref string `yaml:"-"` // Set by loader, not from YAML
Colors ThemeColors `yaml:"colors,omitempty"`
Chroma ChromaColors `yaml:"chroma,omitempty"`
Markdown MarkdownTheme `yaml:"markdown,omitempty"`
}
Theme represents a complete color theme for the TUI. All fields are optional; unset fields use the built-in defaults.
func CurrentTheme ¶ added in v1.20.0
func CurrentTheme() *Theme
CurrentTheme returns the currently applied theme, or the default if none applied.
func DefaultTheme ¶ added in v1.20.0
func DefaultTheme() *Theme
DefaultTheme returns the built-in default theme loaded from embedded default.yaml. The result is cached internally, but a copy is returned to prevent callers from accidentally modifying the cached theme.
func LoadTheme ¶ added in v1.20.0
LoadTheme loads a theme by reference with mtime-aware caching. If ref is "" (empty), this is an error - caller should resolve to DefaultThemeRef first.
Refs starting with "user:" (e.g., "user:nord") explicitly load from user themes directory. Other refs load built-in themes first, falling back to user themes if no built-in exists.
The cache is mtime-aware: user themes are re-parsed only when the file's modTime changes. If a user theme file exists but fails to parse, an error is returned (no silent fallback).
type ThemeColors ¶ added in v1.20.0
type ThemeColors struct {
// Text colors
TextBright string `yaml:"text_bright,omitempty"` // Bright/emphasized text
TextPrimary string `yaml:"text_primary,omitempty"` // Primary text
TextSecondary string `yaml:"text_secondary,omitempty"` // Secondary text
TextMuted string `yaml:"text_muted,omitempty"` // Muted/subtle text
TextFaint string `yaml:"text_faint,omitempty"` // Very faint text/decorations
// Accent colors
Accent string `yaml:"accent,omitempty"` // Primary accent color
AccentMuted string `yaml:"accent_muted,omitempty"` // Muted accent color
// Background colors
Background string `yaml:"background,omitempty"` // Main background
BackgroundAlt string `yaml:"background_alt,omitempty"` // Alternate background (cards, panels)
// Border colors
BorderSecondary string `yaml:"border_secondary,omitempty"`
// Status colors
Success string `yaml:"success,omitempty"` // Success/positive state
Error string `yaml:"error,omitempty"` // Error/negative state
Warning string `yaml:"warning,omitempty"` // Warning state
Info string `yaml:"info,omitempty"` // Info/neutral state
Highlight string `yaml:"highlight,omitempty"` // Highlighted elements
// Brand colors
Brand string `yaml:"brand,omitempty"` // Primary brand color
BrandBg string `yaml:"brand_bg,omitempty"` // Brand background
// Error-specific colors
ErrorStrong string `yaml:"error_strong,omitempty"` // Strong error emphasis
ErrorDark string `yaml:"error_dark,omitempty"` // Dark error background
// Spinner colors
SpinnerDim string `yaml:"spinner_dim,omitempty"`
SpinnerBright string `yaml:"spinner_bright,omitempty"`
SpinnerBrightest string `yaml:"spinner_brightest,omitempty"`
// Diff colors
DiffAddBg string `yaml:"diff_add_bg,omitempty"`
DiffRemoveBg string `yaml:"diff_remove_bg,omitempty"`
// UI element colors
LineNumber string `yaml:"line_number,omitempty"`
Separator string `yaml:"separator,omitempty"`
Selected string `yaml:"selected,omitempty"`
SelectedFg string `yaml:"selected_fg,omitempty"` // Text on selected/brand backgrounds
SuggestionGhost string `yaml:"suggestion_ghost,omitempty"`
TabBg string `yaml:"tab_bg,omitempty"`
Placeholder string `yaml:"placeholder,omitempty"`
// Badge colors
BadgeAccent string `yaml:"badge_accent,omitempty"` // Accent badge (e.g., purple highlights)
BadgeInfo string `yaml:"badge_info,omitempty"` // Info badge (e.g., cyan)
BadgeSuccess string `yaml:"badge_success,omitempty"` // Success badge (e.g., green)
}
ThemeColors contains all color definitions for the TUI. Use hex color strings (e.g., "#7AA2F7") or ANSI color numbers (e.g., "39").
type ThemeWatcher ¶ added in v1.20.0
type ThemeWatcher struct {
// contains filtered or unexported fields
}
ThemeWatcher watches the current theme file for changes and signals when the file is modified. It does NOT apply the theme directly to avoid race conditions with the TUI goroutine.
func NewThemeWatcher ¶ added in v1.20.0
func NewThemeWatcher(onThemeChanged func(themeRef string)) *ThemeWatcher
NewThemeWatcher creates a new theme watcher. The onThemeChanged callback is called whenever the theme file is modified. The callback receives the theme ref so the caller can load and apply the theme on the appropriate goroutine (e.g., the TUI main loop).
func (*ThemeWatcher) Stop ¶ added in v1.20.0
func (tw *ThemeWatcher) Stop()
Stop stops watching the current theme file.
func (*ThemeWatcher) Watch ¶ added in v1.20.0
func (tw *ThemeWatcher) Watch(themeRef string) error
Watch starts watching the theme file for the given theme reference. Only watches if a user theme file exists for this ref (in ~/.cagent/themes/). Handles "user:" prefix - e.g., "user:nord" watches ~/.cagent/themes/nord.yaml. If the theme is the built-in default or no user file exists, no watching occurs.