Skip to content

[go-fan] Go Module Review: charm.land/huh/v2Β #44690

Description

@github-actions

🐹 Go Fan Report: huh (charm.land/huh/v2)

Module Overview

huh is Charm's library for building interactive terminal forms and prompts β€” inputs, selects, multi-selects, confirms, text areas, notes, and file pickers β€” with theming, validation, keymaps, and an accessible (non-decorated) mode. In gh-aw it powers every interactive CLI prompt: gh aw add, gh aw run, engine/schedule selection, and secret entry.

Current Usage in gh-aw

  • Files: 15 non-test .go files import charm.land/huh/v2
  • Version: v2.0.3 (latest release; upstream pushed 2026-07-06 but only dep-bump/chore commits since v2.0.3 β€” no new API to adopt)
  • Key APIs Used: NewForm, NewGroup, NewInput (+EchoModePassword, Validate), NewSelect, NewMultiSelect, NewText, NewConfirm, NewOption, ThemeBase/ThemeFunc, WithTheme, WithAccessible, Run, RunWithContext

The integration is genuinely well-structured, with two clean abstraction layers:

  • pkg/styles/huh_theme.go β€” a huh.ThemeFunc mapping the Dracula palette via huh.ThemeBase + lipgloss LightDark.
  • pkg/console/prompt_form.go β€” NewForm/NewInputForm/NewSelectForm/NewConfirmForm wrappers that centralize theme + WithAccessible(...).

Research Findings

i Verified against form.go @ tag v2.0.3. huh exposes sentinel errors specifically so callers can distinguish outcomes:

var ErrUserAborted = errors.New("user aborted")   // Ctrl+C / Esc before submit
var ErrTimeout = errors.New("timeout")
var ErrTimeoutUnsupported = errors.New("timeout is not supported in accessible mode")

Run/RunWithContext return ErrUserAborted when the user cancels.

Recent Updates

No functional changes since v2.0.3 (2026-03-10) β€” recent activity is dependency bumps only. The current pin is up to date.

Best Practices

  • Distinguish deliberate cancellation (ErrUserAborted) from real errors.
  • Keep theme + accessible-mode application centralized (gh-aw already does this well).
  • Thread context into prompts so they're cancellable.

Improvement Opportunities

πŸƒ Quick Wins

  • Handle huh.ErrUserAborted explicitly β€” the one concrete gap. No call site anywhere checks errors.Is(err, huh.ErrUserAborted). A deliberate Ctrl+C during secret entry currently surfaces as a hard failure, e.g. failed to get Copilot token: user aborted (pkg/cli/engine_secrets.go:324/368/417). Add a console.IsCancelled(err) helper and let callers return a clean cancellation (friendly Cancelled. message, exit code 130) instead of wrapping it as an error.
  • pkg/cli/run_interactive.go:351 returns false on any Run error, collapsing abort and genuine failures into one path β€” distinguishing them would sharpen logs/behavior.

✨ Feature Opportunities

  • WithTimeout on secret/token prompts to avoid hanging indefinitely in semi-interactive CI, paired with errors.Is(err, huh.ErrTimeout). (Note: timeouts are unsupported in accessible mode β€” guard with ErrTimeoutUnsupported.)

πŸ“ Best Practice Alignment

  • Context consistency β€” pkg/console confirm/input/list use the context-less form.Run(), while pkg/cli/* uses form.RunWithContext(ctx). The console prompts therefore can't be cancelled via context. Consider threading ctx through the console helpers (or adding *WithContext variants) for uniform, cancellable prompts.

πŸ”§ General Improvements

  • Keep new interactive surfaces going through the NewForm wrappers rather than calling huh.NewForm(...).WithTheme(...) directly, so theming/accessibility stay in one place. (No violations found today β€” noting to preserve the pattern.)

Recommendations

  1. (High, low-effort) Add console.IsCancelled(err) around huh.ErrUserAborted and adopt it at the secret-entry call sites so cancellation is a graceful exit, not a failure message.
  2. (Medium) Thread context through pkg/console confirm/input/list for cancellable, consistent prompts.
  3. (Low/optional) Add WithTimeout + ErrTimeout handling on token prompts for CI robustness.

Next Steps


Generated by Go Fan
Module summary saved to: scratchpad/mods/charmbracelet-huh.md

Generated by 🐹 Go Fan Β· 193.6 AIC Β· βŒ– 13.1 AIC Β· ⊞ 7.3K Β· β—·

  • expires on Jul 11, 2026, 1:02 AM UTC-08:00

Metadata

Metadata

Labels

Type

No type

Fields

No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions