/**
 * Parked-agent answer router (RUSH-1474).
 *
 * `agents message` historically only enqueued into the mailbox (delivered at the
 * next PreToolUse). That steers a *running* agent between tool calls but never
 * unblocks a *parked* agent:
 *   - interactive TUI open on AskUserQuestion (needs keystrokes, not context)
 *   - headless run waiting on input (no next tool call; needs resume)
 *
 * This module picks the delivery mechanism from (open feed block × session
 * liveness × runtime rail). Pure — unit-testable without a live PTY.
 */
import type { OpenBlock, BlockOption } from './feed/feed.js';
import type { ActiveSession } from './session/active.js';
import type { InjectTarget } from './terminal/index.js';
export type AnswerRouteKind = 'mailbox' | 'pty' | 'tmux' | 'iterm' | 'resume' | 'refuse';
export interface AnswerRoute {
    kind: AnswerRouteKind;
    /** Human reason shown in CLI output / refused errors. */
    reason: string;
    /**
     * Keystrokes / payload for the chosen path.
     *  - mailbox: unused (text is enqueued as-is)
     *  - pty/tmux/iterm: the digit or free-text to inject
     *  - resume: the free-text prompt to pass on re-entry
     */
    payload?: string;
    /** Inject target when kind is pty/tmux/iterm. */
    inject?: InjectTarget;
    /** Session id + agent kind for resume. */
    resume?: {
        sessionId: string;
        agent: string;
    };
}
export interface AnswerRouterInput {
    /** Resolved mailbox / session id. */
    mailboxId: string;
    /** Answer text (option label or free text). */
    answer: string;
    /** Open feed block for this agent, if any. */
    block?: OpenBlock | null;
    /** Live session row matching the mailbox, if any. */
    session?: ActiveSession | null;
}
/**
 * Match free-text answer against question options.
 * Exact (case-insensitive) > startsWith > includes. Returns 0-based index or -1.
 */
export declare function matchOptionIndex(answer: string, options: Array<Pick<BlockOption, 'label'>> | undefined): number;
/**
 * Build the keystroke payload that closes an AskUserQuestion TUI.
 * Numbered options are selected by digit (1-based) + Enter. Free text with an
 * "Other" option selects Other then types; without Other, types the answer.
 */
export declare function keystrokesForAnswer(answer: string, options?: Array<Pick<BlockOption, 'label'>>): {
    payload: string;
    matched: 'option' | 'free-text' | 'other';
};
/** True when the session is waiting on user input (parked on a question/plan). */
export declare function isParkedOnInput(session: ActiveSession | null | undefined): boolean;
/** True when an open feed block still needs an answer. */
export declare function isOpenQuestionBlock(block: OpenBlock | null | undefined): boolean;
/**
 * Pick the delivery mechanism for one answer.
 *
 * Precedence:
 *   1. Parked on open question + injectable rail (tmux/iterm/pty) → keystroke
 *   2. Parked on open question + headless (no rail) → resume with answer
 *   3. Parked on open question + no rail + interactive → refuse (don't mailbox-drop)
 *   4. Otherwise → mailbox (running agent between tool calls)
 */
export declare function resolveAnswerRoute(input: AnswerRouterInput): AnswerRoute;
/** Build argv for a headless resume that continues with the answer text. */
export declare function resumeArgv(route: AnswerRoute): string[];
