import type { AutoHandoffSkip, FrameworkEvent } from './events.js';
/** The production-grade loop status (#431): the current pass, whether it passed, and any blockers. */
export interface LoopStatus {
    pass: number;
    passing: boolean;
    blockers: string[];
    /** True once the run reached production-grade (the loop ended with no blockers). */
    productionGrade: boolean;
    /** True once a `done` bootstrap event has fired (the loop is over). */
    finished: boolean;
}
/**
 * The latest checklist verdict (#431), from the `checklist`/`improve`/`done` bootstrap
 * events. Null until a checklist has run — a prototype build never loops, and neither
 * does a run with no review configured (#1372: no preset, no serve); `done` with zero
 * passes is not a loop ending, so it does not open a status either. `done` closes an
 * open status out with the final verdict.
 */
export declare function loopStatus(events: readonly FrameworkEvent[]): LoopStatus | null;
/** The chosen deploy plan (#433): how the app renders and where it lands, from the `deploy` bootstrap event. */
export interface DeployPlan {
    render: 'ssr' | 'ssg' | 'spa';
    target: string;
    reason: string;
}
/** The deploy plan the run decided on, or null before the deploy phase ran. Latest wins. */
export declare function deployPlan(events: readonly FrameworkEvent[]): DeployPlan | null;
/** The run's lifecycle progress (#326): the session name it chose and whether it is ready for merge. */
export interface RunProgress {
    /** The `[a-z0-9-]` session name (also the branch), once the agent set one via `setSessionName()`. */
    sessionName?: string;
    /** True once the agent signalled `setReadyForMerge()`: building (false) -> ready (true). */
    readyForMerge: boolean;
}
/**
 * The run's lifecycle progress (#326): the latest `session-name` the agent set and whether
 * a `ready-for-merge` has fired. Drives the dashboard status label + dot (orange building,
 * green ready). Always returns a value — an untouched run is `{ readyForMerge: false }`.
 */
export declare function runProgress(events: readonly FrameworkEvent[]): RunProgress;
/** What a session will do with its work when it ends (#1102), and what it did. */
export interface HandoffState {
    /** Push the branch to `origin` on finish. */
    push: boolean;
    /** Open a draft PR on finish. Implies {@link push}. */
    pr: boolean;
    /**
     * Merge the PR once opened (#1216) — armed at launch, no checkbox, never changes mid-run.
     * Unlike the pair above this defaults to off: merging is opt-in, so a stream from before the
     * event carried it (#1382) must not read as a run that will land on main by itself.
     */
    merge: boolean;
    /** How the handoff ended, once it has run. Absent while the session is still going. */
    result?: {
        outcome: 'skipped';
        reason: AutoHandoffSkip;
    } | {
        outcome: 'done';
        url?: string;
    } | {
        outcome: 'failed';
        error: string;
    };
}
/**
 * What the session is armed to hand back, folded from its own events (#1102).
 *
 * Both halves start armed, so a run from before this existed — which emits no `handoff-armed` —
 * reads as armed, which is what it will actually do once it is running new code. Latest wins: the
 * checkboxes re-emit on every change.
 *
 * `initial` seeds the armed pair for a reader whose event stream missed the opening
 * `handoff-armed` (#1376): the run writes it as its very first event, before the live channel has
 * attached, so a live tab can only learn the real state from the run record's mirror
 * (`RunRecord.handoff`) — without it, a session the launcher armed push-only reads as "Open PR".
 * A `handoff-armed` event in the stream still wins: it is newer than any record snapshot.
 */
export declare function handoffState(events: readonly FrameworkEvent[], initial?: {
    push: boolean;
    pr: boolean;
    merge?: boolean;
}): HandoffState;
/** The wrapped agent session (#431): its id and a deep link, when one is known. */
export interface SessionInfo {
    driver?: string;
    fake?: boolean;
    sessionId?: string;
    sessionLink?: string;
    /**
     * The directory the agent ran in (#1195), from the opening `session` event.
     *
     * Taken from the event rather than the filesystem on purpose: a run that finishes cleanly has
     * its worktree removed (`tearDownWorktree`), so the event is the only surviving record of where
     * the session lived — and that path is exactly what `claude --resume` needs to find it again.
     */
    workspace?: string;
    /**
     * The model id the current leg's agent was started with (#1438). Folded per leg like the
     * driver/workspace: the latest `session` event wins, and a leg that recorded none clears it.
     */
    model?: string;
}
/**
 * The session behind the run (#431): the driver + workspace from the opening `session`
 * event, then the id and any deep link from the latest `session-update`. Null before the
 * session opens. The link is what the old dashboard surfaced as "open session".
 */
export declare function sessionInfo(events: readonly FrameworkEvent[]): SessionInfo | null;
//# sourceMappingURL=run-view.d.ts.map