cli

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Jan 31, 2026 License: EUPL-1.2 Imports: 21 Imported by: 0

Documentation

Overview

Package cli provides the CLI runtime and utilities.

Package cli provides the CLI runtime and utilities.

Package cli provides the CLI runtime and utilities.

The CLI uses the Core framework for its own runtime. Usage is simple:

cli.Init(cli.Options{AppName: "core"})
defer cli.Shutdown()

cli.Success("Done!")
cli.Error("Failed")
if cli.Confirm("Proceed?") { ... }

// When you need the Core instance
c := cli.Core()

Package cli provides common utilities and styles for CLI commands.

This package contains:

  • Terminal styling using lipgloss with Tailwind colours
  • Unicode symbols for consistent visual indicators
  • Helper functions for common output patterns
  • Git and GitHub CLI utilities

Index

Constants

View Source
const (
	// AppName is the CLI application name.
	AppName = "core"
	// AppVersion is the CLI application version.
	AppVersion = "0.1.0"
)
View Source
const (
	LogLevelQuiet = log.LevelQuiet
	LogLevelError = log.LevelError
	LogLevelWarn  = log.LevelWarn
	LogLevelInfo  = log.LevelInfo
	LogLevelDebug = log.LevelDebug
)
View Source
const (
	ColourBlue50     = lipgloss.Color("#eff6ff")
	ColourBlue100    = lipgloss.Color("#dbeafe")
	ColourBlue200    = lipgloss.Color("#bfdbfe")
	ColourBlue300    = lipgloss.Color("#93c5fd")
	ColourBlue400    = lipgloss.Color("#60a5fa")
	ColourBlue500    = lipgloss.Color("#3b82f6")
	ColourBlue600    = lipgloss.Color("#2563eb")
	ColourBlue700    = lipgloss.Color("#1d4ed8")
	ColourGreen400   = lipgloss.Color("#4ade80")
	ColourGreen500   = lipgloss.Color("#22c55e")
	ColourGreen600   = lipgloss.Color("#16a34a")
	ColourRed400     = lipgloss.Color("#f87171")
	ColourRed500     = lipgloss.Color("#ef4444")
	ColourRed600     = lipgloss.Color("#dc2626")
	ColourAmber400   = lipgloss.Color("#fbbf24")
	ColourAmber500   = lipgloss.Color("#f59e0b")
	ColourAmber600   = lipgloss.Color("#d97706")
	ColourOrange500  = lipgloss.Color("#f97316")
	ColourYellow500  = lipgloss.Color("#eab308")
	ColourEmerald500 = lipgloss.Color("#10b981")
	ColourPurple500  = lipgloss.Color("#a855f7")
	ColourViolet400  = lipgloss.Color("#a78bfa")
	ColourViolet500  = lipgloss.Color("#8b5cf6")
	ColourIndigo500  = lipgloss.Color("#6366f1")
	ColourCyan500    = lipgloss.Color("#06b6d4")
	ColourGray50     = lipgloss.Color("#f9fafb")
	ColourGray100    = lipgloss.Color("#f3f4f6")
	ColourGray200    = lipgloss.Color("#e5e7eb")
	ColourGray300    = lipgloss.Color("#d1d5db")
	ColourGray400    = lipgloss.Color("#9ca3af")
	ColourGray500    = lipgloss.Color("#6b7280")
	ColourGray600    = lipgloss.Color("#4b5563")
	ColourGray700    = lipgloss.Color("#374151")
	ColourGray800    = lipgloss.Color("#1f2937")
	ColourGray900    = lipgloss.Color("#111827")
)

Tailwind colours for consistent theming across the CLI.

View Source
const (
	// Status indicators
	SymbolCheck    = "✓" // Success, pass, complete
	SymbolCross    = "✗" // Error, fail, incomplete
	SymbolWarning  = "⚠" // Warning, caution
	SymbolInfo     = "ℹ" // Information
	SymbolQuestion = "?" // Unknown, needs attention
	SymbolSkip     = "○" // Skipped, neutral
	SymbolDot      = "●" // Active, selected
	SymbolCircle   = "◯" // Inactive, unselected

	// Arrows and pointers
	SymbolArrowRight = "→"
	SymbolArrowLeft  = "←"
	SymbolArrowUp    = "↑"
	SymbolArrowDown  = "↓"
	SymbolPointer    = "▶"

	// Decorative
	SymbolBullet    = "•"
	SymbolDash      = "─"
	SymbolPipe      = "│"
	SymbolCorner    = "└"
	SymbolTee       = "├"
	SymbolSeparator = " │ "

	// Progress
	SymbolSpinner = "⠋" // First frame of braille spinner
	SymbolPending = "…"
)

Symbols for consistent visual indicators across commands.

Variables

