ui

package
v0.0.15 Latest Latest
Warning

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

Go to latest
Published: Jun 16, 2026 License: MIT Imports: 11 Imported by: 0

Documentation

Overview

Package ui provides terminal-aware output formatting for gh-actions-lock. It respects NO_COLOR, CLICOLOR, and TTY detection on stderr (not stdout) so that color works correctly even when stdout is piped (e.g. --json mode).

Index

Constants

View Source
const (
	IconSuccess = "✓"
	IconError   = "✗"
	IconWarning = "!"
	IconSkip    = "-"
)

Icons used in status-prefixed output. These always appear regardless of color setting — PRimer says don't rely solely on color.

Variables

This section is empty.

Functions

func CloseProgressTrace

func CloseProgressTrace()

CloseProgressTrace closes the progress trace file if one was opened. It is safe to call unconditionally; it no-ops when tracing is off or already closed.

func Pluralize

func Pluralize(n int, singular, plural string) string

Pluralize returns singular when n==1, plural otherwise.

Types

type UI

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

UI writes human-readable output to an io.Writer with optional ANSI styling.

When a log sink is attached via SetLog, all narration (Success, Detail, Warning, …) is redirected as plain text to the log and the terminal is left to spinners, prompts, and the Term* summary methods. This keeps the interactive output clean and avoids spinner/scrollback interleaving.

