console

package
v0.68.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 16, 2026 License: MIT Imports: 19 Imported by: 0

README

Console Package

The console package provides utilities for formatting and rendering terminal output in GitHub Agentic Workflows. It covers message formatting, table and section rendering, interactive prompts, progress bars, spinners, struct rendering, and accessibility support.

Design Philosophy

This package follows Charmbracelet best practices for terminal UI:

  • Adaptive Colors: All styling uses lipgloss.AdaptiveColor for light/dark theme support
  • Rounded Borders: Tables and boxes use rounded corners (╭╮╰╯) for a polished appearance
  • Consistent Padding: All rendered elements include proper spacing (horizontal and vertical)
  • TTY Detection: Automatically adapts output for terminals vs pipes/redirects
  • Visual Hierarchy: Clear separation between sections using borders and spacing
  • Zebra Striping: Tables use alternating row colors for improved readability
Border Usage Guidelines
  • RoundedBorder (primary): Use for tables, boxes, and panels
    • Creates a polished, modern appearance
    • Consistent with Charmbracelet design language
  • NormalBorder (subtle): Use for left-side emphasis on info sections
    • Provides gentle visual guidance without overwhelming
  • ThickBorder (reserved): Available for special cases requiring extra emphasis
    • Use sparingly - rounded borders with bold text usually suffice
Padding Guidelines
  • Table cells: 1 character horizontal padding (left/right)
  • Boxes: 2 character horizontal padding, 0-1 vertical padding
  • Info sections: 2 character left padding for consistent indentation

Spinner Component

The Spinner component provides animated visual feedback during long-running operations with automatic TTY detection and accessibility support.

Features
  • MiniDot animation: Minimal dot spinner (⣾ ⣽ ⣻ ⢿ ⡿ ⣟ ⣯ ⣷)
  • TTY detection: Automatically disabled in pipes/redirects
  • Accessibility support: Respects ACCESSIBLE environment variable
  • Color adaptation: Uses adaptive colors for light/dark themes
  • Idiomatic Bubble Tea: Uses tea.NewProgram() with proper message passing
  • Thread-safe: Safe for concurrent use via Bubble Tea's message handling
Usage
import "github.com/github/gh-aw/pkg/console"

// Create and use a spinner
spinner := console.NewSpinner("Loading...")
spinner.Start()
// Long-running operation
spinner.Stop()

// Stop with a message
spinner := console.NewSpinner("Processing...")
spinner.Start()
// Long-running operation
spinner.StopWithMessage("✓ Done!")

// Update message while running
spinner := console.NewSpinner("Starting...")
spinner.Start()
spinner.UpdateMessage("Still working...")
// Long-running operation
spinner.Stop()
Accessibility

The spinner respects the ACCESSIBLE environment variable. When 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
TTY Detection

Spinners only animate in terminal environments. When output is piped or redirected, the spinner is automatically disabled:

gh aw compile workflow.md           # Spinner animates
gh aw compile workflow.md > log.txt # Spinner disabled

ProgressBar Component

The ProgressBar component provides a reusable progress bar with TTY detection and graceful fallback for non-TTY environments.

Features
  • Scaled gradient effect: Smooth color transition from purple to cyan as progress advances
  • TTY detection: Automatically adapts to terminal environment
  • Byte formatting: Converts byte counts to human-readable sizes (KB, MB, GB)
  • Thread-safe updates: Safe for concurrent use with atomic operations
Visual Styling

The progress bar uses bubbles v0.21.0+ gradient capabilities for enhanced visual appeal:

  • Start (0%): #BD93F9 (purple) - vibrant, attention-grabbing
  • End (100%): #8BE9FD (cyan) - cool, completion feeling
  • Empty portion: #6272A4 (muted purple-gray)
  • Gradient scaling: WithScaledGradient ensures gradient scales with filled portion
Usage
Determinate Mode (known total)

Use when the total size or count is known:

import "github.com/github/gh-aw/pkg/console"

// Create a progress bar for 1GB total
totalBytes := int64(1024 * 1024 * 1024)
bar := console.NewProgressBar(totalBytes)

