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
Scope: All non-test .go files under pkg/ · 957 source files scanned Libraries detected:charm.land/lipgloss/v2, charm.land/huh/v2, charm.land/bubbles/v2/spinner, charm.land/bubbles/v2/progress
Summary
The codebase has a mature, well-structured console layer. The pkg/styles/ + pkg/console/ pairing is exemplary: adaptive colors, TTY-gated styling, accessibility support, and clean Format*/Render* naming conventions are all in place. Interactive forms consistently apply the custom Huh theme and accessibility mode. However, a handful of interactive flow files bypass console formatters and use raw fmt.Fprintln for plain-text messages and hardcoded separator characters.
This pattern is used consistently throughout all Format* and Render* functions. Direct tty.IsStderrTerminal() calls in CLI files are also used correctly for conditional rendering.
Layout and Table Usage — ✅ Good, with one anti-pattern
RenderTable() correctly uses lipgloss/table with per-row StyleFunc, zebra-striping, and rounded borders
RenderComposedSections() uses lipgloss.JoinVertical() in TTY mode, falls back to plain loops in non-TTY
RenderTitleBox() uses double border + center alignment; RenderErrorBox() uses rounded border with error color; RenderInfoSection() uses left-border emphasis — all with non-TTY fallbacks
Anti-pattern found:trial_confirmation.go:221 wraps a separator line inside console.FormatInfoMessage():
// ❌ Current — raw separators not adaptive to TTY width or themefmt.Fprintln(os.Stderr, "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━")
fmt.Fprintln(os.Stderr, console.FormatInfoMessage("═══════════════════════════════════════")) // wraps separator in info prefix// ✅ Recommended — use the existing layout primitivesections:=console.RenderTitleBox("🎉 Addition complete!", 40)
console.RenderComposedSections(sections)
RenderTitleBox already handles TTY vs plain fallback correctly.
🔴 Medium — Unformatted instructional text in interactive flows
// ❌ Current — plain text without formattingfmt.Fprintln(os.Stderr, "Please add the secret manually:")
fmt.Fprintln(os.Stderr, " 1. Go to your repository Settings → Secrets and variables → Actions")
fmt.Fprintln(os.Stderr, "Please merge the PR manually from the GitHub web interface.")
// ✅ Recommendedfmt.Fprintln(os.Stderr, console.FormatWarningMessage("Please add the secret manually:"))
fmt.Fprintln(os.Stderr, console.FormatListItem("Go to your repository Settings → Secrets and variables → Actions"))
fmt.Fprintln(os.Stderr, console.FormatWarningMessage("Please merge the PR manually from the GitHub web interface."))
🟡 Low — Manual bullet points instead of FormatListItem
pkg/cli/trial_confirmation.go is the gold standard for interactive output — it uses RenderTitleBox, RenderInfoSection, and RenderComposedSections correctly, all with proper TTY/plain fallbacks. New interactive flows should follow this file's pattern.
pkg/cli/deps_security.go and pkg/cli/mcp_inspect_mcp.go demonstrate correct console.RenderErrorBox() usage for error states.
Next Actions
Replace hardcoded ━━━/═══ separators in add_interactive_orchestrator.go, deps_report.go, trial_confirmation.go, and actionlint.go with console.RenderTitleBox() / console.RenderComposedSections() calls
Wrap plain instructional text in add_interactive_*.go files with appropriate console.Format*Message() helpers
Replace manual bullet points with console.FormatListItem() in add_interactive_orchestrator.go
Convert debug fmt.Fprintf calls in add_interactive_workflow.go to use the logger package (gated by DEBUG env var)
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.
-
Terminal Stylist Report — Console Output Analysis
Scope: All non-test
.gofiles underpkg/· 957 source files scannedLibraries detected:
charm.land/lipgloss/v2,charm.land/huh/v2,charm.land/bubbles/v2/spinner,charm.land/bubbles/v2/progressSummary
The codebase has a mature, well-structured console layer. The
pkg/styles/+pkg/console/pairing is exemplary: adaptive colors, TTY-gated styling, accessibility support, and cleanFormat*/Render*naming conventions are all in place. Interactive forms consistently apply the custom Huh theme and accessibility mode. However, a handful of interactive flow files bypass console formatters and use rawfmt.Fprintlnfor plain-text messages and hardcoded separator characters.console.Format*/console.Render*fmt.Fprintln(os.Stderr, console.Format*...)call sitesfmt.Fprintln(os.Stderr, ...)without console wrapperhuh.NewForm(...).WithTheme(...))pkg/styles/+pkg/console/Lipgloss Analysis
Adaptive Color System — ✅ Excellent
pkg/styles/theme.goimplements a customadaptiveColortype that satisfiescolor.Colorand selects light/dark variants at runtime:init()vialipgloss.HasDarkBackground— safely skipped on Windows (ConPTY crash prevention)Error,Warning,Success,Info, etc.) use these adaptive colorsTTY Detection — ✅ Correct
The
applyStyle()helper inpkg/console/console.gogates styling onisTTY():This pattern is used consistently throughout all
Format*andRender*functions. Directtty.IsStderrTerminal()calls in CLI files are also used correctly for conditional rendering.Layout and Table Usage — ✅ Good, with one anti-pattern
RenderTable()correctly useslipgloss/tablewith per-rowStyleFunc, zebra-striping, and rounded bordersRenderComposedSections()useslipgloss.JoinVertical()in TTY mode, falls back to plain loops in non-TTYRenderTitleBox()uses double border + center alignment;RenderErrorBox()uses rounded border with error color;RenderInfoSection()uses left-border emphasis — all with non-TTY fallbackstrial_confirmation.go:221wraps a separator line insideconsole.FormatInfoMessage():FormatInfoMessageadds a cyaniprefix — semantically wrong for a separator. Useconsole.RenderTitleBox()instead.Huh Analysis
Theme Integration — ✅ Consistent
pkg/styles/huh_theme.gomaps the package's Dracula-inspired palette onto every Huh style token usinglipgloss.LightDark(isDark):HiddenBorder()so inactive fields recede visuallyAll 14 form-using files consistently apply
.WithTheme(styles.HuhTheme).WithAccessible(console.IsAccessibleMode()).Accessibility — ✅ Comprehensive
console.IsAccessibleMode()checks three signals:ACCESSIBLEenv var (any value)TERM=dumbNO_COLORenv varAll Huh forms pass
IsAccessibleMode()toWithAccessible(). The spinner additionally checksACCESSIBLEdirectly and disables animation entirely.Non-TTY Fallbacks — ✅ Present in all interactive components
ConfirmAction()→ numbered text list with y/n promptShowInteractiveList()→ numbered text list with integer selectionPromptSecretInput()→ returns error (secret masking not possible outside TTY)NewSpinner()→ disabled entirely (no-op); messages still printed onStopWithMessage()ProgressBar.Update()→ returns text percentage strings (50% (512MB/1024MB))Spinner Bubble Tea Integration — ✅ Correct
The spinner uses
tea.WithInput(nil)to avoid consuming stdin that subsequent Huh forms need:Thread-safe lifecycle (mutex + WaitGroup) prevents double-start and deadlock on early stop.
Issues and Recommendations
🔴 Medium — Hardcoded separators bypassing layout primitives
Files:
add_interactive_orchestrator.go:326,328,deps_report.go:105,107,actionlint.go:121,123,168RenderTitleBoxalready handles TTY vs plain fallback correctly.🔴 Medium — Unformatted instructional text in interactive flows
Files:
add_interactive_git.go:60,124,189-191,add_interactive_auth.go:28-31,add_interactive_engine.go:179,add_interactive_orchestrator.go:334,338,343,add_interactive_secrets.go:44🟡 Low — Manual bullet points instead of
FormatListItemFiles:
add_interactive_orchestrator.go:247,add_interactive_secrets.go:44🟡 Low — Debug-style outputs leaking into
add_interactive_workflow.goLines: 181, 187, 193-194, 203, 209 — plain
fmt.Fprintf(os.Stderr, "Running: gh %s\n", ...),"gh workflow list output: ...","Looking for workflow...","Workflow ... found/NOT found in workflow list".These appear to be development diagnostics that were never converted to use the existing logger (which respects
DEBUG/DEBUG_COLORSenv vars):Exemplary Patterns to Follow
pkg/cli/trial_confirmation.gois the gold standard for interactive output — it usesRenderTitleBox,RenderInfoSection, andRenderComposedSectionscorrectly, all with proper TTY/plain fallbacks. New interactive flows should follow this file's pattern.pkg/cli/deps_security.goandpkg/cli/mcp_inspect_mcp.godemonstrate correctconsole.RenderErrorBox()usage for error states.Next Actions
━━━/═══separators inadd_interactive_orchestrator.go,deps_report.go,trial_confirmation.go, andactionlint.gowithconsole.RenderTitleBox()/console.RenderComposedSections()callsadd_interactive_*.gofiles with appropriateconsole.Format*Message()helpersconsole.FormatListItem()inadd_interactive_orchestrator.gofmt.Fprintfcalls inadd_interactive_workflow.goto use theloggerpackage (gated byDEBUGenv var)References: §28161453108
Beta Was this translation helpful? Give feedback.
All reactions