import { type CliRunner } from '../cli-exec.js';
import { type Cached } from './cache.js';
import type { AutoMergeOutcome } from '../events.js';
/**
 * The `gh` CLI, in one place: the two JSON reads the dashboard makes and the runner its write
 * actions use.
 *
 * There were four separate `gh` adapters across three modules. Three were reads that each
 * hand-rolled `execFile` + `JSON.parse` + a swallowed failure and each spelled the 8s timeout
 * again, and two of those differed only in whether a branch positional was passed; the fourth was
 * a generic runner for the write actions, which rejects with stderr and waits longer.
 */
/** Runs `gh`, resolving stdout and rejecting with the CLI's own stderr on failure. */
export type GhRunner = CliRunner;
/**
 * A {@link GhRunner} for the write actions (push, open a PR). Longer timeout than a read: these
 * talk to the network and to git, and the user is waiting on a button they pressed.
 */
export declare function nodeGhRunner(): GhRunner;
/**
 * The GitHub token an Actions run authenticates with (#1352).
 *
 * `GH_TOKEN` / `GITHUB_TOKEN` win, because CI sets them and must beat whatever `gh` happens to be
 * logged in as on the runner. With neither set, fall back to the `gh` CLI's own credential — the
 * same one every PR this framework opens is already authenticated by. A machine that can open a PR
 * could always have run an Actions session too; it just had no way to say so, and the agent failed
 * with the credential sitting one `gh auth token` away.
 *
 * Undefined when there is no token to be had (gh missing, logged out, or refusing to hand it over),
 * which the caller turns into the agent's stated reason for not starting. Deliberately quiet about
 * *why* gh declined: the caller's message names both ways to fix it, and a keyring prompt's stderr
 * is not something to put in front of someone who simply has not set GH_TOKEN.
 */
export declare function githubToken(cwd: string, env?: Record<string, string | undefined>, gh?: GhRunner): Promise<string | undefined>;
/** A forgiving `gh --json` read: resolves `empty` when gh is missing/unauthed, or its output is not JSON. */
export declare function ghJson<T>(args: string[], cwd: string, empty: T, gh?: GhRunner): Promise<T>;
/** The PR opened for a branch, when there is one. */
export interface LinkedPr {
    number: number;
    url: string;
    /** OPEN / MERGED / CLOSED (as gh reports it). */
    state: string;
    title: string;
    /** ISO creation time, when the read included it: what tells one agent's PR from a predecessor's. */
    createdAt?: string;
    /**
     * The head commit the PR covers, when the read included it (#1512): what tells "the branch's
     * PR already landed everything" from "the session kept working after its PR merged".
     */
    headRefOid?: string;
}
/**
 * A best-effort PR lookup, for a named branch or for the checkout's current branch. One type for
 * both: the named-branch form is the general one, and "the current branch" is just omitting it.
 */
export type PrLookup = (cwd: string, branch?: string) => Promise<LinkedPr | undefined>;
/**
 * The branch-addressed form, for a caller that always names one (#799): a finished session's
 * worktree may be gone, so "the current branch" would silently be the project's, not the
 * session's. Narrower than {@link PrLookup} on purpose, so that invariant is in the type.
 */
export type BranchPrLookup = (cwd: string, branch: string) => Promise<LinkedPr | undefined>;
/**
 * The PR for `branch`, or for whatever branch `cwd` is on when none is named. Resolves undefined
 * when gh is missing/unauthed or there is no PR.
 *
 * The named-branch form is what a finished session needs (#799): its worktree may be gone, so the
 * checkout's current branch is the project's, not the session's. The fields are copied out rather
 * than passed through, so a future `--json` addition cannot leak into what callers store.
 *
 * Every optional field {@link LinkedPr} declares must be both asked for and copied out here, or it
 * is silently absent for every caller of this path. `createdAt` was neither, and the CI watch reads
 * it to decide whether a check-less PR has outlived the window a check suite takes to attach — with
 * the field missing, that age is unknowable and such a PR could never be merged at all.
 */