// Update progress (returns formatted string)
output := bar.Update(currentBytes)
fmt.Fprintf(os.Stderr, "\r%s", output)
Indeterminate Mode (unknown total)

Use when the total size or count is unknown:

import "github.com/github/gh-aw/pkg/console"

// Create an indeterminate progress bar
bar := console.NewIndeterminateProgressBar()

// Update with current progress (shows activity without percentage)
output := bar.Update(currentBytes)
fmt.Fprintf(os.Stderr, "\r%s", output)
Output Examples

Determinate Mode - TTY:

████████████████████░░░░░░░░░░░░░░░░░  50%

(Displays with gradient from purple to cyan)

Determinate Mode - Non-TTY:

50% (512.0MB/1.00GB)

Indeterminate Mode - TTY:

████████████████░░░░░░░░░░░░░░░░░░░░  (pulsing animation)

(Shows pulsing progress indicator)

Indeterminate Mode - Non-TTY:

Processing... (512.0MB)

RenderStruct Function

The RenderStruct function uses reflection to automatically render Go structs based on struct tags.

Struct Tags

Use the console struct tag to control rendering behavior:

Available Tags
  • header:"Column Name" - Sets the display name for the field (used in both structs and tables)
  • title:"Section Title" - Sets the title for nested structs, slices, or maps
  • omitempty - Skips the field if it has a zero value
  • "-" - Always skips the field
Tag Examples
type Overview struct {
    RunID      int64  `console:"header:Run ID"`
    Workflow   string `console:"header:Workflow"`
    Status     string `console:"header:Status"`
    Duration   string `console:"header:Duration,omitempty"`
    Internal   string `console:"-"` // Never displayed
}
Rendering Behavior
Structs

Structs are rendered as key-value pairs with proper alignment:

  Run ID    : 12345
  Workflow  : my-workflow
  Status    : completed
  Duration  : 5m30s
Slices

Slices of structs are automatically rendered as tables using the console table renderer:

type Job struct {
    Name       string `console:"header:Name"`
    Status     string `console:"header:Status"`
    Conclusion string `console:"header:Conclusion,omitempty"`
}

jobs := []Job{
    {Name: "build", Status: "completed", Conclusion: "success"},
    {Name: "test", Status: "in_progress", Conclusion: ""},
}

fmt.Print(console.RenderStruct(jobs))

Renders as:

Name  | Status      | Conclusion
----- | ----------- | ----------
build | completed   | success
test  | in_progress | -
Maps

Maps are rendered as markdown-style headers with key-value pairs:

data := map[string]string{
    "Repository": "github/gh-aw",
    "Author":     "test-user",
}

fmt.Print(console.RenderStruct(data))

Renders as:

  Repository: github/gh-aw
  Author    : test-user
Special Type Handling
time.Time

time.Time fields are automatically formatted as "2006-01-02 15:04:05". Zero time values are considered empty when used with omitempty.

Unexported Fields

The rendering system safely handles unexported struct fields by checking CanInterface() before attempting to access field values.

Usage in Audit Command

The audit command uses the new rendering system for structured output:

// Render overview section
renderOverview(data.Overview)

// Render metrics with custom formatting
renderMetrics(data.Metrics)

// Render jobs as a table
renderJobsTable(data.Jobs)

This provides:

  • Consistent formatting across all audit sections
  • Automatic table generation for slice data
  • Proper handling of optional/empty fields
  • Type-safe reflection-based rendering
Migration Guide

To migrate existing rendering code to use the new system:

  1. Add struct tags to your data types:

    type MyData struct {
        Field1 string `console:"header:Field 1"`
        Field2 int    `console:"header:Field 2,omitempty"`
    }
    
  2. Use RenderStruct for simple structs:

    fmt.Print(console.RenderStruct(myData))
    
  3. Use custom rendering for special formatting needs:

    func renderMyData(data MyData) {
        fmt.Printf("  %-15s %s\n", "Field 1:", formatCustom(data.Field1))
        // ... custom formatting logic
    }
    
  4. Use console.RenderTable for tables with custom formatting:

    config := console.TableConfig{
        Headers: []string{"Name", "Value"},
        Rows: [][]string{
            {truncateString(item.Name, 40), formatNumber(item.Value)},
        },
    }
    fmt.Print(console.RenderTable(config))
    