View Source
var (
	// RepoNameStyle highlights repository names (blue, bold).
	RepoNameStyle = lipgloss.NewStyle().
					Bold(true).
					Foreground(ColourBlue500)

	// SuccessStyle indicates successful operations (green, bold).
	SuccessStyle = lipgloss.NewStyle().
					Bold(true).
					Foreground(ColourGreen500)

	// ErrorStyle indicates errors and failures (red, bold).
	ErrorStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(ColourRed500)

	// WarningStyle indicates warnings and cautions (amber, bold).
	WarningStyle = lipgloss.NewStyle().
					Bold(true).
					Foreground(ColourAmber500)

	// InfoStyle for informational messages (blue).
	InfoStyle = lipgloss.NewStyle().
				Foreground(ColourBlue400)

	// DimStyle for secondary/muted text (gray).
	DimStyle = lipgloss.NewStyle().
				Foreground(ColourGray500)

	// MutedStyle for very subtle text (darker gray).
	MutedStyle = lipgloss.NewStyle().
				Foreground(ColourGray600)

	// ValueStyle for data values and output (light gray).
	ValueStyle = lipgloss.NewStyle().
				Foreground(ColourGray200)

	// AccentStyle for highlighted values (cyan).
	AccentStyle = lipgloss.NewStyle().
				Foreground(ColourCyan500)

	// LinkStyle for URLs and clickable references (blue, underlined).
	LinkStyle = lipgloss.NewStyle().
				Foreground(ColourBlue500).
				Underline(true)

	// HeaderStyle for section headers (light gray, bold).
	HeaderStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(ColourGray200)

	// TitleStyle for command titles (blue, bold).
	TitleStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(ColourBlue500)

	// BoldStyle for emphasis without colour.
	BoldStyle = lipgloss.NewStyle().
				Bold(true)

	// CodeStyle for inline code or paths.
	CodeStyle = lipgloss.NewStyle().
				Foreground(ColourGray300).
				Background(ColourGray800).
				Padding(0, 1)

	// KeyStyle for labels/keys in key-value pairs.
	KeyStyle = lipgloss.NewStyle().
				Foreground(ColourGray400)

	// NumberStyle for numeric values.
	NumberStyle = lipgloss.NewStyle().
				Foreground(ColourBlue300)

	// PrNumberStyle for pull request numbers (purple, bold).
	PrNumberStyle = lipgloss.NewStyle().
					Bold(true).
					Foreground(ColourPurple500)

	// AccentLabelStyle for highlighted labels (violet).
	AccentLabelStyle = lipgloss.NewStyle().
						Foreground(ColourViolet400)

	// StageStyle for pipeline/QA stage headers (indigo, bold).
	StageStyle = lipgloss.NewStyle().
				Bold(true).
				Foreground(ColourIndigo500)
)

Terminal styles using Tailwind colour palette. These are shared across command packages for consistent output.

