feat(relay): read conversation history from agent transcripts
An agent TUI runs on the alternate screen, so herdr keeps no scrollback for it (max_offset_from_bottom is 0 on every agent pane here), and the one read that does reach older rows costs ~31ms per line and visibly scrolls the operator's terminal. History now comes from the transcript the agent writes for itself, keyed by the agent_session ref on the pane record. The session uuid never crosses the wire: clients send a pane_id and the relay resolves it through pane_session_map. relay/transcript.py locates the file by session uuid (a glob, 0.7ms -- deriving the path from the pane's cwd is wrong, because claude fixes its project directory at its own startup cwd and the two drift), parses claude's JSONL into turns, pages backwards from the newest, and caches parsed turns rather than raw bytes (33MB of JSONL is 0.25MB of turns; cold 227ms, warm 1ms). Remote panes are read over SSH in one round trip using only ls/wc/tail/head, and the relay hands the far side the size it already has, so paging a remote pane usually moves no bytes -- at the cost of remote history being recency-bounded, which file_truncated says out loud. Two things the real files forced: - rows get replayed (591 of 2602 in one session here, same uuid, same content), so they are deduped by row uuid; otherwise every turn renders twice and a turn uuid cannot serve as a pagination cursor - 200-turn pages measured 97KB to 324KB of JSON, so a page is bounded by characters as well as by turns, with the remainder reachable through has_more The panes the relay reports now carry title, scrollback and has_session, which is what lets a client know a pane has a transcript to ask for.
N
Nick007 committed
ed9a4fee07acbcaa0cdcd25c42805cc1d9fb8fe6
Parent: 37b478d