Message Formatting Functions

All Format* functions return a styled string ready to be printed to os.Stderr. Colors adapt automatically to the terminal background.

Function Style Typical use
FormatSuccessMessage(message string) string Green, bold Operation completed successfully
FormatInfoMessage(message string) string Cyan, bold General informational output
FormatWarningMessage(message string) string Orange, bold Non-fatal warnings
FormatErrorMessage(message string) string Red, bold Recoverable error messages
FormatCommandMessage(command string) string Purple CLI commands and code snippets
FormatProgressMessage(message string) string Yellow In-progress status updates
FormatPromptMessage(message string) string Cyan Interactive prompt labels
FormatVerboseMessage(message string) string Muted/comment Verbose/debug detail
FormatListItem(item string) string Foreground Individual list entries
FormatListHeader(header string) string Plain (WASM only) Section headers inside lists
FormatSectionHeader(header string) string Bold, bordered Section titles in output
FormatLocationMessage(message string) string Foreground (WASM only) File and location paths
FormatCountMessage(message string) string Foreground (WASM only) Counts and metrics
Usage Pattern
import (
    "fmt"
    "os"
    "github.com/github/gh-aw/pkg/console"
)

// Always write formatted messages to stderr
fmt.Fprintln(os.Stderr, console.FormatSuccessMessage("Workflow compiled successfully"))
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("Processing 3 files..."))
fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Network access is unrestricted"))
fmt.Fprintln(os.Stderr, console.FormatErrorMessage("File not found: workflow.md"))
fmt.Fprintln(os.Stderr, console.FormatCommandMessage("gh aw compile workflow.md"))
fmt.Fprintln(os.Stderr, console.FormatProgressMessage("Downloading release..."))

Error Formatting

FormatError(err CompilerError) string

Formats a structured CompilerError with position information, source context lines, and an optional fix hint. Used by the compiler to display actionable error messages.

err := console.CompilerError{
    Position: console.ErrorPosition{File: "workflow.md", Line: 12, Column: 5},
    Type:     "error",
    Message:  "unknown engine: 'myengine'",
    Context:  []string{"engine: myengine"},
    Hint:     "Valid engines are: copilot, claude, codex, gemini",
}
fmt.Fprint(os.Stderr, console.FormatError(err))
FormatErrorChain(err error) string

Formats an error together with its entire %w-wrapped cause chain. Each level of the chain is shown on a new indented line for easy debugging.

fmt.Fprintln(os.Stderr, console.FormatErrorChain(err))

Section Rendering Functions

These functions return []string slices (lines of output) that can be composed using RenderComposedSections.

RenderTitleBox(title string, width int) []string

Returns a rounded-border box containing title, padded to at least width characters.

RenderErrorBox(title string) []string

Returns a red-bordered error box displaying title.

RenderInfoSection(content string) []string

Returns content wrapped in a left-bordered info section with muted styling.

RenderComposedSections(sections []string)

Prints multiple rendered sections to os.Stderr, separated by blank lines.

lines := append(
    console.RenderTitleBox("Audit Report", 60),
    console.RenderInfoSection("3 jobs completed")...,
)
console.RenderComposedSections(lines)
RenderTable(config TableConfig) string

Renders a formatted table with optional title and total row. See the TableConfig type for configuration options.

table := console.RenderTable(console.TableConfig{
    Headers: []string{"Name", "Status", "Duration"},
    Rows: [][]string{
        {"build", "success", "1m30s"},
        {"test",  "failure", "45s"},
    },
    Title: "Job Results",
})
fmt.Print(table)
RenderTree(root TreeNode) string

Renders a TreeNode hierarchy as an indented tree string.

tree := console.RenderTree(console.TreeNode{
    Value: "root",
    Children: []console.TreeNode{
        {Value: "child1"},
        {Value: "child2", Children: []console.TreeNode{{Value: "grandchild"}}},
    },
})
fmt.Print(tree)

Types

CompilerError

Structured error with source position, type, message, context lines, and a fix hint.