export declare function ghPrView(cwd: string, branch?: string, gh?: GhRunner): Promise<LinkedPr | undefined>;
/**
 * The cached form of {@link ghPrView} (#1028), and what the dashboard's panels use.
 *
 * A PR lookup costs about 600ms where the git reads beside it cost ten, and the answer changes
 * about as often as someone opens a PR. Cached per checkout and branch, shared between the
 * worktree bar and the handoff summary, and refreshed behind whoever asks. `pending` says the
 * answer is not known yet rather than that there is no PR — the difference matters to a caller
 * deciding whether to offer "Open PR".
 */
export declare function cachedPrView(cwd: string, branch?: string): Promise<Cached<LinkedPr | undefined>>;
/** Forget a branch's PR, after an action that changes whether it has one. */
export declare function forgetPr(cwd: string, branch?: string): void;
/**
 * Every PR a branch name has ever had, newest first (#1251).
 *
 * `gh pr view <branch>` answers with the newest PR for that head *in any state*, so a session
 * whose prompt pins its branch name (`the-framework/triage-quick`) inherits a predecessor's
 * merged PR as its own. The list form keeps the whole history so {@link pickAgentPr} can decide
 * which entry, if any, belongs to the agent asking. Resolves `[]` when gh is missing/unauthed —
 * indistinguishable from "no PRs", which is what every caller would do with a failure anyway.
 */
export declare function ghPrsForBranch(cwd: string, branch: string): Promise<LinkedPr[]>;
/**
 * {@link ghPrsForBranch} for a caller about to *open* a PR (#1601): a listing that fails throws
 * instead of reading as "no PRs", because "none" and "could not tell" must not look alike there —
 * the difference is a second draft PR on a branch that already has one.
 */
export declare function ghPrsForBranchOrThrow(cwd: string, branch: string): Promise<LinkedPr[]>;
/**
 * How {@link ghMergePr} answers GitHub refusing to arm auto-merge. `merge-now` (the default, and
 * everything before #1418) merges directly: right where a human just said "land it". `watch`
 * merges directly only when the PR's checks have already passed, and otherwise answers `watched`
 * — the daemon's CI watch merges it on green. That is the auto path's mode, because the direct
 * fallback there is precisely the lands-before-CI hazard (#1406): a repo without GitHub
 * auto-merge saw every armed PR merged seconds after opening, before its first check ran.
 */
export interface MergePrOptions {
    whenUnarmed?: 'merge-now' | 'watch';
}
/**
 * Merge a PR the handoff just opened (#1216): GitHub auto-merge first, so the PR lands when its
 * checks pass rather than before them; where the repo does not allow auto-merge, merged directly
 * or handed to the daemon's CI watch, per {@link MergePrOptions.whenUnarmed} (#1418). Squash in
 * all forms — a session's branch is working history, not a story worth preserving.
 *
 * Never throws: the caller reports the outcome alongside the handoff's, and a merge that could
 * not happen must not turn a successful handoff into a failed one.
 */
export declare function ghMergePr(cwd: string, number: number, gh?: GhRunner, opts?: MergePrOptions): Promise<AutoMergeOutcome>;
/** Where a PR's CI stands (#1418), summarised to the one question the merge path asks. */
export interface PrCiStatus {
    /**
     * `passing`: every check has concluded and none failed — the PR may land. `failing`: at least
     * one concluded check failed, whatever the rest are doing — red now, and more green later will
     * not unsay it. `pending`: something is still running and nothing has failed yet. `none`: no
     * checks reported — either the repo has no CI, or the suite has not attached yet (they take a
     * few seconds after a push), which is why callers treat it with a grace period rather than as
     * green. Also the answer when `gh` itself could not say: acting on an unreadable status must
     * never merge anything.
     */
    checks: 'passing' | 'failing' | 'pending' | 'none';
    /** The names of the failed checks, for the CI-fix agent's prompt. */
    failed: string[];
    /** The PR's head commit, so a fix attempt can be recorded against the state it saw. */
    headSha?: string;
    /** The PR's head branch, where a CI fix must land. Rides this read because it is the same `gh` call. */
    branch?: string;
}
/**
 * A PR's combined check state (#1418): GitHub Actions check runs and classic commit statuses,
 * both of which `statusCheckRollup` carries.
 *
 * Skipped and neutral conclusions count as passing, matching how GitHub's own merge box treats
 * them; everything else that concluded non-successfully counts as failed — a cancelled or
 * timed-out check is not evidence the work is good, and the merge this feeds exists to stop
 * unverified work landing (#1406).
 */
