Documentation
¶
Overview ¶
Package ui provides terminal styling for gastown CLI output. Uses the Ayu color theme with adaptive light/dark mode support. Design philosophy: semantic colors that communicate meaning at a glance, minimal visual noise, and consistent rendering across all commands.
Index ¶
- Constants
- Variables
- func GetStatusIcon(status string) string
- func GetStatusStyle(status string) lipgloss.Style
- func IsAgentMode() bool
- func IsTerminal() 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 RenderFail(s string) string
- func RenderFailIcon() string
- func RenderID(id string) string
- func RenderInfoIcon() string
- func RenderIssueCompact(id string, priority int, issueType, status, title string) string
- func RenderMarkdown(markdown string) string
- func RenderMuted(s string) string
- func RenderPass(s string) string
- func RenderPassIcon() string
- func RenderPriority(priority int) string
- func RenderPriorityCompact(priority int) string
- func RenderPriorityForStatus(priority int, status 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 RenderWarn(s string) string
- func RenderWarnIcon() string
- func ShouldUseColor() bool
- func ShouldUseEmoji() bool
- func ToPager(content string, opts PagerOptions) error
- type PagerOptions
Constants ¶
const ( IconPass = "✓" IconWarn = "⚠" IconFail = "✖" IconSkip = "-" IconInfo = "ℹ" )
Status icons - consistent semantic indicators Design: small Unicode symbols, NOT emoji-style icons for visual consistency
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
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 - 42 characters wide
const PriorityIcon = "●"
Priority icon - small filled circle, colored by priority level
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 === // P0/P1/P2 get color - they need attention // P3/P4 are neutral (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 - P0 is bold for extra emphasis
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 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 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
func IsAgentMode ¶
func IsAgentMode() bool
IsAgentMode returns true if the CLI is running in agent-optimized mode. This is triggered by:
- GT_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 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 RenderFailIcon ¶
func RenderFailIcon() string
RenderFailIcon renders the fail icon with styling
func RenderInfoIcon ¶
func RenderInfoIcon() string
RenderInfoIcon renders the info icon with styling
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 with glamour styling. Returns raw markdown on failure for graceful degradation.
func RenderMuted ¶
RenderMuted renders text with muted (gray) styling
func RenderPass ¶
RenderPass renders text with pass (green) styling
func RenderPassIcon ¶
func RenderPassIcon() string
RenderPassIcon renders the pass icon with styling
func RenderPriority ¶
RenderPriority renders a priority level with semantic styling Format: "● P0" (icon + label) P0/P1/P2 get color; P3/P4 use standard text
func RenderPriorityCompact ¶
RenderPriorityCompact renders just the priority label without icon Format: "P0" Use when space is constrained or icon would be redundant
func RenderPriorityForStatus ¶
RenderPriorityForStatus renders priority with color only if not closed
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
func RenderTypeForStatus ¶
RenderTypeForStatus renders type with color only if not closed
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 NO_COLOR (https://no-color.org/), CLICOLOR, and CLICOLOR_FORCE conventions.
func ShouldUseEmoji ¶
func ShouldUseEmoji() bool
ShouldUseEmoji determines if emoji decorations should be used. Disabled in non-TTY mode to keep output machine-readable.
func ToPager ¶
func ToPager(content string, opts PagerOptions) error
ToPager pipes content to a pager if appropriate. Prints directly if pager is disabled, stdout is not a TTY, or content fits in terminal.
Types ¶
type PagerOptions ¶
type PagerOptions struct {
// NoPager disables pager for this command (--no-pager flag)
NoPager bool
}
PagerOptions configures pager behavior for command output.