type CompilerError struct {
    Position ErrorPosition // Source file position
    Type     string        // "error", "warning", "info"
    Message  string
    Context  []string      // Source lines shown around the error
    Hint     string        // Optional actionable fix suggestion
}
ErrorPosition
type ErrorPosition struct {
    File   string
    Line   int
    Column int
}
TableConfig
type TableConfig struct {
    Headers   []string
    Rows      [][]string
    Title     string   // Optional table title
    ShowTotal bool     // Display a total row
    TotalRow  []string // Content for the total row
}
TreeNode

Represents a node in a hierarchical tree for tree-style rendering.

type TreeNode struct {
    Value    string
    Children []TreeNode
}
SelectOption

A labeled option for interactive select fields.

type SelectOption struct {
    Label string
    Value string
}
FormField

Configuration for a single field in an interactive form.

type FormField struct {
    Type        string             // "input", "password", "confirm", "select"
    Title       string
    Description string
    Placeholder string
    Value       any                // Pointer to the field's result value
    Options     []SelectOption     // For "select" type
    Validate    func(string) error // For "input" and "password" types
}
ListItem

An item in an interactive list with title, description, and an internal value. Create with NewListItem(title, description, value string).

Interactive Prompts

ConfirmAction(title, affirmative, negative string) (bool, error)

Displays an interactive yes/no confirmation dialog using the huh library. Returns true when the user selects affirmative.

confirmed, err := console.ConfirmAction(
    "Delete all compiled workflows?",
    "Yes, delete",
    "Cancel",
)
if err != nil || !confirmed {
    return
}

Note: ConfirmAction is only available in non-WASM builds. In WASM environments the function is unavailable.

ShowInteractiveList(title string, items []ListItem) (string, error)

Displays an interactive single-selection list using arrow key navigation. Returns the value of the selected ListItem. Returns an error if the list is empty or the prompt is cancelled. Falls back to a numbered text list in non-TTY environments.

items := []console.ListItem{
    console.NewListItem("Option A", "First choice", "a"),
    console.NewListItem("Option B", "Second choice", "b"),
}
selected, err := console.ShowInteractiveList("Pick one", items)
PromptInput(title, description, placeholder string) (string, error)

Displays a single-line text input prompt. Returns the entered string or an error.

value, err := console.PromptInput("Repository name", "Enter the full owner/repo", "owner/repo")

Note: PromptInput is only available in WASM builds. Use huh forms directly in non-WASM builds.

PromptSecretInput(title, description string) (string, error)

Displays a masked password/secret input prompt. The entered value is hidden as the user types. Returns the entered secret or an error.

token, err := console.PromptSecretInput("GitHub Token", "Enter your personal access token")

Note: In non-WASM builds this requires a TTY on stderr; in WASM builds it always returns an error.

PromptInputWithValidation(title, description, placeholder string, validate func(string) error) (string, error)

Like PromptInput but accepts a validation function that is called on the entered value before the form is submitted.

value, err := console.PromptInputWithValidation(
    "Workflow name", "Must be kebab-case", "my-workflow",
    func(s string) error {
        if s == "" {
            return errors.New("name cannot be empty")
        }
        return nil
    },
)

Note: PromptInputWithValidation is only available in WASM builds.

PromptSelect(title, description string, options []SelectOption) (string, error)

Displays a single-select dropdown prompt. Returns the Value of the chosen SelectOption or an error.

opt, err := console.PromptSelect(
    "Engine", "Choose an AI engine",
    []console.SelectOption{
        {Label: "Copilot", Value: "copilot"},
        {Label: "Claude",  Value: "claude"},
    },
)

Note: PromptSelect is only available in WASM builds.

PromptMultiSelect(title, description string, options []SelectOption, limit int) ([]string, error)

Displays a multi-select prompt. Returns a slice of selected Value strings or an error. Pass limit ≤ 0 for no selection limit.

selected, err := console.PromptMultiSelect(
    "Toolsets", "Choose toolsets to enable",
    []console.SelectOption{
        {Label: "Default", Value: "default"},
        {Label: "Issues",  Value: "issues"},
        {Label: "PRs",     Value: "pull_requests"},
    },
    0,
)

Note: PromptMultiSelect is only available in WASM builds.

RunForm(fields []FormField) error

