Version, replay, and audit AI agent sessions — locally.
Privacy warning: agent transcripts can contain credentials, personal information, source code, private prompts, and tool output. compactdiff redacts common secret fields, tokens, email addresses, phone numbers, and home-directory usernames by default before writing snapshots or exports. Redaction is defense-in-depth, not a guarantee: inspect every replay before sharing it and keep the vault directory private.
The problem: there is no good way to version, replay, or audit AI agent sessions. Claude Code (and similar agents) persist sessions as JSONL, but compaction rewrites them in place, there is no version history, no replay UI, and no way to hand a session to someone else.
| Capability | Implementation |
|---|---|
| Record (local file watcher) | watch polls Claude Code projects and ~/.codex/sessions/**/*.jsonl by default; every changed transcript is snapshotted into a content-addressed vault (~/.compactdiff). Compaction can never destroy history — every observed state is kept, idempotently. |
| Version | list shows every session's version chain (sha · time · lines). |
| Audit | diff <shaA> <shaB> proves what a rewrite removed: verdict append-only vs history-rewritten with occurrence-aware ordered line counts (including duplicates and blank lines), keyed on line uuid when present. integrity_chain gives a tamper-evident fingerprint. |
| Replay (timeline UI) | export -o replay.html writes a single self-contained HTML file: dark timeline of semantic events (user / assistant / thinking / tool calls), j/k stepping, click to expand. No server, no external assets. |
| Share | The replay HTML is the share artifact — send one file. |
| Branch | branch --at N -o fork.jsonl writes an inspectable truncated prefix after N conversational messages. Codex developer bootstrap records are preserved but do not consume branch numbers. It does not promise direct Codex/Claude resume. |
# install from this local checkout
python3 -m pip install -e .
# record continuously (Claude Code + Codex sessions)
compactdiff watch
# or snapshot one transcript now
compactdiff snapshot ~/.claude/projects/<proj>/<session>.jsonl
compactdiff list
compactdiff diff <shaA> <shaB> # what compaction removed
compactdiff export <file|sha> -o replay.html
compactdiff branch <file|sha> --at 12 -o fork.jsonlRequires Python 3.9+. Zero runtime dependencies — Python stdlib only. Run tests:
python3 -m pytest tests/ -q (23 tests) or
python3 -m unittest discover -s tests.
- Redaction is on by default for
snapshot,watch,export, andbranch. - Default vault registries store only each source file's basename, not its full home-directory path.
- Raw mode requires both
--no-redactand the explicit--i-understand-sensitive-dataacknowledgement. Put both global flags before the subcommand. Raw vaults and exports may contain secrets. - Session IDs, prose, uncommon credential formats, and proprietary content may still be sensitive even after pattern redaction. Never publish a replay without a human review.
The offline demonstration is already generated at demo/demo_replay.html; its
static screenshot is demo/demo_replay.png. Regenerate the HTML locally with:
python3 -m compactdiff.cli export demo/demo_session.jsonl -o demo/demo_replay.html- Claude Code JSONL (
~/.claude/projects/<encoded-cwd>/*.jsonl): each user/assistant/system content block is an event; other records staymeta. - Codex-native JSONL (
~/.codex/sessions/**/*.jsonl): visibleresponse_itemmessages, reasoning summaries, tool calls, and tool results are events. Mirroredevent_msgrecords and runtime-only token/context state are intentionally not duplicated into the replay. - Nerve Codex runner logs (
nerve/logs/codex/*.log): explicitTASK,STDOUT, and non-emptySTDERRsections map to user, assistant, and tool/runtime-result events. The wrapper does not retain individual internal tool calls, so compactdiff does not invent them by splitting physical lines.
Bad JSON lines are counted in skipped, never silently swallowed. Pass
--pattern to replace the default Claude Code + Codex coverage with one glob.
- CLI + HTML shell, not an Electron app. The pitch's best form is a desktop app; v1 proves the core (vault / audit / replay / branch) as a pure, headless-testable engine — same cut as the DocSource MVP (engine first, shell thin). An Electron/Tauri wrapper is additive later.
- Polling watcher (5s), not FSEvents; sync/team workspaces/Cursor sqlite ingestion deferred.
- Branch files are faithful redacted prefixes for inspection or caller-managed seeding; direct resume by Codex/Claude is not yet claimed or automated.
<100 signups/beta users in 30 days → kill.
MIT