Repository navigation
[terminal-stylist] Terminal Stylist: console output consistency in pkg/ (Go) #76457
Closed
Replies: 1 comment
|
This discussion has been marked as outdated by Terminal Stylist. A newer discussion is available at Discussion #76814. |
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.
Overview
Scope: 1,926 non-test Go files under
pkg/(_test.goandtestdata/excluded). This analysis is read-only: no code was changed and no repository tests were run. Console output is mostly centralised: 1,883 of 2,702 terminal-directedfmtcalls (70%) go throughpkg/console. The main gap is 819 raw calls (705 to stderr), concentrated inpkg/cli.Key metrics
fmtcalls (Print*, orFprint*toos.Stdoutoros.Stderr)pkg/consoleconsole.*in the call)pkg/cli760,pkg/workflow54,pkg/console4,pkg/actionpins1pkg/stylesLipgloss and Huh usage
charm.land/lipgloss/v2): 12 non-test files import it. Colours come from a shared adaptive light and dark palette inpkg/styles/theme.go. Directlipgloss.NewStyle()calls outsidepkg/consoleandpkg/stylesnumber 9: 6 in the TUI view (pkg/cli/work_command_tui_view.go), layout-only padding inpkg/cli/engine_secrets.goandpkg/cli/compile_schedule_calendar.go, and the logger palette inpkg/logger/logger.go. These look reasonable.charm.land/huh/v2): 60huh.New*calls (fields and options) inpkg/cli, all wrapped byconsole.NewConfirmForm,NewInputForm,NewSelectFormorNewForm. The onlyhuh.NewFormcall (pkg/console/prompt_form.go) appliesstyles.HuhThemeandWithAccessible(IsAccessibleMode()).PromptForm.RunandRunWithContextcheck that stdin and stderr are terminals first. This is a strong pattern.Findings
1. Raw stderr text bypasses formatters (highest impact)
Instructional lines are unstyled, and commands are not visually separated from prose.
Bad:
Good:
Hot spots:
pkg/cli/preconditions.go,pkg/cli/engine_secrets.go,pkg/cli/add_interactive_auth.go,pkg/cli/add_interactive_engine.goandpkg/cli/experiments_analyze_statistics.go. Eight raw calls align labels by hand (%-Ns), and four build separators withstrings.Repeat. Where the output is human-facing,console.RenderStructorconsole.FormatSectionHeaderwould replace them.2. Inconsistent warning glyph and hard-coded prefixes
✓,✗,⚠andi, each followed by one space.⚠️(with the VS16 selector and two spaces) appears 17 times. The plain⚠glyph appears 12 times. Terminals render the two with different widths (example:pkg/cli/deps_report.go).Warning:inpkg/workflow/cache_steps.goandpkg/workflow/push_to_pull_request_branch.go, andNote:inpkg/cli/preconditions.go.✅ **Status:**inpkg/cli/mcp_inspect_mcp.go.3. Markdown syntax written to stderr
Thirteen raw stderr lines in
pkg/cli/mcp_inspect_mcp.go(for example📝 **Description:**) contain Markdown bold markers. In a terminal the asterisks show literally. If the output is meant for Markdown consumers, send it to stdout. Otherwise, use styled labels.4. Formatters wrap printf format strings (fragile)
23 call sites in
pkg/cli/trial_confirmation.goandpkg/cli/run_push.gopass a formatter output as the format argument:This works today because the formatter only adds a prefix and ANSI styling. However, the format argument is not a constant, so
go vetcannot check it, and any formatter that transforms its input would break the verbs. Format first, then style:console.FormatInfoMessageStderr(fmt.Sprintf(...)).5. Banner styled for the wrong stream
pkg/console/banner.go:FormatBanner()usesapplyStyle, which checks the stdout TTY state, butPrintBanner()writes to stderr. If stdout is piped and stderr is a terminal, the banner loses its colour. Leaked escape codes are unlikely, becausecolorwriter.Stderr()strips ANSI when stderr is not a terminal. This comes from code reading and was not run. Fix: addFormatBannerStderrbacked byapplyStderrStyle.6. NO_COLOR also enables accessible prompts
IsAccessibleMode()returns true whenNO_COLORis set, andconsole.NewFormpasses that value toWithAccessible. Users who disable colour therefore also get the Huh accessible (line-based) prompt mode. This may be intended, but it couples two separate preferences. Review it.What works well
*Stdoutvariants check the stdout TTY state. Direct writes show no mismatches.pkg/linters/consolestderrenforces destination-aware formatting for direct standard-stream writes, and it is registered.fmt.Fprintln(os.Stderr, console.*)calls use the console package correctly.NO_COLORandTERM=dumbhandling, and no hard-coded hex colours outsidepkg/styles.pkg/cli) looks deliberate and is not flagged.Top files by raw terminal calls
pkg/cli/audit_diff_render.go(partly stdout Markdown report)pkg/cli/audit_report_render.go(partly stdout Markdown report)pkg/cli/mcp_inspect_mcp.gopkg/cli/experiments_analyze_statistics.gopkg/cli/preconditions.gopkg/cli/audit_cross_run_render.gopkg/cli/engine_secrets.gopkg/cli/deps_report.gopkg/cli/shell_completion.gopkg/cli/add_interactive_orchestrator.gopkg/cli/copilot_setup.goRecommendations (priority order)
pkg/clithrough console helpers, starting withpreconditions.go,engine_secrets.goand theadd_interactive_*.gofiles.⚠(replace the 17⚠️sites), and replace hard-codedWarning:andNote:prefixes with formatters.mcp_inspect_mcp.go, or send that output to stdout.FormatBannerStderrso the banner matches its destination.NO_COLORshould imply accessible prompts, and document the decision.consolestderr-style analyzer that flags rawfmt.Fprint*(os.Stderr, "literal")calls inpkg/cli, with(nolint/redacted)for intentional cases. This would stop the raw backlog from growing.Scope and limitations
_test.gofiles andtestdata/directories are excluded. Counts come from a Go AST scan plus grep. Serena was used for project activation and reference lookups.charm.land/..., notgithub.com/charmbracelet/....References: §42784303186
All reactions