Runs a multi-field interactive form defined by a slice of FormField values. Populates the Value pointer of each field and returns an error if the form is cancelled or fails.

var name, token string
err := console.RunForm([]console.FormField{
    {Type: "input",    Title: "Name",  Value: &name},
    {Type: "password", Title: "Token", Value: &token},
})

Note: RunForm is only available in WASM builds. Use huh forms directly in non-WASM builds.

Layout Functions

These functions compose styled sections for terminal output. They are available only in WASM builds; non-WASM code should use the RenderTitleBox, RenderInfoSection, and RenderComposedSections functions instead.

LayoutTitleBox(title string, width int) string

Returns a title box string of at least width characters containing title.

header := console.LayoutTitleBox("Audit Report", 60)
fmt.Fprintln(os.Stderr, header)
LayoutInfoSection(label, value string) string

Returns a formatted label: value line with consistent indentation.

line := console.LayoutInfoSection("Repository", "github/gh-aw")
fmt.Fprintln(os.Stderr, line)
LayoutEmphasisBox(content string, color any) string

Returns content wrapped in an emphasis box. The color parameter is reserved for future use (for example, to pass a lipgloss.Color value) and is currently ignored by the WASM implementation.

box := console.LayoutEmphasisBox("Important notice", nil)
fmt.Fprintln(os.Stderr, box)
LayoutJoinVertical(sections ...string) string

Joins multiple rendered section strings with newlines.

output := console.LayoutJoinVertical(header, body, footer)
fmt.Fprintln(os.Stderr, output)

Terminal Control Functions

These functions emit ANSI control sequences to manage the terminal display. They are no-ops when stderr is not a TTY.

ClearScreen()

Clears the terminal screen and moves the cursor to the home position.

console.ClearScreen()
ClearLine()

Clears the current terminal line (moves to start of line and erases to end).

console.ClearLine()
fmt.Fprint(os.Stderr, "Updated status...")
ShowWelcomeBanner(description string)

Clears the screen and displays the gh aw welcome banner followed by description. Use at the start of interactive commands for a consistent onboarding experience.

console.ShowWelcomeBanner("Let's create your first agentic workflow.")

Verbose Logging

LogVerbose(verbose bool, message string)

Writes message as a FormatVerboseMessage to os.Stderr when verbose is true. This is a convenience helper that avoids repetitive if verbose guards throughout the codebase.

console.LogVerbose(cfg.Verbose, "Loaded 12 workflow files")

Utility Functions

FormatFileSize(size int64) string

Formats a byte count as a human-readable string with appropriate unit suffix.

console.FormatFileSize(0)              // "0 B"
console.FormatFileSize(1500)           // "1.5 KB"
console.FormatFileSize(2_100_000)      // "2.0 MB"
FormatNumber(n int) string

Formats a large integer as a compact human-readable string using SI suffixes (k, M, B).

console.FormatNumber(0)          // "0"
console.FormatNumber(999)        // "999"
console.FormatNumber(1500)       // "1.50k"
console.FormatNumber(1_200_000)  // "1.20M"
ToRelativePath(path string) string

Converts an absolute path to a path relative to the current working directory. If the relative path would require traversing parent directories (..), the original absolute path is returned unchanged.

// When cwd is /home/user/projects:
console.ToRelativePath("/home/user/projects/workflow.md")  // "workflow.md"
console.ToRelativePath("/etc/hosts")                       // "/etc/hosts"
FormatErrorWithSuggestions(message string, suggestions []string) string

Formats an error message followed by a bulleted list of actionable suggestions. Returns an empty suggestions block when suggestions is nil or empty.

msg := console.FormatErrorWithSuggestions(
    "Unknown engine 'myengine'",
    []string{
        "Valid engines are: copilot, claude, codex",
        "Check your workflow frontmatter",
    },
)
fmt.Fprint(os.Stderr, msg)
FormatBanner() string

Returns the gh aw ASCII art banner as a styled string.

PrintBanner()

Prints the banner to os.Stderr.

Accessibility

IsAccessibleMode() bool

Returns true when the terminal is in accessibility mode based on environment variables:

  • ACCESSIBLE is set (any value)
  • TERM is "dumb"
  • NO_COLOR is set (any value)