View Source
var (
	// StatusPendingStyle for pending/waiting states.
	StatusPendingStyle = lipgloss.NewStyle().Foreground(ColourGray500)

	// StatusRunningStyle for in-progress states.
	StatusRunningStyle = lipgloss.NewStyle().Foreground(ColourBlue500)

	// StatusSuccessStyle for completed/success states.
	StatusSuccessStyle = lipgloss.NewStyle().Foreground(ColourGreen500)

	// StatusErrorStyle for failed/error states.
	StatusErrorStyle = lipgloss.NewStyle().Foreground(ColourRed500)

	// StatusWarningStyle for warning states.
	StatusWarningStyle = lipgloss.NewStyle().Foreground(ColourAmber500)
)
View Source
var (
	// CoverageHighStyle for good coverage (80%+).
	CoverageHighStyle = lipgloss.NewStyle().Foreground(ColourGreen500)

	// CoverageMedStyle for moderate coverage (50-79%).
	CoverageMedStyle = lipgloss.NewStyle().Foreground(ColourAmber500)

	// CoverageLowStyle for low coverage (<50%).
	CoverageLowStyle = lipgloss.NewStyle().Foreground(ColourRed500)
)
View Source
var (
	// PriorityHighStyle for high/critical priority (red, bold).
	PriorityHighStyle = lipgloss.NewStyle().Bold(true).Foreground(ColourRed500)

	// PriorityMediumStyle for medium priority (amber).
	PriorityMediumStyle = lipgloss.NewStyle().Foreground(ColourAmber500)

	// PriorityLowStyle for low priority (green).
	PriorityLowStyle = lipgloss.NewStyle().Foreground(ColourGreen500)
)
View Source
var (
	// SeverityCriticalStyle for critical issues (red, bold).
	SeverityCriticalStyle = lipgloss.NewStyle().Bold(true).Foreground(ColourRed500)

	// SeverityHighStyle for high severity issues (orange, bold).
	SeverityHighStyle = lipgloss.NewStyle().Bold(true).Foreground(ColourOrange500)

	// SeverityMediumStyle for medium severity issues (amber).
	SeverityMediumStyle = lipgloss.NewStyle().Foreground(ColourAmber500)

	// SeverityLowStyle for low severity issues (gray).
	SeverityLowStyle = lipgloss.NewStyle().Foreground(ColourGray500)
)
View Source
var (
	// GitDirtyStyle for uncommitted changes (red).
	GitDirtyStyle = lipgloss.NewStyle().Foreground(ColourRed500)

	// GitAheadStyle for unpushed commits (green).
	GitAheadStyle = lipgloss.NewStyle().Foreground(ColourGreen500)

	// GitBehindStyle for unpulled commits (amber).
	GitBehindStyle = lipgloss.NewStyle().Foreground(ColourAmber500)

	// GitCleanStyle for clean state (gray).
	GitCleanStyle = lipgloss.NewStyle().Foreground(ColourGray500)

	// GitConflictStyle for merge conflicts (red, bold).
	GitConflictStyle = lipgloss.NewStyle().Bold(true).Foreground(ColourRed500)
)
View Source
var (
	// DeploySuccessStyle for successful deployments (emerald).
	DeploySuccessStyle = lipgloss.NewStyle().Foreground(ColourEmerald500)

	// DeployPendingStyle for pending deployments (amber).
	DeployPendingStyle = lipgloss.NewStyle().Foreground(ColourAmber500)

	// DeployFailedStyle for failed deployments (red).
	DeployFailedStyle = lipgloss.NewStyle().Foreground(ColourRed500)
)
View Source
var (
	// BoxStyle creates a rounded border box.
	BoxStyle = lipgloss.NewStyle().
				Border(lipgloss.RoundedBorder()).
				BorderForeground(ColourGray600).
				Padding(0, 1)

	// BoxHeaderStyle for box titles.
	BoxHeaderStyle = lipgloss.NewStyle().
					Bold(true).
					Foreground(ColourBlue400).
					MarginBottom(1)

	// ErrorBoxStyle for error message boxes.
	ErrorBoxStyle = lipgloss.NewStyle().
					Border(lipgloss.RoundedBorder()).
					BorderForeground(ColourRed500).
					Padding(0, 1)

	// SuccessBoxStyle for success message boxes.
	SuccessBoxStyle = lipgloss.NewStyle().
					Border(lipgloss.RoundedBorder()).
					BorderForeground(ColourGreen500).
					Padding(0, 1)
)
View Source
var Style = struct {
	// Text styles
	Dim     lipgloss.Style
	Muted   lipgloss.Style
	Bold    lipgloss.Style
	Value   lipgloss.Style
	Accent  lipgloss.Style
	Code    lipgloss.Style
	Key     lipgloss.Style
	Number  lipgloss.Style
	Link    lipgloss.Style
	Header  lipgloss.Style
	Title   lipgloss.Style
	Stage   lipgloss.Style
	PrNum   lipgloss.Style
	AccentL lipgloss.Style

	// Status styles
	Success lipgloss.Style
	Error   lipgloss.Style
	Warning lipgloss.Style
	Info    lipgloss.Style

	// Git styles
	Dirty    lipgloss.Style
	Ahead    lipgloss.Style
	Behind   lipgloss.Style
	Clean    lipgloss.Style
	Conflict lipgloss.Style

	// Repo name style
	Repo lipgloss.Style

	// Coverage styles
	CoverageHigh lipgloss.Style
	CoverageMed  lipgloss.Style
	CoverageLow  lipgloss.Style

	// Priority styles
	PriorityHigh   lipgloss.Style
	PriorityMedium lipgloss.Style
	PriorityLow    lipgloss.Style

	// Severity styles
	SeverityCritical lipgloss.Style
	SeverityHigh     lipgloss.Style
	SeverityMedium   lipgloss.Style
	SeverityLow      lipgloss.Style

	// Status indicator styles
	StatusPending lipgloss.Style
	StatusRunning lipgloss.Style
	StatusSuccess lipgloss.Style
	StatusError   lipgloss.Style
	StatusWarning lipgloss.Style

	// Deploy styles
	DeploySuccess lipgloss.Style
	DeployPending lipgloss.Style
	DeployFailed  lipgloss.Style

	// Box styles
	Box        lipgloss.Style
	BoxHeader  lipgloss.Style
	ErrorBox   lipgloss.Style
	SuccessBox lipgloss.Style
}{

	Dim:     DimStyle,
	Muted:   MutedStyle,
	Bold:    BoldStyle,
	Value:   ValueStyle,
	Accent:  AccentStyle,
	Code:    CodeStyle,
	Key:     KeyStyle,
	Number:  NumberStyle,
	Link:    LinkStyle,
	Header:  HeaderStyle,
	Title:   TitleStyle,
	Stage:   StageStyle,
	PrNum:   PrNumberStyle,
	AccentL: AccentLabelStyle,

	Success: SuccessStyle,
	Error:   ErrorStyle,
	Warning: WarningStyle,
	Info:    InfoStyle,

	Dirty:    GitDirtyStyle,
	Ahead:    GitAheadStyle,
	Behind:   GitBehindStyle,
	Clean:    GitCleanStyle,
	Conflict: GitConflictStyle,

	Repo: RepoNameStyle,

	CoverageHigh: CoverageHighStyle,
	CoverageMed:  CoverageMedStyle,
	CoverageLow:  CoverageLowStyle,

	PriorityHigh:   PriorityHighStyle,
	PriorityMedium: PriorityMediumStyle,
	PriorityLow:    PriorityLowStyle,

	SeverityCritical: SeverityCriticalStyle,
	SeverityHigh:     SeverityHighStyle,
	SeverityMedium:   SeverityMediumStyle,
	SeverityLow:      SeverityLowStyle,

	StatusPending: StatusPendingStyle,
	StatusRunning: StatusRunningStyle,
	StatusSuccess: StatusSuccessStyle,
	StatusError:   StatusErrorStyle,
	StatusWarning: StatusWarningStyle,

	DeploySuccess: DeploySuccessStyle,
	DeployPending: DeployPendingStyle,
	DeployFailed:  DeployFailedStyle,

	Box:        BoxStyle,
	BoxHeader:  BoxHeaderStyle,
	ErrorBox:   ErrorBoxStyle,
	SuccessBox: SuccessBoxStyle,
}

Styles provides namespaced access to CLI styles. Usage: cli.Style.Dim.Render("text"), cli.Style.Success.Render("done")

Functions

func ArbitraryArgs

func ArbitraryArgs() cobra.PositionalArgs

ArbitraryArgs returns a PositionalArgs that accepts any arguments.

func As

func As(err error, target any) bool

As finds the first error in err's tree that matches target. This is a re-export of errors.As for convenience.

func Bold

func Bold(text string) string

Bold returns bold text.

func BoldStr

func BoldStr(msg string) string

