hermes-agent/ui-tui/src/app/overlayStore.ts
Brooklyn Nicholson df5ca5065f 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.
2026-04-18 18:04:08 -05:00

30 lines
991 B
TypeScript

import { atom, computed } from 'nanostores'
import type { OverlayState } from './interfaces.js'
const buildOverlayState = (): OverlayState => ({
approval: null,
clarify: null,
confirm: null,
modelPicker: false,
pager: null,
picker: false,
secret: null,
skillsHub: false,
sudo: null
})
export const $overlayState = atom<OverlayState>(buildOverlayState())
export const $isBlocked = computed(
$overlayState,
({ approval, clarify, confirm, modelPicker, pager, picker, secret, skillsHub, sudo }) =>
Boolean(approval || clarify || confirm || modelPicker || pager || picker || secret || skillsHub || sudo)
)
export const getOverlayState = () => $overlayState.get()
export const patchOverlayState = (next: Partial<OverlayState> | ((state: OverlayState) => OverlayState)) =>
$overlayState.set(typeof next === 'function' ? next($overlayState.get()) : { ...$overlayState.get(), ...next })
export const resetOverlayState = () => $overlayState.set(buildOverlayState())