When accessibility mode is active:

  • Spinner animations are disabled.
  • The huh confirmation dialog uses accessible (plain-text) mode.
  • All Format* functions still work normally but rendered output may differ if called with lipgloss styles.
if console.IsAccessibleMode() {
    // Use simpler, non-animated output
}

Documentation

Overview

Package console provides terminal UI components and formatting utilities for the gh-aw CLI.

Naming Convention: Format* vs Render*

Functions in this package follow a consistent naming convention:

  • Format* functions return a formatted string for a single item or message. They are pure string transformations with no side effects. Examples: FormatSuccessMessage, FormatErrorMessage, FormatFileSize, FormatCommandMessage, FormatProgressMessage.

  • Render* functions produce multi-element or structured output (tables, boxes, trees, structs). They may return strings, slices of strings, or write directly to output. They are used when the output requires layout or structural composition. Examples: RenderTable, RenderStruct, RenderTitleBox, RenderErrorBox, RenderInfoSection, RenderTree, RenderComposedSections.

Output Routing

All diagnostic output (messages, warnings, errors) should be written to stderr. Structured data output (JSON, hashes, graphs) should be written to stdout. Use fmt.Fprintln(os.Stderr, ...) with the Format* helpers for diagnostic output.

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

Implementation

This spinner uses idiomatic Bubble Tea patterns with tea.NewProgram() for proper message handling and rendering pipeline integration. It includes thread-safe lifecycle management:

  • Thread-safe start/stop tracking with mutex protection
  • Safe to call Stop/StopWithMessage before Start (no-op or message-only)
  • Prevents multiple concurrent Start calls
  • No deadlock when stopping before goroutine initializes
  • Leverages Bubble Tea's message passing for updates

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

Index

Constants

This section is empty.

Variables

View Source
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 ClearLine

func ClearLine()