export declare function ghPrCiStatus(cwd: string, number: number, gh?: GhRunner): Promise<PrCiStatus>;
/** Whether the repo lets PRs use GitHub auto-merge (#1417); `known: false` when `gh` could not say. */
export interface RepoAutoMerge {
    known: boolean;
    allowed: boolean;
}
/**
 * Whether this repo allows GitHub auto-merge (#1417).
 *
 * An armed merge on a repo that does not (the {@link DIRECT_MERGE_FALLBACK} half of #1216) is
 * handed to the daemon's CI watch (#1418): merge on green, but only while the daemon runs — so
 * the launcher notes the local fallback and names the server-side Allow auto-merge setup.
 * `known: false` (gh missing, unauthenticated, not a GitHub repo) is "could not say", which
 * renders nothing: no crying wolf, same stance as the trust (#1318) read.
 *
 * The probe is the REST endpoint, not `gh repo view --json autoMergeAllowed`: `repo view` has no
 * such field (any gh version), so that spelling always errored into "could not say". REST omits
 * `allow_auto_merge` for viewers without push access — absent lands in the same "could not say".
 */
export declare function ghRepoAutoMerge(cwd: string, gh?: GhRunner): Promise<RepoAutoMerge>;
/** The cached form of {@link ghRepoAutoMerge} (#1028): the launcher polls, the setting barely changes. */
export declare function cachedRepoAutoMerge(cwd: string): Promise<Cached<RepoAutoMerge>>;
/** The cached form of {@link ghPrsForBranch}, shared through the same read-through cache (#1028). */
export declare function cachedPrsForBranch(cwd: string, branch: string): Promise<Cached<LinkedPr[]>>;
/** Forget a branch's PR history, after an action that changes it (opening one). */
export declare function forgetBranchPrs(cwd: string, branch: string): void;
/**
 * The PR that belongs to an agent, out of every PR its branch name has had (#1251/#1255).
 *
 * An OPEN PR always counts: GitHub allows one open PR per head branch, so whatever is open on the
 * run's branch is where its pushed commits land. A closed one counts only when it was created
 * after the agent started (`since`, the agent's `startedAt`) — the oldest such entry, which is the one
 * this agent's handoff opened. Anything older is a previous agent's PR wearing the same branch name,
 * which is exactly what showed a merged two-day-old PR as a fresh session's own. Without `since`
 * only an open PR is trusted.
 *
 * `order` exists for the one caller asking a different question (#1512). `'first'` answers
 * identity — which PR did *this agent* open, so a later agent's must not be the answer. `'latest'`
 * answers the handoff decision — which PR last saw the branch, so "did the session keep working
 * past it" is readable off that PR's `headRefOid`; there the oldest entry would call work that a
 * second PR already landed unlanded.
 */
export declare function pickAgentPr(prs: LinkedPr[], since?: string, order?: 'first' | 'latest'): LinkedPr | undefined;
/** An open PR on the interventions queue (#632). */
export interface OpenPr {
    number: number;
    title: string;
    url: string;
    /**
     * Draft PRs are generally left off the queue: a draft is not asking for review.
     *
     * The exception is a draft the framework opened for itself (#1102), which {@link headRefName}
     * is what tells apart.
     */
    isDraft: boolean;
    /** The branch the PR is from, so a session's own PR can be recognised as ours (#1102). */
    headRefName?: string;
    createdAt?: string;
}
/**
 * A checkout's open PRs. Unlike the other reads here it *rejects* when gh could not answer — no
 * remote, not authenticated, GitHub unreachable — instead of resolving `[]`.
 *
 * "No PRs are open" and "I could not look" are different answers, and its caller keeps a baseline
 * of what it has already announced (#1623): taking the second for the first makes the next
 * successful read announce every already-open PR as new. The caller decides what a failure costs;
 * it cannot decide what it never hears about.
 */
export declare function ghPrList(cwd: string, gh?: GhRunner): Promise<OpenPr[]>;
/** Lists a checkout's open PRs; rejects when there is no remote / gh is unavailable. */
export type PrLister = (cwd: string) => Promise<OpenPr[]>;
//# sourceMappingURL=gh.d.ts.map