import { formatBytes } from '../format.js';
export { formatBytes };
import type { SessionMeta } from '../session/types.js';
export type ArtifactKind = 'screenshot' | 'pdf' | 'recording' | 'download';
export interface BrowserArtifact {
    kind: ArtifactKind;
    /** Owning task for session captures; undefined for downloads. */
    task?: string;
    name: string;
    path: string;
    bytes: number;
    mtimeMs: number;
}
export interface ProfileArtifacts {
    profile: string;
    artifacts: BrowserArtifact[];
}
/** Every capture for one profile, newest first. */
export declare function listProfileArtifacts(profile: string): BrowserArtifact[];
/**
 * Captures grouped by profile. With `only` set, returns just that profile (even
 * when empty); otherwise every profile dir on disk that has at least one capture.
 */
export declare function listBrowserSessions(only?: string): ProfileArtifacts[];
/** Per-kind counts over a flat artifact list — shared by the printed table and
 *  the interactive row labels. */
export declare function countByKind(artifacts: BrowserArtifact[]): Record<ArtifactKind, number>;
/** Human table for the CLI. Returns lines (no trailing newline). */
export declare function renderBrowserSessions(groups: ProfileArtifacts[]): string;
/**
 * Resolve `--open <sel>`: `latest` (newest across the groups) or a filename
 * substring match. Returns the absolute path, or null if nothing matched.
 */
export declare function resolveArtifact(groups: ProfileArtifacts[], selector: string): string | null;
/** The identity fields this module cares about for one task. */
export interface TaskIdentity {
    owner?: string;
    launchId?: string;
    /**
     * The agent session that drove the task. Primary identity: it is carried by
     * every agent process, whereas a launch id is present on a minority of them.
     * Sourced from the durable `browser_sessions` row, which survives task stop —
     * `tasks.json` never records it beyond the task's own lifetime (RUSH-2549).
     */
    sessionId?: string;
}
/**
 * Read a profile's `tasks.json` for the identity of its CURRENTLY LIVE tasks,
 * keyed by task name. A task's entry is deleted on `agents browser stop` (see
 * service.ts `saveTaskState`), so a task whose run has already ended is absent
 * here even though its captures remain on disk — that is exactly the
 * "unlinked legacy task" case {@link groupIntoRows} reports. Same read-straight-
 * from-disk approach as the rest of this module: works whether or not the
 * browser daemon is running.
 */
export declare function loadTaskIdentities(profile: string): Map<string, TaskIdentity>;
/**
 * Identity for one profile's tasks, durable copy first.
 *
 * `browser_sessions` is the source of truth: it is written at task start and
 * never deleted, so it answers for tasks that have already stopped — the case
 * `tasks.json` structurally cannot, since `saveTaskState` rewrites that file
 * from the LIVE task map. The live file is still merged on top for a task that
 * is running right now, so a task started by an older CLI (no DB row yet) keeps
 * whatever identity it does have rather than regressing to nothing.
 */
export declare function loadDurableTaskIdentities(profile: string): Map<string, TaskIdentity>;
/** launchId -> indexed session id, built once from every source that records
 *  this join, so a task-heavy profile resolves without re-scanning per task. */
export interface LaunchSessionIndex {
    byLaunchId: Map<string, string>;
}
/**
 * Build the launchId -> sessionId index from the same three sources
 * `feed-post.ts` `resolvePostIdentity` already uses for this exact problem —
 * a browser task's `launchId` IS the `AGENT_LAUNCH_ID` of the CLI run that
 * called `agents browser start` (see service.ts `resolveTaskIdentity`), so
 * resolving "which session ran this launch" is the same join, not a new one.
 * Lowest-confidence source first so a later, more specific source overwrites
 * it on a collision:
 *  1. the activity log (durable, but least specific — read last)
 *  2. the SessionStart hook's live-session index (kept for parity with
 *     `hook-sessions.ts`; empty on this fleet today, harmless when so)
 *  3. the per-pid launch registry (`ag run`, launch-scoped, most authoritative)
 * Computed once per interactive session, not per row.
 */
export declare function buildLaunchSessionIndex(): LaunchSessionIndex;
/** Resolve one launchId through the index to its canonical `SessionMeta`, or
 *  `null` when the join has no hit or the resolved session isn't indexed here. */
export declare function resolveLaunchSession(index: LaunchSessionIndex, launchId: string): SessionMeta | null;
/** Why a row carries no session digest: `linked` resolved one, `unresolved`
 *  has a launchId but no matching indexed session, `unlinked` has no launchId
 *  at all (a legacy task, or one whose owning run already stopped). */
export type BrowserSessionLinkStatus = 'linked' | 'unresolved' | 'unlinked';
/** One task-first row: every capture for one browser task (or, for
 *  `kind: 'downloads'`, one profile's downloads bucket), plus the agent
 *  session it links to when resolvable. */
export interface BrowserSessionRow {
    kind: 'task' | 'downloads';
    profile: string;
    /** Task name; undefined for the downloads row. */
    task?: string;
    owner?: string;
    launchId?: string;
    /** The agent session that drove the task, when one was recorded. */
    sessionId?: string;
    linkStatus: BrowserSessionLinkStatus;
    linkedSession?: SessionMeta;
    /** Newest first. */
    artifacts: BrowserArtifact[];
    counts: Record<ArtifactKind, number>;
    /** Most recent capture's mtime — the row's sort/age key. */
    latestMtimeMs: number;
}
/**
 * Group flat per-profile artifacts into task-first rows, newest first. Pure:
 * identities and the launch resolver are passed in, so this has no filesystem
 * or session-index dependency and is unit-testable with synthetic data (see
 * {@link buildBrowserSessionRows} for the impure disk/index-reading caller).
 */
export declare function groupIntoRows(groups: ProfileArtifacts[], taskIdentities: Map<string, Map<string, TaskIdentity>>, resolveLaunch?: (launchId: string) => SessionMeta | null, resolveSession?: (sessionId: string) => SessionMeta | null): BrowserSessionRow[];
/** Build task-first rows for one profile (or every profile with captures),
 *  reading `tasks.json` and resolving launchIds against the live indexes.
 *  The interactive picker's data source. */
export declare function buildBrowserSessionRows(profile?: string): BrowserSessionRow[];
/**
 * Search predicate for the interactive picker: task name, profile, the linked
 * session's agent/topic/label, and any artifact filename in the row.
 */
export declare function matchesBrowserSessionRow(row: BrowserSessionRow, query: string): boolean;
/**
 * Shared CLI action for `agents browser sessions` and `agents sessions --browser`.
 * `open` is the Commander value for `--open [selector]`: undefined when the flag
 * is absent, `true` when passed bare (defaults to 'latest'), or the selector string.
 */
export declare function runBrowserSessions(opts: {
    profile?: string;
    open?: string | boolean;
    json?: boolean;
}): Promise<void>;