BoldStr returns a bold-styled string.

func BoolFlag

func BoolFlag(cmd *Command, ptr *bool, name, short string, def bool, usage string)

BoolFlag adds a boolean flag to a command. The value will be stored in the provided pointer.

var verbose bool
cli.BoolFlag(cmd, &verbose, "verbose", "v", false, "Enable verbose output")

func Bullet

func Bullet(text string) string

Bullet returns a bulleted item.

func CheckMark

func CheckMark(present bool) string

CheckMark returns a styled checkmark (✓) or dash (—) based on presence. Useful for showing presence/absence in tables and lists.

func CheckMarkCustom

func CheckMarkCustom(present bool, presentStyle, absentStyle lipgloss.Style, presentSymbol, absentSymbol string) string

CheckMarkCustom returns a styled indicator with custom symbols and styles.

func CheckResult

func CheckResult(ok bool, name string, version string) string

CheckResult formats a check result with name and optional version. Used for environment checks like `✓ go 1.22.0` or `✗ docker`.

func Choose

func Choose[T any](prompt string, items []T, opts ...ChooseOption[T]) T

Choose prompts the user to select from a list of items. Returns the selected item. Uses simple numbered selection for terminal compatibility.

choice := Choose("Select a file:", files)
choice := Choose("Select a file:", files, WithDisplay(func(f File) string { return f.Name }))

func ChooseAction

func ChooseAction[T any](verb, subject string, items []T, opts ...ChooseOption[T]) T

ChooseAction prompts for selection using grammar composition.

file := ChooseAction("select", "file", files)

func ChooseMulti

func ChooseMulti[T any](prompt string, items []T, opts ...ChooseOption[T]) []T

ChooseMulti prompts the user to select multiple items from a list. Returns the selected items. Uses space-separated numbers or ranges.

choices := ChooseMulti("Select files:", files)
choices := ChooseMulti("Select files:", files, WithDisplay(func(f File) string { return f.Name }))

Input format:

  • "1 3 5" - select items 1, 3, and 5
  • "1-3" - select items 1, 2, and 3
  • "1 3-5" - select items 1, 3, 4, and 5
  • "" (empty) - select none

func ChooseMultiAction

func ChooseMultiAction[T any](verb, subject string, items []T, opts ...ChooseOption[T]) []T

ChooseMultiAction prompts for multiple selections using grammar composition.

files := ChooseMultiAction("select", "files", files)

func CommandStr

func CommandStr(cmd string) string

CommandStr renders a command string in code style.

func Confirm

func Confirm(prompt string, opts ...ConfirmOption) bool

Confirm prompts the user for yes/no confirmation. Returns true if the user enters "y" or "yes" (case-insensitive).

Basic usage:

if Confirm("Delete file?") { ... }

With options:

if Confirm("Save changes?", DefaultYes()) { ... }
if Confirm("Dangerous!", Required()) { ... }
if Confirm("Auto-continue?", Timeout(30*time.Second)) { ... }

func ConfirmAction

func ConfirmAction(verb, subject string, opts ...ConfirmOption) bool

ConfirmAction prompts for confirmation of an action using grammar composition.

if ConfirmAction("delete", "config.yaml") { ... }
if ConfirmAction("save", "changes", DefaultYes()) { ... }

func ConfirmDangerousAction

func ConfirmDangerousAction(verb, subject string) bool

ConfirmDangerousAction prompts for double confirmation of a dangerous action. Shows initial question, then a "Really verb subject?" confirmation.

if ConfirmDangerousAction("delete", "config.yaml") { ... }

func Context

func Context() context.Context

Context returns the CLI's root context. Cancelled on SIGINT/SIGTERM.

func Core

func Core() *framework.Core

Core returns the CLI's framework Core instance.

func Dim

func Dim(msg string)

Dim prints dimmed/subtle text.

func DimStr

func DimStr(msg string) string

DimStr returns a dim-styled string.

func Err

func Err(format string, args ...any) error

Err creates a new error from a format string. This is a direct replacement for fmt.Errorf.

func Error

func Error(msg string)

Error prints an error message with cross.

func ErrorStr

func ErrorStr(msg string) string

ErrorStr returns an error-styled string with cross.

func ExactArgs

func ExactArgs(n int) cobra.PositionalArgs

ExactArgs returns a PositionalArgs that accepts exactly N arguments.

func Execute

func Execute() error

Execute runs the CLI root command. Returns an error if the command fails.

func Fatal

func Fatal(err error)

Fatal prints an error message and exits with code 1.

func FatalWrap

func FatalWrap(err error, msg string)

FatalWrap prints a wrapped error message and exits with code 1. Does nothing if err is nil.

cli.FatalWrap(err, "load config")  // Prints "✗ load config: <error>" and exits

func FatalWrapVerb

func FatalWrapVerb(err error, verb, subject string)

FatalWrapVerb prints a wrapped error using i18n grammar and exits with code 1. Does nothing if err is nil.

cli.FatalWrapVerb(err, "load", "config")  // Prints "✗ Failed to load config: <error>" and exits

func Fatalf

func Fatalf(format string, args ...any)

Fatalf prints a formatted error message and exits with code 1.

func FmtDim

func FmtDim(text string) string

FmtDim returns dimmed text.

func FmtError

func FmtError(msg string) string

FmtError returns a styled error message with cross.

func FmtInfo

func FmtInfo(msg string) string

FmtInfo returns a styled info message with info symbol.

func FmtSuccess

func FmtSuccess(msg string) string

