import type { AgencyConfig } from "../config/config.js"; import { runViewer, type ViewerResolution } from "../logsViewer/run.js"; import type { ViewerThresholds } from "../logsViewer/thresholds.js"; import { type Trace } from "../runDirectory/traces.js"; import { type ParseResult } from "../statelog/parse.js"; import { type CommentsStore } from "../runDirectory/commentsStore.js"; import { type Source } from "../runsExplorer/sources.js"; import type { RunRow } from "../runsExplorer/rows.js"; import type { InputSource } from "../tui/input/types.js"; import type { OutputTarget } from "../tui/output/types.js"; export type LogsViewOpts = { follow?: boolean; csv?: boolean; /** Open the viewer on this trace (a full id or unique prefix) instead of * the trace picker. The other traces stay reachable with `t`. */ traceId?: string; config?: AgencyConfig; }; /** Injectable route targets, so routing is testable without a TTY. */ export type LogsViewDeps = { viewFile?: (file: string, opts: LogsViewOpts) => Promise; viewRunDirectory?: (dir: string, opts: LogsViewOpts) => Promise; explorer?: (options: ExplorerTerminalOptions) => Promise; loadAll?: (sources: Source[]) => RunRow[]; stdout?: (text: string) => void; onError?: (message: string) => void; }; export declare function logsView(filesArg: string | string[], cliOpts?: LogsViewOpts, deps?: LogsViewDeps): Promise; /** * The full id of the trace `--trace-id` names in a run directory, whose traces * are already read, checked before the terminal is set up so a miss prints as * plain text instead of flashing the viewer. A unique prefix is accepted, as * `agency logs extract` accepts one. Returns `"none"` when the flag was not * given; reports and returns `"missing"` when no trace matches, so the caller * can stop. For a statelog file the viewer checks the id instead, against the * log it reads. Exported for its test. */ export type FocusTrace = { kind: "none"; } | { kind: "trace"; id: string; } /** Reported through `onError` already; the caller stops. */ | { kind: "missing"; }; export declare function resolveFocusTrace(traces: readonly Trace[], idOrPrefix: string | undefined, onError: (message: string) => void): FocusTrace; type ExplorerTerminalOptions = { sources: Source[]; thresholds?: Partial; }; export type ViewerTerminalInput = "current-stdin" | "controlling-tty"; /** What the one viewer host runs: a parsed log held in memory (with the * input-source choice) or a local file with follow. */ type ViewerSource = ({ kind: "events"; parsed: ParseResult; terminalInput: ViewerTerminalInput; } | { kind: "file"; followPath: string; initialFollow: boolean; /** Set when the file is a run directory's statelog: one summary line * of annotations per trace id, shown on the trace rows. */ traceAnnotations?: Record; comments?: CommentsStore; }) & { thresholds?: Partial; focusTraceId?: string; }; type ViewerTerminalDependencies = { createInput(): InputSource; createOutput(): OutputTarget; swapStdinToTty(): () => void; runViewer: typeof runViewer; viewport(): { rows: number; cols: number; }; }; /** @internal Test seam for the viewer's terminal lifecycle; production consumers * use `openViewer` / `logsView`. This is the ONE owner of terminal * construction, the stdin→TTY swap, viewport, `runViewer`, and cleanup, and it * releases every acquired resource exactly once — combining a primary and any * cleanup errors rather than swallowing them. It also owns SIGINT/SIGTERM (the * output is created without its own interrupt handlers), so an external signal * runs the SAME release path — output, input, and stdin restore — before * exiting, rather than the output's teardown alone. */ export declare function createViewerHost(dependencies: ViewerTerminalDependencies): (source: ViewerSource) => Promise; /** Open the interactive statelog viewer on a log already parsed in memory. * `remote logs` passes `current-stdin` (stdin is intact after an HTTP fetch); * the piped local `view -` passes `controlling-tty` (stdin was drained for the * data). */ export declare function openViewer(opts: { parsed: ParseResult; terminalInput: ViewerTerminalInput; thresholds?: Partial; }): Promise; /** Parse a statelog as it streams in, one chunk of lines at a time, so its * text is never one string. */ export declare function parseStatelogStream(stream: AsyncIterable): Promise; export {};