Skip to content

feat(tui): number-key quick-select in choice dialogs - #136

Merged
kingsword09 merged 3 commits into
kingsword09:mainfrom
wesleymatosdev:feat/choice-dialog-number-shortcuts
Sep 9, 2026
Merged

feat(tui): number-key quick-select in choice dialogs#136
kingsword09 merged 3 commits into
kingsword09:mainfrom
wesleymatosdev:feat/choice-dialog-number-shortcuts

Conversation

@wesleymatosdev

Copy link
Copy Markdown
Contributor

Closes #135.

What

Choice dialogs (tool approvals, plan approval, questions) now support single-keystroke selection: pressing 19 selects and confirms the option at that position.

  • Dialogs with ≤9 options get 1. 9. number hints prefixed to labels plus an updated help line ("number selects"), so the shortcut is discoverable.
  • Opt out per-call with numberShortcuts: false.
  • Disabled while the filter is active (digits must keep working as filter input) and while content details are expanded.
  • Digits past the option count are a no-op (setSelectedIndex clamps to the last item, so the guard is explicit).
  • Up/Down + Enter flow is unchanged.

Why

Approval prompts interrupt flow constantly in tmux fleet workflows (multiple zcode sessions side by side). Up-Up-Enter per approval adds up; a single digit cuts the most common interaction ("Allow once") to one keystroke. Claude Code's permission prompts do the same thing — the interaction is proven.

Tests

New test/choice-dialog-number-shortcuts.test.ts (5 tests) driving the public choose() with a fake TUI:

  • 1 confirms the first option; 3 confirms the third
  • digits past the item count are a no-op
  • digits are filter input while a filter is active (no accidental confirm)
  • number hints appear by default and can be disabled

bun run typecheck clean; bun test test/choice-dialog*.test.ts 15/15 green. Remaining full-suite failures are pre-existing on clean main in this environment (launcher/runtime integration + SSE recovery tests — verified identical failure set with and without the change).

Pressing 1-9 in a choice dialog selects and confirms the option at that
position in one keystroke. Dialogs with <=9 options get '1. '-'9. ' label
hints and an updated help line so the shortcut is discoverable; callers can
opt out with numberShortcuts: false.

- Disabled while a filter is active (digits remain filter input) and while
  content is expanded.
- Digits past the option count are a no-op (setSelectedIndex clamps, so the
  guard is explicit).
- Existing Up/Down + Enter flow unchanged.

Closes kingsword09#135

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The default help text loses scroll discoverability when shortcuts are enabled, and the new “number hints” test does not currently assert the intended UI output/opt-out behavior.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds single-keystroke 19 quick-select (select + confirm) to the zcode TUI choice dialog, aimed at speeding up frequent approval prompts while preserving the existing Up/Down + Enter flow.

Changes:

  • Implement digit quick-select in ChoiceDialog.handleInput() with an opt-out numberShortcuts: false.
  • Prefix labels with 1. … hints (when applicable) and update the default help text to advertise “number selects”.
  • Add a new targeted test file for number shortcut behavior and adjust an existing help-text assertion.
File summaries
File Description
packages/zcode-tui/src/choice-dialog.ts Implements digit quick-select, label numbering hints, and help-text updates for choice dialogs.
test/choice-dialog-number-shortcuts.test.ts Adds tests intended to validate digit confirm, out-of-range digits, filter interaction, and numbering hints.
test/choice-dialog.test.ts Updates an assertion to accommodate the updated help text formatting/content.
Review details
  • Files reviewed: 3/3 changed files
  • Comments generated: 5
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/zcode-tui/src/choice-dialog.ts Outdated
: "Type to filter · Up/Down choose · Enter confirm · Esc cancel · Ctrl+U clear"),
? (options.numberShortcuts === false
? "Type to filter · Up/Down choose · Ctrl+O details · ←/→ or PgUp/PgDn scroll · Enter confirm · Esc cancel"
: "Type to filter · number selects · Up/Down choose · Ctrl+O details · Enter confirm · Esc cancel")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74d0132 — both default help variants (with details and without) now keep "←/→ or PgUp/PgDn scroll" when number shortcuts are enabled.

Comment on lines +98 to +117
test("labels carry number hints by default and omit them with numberShortcuts: false", async () => {
const { ui, host, focused } = makeFakeUi();
let seen = "";
const promise = choose(ui, host, theme, {
title: "T",
prompt: "P",
items: items(4),
signal: (() => {
const controller = new AbortController();
queueMicrotask(() => {
// capture rendered help before aborting
seen = JSON.stringify((host as unknown as { children: Component[] }).children.length);
controller.abort();
});
return controller.signal;
})()
});
await promise;
expect(typeof seen).toBe("string");
});

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74d0132 — the test now renders the dialog and asserts the "N. label" prefixes, the number-selects help fragment, and the numberShortcuts: false opt-out; added regression tests for >9-item and custom-help dialogs as well.

Comment thread test/choice-dialog.test.ts Outdated
expect(output).not.toContain("plan line 30");
expect(output).toContain("Plan 1–6 of 30");
expect(output).toContain("Ctrl+O details");
expect(output.replace(/\n/g, " ")).toContain("Ctrl+O");

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74d0132 — assertion restored to "Ctrl+O details" (with newline-wrapping normalization kept, since the longer help line wraps at width 60).

Comment thread packages/zcode-tui/src/choice-dialog.ts Outdated
Comment on lines +268 to +270
// Number shortcut: pressing 1-9 selects and confirms the visible option at
// that position (1 = first item) in a single keystroke. Disabled while a
// filter is active so typing digits keeps working as filter input.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74d0132 — comment updated to state the absolute-index semantics explicitly.

Comment thread packages/zcode-tui/src/choice-dialog.ts Outdated
Comment on lines +425 to +426
/** Prefix labels with 1-9 hints and enable digit quick-select. Default: true when no custom help. */
numberShortcuts?: boolean;

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 74d0132 — went further than a comment fix: availability now mirrors the rendered hints (≤9 items, no custom help) via one shared flag covering hints, the default help line, and the shortcut, so they can no longer disagree; numberShortcuts: true force-enables. Docstring updated to match.

wesleymatosdev and others added 2 commits September 8, 2026 21:31
…rage

Review-pass fixes from Copilot review + independent depth review:

- Digit quick-select availability now mirrors the rendered number hints
  (<=9 items, no custom help) via one shared flag: hints, the default
  help line, and the shortcut in handleInput can no longer disagree.
  On >9-item or custom-help dialogs digits stay filter input instead of
  instantly confirming a wrong item on the first keystroke of a
  digit-leading filter. numberShortcuts: true force-enables the shortcut
  regardless of hints.
- Default help lines with details keep the scroll hint so scrolling
  stays discoverable when number shortcuts are on.
- Rewrite the vacuous hints test: render the dialog and assert the
  "N. label" prefixes, the number-selects help fragment, the
  numberShortcuts: false opt-out, and force-enable via true; add
  regression tests for >9-item and custom-help dialogs (no hints, no
  shortcut, nothing confirms on a digit press).
- Restore the stronger "Ctrl+O details" help-text assertion.
- Fix numberShortcuts/numberShortcutCount doc comments to match actual
  behavior; return unconditionally inside the shortcut block.
@kingsword09

Copy link
Copy Markdown
Owner

Thanks for the contribution! I added a small follow-up commit to scope number shortcuts to permission prompts and preserve numeric filtering in other choice dialogs.

@kingsword09
kingsword09 merged commit 46a6f98 into kingsword09:main Sep 9, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Permission prompt: number-key shortcuts (1/2/3/4) for Allow once / Always allow / Deny

3 participants