FmtSuccess returns a styled success message with checkmark.

func FmtTitle

func FmtTitle(text string) string

FmtTitle returns a styled command/section title.

func FmtWarning

func FmtWarning(msg string) string

FmtWarning returns a styled warning message with warning symbol.

func FormatAge

func FormatAge(t time.Time) string

FormatAge formats a time as a human-readable age string. Examples: "5m ago", "2h ago", "3d ago", "1w ago", "2mo ago"

func FormatCoverage

func FormatCoverage(percent float64) string

FormatCoverage formats a coverage percentage with colour based on thresholds. High (green) >= 80%, Medium (amber) >= 50%, Low (red) < 50%.

func FormatCoverageCustom

func FormatCoverageCustom(percent, highThreshold, medThreshold float64) string

FormatCoverageCustom formats coverage with custom thresholds.

func FormatPriority

func FormatPriority(level string) string

FormatPriority returns styled text for a priority level.

func FormatSeverity

func FormatSeverity(level string) string

FormatSeverity returns styled text for a severity level.

func FormatTaskStatus

func FormatTaskStatus(status string) string

FormatTaskStatus returns styled text for a task status. Supports: pending, in_progress, completed, blocked, failed.

func GhAuthenticated

func GhAuthenticated() bool

GhAuthenticated checks if the GitHub CLI is authenticated. Returns true if 'gh auth status' indicates a logged-in user.

func GitClone

func GitClone(ctx context.Context, org, repo, path string) error

GitClone clones a GitHub repository to the specified path. Prefers 'gh repo clone' if authenticated, falls back to SSH.

func Header(title string, withSeparator bool) string

Header returns a styled section header with optional separator.

func Highlight

func Highlight(text string) string

Highlight returns text with accent colour.

func Indent

func Indent(level int, text string) string

Indent returns text indented by the specified level (2 spaces per level).

func Info

func Info(msg string)

Info prints an info message.

func InfoStr

func InfoStr(msg string) string

InfoStr returns an info-styled string with info symbol.

func Init

func Init(opts Options) error

Init initialises the global CLI runtime. Call this once at startup (typically in main.go or cmd.Execute).

func IntFlag

func IntFlag(cmd *Command, ptr *int, name, short string, def int, usage string)

IntFlag adds an integer flag to a command. The value will be stored in the provided pointer.

var count int
cli.IntFlag(cmd, &count, "count", "n", 10, "Number of items")

func Is

func Is(err, target error) bool

Is reports whether any error in err's tree matches target. This is a re-export of errors.Is for convenience.

func IsStderrTTY

func IsStderrTTY() bool

IsStderrTTY returns true if stderr is a terminal.

func IsStdinTTY

func IsStdinTTY() bool

IsStdinTTY returns true if stdin is a terminal.

func IsTTY

func IsTTY() bool

IsTTY returns true if stdout is a terminal.

func Itoa

func Itoa(n int) string

Itoa converts an integer to a string. This is a convenience function similar to strconv.Itoa.

func Itoa64

func Itoa64(n int64) string

Itoa64 converts an int64 to a string.

func Join

func Join(errs ...error) error

Join returns an error that wraps the given errors. This is a re-export of errors.Join for convenience.

func KeyValue

func KeyValue(key, value string) string

KeyValue returns a styled "key: value" string.

func KeyValueBold

func KeyValueBold(key, value string) string

KeyValueBold returns a styled "key: value" with bold value.

func Label

func Label(text string) string

Label returns a styled label for key-value display. Example: Label("Status") -> "Status:" in dim gray

func LabelValue

func LabelValue(label, value string) string

LabelValue returns a styled "label: value" pair. Example: LabelValue("Branch", "main") -> "Branch: main"

func LabelValueStyled

func LabelValueStyled(label, value string, valueStyle lipgloss.Style) string

LabelValueStyled returns a styled "label: value" pair with custom value style.

func Line

func Line(key string, args ...any)

Line translates a key via i18n.T and prints with newline. If no key is provided, prints an empty line.

cli.Line("i18n.progress.check")           // prints "Checking...\n"
cli.Line("cmd.dev.ci.short")              // prints translated text + \n
cli.Line("greeting", map[string]any{"Name": "World"})  // with args
cli.Line("")                              // prints empty line

func LogDebug

func LogDebug(msg string)

LogDebug logs a debug message if log service is available.

func LogError

func LogError(msg string)

LogError logs an error message if log service is available.

func LogInfo

func LogInfo(msg string)

LogInfo logs an info message if log service is available.

func LogWarn

func LogWarn(msg string)

LogWarn logs a warning message if log service is available.

func Main

func Main()

Main initialises and runs the CLI application. This is the main entry point for the CLI. Exits with code 1 on error.

func MaximumNArgs

func MaximumNArgs(n int) cobra.PositionalArgs

MaximumNArgs returns a PositionalArgs that accepts maximum N arguments.

func MinimumNArgs

func MinimumNArgs(n int) cobra.PositionalArgs

MinimumNArgs returns a PositionalArgs that accepts minimum N arguments.

func NewI18nService

func NewI18nService(opts I18nOptions) func(*framework.Core) (any, error)

NewI18nService creates an i18n service factory.

func NewLogService

func NewLogService(opts LogOptions) func(*framework.Core) (any, error)

NewLogService creates a log service factory with CLI styling.

func NoArgs

func NoArgs() cobra.PositionalArgs

NoArgs returns a PositionalArgs that accepts no arguments.

func Number

func Number(n int) string

Number renders a number with styling.