Headless mode (set when stderr isn't a TTY or CI=true) takes precedence over the log sink: every narration call writes one plain `text\n` line to the writer with no icons, no indentation, and no color. Progress methods emit a single line per phase boundary (label stem change) and otherwise no-op — no spinner, no N/M churn.

func New

func New() *UI

New creates a UI that writes to stderr with color auto-detected from the stderr file descriptor. Respects NO_COLOR and CLICOLOR environment variables.

func NewPlain

func NewPlain(w io.Writer) *UI

NewPlain creates a UI with no color and writes to the given writer. Useful for tests. The result is in headless mode: narration writes plain `text\n` lines to w with no icons or color, progress methods don't spawn a spinner, and Blank/TermBlank are no-ops.

func NewWithWriter

func NewWithWriter(w io.Writer) *UI

NewWithWriter creates a UI that writes to the given writer. If the writer is an *os.File whose fd is a terminal, color is auto-detected. Otherwise color is disabled. This is the injection-friendly constructor for DI.

func (*UI) Blank

func (u *UI) Blank()

Blank prints an empty line. In log mode it is a no-op so the JSONL transcript stays one valid object per line. In headless mode it is also a no-op so CI logs stay flat — phase boundaries do the visual separating instead.

func (*UI) Bold

func (u *UI) Bold(s string) string

Bold returns s in bold if color is enabled.

func (*UI) ClearWorkerStatuses

func (u *UI) ClearWorkerStatuses()

ClearWorkerStatuses wipes every worker slot so stale "✓ NWO" rows from a completed phase don't carry into the next one. No-op when no spinner is active.

func (*UI) Cyan

func (u *UI) Cyan(s string) string

Cyan returns s in cyan if color is enabled.

func (*UI) Detail

func (u *UI) Detail(msg string, args ...any)

Detail prints an indented detail line (2-space indent).

func (*UI) Dim

func (u *UI) Dim(s string) string

Dim returns s in dim/faint if color is enabled.

func (u *UI) DocLink(url string) string

DocLink renders a documentation reference: the bare URL when writing to the log (so the transcript stays actionable), otherwise a dim "docs" hyperlink for the terminal.

func (*UI) Error

func (u *UI) Error(msg string, args ...any)

Error prints a red "✗" prefixed message.

func (*UI) Green

func (u *UI) Green(s string) string

Green returns s in green if color is enabled.

func (*UI) Header

func (u *UI) Header(msg string, args ...any)

Header prints a bold message, used for file/section headers.

func (*UI) Headless

func (u *UI) Headless() bool

Headless reports whether the UI is running in plain-text streaming mode (non-TTY writer, or CI environment). Callers can use this to gate behavior that should differ between interactive and machine-consumable output — for example, leaving the narration log attached so per-action lines stream to stderr rather than being discarded.

func (*UI) Hint

func (u *UI) Hint(msg string, args ...any)

Hint prints a dim, indented message — typically a suggested command.

func (u *UI) Hyperlink(text, url string) string

Hyperlink returns text as a clickable OSC 8 hyperlink when the terminal supports it, otherwise returns text as-is. Most modern terminals (iTerm2, WezTerm, kitty, GNOME Terminal, Windows Terminal) support this.

func (*UI) Info

func (u *UI) Info(msg string, args ...any)

Info prints a message with no prefix.

func (*UI) Infof

func (u *UI) Infof(msg string, args ...any)

Infof prints a message with no prefix and no trailing newline.

func (*UI) IsTTY

func (u *UI) IsTTY() bool

IsTTY returns true if the output is a terminal.

func (*UI) MarkHeadless

func (u *UI) MarkHeadless()

MarkHeadless forces the UI into plain-text streaming mode after construction. Used when a flag like --no-interactive signals headless intent that the auto-detection (TTY + CI env) at construction time couldn't see. Idempotent and one-way: once headless, the UI stays headless for the rest of its lifetime. Also disables color so any already-cached output profile is consistent with the new mode.

func (*UI) PauseProgress

func (u *UI) PauseProgress()

PauseProgress temporarily halts the spinner and clears its line so other output (typically an interactive prompt) can render cleanly. The label and detail are retained; ResumeProgress restarts the spinner where it left off. Safe to call when no spinner is active or one is already paused.

func (*UI) ProgressActive

func (u *UI) ProgressActive() bool

ProgressActive reports whether a spinner is currently running. Callers use this to adopt an already-running spinner (keeping it continuous across phases) instead of stopping and restarting one, which would leave a visible gap on the terminal.

func (*UI) Red

func (u *UI) Red(s string) string

Red returns s in red if color is enabled.

func (*UI) ResumeProgress

func (u *UI) ResumeProgress()

ResumeProgress restarts a spinner previously paused by PauseProgress, redrawing the retained label/detail. Safe to call when no spinner is active or one is not paused.

func (*UI) SetLog

func (u *UI) SetLog(w io.Writer)

SetLog attaches a narration sink. Once set, narration methods write plain text to w instead of the terminal. Pass nil to detach.

func (*UI) SetWorkerHint

func (u *UI) SetWorkerHint(slot int, hint string)

SetWorkerHint sets or clears a dim suffix appended after the worker slot's status text (e.g. "→ workflow.yml (still working…)"). Used by pinpool's stall watcher to surface that a worker has been on the same job for longer than the stall threshold without clobbering the slot's main status. No-op when no spinner is active.

func (*UI) SetWorkerStatus

func (u *UI) SetWorkerStatus(slot int, status string)

SetWorkerStatus sets or clears one worker slot's status line, shown as a subdued line below the spinner. slot indexes from 0. No-op when no spinner is active.

func (*UI) Skip

func (u *UI) Skip(msg string, args ...any)

Skip prints a gray "-" prefixed message.

func (*UI) StartProgress

func (u *UI) StartProgress(label string)

StartProgress starts an animated spinner with the given label on stderr. On non-TTY outputs, prints a static label instead. Matches gh CLI's Primer progress indicator: braille dots, 120ms, cyan.

The spinner is not rendered immediately: a short grace period suppresses flicker for fast runs. If StopProgress is called before the grace period expires, no spinner is ever shown.

func (*UI) StopProgress

func (u *UI) StopProgress()

StopProgress stops the spinner. Safe to call if no spinner is active.

func (*UI) Success

func (u *UI) Success(msg string, args ...any)

Success prints a green "✓" prefixed message.

func (*UI) TermBlank

func (u *UI) TermBlank()

TermBlank prints an empty line directly to the terminal.

func (*UI) TermBold

func (u *UI) TermBold(s string) string

TermBold returns s in bold for use in Term* output.

func (*UI) TermCaution

func (u *UI) TermCaution(msg string, args ...any)

TermCaution prints a yellow "!" summary line directly to the terminal. Use for non-fatal but attention-worthy signals (e.g. a commit pinned only after a full-branch-scan fallback) that warrant emphasis without the "✗ failure" framing.

func (*UI) TermDetail

func (u *UI) TermDetail(msg string, args ...any)

TermDetail prints an indented summary detail line directly to the terminal.

func (*UI) TermDim

func (u *UI) TermDim(s string) string

TermDim returns s in dim/faint for use in Term* output.

func (*UI) TermError

func (u *UI) TermError(msg string, args ...any)

TermError prints a red "✗" summary line directly to the terminal.

func (u *UI) TermLink(text, url string) string

TermLink wraps text in an OSC 8 hyperlink for use in Term* output. Falls back to plain text when color is disabled or url is empty.

func (*UI) TermNeutral

func (u *UI) TermNeutral(msg string, args ...any)

TermNeutral prints a dimmed, neutral "-" summary line directly to the terminal. Per cli/cli iconography, "-" denotes neutral/informational status (not success, alert, or failure). Used for footer pointers such as the resolution-record path.

func (*UI) TermSuccess

func (u *UI) TermSuccess(msg string, args ...any)

TermSuccess prints a green "✓" summary line directly to the terminal, bypassing the narration log. Use for the final run summary.

func (*UI) TermWarn

func (u *UI) TermWarn(msg string, args ...any)

TermWarn prints a yellow "!" summary line directly to the terminal.

func (*UI) TermYellow

func (u *UI) TermYellow(s string) string

TermYellow returns s in yellow for use in Term* output. Unlike Yellow, this does not suppress color when a narration log sink is attached, since Term* methods write directly to the terminal rather than the log.

func (*UI) UpdateLabel

func (u *UI) UpdateLabel(label string)

UpdateLabel is a no-op on TTY — the spinner label is static for the lifetime of the spinner. In headless mode it logs a plain-text phase boundary when the label changes.

func (*UI) UpdateProgress

func (u *UI) UpdateProgress(detail string)

UpdateProgress sets a detail string in worker slot 0 (backward-compat single-detail shim). No-op when no spinner is active.

func (*UI) Warning

func (u *UI) Warning(msg string, args ...any)

Warning prints a yellow "!" prefixed message.

func (*UI) Yellow

func (u *UI) Yellow(s string) string

Yellow returns s in yellow if color is enabled.

Jump to

Keyboard shortcuts

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