import type { Director } from '@wrongstack/core/coordination'; import type { SlashCommand } from '@wrongstack/core/types'; import type { MutableRefObject } from 'react'; import type { Action, State } from '../app-reducer.js'; import type { SessionInterruptController } from './use-session-interrupt-controller.js'; /** * Minimal structural type for the slash registry hooks use. The real * registry exports a richer `SlashCommand` interface, but this hook only * needs the registration API surface and accepts the command shape * implicitly via the factory we register. */ interface SlashRegistryLike { register(cmd: SlashCommand, owner?: string, opts?: { official?: boolean; }): void; unregister(name: string): void; get?(name: string): SlashCommand | undefined; } export interface UseExitCommandOptions { slashRegistry: SlashRegistryLike; dispatch: (action: Action) => void; /** * Reducer-mirrored snapshot of `state.exitConfirm`. Retained in the hook * contract so the caller owns the panel state explicitly; lifecycle * teardown is enforced by the awaited confirmation resolver rather than * by observing a later render. */ exitConfirm: State['exitConfirm']; stateRef: MutableRefObject; sessionGenerationRef: MutableRefObject; interruptController?: SessionInterruptController | undefined; getDirector?: (() => Director | null | undefined) | undefined; } /** * Wire `/exit` to the TUI shell. * * Mirrors the `/clear` invariant: while a leader run or any subagent is in * flight, `/exit` must NOT terminate the TUI silently. It opens an * `exitConfirm` panel that requires explicit Enter/Esc acknowledgement. * * Once the user confirms, the hook bumps the session generation, aborts the * foreground leader plus autonomy/SDD drivers, and waits for both leader-idle * and fleet teardown behind a bounded 1500 ms grace window. This matches the * producer lifecycle used by `/interrupt` and `/clear`. * The slash dispatcher then observes `{ exit: true }` on the resolved * command and asks Ink to unmount; we deliberately do NOT call `exit()` * ourselves so there is exactly one graceful-unmount path. * * When no work is active, `confirmExit` resolves `true` without opening the * modal because there is no fleet teardown to await. * * The hook must be mounted exactly once from the App component. */ export declare function useExitCommand({ slashRegistry, dispatch, stateRef, sessionGenerationRef, interruptController, getDirector, }: UseExitCommandOptions): void; export {}; //# sourceMappingURL=use-exit-command.d.ts.map