import { type SessionStats } from './render.js';
import type { SessionEvent, SessionMeta } from './types.js';
/** One drawable step on a session's trajectory — a tool call or a thinking block. */
export interface TrajectoryStep {
    /** 1-based position among drawn steps, stable for `--errors-only` and step refs. */
    ordinal: number;
    kind: 'tool' | 'thinking';
    /** Tool name for `kind === 'tool'` (e.g. `Bash`, `Read`, `Task`). */
    tool?: string;
    /** The waterfall row this draws on — the tool name, or `think` for reasoning. */
    lane: string;
    /** Milliseconds from session start (the earliest event) to this step's start. */
    startMs: number;
    /**
     * Duration in ms. Measured by pairing this `tool_use` with its `tool_result`
     * on `callId`; when no paired result exists (or the harness omits `callId`),
     * falls back to the delta to the next event and sets `durationEstimated`.
     */
    durationMs: number;
    /** True when `durationMs` is the next-event fallback, not a measured pairing. */
    durationEstimated: boolean;
    /** Structured harness outcome from the paired result; never inferred from text. */
    outcome?: 'ok' | 'error' | 'unknown';
    /** Redacted one-line summary (command / path / subagent / pattern). */
    label: string;
    /** Redacted, bounded output/evidence snippet from the paired result. */
    detail?: string;
    /** An inline `Task`/`Agent` sub-agent branch (a cross-session teammate is lineage). */
    delegation?: 'inline-task' | 'teammate';
    /** Output tokens attributed from the nearest following usage event. */
    outputTokens?: number;
    /** Harness-native call identity, when present. */
    callId?: string;
    /**
     * For a shell tool call (`Bash`), the effective program the command actually
     * ran — `git`, `gh`, `agents`, `bun`, `sed`… — extracted by the shared shell
     * parser (`extractShellPrograms`, wrappers like `timeout`/`sudo`/`agents ssh`
     * unwrapped). Lets a Bash-dominated trajectory read by what it DID, not a wall
     * of "Bash". Undefined for non-shell tools or an unparseable command.
     */
    program?: string;
    /** Process exit code from the paired result (or the tool_use event), when the harness recorded one. */
    exitCode?: number;
}
/** An idle stall between two events — a candidate "where did it hang" marker. */
export interface TrajectoryGap {
    /** Milliseconds from session start to where the gap begins. */
    startMs: number;
    /** How long nothing happened, in ms. */
    durationMs: number;
    /** Ordinal of the last step before the gap (0 when the gap precedes step 1). */
    afterOrdinal: number;
}
/** The derived trajectory of one session. */
export interface SessionTrajectory {
    session: SessionMeta;
    /** Wall-clock span of the session in ms (last event − first event). */
    spanMs: number;
    steps: TrajectoryStep[];
    gaps: TrajectoryGap[];
    /**
     * Fraction of measured tool time per effective program, summing to ~1 (empty if
     * no time). Keyed by the same tag the step list and badges use — a shell call's
     * effective program (`git`, `bun`, `gh`), else the raw tool — so a Bash-heavy
     * session reads as `git / bun / gh`, never a single opaque `Bash`. The single
     * source both the HTML and text "where the time went" panels read.
     */
    programTimeShare: Record<string, number>;
    /**
     * Failed steps — steps whose paired result carried `outcome: 'error'`. Distinct
     * from `stats.errorCount`, which counts only standalone `type: 'error'` events;
     * a tool that failed via a `tool_result` outcome is invisible there but counted
     * here, so this is the truthful "how many calls failed" for the trajectory view.
     */
    errorCount: number;
    /** True when derived labels/details were secret-redacted (false under `--no-redact`). */
    redacted: boolean;
    /** Reused wholesale from `computeSummaryStats` — turns, tools, tokens, span. */
    stats: SessionStats;
    /** Steps dropped by the `maxSteps` cap, surfaced so truncation is never silent. */
    truncatedSteps: number;
}
export interface BuildTrajectoryOptions {
    /** Redact derived labels/details (default true; `--no-redact` is local-only). */
    redact?: boolean;
    /** Known secret values to mask, from `knownSecretValuesFromEnv()`. */
    knownSecrets?: readonly string[];
    /** A gap longer than this (ms) is recorded as an idle stall. Default 120000. */
    idleThresholdMs?: number;
    /** Cap on drawn steps; the tail is dropped and counted. Default 5000. */
    maxSteps?: number;
}
/**
 * The effective program a shell command ran, via the shared shell parser
 * (`extractShellPrograms` — which unwraps the wrappers it knows: `env`, `sudo`,
 * `agents ssh`; note `timeout` is deliberately NOT a wrapper there, per SES-37,
 * so `timeout 30 npm test` resolves to `timeout`). On top of that this skips
 * bare builtins/assignments (`cd`, `export`, …) when a real program follows. For
 * a pipeline it takes the LEFTMOST effective program (`cat f | grep x` → `cat`),
 * matching how the parser orders occurrences. Undefined when nothing static is
 * identifiable. Never executes anything.
 */
export declare function effectiveProgram(command: string | undefined): string | undefined;
/**
 * One paired step: the drawn {@link TrajectoryStep}, the index of its originating
 * `tool_use`/`thinking` event, and — once pairing completes — the index of the
 * `tool_result`/`error` event that answered it. `buildSessionDetailV2` reads these
 * triples (step, useEvent, resultEvent) to populate the schema-2 per-tool shapes
 * WITHOUT re-running the callId pairing loop.
 */
export interface StepDraft {
    step: TrajectoryStep;
    eventIndex: number;
    callId?: string;
    resultEventIndex?: number;
}
/** Absolute ms per event index (NaN when the timestamp is unparseable). */
export declare function eventTimestampsMs(events: SessionEvent[]): number[];
/**
 * Draw a step for each thinking block and each non-local tool_use, in order, and
 * pair each `tool_use` with its `tool_result`/`error` on `callId` (FIFO within a
 * reused id — never across ids, and never by arrival order for concurrent calls,
 * matching `ToolCallCollector.takePending`'s refusal to guess, `tool-calls.ts:509`).
 *
 * `_local` tool calls (Claude `!`-prefixed shell) are excluded to match the
 * header's tool count (`computeSummaryStats` skips them, `render.ts:224`).
 *
 * The single source of the pairing: both {@link buildTrajectory} and
 * `buildSessionDetailV2` consume the returned drafts (each draft's `eventIndex` +
 * `resultEventIndex` are the use/result event indices) so the schema-2 producer
 * never re-implements the loop. Durations/outcomes are still resolved by the
 * caller — this only draws and pairs.
 */
export declare function pairSteps(events: SessionEvent[], eventMs: number[], firstTs: number, redact: boolean, knownSecrets: readonly string[] | undefined): StepDraft[];
/**
 * Build the derived trajectory for one session's normalized events.
 *
 * Pairs each `tool_use` with its `tool_result`/`error` on `callId` (FIFO within a
 * reused id — never across ids, and never by arrival order for concurrent calls,
 * matching `ToolCallCollector.takePending`'s refusal to guess, `tool-calls.ts:509`).
 * A harness with no parseable transcript (OpenClaw, `parse.ts:186`) yields an empty
 * event array and therefore an empty trajectory — never a crash or a fabricated one.
 */
export declare function buildTrajectory(events: SessionEvent[], meta: SessionMeta, options?: BuildTrajectoryOptions): SessionTrajectory;
