Conversation
Attaching to a session that already had activity only showed the text of the current turn: tool calls, subagent spawns and earlier messages were pre-scanned for dedup and never emitted. - prepareBackfill() splits existing content: older turns are pre-scanned only, the last BACKFILL_TURNS (50) user turns are kept as raw lines. - replayLines() runs those lines through the normal live path, with the session clock pinned to each entry's timestamp (WatchedSession.replayNow), so durations and the timeline reflect real timing. Session start is set to the first transcript entry for the same reason. - Applies to both the VS Code watcher and the standalone relay. Codex already drained the full rollout on attach and is unchanged. - Audio stays quiet during a replay burst. Claude-Session: https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf
…ssion to new SSE clients - Session clock now starts at the first transcript line that carries a timestamp; ai-title/mode/summary lines have none, which left the clock at 'now', made elapsed() negative and collapsed every replayed event onto one instant in the frontend. - The relay replayed buffered events only for the most recent session on SSE connect, so every other tab opened empty. It now sends each session's buffer; the frontend already buffers per session and flushes on selection. Claude-Session: https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf
Real timestamps made a week-old session produce a 10000-minute timeline that was almost entirely dead time. Gaps between replayed entries longer than MAX_REPLAY_GAP_MS (30s) are now shortened to that length; the removed time is tracked in WatchedSession.compressedMs and subtracted by elapsed() for live events too, so the timeline stays continuous after the replay. Claude-Session: https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf
… live events
- The context_update emitted before the replay used an uncompressed elapsed()
('now' minus a days-old start), which pushed the frontend clock past every
replayed event and collapsed them again. It is now emitted after the replay.
- advanceClock() replaces the ad-hoc gap logic: it is called per replayed entry,
once at the end of the replay (gap between last entry and now), and whenever
live lines arrive, so idle pauses are compressed the same way live.
Claude-Session: https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf
Long sessions replay only the last BACKFILL_TURNS, but the clock starts at the first transcript timestamp; the gap up to the first replayed entry was never compressed because the compression clock had no previous event. Seed it at session start. Claude-Session: https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf
Audit findings applied: - lineTimestamp() now parses the top-level timestamp of user/assistant/ progress/system lines only. file-history-snapshot lines carry a nested, later timestamp that pinned the session start hours off and gave the whole replay negative times. - Replay clock never moves backwards (transcript lines are not strictly ordered) and advanceClock() ignores timestamps in the future. - elapsed() is monotonic per session so timer- and subagent-driven events cannot land before the last transcript event. - No per-line context_update during replay; one is emitted at the end. - The relay ships a replay as a single agent-event-batch frame instead of thousands of SSE messages that trickled onto the canvas like playback. - Buffer trimming keeps agent_spawn/subagent_dispatch/model_detected so a late client never receives events for unknown agents. - SSE frames carry ids; a reconnecting client (Last-Event-ID) gets only what it missed, or a reset when the relay was restarted, instead of duplicated history and doubled token totals. Claude-Session: https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Implements #77.
Attaching to a session that already had activity only showed the text of the current turn. This replays the last 50 user turns (
BACKFILL_TURNS) through the normal live path so tool calls, subagents and messages appear, with a real timeline.prepareBackfill()splits existing content: older turns are pre-scanned only (dedup + tokens), the tail is replayed viareplayLines().MAX_REPLAY_GAP_MS) are compressed, for replayed and live events alike.elapsed()is monotonic per session.context_updateat the end of the replay instead of one per line (they were 57% of the events).agent-event-batchframe; buffer trimming keeps spawn/model events; SSE frames carry ids so a reconnecting client (Last-Event-ID) only gets what it missed, or a reset when the relay restarted; every session's buffer is sent on connect, not only the most recent.Both the VS Code watcher and the standalone relay use the same helpers; Codex already drained the full rollout on attach and is unchanged. Known limitation: subagent transcripts already complete at attach time are pre-scanned only (spawn shown, inner tool calls not).
Pairs well with the frontend race fixes in the sibling PR (session switch / replay), which the longer event logs make more visible.
https://claude.ai/code/session_01AGs5TZo6yxv7NHARHawyJf