[Side Project] Two hours of agent work in 35 seconds: building sessionreel
Loading comments...
Loading comments...
Hand a bug to an agent and two hours later it's done: tests pass, the commit is pushed. Then you try to show a teammate or your manager how it was fixed, and you're stuck, because all you have is a 30 MB session log.
There are already tools that display sessions: claude-replay, mindwalk, claude-code-log, zoetrope. They're all viewers. The other person has to open a link, scroll and dig. Nobody does.
So I built the opposite. Instead of asking people to come to the session, it makes something you send. sessionreel reads the session log and renders a 30–60 second mp4.
1uvx sessionreel
pip install sessionreel / uvx sessionreel/plugin marketplace add mandu5/sessionreel → /reelClaude Code writes every session to ~/.claude/projects/: prompts, the agent's messages, every tool call and its result, and even the diff hunks the Edit tool records. Everything a video needs is already there.
The pipeline has four stages.
"Why not give the log to an LLM and ask for a summary video?" That was my first thought too. But this is a video people will post publicly; a single untrue scene ruins it. So the story engine is deterministic and every caption is built from numbers in the log.
Deterministic isn't the same as honest, though. I ran an independent reviewer agent against 29 real sessions, and it found:
ruff check A.py and a passing ruff format B.py became "fixed". A full run with 5 failures followed by a narrowed -k empty run with 1 pass was shown as "5 failed → 1 passed". → Pair only the same check with the same selectors (paths, -k, -m), and never accept a green run that narrowed the scope.N passed, All checks passed, …).git commit, or running grep "git push", produced a "Shipped" scene; so did git push --dry-run. → Split shell lines into segments, treat heredoc bodies as data, and judge only at the start of a segment. A local commit is captioned "Committed", not "Shipped".None of these showed up on synthetic test data. They only appeared on real logs. A green test suite built on synthetic fixtures means little until you run real input through it.
Session logs contain everything: reads of .env, emails in commit messages, tokens printed in terminals. Redaction runs on the whole parsed session before the storyboard exists, so later stages never see the originals.
The review still found holes:
/Users/name). The username and hostname survived via Claude Code's project folder names (-Users-name-…), differently-cased paths, and shell prompts like name@hostname ~ %, and one hostname contained another person's name.{"api_key": "…"}, mysql -p and curl -u user:pass were missing from the patterns.There were mistakes in the other direction too. Treating auth as a secret word wiped the name from author: Name and mangled Co-Authored-By:. Over-redact and the video is unreadable; under-redact and a key ends up on X. I kept tuning until a sweep of all 29 real sessions left 0 secrets on screen and the confirmed over-redactions (long file names, LaTeX's \if@…, @ in agent ids) were carved out. It is still pattern-based, which is why the README says: watch it before you post it.
A fun footnote: the moment the repo went public, GitGuardian emailed "8 secrets detected". They were the fake keys in the redaction tests (abcdefgh…, AWS's documented example key). To test a secret detector you need strings that look like secrets, and to another detector they are secrets. The test strings are now assembled at runtime.
--lang ko switches the captions.--format tall) and narration with the OS voice (--voice, macOS say); no cloud TTS.What stuck with me most wasn't a technique but a stance: when a tool speaks for its user, it should say only as much as the evidence supports. That goes for pass counts, for "fixed", and for "shipped".
There are 146 tests and CI on macOS and Ubuntu × Python 3.10 and 3.13. Codex session logs are next. If a reel shows a scene that looks wrong, please open an issue.