/** Flag subset both twins share for the interactive-routing gate. */
export interface SessionsPickerGateOpts {
    interactive?: boolean;
    json?: boolean;
    /** Present only on the browser twin; computer never sets it. */
    open?: string | boolean;
}
export interface SessionsPickerCommandSpec<TRow, TOpts extends SessionsPickerGateOpts> {
    /**
     * Browser requires `opts.open === undefined` so `--open` (bare or with a
     * selector) falls through to the flat printer. Computer has no `--open`.
     */
    requireOpenUndefined?: boolean;
    /** May be async — the browser spec's flat path awaits an artifact open. */
    runFlat: (opts: TOpts) => void | Promise<void>;
    buildRows: (opts: TOpts) => TRow[];
    emptyMessage: (opts: TOpts) => string;
    message: string;
    matches: (row: TRow, query: string) => boolean;
    labelFor: (row: TRow) => string;
    buildPreview: (row: TRow) => string;
    emptyFilterMessage: string;
    enterHint: string;
    onOpen: (row: TRow) => void | Promise<void>;
}
export interface SessionsPickerCommand<TOpts extends SessionsPickerGateOpts> {
    shouldOpen: (opts: TOpts, isTTY: boolean) => boolean;
    run: (opts: TOpts) => Promise<void>;
}
export declare function shouldOpenInteractiveSessions(opts: SessionsPickerGateOpts, isTTY: boolean, requireOpenUndefined?: boolean): boolean;
export declare function browseSessionsUntilQuit<TRow>(spec: {
    message: string;
    rows: TRow[];
    matches: (row: TRow, query: string) => boolean;
    labelFor: (row: TRow) => string;
    buildPreview: (row: TRow) => string;
    emptyFilterMessage: string;
    enterHint: string;
    onOpen: (row: TRow) => void | Promise<void>;
}): Promise<void>;
export declare function createSessionsPickerCommand<TRow, TOpts extends SessionsPickerGateOpts>(spec: SessionsPickerCommandSpec<TRow, TOpts>): SessionsPickerCommand<TOpts>;
