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
- func CloseProgressTrace()
- func Pluralize(n int, singular, plural string) string
- type UI
- func (u *UI) Blank()
- func (u *UI) Bold(s string) string
- func (u *UI) ClearWorkerStatuses()
- func (u *UI) Cyan(s string) string
- func (u *UI) Detail(msg string, args ...any)
- func (u *UI) Dim(s string) string
- func (u *UI) DocLink(url string) string
- func (u *UI) Error(msg string, args ...any)
- func (u *UI) Green(s string) string
- func (u *UI) Header(msg string, args ...any)
- func (u *UI) Headless() bool
- func (u *UI) Hint(msg string, args ...any)
- func (u *UI) Hyperlink(text, url string) string
- func (u *UI) Info(msg string, args ...any)
- func (u *UI) Infof(msg string, args ...any)
- func (u *UI) IsTTY() bool
- func (u *UI) MarkHeadless()
- func (u *UI) PauseProgress()
- func (u *UI) ProgressActive() bool
- func (u *UI) Red(s string) string
- func (u *UI) ResumeProgress()
- func (u *UI) SetLog(w io.Writer)
- func (u *UI) SetWorkerHint(slot int, hint string)
- func (u *UI) SetWorkerStatus(slot int, status string)
- func (u *UI) Skip(msg string, args ...any)
- func (u *UI) StartProgress(label string)
- func (u *UI) StopProgress()
- func (u *UI) Success(msg string, args ...any)
- func (u *UI) TermBlank()
- func (u *UI) TermBold(s string) string
- func (u *UI) TermCaution(msg string, args ...any)
- func (u *UI) TermDetail(msg string, args ...any)
- func (u *UI) TermDim(s string) string
- func (u *UI) TermError(msg string, args ...any)
- func (u *UI) TermLink(text, url string) string
- func (u *UI) TermNeutral(msg string, args ...any)
- func (u *UI) TermSuccess(msg string, args ...any)
- func (u *UI) TermWarn(msg string, args ...any)
- func (u *UI) TermYellow(s string) string
- func (u *UI) UpdateLabel(label string)
- func (u *UI) UpdateProgress(detail string)
- func (u *UI) Warning(msg string, args ...any)
- func (u *UI) Yellow(s string) string
Constants ¶
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.
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 ¶
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 ¶
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) 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) DocLink ¶
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) Headless ¶
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) Hyperlink ¶
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) 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 ¶
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) 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 ¶
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 ¶
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 ¶
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) StartProgress ¶
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) TermBlank ¶
func (u *UI) TermBlank()
TermBlank prints an empty line directly to the terminal.
func (*UI) TermCaution ¶
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 ¶
TermDetail prints an indented summary detail line directly to the terminal.
func (*UI) TermLink ¶
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 ¶
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 ¶
TermSuccess prints a green "✓" summary line directly to the terminal, bypassing the narration log. Use for the final run summary.
func (*UI) TermYellow ¶
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 ¶
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 ¶
UpdateProgress sets a detail string in worker slot 0 (backward-compat single-detail shim). No-op when no spinner is active.