Show a replayed session's images instead of dropping them

An imported session showed no screenshots. `text_of` kept only `text`
blocks, so every image in the replayed tail was silently discarded -- while
the *live* translator has always saved them into the session's `files/` and
referenced them. Two readings of the same records, and the one used for
history was the lesser.

`save_image` moves out of `Translator` to a free function both paths call,
since the naming scheme for that directory should exist once. `events_from`
now takes the session directory to write into, which means the conversion
has to happen where that directory exists -- so `Seed` carries the raw
JSONL and `launch` turns it into events, rather than `routes` doing it
before the session is created.

Costs nothing in tokens, which is the point worth recording: this writes
into ai-app's own session directory and the phone fetches a reference only
when it draws one. Nothing here is ever written to the CLI's stdin -- it
reads its own session file, and the only things this app sends it are typed
messages, control requests and `/compact`.

Verified against the 133 MB session behind the 2026-08-29 incident: 45
images in the replayed tail, written as real PNGs and served over the files
route, with the transcript itself staying at 756 KB of references.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VETa8afmpWaYezLCqJhDB8
This commit is contained in:
irisandClaude Opus 5 committed 2026-08-29 05:01:48 -04:00
1 parent d96bc041a7
commit d7c692a4ec
6 files changed
+148 -50

No files matched your search

+5
View File
@@ -41,6 +41,11 @@ repo is in PLAN.md's "Backend layout" section.
`POST /setups`. Only the tail is replayed (`REPLAY_LINES`) because these
files reach tens of megabytes and the CLI reads the real one itself; what
crosses the tunnel is what a person reads, not what the model is given.
Images in the replayed tail are written into the session's `files/` by
the same function the live translator uses, and referenced -- so a
screenshot looks the same whether it was watched happening or replayed
afterwards, the phone fetches the bytes only when it draws one, and none
of it goes anywhere near the CLI, which reads its own file.
An imported session then **keeps itself level with that file**, so work
done at a terminal appears without anyone pressing anything. `--resume`
appends to the same transcript rather than forking — measured, but