UNPKG

framework

Version:

The (AI) Framework: turnkey, zero-config AI orchestration that wraps a coding-agent CLI (Claude Code) as a black box and takes you from an idea to a running app. Vite for AI.

72 lines 4.53 kB
import { withDataBranch } from './data-branch.js'; import type { PlanAssignment } from './auto-pm.js'; /** A ticket filename's lock sibling, e.g. `a.md` → `a.lock.md`, without the directory. */ export declare function ticketLockName(ticket: string): string; /** What a lock file holds: the claim line and nothing else, matching the ticketing format. */ export declare function ticketLockContent(agentId: string): string; /** The agent a lock file names, or undefined for content that is not a claim line. */ export declare function ticketLockHolder(md: string): string | undefined; /** The commit a batch of locks lands as. Names the count so the history reads as what happened. */ export declare function lockMessage(count: number): string; /** The commit a manual release lands as, naming the ticket freed. */ export declare function releaseMessage(ticket: string): string; /** The commit an abandoned claim's release lands as (#1583), naming why the daemon freed it. */ export declare function abandonedReleaseMessage(ticket: string): string; /** Injectable seams so every operation is unit-testable off disk and git. */ export interface TicketLockDeps { /** Write one lock file (default `fs.writeFile`). */ write?: (path: string, content: string) => Promise<void>; /** Read one sibling (default `fs.readFile`); a rejection reads as "absent". */ read?: (path: string) => Promise<string>; /** Delete one lock file (default `fs.rm`). */ remove?: (path: string) => Promise<void>; /** The data-branch write funnel (default {@link withDataBranch}); a test's fake stands in. */ funnel?: typeof withDataBranch; /** Progress line. */ log?: (message: string) => void; } /** * Which side of a ticket's life a batch claims for (#1420). A `plan` batch is about to *write* * plans, so an existing `.plan.md` means the work it came for is already done and the ticket is * skipped. A `drain` batch is about to *implement* a plan — the `.plan.md` is its input, not a * competing claim — so only an existing `.lock.md` stands in its way. */ export type TicketLockPhase = 'plan' | 'drain'; /** * Claim `assignments`' tickets for their agents: one `.lock.md` per ticket, written on the data * branch in one funneled cycle (#1582) — the funnel commits the batch and pushes the branch. The * cycle re-runs the checks against origin's state when a push loses a race, so a ticket whose * lock (or, for a `plan` batch, whose plan — see {@link TicketLockPhase}) appeared meanwhile is * skipped, not overwritten: an existing file is someone's claim or someone's work, and either * outranks this batch. * * Resolves the subset actually locked. A batch that could not land at all resolves `[]`; a batch * that committed but could not *push* is kept and resolved as locked — the commit still guards * every agent forked from this machine, which is the common case, and the sweep should not stand * a healthy local fan-out down over a network blip. The push is what closes the cross-machine * window (#1320), so its failure is logged rather than swallowed. * * Never throws: this runs on a background tick with nothing to catch it. */ export declare function acquireTicketLocks(cwd: string, assignments: readonly PlanAssignment[], deps?: TicketLockDeps, phase?: TicketLockPhase): Promise<PlanAssignment[]>; /** * What a release did: freed the ticket, found nothing to free, found someone else's claim * (`heldBy` releases only, #1583), or could not commit. */ export type ReleaseTicketLockResult = 'released' | 'no-lock' | 'not-holder' | 'error'; /** * Free one ticket's `.lock.md` by hand (#1420): the dashboard's answer to a dead agent, now that * no timer releases locks. One funneled data-branch cycle (#1582); a release that cannot land * reports `error` and changes nothing — the funnel restores the checkout, so the committed state * keeps telling the truth about the claim. */ export declare function releaseTicketLock(cwd: string, ticket: string, deps?: TicketLockDeps, opts?: { /** * Free the lock only while it still names this exact agent (#1583): the daemon releasing a * claim it minted for an agent that ended with nothing to hand off. A lock naming anyone * else is someone's live claim — re-locked after a manual release, say — and outranks the * cleanup. Absent (the dashboard button), whoever holds the lock is released. */ heldBy?: string; }): Promise<ReleaseTicketLockResult>; //# sourceMappingURL=ticket-locks.d.ts.map