func Path

func Path(p string) string

Path renders a file path in code style.

func Pending

func Pending(msg string) string

Pending returns a styled pending message with ellipsis.

func PersistentBoolFlag

func PersistentBoolFlag(cmd *Command, ptr *bool, name, short string, def bool, usage string)

PersistentBoolFlag adds a persistent boolean flag (inherited by subcommands).

func PersistentStringFlag

func PersistentStringFlag(cmd *Command, ptr *string, name, short, def, usage string)

PersistentStringFlag adds a persistent string flag (inherited by subcommands).

func ProgressLabel

func ProgressLabel(label string) string

ProgressLabel returns a dimmed label with colon for progress output. Example: ProgressLabel("Installing") -> "Installing:" in dim gray

func Question

func Question(prompt string, opts ...QuestionOption) string

Question prompts the user for text input.

name := Question("Enter your name:")
name := Question("Enter your name:", WithDefault("Anonymous"))
name := Question("Enter your name:", RequiredInput())

func QuestionAction

func QuestionAction(verb, subject string, opts ...QuestionOption) string

QuestionAction prompts for text input using grammar composition.

name := QuestionAction("rename", "old.txt")

func RegisterCommands

func RegisterCommands(fn CommandRegistration)

RegisterCommands registers a function that adds commands to the CLI. Call this in your package's init() to register commands.

func init() {
    cli.RegisterCommands(AddCommands)
}

func AddCommands(root *cobra.Command) {
    root.AddCommand(myCmd)
}

func RootCmd

func RootCmd() *cobra.Command

RootCmd returns the CLI's root cobra command.

func Run

func Run(ctx context.Context) error

Run blocks until context is cancelled or signal received. Simple helper for daemon mode without advanced features.

cli.Init(cli.Options{AppName: "myapp"})
defer cli.Shutdown()
cli.Run(cli.Context())

func RunWithTimeout

func RunWithTimeout(timeout time.Duration) func()

RunWithTimeout wraps Run with a graceful shutdown timeout. The returned function should be deferred to replace cli.Shutdown().

cli.Init(cli.Options{AppName: "myapp"})
shutdown := cli.RunWithTimeout(30 * time.Second)
defer shutdown()
cli.Run(cli.Context())

func Scanln

func Scanln(a ...any) (int, error)

Scanln reads from stdin, similar to fmt.Scanln.

func Separator

func Separator(width int) string

Separator returns a horizontal separator line.

func Shutdown

func Shutdown()

Shutdown gracefully shuts down the CLI.

func Skip

func Skip(msg string) string

Skip returns a styled skipped message with circle.

func Sprint

func Sprint(args ...any) string

Sprint formats using the default formats for its operands. This is a direct replacement for fmt.Sprint.

func Sprintf

func Sprintf(format string, args ...any) string

Sprintf formats a string. This is a direct replacement for fmt.Sprintf.

func StatusLine

func StatusLine(parts ...string) string

StatusLine creates a pipe-separated status line from parts. Each part should be pre-styled.

func StatusPart

func StatusPart(count int, label string, style lipgloss.Style) string

StatusPart creates a styled count + label for status lines. Example: StatusPart(5, "repos", SuccessStyle) -> "5 repos" in green

func StatusPrefix

func StatusPrefix(style lipgloss.Style) string

StatusPrefix returns a styled ">>" prefix for status messages.

func StatusText

func StatusText(text string, style lipgloss.Style) string

StatusText creates a styled label for status lines. Example: StatusText("clean", SuccessStyle) -> "clean" in green

func StringFlag

func StringFlag(cmd *Command, ptr *string, name, short, def, usage string)

StringFlag adds a string flag to a command. The value will be stored in the provided pointer.

var output string
cli.StringFlag(cmd, &output, "output", "o", "", "Output file path")

func StringSliceFlag

func StringSliceFlag(cmd *Command, ptr *[]string, name, short string, def []string, usage string)

StringSliceFlag adds a string slice flag to a command. The value will be stored in the provided pointer.

var tags []string
cli.StringSliceFlag(cmd, &tags, "tag", "t", nil, "Tags to apply")

func Styled

func Styled(style lipgloss.Style, text string) string

Styled returns text formatted with a style. Example: cli.Styled(cli.Style.Success, "Done!")

func Styledf

func Styledf(style lipgloss.Style, format string, args ...any) string

Styledf returns formatted text with a style. Example: cli.Styledf(cli.Style.Success, "Processed %d items", count)

func Success

func Success(msg string)

Success prints a success message with checkmark.

func SuccessStr

func SuccessStr(msg string) string

SuccessStr returns a success-styled string with checkmark.

func T

func T(key string, args ...map[string]any) string

T translates a key using the CLI's i18n service. Falls back to the global i18n.T if CLI not initialised.

func Title

func Title(msg string)

Title prints a title/header.

func TreeItem

func TreeItem(text string, isLast bool) string

TreeItem returns a tree item with branch indicator.

func Truncate

func Truncate(s string, max int) string

Truncate shortens a string to max characters, adding "..." if truncated.

func Warning

func Warning(msg string)

Warning prints a warning message.

func WarningStr

func WarningStr(msg string) string

WarningStr returns a warning-styled string with warning symbol.

func Wrap

func Wrap(err error, msg string) error

Wrap wraps an error with a message. Returns nil if err is nil.

return cli.Wrap(err, "load config")  // "load config: <original error>"

func WrapAction

func WrapAction(err error, verb string) error

