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.
55 lines • 2.8 kB
TypeScript
/**
* Tails an append-only JSONL log, calling `onLine` for each complete line as it
* is written. Reads only the bytes appended since the last {@link pull},
* buffering a torn trailing line until its newline arrives. A file that shrinks
* (a fresh agent truncated the log) resets to the start so the new content is
* picked up. The generic base behind the daemon's event tail and the agent's
* control tail (#344) — one tailer, two directions.
*/
export declare class JsonlTailer<T> {
private path;
private readonly onLine;
private offset;
private partial;
private lastMtimeMs;
private adoptMtime;
constructor(path: string, onLine: (value: T) => void);
/**
* Point the tailer at the journal's new home, keeping the read offset. For a log that is
* *relocated with its content intact* — an agent's `events.jsonl` is copied verbatim into the
* archive at teardown (and restored on a continuation) — the bytes already consumed are a
* prefix of the new file, so the next {@link pull} delivers exactly the lines the move would
* otherwise have swallowed, without replaying what was already delivered.
*
* The first pull after a retarget adopts the new home's mtime instead of running the
* same-length-rewrite check: the copy is younger than the original by construction, and a
* fully-consumed journal would otherwise read as "rewritten to the same length" and replay
* every line it already delivered.
*/
retarget(path: string): void;
/** Read and dispatch any lines appended since the previous call. */
pull(): Promise<void>;
}
/** Options for {@link followFile}. */
export interface FollowFileOptions {
/** How often the backstop poll runs. */
pollMs: number;
/**
* Let the process exit with the tail still running (steering must never hold it open).
* Covers both handles this opens — the poll timer *and* the `fs.watch` — since either one
* on its own is enough to keep the event loop alive.
*/
unref?: boolean;
}
/**
* Drive a {@link JsonlTailer} as the file grows: an `fs.watch` on `dir` for latency, plus a
* poll backstop because `fs.watch` is unreliable across platforms. Pulls are serialized (a
* pull already in flight swallows the next trigger) and stop for good once the returned
* function is called. Shared by the agent's control tail and the dashboard's event tail, which
* hand-rolled this separately and drifted apart.
*
* Nothing here may throw at the process: a failed pull and a watcher error are both survivable,
* and the poll alone is a complete tail (#996).
*/
export declare function followFile(dir: string, pull: () => Promise<void>, opts: FollowFileOptions): () => void;
//# sourceMappingURL=jsonl-tail.d.ts.map