You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This analysis covers all Go source files in pkg/ (excluding tests) for console output patterns, Lipgloss styling, and Huh form usage. The codebase shows a mature, well-structured approach to terminal output with a dedicated pkg/console package that centralizes formatting. The overall quality is high, with several specific improvement opportunities identified.
Summary Statistics
Pattern
Count
fmt.Fprintln/Fprintf (total)
2,971
fmt.Fprintln(os.Stderr, ...) calls
2,216
console.Format* usages
1,482
lipgloss.* usages
102
huh.* usages
122
Huh forms in pkg/cli/
16
Huh forms with WithTheme + WithAccessible
16 (100%)
✅ What's Working Well
Lipgloss — Robust Styling Infrastructure
Adaptive colors: pkg/styles/theme.go defines every semantic color with both light/dark variants via compat.AdaptiveColor, automatically adapting to terminal background. Example: ColorError = compat.AdaptiveColor{Light: "#D73737", Dark: "#FF5555"}.
TTY detection: applyStyle() in pkg/console/console.go guards all styling behind isTTY(), preventing ANSI escape codes from leaking into pipes/redirects.
WASM compatibility: All non-terminal platforms have stub implementations in *_wasm.go files — clean build-tag separation.
Table rendering: console.RenderTable uses lipgloss/table for structured data, abstracted behind a TableConfig struct.
Struct-tag rendering: console.RenderStruct provides reflection-based rendering with console:"header:" and console:"title:" tags — a standout feature.
Huh — Consistent Interactive Forms
100% theme/accessibility coverage: All 16 huh.NewForm calls in pkg/cli/ correctly chain .WithTheme(styles.HuhTheme).WithAccessible(console.IsAccessibleMode()).
Accessibility detection: IsAccessibleMode() checks ACCESSIBLE, NO_COLOR, and TERM=dumb env vars — comprehensive.
TTY guard before forms: pkg/console/input.go, list.go, and confirm.go all check tty.IsStderrTerminal() before launching interactive prompts and fall back gracefully.
Validation present: PromptSecretInput validates non-empty input with a proper error message.
Custom theme: styles.HuhTheme provides branded styling, keeping forms visually consistent with the rest of the CLI.
⚠️ Improvement Opportunities
1. TTY Stream Inconsistency in pkg/console/console.go
The module-level isTTY() helper checks stdout, but all format functions (FormatSuccessMessage, FormatInfoMessage, etc.) are used with os.Stderr. Lines 344–398 call tty.IsStderrTerminal() directly, creating a split:
Recommendation: Rename isTTY() to isStdoutTTY() and introduce isStderrTTY(), or reconsider whether applyStyle (used on stderr-bound output) should check tty.IsStderrTerminal() instead.
2. Unformatted Messages in User-Facing Code
Several pkg/cli/ files write plain strings directly to stderr instead of using console formatters. These messages lose color, icon prefixes, and consistent styling:
Files with unformatted stderr messages (click to expand)
pkg/cli/preconditions.go (lines 26–142) — All precondition guidance messages:
// ❌ Currentfmt.Fprintln(os.Stderr, "Please run the following command to authenticate:")
fmt.Fprintln(os.Stderr, "Agentic workflows require GitHub-owned actions to run.")
// ✅ Recommendedfmt.Fprintln(os.Stderr, console.FormatInfoMessage("Please run the following command to authenticate:"))
fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Agentic workflows require GitHub-owned actions to run."))
// ❌ Current — raw Unicode box-drawing character as separatorfmt.Fprintln(os.Stderr, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
fmt.Fprintln(os.Stderr, "Operation cancelled.")
// ✅ Recommended — use console.FormatSectionHeader or styles.TableHeaderfmt.Fprintln(os.Stderr, console.FormatSectionHeader("Next steps"))
fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Operation cancelled."))
// ❌ Currentfmt.Fprintln(os.Stderr, "Please merge the PR manually from the GitHub web interface.")
// ✅ Recommendedfmt.Fprintln(os.Stderr, console.FormatInfoMessage("Please merge the PR manually from the GitHub web interface."))
pkg/cli/add_interactive_workflow.go (lines 63–139) — status messages during wizard:
// ❌ Currentfmt.Fprintln(os.Stderr, "Updating local branch (this may take a few seconds)...")
// ✅ Recommendedfmt.Fprintln(os.Stderr, console.FormatProgressMessage("Updating local branch (this may take a few seconds)..."))
pkg/cli/fix_command.go (lines 248–249) — hint after fix:
// ❌ Currentfmt.Fprintln(os.Stderr, " gh aw fix --write")
// ✅ Recommended — use FormatCommandMessagefmt.Fprintln(os.Stderr, " "+console.FormatCommandMessage("gh aw fix --write"))
3. Direct Lipgloss Usage in pkg/cli/compile_schedule_calendar.go
intensityStyle() creates lipgloss.NewStyle() values inline using styles.Color* constants, which is fine. However the table rows are manually built with a strings.Builder, and separators/headers are written with fmt.Fprintln(os.Stderr, styles.TableHeader.Render(header)). This bypasses the console.RenderTable abstraction.
Recommendation: For complex calendar-style output that doesn't map to simple tables, the current approach is acceptable. Consider extracting a console.FormatCalendar helper to keep CLI command files free of direct Lipgloss calls.
4. Markdown Report to Stdout in audit_cross_run_render.go
Lines 29–50 write raw Markdown headings and pipe-separated tables directly to stdout:
This is intentional for machine-readable output, but the hardcoded # h1 heading violates the style guide (which reserves h1 for titles). If this output is meant for human reading in a terminal, consider using console.RenderStruct with struct tags for the table sections, or at minimum downgrade headers to ###.
📋 Prioritized Recommendations
Priority
File
Action
🔴 High
pkg/console/console.go
Fix TTY stream split: isTTY() checks stdout while format functions output to stderr
🟠 Medium
pkg/cli/preconditions.go
Replace plain fmt.Fprintln(os.Stderr, ...) strings with console.FormatInfoMessage / FormatWarningMessage
🟠 Medium
pkg/cli/add_interactive_orchestrator.go
Replace raw Unicode separator and plain messages with console.FormatSectionHeader / FormatWarningMessage
🟡 Low
pkg/cli/add_interactive_git.go
Wrap instruction messages with FormatInfoMessage
�� Low
pkg/cli/add_interactive_workflow.go
Wrap progress messages with FormatProgressMessage
🟡 Low
pkg/cli/fix_command.go
Wrap command hints with FormatCommandMessage
🔵 Info
pkg/cli/audit_cross_run_render.go
Consider whether stdout Markdown output should use lower heading levels
💡 Charmbracelet Ecosystem Best Practices — Compliance Summary
Practice
Status
Notes
Adaptive colors (light/dark)
✅ Excellent
All colors in pkg/styles have both variants
TTY detection before styling
✅ Good
applyStyle() guards all Lipgloss calls
Consistent semantic styles
✅ Good
console.Format*Message functions used throughout
Huh forms with theme
✅ Excellent
100% of forms use WithTheme(styles.HuhTheme)
Huh forms with accessibility
✅ Excellent
100% of forms use WithAccessible(IsAccessibleMode())
Non-TTY fallback for prompts
✅ Good
All interactive components check TTY before running
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
-
Overview
This analysis covers all Go source files in
pkg/(excluding tests) for console output patterns, Lipgloss styling, and Huh form usage. The codebase shows a mature, well-structured approach to terminal output with a dedicatedpkg/consolepackage that centralizes formatting. The overall quality is high, with several specific improvement opportunities identified.Summary Statistics
fmt.Fprintln/Fprintf(total)fmt.Fprintln(os.Stderr, ...)callsconsole.Format*usageslipgloss.*usageshuh.*usagespkg/cli/WithTheme+WithAccessible✅ What's Working Well
Lipgloss — Robust Styling Infrastructure
pkg/styles/theme.godefines every semantic color with both light/dark variants viacompat.AdaptiveColor, automatically adapting to terminal background. Example:ColorError = compat.AdaptiveColor{Light: "#D73737", Dark: "#FF5555"}.applyStyle()inpkg/console/console.goguards all styling behindisTTY(), preventing ANSI escape codes from leaking into pipes/redirects.styles.Error,styles.Success,styles.Warning,styles.Info,styles.FilePathetc. encourage consistent usage.*_wasm.gofiles — clean build-tag separation.console.RenderTableuseslipgloss/tablefor structured data, abstracted behind aTableConfigstruct.console.RenderStructprovides reflection-based rendering withconsole:"header:"andconsole:"title:"tags — a standout feature.Huh — Consistent Interactive Forms
huh.NewFormcalls inpkg/cli/correctly chain.WithTheme(styles.HuhTheme).WithAccessible(console.IsAccessibleMode()).IsAccessibleMode()checksACCESSIBLE,NO_COLOR, andTERM=dumbenv vars — comprehensive.pkg/console/input.go,list.go, andconfirm.goall checktty.IsStderrTerminal()before launching interactive prompts and fall back gracefully.PromptSecretInputvalidates non-empty input with a proper error message.styles.HuhThemeprovides branded styling, keeping forms visually consistent with the rest of the CLI.1. TTY Stream Inconsistency in
pkg/console/console.goThe module-level
isTTY()helper checks stdout, but all format functions (FormatSuccessMessage,FormatInfoMessage, etc.) are used withos.Stderr. Lines 344–398 calltty.IsStderrTerminal()directly, creating a split:Recommendation: Rename
isTTY()toisStdoutTTY()and introduceisStderrTTY(), or reconsider whetherapplyStyle(used on stderr-bound output) should checktty.IsStderrTerminal()instead.2. Unformatted Messages in User-Facing Code
Several
pkg/cli/files write plain strings directly to stderr instead of using console formatters. These messages lose color, icon prefixes, and consistent styling:Files with unformatted stderr messages (click to expand)
pkg/cli/preconditions.go(lines 26–142) — All precondition guidance messages:pkg/cli/add_interactive_orchestrator.go(lines 233–331) — Post-wizard summary:pkg/cli/add_interactive_git.go(lines 59–189) — merge/secret instructions:pkg/cli/add_interactive_workflow.go(lines 63–139) — status messages during wizard:pkg/cli/fix_command.go(lines 248–249) — hint after fix:3. Direct Lipgloss Usage in
pkg/cli/compile_schedule_calendar.gointensityStyle()createslipgloss.NewStyle()values inline usingstyles.Color*constants, which is fine. However the table rows are manually built with astrings.Builder, and separators/headers are written withfmt.Fprintln(os.Stderr, styles.TableHeader.Render(header)). This bypasses theconsole.RenderTableabstraction.Recommendation: For complex calendar-style output that doesn't map to simple tables, the current approach is acceptable. Consider extracting a
console.FormatCalendarhelper to keep CLI command files free of direct Lipgloss calls.4. Markdown Report to Stdout in
audit_cross_run_render.goLines 29–50 write raw Markdown headings and pipe-separated tables directly to stdout:
This is intentional for machine-readable output, but the hardcoded
# h1heading violates the style guide (which reserves h1 for titles). If this output is meant for human reading in a terminal, consider usingconsole.RenderStructwith struct tags for the table sections, or at minimum downgrade headers to###.📋 Prioritized Recommendations
pkg/console/console.goisTTY()checks stdout while format functions output to stderrpkg/cli/preconditions.gofmt.Fprintln(os.Stderr, ...)strings withconsole.FormatInfoMessage/FormatWarningMessagepkg/cli/add_interactive_orchestrator.goconsole.FormatSectionHeader/FormatWarningMessagepkg/cli/add_interactive_git.goFormatInfoMessagepkg/cli/add_interactive_workflow.goFormatProgressMessagepkg/cli/fix_command.goFormatCommandMessagepkg/cli/audit_cross_run_render.go💡 Charmbracelet Ecosystem Best Practices — Compliance Summary
pkg/styleshave both variantsapplyStyle()guards all Lipgloss callsconsole.Format*Messagefunctions used throughoutWithTheme(styles.HuhTheme)WithAccessible(IsAccessibleMode())IsAccessibleMode()coversACCESSIBLE,NO_COLOR,TERM=dumbShowInteractiveListfalls back to numbered text listisTTY()checks stdout; stderr-bound styles check stderr directlypkg/cli/files bypass formatters for user-facing stringsReferences:
Beta Was this translation helpful? Give feedback.
All reactions