WrapAction wraps an error using i18n grammar for "Failed to verb". Uses the i18n.ActionFailed function for proper grammar composition. Returns nil if err is nil.

return cli.WrapAction(err, "connect")  // "Failed to connect: <original error>"

func WrapVerb

func WrapVerb(err error, verb, subject string) error

WrapVerb wraps an error using i18n grammar for "Failed to verb subject". Uses the i18n.ActionFailed function for proper grammar composition. Returns nil if err is nil.

return cli.WrapVerb(err, "load", "config")  // "Failed to load config: <original error>"

Types

type ChooseOption

type ChooseOption[T any] func(*chooseConfig[T])

ChooseOption configures Choose behaviour.

func Display

func Display[T any](fn func(T) string) ChooseOption[T]

Display sets a custom display function for items. Alias for WithDisplay for shorter syntax.

Choose("Select:", items, Display(func(f File) string { return f.Name }))

func Filter

func Filter[T any]() ChooseOption[T]

Filter enables type-to-filter functionality. Users can type to narrow down the list of options. Note: This is a hint for interactive UIs; the basic CLI Choose implementation uses numbered selection which doesn't support filtering.

func Multi

func Multi[T any]() ChooseOption[T]

Multi allows multiple selections. Use ChooseMulti instead of Choose when this option is needed.

func WithDefaultIndex

func WithDefaultIndex[T any](idx int) ChooseOption[T]

WithDefaultIndex sets the default selection index (0-based).

func WithDisplay

func WithDisplay[T any](fn func(T) string) ChooseOption[T]

WithDisplay sets a custom display function for items.

type Command

type Command = cobra.Command

Command is the cobra command type. Re-exported for convenience so packages don't need to import cobra directly.

func NewCommand

func NewCommand(use, short, long string, run func(cmd *Command, args []string) error) *Command

NewCommand creates a new command with a RunE handler. This is the standard way to create commands that may return errors.

cmd := cli.NewCommand("build", "Build the project", "", func(cmd *cli.Command, args []string) error {
    // Build logic
    return nil
})

func NewGroup

func NewGroup(use, short, long string) *Command

NewGroup creates a new command group (no RunE). Use this for parent commands that only contain subcommands.

devCmd := cli.NewGroup("dev", "Development commands", "")
devCmd.AddCommand(buildCmd, testCmd)

func NewRun

func NewRun(use, short, long string, run func(cmd *Command, args []string)) *Command

NewRun creates a new command with a simple Run handler (no error return). Use when the command cannot fail.

cmd := cli.NewRun("version", "Show version", "", func(cmd *cli.Command, args []string) {
    cli.Println("v1.0.0")
})

func WithArgs

func WithArgs(cmd *Command, args cobra.PositionalArgs) *Command

WithArgs sets the Args validation function for a command. Returns the command for chaining.

cmd := cli.NewCommand("build", "Build", "", run).WithArgs(cobra.ExactArgs(1))

func WithExample

func WithExample(cmd *Command, example string) *Command

WithExample sets the Example field for a command. Returns the command for chaining.

type CommandRegistration

type CommandRegistration func(root *cobra.Command)

CommandRegistration is a function that adds commands to the root.

type ConfirmOption

type ConfirmOption func(*confirmConfig)

ConfirmOption configures Confirm behaviour.

func DefaultYes

func DefaultYes() ConfirmOption

DefaultYes sets the default response to "yes" (pressing Enter confirms).

func Required

func Required() ConfirmOption

Required prevents empty responses; user must explicitly type y/n.

func Timeout

func Timeout(d time.Duration) ConfirmOption

Timeout sets a timeout after which the default response is auto-selected. If no default is set (not Required and not DefaultYes), defaults to "no".

Confirm("Continue?", Timeout(30*time.Second))  // Auto-no after 30s
Confirm("Continue?", DefaultYes(), Timeout(10*time.Second))  // Auto-yes after 10s

type Daemon

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

Daemon manages daemon lifecycle.

func NewDaemon

func NewDaemon(opts DaemonOptions) *Daemon

NewDaemon creates a daemon runner with the given options.

func (*Daemon) HealthAddr

func (d *Daemon) HealthAddr() string

HealthAddr returns the health server address, or empty if disabled.

func (*Daemon) Run

func (d *Daemon) Run(ctx context.Context) error

Run blocks until the context is cancelled or a signal is received. Handles graceful shutdown with the configured timeout.

func (*Daemon) SetReady

func (d *Daemon) SetReady(ready bool)

SetReady sets the daemon readiness status for health checks.

func (*Daemon) Start

func (d *Daemon) Start() error

Start initialises the daemon (PID file, health server). Call this after cli.Init().

func (*Daemon) Stop

func (d *Daemon) Stop() error

Stop performs graceful shutdown.

type DaemonOptions

type DaemonOptions struct {
	// PIDFile path for single-instance enforcement.
	// Leave empty to skip PID file management.
	PIDFile string

	// ShutdownTimeout is the maximum time to wait for graceful shutdown.
	// Default: 30 seconds.
	ShutdownTimeout time.Duration

	// HealthAddr is the address for health check endpoints.
	// Example: ":8080", "127.0.0.1:9000"
	// Leave empty to disable health checks.
	HealthAddr string

	// HealthChecks are additional health check functions.
	HealthChecks []HealthCheck

	// OnReload is called when SIGHUP is received.
	// Use for config reloading. Leave nil to ignore SIGHUP.
	OnReload func() error
}

DaemonOptions configures daemon mode execution.

type HealthCheck

type HealthCheck func() error

