Conversation
Adds libs/cmdio/cmdiotest, an external test package that drives cmdio.Select / SelectOrdered / Secret / RunPrompt through a real pty and snapshots the rendered screen via vt10x. 26 tests cover the prompt matrix as it behaves on origin/main today (still promptui under the hood): basic navigation, scrolling, filter typing and no-match, vim-key fallthrough, Esc/Tab inertness, Ctrl+C with and without filter text, single-item rendering, long descriptions, cursor editing keys (Home/End/Ctrl+W/Ctrl+U), 20-item filter scroll, UTF-8 input, and the empty-list rejection path. Lives on its own branch as a one-shot test capsule: never merged to main, copied into the bubbletea migration branch to verify each widget swap leaves the goldens byte-identical. Once promptui is gone the harness is rewritten on charmbracelet/x/exp/teatest, which lets us drop creack/pty and x/term entirely. Adds three test-only deps with license annotations: - creack/pty (MIT) - hinshun/vt10x (MIT) - golang.org/x/term (BSD-3-Clause) Co-authored-by: Isaac
Adds TestSelectBaseline_SelectedTemplate, the only golden test that exercises the post-submit render path of cmdio.RunSelect. The existing select baseline tests all go through cmdio.Select / cmdio.SelectOrdered, which set HideSelected:true and skip the Selected template branch. Real callers (cmd/auth/profile_picker.go, libs/databrickscfg/profile/select.go, libs/databrickscfg/cfgpickers/clusters.go) all set Selected:; without this test, breaking the post-submit render or the Selected template goes undetected. Co-authored-by: Isaac
…Delete-as-EOF separately The Delete key (\x1b[3~) maps to chzyer/readline's CharDelete (=4), the same rune as Ctrl+D. CharDelete's handler treats a non-empty buffer as forward-delete and an empty buffer as EOF. Promptui's listener resets readline's buffer to empty after every keystroke (cur is the source of truth), so from readline's perspective the buffer is always empty when Delete arrives — every Delete press takes the EOF path and exits the prompt. The Delete step in TestPromptBaseline_CursorEditing was unintentionally pinning post-exit screen residue, which presented as a load-dependent flake (vt10x snapshot timing relative to exit cleanup). Replace the Delete step with Backspace, which goes through promptui's Cursor.Listen and works correctly. The Ctrl+W and Ctrl+U steps stay — they're known no-ops in promptui (no case in Cursor.Listen), and the post-Backspace goldens after them being identical pins that. Add TestPromptBaseline_DeleteKeyExits to document the Delete-as-EOF behavior so any future change (e.g. a promptui or readline upgrade that splits the two keys) is intentional. Co-authored-by: Isaac
vt10x's Write decodes the input as UTF-8 and treats partial-rune bytes at the tail as invalid: it logs each leading byte of an incomplete sequence as "invalid utf8 sequence" and reports written-1 back. Since that count doesn't capture how many bytes the parser actually advanced past, the caller can't reconstruct the dropped bytes for the next call. When a pty read happens to split a multi-byte rune (✔, █, etc.) under load, the lost bytes corrupt vt10x's downstream parser state and the escape sequences that follow can land on the wrong line — producing a screen that diverges from the real byte stream and a flaky golden. Fix the pump to detect a partial UTF-8 sequence at the end of each read using utf8.RuneStart / utf8.FullRune, hold those bytes back, and prepend them to the next read. Bytes from any genuinely invalid sequence in the middle are still passed through; vt10x logs and skips them (which doesn't cause divergence). Co-authored-by: Isaac
Adds two tests that pin the post-submit screen for cmdio.RunPrompt: - HideEntered=false (the default): the success template is shown with the entered value (e.g. "Workspace name: hello"). - HideEntered=true: the prompt frame is cleared, leaving no trace of the entered value. This is the path used by cmdio.Secret. Existing prompt and secret tests verified the typing UX and the returned value but never snapshotted the post-Enter state, so neither HideEntered branch was pinned. Co-authored-by: Isaac
Adds TestPromptBaseline_AltKeyNoop. Alt+f is the readline binding for "move forward by word", which chzyer/readline does process — it calls o.buf.MoveToNextWord and fires the listener with key=MetaForward. But promptui's Cursor.Listen has no case for MetaForward and the listener wrapper returns (nil, 0, true), which makes readline overwrite its buffer with empty. Net effect on the user-visible state (promptui's own cur): nothing changes. The same shape applies to Alt+b, Alt+d, Alt+Backspace, and other modified keys promptui doesn't explicitly handle. Pinning Alt+f covers the class — if a future promptui or readline change starts letting these slip through (insert, move cursor, etc.), the goldens diverge. Co-authored-by: Isaac
Adds TestPromptBaseline_CtrlFCtrlB and the missing KeyCtrlB / KeyCtrlF constants in termtest. chzyer/readline maps Ctrl+F to CharForward and Ctrl+B to CharBackward — the same runes the right and left arrow keys decode to — and promptui's Cursor.Listen dispatches both via its KeyForward / KeyBackward cases. So the emacs-style bindings are de-facto aliases for the arrow keys; this test pins that equivalence so a future implementation that drops Ctrl+F / Ctrl+B handling fails the goldens. Co-authored-by: Isaac
Adds two select baselines and the missing KeyCtrlN / KeyCtrlP constants in termtest: - TestSelectBaseline_CtrlNCtrlP: small list, asserts that Ctrl+N and Ctrl+P move the highlighted item down and up by one — the same as the down and up arrow keys (promptui exposes both as readline.CharNext / readline.CharPrev). - TestSelectBaseline_CtrlFCtrlB: 12-item list against promptui's default 5-row window, asserts that Ctrl+F and Ctrl+B page the selection (skip ~5 items) rather than moving by one. Promptui maps these to KeyForward / KeyBackward, distinct from KeyNext / KeyPrev, and the select widget treats them as page-down / page-up. These pin behavior the existing baselines didn't cover (DownEnter and Scroll only exercise the arrow keys, never the emacs-style aliases). Co-authored-by: Isaac
Adds three Select baselines that close gaps surfaced by an audit of promptui's select.go key handling: - TestSelectBaseline_VimNavOutsideSearch: pins j/k/h/l navigation when StartInSearchMode=false. The existing TestSelectBaseline_VimKeys runs with search mode on, so its goldens record letters going into the filter — the actual nav branch (key == 'j' && !searchMode etc.) was never pinned. Real callers that hit this branch with small lists: cmd/auth/resolve.go, cmd/auth/profile_picker.go. - TestSelectBaseline_SlashEntersSearch: pins the "/" toggle into search mode. cmdio.SelectOrdered sets StartInSearchMode=true so the toggle path was unreachable from the existing wrappers. Same callers as above set StartInSearchMode based on len(items) > 5, so for small lists "/" is the only way to filter. - TestSelectBaseline_ArrowPageNav: pins that Left/Right arrows page through the list, mirroring TestSelectBaseline_CtrlFCtrlB but via the arrow keys. Promptui maps both pairs to KeyForward/KeyBackward which the select widget treats as page-down/page-up. Co-authored-by: Isaac
Adds TestSelectBaseline_DefaultTemplates, mirroring the data shape and
options of the `databricks selftest tui run-select` plain mode
(cmd/selftest/tui/select.go: runSelectPlain). It calls cmdio.RunSelect
with only Label and Items set, so promptui falls back to its built-in
defaults, which render the whole item via {{.}} — for cmdio.Tuple that
prints as "{Name Id}".
The goldens make that ugly default visible: a future change to the
defaults — or an accidental loss of a custom template at a real call
site — produces a diff. The post-Enter golden (default Selected
template "✔ {Name Id}") closes the corresponding gap on the exit
render path.
Co-authored-by: Isaac
…t and select Ctrl+H sends BS (0x08) and Ctrl+J sends LF (0x0a); chzyer/readline treats them as aliases for Backspace (DEL, 0x7f) and Enter (CR, 0x0d). RunPrompt honours both aliases in full. Select honours Ctrl+H inside the search buffer but diverges on Ctrl+J: it ends the prompt cleanly, yet resets the highlighted item to the first one, so Down + Ctrl+J returns "a" where Down + Enter (TestSelectBaseline_DownEnter) returns "b". The select_baseline_ctrl_j baseline locks that quirk in. Co-authored-by: Isaac
The previous assertion pinned promptui's bug where Ctrl+J on a non-first item resets the highlight to the first item before returning, locking in the broken "a" value. A future Select implementation should be free to fix that (mapping Ctrl+J to Enter), so the test now only requires that submission succeeds and the returned id is one of the valid items. Co-authored-by: Isaac
PromptOptions.Default is rendered like a placeholder (cursor sits at column 0 with the default text to its right), but the readline buffer is actually pre-filled. The dismissal trigger is "first typed rune" — if the user instead presses Right or Ctrl+F first, the cursor moves *into* the pre-filled default and subsequent typing inserts there. So Right×2 + Ctrl+F + "e" on default "us-west-2" returns "us-ewest-2", not "e". Adds DefaultCursorMovementEntersBuffer to pin that path and DefaultEnterAccepts to pin that bare Enter returns the default verbatim. Co-authored-by: Isaac
- gocritic (24): replace context.Background() with t.Context() in test files - gofmt (19): fix import ordering after the context replacement - forbidigo (1): annotate os.Getenv in termtest.go (test-only UPDATE flag, no ctx available in the helper) Co-authored-by: Isaac
Adds five baselines for the first-key handling of PromptOptions.Default, covering the cases not exercised by the existing DefaultNoEdit and DefaultCursorMovementEntersBuffer tests: - Backspace/Ctrl+H erase the entire default (promptui's eraseDefault path), leaving an empty buffer. - Left/Ctrl+B is visually inert at column 0 and does not opt into editing the default — a subsequent printable rune still replaces the default rather than inserting before it. - After Right has loaded the default into the editable buffer, Backspace deletes one character within it (Right + Backspace on "us-west-2" yields "s-west-2"), not the whole default. Co-authored-by: Isaac
No production caller sets it. databricks auth login renders the default in the label and substitutes it manually on empty input (PR #3252), and no other prompt uses it. Also drop the --default flag from selftest tui prompt, which only existed to exercise the field. Co-authored-by: Isaac
The merged commit removes the Default field from cmdio.PromptOptions (no production caller sets it; databricks auth login renders the default in the label and substitutes it manually). The cmdiotest baselines that pinned Default's promptui behavior are no longer applicable, so this merge also drops: - prompt_default_no_edit_baseline_test.go - prompt_default_placeholder_baseline_test.go - prompt_default_first_key_baseline_test.go and their associated testdata directories. Co-authored-by: Isaac
pietern
added a commit
that referenced
this pull request
May 11, 2026
Drops the manifoldco/promptui (and transitive chzyer/readline) dependency in favor of hand-rolled bubbletea models that reproduce promptui's rendering and key handling. RunPrompt and Secret share a single-line editor that pins the cursor-block visuals, mask, validate (with inline "✗" glyph and a red ">> <err>" line surfaced after a failed Enter), HideEntered post-submit clearing, Ctrl+B/F as left/right, Ctrl+H as backspace, Ctrl+J as Enter, and Delete/Ctrl+D as EOF. RunSelect, Select, and SelectOrdered share a templated list with viewport scroll and ↑/↓ gutters, a search filter with vim-style nav and "/" toggle, Ctrl+P/N as item-up/down, Ctrl+B/F (and the left/right arrows) as page-up/down, default Active / Inactive / Selected templates that match promptui's defaults, and an empty final frame when HideSelected is set. Both primitives refuse to draw on a non-interactive terminal so callers no longer have to gate on IsPromptSupported themselves; SelectOrdered drops its now-redundant guard. SelectOptions.Items is now validated at construction and normalized to []any so the render path doesn't reflect on every row. The behavior pinned above is verified against the cmdiotest pty- and vt10x-based baseline suite developed in #5231. That suite is kept on a separate branch — and not merged here — because it pulls in test-only dependencies (creack/pty, hinshun/vt10x, x/term) that we'd prefer not to land in the main module. Co-authored-by: Isaac
pietern
added a commit
that referenced
this pull request
May 11, 2026
Drops the manifoldco/promptui (and transitive chzyer/readline) dependency in favor of hand-rolled bubbletea models that reproduce promptui's rendering and key handling. RunPrompt and Secret share a single-line editor that pins the cursor-block visuals, mask, validate (with inline "✗" glyph and a red ">> <err>" line surfaced after a failed Enter), HideEntered post-submit clearing, Ctrl+B/F as left/right, Ctrl+H as backspace, Ctrl+J as Enter, and Delete/Ctrl+D as EOF. RunSelect, Select, and SelectOrdered share a templated list with viewport scroll and ↑/↓ gutters, a search filter with vim-style nav and "/" toggle, Ctrl+P/N as item-up/down, Ctrl+B/F (and the left/right arrows) as page-up/down, default Active / Inactive / Selected templates that match promptui's defaults, and an empty final frame when HideSelected is set. Both primitives refuse to draw on a non-interactive terminal so callers no longer have to gate on IsPromptSupported themselves; SelectOrdered drops its now-redundant guard. SelectOptions.Items is now validated at construction and normalized to []any so the render path doesn't reflect on every row. The behavior pinned above is verified against the cmdiotest pty- and vt10x-based baseline suite developed in #5231. That suite is kept on a separate branch — and not merged here — because it pulls in test-only dependencies (creack/pty, hinshun/vt10x, x/term) that we'd prefer not to land in the main module. Co-authored-by: Isaac
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.
Note
Reference branch only — not for merge. Parked on origin so the bubbletea-based prompt rewrite can pull individual tests as it lands matching behavior.
Summary
libs/cmdio/cmdiotest/pinning promptui's currentRunPrompt,RunSelect, andSecretbehavior (key handling, filter typing, navigation, validation, masking, templates).termtest/, so a future implementation can be diffed step-by-step, not just at submit.