[terminal-stylist] Terminal Stylist: Console Output Analysis #43520
Closed
Replies: 2 comments 1 reply
-
|
/plan |
Beta Was this translation helpful? Give feedback.
1 reply
-
|
This discussion was automatically closed because it expired on 2026-07-06T09:39:34.305Z.
|
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
Scope:
pkg/directory, 1,005 non-test Go source filesLibraries analysed:
charm.land/lipgloss/v2,charm.land/huh/v2,charm.land/bubbles/v2,charm.land/lipgloss/v2/tree,charm.land/lipgloss/v2/tableSummary
The codebase has a mature, well-structured terminal output system. Central style definitions live in
pkg/styles/, formatting helpers inpkg/console/, and interactive forms are consistently themed viastyles.HuhTheme. The vast majority of user-facing output passes through the console package correctly. A small set of callsites bypass it, and a few minor patterns could be tightened.Key Metrics
charm.*librariesconsole.*helpers.WithTheme+.WithAccessible)fmt.Fprintf(os.Stderr, ...)without console wrapperstyles.X.Render()without TTY guardpkg/console/terminal.goLipgloss Usage Analysis
✅ Strengths
pkg/styles/theme.go): TheadaptiveColortype satisfiescolor.Colorand automatically selects light/dark hex variants based on a startup terminal probe (lipgloss.HasDarkBackground). Windows is safely excluded from the probe to avoid ConPTY crashes.ColorError,ColorWarning,ColorSuccess,ColorInfo,ColorPurple,ColorYellow,ColorComment,ColorForeground,ColorBackground,ColorBorder,ColorTableAltRow) — Dracula-inspired dark, accessible light equivalents.styles.Error,styles.Warning,styles.Success,styles.Info,styles.FilePath,styles.Command,styles.Progress,styles.Prompt,styles.Verbose,styles.Header,styles.TableHeader,styles.TableCell,styles.TableTotal,styles.TableBorder,styles.ListHeader,styles.ListItem,styles.ServerName,styles.ServerType,styles.ErrorBox,styles.TreeEnumerator,styles.TreeNode,styles.ScheduleCalendar*.pkg/console/console.goprovidesapplyStyleandapplyStyleWithTTYwrappers. AllRenderTable,RenderTitleBox,RenderErrorBox,RenderInfoSection, andRenderComposedSectionsfunctions checktty.IsStderrTerminal()or use the injectableTTYFuncfield inTableConfig.lipgloss/tablefor data tables:RenderTableusescharm.land/lipgloss/v2/tablewith zebra-stripeStyleFunc, rounded borders, and header/total row differentiation.lipgloss/treefor hierarchical data:pkg/cli/status_command.gousescharm.land/lipgloss/v2/treewithstyles.TreeEnumeratorandstyles.TreeNode, matching the design system.lipgloss.Fprintfin logger:pkg/logger/logger.gouseslipgloss.Fprintf(color-profile-aware writer) rather thanfmt.Fprintf, ensuring ANSI is stripped when the output is not a terminal.compile_schedule_calendar.go(lines 252, 264): Callsstyles.TableHeader.Render(header)andstyles.TableHeader.Render(label)without going throughapplyStyle. Both are inside anif isTerminalblock, so the TTY check is correct — but for consistency with the rest of the codebase the pattern should useconsole.applyStyleor justapplyStyleWithTTY. SinceapplyStyleis unexported, consider adding aninternalvariant or moving these to useRenderTable.compile_stats.go(lines 302–303): Usesstyles.Error.Render("✗ ")directly inside atty.IsStderrTerminal()guard. Functionally correct but inconsistent withconsole.FormatErrorMessage; could reuseapplyStyleWithTTY.org_runner.go(lines 87–103),update_container_pins.go(lines 160–344): Plainfmt.Fprintf(os.Stderr, " - ...")messages without color or console formatting. These are informational list items — ideal candidates forconsole.FormatListItemStderrorconsole.FormatInfoMessageStderr.mcp_list_tools.go(lines 77–136): Uses rawfmt.Fprintf(os.Stderr, ...)for informational messages about MCP server discovery. Suitable forconsole.FormatInfoMessageStderr.Huh Forms Usage Analysis
✅ Strengths
pkg/cli/(add-wizard, run-interactive, engine-secrets, interactive.go) andpkg/console/(confirm, input, list). All use.WithTheme(styles.HuhTheme).WithAccessible(console.IsAccessibleMode()).pkg/styles/huh_theme.go):HuhThemeis ahuh.ThemeFuncusinglipgloss.LightDark(isDark)for per-render color selection (correct for forms, distinct from the package-leveladaptiveColorprobe). Maps all semantic palette colors to focused/blurred/group styles.pkg/console/accessibility.go): DetectsACCESSIBLE,TERM=dumb, andNO_COLORenv vars and passesIsAccessibleMode()to all forms.huh.NewInput,huh.NewConfirm,huh.NewSelect,huh.NewMultiSelect,huh.NewTextare all in use.huh.NewInputwithEchoMode(huh.EchoModePassword)is used for secret input.pkg/console/confirm.goandpkg/console/input.gochecktty.IsStderrTerminal()before showing a form and fall back to plain text input — good UX.showTextConfirminconfirm.goprovides a readable non-interactive alternative.add_interactive_auth.go,add_interactive_git.go: Huh forms are constructed directly in CLI files rather than going through thepkg/consoleabstraction layer. This duplicates the.WithTheme(styles.HuhTheme).WithAccessible(console.IsAccessibleMode())chain — consider thin wrappers inpkg/console(e.g.,console.PromptSelect,console.PromptInput) that bake in theme + accessibility automatically, reducing boilerplate.Validation messages: Validation closures in
engine_secrets.goandrun_interactive.goreturn plainerrors.New("...")strings. For consistency, these could usefmt.Errorfwith the same terse, lowercase style used in compilation errors.No
Notefields:huh.NewNoteis available for displaying contextual help inside forms but is not currently used. Where wizard steps display explanatory text viafmt.Fprintln(os.Stderr, ...)before showing a form, aNotefield would keep context co-located with the form.Raw fmt.Print* Callsites That Bypass Console Formatting
These are callsites in
pkg/cli/writing directly toos.Stderr/os.Stdoutwithout aconsole.*wrapper:trial_confirmation.gofmt.Fprintf(os.Stderr, " a. Execute...")sub-step bulletsconsole.FormatListItemStderrtrial_confirmation.gofmt.Fprintln(os.Stderr, "")blank linesorg_runner.gofmt.Fprintf(os.Stderr, " - ...")bullet pointsconsole.FormatListItemStderrmcp_list_tools.goconsole.FormatInfoMessageStderrexperiments_command.goconsole.FormatInfoMessageStderrhealth_command.gofmt.Fprintln(os.Stderr, "")spacingupdate_container_pins.go" image: reason"console.FormatListItemStderrlogs_format_compact.go[tag] valuemachine-parseable formatNote:
logs_format_compact.godeliberately emits machine-parseable[tag] valuetokens to stdout/writer — this is correct and should not use console styling.Recommendations
High value, low effort:
Wrap
org_runner.goandmcp_list_tools.goinformational bullets withconsole.FormatInfoMessageStderr/console.FormatListItemStderr. These are user-facing status lines that would benefit from thei/•prefix and color.Sub-step bullets in
trial_confirmation.go(lines 182–183, 199–200): The surrounding steps useconsole.FormatInfoMessage; the two unformatted" a./b."sub-items are visually inconsistent. Considerconsole.FormatListItemStderrwith a custom indent or a dedicatedFormatSubItemhelper.Architectural consideration:
pkg/consolewrappers (PromptInput,PromptSelect,PromptMultiSelect,PromptText). This would eliminate the 16 copy-pasted.WithTheme(styles.HuhTheme).WithAccessible(console.IsAccessibleMode())chains inpkg/cli/and enforce consistent form behavior automatically.Already excellent — no action needed:
lipgloss/tablewith TTY-awareStyleFunc✅lipgloss/treeusing design-system styles ✅lipgloss.Fprintfin logger for color-safe output ✅pkg/console/terminal.goconstants ✅References:
Beta Was this translation helpful? Give feedback.
All reactions