ClearLine clears the current line in the terminal if stderr is a TTY Uses ANSI escape codes: \r moves cursor to start, \033[K clears to end of line

func ClearScreen

func ClearScreen()

ClearScreen clears the terminal screen if stderr is a TTY Uses ANSI escape codes for cross-platform compatibility

func ConfirmAction

func ConfirmAction(title, affirmative, negative string) (bool, error)

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

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

func FormatCommandMessage(command string) string

FormatCommandMessage formats a command execution message

func FormatError

func FormatError(err CompilerError) string

FormatError formats a CompilerError with Rust-like rendering

func FormatErrorChain added in v0.59.1

func FormatErrorChain(err error) string

FormatErrorChain formats an error and its full unwrapped chain in a reading-friendly way. For wrapped errors (fmt.Errorf with %w), each level of the chain is shown on a new indented line. For errors whose message contains newlines (e.g. errors.Join), each line is indented after the first.

func FormatErrorMessage

func FormatErrorMessage(message string) string

FormatErrorMessage formats a simple error message (for stderr output)

func FormatErrorWithSuggestions

func FormatErrorWithSuggestions(message string, suggestions []string) string

FormatErrorWithSuggestions formats an error message with actionable suggestions

func FormatFileSize

func FormatFileSize(size int64) string

FormatFileSize formats file sizes in a human-readable way (e.g., "1.2 KB", "3.4 MB")

func FormatInfoMessage

func FormatInfoMessage(message string) string

FormatInfoMessage formats an informational message

func FormatListItem

func FormatListItem(item string) string

FormatListItem formats an item in a list

func FormatNumber

func FormatNumber(n int) string

FormatNumber formats large numbers in a human-readable way (e.g., "1k", "1.2k", "1.12M")

func FormatProgressMessage

func FormatProgressMessage(message string) string

FormatProgressMessage formats a progress/activity message

func FormatPromptMessage

func FormatPromptMessage(message string) string

FormatPromptMessage formats a user prompt message

func FormatSectionHeader

func FormatSectionHeader(header string) string

FormatSectionHeader formats a section header with proper styling

func FormatSuccessMessage

func FormatSuccessMessage(message string) string

FormatSuccessMessage formats a success message with styling

func FormatVerboseMessage

func FormatVerboseMessage(message string) string

FormatVerboseMessage formats verbose debugging output

func FormatWarningMessage

func FormatWarningMessage(message string) string

FormatWarningMessage formats a warning message

func IsAccessibleMode

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 LogVerbose

func LogVerbose(verbose bool, message string)

LogVerbose outputs a verbose message to stderr only when verbose mode is enabled. This is a convenience helper to avoid repetitive if-verbose checks throughout the codebase.

func PrintBanner

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 PromptSecretInput added in v0.42.14

func PromptSecretInput(title, description string) (string, error)

PromptSecretInput shows an interactive password input prompt with masking The input is masked for security and includes validation Returns the entered secret value or an error

func RenderComposedSections

func RenderComposedSections(sections []string)

RenderComposedSections composes and outputs a slice of sections to stderr

func RenderErrorBox

func RenderErrorBox(title string) []string

RenderErrorBox renders an error/warning message with a rounded border box

func RenderInfoSection

func RenderInfoSection(content string) []string

RenderInfoSection renders an info section with left border emphasis

func RenderStruct

func RenderStruct(v any) string

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 RenderTitleBox

func RenderTitleBox(title string, width int) []string

RenderTitleBox renders a title with a double border box in TTY mode

func ShowInteractiveList

func ShowInteractiveList(title string, items []ListItem) (string, error)

ShowInteractiveList displays an interactive list using huh.Select with arrow key navigation. Returns the selected item's value, or an error if cancelled or failed.

Use this for standalone pickers outside a form context; prefer huh.Select directly when building a multi-field form with WithTheme/WithAccessible applied to the whole form.

func ShowWelcomeBanner added in v0.45.5

func ShowWelcomeBanner(description string)

ShowWelcomeBanner clears the screen and displays the welcome banner for interactive commands. Use this at the start of interactive commands (add, trial, init) for a consistent experience.

func ToRelativePath

func ToRelativePath(path string) string

ToRelativePath converts an absolute path to a relative path from the current working directory If the relative path contains "..", returns the absolute path instead for clarity

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

type ErrorPosition struct {
	File   string
	Line   int
	Column int
}

ErrorPosition represents a position in a source file

type FormField added in v0.42.14

type FormField struct {
	Type        string // "input", "password", "confirm", "select"
	Title       string
	Description string
	Placeholder string
	Value       any                // Pointer to the value to store the result
	Options     []SelectOption     // For select fields
	Validate    func(string) error // For input/password fields
}

FormField represents a generic form field configuration

type ListItem

type ListItem struct {
	// contains filtered or unexported fields
}

ListItem represents an item in an interactive list

func NewListItem

func NewListItem(title, description, value string) ListItem

NewListItem creates a new list item with title, description, and value

type ProgressBar

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 color blend effect from purple to cyan (adaptive for light/dark terminals)
  • Smooth color transitions using bubbles v2 blend capabilities
  • Blend 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 NewProgressBar

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

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 SelectOption added in v0.42.14

type SelectOption struct {
	Label string
	Value string
}

SelectOption represents a selectable option with a label and value

type SpinnerWrapper

type SpinnerWrapper struct {
	// contains filtered or unexported fields
}

SpinnerWrapper wraps the spinner functionality with TTY detection and Bubble Tea program

func NewSpinner

func NewSpinner(message string) *SpinnerWrapper

NewSpinner creates a new spinner with the given message using MiniDot style. Automatically disabled when not running in a TTY or when ACCESSIBLE env var is set.

func (*SpinnerWrapper) Start

func (s *SpinnerWrapper) Start()

func (*SpinnerWrapper) Stop

func (s *SpinnerWrapper) Stop()

func (*SpinnerWrapper) StopWithMessage

func (s *SpinnerWrapper) StopWithMessage(msg string)

func (*SpinnerWrapper) UpdateMessage

func (s *SpinnerWrapper) UpdateMessage(message string)

type TableConfig

type TableConfig struct {
	Headers   []string
	Rows      [][]string
	Title     string
	ShowTotal bool
	TotalRow  []string
}

TableConfig represents configuration for table rendering

type TreeNode

type TreeNode struct {
	Value    string
	Children []TreeNode
}

TreeNode represents a node in a hierarchical tree structure

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL