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.

85 lines 4.79 kB
import { type LiveAgent, type AgentMeta } from '../store/index.js'; import type { ProjectSummary, ProjectionRead } from './projects.js'; import { type AgentHandoff } from './agent-handoff.js'; import { type PrLister } from './gh.js'; export { interventionKey } from './keys.js'; /** * One item awaiting the human. Two kinds: an open `pr` to review/merge or close, and an * `awaiting` run paused on a choice gate. The card, the browser hook, and the Discord watcher * all iterate the flat list, branching on `kind` for the fields that differ. */ export interface Intervention { projectId: string; projectName: string; /** * `pr` = an open PR to review/merge or close; `awaiting` = an agent paused on a choice gate (#636); * `unpushed` = a finished agent whose branch has commits that were never pushed (#860). */ kind: 'pr' | 'awaiting' | 'unpushed'; title: string; /** Where to act: the PR on GitHub (`pr`), or the dashboard (the other two, when the URL is known). */ url: string; /** The PR number (`pr` only). */ number?: number; /** The parked gate's id (`awaiting` only) — its stable identity, so it notifies exactly once. */ awaitId?: string; /** Which run this is about (`awaiting` #738 / `unpushed`): a project has several agents. */ agentId?: string; /** The branch the work is sitting on (`unpushed` only). */ branch?: string; /** How many commits are waiting (`unpushed` only). */ commits?: number; /** When the PR was opened (`pr`) or the agent last updated (the other two), ISO, for ordering. */ createdAt?: string; } /** Injectable seam so {@link buildInterventions} is unit-testable off disk. */ export interface InterventionsDeps { prs?: PrLister; /** The live-agent reader (default {@link readLiveMetas}); drives the `awaiting` source (#636). */ liveAgents?: (cwd: string) => Promise<LiveAgent[]>; /** The finished-agent reader (default {@link listAgents}); drives the `unpushed` source (#860). */ agents?: (cwd: string) => Promise<AgentMeta[]>; /** Reads a branch's state (default {@link readAgentHandoff}); drives the `unpushed` source (#860). */ handoff?: (cwd: string, branch: string) => Promise<AgentHandoff | undefined>; /** * How many of a project's most recent finished agents to inspect for unpushed work. Each one costs * a handful of git reads, and this runs on a poll, so old history is not re-walked every minute: * work that has sat unpushed for dozens of agents is not news, and the agent list stays the record. */ handoffLimit?: number; /** * The dashboard's own URL, so an `awaiting` item can link back to it. Only the daemon knows * it (the card path resolves the project client-side and needs no URL), so it is optional; an * awaiting item's `url` is empty when it is unset. */ dashboardUrl?: string; } /** * Build the cross-project interventions queue: every registered project's open PRs, plus any run * currently paused on a choice gate (#636), newest first. Forgiving — a project with no remote * (or an unreadable one) simply contributes nothing. Hand-opened draft PRs are excluded: they are * not yet asking for review. A session's own draft is not (#1102), because that is how * auto-handoff hands work back. * * Which projects were read whole comes back alongside the items (#1623): forgiveness here is what * lets one unreachable project keep the queue useful, and it is also what would let that project's * whole backlog announce itself as new the moment it came back. The queue's panels ignore this; * the notification watcher is the caller that cannot. */ export declare function buildInterventions(projects: ProjectSummary[], deps?: InterventionsDeps): Promise<ProjectionRead<Intervention>>; /** * How one intervention reads on Discord. Beside {@link Intervention} rather than inside the * watcher that posts it: it switches on every `kind`, so adding a kind is a change here, not in * a transport module that has no other opinion about what an intervention is. * * A PR reads `#123 Title — url`; a paused agent (#636) has no number and only the dashboard url, * so it reads `Title — awaiting your answer` with the link appended when the daemon knows it. * Unpushed work (#860) names the branch, since that is the actionable part. */ export declare function interventionLine(item: Intervention): string; /** * Post the given interventions to a Discord webhook as one message, resolving whether Discord * accepted it (#940). `fetch` is injectable for tests. */ export declare function postInterventionsDiscord(webhook: string, items: Intervention[], fetchImpl?: typeof fetch): Promise<boolean>; //# sourceMappingURL=interventions.d.ts.map