[terminal-stylist] Terminal Stylist: Console Output Analysis — pkg/ Charmbracelet Best Practices Review #41645
Replies: 1 comment 1 reply
-
|
/plan |
Beta Was this translation helpful? Give feedback.
1 reply
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
This report analyzes console output patterns across all 959 non-test Go source files in
pkg/to evaluate consistency, Lipgloss styling, Huh form usage, and opportunities for improvement.Key Metrics
pkg/Go source filespkg/consolefmt.Fprintln/Fprintfto stderr (outsidepkg/console)huhformshuhfiles missingWithThemeorWithAccessibleStrengths ✅
pkg/console,pkg/styles, andpkg/ttyform a cohesive system with clear separation of concerns.pkg/stylesimplements a customadaptiveColortype that probes the terminal background at startup and selects Dracula-inspired dark or muted-saturated light variants automatically. Windows is safely excluded from the probe.applyStyle()inconsole.goalways checksisTTY()before applying Lipgloss styles, preventing raw ANSI codes from appearing in pipes/redirects.lipgloss/tablefully adopted —RenderTable()uses thecharm.land/lipgloss/v2/tablepackage with header, zebra-row, and total-row styles, plusRoundedBorderfor a polished appearance.lipgloss.JoinVerticalfor layout —RenderComposedSections()composes UI sections with proper layout rather than concatenating strings.huh(9 inpkg/cli, 3 inpkg/console, 1 inpkg/styles) apply bothWithTheme(styles.HuhTheme)andWithAccessible(console.IsAccessibleMode()), providing brand-consistent interactive forms with accessibility support.HuhTheme—pkg/styles/huh_theme.gomaps the shared color palette to all Huh field states (focused, blurred, selected, error, button, cursor), usinglipgloss.LightDark()correctly for the v2 API.ConfirmAction()andShowInteractiveList()both detect non-TTY and fall back to text-based interaction.terminal.gouses raw\033[sequences, strictly for cursor control (clear screen, clear line), and these are wrapped intty.IsStderrTerminal()guards.Issues and Recommendations
compile_stats.go— styled summaries, unstyled sub-itemscompile_stats.gousesconsole.FormatErrorMessage()for top-level summaries but drops back to rawfmt.Fprintffor indented sub-items, creating visual inconsistency:Recommendation: Use
console.FormatListItem(),console.FormatInfoMessage(), andstyles.Error.Render()for the sub-items to match the top-level styling. The✗,💡, andisymbols should use styled prefixes like other message types.pkg/consoleThese files emit user-facing messages to stderr with no styling, bypassing the console abstraction entirely:
cli/add_interactive_secrets.go"Found %d existing secret(s)..."cli/copilot_setup.go"No version upgrade needed...","Updated %s with new version..."cli/devcontainer.go"Updated existing devcontainer...","Created new devcontainer..."cli/mcp_config_file.go"MCP server '%s' already configured..."cli/observability_insights.go" %s %s [%s]\n"for insight itemscli/vscode_config.go"Settings file already exists at %s"Recommendation: Add
pkg/consoleimport and use the appropriate format function:console.FormatSuccessMessage()console.FormatInfoMessage()observability_insights.goinsight rendering → considerconsole.RenderTable()orconsole.FormatSectionHeader()+console.FormatListItem()i️ 3.
logs_format_compact.go— intentional machine-readable stdout (no action needed)logs_format_compact.gousesfmt.Fprintf(os.Stdout, ...)with key=value structured format ([summary],[runs],[errors], etc.). This is intentional machine-readable output for scripting and piping — it should not be styled. No changes recommended here.i️ 4. Huh — no
MultiSelectorNotefields observedThe current Huh usage covers
Input,Confirm, andSelectfield types. Two opportunities for enhanced UX:huh.NewMultiSelect: Theadd_interactive_workflow.goflow that collects tool selections would benefit from aMultiSelectfield instead of multipleSelectfields or CLI flags. TheHuhThemealready coversMultiSelectSelector,SelectedPrefix, andUnselectedPrefixstyles.huh.NewNote: Long instructional text currently printed withfmt.Fprintlnbefore forms could be moved into aNotefield so the help text stays in-form and scrolls with it.i️ 5.
experiments_command.gomanual table formattingexperiments_command.gobuilds manual text tables withfmt.Fprintf(os.Stderr, " %-20s %d (%d%%)\n", ...). Withconsole.RenderTable()available this could be upgraded to a proper styled table with borders, zebra rows, and adaptive colors — especially useful for the experiments breakdown output.Lipgloss Usage — Detailed Assessment
Full Lipgloss Analysis
What's done well:
adaptiveColorstruct implementscolor.Colorand is used for every semantic color — no hardcoded hex strings appear at the style callsitesRoundedBorder,NormalBorder,ThickBorder) centralized inpkg/stylesand reused acrossconsole.goapplyStyle(style, text)is a clean TTY-detection wrapper that avoids conditional blocks at every callsiteRenderTitleBox()andRenderErrorBox()correctly fall back to plain-text separators in non-TTY modelipgloss.JoinVertical(lipgloss.Left, sections...)used inRenderComposedSections()— correct composition patternScheduleCalendarEmpty/Low/Medium/High/Critical) follow the semantic color progression correctlyMinor gaps:
ShowWelcomeBanner()interminal.gousesstyles.Header.Render(header)but doesn't wrap inapplyStyle()— instead uses a manual TTY check. While functionally equivalent, it diverges from theapplyStyle()pattern used everywhere else.BannerStyleinbanner.gois exported as avarbut itsapplyStyle()call is inFormatBanner(). Callers usingBannerStyledirectly could bypass TTY detection. Consider keepingBannerStyleunexported.Huh Usage — Detailed Assessment
Full Huh Analysis
Files and patterns:
console/confirm.goConfirmconsole/input.goInput(password)console/list.goSelectcli/interactive.goSelect,Input,Confirmcli/run_interactive.goSelect,Input,Confirmcli/add_interactive_*.go(×5)cli/engine_secrets.goInputAccessibility support:
console.IsAccessibleMode()reads theACCESSIBLEenv variable and propagates it to Huh's accessible text modeValidation:
console/input.gouses.Validate()with empty-string check — good patternconsole/confirm.gonon-TTY fallback parsesy/yes/1/n/no/2— robust text fallbackGaps:
.Validate()callbacks observed in theadd_interactive_*.goforms beyond whathuhprovides nativelyhuh.NewNoteusage for in-form rich documentationhuh.NewMultiSelectdespite multiple multi-value collection pointsNext Actions
fmt.Fprintfsub-items incompile_stats.gowithconsole.FormatListItem()/ styled helperscli/compile_stats.gopkg/consoleimport and use format helpers in the 6 files that bypass itadd_interactive_secrets.go,copilot_setup.go,devcontainer.go,mcp_config_file.go,observability_insights.go,vscode_config.goexperiments_command.gomanual table toconsole.RenderTable()cli/experiments_command.gohuh.NewMultiSelectfor tool/option selection in interactive add wizardcli/interactive.go,cli/add_interactive_workflow.gohuh.NewNotefor pre-form instructional textcli/add_interactive_*.goBannerStyleunexported to prevent direct style use that bypasses TTY detectionconsole/banner.goReferences:
[§28230500820]Beta Was this translation helpful? Give feedback.
All reactions