agent-flight-recorder
Every agent session you run disappears the moment it ends. This one doesn't.
A CLI that records every Claude Code and Codex session - prompts, tool calls, shell commands, file changes, errors and token costs into a searchable SQLite database. Find what you worked on, see what failed and extract reusable workflow patterns.
The problem this solves
AI coding sessions are opaque. When a session ends, all you have is changed files and a vague memory of what the agent tried. There's no way to answer:
- What tools did the agent call, and in what order?
- Which shell commands failed, and what was the error?
- How much did that session actually cost in tokens?
- Why does this same class of problem keep taking 3 sessions to fix?
afr records all of that and keeps it queryable - locally, permanently, without sending anything to a server.
Install
git clone https://github.com/AravindKurapati/agent-flight-recorder
cd agent-flight-recorder
pip install -e .
Requirements: Python 3.11+ - no API keys, no accounts, everything stays on your machine.
Usage
Ingest your sessions
afr ingest claude # reads ~/.claude/projects/**/*.jsonl
afr ingest codex # reads ~/.codex/sessions/**/*.jsonl
Or wire a Claude Code hook to ingest automatically after every session (add to ~/.claude/settings.json):
{
"hooks": {
"Stop": [{ "matcher": "", "hooks": [{ "type": "command", "command": "afr ingest claude" }] }]
}
}
Browse recent runs
afr list --days 7
Inspect a session
afr show 50c3f2a1
Search across all sessions
afr search "authentication"
afr search "modal" --days 30
Resume a session
afr list/afr search show an 8-char id prefix, but claude --resume needs the
full session id and must run from the directory the session started in. afr resume
resolves the prefix to the full id plus the recorded working directory and hands you
the exact command:
afr resume 6c84c429
# Session: 6c84c429-b7cb-4685-af6d-a318a2def2fc (claude)
# branch: main
# Resume with:
# cd "D:\Aru\NYU\prosper-podcast" && claude --resume 6c84c429-b7cb-4685-af6d-a318a2def2fc
afr resume 6c84c429 --run # launch it now instead of printing
An ambiguous prefix lists the matches so you can add characters. Codex sessions get a
codex resume <id> command instead. Sessions recorded before v0.2.0 backfill their
directory on the next afr ingest; if the original session file is gone, resume still
gives you the full id to run from the project directory yourself.
See patterns across sessions
afr stats --days 30
See your 5-hour usage windows
afr config set weekly-reset "Wed 00:00" # when your weekly cap resets
afr config set timezone "America/New_York" # your display timezone (IANA)
afr windows
afr windows reconstructs the Anthropic 5-hour usage windows you actually
opened (from recorded run timestamps) and shows how many fresh windows fit
before your weekly reset. This is the time/window view; for the token-budget
forecast, use claude-burnrate with /usage.
Export a session as markdown
afr export 50c3f2a1 # prints to stdout
afr export 50c3f2a1 --out report.md # writes to file
Valid outcomes: shipped, blocked, abandoned, exploratory
Extract reusable workflow skills
After a few sessions solving the same class of problem, run:
afr extract-skills --min-runs 3
Candidate: deployment-modal-debug
4 sessions | tools: Bash, Read | errors: 6
Generate SKILL.md? [y/n]: y
Written → generated_skills/deployment-modal-debug/SKILL.md
It clusters sessions by keyword similarity, finds ones that ended in shipped, and drafts a SKILL.md from the successful tool sequence. You approve before anything is written.
All commands
| Command | What it does |
|---|---|
afr ingest claude |
Parse ~/.claude/ sessions into the database |
afr ingest codex |
Parse ~/.codex/ sessions into the database |
afr list [--days N] |
Table of recent runs with goals, outcomes, and token in/out |
afr show <id> |
Full detail: tool calls, shell commands, errors, cost |
afr resume <id> |
Print (or --run) the command to resume a session in its original directory |
afr search <query> |
Full-text search across run goals and summaries |
afr stats [--days N] |
Outcome distribution, top tools, error counts |
afr tag <id> <outcome> |
Label a run: shipped / blocked / abandoned / exploratory |
afr export <id> [--out file] |
Export session as a markdown report |
afr extract-skills |
Cluster sessions, propose SKILL.md candidates |
<id> accepts the first 8 characters from afr list output.
What gets recorded
For each session:
- Goal - first user message
- Location - the working directory and git branch the session ran in (enables
afr resume) - Tool calls - every tool fired, input summary, success or error
- Shell commands - command, exit code, stdout/stderr excerpt
- File events - every read, write, patch, or delete
- Errors - failed tool calls and non-zero shell exits
- Token counts - input, output, cache read, cache write
- Outcome - you tag this:
shipped,blocked,abandoned,exploratory
Secrets are redacted before anything is written to the database (API keys, bearer tokens, private keys, .env contents).
How data is stored
Everything lives at ~/.afr/afr.db - a single SQLite file on your machine. No data leaves your machine.
You can query it directly with any SQLite client:
sqlite3 ~/.afr/afr.db "SELECT user_goal, outcome, tokens_in FROM runs ORDER BY started_at DESC LIMIT 10"
Supported agents
| Agent | Source | Adapter |
|---|---|---|
| Claude Code | ~/.claude/projects/**/*.jsonl |
Full - tool calls, tokens, errors |
| Codex (OpenAI) | ~/.codex/sessions/**/*.jsonl |
Full - tool name mapping, tokens, errors |
License
MIT
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agent_recorder-0.2.0.tar.gz.
File metadata
- Download URL: agent_recorder-0.2.0.tar.gz
- Upload date:
- Size: 276.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c4df157170ba0b232fa340ad0367184d2092939ca6a59853559c46926e78f074
|
|
| MD5 |
3a22eaa7a298b9dbed76e86dcaef27e8
|
|
| BLAKE2b-256 |
1fc0c3654e858ede1bff239d1d2834445b5704d58446289ee1718d49fbce5389
|
File details
Details for the file agent_recorder-0.2.0-py3-none-any.whl.
File metadata
- Download URL: agent_recorder-0.2.0-py3-none-any.whl
- Upload date:
- Size: 30.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
013ca2e7e27158d94ebb9f9ec84b87295ae0a5fc6425dd7a63598917ff063128
|
|
| MD5 |
80ea9abe2bcf32ffede87cda8b4817a0
|
|
| BLAKE2b-256 |
132a07ee425dcfffb41aa7d80580460f2aa10cbf74f5acf8e6b7dd22977b40aa
|