export declare const ASSISTANT_STATUS_BOX_PREFIX = "\u250C\u2500 agent-"; /** * Scan a CC-style JSONL transcript for the `┌─ agent-` status-box prefix in * the most-recent assistant turn. Used by `turn.completed` events to populate * `status_box_present`. * * Cheap by default: caps the read at 256KB tailed from the file, since the * status box (if present) is always near the end of the most-recent turn. * Phase 2 doesn't try to fight the flush race: if the last assistant block * hasn't been written yet at Stop-hook time, status_box_present is `false` * and Phase 5 verdict path catches the race via a single retry. */ export declare function scanStatusBoxPresent(transcriptPath: string | undefined): boolean; /** * Scan a CC-style JSONL transcript for a needle in ASSISTANT message text * blocks only. Used by `turn.completed` to detect the suggested session name in the * reply. * * The row filter is load-bearing: the transcript tail also carries the needle * inside `tool_result` rows (the `agents set-task` JSON output) and hook * context rows, so a raw `includes()` over the tail — the way the status-box * scan works — would false-pass the moment set-task runs. Verified empirically * 2026-08-09 against a live transcript. * * Same 256KB tail window as the other scans; the window's first line may be a * truncated JSON row, which the per-line parse guard skips. */ export declare function scanAssistantTextIncludes(transcriptPath: string | undefined, needle: string): boolean; /** * Strict status-box evidence shared by turn telemetry and the Stop-time * continuation fallback. Both inputs are assistant-only surfaces: the JSONL * scanner rejects tool_result rows, while lastAssistantMessage comes directly * from the adapter's completed assistant response. */ export declare function scanAssistantStatusBoxPresent(transcriptPath: string | undefined, lastAssistantMessage: string | undefined): boolean; /** Most recent user-visible assistant text across Claude Code and Codex JSONL. */ export declare function scanLatestAssistantText(transcriptPath: string | undefined): string | undefined; /** * Verify that the first assistant message after the set-task result begins * with the exact session-name block. This is the Stop-time fallback for a * correctly displayed name followed by no further tool call. A name printed * after later work does not pass. */ export declare function scanSessionNameDisplayedImmediately(transcriptPath: string | undefined, name: string, startsWithBlock: (text: string, expectedName: string) => boolean): boolean; export type SessionNameDisplayInspection = { state: "present"; } | { state: "absent"; } | { state: "unavailable"; reason: "missing_transcript" | "transcript_not_ready"; }; /** * Inspect the ordered post-mint reply without conflating a malformed display * with an unreadable transcript. PreToolUse can enforce the former, while the * latter must remain an honest unsupported observation instead of deadlocking * every tool behind evidence the adapter has not persisted yet. */ export declare function inspectSessionNameDisplayImmediately(transcriptPath: string | undefined, name: string, startsWithBlock: (text: string, expectedName: string) => boolean): SessionNameDisplayInspection; /** * Resolve a transcript path at the adapter boundary. Windows-native Codex can * send `C:\...` while the managed hook executes inside WSL, where the same * file is mounted at `/mnt/c/...`. */ export declare function transcriptPathCandidates(transcriptPath: string | undefined): string[]; /** Runtime identity read from one transcript row: the model plus the tuning * values that row reported alongside it. */ export interface TranscriptRuntimeScan { model: string; /** CC stamps the effective effort level on each assistant row; absent when * the model has no effort dial (verified: haiku rows omit it entirely). */ effort?: string; /** CC reports the response speed tier inside `message.usage`. */ speed?: string; } /** * Resolve the agent's runtime identity from a CC-style JSONL transcript by * reading the most-recent assistant row. Claude Code's SessionStart payload * omits `model` and `effort` (Codex + Cursor supply model directly), so this * is the fallback that lets `session.started` / `turn.completed` populate * model and tuning once the transcript has at least one assistant turn. * * Model, effort, and speed are read from the SAME row, never independently: * effort varies with model inside one transcript (a mid-session model swap * changes both), so pairing the newest model with a separately scanned newest * effort can mislabel the session. * * Tail-reads the same 256KB window as the status-box scan and walks lines from * the end, returning the first row with a real model id. Synthetic * placeholders (``) and empty values are skipped. Returns undefined * when the transcript is missing/empty (e.g. a fresh session's first * SessionStart). */ export declare function scanTranscriptRuntime(transcriptPath: string | undefined): TranscriptRuntimeScan | undefined; /** * Detect the parent session of a forked CC conversation from its transcript. * * Empirical basis (verified 2026-08-05 against `claude --resume * --fork-session`): the fork copies the parent's rows into a new * `.jsonl`, rewriting every row's `sessionId` to the new id * but PRESERVING each copied message row's `uuid`. So a sibling transcript in * the same project directory that contains the fork's message uuids is an * ancestor of the fork. * * Ancestor vs. parent: a grandparent (when the parent was itself a fork) * shares the fork's early uuids too, but only the true parent contains the * whole copied prefix. At detection time the fork's transcript is almost * entirely copied prefix, so uuids sampled across the whole file separate the * two: score candidates by containment, highest wins. * * Sibling forks force a second rule: a PRIOR fork of the same parent also * contains the whole copied prefix, so it ties the true parent on score. The * sibling additionally carries its own post-fork turns, which the parent * lacks, so among tied scores the MINIMAL container (fewest message rows) * wins. A wrong pick under this rule stays within the ancestry (grandparent * at worst); a recency tie-break can name a non-ancestor sibling (observed * 2026-08-05 with two probes forked off one parent). * * Fail-soft by design: any read error, an unflushed transcript, or no * qualifying sibling returns undefined, which downgrades the caller to the * no-lineage behavior. Never throws. */ export declare function detectForkParent(transcriptPath: string | undefined, sessionId: string): string | undefined; //# sourceMappingURL=transcript.d.ts.map