UNPKG

@phren/cli

Version:

Knowledge layer for AI agents - CLI, MCP server, and data layer

142 lines (141 loc) • 6.73 kB
import type { SchedulePush, SchedulePushResult } from "./push.js"; /** The schedules.yaml store: the schedule and run record shapes, validation, * the five timing forms evaluated in local time, and the run history file. */ export declare const SCHEDULE_EVERY: readonly ["interval", "daily", "weekly", "once", "cron"]; export declare const SCHEDULE_HARNESSES: readonly ["claude", "codex", "opencode", "copilot"]; export declare const SCHEDULE_NOTIFY: readonly ["start", "finish", "failure"]; export declare const WEEKDAYS: readonly ["sun", "mon", "tue", "wed", "thu", "fri", "sat"]; /** `new` starts a session per firing; `reuse` types the prompt into the schedule's last session while it is still open. */ export declare const SCHEDULE_SESSIONS: readonly ["new", "reuse"]; export type ScheduleEvery = typeof SCHEDULE_EVERY[number]; export type ScheduleHarness = typeof SCHEDULE_HARNESSES[number]; export type ScheduleNotify = typeof SCHEDULE_NOTIFY[number]; export type Weekday = typeof WEEKDAYS[number]; export type ScheduleSession = typeof SCHEDULE_SESSIONS[number]; export declare const SCHEDULE_RUN_STATUSES: readonly ["launched", "running", "blocked", "finished", "needs-you", "failed", "skipped"]; export type ScheduleRunStatus = typeof SCHEDULE_RUN_STATUSES[number]; /** How a run ended: done, done but waiting on the owner's answer, or not done. */ export interface ScheduleRunOutcome { status: "finished" | "needs-you" | "failed"; reason?: string; } export interface Schedule { id: string; name: string; enabled: boolean; computer: string; harness: ScheduleHarness; model?: string; /** Claude account id (a slug) the run uses; absent means the default account. */ account?: string; notify?: ScheduleNotify[]; /** Explicit targets; absent means the directory owning this schedule. */ projects?: string[]; /** Absent means `new`. */ session?: ScheduleSession; every: ScheduleEvery; at?: string; days?: Weekday[]; interval?: string; once?: string; cron?: string; prompt: string; createdAt: string; updatedAt: string; [key: string]: unknown; } export interface ScheduleLaunchRecord { mode: "herdr" | "headless"; workspaceId?: string; tabId?: string; paneId?: string; sessionId?: string; server?: string; jobDir?: string; /** The prompt went to the schedule's earlier session instead of a new one. */ reused?: boolean; } export interface ScheduleRun { id: string; scheduleId: string; project: string; scheduleProject?: string; batchId?: string; startedAt: string; finishedAt?: string; status: ScheduleRunStatus; reason?: string; blockedStartupPrompt?: string; blockNotified?: boolean; notified?: boolean; notifyReason?: string; launch: ScheduleLaunchRecord; } export interface ScheduleLaunchResult { launch: ScheduleLaunchRecord; completion?: Promise<ScheduleRunOutcome>; /** Nothing was started: the reused session was busy, for this reason. */ skipped?: string; } export interface ScheduleLaunchContext { schedule: Schedule; project: string; projectDir: string; cwd: string; runId: string; /** With `session: reuse`, the panes this target's earlier runs used, newest first: the newest still open is continued. */ reuse?: ScheduleLaunchRecord[]; blockedStartup?: (promptText: string) => void | Promise<void>; } export type ScheduleLauncher = ((context: ScheduleLaunchContext) => Promise<ScheduleLaunchResult>) & { close?: () => void; /** Follows a run a previous Hook process launched and never saw finish. */ resume?: (run: ScheduleRun, schedule: Schedule) => Promise<ScheduleRunOutcome>; }; export interface SchedulePushSender { notify(value: SchedulePush): Promise<SchedulePushResult>; } export interface ScheduleStatus extends Schedule { project: string; nextRun: string | null; lastRun: Omit<ScheduleRun, "id" | "scheduleId" | "project"> | null; lastRuns: ScheduleRun[]; running: boolean; /** Whether this computer owns the schedule: it runs it and answers Run now. */ owned: boolean; /** Why this schedule can never fire, when something is wrong with its computer or source paths. */ problems?: string[]; } interface ScheduleDocument { document: Record<string, unknown>; schedules: Schedule[]; } export declare const runningStatuses: Set<"blocked" | "failed" | "finished" | "launched" | "needs-you" | "running" | "skipped">; export declare function intervalMilliseconds(value: string): number; export declare function parseSchedule(value: unknown): Schedule; export declare function readScheduleDocument(projectDir: string): Promise<ScheduleDocument>; /** Synchronous I/O for writers sharing a lock with synchronous store routes. */ export declare function readScheduleDocumentSync(projectDir: string): ScheduleDocument; /** Hold `<project>/schedules.yaml.lock` (one holder per file, in this process and * across processes) for one read, check and write, so two edits never * overwrite each other. */ export declare function withScheduleLock<T>(projectDir: string, work: () => T | Promise<T>): Promise<T>; export declare function writeScheduleDocument(projectDir: string, schedules: Schedule[], original?: Record<string, unknown>): Promise<void>; export declare function writeScheduleDocumentSync(projectDir: string, schedules: Schedule[], original?: Record<string, unknown>): void; export declare function canonicalComputer(value: string): string; export declare function computerMatches(wanted: string, current: string): boolean; export declare function scheduleNotifications(schedule: Schedule): Set<ScheduleNotify>; export declare function scheduleSessionRoute(schedule: Schedule, launch: ScheduleLaunchRecord): string | undefined; export declare function nextRun(schedule: Schedule, lastRun?: ScheduleRun): Date | null; /** Summarize the newest firing of one owner's schedule, including old single runs. */ export declare function latestScheduleBatch(runs: ScheduleRun[]): { lastRun: ScheduleRun | undefined; lastRuns: ScheduleRun[]; }; /** The distinct Herdr panes a target's runs used, newest first, which `session: reuse` continues (the newest still open) and tidies (the older finished ones). */ export declare function reusableLaunches(runs: readonly ScheduleRun[]): ScheduleLaunchRecord[]; export declare function readScheduleRuns(file: string): Promise<ScheduleRun[]>; export declare function writeScheduleRuns(file: string, runs: ScheduleRun[]): Promise<void>; export declare function newScheduleId(existing: Iterable<string>): string; export declare function scheduleRunsFile(): string; export {};