Documentation
¶
Overview ¶
Package ui provides common UI components for the miren CLI
Index ¶
- Constants
- func BriefId(e entity.AttrGetter) string
- func CleanEntityID(id string) string
- func CleanStatus(status string) string
- func Completed(str string, args ...any) string
- func Confirm(opts ...ConfirmOption) (bool, error)
- func DisplayAppVersion(version string) string
- func DisplayShortID(shortID, fullID string) string
- func DisplayStatus(status string) string
- func FriendlyId(e entity.AttrGetter) string
- func Hyperlink(url, text string) string
- func HyperlinkStyled(url, text string, color lipgloss.TerminalColor) string
- func IsInteractive() bool
- func IsTTY() bool
- func PromptForInput(opts ...PromptOption) (string, error)
- func RenderMarkdownLink(s string, color lipgloss.TerminalColor) string
- func Run(prefix string, cmd *exec.Cmd) error
- func TerminalWidth() int
- type Action
- type Column
- type ColumnBuilder
- type ColumnHint
- type ConfirmOption
- type Definition
- type DefinitionDetail
- type DefinitionList
- type DefinitionListOption
- type DefinitionListStyles
- type Diagnostic
- type Fact
- type Hint
- type List
- type NamedValue
- type NamedValueList
- type NamedValueOption
- type NamedValueStyles
- type PickerItem
- type PickerModel
- type PickerOption
- type PromptOption
- type Row
- type Severity
- type SeverityTerminalError
- type SimplePickerItem
- type Table
- type TableOption
- type TablePickerItem
- type TableStyles
- type TerminalError
- type ValueType
Examples ¶
Constants ¶
const ( Checkmark = "\u2713" Play = "\u25B6" )
const Indent = " │"
Variables ¶
This section is empty.
Functions ¶
func BriefId ¶ added in v0.7.0
func BriefId(e entity.AttrGetter) string
BriefId returns the shortest usable identifier for an entity: short-id > name > full id.
func CleanEntityID ¶
CleanEntityID removes common entity type prefixes from entity IDs for cleaner display. For example: "sandbox/sb-ABC123" -> "sb-ABC123", "app_version/meet-vXYZ" -> "meet-vXYZ"
func CleanStatus ¶
CleanStatus removes the "status." prefix from a status string without applying color.
func Confirm ¶
func Confirm(opts ...ConfirmOption) (bool, error)
Confirm displays a yes/no confirmation prompt
func DisplayAppVersion ¶
DisplayAppVersion formats an app version string by removing prefixes and bolding the app name. For example: "app_version/meet-vXYZ123" -> "**meet**-vXYZ123" (where **meet** is bold)
func DisplayShortID ¶ added in v0.7.0
DisplayShortID returns the short ID if available, otherwise falls back to CleanEntityID.
func DisplayStatus ¶
DisplayStatus returns a colored version of the status string based on common status values. It also removes the "status." prefix if present.
func FriendlyId ¶ added in v0.7.0
func FriendlyId(e entity.AttrGetter) string
FriendlyId returns the most human-readable identifier: name > short-id > full id.
func Hyperlink ¶ added in v0.7.0
Hyperlink creates a clickable terminal hyperlink using the OSC 8 escape sequence with underline styling. Raw SGR sequences are used so the result can be safely combined with lipgloss-rendered text without interference.
We use a plain underline (\x1b[4m) rather than the colon-style dotted underline (\x1b[4:4m): Terminal.app and other terminals don't understand colon SGR subparameters and misrender them as a stray background that bleeds across the line.
When stdout is not a TTY, returns just the text with no escape sequences.
func HyperlinkStyled ¶ added in v0.7.0
func HyperlinkStyled(url, text string, color lipgloss.TerminalColor) string
HyperlinkStyled is like Hyperlink but also applies a foreground color, which adapts to the terminal's profile and background via the theme's color roles.
When stdout is not a TTY, returns just the text with no escape sequences.
func IsInteractive ¶
func IsInteractive() bool
IsInteractive checks if we're in an interactive terminal
func IsTTY ¶ added in v0.7.0
func IsTTY() bool
IsTTY reports whether stdout is connected to a terminal.
func PromptForInput ¶
func PromptForInput(opts ...PromptOption) (string, error)
PromptForInput displays an interactive text input prompt and returns the user's input
func RenderMarkdownLink ¶ added in v0.7.0
func RenderMarkdownLink(s string, color lipgloss.TerminalColor) string
RenderMarkdownLink parses a markdown-style link "[text](url)" and renders it as a clickable terminal hyperlink in the given theme color.
When stdout is not a TTY, renders as "text (url)" for readability in pipes/logs. If the input isn't a valid markdown link, it's returned as-is.
func TerminalWidth ¶ added in v0.7.0
func TerminalWidth() int
TerminalWidth returns the current terminal width, or 0 if stdout is not a TTY.
Types ¶
type Action ¶ added in v0.13.0
Action is a command the reader can run next, with a short note on what it does. Commands are never wrapped, so they stay copy-pasteable.
type Column ¶
type Column struct {
Title string
Width int
NoTruncate bool // If true, this column won't be truncated when scaling
WordWrap bool // If true, text that exceeds Width is wrapped instead of truncated
}
Column defines a table column with title and width
func AutoSizeColumns ¶
func AutoSizeColumns(headers []string, rows []Row, builder *ColumnBuilder) []Column
AutoSizeColumns calculates optimal column widths based on content, respecting terminal width and column configuration hints. Pass nil for builder to use default behavior.
type ColumnBuilder ¶ added in v0.0.2
type ColumnBuilder struct {
// contains filtered or unexported fields
}
ColumnBuilder helps configure column options using a fluent API
func Columns ¶ added in v0.0.2
func Columns() *ColumnBuilder
Columns creates a new ColumnBuilder for configuring column options
func (*ColumnBuilder) MaxWidth ¶ added in v0.0.2
func (b *ColumnBuilder) MaxWidth(index, width int) *ColumnBuilder
MaxWidth sets the maximum width for a specific column
func (*ColumnBuilder) MinWidth ¶ added in v0.0.2
func (b *ColumnBuilder) MinWidth(index, width int) *ColumnBuilder
MinWidth sets the minimum width for a specific column when scaling
func (*ColumnBuilder) NoTruncate ¶ added in v0.0.2
func (b *ColumnBuilder) NoTruncate(indices ...int) *ColumnBuilder
NoTruncate marks the specified column indices as non-truncatable
func (*ColumnBuilder) WordWrap ¶ added in v0.4.0
func (b *ColumnBuilder) WordWrap(indices ...int) *ColumnBuilder
WordWrap marks the specified column indices as word-wrapping. Wrapped columns split text across multiple lines at word boundaries instead of truncating with an ellipsis.
type ColumnHint ¶ added in v0.0.2
type ColumnHint struct {
MaxWidth int // Maximum width (0 = no limit)
NoTruncate bool // If true, this column won't be scaled down
MinWidth int // Minimum width when scaling (0 = use default)
WordWrap bool // If true, wrap text instead of truncating
}
ColumnHint provides configuration hints for a specific column
type ConfirmOption ¶
type ConfirmOption func(*confirmConfig)
ConfirmOption configures a confirmation prompt
func WithAffirmative ¶
func WithAffirmative(text string) ConfirmOption
WithAffirmative sets the affirmative response text (default: "yes")
func WithDefault ¶
func WithDefault(defaultYes bool) ConfirmOption
WithDefault sets the default response when user just presses enter
func WithIndent ¶ added in v0.0.2
func WithIndent(indent string) ConfirmOption
WithIndent sets the indentation prefix for the prompt
func WithMessage ¶
func WithMessage(message string) ConfirmOption
WithMessage sets the confirmation message
func WithNegative ¶
func WithNegative(text string) ConfirmOption
WithNegative sets the negative response text (default: "no")
type Definition ¶ added in v0.3.1
type Definition struct {
Term string
Description string
Details []DefinitionDetail
}
Definition represents a single definition entry with a term, description, and optional details
type DefinitionDetail ¶ added in v0.3.1
DefinitionDetail represents a child item in a definition (displayed as a tree)
type DefinitionList ¶ added in v0.3.1
type DefinitionList struct {
// contains filtered or unexported fields
}
DefinitionList renders a list of definitions with tree-style details
func NewDefinitionList ¶ added in v0.3.1
func NewDefinitionList(items []Definition, opts ...DefinitionListOption) *DefinitionList
NewDefinitionList creates a new definition list
func (*DefinitionList) Render ¶ added in v0.3.1
func (d *DefinitionList) Render() string
Render generates the string representation
type DefinitionListOption ¶ added in v0.3.1
type DefinitionListOption func(*DefinitionList)
DefinitionListOption is a function that configures a DefinitionList
func WithDefinitionListStyles ¶ added in v0.3.1
func WithDefinitionListStyles(styles DefinitionListStyles) DefinitionListOption
WithDefinitionListStyles sets custom styles
func WithDefinitionListTitle ¶ added in v0.3.1
func WithDefinitionListTitle(title string) DefinitionListOption
WithDefinitionListTitle sets the title
type DefinitionListStyles ¶ added in v0.3.1
type DefinitionListStyles struct {
Title lipgloss.Style
Term lipgloss.Style
Description lipgloss.Style
DetailName lipgloss.Style
DetailType lipgloss.Style
Required lipgloss.Style
TreeLine lipgloss.Style
}
DefinitionListStyles contains the styling configuration
func DefaultDefinitionListStyles ¶ added in v0.3.1
func DefaultDefinitionListStyles() DefinitionListStyles
DefaultDefinitionListStyles returns the default styling
type Diagnostic ¶ added in v0.13.0
type Diagnostic struct {
// Summary is the one-line headline: what failed, in the reader's terms.
Summary string
// Detail is prose explaining what was observed. Wrapped to terminal width.
Detail string
// Facts are label/value context pairs, rendered in an aligned column.
Facts []Fact
// Causes are possible explanations, most common first. This section only
// appears when we genuinely don't know which one it is: a diagnosis we're
// sure of states the cause outright in Detail instead.
Causes []string
// Actions are suggested next commands.
Actions []Action
// Cause is the underlying error. It is always reachable via errors.Unwrap
// and included in Error(), but only displayed in the rich block when
// ShowCause is set, since raw transport errors are noise for most readers.
Cause error
// ShowCause displays Cause in the rendered block (wire it to -v).
ShowCause bool
}
Diagnostic is a structured, human-facing failure report. It implements TerminalError, so returning one from a command yields a rich block on a terminal while Error() stays a single line suitable for logs and wrapping.
Both renderers read the same fields, which is the point: a hand-written WriteForTerminal alongside a hand-written Error() drifts apart the first time someone edits one of them.
Only fill in what you actually know. Every section is omitted when empty, and per the doctor design rule, Causes should only list possibilities the reader can act on.
Example ¶
ExampleDiagnostic pins the exact rendered layout. Output is plain here because go test's stdout isn't a terminal, which is also the pipe/CI shape.
d := &Diagnostic{
Summary: `couldn't reach cluster "prod" at cluster.example.com:8443`,
Detail: "Nothing answered after 5s. The hostname resolved, so either the server isn't running or something between here and there is blocking it.",
Facts: []Fact{
{Label: "Cluster", Value: "prod"},
{Label: "Address", Value: "cluster.example.com:8443"},
},
Causes: []string{"the server isn't running", "a firewall is blocking UDP"},
Actions: []Action{
{Command: "miren doctor", Note: "check what's reachable"},
{Command: "miren cluster list", Note: "see configured clusters"},
},
}
d.WriteForTerminal(os.Stdout)
Output: ERROR: couldn't reach cluster "prod" at cluster.example.com:8443 Nothing answered after 5s. The hostname resolved, so either the server isn't running or something between here and there is blocking it. Cluster prod Address cluster.example.com:8443 Possible causes • the server isn't running • a firewall is blocking UDP Try miren doctor check what's reachable miren cluster list see configured clusters
func (*Diagnostic) Error ¶ added in v0.13.0
func (d *Diagnostic) Error() string
func (*Diagnostic) Unwrap ¶ added in v0.13.0
func (d *Diagnostic) Unwrap() error
Unwrap exposes the underlying error so errors.Is/As still reach it through the Diagnostic. Doctor relies on this to re-classify a failure it was handed.
func (*Diagnostic) WriteForTerminal ¶ added in v0.13.0
func (d *Diagnostic) WriteForTerminal(w io.Writer)
WriteForTerminal renders the diagnostic at error severity.
func (*Diagnostic) WriteWithSeverity ¶ added in v0.13.0
func (d *Diagnostic) WriteWithSeverity(w io.Writer, sev Severity)
WriteWithSeverity renders the diagnostic with an explicit severity, for callers that surface the same error type as a non-fatal warning.
type Fact ¶ added in v0.13.0
Fact is a label/value pair shown in an aligned column, for context the reader needs but shouldn't have to parse out of prose (cluster, address, elapsed).
type Hint ¶ added in v0.3.1
type Hint struct {
// contains filtered or unexported fields
}
Hint renders a dimmed hint/tip message
type NamedValue ¶ added in v0.3.1
NamedValue represents a label-value pair for display
func NewNamedValue ¶ added in v0.3.1
func NewNamedValue(label string, value any) NamedValue
NewNamedValue creates a NamedValue with automatic type detection
type NamedValueList ¶ added in v0.3.1
type NamedValueList struct {
// contains filtered or unexported fields
}
NamedValueList renders a list of named values with right-aligned labels
func NewNamedValueList ¶ added in v0.3.1
func NewNamedValueList(items []NamedValue, opts ...NamedValueOption) *NamedValueList
NewNamedValueList creates a new named value list
func (*NamedValueList) Render ¶ added in v0.3.1
func (n *NamedValueList) Render() string
Render generates the string representation of the named value list
type NamedValueOption ¶ added in v0.3.1
type NamedValueOption func(*NamedValueList)
NamedValueOption is a function that configures a NamedValueList
func WithNamedValueStyles ¶ added in v0.3.1
func WithNamedValueStyles(styles NamedValueStyles) NamedValueOption
WithNamedValueStyles sets custom styles for the named value list
type NamedValueStyles ¶ added in v0.3.1
type NamedValueStyles struct {
Label lipgloss.Style
Separator string
StringValue lipgloss.Style
NumberValue lipgloss.Style
BoolValue lipgloss.Style
NullValue lipgloss.Style
OtherValue lipgloss.Style
}
NamedValueStyles contains the styling configuration for named values
func DefaultNamedValueStyles ¶ added in v0.3.1
func DefaultNamedValueStyles() NamedValueStyles
DefaultNamedValueStyles returns the default styling for named values
type PickerItem ¶
type PickerItem interface {
// Row returns the table row data for this item
Row() []string
// ID returns a unique identifier for this item
ID() string
}
PickerItem represents an item that can be selected in the picker
func RunPicker ¶
func RunPicker(items []PickerItem, opts ...PickerOption) (PickerItem, error)
RunPicker runs an interactive picker and returns the selected item
type PickerModel ¶
type PickerModel struct {
Title string
Headers []string
Items []PickerItem
Selected PickerItem
Cancelled bool
// Optional filter function to disable certain items
IsDisabled func(item PickerItem) bool
// Optional message for disabled items
DisabledMessage string
// contains filtered or unexported fields
}
PickerModel is a table-based picker for selecting from a list of items
func NewPicker ¶
func NewPicker(items []PickerItem, opts ...PickerOption) *PickerModel
NewPicker creates a new picker model with the given options
func (*PickerModel) Init ¶
func (m *PickerModel) Init() tea.Cmd
func (*PickerModel) SetCursor ¶
func (m *PickerModel) SetCursor(index int)
SetCursor sets the cursor to the specified index
func (*PickerModel) View ¶
func (m *PickerModel) View() string
type PickerOption ¶
type PickerOption func(*PickerModel)
Picker configuration options
func WithDisabledCheck ¶
func WithDisabledCheck(check func(PickerItem) bool, message string) PickerOption
WithDisabledCheck sets a function to determine if items are disabled
func WithFooter ¶
func WithFooter(footer string) PickerOption
WithFooter sets the picker footer text
func WithHeaders ¶
func WithHeaders(headers []string) PickerOption
WithHeaders sets the table headers for the picker
type PromptOption ¶
type PromptOption func(*promptConfig)
PromptOption configures a text input prompt
func WithCharLimit ¶
func WithCharLimit(limit int) PromptOption
WithCharLimit sets the character limit (0 for unlimited)
func WithPlaceholder ¶
func WithPlaceholder(placeholder string) PromptOption
WithPlaceholder sets the placeholder text
func WithSensitive ¶
func WithSensitive(sensitive bool) PromptOption
WithSensitive makes the input masked (for passwords/secrets)
type Severity ¶ added in v0.13.0
type Severity int
Severity selects the label a Diagnostic leads with and the color it wears.
type SeverityTerminalError ¶ added in v0.13.0
type SeverityTerminalError interface {
TerminalError
WriteWithSeverity(w io.Writer, sev Severity)
}
SeverityTerminalError is a TerminalError that renders its own severity label (an "ERROR:"/"WARNING:" prefix, colored to match). The display boundary must not add a prefix of its own to these, and should pass the severity it wants instead — the same error is an error in one place and a warning in another.
type SimplePickerItem ¶
SimplePickerItem is a basic implementation of PickerItem for single-column pickers
func (SimplePickerItem) ID ¶
func (s SimplePickerItem) ID() string
func (SimplePickerItem) Row ¶
func (s SimplePickerItem) Row() []string
type Table ¶
type Table struct {
// contains filtered or unexported fields
}
Table represents a simple, non-interactive table for CLI output
func NewTable ¶
func NewTable(opts ...TableOption) *Table
NewTable creates a new table with the given options
type TableOption ¶
type TableOption func(*Table)
TableOption is a function that configures a table
func WithColumns ¶
func WithColumns(cols []Column) TableOption
WithColumns sets the columns for the table
func WithStyles ¶
func WithStyles(styles TableStyles) TableOption
WithStyles sets custom styles for the table
func WithTableTitle ¶ added in v0.4.0
func WithTableTitle(title string) TableOption
WithTableTitle sets a title displayed above the table header
type TablePickerItem ¶
TablePickerItem is a multi-column implementation of PickerItem
func (TablePickerItem) ID ¶
func (t TablePickerItem) ID() string
func (TablePickerItem) Row ¶
func (t TablePickerItem) Row() []string
type TableStyles ¶
TableStyles contains the styling configuration for the table
func DefaultTableStyles ¶
func DefaultTableStyles() TableStyles
DefaultTableStyles returns the default styling for tables
type TerminalError ¶ added in v0.7.0
TerminalError is an optional interface for errors that can render a rich, human-friendly representation to a terminal. Errors that implement this interface get colorized, multi-line output with source context when displayed through the CLI.
The Error() method should still return a plain-text representation suitable for logging and wrapping. WriteForTerminal provides the enhanced version for interactive use.
This follows the same pattern as io.WriterTo and http.Flusher — a type assertion at the display boundary unlocks richer behavior.
Design note: this interface is rendering-only. The underlying error type should carry structured data (source locations, hints, etc.) as exported fields so that the data can be serialized over RPC. Client-side code can then reconstruct a TerminalError from the wire data for local rendering.