import type { SectionDef, Condition, ExtractTitle, ExtractButtons } from './types.js';
export interface ResolvedSection {
    id: string;
    fromLine: number;
    toLine: number;
    text: string;
}
export interface TraceEntry {
    kind: 'section' | 'state_match' | 'state_skip' | 'modal' | 'control' | 'notification' | 'delegate';
    text: string;
}
export declare function resolveSections(sectionsObj: Record<string, SectionDef>, lines: string[]): ResolvedSection[];
export declare function sectionText(sections: ResolvedSection[], sectionId: string | undefined, fullScreen: string): string;
export declare function evaluateCondition(cond: Condition, sections: ResolvedSection[], fullScreen: string, cursor: {
    row: number;
    col: number;
} | undefined, prevLines: string[] | undefined, trace: TraceEntry[], stateId: string): boolean;
export declare function extractTitle(rule: ExtractTitle, sections: ResolvedSection[], fullScreen: string): string | null;
export declare function extractButtonsFromRule(rule: ExtractButtons, hay: string): {
    index: number;
    label: string;
    key: string;
    current: boolean;
}[];
/**
 * Reduce a top→bottom-ordered list of parsed numbered entries to only the
 * bottom-most contiguous block — the run whose indices descend by exactly 1
 * scanning upward from the last entry.
 *
 * Picker and approval choices always render as the LAST contiguous numbered
 * block at the bottom of the modal section. The conversation history above can
 * carry its own stray "1./2./3." numbered lists (and blockquote `>` lines), and
 * because section anchoring can pull body lines into the modal section, a naive
 * top-down scan would bind the low option indices to those body lines and drop
 * the real choices (the dashboard would show, and an arrow-key picker would
 * commit, the wrong row). Selecting the bottom block makes the on-screen picker
 * win regardless of body content. Since pickers number their options 1..N
 * contiguously and bodies use indices ≥ 1, the upward chain always breaks the
 * moment it would need a "0." above the picker's "1." — so the picker block is
 * isolated cleanly. Entries are assumed already in screen order; the returned
 * slice keeps that order.
 */
export declare function lastContiguousNumberedBlock<T extends {
    index: number;
}>(entries: T[]): T[];
