(
filePath: string,
opts?: { keepAllLeaves?: boolean },
)
| 3470 | * Returns the messages, summaries, custom titles, tags, file history snapshots, and attribution snapshots. |
| 3471 | */ |
| 3472 | export async function loadTranscriptFile( |
| 3473 | filePath: string, |
| 3474 | opts?: { keepAllLeaves?: boolean }, |
| 3475 | ): Promise<{ |
| 3476 | messages: Map<UUID, TranscriptMessage> |
| 3477 | summaries: Map<UUID, string> |
| 3478 | customTitles: Map<UUID, string> |
| 3479 | tags: Map<UUID, string> |
| 3480 | agentNames: Map<UUID, string> |
| 3481 | agentColors: Map<UUID, string> |
| 3482 | agentSettings: Map<UUID, string> |
| 3483 | prNumbers: Map<UUID, number> |
| 3484 | prUrls: Map<UUID, string> |
| 3485 | prRepositories: Map<UUID, string> |
| 3486 | modes: Map<UUID, string> |
| 3487 | worktreeStates: Map<UUID, PersistedWorktreeSession | null> |
| 3488 | fileHistorySnapshots: Map<UUID, FileHistorySnapshotMessage> |
| 3489 | attributionSnapshots: Map<UUID, AttributionSnapshotMessage> |
| 3490 | contentReplacements: Map<UUID, ContentReplacementRecord[]> |
| 3491 | agentContentReplacements: Map<AgentId, ContentReplacementRecord[]> |
| 3492 | contextCollapseCommits: ContextCollapseCommitEntry[] |
| 3493 | contextCollapseSnapshot: ContextCollapseSnapshotEntry | undefined |
| 3494 | leafUuids: Set<UUID> |
| 3495 | }> { |
| 3496 | const messages = new Map<UUID, TranscriptMessage>() |
| 3497 | const summaries = new Map<UUID, string>() |
| 3498 | const customTitles = new Map<UUID, string>() |
| 3499 | const tags = new Map<UUID, string>() |
| 3500 | const agentNames = new Map<UUID, string>() |
| 3501 | const agentColors = new Map<UUID, string>() |
| 3502 | const agentSettings = new Map<UUID, string>() |
| 3503 | const prNumbers = new Map<UUID, number>() |
| 3504 | const prUrls = new Map<UUID, string>() |
| 3505 | const prRepositories = new Map<UUID, string>() |
| 3506 | const modes = new Map<UUID, string>() |
| 3507 | const worktreeStates = new Map<UUID, PersistedWorktreeSession | null>() |
| 3508 | const fileHistorySnapshots = new Map<UUID, FileHistorySnapshotMessage>() |
| 3509 | const attributionSnapshots = new Map<UUID, AttributionSnapshotMessage>() |
| 3510 | const contentReplacements = new Map<UUID, ContentReplacementRecord[]>() |
| 3511 | const agentContentReplacements = new Map< |
| 3512 | AgentId, |
| 3513 | ContentReplacementRecord[] |
| 3514 | >() |
| 3515 | // Array, not Map — commit order matters (nested collapses). |
| 3516 | const contextCollapseCommits: ContextCollapseCommitEntry[] = [] |
| 3517 | // Last-wins — later entries supersede. |
| 3518 | let contextCollapseSnapshot: ContextCollapseSnapshotEntry | undefined |
| 3519 | |
| 3520 | try { |
| 3521 | // For large transcripts, avoid materializing megabytes of stale content. |
| 3522 | // Single forward chunked read: attribution-snapshot lines are skipped at |
| 3523 | // the fd level (never buffered), compact boundaries truncate the |
| 3524 | // accumulator in-stream. Peak allocation is the OUTPUT size, not the |
| 3525 | // file size — a 151 MB session that is 84% stale attr-snaps allocates |
| 3526 | // ~32 MB instead of 159+64 MB. This matters because mimalloc does not |
| 3527 | // return those pages to the OS even after JS-level GC frees the backing |
| 3528 | // buffers (measured: arrayBuffers=0 after Bun.gc(true) but RSS stuck at |
| 3529 | // ~316 MB on the old scan+strip path vs ~155 MB here). |
no test coverage detected