import { getTranscriptArchiveRoot } from "./paths/paths.js";
import { type IndexEntry, type ProjectsRegistry, type RunManifest } from "./transcript-archive-types.js";
export interface ProjectIdentity {
    prefix: string;
    name: string;
    projectDir: string;
}
/**
 * Read `{prefix, name, projectDir}` from a `.forge/config.json`. Defaults on
 * any failure (missing file, malformed JSON, absent fields) — never throws.
 * `projectDir` is derived from the config path itself (`<dir>/.forge/config.json`).
 */
export declare function readProjectIdentity(configPath: string): ProjectIdentity;
/**
 * `<prefix>-<sha256(realpath(projectDir)).slice(0,8)>` — prefix alone can
 * collide across projects (two repos both named "FORGE"); the path hash
 * disambiguates. Falls back to the raw path when realpath throws (deleted
 * or unmounted project dir — archive entries must remain addressable).
 */
export declare function computeProjectKey(projectDir: string, prefix: string): string;
interface PhaseFileInfo {
    /** Absolute path to the project-local phase transcript JSON. */
    absPath: string;
    /** Basename, e.g. "20260601T100100Z__CART-BUG-001__triage.json". */
    file: string;
    /** Compact ISO prefix from the filename. */
    ts: string;
    /** Role segment from the filename (third "__" part onward). */
    role: string;
}
/** One discovered run: source files + the manifest built from them. */
export interface DiscoveredRun {
    runId: string;
    jsonlPath: string;
    phaseFiles: PhaseFileInfo[];
    /** Live tail-view logs (`*.tail.jsonl`) belonging to this run. */
    tailFiles: PhaseFileInfo[];
    manifest: RunManifest;
}
interface BuildOptions {
    /** Sprint back-reference stamped onto the manifest (run-sprint wiring). */
    sprintId?: string;
}
/**
 * Discover every run in a project-local entity transcript dir
 * (`.forge/transcripts/<entityId>/`) and build a RunManifest for each.
 *
 * A "run" is one orchestrator JSONL file; its runId is the compact-ISO
 * pipeline-start timestamp (falling back to the filename prefix). Phase
 * transcript files are assigned to the latest run whose start precedes
 * them — compact ISO prefixes compare lexicographically as timestamps.
 */
export declare function buildRunsForEntityDir(entityDir: string, identity: ProjectIdentity, projectKey: string, opts?: BuildOptions): DiscoveredRun[];
export interface ArchiveRunResult {
    archived: boolean;
    runDir?: string;
    error?: string;
}
export interface ArchiveRunOptions {
    /** Project dir (the dir containing `.forge/`). */
    cwd: string;
    /** Project-local orchestrator JSONL path for the run to archive. */
    orchestratorJsonlPath: string;
    /** Sprint back-reference for sprint-nested task runs. */
    sprintId?: string;
    /** Override for `<cwd>/.forge/config.json` (tests). */
    configPath?: string;
}
/**
 * Archive the run identified by its project-local orchestrator transcript.
 * Called by orchestrators after the pipeline result is known. Best-effort,
 * never throws.
 */
export declare function archiveRun(opts: ArchiveRunOptions): ArchiveRunResult;
export interface SweepResult {
    adopted: number;
    errors: number;
}
/**
 * Adopt orphans: archive every project-local run whose runId isn't in the
 * central index. Covers crash recovery (pipeline died before its archive
 * call) and adoption of pre-existing history (transcripts written before
 * this feature shipped). Called best-effort at pipeline start; never throws.
 */
export declare function sweepProjectTranscripts(cwd: string, configPath?: string): SweepResult;
/** Read index.jsonl — skips malformed/truncated lines, never throws. */
export declare function readIndex(): IndexEntry[];
/** Read projects.json — empty registry on any failure, never throws. */
export declare function readProjects(): ProjectsRegistry;
/** Read `<runDir>/manifest.json` — null on missing/truncated/mismatched. */
export declare function readManifest(runDir: string): RunManifest | null;
/**
 * Gunzip + parse an archived phase transcript. `file` is the manifest's
 * phase `file` field (without `.gz`). Null on any failure, never throws.
 */
export declare function gunzipPhase(runDir: string, file: string): Record<string, unknown> | null;
/** One persisted live tail-view line (see viewport/events.ts TailLogEntry). */
export interface ArchivedTailEntry {
    line: string;
    warning?: boolean;
}
/**
 * Gunzip + parse an archived live tail log (`*.tail.jsonl.gz`). Returns the
 * exact lines the dashboard rendered during the run, in order. Tolerant of
 * truncated tails; null when the file is missing/unreadable. Never throws.
 */
export declare function gunzipTailLog(runDir: string, file: string): ArchivedTailEntry[] | null;
/** Resolve the archive dir for an index entry. */
export declare function runDirForEntry(entry: IndexEntry): string;
/**
 * Per-turn digest of a gunzipped phase payload — never a raw JSON dump.
 * Each assistant message is a turn: first text line + tool-call names;
 * toolResult messages render as compact result markers.
 */
export declare function digestPhasePayload(payload: Record<string, unknown>): string[];
/**
 * VERBOSE digest of a gunzipped phase payload — the replay-dashboard feed.
 * Unlike digestPhasePayload (compact markers for the `show` table), this
 * carries the actual transcript content so a replayed run is readable:
 * full assistant text (capped per turn), thinking first-lines, tool-call
 * argument previews, and tool-result first-line previews.
 *
 * Multi-line assistant text is pushed as ONE entry — the dashboard splits
 * lines at display time, and the tree's per-entry char cap still applies.
 */
export declare function digestPhasePayloadVerbose(payload: Record<string, unknown>): string[];
export { getTranscriptArchiveRoot };
