import type { ActiveSession } from '../session/active.js';
import { type AttentionResolution, type AttentionSource, type AttentionState, type BlockOption, type BlockQuestion, type OpenBlock, type SourceCursor } from './feed.js';
/** What an attention item is asking of the operator. */
export type AttentionKind = 'question' | 'permission' | 'plan_review' | 'declared' | 'failure' | 'stall' | 'review';
/** How an answer can be routed back to the waiting agent. */
export type ReplyCapability = 'terminal' | 'tmux' | 'cloud' | 'team' | 'none';
/**
 * One answerable choice on an attention item. Extends {@link BlockOption} with a
 * stable `id` the UI echoes back when the operator picks it, and an optional
 * `deliveryKey` (the harness-native keystroke / selection token) that Track B's
 * answer router resolves the reply rail with.
 */
export interface AttentionChoice extends BlockOption {
    id: string;
    deliveryKey?: string;
}
/**
 * The canonical operator-facing attention record. One reconciled thing that needs
 * a human, whatever produced it. This is the public envelope Tracks B and C
 * consume — a stability contract, not an internal shape.
 */
export interface AttentionItem {
    /** Stable identity: `host/session/generation`. A new generation is a new item. */
    key: string;
    sessionId: string;
    mailboxId: string;
    host: string;
    project?: string;
    kind: AttentionKind;
    source: AttentionSource;
    state: AttentionState;
    /** ISO-8601 timestamp the ask opened. */
    openedAt: string;
    question?: BlockQuestion;
    choices?: AttentionChoice[];
    replyCapability: ReplyCapability;
    safeDefault?: string;
    /**
     * Clusters IDENTICAL asks across different agents for batch triage. It is a hash
     * of the RAW question intent (kind + verbatim question text + option labels) —
     * deliberately NOT the UI-normalized display text, so two agents asking the same
     * thing collapse even when the floor renders them differently.
     */
    fingerprint: string;
    /** Where in the source this generation sits — the fence a resolution compares against. */
    sourceCursor?: SourceCursor;
}
/**
 * A pull-request attention signal, supplied BY the CLI (Track B refreshes it on a
 * bounded TTL and hands it in). Track A only consumes the computed `needsHuman`
 * flag — it never reaches into the extension's PR board or recomputes review
 * state. Fields mirror the `gh pr view` projection so Track B can populate it.
 */
export interface PullRequestAttentionSignal {
    number: number;
    title?: string;
    url?: string;
    /** True when the PR is in a state that needs a human decision (review / merge). */
    needsHuman: boolean;
    reviewDecision?: string;
    mergeable?: string;
    state?: string;
    isDraft?: boolean;
}
/**
 * Fingerprint of an ask's raw intent. Uses the verbatim question text and option
 * labels (NOT display-normalized text) so identical asks from different agents
 * share a fingerprint for batch triage.
 */
export declare function attentionFingerprint(kind: AttentionKind, question?: BlockQuestion): string;
/**
 * Reconcile the feed block ledger, the session lifecycle, a CLI-supplied PR
 * signal, and the latest resolution tombstone into one attention item — or
 * `undefined` when nothing needs a human. Pure; the extension never chooses
 * authority.
 */
export declare function reconcileAttention(input: {
    block?: OpenBlock;
    session: ActiveSession;
    pullRequest?: PullRequestAttentionSignal;
    resolution?: AttentionResolution;
    nowMs: number;
}): AttentionItem | undefined;
