@phren/cli
Version:
Knowledge layer for AI agents - CLI, MCP server, and data layer
99 lines (98 loc) • 5.35 kB
TypeScript
import { type Json, type Provider } from "./protocol.js";
import type { ScheduleHarness, ScheduleRunOutcome } from "./schedule-format.js";
/** Watching a scheduled run in its Herdr pane: how it ended, whether the final
* reply asks the owner something, and a startup screen that blocked it. */
export declare const STARTUP_BLOCK_WINDOW_MS = 90000;
export declare const STARTUP_BLOCK_WINDOW_OPEN_MS = 5000;
export declare function classifyStartupBlock(input: {
elapsedMs: number;
transcriptActive: boolean;
status: unknown;
lines: readonly string[];
}): string | undefined;
/** The watch loop's own words for a failure, instead of assuming Herdr went away. */
export declare function watchFailureReason(error: unknown): string;
interface StartupWatch {
source: ScheduleHarness;
startedAt: number;
sessionId?: string;
onBlocked?: (promptText: string) => void | Promise<void>;
/** The prompt went to a session that was already idle, whose transcript
* looked like this beforehand. Idle ends the run only once the pane was
* seen busy or the transcript moved; otherwise it is the turn not started. */
continued?: {
transcript?: {
size: number;
mtimeMs: number;
};
};
}
/** How long a continued session may sit idle without taking up the prompt. */
export declare const CONTINUED_TURN_START_MS = 120000;
export interface StartupWatchEnv {
now?: () => number;
pause?: (ms: number) => Promise<void>;
readPane?: (server: string, paneId: string) => Promise<string[]>;
resolveSession?: (server: string, pane: Json) => Promise<string | undefined>;
transcriptStamp?: (source: ScheduleHarness, sessionId: string | undefined) => Promise<{
size: number;
mtimeMs: number;
} | undefined>;
panes?: (server: string) => Promise<Json[]>;
finalTurn?: (source: ScheduleHarness, sessionId: string | undefined) => Promise<FinalTurn | undefined>;
}
/** `error`: the harness ended the turn on an error (Codex's usage limit) instead of a reply.
* `interrupted`: the owner stopped the last turn (Claude's "[Request interrupted by user]",
* Codex's turn_aborted); the harness sends no Stop for it.
* `background`: Claude Code background tasks (shells, subagents, monitors) started in
* the transcript's tail with no task-notification or TaskStop ending them yet.
* `finishedTasks`: when each Claude background task the tail shows finishing
* finished (its first final task-notification's timestamp), one per task.
* `awaited`: those of the running tasks that are shells or monitors started
* since the owner's last prompt, or started before it and looked at since
* (its output read, its id named), other than streams that never end (a log
* tail, a watcher, a dev server). Sub-agents are left to the child tree.
* `endless`: the running shells that are such streams. */
export interface FinalTurn {
completed: boolean;
lastAssistant?: string;
error?: string;
interrupted?: boolean;
background?: number;
finishedTasks?: string[];
awaited?: number;
endless?: number;
}
/** The public text of one assistant row, without reasoning or tool output. */
export declare function publicAssistant(raw: Json, source: Provider): string | undefined;
/** How a Claude usage-limit error starts, so dispatch can tell it from any other failure (account-failover.ts). */
export declare const CLAUDE_USAGE_LIMIT = "Claude usage limit:";
export declare const isClaudeUsageLimit: (error: string | undefined) => boolean;
/** Claude Code background work a transcript line starts or ends, by task id:
* a backgrounded Bash call, an async subagent or a Monitor start one; a
* task-notification with a final status, or a TaskStop, ends it. A
* persistent monitor runs for the whole session and is never waited on.
* `finished` keeps when each task's first final notification was written.
* A notification reaching an idle session is written as a queue-operation
* row, and may stay there with no new turn to deliver it. */
/** A backgrounded command that runs until killed rather than finishing:
* following a log, watching files, serving a dev build. Nobody waits on it. */
export declare const ENDLESS_COMMAND: RegExp;
/** The last assistant reply in a transcript and whether its turn finished.
* A person's message after the reply opens a new turn, so it clears both. */
export declare function finalTurnFromLines(lines: readonly string[], source: ScheduleHarness): FinalTurn;
/** The final turn of a conversation, read from the tail of its transcript. */
export declare function readFinalTurn(source: ScheduleHarness, sessionId: string | undefined): Promise<FinalTurn | undefined>;
/** When a finished reply ends by asking the owner something (a question, or
* numbered options introduced as a choice), the question's first line. */
export declare function ownerQuestion(text: string): string | undefined;
export declare function realTranscriptStamp(source: ScheduleHarness, sessionId: string | undefined): Promise<{
size: number;
mtimeMs: number;
} | undefined>;
export declare function watchHerdrRun(server: string, target: {
workspaceId: string;
tabId: string;
paneId: string;
}, signal: AbortSignal, startup: StartupWatch, env?: StartupWatchEnv): Promise<ScheduleRunOutcome>;
export {};