When using certain modern terminals, interactive prompts that require text input (e.g., entering a branch name for gh stack add, setting a prefix for gh stack init) cause the terminal to scroll unexpectedly, pushing all previous output to the top of the screen. The prompt line jumps and hides the user's history.
Root Cause
We currently use github.com/cli/go-gh/v2/pkg/prompter, which wraps AlecAivazis/survey/v2. To detect terminal dimensions, survey emits the ANSI escape sequence \x1b[999;999f (HVP — Horizontal Vertical Position: move cursor to row 999, column 999) and then reads back the actual cursor position. Traditional xterm-compatible terminals clamp this to the viewport boundary — a 24×80 terminal moves the cursor to row 24, column 80 with no side effects.
However, this behavior is not universal. Terminals with non-standard renderers (custom terminal frameworks) may interpret the sequence literally, extending the scrollback buffer or scrolling the viewport down hundreds of lines instead of clamping. The ANSI standard is ambiguous on what should happen when a position beyond the screen boundary is requested, so terminal behavior varies.
Since survey/v2 was archived in April 2024, no fix is possible upstream. The go-gh/v2/pkg/prompter package has not been updated to use an alternative.
Solution
Created a new internal/prompter package that replaces go-gh/v2/pkg/prompter with prompt implementations that avoid the problematic ANSI escape sequences:
Select — Uses charm.land/huh/v2 (the same library the GitHub CLI uses in its own internal/prompter/huh_prompter.go, merged in cli/cli#12859). The cursor.Size() call was only triggered by survey's Select/MultiSelect prompts, so huh eliminates the problematic escape sequences entirely.
Input — Also uses charm.land/huh/v2 with Inline(true) for single-line rendering that matches the old survey look. survey's Input prompt also triggered cursor manipulation sequences that could cause issues in non-standard terminals.
Confirm — Uses a simple bufio.Reader-based line prompt. Survey's Confirm prompt did not use cursor.Size() or other problematic escape sequences (it just reads y/n from stdin), so a plain stdin reader preserves the exact same ? Question (Y/n) format without needing any TUI library.
Visual Style
A custom surveyTheme ensures prompts visually match the old survey/v2 style:
Prompt Type
Before (survey/v2)
After
Input
? Enter a name for the new branch bar
? Enter a name for the new branch bar
Confirm
? Enable git rerere? (Y/n)
? Enable git rerere? (Y/n)
Select
? Which stack? + > option list
? Which stack? + > option list
No box borders (removed huh's default ┃ left border)
Cyan ? prefix on all prompts
Inline layout for Input (title + cursor on the same line)
(Y/n) / (y/N) hint format for Confirm
Cyan > selector for Select options
No help text footer ("enter submit")
Interrupt Handling
On Ctrl+C, huh returns huh.ErrUserAborted, which is mapped to a local prompter.ErrInterrupt sentinel error
After huh exits, printResult() re-prints the prompt line so it stays visible in terminal history (huh's bubbletea renderer clears its rendering area on exit)
For Select prompts, residual option lines are cleared with ANSI cursor movement before re-printing the clean result
errInterrupt is now handled in Execute() to exit silently (previously it fell through and printed "interrupt" to stderr)
Dependency Changes
Added
charm.land/huh/v2 v2.0.3 — same version used by cli/cli
charm.land/lipgloss/v2, charm.land/bubbles/v2, charm.land/bubbletea/v2 — transitive deps of huh/v2
Removed
github.com/AlecAivazis/survey/v2 — archived, source of the problematic escape sequences
github.com/kballard/go-shellquote — was a transitive dep of survey
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
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.
Problem
When using certain modern terminals, interactive prompts that require text input (e.g., entering a branch name for gh stack add, setting a prefix for gh stack init) cause the terminal to scroll unexpectedly, pushing all previous output to the top of the screen. The prompt line jumps and hides the user's history.
Root Cause
We currently use github.com/cli/go-gh/v2/pkg/prompter, which wraps AlecAivazis/survey/v2. To detect terminal dimensions, survey emits the ANSI escape sequence \x1b[999;999f (HVP — Horizontal Vertical Position: move cursor to row 999, column 999) and then reads back the actual cursor position. Traditional xterm-compatible terminals clamp this to the viewport boundary — a 24×80 terminal moves the cursor to row 24, column 80 with no side effects.
However, this behavior is not universal. Terminals with non-standard renderers (custom terminal frameworks) may interpret the sequence literally, extending the scrollback buffer or scrolling the viewport down hundreds of lines instead of clamping. The ANSI standard is ambiguous on what should happen when a position beyond the screen boundary is requested, so terminal behavior varies.
Since survey/v2 was archived in April 2024, no fix is possible upstream. The go-gh/v2/pkg/prompter package has not been updated to use an alternative.
Solution
Created a new internal/prompter package that replaces go-gh/v2/pkg/prompter with prompt implementations that avoid the problematic ANSI escape sequences:
Select — Uses charm.land/huh/v2 (the same library the GitHub CLI uses in its own internal/prompter/huh_prompter.go, merged in cli/cli#12859). The cursor.Size() call was only triggered by survey's Select/MultiSelect prompts, so huh eliminates the problematic escape sequences entirely.
Input — Also uses charm.land/huh/v2 with Inline(true) for single-line rendering that matches the old survey look. survey's Input prompt also triggered cursor manipulation sequences that could cause issues in non-standard terminals.
Confirm — Uses a simple bufio.Reader-based line prompt. Survey's Confirm prompt did not use cursor.Size() or other problematic escape sequences (it just reads y/n from stdin), so a plain stdin reader preserves the exact same ? Question (Y/n) format without needing any TUI library.
Visual Style
A custom surveyTheme ensures prompts visually match the old survey/v2 style:
Interrupt Handling
Dependency Changes
Added
Removed