feat(pair): huh forms for prompts (TTY-gated, legacy fallback)#21
Merged
Conversation
Final phase of the Charmbracelet polish sprint. Three pair-flow
prompts now render through huh in real terminals; the legacy
bufio implementations are preserved verbatim and still fire when
stdout is not a TTY.
promptForServerURL -> huh.NewSelect + huh.NewInput on "Other"
promptForDefaultNamespace -> huh.NewSelect with explicit skip option
confirmFileMerge (F24) -> huh.NewConfirm("Yes, merge" / "No, skip")
Each new wrapper:
if !isTTY(out) { return *Legacy(in, out, ...) }
// ...huh form...
isTTY (added in render.go for Phase 3) returns false for any writer
that isn't a *os.File — including the *bytes.Buffer and io.Discard
that pair_flow_test.go uses. Result: the entire existing test suite
(TestPair_F24_*, TestPair_PromptsForServerWhenConfigEmpty,
TestPair_NamespacePromptSetsDefault, etc.) exercises the legacy path
and passes unchanged.
The legacy functions are intentionally not deleted. Three reasons:
- Tests + scripted use need them; gating preserves both UX modes.
- Removing them would mean either rewriting the tests against a pty
harness (overkill) or losing test coverage entirely (worse).
- They're tiny (~25 lines each) and have stable behavior.
Closes the original 5-phase plan. Phases 0-3 already on main; this
is Phase 4. Phase 5 is the v0.1.0 tag — separate step, owned by Brad
per AGENTS.md early-weeks rule.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Final phase of the Charmbracelet polish sprint (Phase 4 of `~/.claude/plans/peppy-forging-dahl.md`). Three pair-flow prompts now render through `huh` in real terminals; the legacy bufio implementations are preserved verbatim and still fire when stdout isn't a TTY.
Gating logic
Each new wrapper:
```go
if !isTTY(out) {
return *Legacy(in, out, ...)
}
// ...huh form...
```
`isTTY` (added in `render.go` for Phase 3) returns false for any writer that isn't a `*os.File` — including the `*bytes.Buffer` and `io.Discard` that `pair_flow_test.go` uses. Result: every existing pair test exercises the legacy path and passes unchanged.
Why keep the legacy functions
Three reasons, all carry-forward from CLAUDE.md:
Verification
` in a real terminal will now show huh's arrow-key picker for server URL + namespace + the F24 confirm — same flow, prettier UI.` falls through to the legacy bufio path (provable with `script`/`tee`/etc.).Sprint complete
This closes the original 5-phase plan:
Plus side-quests landed along the way: CI hardening (#11), branch protection ruleset, Blacksmith migration (#16), 4 dependabot bumps (#12-15), API key preflight (#19), styled install.sh (#20).
Test plan
` shows the huh-styled flow.🤖 Generated with Claude Code
Need help on this PR? Tag
@codesmithwith what you need.