import type { GitRunner } from './project.js';
/**
 * Promoting the agent queue out of a finished agent's branch and into the project checkout (#852).
 *
 * Runs happen in their own git worktree (#736), which is right for code and wrong for the queue:
 * `TODO_AGENTS.md` is shared mutable state, and a worktree forks it. So a quick-wins agent (#773)
 * wrote a perfectly good queue onto a branch nobody reads, auto PM kept seeing an empty checkout,
 * and it re-derived the same entries every cooldown, forever, spending real quota each time.
 *
 * Rom settled the destination on #624: the queue is a durable global `TODO_AGENTS.md` the session
 * writes directly, unlike a *proposal* (a ticket), which is a PR for a human to accept. So the
 * queue belongs in the checkout, and nothing should have to be merged by hand for the loop to turn.
 *
 * The daemon does this, not the agent. The agent stays sandboxed in its worktree with no write
 * access to the project checkout; the daemon copies one known file across, and commits only that
 * pathspec. Narrow enough to audit in a single log line.
 *
 * Conservative everywhere it is not certain: anything unexpected skips with a reason and leaves the
 * checkout untouched. A skipped promotion costs one idle cycle; a wrong one touches a repo a human
 * is working in.
 */
/** Why a promotion did not happen, or that it did. */
export type QueuePromotion = {
    promoted: true;
    branch: string;
} | {
    promoted: false;
    reason: string;
    /**
     * Worth trying again next tick: the queue file is mid-edit in the checkout, and the human's
     * work outranks an unattended tidy-up only until they commit it. Every other skip is final
     * for this agent. The callee owns this call — the daemon used to decide it by string-matching
     * the prose `reason`, where a one-word copyedit would have silently turned "retry next
     * tick" into "settled forever".
     */
    retry?: true;
};
/**
 * Copy `TODO_AGENTS.md` from a finished agent's branch into the project checkout and commit it.
 *
 * Skips, rather than forcing, when:
 * - the agent recorded no branch (nothing to read from)
 * - the branch has no queue file, or it matches the checkout already (nothing to do)
 * - the checkout has uncommitted changes to the queue file — a human is mid-edit, and their work
 *   outranks an unattended tidy-up
 *
 * Never throws: this runs on a background tick with nothing to catch it.
 */
export declare function promoteQueue(projectCwd: string, agent: {
    id: string;
    branch?: string | undefined;
    entry?: string | undefined;
}, git?: GitRunner, write?: (path: string, content: string) => Promise<void>): Promise<QueuePromotion>;
/**
 * Land what a drain agent pinned to one entry actually did (#1204): retire that entry, and keep any
 * follow-ups it queued.
 *
 * Additive by construction, which is what makes it safe to run concurrently: it only ever checks a
 * box or appends a line. It never unchecks, never removes, and never reorders, so two drains
 * landing in either order compose, and the worst a wrong guess can do is leave a duplicate line
 * for a human to delete rather than silently send an agent to redo finished work.
 *
 * A follow-up is an entry the agent's branch has that `atBase` did not: written during the agent. The
 * fork point is what tells that from an entry somebody *removed* meanwhile, which looks identical
 * from the branch alone and which `todo_format.md` makes the ordinary way to retire an entry. With
 * no fork point to compare against, nothing is added -- resurrecting struck-off work is worse than
 * leaving a follow-up on the branch, and the check-off still lands either way.
 */
export declare function landPinnedEntry(inCheckout: string, fromBranch: string, entry: string, atBase: string | undefined): string;
//# sourceMappingURL=queue-promote.d.ts.map