Documentation
¶
Overview ¶
Package console provides layout composition helpers for creating styled CLI output with Lipgloss.
Layout Composition Helpers ¶
The layout package provides reusable helper functions for common Lipgloss layout patterns. These helpers automatically respect TTY detection and provide both styled (TTY) and plain text (non-TTY) output modes.
Usage Example ¶
Here's a complete example showing how to compose a styled CLI output:
import (
"fmt"
"os"
"github.com/githubnext/gh-aw/pkg/console"
"github.com/githubnext/gh-aw/pkg/styles"
)
// Create layout elements
title := console.LayoutTitleBox("Trial Execution Plan", 60)
info1 := console.LayoutInfoSection("Workflow", "test-workflow")
info2 := console.LayoutInfoSection("Status", "Ready")
warning := console.LayoutEmphasisBox("⚠️ WARNING: Large workflow file", styles.ColorWarning)
// Compose sections vertically with spacing
output := console.LayoutJoinVertical(title, "", info1, info2, "", warning)
fmt.Fprintln(os.Stderr, output)
TTY Detection ¶
All layout helpers automatically detect whether output is going to a terminal (TTY) or being piped/redirected. In TTY mode, they use Lipgloss styling with colors and borders. In non-TTY mode, they output plain text suitable for parsing or logging.
Available Helpers ¶
- LayoutTitleBox: Centered title with double border
- LayoutInfoSection: Info section with left border emphasis
- LayoutEmphasisBox: Thick-bordered box with custom color
- LayoutJoinVertical: Composes sections with automatic spacing
Comparison with Existing Functions ¶
These helpers complement the existing RenderTitleBox, RenderInfoSection, and RenderComposedSections functions in console.go. The key differences:
- Layout helpers return strings instead of []string for simpler composition
- LayoutInfoSection takes separate label and value parameters
- LayoutEmphasisBox provides custom color support with thick borders
- Layout helpers are designed for inline composition and chaining
Package console provides terminal UI components including spinners for long-running operations.
Spinner Component ¶
The spinner provides visual feedback during long-running operations with a minimal dot animation (⣾ ⣽ ⣻ ⢿ ⡿ ⣟ ⣯ ⣷). It automatically adapts to the environment:
- TTY Detection: Spinners only animate in terminal environments (disabled in pipes/redirects)
- Accessibility: Respects ACCESSIBLE environment variable to disable animations
- Color Adaptation: Uses lipgloss adaptive colors for light/dark terminal themes
Usage Example ¶
spinner := console.NewSpinner("Loading...")
spinner.Start()
// Long-running operation
spinner.Stop()
Accessibility ¶
Spinners respect the ACCESSIBLE environment variable. When ACCESSIBLE is set to any value, spinner animations are disabled to support screen readers and accessibility tools.
export ACCESSIBLE=1 gh aw compile workflow.md # Spinners will be disabled
Example ¶
Example demonstrates how to compose a styled CLI output using the layout helper functions.
// Create layout elements
title := LayoutTitleBox("Trial Execution Plan", 60)
info1 := LayoutInfoSection("Workflow", "test-workflow")
info2 := LayoutInfoSection("Status", "Ready")
warning := LayoutEmphasisBox("⚠️ WARNING: Large workflow file", styles.ColorWarning)
// Compose sections vertically with spacing
output := LayoutJoinVertical(title, "", info1, info2, "", warning)
// In a real application, you would output to stderr:
// fmt.Fprintln(os.Stderr, output)
// For test purposes, just verify the output contains expected content
if !strings.Contains(output, "Trial Execution Plan") {
panic("missing title")
}
if !strings.Contains(output, "test-workflow") {
panic("missing workflow name")
}
if !strings.Contains(output, "WARNING") {
panic("missing warning")
}
Index ¶
- Variables
- func ClearScreen()
- func ConfirmAction(title, affirmative, negative string) (bool, error)
- func FormatBanner() string
- func FormatCommandMessage(command string) string
- func FormatCountMessage(message string) string
- func FormatError(err CompilerError) string
- func FormatErrorMessage(message string) string
- func FormatErrorWithSuggestions(message string, suggestions []string) string
- func FormatFileSize(size int64) string
- func FormatInfoMessage(message string) string
- func FormatListHeader(header string) string
- func FormatListItem(item string) string
- func FormatLocationMessage(message string) string
- func FormatNumber(n int) string
- func FormatProgressMessage(message string) string
- func FormatPromptMessage(message string) string
- func FormatSectionHeader(header string) string
- func FormatSuccessMessage(message string) string
- func FormatVerboseMessage(message string) string
- func FormatWarningMessage(message string) string
- func IsAccessibleMode() bool
- func LayoutEmphasisBox(content string, color lipgloss.AdaptiveColor) string
- func LayoutInfoSection(label, value string) string
- func LayoutJoinVertical(sections ...string) string
- func LayoutTitleBox(title string, width int) string
- func PrintBanner()
- func RenderComposedSections(sections []string)
- func RenderErrorBox(title string) []string
- func RenderInfoSection(content string) []string
- func RenderStruct(v any) string
- func RenderTable(config TableConfig) string
- func RenderTableAsJSON(config TableConfig) (string, error)
- func RenderTitleBox(title string, width int) []string
- func RenderTree(root TreeNode) string
- func ShowInteractiveList(title string, items []ListItem) (string, error)
- func ToRelativePath(path string) string
- type CompilerError
- type ErrorPosition
- type ListItem
- type ProgressBar
- type SpinnerWrapper
- type TableConfig
- type TreeNode
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var BannerStyle = lipgloss.NewStyle(). Bold(true). Foreground(styles.ColorPurple)
BannerStyle defines the style for the ASCII banner Uses GitHub's purple color theme
Functions ¶
func ClearScreen ¶ added in v0.22.0
func ClearScreen()
ClearScreen clears the terminal screen if stdout is a TTY Uses ANSI escape codes for cross-platform compatibility
func ConfirmAction ¶ added in v0.34.5
ConfirmAction shows an interactive confirmation dialog using Bubble Tea (huh) Returns true if the user confirms, false if they cancel or an error occurs
func FormatBanner ¶ added in v0.31.4
func FormatBanner() string
FormatBanner returns the ASCII logo formatted with purple GitHub color theme. It applies the purple color styling when running in a terminal (TTY).
func FormatCommandMessage ¶
FormatCommandMessage formats a command execution message
func FormatCountMessage ¶
FormatCountMessage formats a count/numeric status message
func FormatError ¶
func FormatError(err CompilerError) string
FormatError formats a CompilerError with Rust-like rendering
func FormatErrorMessage ¶
FormatErrorMessage formats a simple error message (for stderr output)
func FormatErrorWithSuggestions ¶ added in v0.28.7
FormatErrorWithSuggestions formats an error message with actionable suggestions
func FormatFileSize ¶ added in v0.28.3
FormatFileSize formats file sizes in a human-readable way (e.g., "1.2 KB", "3.4 MB")
func FormatInfoMessage ¶
FormatInfoMessage formats an informational message
func FormatListHeader ¶
FormatListHeader formats a section header for lists
func FormatListItem ¶
FormatListItem formats an item in a list
func FormatLocationMessage ¶
FormatLocationMessage formats a file/directory location message
func FormatNumber ¶ added in v0.26.0
FormatNumber formats large numbers in a human-readable way (e.g., "1k", "1.2k", "1.12M")
func FormatProgressMessage ¶
FormatProgressMessage formats a progress/activity message
func FormatPromptMessage ¶
FormatPromptMessage formats a user prompt message
func FormatSectionHeader ¶ added in v0.34.5
FormatSectionHeader formats a section header with proper styling This is used for major sections in CLI output (e.g., "Overview", "Metrics")
func FormatSuccessMessage ¶
FormatSuccessMessage formats a success message with styling
func FormatVerboseMessage ¶
FormatVerboseMessage formats verbose debugging output
func FormatWarningMessage ¶
FormatWarningMessage formats a warning message
func IsAccessibleMode ¶ added in v0.34.5
func IsAccessibleMode() bool
IsAccessibleMode detects if accessibility mode should be enabled based on environment variables. Accessibility mode is enabled when: - ACCESSIBLE environment variable is set to any value - TERM environment variable is set to "dumb" - NO_COLOR environment variable is set to any value
This function should be used by UI components to determine whether to: - Disable animations and spinners - Simplify interactive elements - Use plain text instead of fancy formatting
func LayoutEmphasisBox ¶ added in v0.34.0
func LayoutEmphasisBox(content string, color lipgloss.AdaptiveColor) string
LayoutEmphasisBox renders content in a thick-bordered box with custom color. In TTY mode, uses Lipgloss styled box with thick border. In non-TTY mode, renders content with surrounding marker lines.
Example:
warning := console.LayoutEmphasisBox("⚠️ WARNING: Large workflow", styles.ColorWarning)
fmt.Fprintln(os.Stderr, warning)
func LayoutInfoSection ¶ added in v0.34.0
LayoutInfoSection renders an info section with left border emphasis as a single string. In TTY mode, uses Lipgloss styled section with left border. In non-TTY mode, adds manual indentation. This is a simpler alternative to RenderInfoSection that returns a string and takes label/value.
Example:
info := console.LayoutInfoSection("Workflow", "test-workflow")
fmt.Fprintln(os.Stderr, info)
func LayoutJoinVertical ¶ added in v0.34.0
LayoutJoinVertical composes sections vertically with automatic spacing. In TTY mode, uses lipgloss.JoinVertical for proper composition. In non-TTY mode, joins sections with newlines.
Example:
title := console.LayoutTitleBox("Plan", 60)
info := console.LayoutInfoSection("Status", "Ready")
output := console.LayoutJoinVertical(title, info)
fmt.Fprintln(os.Stderr, output)
func LayoutTitleBox ¶ added in v0.34.0
LayoutTitleBox renders a title with a double border box as a single string. In TTY mode, uses Lipgloss styled box centered with the Info color scheme. In non-TTY mode, renders plain text with separator lines. This is a simpler alternative to RenderTitleBox that returns a string instead of []string.
Example:
title := console.LayoutTitleBox("Trial Execution Plan", 60)
fmt.Fprintln(os.Stderr, title)
func PrintBanner ¶ added in v0.31.4
func PrintBanner()
PrintBanner prints the ASCII logo to stderr with purple GitHub color theme. This is used by the --banner flag to display the logo at the start of command execution.
func RenderComposedSections ¶ added in v0.34.0
func RenderComposedSections(sections []string)
RenderComposedSections composes and outputs a slice of sections to stderr. In TTY mode, uses lipgloss.JoinVertical for proper composition. In non-TTY mode, outputs each section as a separate line. Adds blank lines before and after the output.
func RenderErrorBox ¶ added in v0.34.0
RenderErrorBox renders an error/warning message with a thick border box in TTY mode, or plain text in non-TTY mode. The box will be styled with the Error color scheme for critical messages. Returns a slice of strings ready to be added to sections or printed directly.
func RenderInfoSection ¶ added in v0.34.0
RenderInfoSection renders an info section with left border emphasis in TTY mode, or plain text with manual indentation in non-TTY mode. Returns a slice of strings ready to be added to sections.
func RenderStruct ¶ added in v0.21.0
RenderStruct renders a Go struct to console output using reflection and struct tags. It supports: - Rendering structs as markdown-style headers with key-value pairs - Rendering slices as tables using the console table renderer - Rendering maps as markdown headers
Struct tags: - `console:"title:My Title"` - Sets the title for a section - `console:"header:Column Name"` - Sets the column header name for table columns - `console:"omitempty"` - Skips zero values - `console:"-"` - Skips the field entirely
func RenderTable ¶
func RenderTable(config TableConfig) string
RenderTable renders a formatted table using lipgloss/table package
func RenderTableAsJSON ¶ added in v0.20.0
func RenderTableAsJSON(config TableConfig) (string, error)
RenderTableAsJSON renders a table configuration as JSON This converts the table structure to a JSON array of objects
func RenderTitleBox ¶ added in v0.34.0
RenderTitleBox renders a title with a double border box in TTY mode, or plain text with separator lines in non-TTY mode. The box will be centered and styled with the Info color scheme. Returns a slice of strings ready to be added to sections.
func RenderTree ¶ added in v0.34.0
RenderTree renders a hierarchical tree structure using lipgloss/tree package Returns styled tree output for TTY, or simple indented text for non-TTY
func ShowInteractiveList ¶ added in v0.34.2
ShowInteractiveList displays an interactive list with arrow key navigation Returns the selected item's value, or an error if cancelled or failed
func ToRelativePath ¶
ToRelativePath converts an absolute path to a relative path from the current working directory
Types ¶
type CompilerError ¶
type CompilerError struct {
Position ErrorPosition
Type string // "error", "warning", "info"
Message string
Context []string // Source code lines for context
Hint string // Optional hint for fixing the error
}
CompilerError represents a structured compiler error with position information
type ErrorPosition ¶
ErrorPosition represents a position in a source file
type ListItem ¶ added in v0.34.2
type ListItem struct {
// contains filtered or unexported fields
}
ListItem represents an item in an interactive list
func NewListItem ¶ added in v0.34.2
NewListItem creates a new list item with title, description, and value
func (ListItem) Description ¶ added in v0.34.2
Description returns the item's description
func (ListItem) FilterValue ¶ added in v0.34.2
FilterValue returns the value used for filtering
type ProgressBar ¶ added in v0.34.2
type ProgressBar struct {
// contains filtered or unexported fields
}
ProgressBar provides a reusable progress bar component with TTY detection and graceful fallback to text-based progress for non-TTY environments.
Modes:
- Determinate: When total size is known (shows percentage and progress)
- Indeterminate: When total size is unknown (shows activity indicator)
Visual Features:
- Scaled gradient effect from purple (#BD93F9) to cyan (#8BE9FD)
- Smooth color transitions using bubbles v0.21.0+ gradient capabilities
- Gradient scales with filled portion for enhanced visual feedback
- Works well in both light and dark terminal themes
The gradient provides visual appeal without affecting functionality:
- TTY mode: Visual progress bar with smooth gradient transitions
- Non-TTY mode: Text-based percentage with human-readable byte sizes
func NewIndeterminateProgressBar ¶ added in v0.34.2
func NewIndeterminateProgressBar() *ProgressBar
NewIndeterminateProgressBar creates a progress bar for when the total size is unknown This mode shows activity without a specific completion percentage, useful for:
- Streaming downloads with unknown size
- Processing unknown number of items
- Operations where duration cannot be predicted
The progress bar automatically adapts to TTY/non-TTY environments
func NewProgressBar ¶ added in v0.34.2
func NewProgressBar(total int64) *ProgressBar
NewProgressBar creates a new progress bar with the specified total size (determinate mode) The progress bar automatically adapts to TTY/non-TTY environments
func (*ProgressBar) Update ¶ added in v0.34.2
func (p *ProgressBar) Update(current int64) string
Update updates the current progress and returns a formatted string In determinate mode:
- TTY: Returns a visual progress bar with gradient and percentage
- Non-TTY: Returns text percentage with human-readable sizes
In indeterminate mode:
- TTY: Returns a pulsing progress indicator
- Non-TTY: Returns processing indicator with current value
type SpinnerWrapper ¶
type SpinnerWrapper struct {
// contains filtered or unexported fields
}
SpinnerWrapper wraps the spinner functionality with TTY detection
func NewSpinner ¶
func NewSpinner(message string) *SpinnerWrapper
NewSpinner creates a new spinner with the given message using MiniDot style The spinner is automatically disabled when not running in a TTY or in accessibility mode
func (*SpinnerWrapper) IsEnabled ¶
func (s *SpinnerWrapper) IsEnabled() bool
IsEnabled returns whether the spinner is enabled (i.e., running in a TTY)
func (*SpinnerWrapper) StopWithMessage ¶ added in v0.31.4
func (s *SpinnerWrapper) StopWithMessage(msg string)
StopWithMessage stops the spinner and displays a final message The message will only be displayed if the spinner is enabled (TTY check)
func (*SpinnerWrapper) UpdateMessage ¶
func (s *SpinnerWrapper) UpdateMessage(message string)
UpdateMessage updates the spinner message