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.

102 lines 5.31 kB
import { type GitRunner } from './project.js'; /** * Turn a plan's own verdict into queued work (#1334). * * The missing link in the autonomy chain. Tickets arrive from GitHub, [Spike & plan] costs them, * and the drain implements whatever is on the queue -- but nothing carried a plan's conclusion * onto that queue, so a ticket the planner had already judged trivial still waited for a triage * run to read the same ticket and reach the same conclusion a second time. * * The promotion is done here rather than by an agent because it is a decision the plan has * already made: reading two keys out of a file and appending a line needs judgement from nobody, * and spending a subscription turn to re-derive an answer already written down is the waste #879 * exists to avoid. It is the daemon that writes, for the reason queue-promote.ts gives: agents * stay sandboxed in their worktrees with no write access to the checkout. */ /** How much work the plan says the ticket is. */ export type PlanEffort = 'quick-win' | 'significant'; /** Whether the plan says there is anything left to decide. */ export type PlanConsensus = 'consensual' | 'open-questions'; /** The two keys a plan records about itself, absent when the plan did not say. */ export interface PlanVerdict { effort?: PlanEffort; consensus?: PlanConsensus; } /** * Read a plan file's verdict keys. * * Only the header is scanned -- everything above the first `##` section -- because that is where * the ticket format puts its keys, and because a plan that *discusses* quick wins in its prose * must not be read as declaring itself one. */ export declare function parsePlanVerdict(md: string): PlanVerdict; /** * Whether a plan authorises the drain to implement its ticket unattended. * * Fails closed, and demands both keys explicitly: the same polarity as `quotaHeadroom` (#879), * for the same reason. A plan that forgot to say, or said something this version does not * recognise, means a human decides -- not that an agent starts. */ export declare function isAutoImplementable(verdict: PlanVerdict): boolean; /** `tickets/<slug>.plan.md` for `tickets/<slug>.md`, and the read back. */ export declare function planPathFor(ticket: string): string; /** The ticket a plan belongs to, or undefined for a file that is not one. */ export declare function ticketForPlan(plan: string): string | undefined; /** A ticket's `Status:`/`Priority:`/title, as the queue needs them. */ export interface TicketHeader { title: string; priority: number; open: boolean; } /** * Read a ticket's header. Keys sit above the `# Title`, per the ticket format. * * A ticket with no `Status:` counts as open: the key is what a *closed* ticket is marked with, * and treating an unmarked one as closed would silently drop it out of the roadmap. */ export declare function parseTicketHeader(md: string): TicketHeader; /** The queue line for a planned ticket: the link, and nothing else. */ export declare function queueEntryFor(ticket: string, title: string): string; /** * Add an entry under its priority heading, creating the section when the file has none. * * Placement is the whole point rather than a nicety: `parseTodoEntries` returns entries in file * order and the drain takes the first, so an entry appended to the end of the file is the last * thing that would ever be worked -- which is the opposite of what "autonomously work on * quick-wins" asks for. Additive like `landPinnedEntry`, so it composes with whatever else is * mid-flight: it only ever inserts one line. */ export declare function insertQueueEntry(md: string, entry: string, priority: number): string; /** Everything the promotion reads and writes, injected so the policy above tests off disk. */ export interface PlanPromoteDeps { list?: (dir: string) => Promise<string[]>; read?: (path: string) => Promise<string>; write?: (path: string, content: string) => Promise<void>; git?: GitRunner; } /** What one promotion pass did. Never throws: this runs on a background tick. */ export interface PlanPromotion { /** The entries appended, in the order they were added. */ queued: string[]; /** Why nothing was queued, when nothing was. */ reason?: string; /** * Something stood in the way, as opposed to there simply being nothing to promote. * * The distinction is what keeps the daemon log readable: "no plan called its ticket a quick-win" * is the ordinary state of a healthy repo and would otherwise print on every tick of every * project forever, burying the one line that means a human should look. */ blocked?: true; } /** The commit message a promotion writes, naming the count so the history reads at a glance. */ export declare function plannedQueueMessage(count: number): string; /** * Queue every ticket whose plan declares itself a consensual quick-win and that is not on the * queue already (#1334). * * Skips wholesale on a dirty queue file, for the same reason `promoteQueue` does: a human editing * the queue by hand outranks an unattended tidy-up, and the next tick will try again. */ export declare function promotePlannedQuickWins(projectCwd: string, deps?: PlanPromoteDeps): Promise<PlanPromotion>; //# sourceMappingURL=planned-quick-wins.d.ts.map