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.
130 lines • 6.56 kB
TypeScript
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