Skip to content

fix: Return to the previous prompt when one is dismissed - #607

Merged
razor-x merged 2 commits into
mainfrom
claude/ctrl-pn-arrow-keys-gmyet0
Aug 5, 2026
Merged

fix: Return to the previous prompt when one is dismissed#607
razor-x merged 2 commits into
mainfrom
claude/ctrl-pn-arrow-keys-gmyet0

Conversation

@razor-x

@razor-x razor-x commented Aug 4, 2026

Copy link
Copy Markdown
Member

Summary

Dismissing a prompt ended the whole command. Escaping out of a single mistyped or misread answer — picking the wrong connected account for connected_account_id, say — threw away every parameter gathered so far and exited.

Now a dismissal abandons that one answer and returns to the step before it, and the prompt says so:

◆  [/devices/get] Parameters · Esc: go back
│  Search:
│  ● device_id [device1]
│    name
│    [Back]
│  ↑/↓ to select • Enter: confirm • Type: to search
└

Implementation

No new machinery. The prompts already reported a dismissal as PromptCancelledError; the only place it was handled was the top-level catch in src/bin/cli.ts, which ends the command. Each step of a flow now catches it and returns to the step before.

Escape and ctrl-c are treated identically — neither is special-cased, and nothing inspects which key was pressed.

The hint comes from one small helper, withBackHint in src/lib/util/prompt.ts, applied to the message of each prompt whose caller catches the dismissal — and only those, so it never promises a way back that does not exist. It goes on the message because clack builds its keyboard hint line from a hardcoded list: autocomplete has no option for it at all (@clack/prompts/dist/index.mjs:191-195), and showInstructions on select/multiselect only toggles the stock text on or off. Making that line itself customizable needs an upstream change to clack, worth a separate PR.

Behavior

Where you dismiss What happens Hinted
A parameter's value prompt (text, number, enum, list, resource picker, timestamp) Back to the parameter menu, parameter left as it was Yes
The parameter menu Leaves the command, same as its [Back] entry Yes
A sub-object's menu Back to the parent menu, same as its [Back] entry Yes
The list or metadata editor's action menu Finishes editing, keeping changes so far Yes
A prompt inside those editors Back to the editor's action menu Yes
A sub-command menu Up one level Yes
The top-level command menu Stops the CLI, as before No
Login, workspace and server selection, action attempt polling Stops the CLI, as before No

A dismissal with no step to go back to still stops the CLI with Cancelled and exit code 1, exactly as before.

Note on exiting

With ctrl-c now going back a level, leaving a deep flow in one keystroke is worth a follow-up. ctrl-d looks like it exits, but only by accident: it closes clack's readline, the prompt promise never settles, and Node bails with exit code 13 and an unsettled-promise warning, so no error handling or message runs. Verified in a pty. Happy to make that a clean exit separately — it needs care not to leave the terminal in raw mode.

Testing

  • src/lib/interact-for-blueprint-object.test.ts — dismissing the parameter menu leaves the command; dismissing a value prompt returns to the menu with the parameter unset; a previously supplied value survives a dismissal; the menu and value prompts carry the hint.
  • src/lib/interact-for-command-selection.test.ts — a sub-command menu is hinted, the top-level menu is not.
  • The prompt mocks in those tests and in interact-for-custom-metadata.test.ts now replace only the prompts, so the real PromptCancelledError and withBackHint are exercised.
  • Rendered frame checked against real clack output, and the flows checked in a pty.

Full suite green: 181 tests across 18 files, plus typecheck, lint, and formatting.

claude added 2 commits August 4, 2026 23:56
Dismissing a prompt ended the whole command, so escaping out of a single
mistyped or misread answer, such as picking the wrong connected account,
threw away every parameter gathered so far.

The prompts already report a dismissal; only the flows around them
treated it as fatal. Each step of a flow now catches it and returns to
the step before, so a dismissal abandons an answer rather than the
command. Dismissing the top level command menu still stops the CLI,
since there is no step to go back to.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyVFq6gYChW9wtoDq8CHsD
The new behaviour was invisible: prompts still only advertised the keys
clack knows about. Note it on the message of every prompt whose flow
returns to the step before, and only those, so it never claims a way back
that does not exist.

Clack renders its keyboard hints from a hardcoded list that a caller
cannot add to, so the note goes on the message rather than that line.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FyVFq6gYChW9wtoDq8CHsD
@razor-x
razor-x merged commit 5f9e8f5 into main Aug 5, 2026
12 checks passed
@razor-x
razor-x deleted the claude/ctrl-pn-arrow-keys-gmyet0 branch August 5, 2026 05:48
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.

2 participants