Documentation
¶
Index ¶
- Constants
- Variables
- func FindRoots(g *dag.DAG) []string
- func FitToWidth(s string, width int) string
- func FormatAge(t time.Time) string
- func FormatBytes(b int64) string
- func FormatConstraints(constraints []string) string
- func FormatCount(n int) string
- func FormatDuration(d time.Duration) string
- func FormatRequiredBy(parents []string, isDirect bool, rootName string) string
- func FormatRuntimeSource(source string) string
- func IsQuiet() bool
- func JoinDot(parts []string) string
- func NodeVersion(g *dag.DAG, id string) string
- func PadRight(s string, width int) string
- func PrintDetail(format string, args ...any)
- func PrintError(format string, args ...any)
- func PrintFile(path string)
- func PrintHeader(title string)
- func PrintInfo(format string, args ...any)
- func PrintInline(format string, args ...any)
- func PrintKeyValue(key, value string)
- func PrintNewline()
- func PrintNextStep(description, cmd string)
- func PrintRenderStats(s RenderStats)
- func PrintResolveSummary(w io.Writer, result ResolveResult)
- func PrintRuntimeInfo(langName, version, source string)
- func PrintSeparator(title string)
- func PrintStats(nodeCount, edgeCount, depth int, cached bool, elapsed time.Duration)
- func PrintSuccess(format string, args ...any)
- func PrintTreeSummary(w io.Writer, nodeCount int, stats TreeStats)
- func PrintVersionInfo(version, commit, date string)
- func PrintWarning(format string, args ...any)
- func RenderHelp(cmd *cobra.Command) string
- func RenderUsage(cmd *cobra.Command) string
- func SetQuiet(q bool)
- func StderrIsTTY() bool
- func StderrWidth() int
- func StdoutIsTTY() bool
- func StdoutWidth() int
- func SupportedManifestList(langs []*deps.Language) string
- func Truncate(s string, maxLen int) string
- func WriteDiff(w io.Writer, d *dag.DiffResult)
- func WritePaths(w io.Writer, target, version string, paths [][]string, shortestDepth int)
- func WriteResolveOutput(w io.Writer, result ResolveResult, color bool)
- func WriteStats(w io.Writer, r StatsReport)
- type LoadBearingEntry
- type ManifestListModel
- type Operation
- type ProgressView
- func (pv *ProgressView) OnCircuitStateChange(_ context.Context, registry string, state observability.CircuitState, ...)
- func (pv *ProgressView) OnEnrichComplete(_ context.Context, _ string, _ int, _ error)
- func (pv *ProgressView) OnEnrichStart(_ context.Context, provider string, count int)
- func (pv *ProgressView) OnFetchComplete(_ context.Context, pkg string, _ int, _ int, err error)
- func (pv *ProgressView) OnFetchStart(_ context.Context, pkg string, _ int)
- func (pv *ProgressView) OnProgress(_ context.Context, _, pending, _ int)
- func (pv *ProgressView) OnRateLimitHit(_ context.Context, registry string, retryAfterSeconds int)
- func (pv *ProgressView) OnRateLimitWait(_ context.Context, registry string, wait time.Duration)
- func (pv *ProgressView) OnRetry(_ context.Context, registry string, attempt int, backoff time.Duration)
- func (pv *ProgressView) Start()
- func (pv *ProgressView) Stop()
- func (pv *ProgressView) StopWithError(message string)
- type ProgressWriter
- type RefItem
- type RefListModel
- type RenderStats
- type RepoListModel
- type RepoSelection
- type ResolveEntry
- type ResolveResult
- type Spinner
- func (s *Spinner) Cancelled() bool
- func (s *Spinner) ClearLine()
- func (s *Spinner) Start()
- func (s *Spinner) Stop()
- func (s *Spinner) StopWithError(message string)
- func (s *Spinner) StopWithSuccess(message string)
- func (s *Spinner) StopWithWarning(message string)
- func (s *Spinner) UpdateMessage(message string)
- type StatsReport
- type TreeOpts
- type TreeStats
- type VulnAffectedPkg
Constants ¶
const ( IconSuccess = "✓" IconError = "✗" IconWarning = "!" IconInfo = "›" IconArrow = "→" IconCached = "cached" IconFresh = "fresh" )
const SpinnerInterval = 80 * time.Millisecond
SpinnerInterval is the shared animation speed for all spinners.
const TUIHints = "↑/↓ navigate ⏎ select q quit"
TUIHints contains shared TUI chrome for navigation hints.
Variables ¶
var ( // AdaptiveColor{Light: colorForLightBg, Dark: colorForDarkBg} ColorPurple = lipgloss.AdaptiveColor{Light: "93", Dark: "135"} // Purple - primary actions ColorGreen = lipgloss.AdaptiveColor{Light: "28", Dark: "76"} // Green - success ColorYellow = lipgloss.AdaptiveColor{Light: "136", Dark: "220"} // Yellow - warnings ColorRed = lipgloss.AdaptiveColor{Light: "124", Dark: "167"} // Red - errors ColorBlue = lipgloss.AdaptiveColor{Light: "27", Dark: "75"} // Blue - links ColorWhite = lipgloss.AdaptiveColor{Light: "235", Dark: "255"} // Text - values (dark on light, white on dark) ColorGray = lipgloss.AdaptiveColor{Light: "242", Dark: "245"} // Gray - secondary text ColorDim = lipgloss.AdaptiveColor{Light: "247", Dark: "240"} // Dim - muted text )
var ( // StyleTitle for main headings. StyleTitle = lipgloss.NewStyle().Bold(true).Foreground(ColorPurple) // StyleHighlight for emphasized values. StyleHighlight = lipgloss.NewStyle().Foreground(ColorPurple) // StyleLink for URLs. StyleLink = lipgloss.NewStyle().Foreground(ColorBlue).Underline(true) // StyleDim for secondary/muted text. StyleDim = lipgloss.NewStyle().Foreground(ColorDim) // StyleValue for data values. StyleValue = lipgloss.NewStyle().Foreground(ColorWhite) // StyleNumber for numeric values. StyleNumber = lipgloss.NewStyle().Foreground(ColorPurple) // StyleSuccess for success messages. StyleSuccess = lipgloss.NewStyle().Foreground(ColorGreen) // StyleWarning for warning messages. StyleWarning = lipgloss.NewStyle().Foreground(ColorYellow) // StyleInfo for informational messages. StyleInfo = lipgloss.NewStyle().Foreground(ColorBlue) // StyleError for error messages. StyleError = lipgloss.NewStyle().Foreground(ColorRed) )
var ( StyleIconSuccess = lipgloss.NewStyle().Foreground(ColorGreen) StyleIconError = lipgloss.NewStyle().Foreground(ColorRed) StyleIconWarning = lipgloss.NewStyle().Foreground(ColorYellow) StyleIconInfo = lipgloss.NewStyle().Foreground(ColorGray) StyleIconSpinner = lipgloss.NewStyle().Foreground(ColorPurple) StyleCached = lipgloss.NewStyle().Foreground(ColorGreen) StyleComputed = lipgloss.NewStyle().Foreground(ColorGray) StyleCommand = lipgloss.NewStyle().Foreground(ColorBlue) StyleKeyLabel = lipgloss.NewStyle().Foreground(ColorGray).Width(12) )
var ( ListSelectedStyle = lipgloss.NewStyle().Bold(true).Foreground(ColorPurple) ListNormalStyle = lipgloss.NewStyle().Foreground(ColorWhite) ListDimStyle = lipgloss.NewStyle().Foreground(ColorDim) TUITableBorder = lipgloss.NewStyle().Foreground(ColorDim) TUIHeaderStyle = lipgloss.NewStyle().Foreground(ColorGray).Bold(true) )
List styles
var SpinnerFrames = []string{"⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"}
SpinnerFrames is the shared animation sequence for all spinners and progress views. Using a consistent animation provides a cohesive visual experience across all CLI operations.
Functions ¶
func FitToWidth ¶
FitToWidth truncates a string to fit within a terminal width.
func FormatAge ¶ added in v1.6.0
FormatAge returns a coarse human-friendly "X minutes/hours/days ago" label for the given timestamp.
func FormatBytes ¶ added in v1.6.0
FormatBytes formats a byte count using IEC binary units (KB = 1024 B, etc.).
Examples:
FormatBytes(512) → "512 B" FormatBytes(2048) → "2.0 KB" FormatBytes(5 * 1 << 20) → "5.0 MB"
func FormatConstraints ¶
FormatConstraints formats a list of constraints for display.
func FormatCount ¶ added in v1.6.0
FormatCount formats a number with K/M suffixes for readability.
Examples:
FormatCount(42) → "42" FormatCount(1_500) → "1.5K" FormatCount(25_000) → "25.0K" FormatCount(1_750_000) → "1.8M"
func FormatDuration ¶
FormatDuration formats a duration for human-readable display.
func FormatRequiredBy ¶
FormatRequiredBy formats the "required by" field for display.
func FormatRuntimeSource ¶ added in v1.6.0
FormatRuntimeSource returns a human-readable parenthesized label for the given runtime-source tag as emitted by the pipeline (e.g. "cli", "manifest", "package", "default"). Unknown values return the empty string.
func NodeVersion ¶ added in v1.6.0
NodeVersion extracts the version string from a DAG node's metadata.
func PadRight ¶
PadRight pads a string to the right with spaces to reach the given display width (using runewidth for correct CJK/emoji handling).
func PrintDetail ¶
PrintDetail prints a detail line (indented) to stderr. Suppressed in quiet mode.
func PrintError ¶
PrintError prints an error message to stderr. Never suppressed.
func PrintFile ¶
func PrintFile(path string)
PrintFile prints a file output line to stderr. Suppressed in quiet mode.
func PrintHeader ¶
func PrintHeader(title string)
PrintHeader prints a styled top-level section header to stderr. Used for multi-phase commands (e.g. GitHub flow) and informational displays (e.g. whoami). Suppressed in quiet mode.
func PrintInline ¶
PrintInline prints a dim message to stderr without a trailing newline.
func PrintKeyValue ¶
func PrintKeyValue(key, value string)
PrintKeyValue prints a labeled value to stderr.
func PrintNewline ¶
func PrintNewline()
PrintNewline prints an empty line to stderr. Suppressed in quiet mode.
func PrintNextStep ¶
func PrintNextStep(description, cmd string)
PrintNextStep prints a suggested next command to stderr. Suppressed in quiet mode.
func PrintRenderStats ¶
func PrintRenderStats(s RenderStats)
PrintRenderStats prints a curated summary of the render operation.
func PrintResolveSummary ¶
func PrintResolveSummary(w io.Writer, result ResolveResult)
PrintResolveSummary prints a summary line for resolved dependencies.
func PrintRuntimeInfo ¶ added in v1.6.0
func PrintRuntimeInfo(langName, version, source string)
PrintRuntimeInfo prints a styled "Runtime: <lang> <version> (source)" line to stderr followed by a blank line. Suppressed in quiet mode. If version is empty, this is a no-op.
func PrintSeparator ¶ added in v1.6.0
func PrintSeparator(title string)
PrintSeparator prints a styled inline separator ("─── Title ───") on its own line, padded with blank lines above and below. Use this to delimit sub-sections WITHIN a single command's output (not as a top-level banner — use PrintHeader for that). Suppressed in quiet mode.
func PrintStats ¶
PrintStats prints graph statistics on a single line to stderr. Suppressed in quiet mode. Pass depth <= 0 to omit the depth field. Pass elapsed <= 0 to omit timing.
func PrintSuccess ¶
PrintSuccess prints a success message to stderr. Suppressed in quiet mode.
func PrintTreeSummary ¶
PrintTreeSummary writes a styled summary line for resolved dependencies.
func PrintVersionInfo ¶
func PrintVersionInfo(version, commit, date string)
PrintVersionInfo prints styled version information to stderr.
func PrintWarning ¶
PrintWarning prints a warning message to stderr. Never suppressed.
func RenderHelp ¶
RenderHelp renders styled help output for a cobra command.
func RenderUsage ¶
RenderUsage renders styled usage output for a cobra command.
func StderrIsTTY ¶ added in v1.6.0
func StderrIsTTY() bool
StderrIsTTY reports whether stderr is an interactive terminal. Progress views and spinners use this since they always write to stderr.
func StderrWidth ¶ added in v1.6.0
func StderrWidth() int
StderrWidth returns the current stderr terminal width, falling back to defaultTerminalWidth (80 columns). Used by the progress view to fit multi-line status output without wrapping.
func StdoutIsTTY ¶ added in v1.6.0
func StdoutIsTTY() bool
StdoutIsTTY reports whether stdout is an interactive terminal. Callers use this to decide between styled human output and machine-readable output suitable for pipes (e.g. `list | head`).
func StdoutWidth ¶ added in v1.6.0
func StdoutWidth() int
StdoutWidth returns the current stdout terminal width, falling back to defaultTerminalWidth (80 columns) when stdout is not a terminal or the width cannot be determined.
func SupportedManifestList ¶
SupportedManifestList returns a comma-separated, alphabetically sorted list of supported manifest filenames across the given languages.
The result for the global languages.All slice is cached because it's hit from error paths that can fire multiple times per command (e.g. `resolve` surfacing both an argument hint and a file-not-found hint in one run), and the list is stable for the lifetime of the process.
func Truncate ¶
Truncate truncates a string to the given max display width, adding "..." if needed. Uses runewidth to avoid slicing mid-rune.
func WriteDiff ¶ added in v1.5.0
func WriteDiff(w io.Writer, d *dag.DiffResult)
WriteDiff renders a diff result to the writer in the styled terminal format.
func WritePaths ¶ added in v1.5.0
WritePaths renders dependency paths to the writer in the styled terminal format.
func WriteResolveOutput ¶
func WriteResolveOutput(w io.Writer, result ResolveResult, color bool)
WriteResolveOutput writes a formatted resolver output to w.
func WriteStats ¶ added in v1.5.0
func WriteStats(w io.Writer, r StatsReport)
WriteStats renders a stats report to the writer in the styled terminal format.
Types ¶
type LoadBearingEntry ¶ added in v1.5.0
type LoadBearingEntry struct {
Package string `json:"package"`
ReverseDeps int `json:"reverse_deps"`
}
LoadBearingEntry records a load-bearing package and its reverse dep count.
type ManifestListModel ¶
type ManifestListModel struct {
Manifests []github.ManifestFile
Cursor int
Selected *github.ManifestFile
}
ManifestListModel is the bubbletea model for interactive manifest selection.
func NewManifestListModel ¶
func NewManifestListModel(manifests []github.ManifestFile) ManifestListModel
NewManifestListModel creates a new manifest list model.
func (ManifestListModel) Init ¶
func (m ManifestListModel) Init() tea.Cmd
func (ManifestListModel) View ¶
func (m ManifestListModel) View() string
type Operation ¶
type Operation interface {
// Stop halts the operation's progress display.
Stop()
// StopWithError stops and displays an error message.
StopWithError(message string)
}
Operation represents a running CLI operation with progress indication. Both Spinner and ProgressView implement this interface, allowing code to work with either depending on the complexity of the operation.
Use Spinner for simple operations (network fetches, file I/O). Use ProgressView for complex resolver operations with observability hooks.
type ProgressView ¶
type ProgressView struct {
// contains filtered or unexported fields
}
ProgressView renders live resolver progress on stderr. It implements both observability.ResolverHooks and observability.RateLimitHooks so the crawler and HTTP clients feed it events without any direct coupling to CLI code.
ProgressView uses shared spinner frames from styles.go for consistent visual appearance with the simpler Spinner component.
func NewProgressView ¶
func NewProgressView(ctx context.Context, message string, maxNodes int) *ProgressView
NewProgressView creates a new progress view.
func (*ProgressView) OnCircuitStateChange ¶
func (pv *ProgressView) OnCircuitStateChange(_ context.Context, registry string, state observability.CircuitState, until time.Time)
func (*ProgressView) OnEnrichComplete ¶
func (*ProgressView) OnEnrichStart ¶
func (pv *ProgressView) OnEnrichStart(_ context.Context, provider string, count int)
func (*ProgressView) OnFetchComplete ¶
func (*ProgressView) OnFetchStart ¶
func (pv *ProgressView) OnFetchStart(_ context.Context, pkg string, _ int)
func (*ProgressView) OnProgress ¶
func (pv *ProgressView) OnProgress(_ context.Context, _, pending, _ int)
func (*ProgressView) OnRateLimitHit ¶
func (pv *ProgressView) OnRateLimitHit(_ context.Context, registry string, retryAfterSeconds int)
func (*ProgressView) OnRateLimitWait ¶
func (*ProgressView) Start ¶
func (pv *ProgressView) Start()
Start registers hooks and launches the render loop. If another ProgressView is already active, Start is a no-op (the other view keeps its hook registrations). This guards against accidental concurrent use, which would otherwise race for the global observability hook slots.
func (*ProgressView) Stop ¶
func (pv *ProgressView) Stop()
Stop deregisters hooks, cancels the render loop, and clears the output area.
func (*ProgressView) StopWithError ¶
func (pv *ProgressView) StopWithError(message string)
StopWithError deregisters hooks, clears progress, and prints an error.
type ProgressWriter ¶
type ProgressWriter struct {
// contains filtered or unexported fields
}
ProgressWriter wraps an io.Writer so that any write (e.g. from a logger) first clears the progress display. The next render tick redraws it below the newly written content, preventing interleaved output.
func NewProgressWriter ¶
func NewProgressWriter(pv *ProgressView, w io.Writer) *ProgressWriter
NewProgressWriter creates a writer that clears progress before writing.
type RefListModel ¶
type RefListModel struct {
Items []RefItem
Cursor int
Selected *RefItem
Filter string
Filtered []int // indices into Items matching the filter
Height int
Offset int
}
RefListModel is the bubbletea model for interactive ref selection.
func NewRefListModel ¶
func NewRefListModel(branches []github.Branch, tags []github.Tag, defaultBranch string) *RefListModel
NewRefListModel creates a ref list with the default branch first.
func (*RefListModel) Init ¶
func (m *RefListModel) Init() tea.Cmd
func (*RefListModel) View ¶
func (m *RefListModel) View() string
type RenderStats ¶
type RenderStats struct {
Layers int
Crossings int
OrderingRan bool // true when layout ordering was computed (not just visualization)
Ordering string
Style string
Dimensions string
}
RenderStats holds curated render output info.
type RepoListModel ¶
type RepoListModel struct {
Repos []github.RepoWithManifests
Cursor int
Selected *RepoSelection
Height int
Offset int
}
RepoListModel is the bubbletea model for interactive repo selection.
func NewRepoListModel ¶
func NewRepoListModel(repos []github.RepoWithManifests) RepoListModel
NewRepoListModel creates a new repo list model.
func (RepoListModel) Init ¶
func (m RepoListModel) Init() tea.Cmd
func (RepoListModel) View ¶
func (m RepoListModel) View() string
type RepoSelection ¶
type RepoSelection struct {
Repo *github.RepoWithManifests
}
RepoSelection holds the result of the repo selection.
type ResolveEntry ¶
type ResolveEntry = pipeline.ResolveEntry
Type aliases for pipeline types used in UI functions. These make the UI code cleaner while keeping the types in the pipeline package.
type ResolveResult ¶
type ResolveResult = pipeline.ResolveResult
Type aliases for pipeline types used in UI functions. These make the UI code cleaner while keeping the types in the pipeline package.
type Spinner ¶
type Spinner struct {
// contains filtered or unexported fields
}
Spinner provides a simple progress indicator with context cancellation support. It uses shared animation frames from styles.go for consistent visual appearance across all CLI operations.
For complex resolver operations that require observability hooks, use ProgressView instead.
func NewSpinner ¶
NewSpinner creates a new spinner with the given message. The spinner uses shared animation frames from styles.go.
func NewSpinnerWithContext ¶
NewSpinnerWithContext creates a spinner that will stop when the context is cancelled. The spinner uses shared animation frames from styles.go.
func (*Spinner) Cancelled ¶
Cancelled returns true if the spinner was stopped due to context cancellation.
func (*Spinner) ClearLine ¶
func (s *Spinner) ClearLine()
ClearLine clears the current spinner line without stopping. Use this before printing other output while the spinner is running.
func (*Spinner) Start ¶
func (s *Spinner) Start()
Start begins the spinner animation. It is safe to call more than once; subsequent calls are no-ops.
In quiet mode or when stderr is not a terminal, no animation is shown but Stop() remains callable.
func (*Spinner) Stop ¶
func (s *Spinner) Stop()
Stop stops the spinner and clears the line. Stop is safe to call concurrently from multiple goroutines.
func (*Spinner) StopWithError ¶
StopWithError stops the spinner and shows an error message.
func (*Spinner) StopWithSuccess ¶
StopWithSuccess stops the spinner and shows a success message.
func (*Spinner) StopWithWarning ¶
StopWithWarning stops the spinner and shows a warning message.
func (*Spinner) UpdateMessage ¶
UpdateMessage changes the spinner message while running. This is useful for multi-phase operations that need to indicate progress.
type StatsReport ¶ added in v1.5.0
type StatsReport struct {
Root string `json:"root"`
Version string `json:"version,omitempty"`
Language string `json:"language,omitempty"`
// Overview
TotalPackages int `json:"total_packages"`
TotalEdges int `json:"total_edges"`
MaxDepth int `json:"max_depth"`
DirectDeps int `json:"direct"`
TransitiveDeps int `json:"transitive"`
// Maintenance
SingleMaintainerCount int `json:"single_maintainer_count,omitempty"`
SingleMaintainerPct float64 `json:"single_maintainer_pct,omitempty"`
Brittle []string `json:"brittle,omitempty"`
Archived []string `json:"archived,omitempty"`
MedianLastCommitDays int `json:"median_last_commit_days,omitempty"`
HasMaintenanceData bool `json:"-"`
// Licenses
LicenseSummary map[string]int `json:"license_summary,omitempty"` // risk category -> count
LicenseBreakdown map[string]int `json:"license_breakdown,omitempty"` // license name -> count
Compliant bool `json:"compliant,omitempty"`
HasLicenseData bool `json:"-"`
// Vulnerabilities
VulnCritical int `json:"vuln_critical,omitempty"`
VulnHigh int `json:"vuln_high,omitempty"`
VulnMedium int `json:"vuln_medium,omitempty"`
VulnLow int `json:"vuln_low,omitempty"`
VulnAffected []VulnAffectedPkg `json:"vuln_affected,omitempty"`
HasVulnData bool `json:"-"`
// Load-bearing
LoadBearing []LoadBearingEntry `json:"load_bearing,omitempty"`
}
StatsReport holds all data for the stats terminal output.
JSON tags are provided as a convenience for future callers that want to encode this value directly. Note that the CLI's `stats -f json` uses a re-grouped wire format (nested overview/maintenance/licenses/vulnerabilities sections) rather than the flat layout here, so the tags below are not used by the CLI today; see MaintenanceSummary / MaintenanceSummary etc. in internal/cli/stats.go for the actual wire schema.
type TreeOpts ¶
type TreeOpts struct {
Color bool
ShowMeta bool // display description/license/stars beneath each node
}
TreeOpts controls tree rendering behavior.
type VulnAffectedPkg ¶ added in v1.5.0
VulnAffectedPkg describes a package with a vulnerability.