Everything Claude Code remembers about your sessions lives in one folder on your machine: ~/.claude. Here's what's in it and how to use it without your scripts breaking on the next update.
The two files that matter
Transcripts live at:
~/.claude/projects/<project>/<session-id>.jsonl<project> is your working directory's path with every non-alphanumeric character replaced by -, so /Users/sam/code/checkout becomes -Users-sam-code-checkout. Each session is one file, and each line in it is a JSON object: a message, a tool call, a tool result, or metadata such as the session's generated title. Very long directory names are cut to 200 characters with a hash of the full path added.
Prompt history lives at:
~/.claude/history.jsonlOne line per prompt you typed: the text, a timestamp, the project path and the session ID. It powers the up arrow and Ctrl+R search. It is not deleted by the automatic cleanup, which makes it the longest-lasting record of what you worked on.
Everything else in ~/.claude
| Path | What it holds |
|---|---|
settings.json | Your user settings |
projects/<project>/memory/ | Auto memory for that project |
file-history/<session>/ | Copies of files before Claude edited them, used by rewind |
plans/ | Plans from plan mode |
paste-cache/, debug/, tasks/ | Per-session working files |
Transcripts and most per-session files are deleted after cleanupPeriodDays, 30 days by default. See why Claude Code sessions disappear for how to change that.
How to find a specific session
Inside Claude Code, /resume opens the session picker. Ctrl+A widens it to every project on the machine, Ctrl+W to every worktree of the current repo, and Ctrl+B filters to your current branch. Type to search, or paste a pull request URL to find the session that created it.
From the shell, sessions are ordinary files, so this lists every session changed in the last two days, across all projects (it works even with thousands of sessions, where ls with a wildcard fails):
find ~/.claude/projects -name '*.jsonl' -mtime -2Reading sessions from a script, safely
Anthropic's docs are direct about this: the transcript format is internal and changes between versions, so a script that parses the files can break on any release. The supported ways in are:
/export, which writes a readable transcript of the current conversation to a file.claude -p --output-format json, which returns a run's result, session ID, usage and cost as JSON.claude -p --resume <session-id> "summarize what we changed", which asks an existing session a question and returns the answer.- Hooks. Every hook receives a
transcript_pathfield, so aSessionEndhook can archive or index each transcript as the session closes.
If you do read the files directly, treat the format as something that will change: check for the fields you depend on and fail loudly when they're missing, rather than silently producing wrong results.
Moving it somewhere else
Set CLAUDE_CONFIG_DIR to move all of it off ~/.claude, for example onto an external drive or a synced folder. Set it in the shell that starts claude, since Claude Code reads it once at startup.
If you want all of this organized for you, Shabash reads these files on your Mac and turns them into threads of work per project, with what's done, what's open, and what you left unfinished.