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.

77 lines 3.9 kB
import { type RemoveResult, type WorktreeRow } from './worktrees.js'; /** One worktree this sweep removed. */ export interface RemovedWorktree { /** The agent id, which is also the worktree's directory name. */ agentId: string; } /** A worktree the sweep tried to reclaim and could not, and why. */ export interface FailedRemoval { agentId: string; error: string; } /** What {@link removeMergedWorktrees} did. */ export interface MergedSweepResult { removed: RemovedWorktree[]; /** Worktrees it tried and could not reclaim — most often a branch it could not push. */ failed: FailedRemoval[]; } /** Injectable seams so the sweep is unit-testable off disk. */ export interface MergedSweepDeps { /** The worktrees on disk (default {@link listProjectWorktrees}). */ worktrees?: (cwd: string) => Promise<WorktreeRow[]>; /** Removes one worktree (default {@link removeProjectWorktree}). */ remove?: (cwd: string, agentId: string) => Promise<RemoveResult>; /** Whether the repo has a remote at all (default {@link repoHasRemote}). */ hasRemote?: (cwd: string) => Promise<boolean>; /** Agent ids whose checkouts the daemon is still responsible for; see {@link MergedSweepOptions.busy}. */ busy?: ReadonlySet<string>; } /** * Reclaim every retained worktree in `cwd` whose work can reach the remote (E5). * * The decision is entirely {@link removeProjectWorktree}'s — commit what is pending, push the * branch, remove only once the remote has it — so the automatic path and the manual one (the * dashboard's Remove button) are one behaviour rather than two that can disagree. This adds the * loop, the one thing it must never touch (a live agent's checkout, where its agent is working), and * the agent lock. * * The lock is load-bearing: an agent's meta flips to `done` a beat before its teardown finishes * archiving, so a sweep landing in that window would remove the checkout out from under the * archive — which then recreates the directory it was reading from, and the removal silently * un-happens. Every other actor on a checkout already takes this lock. */ export declare function removeMergedWorktrees(cwd: string, deps?: MergedSweepDeps): Promise<MergedSweepResult>; /** A running sweep, in the shape the daemon's other background services use. */ export interface MergedWorktreeSweep { /** Run one sweep now, awaiting it. Exposed for tests and for a caller that wants it on demand. */ tick: () => Promise<void>; stop: () => void; } /** What {@link startMergedWorktreeSweep} needs from the daemon. */ export interface MergedSweepOptions { /** The registered projects to sweep. */ projects: () => Promise<readonly { path: string; }[]>; log: (message: string) => void; /** * The agents the daemon is still responsible for — spawning, running, or mid-retirement — whose * checkouts this must not touch. * * "Not live" on disk is not "the daemon is finished with it": an agent's meta flips to `done` a * beat before its teardown archives the history and reclaims the checkout, and a sweep landing * in that window races the teardown for the same directory. Absent means nothing is busy, which * is right for a caller that spawns no agents. */ busy?: () => ReadonlySet<string>; /** The per-project sweep (default {@link removeMergedWorktrees}). */ sweep?: (cwd: string) => Promise<MergedSweepResult>; } /** * Sweep every registered project's reclaimable worktrees (#1036), one turn per call. * * Says what it removed rather than removing it silently: a checkout vanishing from under someone * with no line explaining why reads as a bug, even when the work behind it is safe. */ export declare function startMergedWorktreeSweep(opts: MergedSweepOptions): MergedWorktreeSweep; //# sourceMappingURL=merged-worktrees.d.ts.map