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.

132 lines 7.02 kB
import { type GitRunner } from './project.js'; /** * The maintenance sweep (#298): a background job that walks the registered repos, * finds the commits each repo has grown since its last maintenance review, and runs * the maintainability loop on them. Per-repo review state is a small local file * (`.the-framework/maintenance.json`, gitignored) recording the last-reviewed commit, * so a sweep only ever acts on new work. The capacity gate is the existing budget cap * (`--max-cost`). #298's "check the limit" half is reachable after all — the agent * reports the account's quota per turn (#517) and on demand (#521) — but this sweep * does not gate on it yet; that is #519's consumption limits. */ /** The per-repo review-state filename under `.the-framework/`. */ export declare const MAINTENANCE_FILE = "maintenance.json"; /** What a repo's last maintenance review recorded. */ export interface MaintenanceState { /** The HEAD commit the maintenance loop last reviewed (a full SHA). */ reviewedSha?: string; /** ISO timestamp of that review. */ reviewedAt?: string; /** * ISO timestamp of the last automatic codebase-wide sweep (#882). Deliberately separate * from {@link MaintenanceState.reviewedAt}: that one tracks how far the commit-delta sweep * (#298) has read, and this one paces a whole-codebase pass that ignores commits entirely. * Sharing a key would make either feature silently reset the other's schedule. */ sweptAt?: string; } /** * How long a repo is left alone between automatic codebase-wide sweeps (#882). * * A week, and deliberately not configurable: per #879 the answer to "should this have a * setting?" is no unless a setting earns itself. The sweep only queues follow-up entries and * only runs on an idle machine under its quota boundary, so the cost of it being a little too * eager is a backlog entry, not a bill. */ export declare const DEFAULT_MAINTENANCE_INTERVAL_MS: number; /** * Whether a repo is due an automatic sweep: never swept, or swept longer ago than the interval. * * A never-swept repo is due immediately, which is the case #882 exists for. The commit-delta * sweep (#298) treats a first-seen repo the opposite way, baselining it at HEAD so its whole * pre-existing history is never reviewed, and that is precisely the gap this closes. * * An unparseable timestamp counts as due: a repo whose state file was hand-edited into nonsense * should get swept, not fall silently out of the schedule forever. */ export declare function maintenanceDue(state: MaintenanceState, now: number, intervalMs?: number): boolean; /** Minimal fs seam so the state IO is unit-testable without touching disk. */ export interface MaintenanceFs { read(path: string): Promise<string>; write(path: string, contents: string): Promise<void>; mkdir(path: string): Promise<void>; } /** The review-state file path for a repo. */ export declare function maintenanceStatePath(cwd: string): string; /** Read a repo's review state. Forgiving: a missing/unreadable/malformed file yields `{}`. */ export declare function readMaintenanceState(cwd: string, fs?: MaintenanceFs): Promise<MaintenanceState>; /** Record a repo's review state, creating `.the-framework/` as needed. */ export declare function writeMaintenanceState(cwd: string, state: MaintenanceState, fs?: MaintenanceFs): Promise<void>; /** * Record part of a repo's state, leaving the keys not mentioned alone. * * Load-bearing since #882: {@link writeMaintenanceState} replaces the file wholesale, and two * features now write it. The commit-delta sweep (#298) writes `reviewedSha`/`reviewedAt` and the * automatic sweep writes `sweptAt`, so a wholesale write from either one would silently reset the * other's schedule. */ export declare function mergeMaintenanceState(cwd: string, patch: MaintenanceState, fs?: MaintenanceFs): Promise<void>; /** What the sweep decided for one repo. */ export type MaintenanceAction = 'baseline' | 'review' | 'skip' | 'error'; /** A repo's assessed maintenance status. */ export interface RepoReview { /** Registry id, when assessed from the registry. */ id?: string; /** Absolute repo path. */ path: string; /** Current HEAD SHA, when resolvable. */ headSha?: string; /** The last-reviewed SHA, when the repo has been reviewed before. */ reviewedSha?: string; /** Commits in `reviewedSha..HEAD` (0 for a first-seen or up-to-date repo). */ newCommits: number; /** What to do: baseline a first-seen repo, review new commits, skip an up-to-date one, or an error. */ action: MaintenanceAction; /** Context for an `error` or an unusual `review` (e.g. rewritten history). */ note?: string; } /** * Assess one repo: resolve HEAD, read its review state, and count the commits since * the last review. A never-reviewed repo is `baseline` (we record HEAD without * reviewing history retroactively); an unchanged repo is `skip`; new commits are * `review`. A non-repo / missing git is `error` (skipped, never throws). A reviewed * SHA git no longer knows (rebased away) falls back to `review`. */ export declare function assessRepo(path: string, git?: GitRunner, fs?: MaintenanceFs): Promise<RepoReview>; /** Assess every registered repo, tagging each review with its registry id. */ export declare function planMaintenanceSweep(repos: readonly { id?: string; path: string; }[], git?: GitRunner, fs?: MaintenanceFs): Promise<RepoReview[]>; /** The tally a sweep returns. */ export interface SweepSummary { reviewed: number; baselined: number; skipped: number; failed: number; /** Repos not reached because `maxRepos` was hit. */ pending: number; } /** Injected effects for {@link maintainSweep}, so the orchestration is testable off disk/process. */ export interface SweepDeps { /** Run the maintenance loop on a repo; resolves true on success. */ agent(review: RepoReview): Promise<boolean>; /** Persist a repo's review state (called after a baseline or a successful review). */ record(path: string, state: MaintenanceState): Promise<void>; /** Progress line. */ log(message: string): void; /** ISO timestamp for a recorded review (injected so runs are deterministic in tests). */ now(): string; /** Stop after reviewing this many repos in one sweep (baselines/skips don't count). */ maxRepos?: number; } /** * Orchestrate a sweep over pre-assessed reviews: baseline first-seen repos (record * HEAD, no run), skip up-to-date ones, and run the maintenance loop on the rest — * recording the reviewed SHA only when the agent succeeds, so a failure is retried next * sweep. Honors `maxRepos`; the remainder is reported as `pending`. */ export declare function maintainSweep(reviews: readonly RepoReview[], deps: SweepDeps): Promise<SweepSummary>; /** Short SHA for logs. */ export declare function short(sha: string | undefined): string; //# sourceMappingURL=maintenance.d.ts.map