import { type AgentMeta } from './store/index.js';
import { type HandoffResult, type PrAgent } from './dashboard/agent-handoff.js';
import { type LinkedPr, type PrCiStatus } from './dashboard/gh.js';
import type { Cached } from './dashboard/cache.js';
/**
 * How long an agent's watched PR stays on the sweep's list: long enough to survive a weekend of the
 * daemon being off, short enough that the sweep's `gh` spend cannot grow with the archive. A PR
 * older than this is a human's to land — it has been red or unmergeable for a week.
 */
export declare const CI_WATCH_WINDOW_MS: number;
/**
 * How old a check-less PR must be before "no checks" is believed to mean "this repo has no CI"
 * rather than "the suite has not attached yet" — GitHub takes seconds to attach one after a push,
 * and merging inside that window is the stale-check hazard (#1406) wearing a different face.
 */
export declare const NO_CHECKS_GRACE_MS: number;
/**
 * The marker a CI-fix agent's prompt opens with, so attempts are discoverable from agent metas. The
 * `@` is always there, sha or not: it is what stops "PR #12" reading as a prefix of "PR #123"
 * when the metas are scanned for prior attempts.
 */
export declare function ciFixMarker(number: number, headSha?: string): string;
/** What the fix agent needs to know, distilled from the PR and its checks read. */
export interface CiFixRequest {
    number: number;
    title: string;
    url: string;
    branch: string;
    headSha: string;
    failed: string[];
}
/**
 * The prompt a CI-fix session runs (#1418). Explicit about the git mechanics because the agent gets
 * an ordinary session worktree on its own scratch branch: the PR's branch may be checked out in a
 * retained worktree elsewhere, so `push origin HEAD:<branch>` is the one spelling that always
 * lands the fix without fighting over who holds the branch.
 */
export declare function ciFixPrompt(fix: CiFixRequest): string;
/** One PR the sweep merged. */
export interface CiMerged {
    agentId: string;
    number: number;
    url?: string;
}
/** One fix session the sweep started, or why it stood down. */
export interface CiFixOutcome {
    number: number;
    /** The started session, when one was. */
    agentId?: string;
    /** Why no session was started: the wiring declined (gate/quota), or the attempts cap is spent. */
    reason?: 'declined' | 'attempts-exhausted';
}
/** What one project's sweep did. */
export interface CiSweepResult {
    merged: CiMerged[];
    /** Merges that should have happened and did not, with the refusal. */
    failed: {
        agentId: string;
        number: number;
        error: string;
    }[];
    fixes: CiFixOutcome[];
}
/** Injectable seams so the sweep is unit-testable off disk and off `gh`. */
export interface CiSweepDeps {
    /** Every agent meta worth scanning — live and archived (default: both stores). */
    agents?: (cwd: string) => Promise<AgentMeta[]>;
    /** The PR that belongs to an agent (default {@link resolveAgentPr}, which rides the PR-lookup cache (#1028)). */
    pr?: (cwd: string, agent: PrAgent) => Promise<Cached<LinkedPr | undefined>>;
    /** A PR's combined check state (default {@link ghPrCiStatus}). */
    ci?: (cwd: string, number: number) => Promise<PrCiStatus>;
    /** Merge an agent's open PR (default {@link mergeAgentPr}, which also forgets the PR caches). */
    merge?: (cwd: string, agent: PrAgent) => Promise<HandoffResult>;
    /**
     * Start a CI-fix session for a red PR (#1418's fix half), resolving the agent id or undefined
     * when the wiring declined (preference off, no quota headroom, start failed). Absent = the fix
     * half is off and red PRs are only left for the merge half to keep ignoring.
     */
    fix?: (cwd: string, request: CiFixRequest) => Promise<string | undefined>;
    /**
     * Merge attempts that already failed (`<cwd>\0<number>\0<headSha>`), fed and consulted by the
     * sweep so a persistently refused merge (branch protection demanding a review, say) costs one
     * `gh` write per head, not one per tick for a week. The head sha is part of the key (#1484):
     * a push that changes the head — a conflict resolved, say — re-arms exactly one more attempt,
     * the same re-arm rule the CI-fix half applies. Before, a PR that arrived unmergeable was
     * skipped for the daemon's lifetime even after its branch was fixed and its checks went green.
     * In-memory on purpose: a daemon restart retries once.
     */
    attemptedMerges?: Set<string>;
    now?: () => number;
}
/**
 * Sweep one project's watched PRs (#1418): merge the green ones the repo could not arm GitHub
 * auto-merge for, and start a fix session for the red ones.
 *
 * Conservative wherever the answer is unclear: a PR that is not OPEN is done (merged or a
 * human's rejection — neither is this sweep's to touch), `pending` checks wait for the next
 * tick, and a check-less PR only counts as green once it has been check-less for longer than a
 * suite takes to attach ({@link NO_CHECKS_GRACE_MS}). An `auto-armed` PR is never merged here —
 * GitHub holds that promise — but its checks going red still starts a fix.
 */
export declare function sweepProjectCi(cwd: string, deps?: CiSweepDeps): Promise<CiSweepResult>;
/** A running watch, in the shape the daemon's other background services use. */
export interface CiWatch {
    /** Run one sweep now, awaiting it. Exposed for tests and on-demand callers. */
    tick: () => Promise<void>;
    stop: () => void;
}
/** What {@link startCiWatch} needs from the daemon. */
export interface CiWatchOptions {
    /** The registered projects to sweep. */
    projects: () => Promise<readonly {
        path: string;
    }[]>;
    log: (message: string) => void;
    /** The per-project sweep's seams, {@link CiSweepDeps.fix} included — the daemon wires the gates. */
    deps?: CiSweepDeps;
    /** The per-project sweep (default {@link sweepProjectCi}). */
    sweep?: (cwd: string, deps: CiSweepDeps) => Promise<CiSweepResult>;
}
/**
 * Watch every registered project's armed PRs on a timer (#1418).
 *
 * Same lifecycle contract as the merged-worktree sweep: an immediate start-up tick (the case is a
 * daemon that was off while checks went green), overlapping ticks join the sweep in flight, the
 * timer is unref'd, and everything it does is logged — a PR merging with no line explaining why
 * reads as a bug even when it is the feature.
 */
export declare function startCiWatch(opts: CiWatchOptions): CiWatch;
//# sourceMappingURL=ci-watch.d.ts.map