HealthCheck is a function that returns nil if healthy.

type HealthServer

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

HealthServer provides a minimal HTTP health check endpoint.

func NewHealthServer

func NewHealthServer(addr string) *HealthServer

NewHealthServer creates a health check server.

func (*HealthServer) AddCheck

func (h *HealthServer) AddCheck(check HealthCheck)

AddCheck registers a health check function.

func (*HealthServer) Addr

func (h *HealthServer) Addr() string

Addr returns the actual address the server is listening on. Useful when using port 0 for dynamic port assignment.

func (*HealthServer) SetReady

func (h *HealthServer) SetReady(ready bool)

SetReady sets the readiness status.

func (*HealthServer) Start

func (h *HealthServer) Start() error

Start begins serving health check endpoints. Endpoints:

  • /health - liveness probe (always 200 if server is up)
  • /ready - readiness probe (200 if ready, 503 if not)

func (*HealthServer) Stop

func (h *HealthServer) Stop(ctx context.Context) error

Stop gracefully shuts down the health server.

type I18nOptions

type I18nOptions struct {
	// Language overrides auto-detection (e.g., "en-GB", "de")
	Language string
	// Mode sets the translation mode (Normal, Strict, Collect)
	Mode i18n.Mode
}

I18nOptions configures the i18n service.

type I18nService

type I18nService struct {
	*framework.ServiceRuntime[I18nOptions]
	// contains filtered or unexported fields
}

I18nService wraps i18n as a Core service.

func (*I18nService) AvailableLanguages

func (s *I18nService) AvailableLanguages() []string

AvailableLanguages returns all available languages.

func (*I18nService) ClearMissingKeys

func (s *I18nService) ClearMissingKeys()

ClearMissingKeys resets the collected missing keys.

func (*I18nService) Language

func (s *I18nService) Language() string

Language returns the current language.

func (*I18nService) MissingKeys

func (s *I18nService) MissingKeys() []i18n.MissingKey

MissingKeys returns all missing keys collected in collect mode. Call this at the end of a QA session to report missing translations.

func (*I18nService) Mode

func (s *I18nService) Mode() i18n.Mode

Mode returns the current translation mode.

func (*I18nService) OnStartup

func (s *I18nService) OnStartup(ctx context.Context) error

OnStartup initialises the i18n service.

func (*I18nService) SetLanguage

func (s *I18nService) SetLanguage(lang string)

SetLanguage changes the current language.

func (*I18nService) SetMode

func (s *I18nService) SetMode(mode i18n.Mode)

SetMode changes the translation mode.

func (*I18nService) T

func (s *I18nService) T(key string, args ...map[string]any) string

T translates a key with optional arguments.

type LogLevel

type LogLevel = log.Level

LogLevel aliases for backwards compatibility.

type LogOptions

type LogOptions = log.Options

LogOptions configures the log service.

type LogService

type LogService struct {
	*log.Service
}

LogService wraps log.Service with CLI styling.

func Log

func Log() *LogService

Log returns the CLI's log service, or nil if not available.

type Mode

type Mode int

Mode represents the CLI execution mode.

const (
	// ModeInteractive indicates TTY attached with coloured output.
	ModeInteractive Mode = iota
	// ModePipe indicates stdout is piped, colours disabled.
	ModePipe
	// ModeDaemon indicates headless execution, log-only output.
	ModeDaemon
)

func DetectMode

func DetectMode() Mode

DetectMode determines the execution mode based on environment. Checks CORE_DAEMON env var first, then TTY status.

func (Mode) String

func (m Mode) String() string

String returns the string representation of the Mode.

type Options

type Options struct {
	AppName  string
	Version  string
	Services []framework.Option // Additional services to register

	// OnReload is called when SIGHUP is received (daemon mode).
	// Use for configuration reloading. Leave nil to ignore SIGHUP.
	OnReload func() error
}

Options configures the CLI runtime.

type PIDFile

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

PIDFile manages a process ID file for single-instance enforcement.

func NewPIDFile

func NewPIDFile(path string) *PIDFile

NewPIDFile creates a PID file manager.

func (*PIDFile) Acquire

func (p *PIDFile) Acquire() error

Acquire writes the current PID to the file. Returns error if another instance is running.

func (*PIDFile) Path

func (p *PIDFile) Path() string

Path returns the PID file path.

func (*PIDFile) Release

func (p *PIDFile) Release() error

Release removes the PID file.

type QueryTranslate

type QueryTranslate struct {
	Key  string
	Args map[string]any
}

QueryTranslate requests a translation.

type QuestionOption

type QuestionOption func(*questionConfig)

QuestionOption configures Question behaviour.

func RequiredInput

func RequiredInput() QuestionOption

RequiredInput prevents empty responses.

func WithDefault

func WithDefault(value string) QuestionOption

WithDefault sets the default value shown in brackets.

func WithValidator

func WithValidator(fn func(string) error) QuestionOption

WithValidator adds a validation function for the response.

type SignalOption

type SignalOption func(*signalService)

SignalOption configures signal handling.

func WithReloadHandler

func WithReloadHandler(fn func() error) SignalOption

WithReloadHandler sets a callback for SIGHUP.

type Table

type Table struct {
	Headers []string
	Rows    []TableRow
	Widths  []int // Optional: fixed column widths
}

Table provides simple table rendering.

func (*Table) Render

func (t *Table) Render() string

Render returns the table as a formatted string.

type TableRow

type TableRow []string

TableRow represents a row in a simple table.

Jump to

Keyboard shortcuts

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