feat(tui): replace /clear double-press gate with a proper confirm overlay

The time-window gate felt wrong — users would hit /clear, read the
prompt, retype, and consistently blow past the window. Swapping to a
real yes/no overlay that blocks input like the existing Approval and
Clarify prompts.

- add ConfirmReq type + OverlayState.confirm + $isBlocked coverage
- ConfirmPrompt component (prompts.tsx): cancel row on top as the
  default, danger-coloured confirm row on the bottom, Y/N hotkeys,
  Enter on default = cancel, Esc/Ctrl+C cancel
- wire into PromptZone (appOverlays.tsx)
- /clear + /new now push onto the overlay instead of arming a timer
- HERMES_TUI_NO_CONFIRM=1 still skips the prompt for scripting
- drop the destructiveGate + createSlashHandler reset wiring
  (destructive.ts and its tests removed)

Refs #4069.
This commit is contained in:
Brooklyn Nicholson 2026-04-18 18:04:08 -05:00
parent 75377feb07
commit df5ca5065f
9 changed files with 132 additions and 115 deletions

View file

@ -5,6 +5,7 @@ import type { OverlayState } from './interfaces.js'
const buildOverlayState = (): OverlayState => ({
approval: null,
clarify: null,
confirm: null,
modelPicker: false,
pager: null,
picker: false,
@ -17,8 +18,8 @@ export const $overlayState = atom<OverlayState>(buildOverlayState())
export const $isBlocked = computed(
$overlayState,
({ approval, clarify, modelPicker, pager, picker, secret, skillsHub, sudo }) =>
Boolean(approval || clarify || modelPicker || pager || picker || secret || skillsHub || sudo)
({ approval, clarify, confirm, modelPicker, pager, picker, secret, skillsHub, sudo }) =>
Boolean(approval || clarify || confirm || modelPicker || pager || picker || secret || skillsHub || sudo)
)
export const getOverlayState = () => $overlayState.get()