Documentation
¶
Overview ¶
Package ui provides terminal styling for beads CLI output.
Package ui provides terminal styling and pager support for beads CLI output.
Package ui provides terminal styling for beads CLI output. Uses the Ayu color theme with adaptive light/dark mode support.
Package ui provides terminal styling and output helpers for beads CLI.
Index ¶
- Constants
- Variables
- func BuildEntityTree(graph *queries.EntityGraph) *tree.Tree
- func GetStatusIcon(status string) string
- func GetStatusStyle(status string) lipgloss.Style
- func GetWidth() int
- func IsAgentMode() bool
- func IsTerminal() bool
- func NewSearchTable(width int) *table.Table
- func Prompt(question, defaultValue string) string
- func PromptYesNo(question string, defaultYes bool) bool
- func RenderAccent(s string) string
- func RenderBold(s string) string
- func RenderCategory(s string) string
- func RenderClosedLine(line string) string
- func RenderCommand(s string) string
- func RenderCooccurrenceTable(target string, coNodes []queries.CooccurrenceNode, width int) string
- func RenderEntitiesTable(title string, entities [][]string, width int) string
- func RenderEntityTree(graph *queries.EntityGraph) string
- func RenderEvalReport(runs []EvalRun, width int) string
- func RenderFail(s string) string
- func RenderFailIcon() string
- func RenderGraphTable(query string, matches []struct{ ... }, width int) string
- func RenderID(id string) string
- func RenderImpactTable(target string, deps []string, width int) string
- func RenderInfoIcon() string
- func RenderInitLogo() string
- func RenderInitReport(res InitResult, width int) string
- func RenderIssueCompact(id string, priority int, issueType, status, title string) string
- func RenderMarkdown(markdown string) string
- func RenderMuted(s string) string
- func RenderNoResults(query string, suggestions []string, width int) string
- func RenderPass(s string) string
- func RenderPassIcon() string
- func RenderPath(path []queries.PathStep, width int) string
- func RenderPriority(priority int) string
- func RenderPriorityCompact(priority int) string
- func RenderPriorityForStatus(priority int, status string) string
- func RenderResultsWithContext(query string, results []SearchResultItem, related []string, neighbors []string, ...) string
- func RenderSeparator() string
- func RenderSkipIcon() string
- func RenderStatus(status string) string
- func RenderStatusIcon(status string) string
- func RenderType(issueType string) string
- func RenderTypeForStatus(issueType, status string) string
- func RenderTypoCorrection(query, corrected string, results []SearchResultItem, width int) string
- func RenderWarn(s string) string
- func RenderWarnIcon() string
- func ShouldUseColor() bool
- func ShouldUseEmoji() bool
- func ToPager(content string, opts PagerOptions) error
- type EvalRun
- type InitResult
- type PagerOptions
- type SearchResultItem
Constants ¶
const ( IconPass = "✓" IconWarn = "⚠" IconFail = "✖" IconSkip = "-" IconInfo = "ℹ" )
Status icons - consistent semantic indicators
const ( StatusIconOpen = "○" // available to work (hollow circle) StatusIconInProgress = "◐" // active work (half-filled) StatusIconBlocked = "●" // needs attention (filled circle) StatusIconClosed = "✓" // completed (checkmark) StatusIconDeferred = "❄" // scheduled for later (snowflake) StatusIconPinned = "📌" // elevated priority )
Issue status icons - used consistently across all commands Design principle: icons > text labels for scannability IMPORTANT: Use small Unicode symbols, NOT emoji-style icons (🔴🟠 etc.) Emoji blobs cause cognitive overload and break visual consistency
const ( TreeChild = "⎿ " // child indicator TreeLast = "└─ " // last child / detail line TreeIndent = " " // 2-space indent per level )
Tree characters for hierarchical display
const ( SeparatorLight = "" /* 126-byte string literal not displayed */ SeparatorHeavy = "" /* 126-byte string literal not displayed */ )
Separators
const InitLogo = `` /* 225-byte string literal not displayed */
const PriorityIcon = "●"
Priority icon - small filled circle, colored by priority level IMPORTANT: Use this small circle, NOT emoji blobs (🔴🟠🟡🔵⚪)
Variables ¶
var ( // Core semantic colors (Ayu theme - adaptive light/dark) ColorPass = lipgloss.AdaptiveColor{ Light: "#86b300", Dark: "#c2d94c", } ColorWarn = lipgloss.AdaptiveColor{ Light: "#f2ae49", Dark: "#ffb454", } ColorFail = lipgloss.AdaptiveColor{ Light: "#f07171", Dark: "#f07178", } ColorMuted = lipgloss.AdaptiveColor{ Light: "#828c99", Dark: "#6c7680", } ColorAccent = lipgloss.AdaptiveColor{ Light: "#399ee6", Dark: "#59c2ff", } // === Workflow Status Colors === // Only actionable states get color - open/closed match standard text ColorStatusOpen = lipgloss.AdaptiveColor{ Light: "", Dark: "", } ColorStatusInProgress = lipgloss.AdaptiveColor{ Light: "#f2ae49", Dark: "#ffb454", } ColorStatusClosed = lipgloss.AdaptiveColor{ Light: "#9099a1", Dark: "#8090a0", } ColorStatusBlocked = lipgloss.AdaptiveColor{ Light: "#f07171", Dark: "#f26d78", } ColorStatusPinned = lipgloss.AdaptiveColor{ Light: "#d2a6ff", Dark: "#d2a6ff", } ColorStatusHooked = lipgloss.AdaptiveColor{ Light: "#59c2ff", Dark: "#59c2ff", } // === Priority Colors === // Only P0/P1 get color - they need attention // P2/P3/P4 are neutral (medium/low/backlog don't need visual urgency) ColorPriorityP0 = lipgloss.AdaptiveColor{ Light: "#f07171", Dark: "#f07178", } ColorPriorityP1 = lipgloss.AdaptiveColor{ Light: "#ff8f40", Dark: "#ff8f40", } ColorPriorityP2 = lipgloss.AdaptiveColor{ Light: "#e6b450", Dark: "#e6b450", } ColorPriorityP3 = lipgloss.AdaptiveColor{ Light: "", Dark: "", } ColorPriorityP4 = lipgloss.AdaptiveColor{ Light: "", Dark: "", } // === Issue Type Colors === // Bugs and epics get color - they need attention // All other types use standard text ColorTypeBug = lipgloss.AdaptiveColor{ Light: "#f07171", Dark: "#f26d78", } ColorTypeFeature = lipgloss.AdaptiveColor{ Light: "", Dark: "", } ColorTypeTask = lipgloss.AdaptiveColor{ Light: "", Dark: "", } ColorTypeEpic = lipgloss.AdaptiveColor{ Light: "#d2a6ff", Dark: "#d2a6ff", } ColorTypeChore = lipgloss.AdaptiveColor{ Light: "", Dark: "", } // === Issue ID Color === // IDs use standard text color - subtle, not attention-grabbing ColorID = lipgloss.AdaptiveColor{ Light: "", Dark: "", } )
Ayu theme color palette Dark: https://terminalcolors.com/themes/ayu/dark/ Light: https://terminalcolors.com/themes/ayu/light/ Source: https://github.com/ayu-theme/ayu-colors
var ( PassStyle = lipgloss.NewStyle().Foreground(ColorPass) WarnStyle = lipgloss.NewStyle().Foreground(ColorWarn) FailStyle = lipgloss.NewStyle().Foreground(ColorFail) MutedStyle = lipgloss.NewStyle().Foreground(ColorMuted) AccentStyle = lipgloss.NewStyle().Foreground(ColorAccent) )
Core styles - consistent across all commands
var ( StatusOpenStyle = lipgloss.NewStyle().Foreground(ColorStatusOpen) StatusInProgressStyle = lipgloss.NewStyle().Foreground(ColorStatusInProgress) StatusClosedStyle = lipgloss.NewStyle().Foreground(ColorStatusClosed) StatusBlockedStyle = lipgloss.NewStyle().Foreground(ColorStatusBlocked) StatusPinnedStyle = lipgloss.NewStyle().Foreground(ColorStatusPinned) StatusHookedStyle = lipgloss.NewStyle().Foreground(ColorStatusHooked) )
Status styles for workflow states
var ( PriorityP0Style = lipgloss.NewStyle().Foreground(ColorPriorityP0).Bold(true) PriorityP1Style = lipgloss.NewStyle().Foreground(ColorPriorityP1) PriorityP2Style = lipgloss.NewStyle().Foreground(ColorPriorityP2) PriorityP3Style = lipgloss.NewStyle().Foreground(ColorPriorityP3) PriorityP4Style = lipgloss.NewStyle().Foreground(ColorPriorityP4) )
Priority styles
var ( TypeBugStyle = lipgloss.NewStyle().Foreground(ColorTypeBug) TypeFeatureStyle = lipgloss.NewStyle().Foreground(ColorTypeFeature) TypeTaskStyle = lipgloss.NewStyle().Foreground(ColorTypeTask) TypeEpicStyle = lipgloss.NewStyle().Foreground(ColorTypeEpic) TypeChoreStyle = lipgloss.NewStyle().Foreground(ColorTypeChore) )
Type styles for issue categories
var ( TableHeaderStyle = lipgloss.NewStyle(). Bold(true). Foreground(ColorAccent). Align(lipgloss.Center) TableWarningStyle = lipgloss.NewStyle(). Foreground(ColorWarn) TableSuccessStyle = lipgloss.NewStyle(). Foreground(ColorPass) TableFailStyle = lipgloss.NewStyle(). Foreground(ColorFail) TableHintStyle = lipgloss.NewStyle(). Foreground(ColorMuted) TableBorderStyle = lipgloss.NewStyle(). Foreground(ColorMuted) )
Table Styles
var BoldStyle = lipgloss.NewStyle().Bold(true)
BoldStyle for emphasis
var CategoryStyle = lipgloss.NewStyle().Bold(true).Foreground(ColorAccent)
CategoryStyle for section headers - bold with accent color
var CommandStyle = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{
Light: "#5c6166",
Dark: "#bfbdb6",
})
CommandStyle for command names - subtle contrast, not attention-grabbing
var IDStyle = lipgloss.NewStyle().Foreground(ColorID)
Issue ID style
Functions ¶
func BuildEntityTree ¶
func BuildEntityTree(graph *queries.EntityGraph) *tree.Tree
BuildEntityTree constructs a lipgloss/tree for an EntityGraph
func GetStatusIcon ¶
GetStatusIcon returns just the icon character without styling Useful when you need to apply custom styling or for non-TTY output
func GetStatusStyle ¶
GetStatusStyle returns the lipgloss style for a given status Use this when you need to apply the semantic color to custom text Example: ui.GetStatusStyle("in_progress").Render(myCustomText)
func IsAgentMode ¶
func IsAgentMode() bool
IsAgentMode returns true if the CLI is running in agent-optimized mode. This is triggered by:
- BD_AGENT_MODE=1 environment variable (explicit)
- CLAUDE_CODE environment variable (auto-detect Claude Code)
Agent mode provides ultra-compact output optimized for LLM context windows.
func IsTerminal ¶
func IsTerminal() bool
IsTerminal returns true if stdout is connected to a terminal (TTY).
func NewSearchTable ¶
NewSearchTable creates a new table with default search styling
func PromptYesNo ¶
PromptYesNo displays a yes/no question and returns the user's answer. It defaults to the `defaultYes` value if the user just presses Enter or in non-interactive mode.
func RenderAccent ¶
RenderAccent renders text with accent (blue) styling
func RenderCategory ¶
RenderCategory renders a category header in uppercase with accent color
func RenderClosedLine ¶
RenderClosedLine renders an entire line in the closed/dimmed style
func RenderCommand ¶
RenderCommand renders a command name with subtle styling
func RenderCooccurrenceTable ¶
func RenderCooccurrenceTable(target string, coNodes []queries.CooccurrenceNode, width int) string
RenderCooccurrenceTable renders a list of entities frequently mentioned together
func RenderEntitiesTable ¶
RenderEntitiesTable renders a list of entities and their counts
func RenderEntityTree ¶
func RenderEntityTree(graph *queries.EntityGraph) string
RenderEntityTree renders an EntityGraph using lipgloss/tree
func RenderEvalReport ¶
func RenderFailIcon ¶
func RenderFailIcon() string
RenderFailIcon renders the fail icon with styling
func RenderGraphTable ¶
func RenderGraphTable(query string, matches []struct { Name string Graph *queries.EntityGraph }, width int) string
RenderGraphTable renders multiple trees inside a single structured table
func RenderImpactTable ¶
RenderImpactTable renders the impact of an entity using a Lipgloss table
func RenderInfoIcon ¶
func RenderInfoIcon() string
RenderInfoIcon renders the info icon with styling
func RenderInitLogo ¶
func RenderInitLogo() string
RenderInitLogo returns the stylized ASCII logo for initialization
func RenderInitReport ¶
func RenderInitReport(res InitResult, width int) string
RenderInitReport generates a professional Lipgloss report for the init command
func RenderIssueCompact ¶
RenderIssueCompact renders a compact one-line issue summary Format: ID [Priority] [Type] Status - Title When status is "closed", the entire line is dimmed to show it's done
func RenderMarkdown ¶
RenderMarkdown renders markdown text using glamour with beads theme colors. Returns the rendered markdown or the original text if rendering fails. Word wraps at terminal width (or 80 columns if width can't be detected).
func RenderMuted ¶
RenderMuted renders text with muted (gray) styling
func RenderNoResults ¶
RenderNoResults renders the no results view
func RenderPass ¶
RenderPass renders text with pass (green) styling
func RenderPassIcon ¶
func RenderPassIcon() string
RenderPassIcon renders the pass icon with styling
func RenderPath ¶
RenderPath renders a path between two entities
func RenderPriority ¶
RenderPriority renders a priority level with semantic styling Format: ● P0 (icon + label) P0/P1 get color; P2/P3/P4 use standard text
func RenderPriorityCompact ¶
RenderPriorityCompact renders just the priority label without icon Use when space is constrained or icon would be redundant
func RenderPriorityForStatus ¶
RenderPriorityForStatus renders priority with color only if not closed
func RenderResultsWithContext ¶
func RenderResultsWithContext(query string, results []SearchResultItem, related []string, neighbors []string, width int, strategy string, explain bool) string
RenderResultsWithContext renders the search results with headers and tables
func RenderSeparator ¶
func RenderSeparator() string
RenderSeparator renders the light separator line in muted color
func RenderSkipIcon ¶
func RenderSkipIcon() string
RenderSkipIcon renders the skip icon with styling
func RenderStatus ¶
RenderStatus renders a status with semantic styling in_progress/blocked/pinned get color; open/closed use standard text
func RenderStatusIcon ¶
RenderStatusIcon returns the appropriate icon for a status with semantic coloring This is the canonical source for status icon rendering - use this everywhere
func RenderType ¶
RenderType renders an issue type with semantic styling bugs and epics get color; all other types use standard text Note: Gas Town-specific types (agent, role, rig) now fall through to default
func RenderTypeForStatus ¶
RenderTypeForStatus renders type with color only if not closed
func RenderTypoCorrection ¶
func RenderTypoCorrection(query, corrected string, results []SearchResultItem, width int) string
RenderTypoCorrection renders the typo correction view
func RenderWarn ¶
RenderWarn renders text with warning (yellow) styling
func RenderWarnIcon ¶
func RenderWarnIcon() string
RenderWarnIcon renders the warning icon with styling
func ShouldUseColor ¶
func ShouldUseColor() bool
ShouldUseColor determines if ANSI color codes should be used. Respects standard conventions:
- NO_COLOR: https://no-color.org/ - disables color if set
- CLICOLOR=0: disables color
- CLICOLOR_FORCE: forces color even in non-TTY
- Falls back to TTY detection
func ShouldUseEmoji ¶
func ShouldUseEmoji() bool
ShouldUseEmoji determines if emoji decorations should be used. Disabled in non-TTY mode to keep output machine-readable. Can be controlled with BD_NO_EMOJI environment variable.
func ToPager ¶
func ToPager(content string, opts PagerOptions) error
ToPager pipes content to a pager if appropriate. If pager should not be used (not a TTY, --no-pager, etc.), prints directly. If content fits in terminal, prints directly without pager.
Types ¶
type EvalRun ¶
type EvalRun struct {
ID string
Strategy string
Tools string
TokenCost string
TimeSpent string
Pass string
Score int
Efficiency string // 🔴, 🟠, 🟢
}
EvalRun represents a single session's data for the report
type InitResult ¶
type InitResult struct {
// Database info
DBPath string
Prefix string
RepoID string
CloneID string
// Step results
OrchestrationFiles []string
DevlogSpaceStatus string
DevlogPromptStatus string
AgentRules []string
DevlogHooks []string
HooksInstalled bool
MergeDriverInstalled bool
// Diagnostics
DoctorIssues []string
// Next steps
QuickstartCommands []string
}
InitResult aggregates all information from the initialization process
type PagerOptions ¶
type PagerOptions struct {
// NoPager disables pager for this command (--no-pager flag)
NoPager bool
}
PagerOptions controls pager behavior
type SearchResultItem ¶
type SearchResultItem struct {
ID string
Title string
Date string
Narrative string
Reason string
// Explanation fields
Score float64
BM25 float64
PhraseBonus float64
NearBonus float64
EntityBonus float64
RecencyBonus float64
IsLowConfidence bool
// Lifecycle fields
LifecycleStatus string
StatusReason string
IsValidated bool
Author string
AuthorEmail string
Agent string
Branch string
}
SearchResultItem represents a search result for rendering