Your AI Tool Already Saved Your Session to Disk — Here's Where to Look When You Need It Back
If your AI coding assistant just deleted the wrong files, blew away your working branch, or forgot the plan you spent forty minutes shaping, you are not empty-handed. Cloud AI tools already write a full transcript of every session to a documented path on your own disk — Claude Code, OpenAI's Codex CLI, Cursor, Gemini CLI, GitHub Copilot CLI, and Aider all do it.
This tutorial is the vendor-neutral discipline for finding those files, backing them up before they are auto-swept, and treating them like any other note. It is the output-side companion to yesterday's input-side piece, Keep the raw prompt you sent your AI — together they close the loop on owning the record of your session. All paths were verified against vendor primary docs on 2026-07-02.
The story that made this obvious for a lot of people was posted to Hacker News on 2026-02-27 by a developer named Rikkert ten Klooster.1 Claude Code, working through a symlink it did not understand, had run rm -rf against real directories inside their Obsidian vault. Their backup had not run for a month.
But the whole session — every file Claude had ever read, edited, or written — was still sitting in ~/.claude/projects/ as JSONL. They wrote a recovery tool over the weekend and shipped it.2 Five months later, at least five separate public tools read the same file location. The discipline is not a same-day novelty; it is a five-month sustained ecosystem.
The one idea: the receipt is the note
Every "cloud" AI coding assistant listed in this post runs a local process on your machine. That process writes what it did — every prompt, every tool call, every file it touched, every model response — to a documented file on your disk.
Anthropic's own Claude Code docs describe the artifact as a "Full conversation transcript: every message, tool call, and tool result."3 Simon Willison, writing about the same files, calls them "an invaluable record of the decisions that went into building features."4
Yi Huang, writing on databunny, is more specific: "Claude Code stores a complete, machine-readable transcript of every session as structured JSONL files on your local disk. Not summaries. Not logs. The full message-by-message record: tool calls with their exact inputs and outputs, extended thinking blocks, subagent spawning events, token usage per turn, model selection, working directory, git state snapshots — everything."5
The receipt is the note. That reframes the workflow. You do not need a separate "session capture" plugin or a paid history feature — the artifact already exists, in a plain, greppable format, on the disk you already back up. The rest of this post is the map of where each vendor writes it, plus the discipline for surviving the day the file matters. Related philosophy: The only record of what your agent did is the agent's own session.
Tool-by-tool: where the session file lives
Every tool below writes a session artifact to a documented on-disk path — most as line-delimited JSON, one as Markdown, one as a server-side ZIP you request. This section is the vendor-by-vendor map, verified against primary docs on 2026-07-02, with the platform overrides (Windows %USERPROFILE%, CLAUDE_CONFIG_DIR, CODEX_HOME, COPILOT_OTEL_FILE_EXPORTER_PATH) called out where they matter.
Claude Code — ~/.claude/projects/<project>/<session>.jsonl
Anthropic documents the location and the content plainly. From their code.claude.com/docs/en/claude-directory reference: sessions live at a "Path under ~/.claude/ … projects/<project>/<session>.jsonl … Full conversation transcript: every message, tool call, and tool result."3 A second, adjacent file is worth knowing about — ~/.claude/history.jsonl, described as "Every prompt you've typed, with timestamp and project path. Used for up-arrow recall."6 The transcript is per-session; the history is your prompt log across sessions and is kept indefinitely.
Platform detail matters here. Anthropic's docs state: "On Windows, ~/.claude resolves to %USERPROFILE%\.claude. If you set CLAUDE_CONFIG_DIR, every ~/.claude path on this page lives under that directory instead."7 So the honest tour is:
- macOS / Linux:
~/.claude/projects/<project>/<session>.jsonland~/.claude/history.jsonl. - Windows:
%USERPROFILE%\.claude\projects\<project>\<session>.jsonland%USERPROFILE%\.claude\history.jsonl. - Any OS: if
CLAUDE_CONFIG_DIRis set, both trees live under that directory instead.
Third-party tooling that also reads these files — for recovery, for cost analysis, for browsable transcripts — confirms the shape. From the claude-JSONL-browser README: "Claude Code CLI automatically saves all your conversations in JSONL format at ~/.claude/projects/."8 From Rikkert ten Klooster's claude-file-recovery README: "Claude Code stores a full log of every tool call in ~/.claude/projects/. This tool parses those transcripts, replays Write, Edit, and Read operations in order, and reconstructs the files so you can browse, search, and extract them."1
One landmine worth flagging up front: a widely-cited Medium piece by Yi Huang uses the sub-path sessions/<session-uuid>.jsonl.5 Anthropic's own live doc does not use a sessions/ intermediate — the path is projects/<project>/<session>.jsonl. Trust the vendor primary. When two secondaries disagree, the primary wins.
OpenAI Codex CLI — ~/.codex/sessions/ and ~/.codex/archived_sessions/
Codex's on-disk shape is documented in two places that agree. OpenAI's own configuration reference describes the transcript-saving setting: "session_transcripts — save-all | none — Control whether Codex saves session transcripts to history.jsonl."9 The ccusage project, which maintains a mature open-source Codex adapter, ships the concrete paths in code: sessions and archived sessions live under ~/.codex/sessions and ~/.codex/archived_sessions, with the environment variable CODEX_HOME overriding both.10 So on a fresh Codex install:
- Current rollouts:
~/.codex/sessions/. - Archived rollouts:
~/.codex/archived_sessions/. - Both roots move if you export
CODEX_HOME=/some/other/path.
If you have session_transcripts set to none, this directory will be empty or truncated on new work — that is the setting to check first when the file is missing.
Cursor — ~/.cursor/projects/**/*.jsonl
Cursor's own docs sit behind a JavaScript SPA that does not publicly enumerate this path. The best public confirmation is the siteboon/claudecodeui providers spec, which supports Cursor as a session source: "~/.cursor/projects/**/*.jsonl — Uses sibling worker.log to recover workspacePath, then derives the session title from the first user prompt."11
The path is well-attested across the ecosystem (multiple tools read from it), but it is not, as of 2026-07-02, a documented Cursor primary. Verify against your own install with find ~/.cursor -name '*.jsonl' 2>/dev/null. On Windows, adapt the tilde to %USERPROFILE%\.cursor\projects.
Gemini CLI — ~/.gemini/tmp/**/*.jsonl
Gemini CLI stores session artifacts under a tmp/ directory. From the claudecodeui providers spec: "~/.gemini/tmp/**/*.jsonl — Current full scans only index temp JSONL chat artifacts. Single-file sync also accepts legacy .json files."12
The word tmp is doing serious work here — a tmp/ tree is exactly the kind of directory a helpful cleanup script or an OS reboot might wipe. Treat Gemini's session file as ephemeral by default. If a session matters, copy the JSONL out of ~/.gemini/tmp/ and into a place you actually back up before you close the shell.
GitHub Copilot CLI — ~/.copilot/otel/**/*.jsonl
Copilot CLI is the odd one out. Where the tools above write full conversation transcripts, Copilot's on-disk artifacts are OpenTelemetry event streams — JSONL, still greppable, but records of what happened, not verbatim assistant text. From the ccusage Copilot adapter: JSONL is written under ~/.copilot/otel/, and the env variable COPILOT_OTEL_FILE_EXPORTER_PATH overrides that root.13 So the honest expectation is:
- Location:
~/.copilot/otel/(or whereverCOPILOT_OTEL_FILE_EXPORTER_PATHpoints). - Content: telemetry events, one JSON object per line, useful for auditing what tools were invoked and what token costs accrued — not a "replay the conversation" transcript.
This is the tool where the answer to "can I recover what the assistant said?" is honestly "less than you can with Claude Code." Grep still helps; expectations do not.
Aider — .aider.chat.history.md (per repo)
Aider is the outlier in the other direction. It is open source, its history format is Markdown, and it writes into your repository — not a hidden home directory. Its options docs document the defaults: --input-history-file defaults to .aider.input.history; --chat-history-file defaults to .aider.chat.history.md; and --llm-history-file, unset by default, "records the raw content of all the messages sent by aider to the LLM" when turned on.
If Aider detects it is inside a git repository, those files are written into the repo root; otherwise they land next to the current working directory.14 A normal Aider workflow is already producing a per-repo Markdown chat log — the least ceremony of any tool in this list, and the format needs no conversion.
ChatGPT (web) — no local JSONL; a server-side export
ChatGPT web is not a CLI, and it does not write a session file to your disk. What it offers instead is a formal data export: from OpenAI's Help Center, the flow is Settings → Data Controls → Export data. OpenAI then emails a download link, "usually within a few hours but sometimes up to 7 days," and the download link "will expire 24 hours after you receive it."15
It is a different mechanism — server-side, zipped, and time-boxed — but it is the equivalent artifact for a web-only assistant. See Own your AI chat history for the full walk-through.
Back it up before the auto-sweep
Finding the file is half the discipline; keeping it long enough to matter is the other half. Anthropic's docs are explicit about what happens if you do nothing: "Files in the paths below are deleted on startup once they're older than cleanupPeriodDays. The default is 30 days."16
Thirty days is generous compared to no history at all and stingy compared to how long an interesting decision matters. The history.jsonl prompt log is not covered by this sweep; the per-session transcripts are.
The discipline is the one you already know from every other kind of note. Steph Ango, the CEO of Obsidian, wrote it as an ownership principle: "File over app is a philosophy: if you want to create digital artifacts that last, they must be files you control, in formats that are easy to retrieve and read. Use tools that give you this freedom. … Apps are ephemeral, but your files have a chance to last."17
The session JSONL is a file you control, in a format that is easy to read. It qualifies. Extend the same backup discipline you already have — Time Machine, restic, borg, or a plain cp -a into your notes vault — to ~/.claude/projects/, ~/.codex/sessions/, ~/.codex/archived_sessions/, ~/.cursor/projects/, ~/.gemini/tmp/, ~/.copilot/otel/, and any repo containing an .aider.chat.history.md. That is the whole practice.
A 3-minute rescue script you can copy
If you need to recover a lost file, the whole rescue is four short commands: find the JSONL, copy it somewhere permanent, grep it for the missing file, and — if a lot was deleted at once — replay the Write and Edit operations with an open-source tool. The transcripts are structured, greppable, and mostly already on your disk. This section is that recipe.
The one command that answers "does the file exist and where":
find ~ -maxdepth 6 -name '*.jsonl' 2>/dev/null | \
grep -Ei '(claude|codex|cursor|gemini|copilot|aider)' | \
xargs -I{} ls -lh {}
That prints every JSONL in your home tree owned by one of the tools, with size and mtime, in one screen. From there:
- Copy the recent ones out to somewhere permanent:
cp -a ~/.claude/projects/<project>/ ~/notes/ai-sessions/claude/<date>/. - Grep for the file you lost:
grep -l 'the-lost-file-name' ~/notes/ai-sessions/claude/**/*.jsonl. - Replay Write/Edit operations with
claude-file-recoveryif a lot was deleted at once — Rikkert ten Klooster's tool does exactly this from the JSONL.1 - Convert to something you will re-read — Simon Willison's
claude-code-transcriptsrenders the JSONL as browseable HTML transcripts,4 andclaude-code-logrenders the same tree as HTML plus Markdown.
None of that requires anything but files that were already on your disk.
An honest limits section (what this discipline does NOT do)
Owning the session file is a receipt discipline, not an insurance policy. It gives you a local audit trail that outlives the vendor's live UI, but it does not delete the provider's server-side copy, encrypt the plaintext on disk, or defeat every default cleanup. Four hard limits are worth naming before you rely on this in a crisis.
- Local receipt is not a private receipt. The JSONL on your disk records what the assistant did on your machine. The provider processed the request on their servers and has their own copy, subject to their retention and training policies. Reaching a file you own does not delete or block what OpenAI or Anthropic already have. Sibling reading: the vendor-defaults piece Turn off the training.
- The transcripts are plaintext at rest. Whatever you told the assistant, the raw
.jsonlstill contains — including anything you assumed was private inside the UI. Treat the file with the same care you would treat the underlying notes; if you drop a session into a shared vault, redact first. Sibling: Secrets do not belong in notes an AI reads. - "Recovery" is best-effort, not guaranteed. Recovery works against what was written to disk before the auto-sweep, in a format the tool understands. Anthropic's default is 30 days.16 Gemini's
tmp/directory can be swept sooner. Copilot CLI writes telemetry events, not full assistant text.13 Set expectations honestly: this is a receipt discipline, not an insurance policy. - Paths drift with vendor releases. Every path in this post was verified 2026-07-02. Vendors change layouts. The durable practice is the search command above, not any single string; run it once a quarter and you will notice a rename the day it happens.
Common mistakes
Five things people get wrong the day they actually need to recover a session — worth reading before you need to, because most of them are architectural, not fixable in the moment. The pattern across all five is the same: assume the session file is more permanent, more private, or more complete than it actually is, and then find out it is not when a live session has already overwritten the clue you needed.
- Waiting past the 30-day sweep. Claude Code's default
cleanupPeriodDaysis 30. If you thought "I will grab that transcript next week" and it has been six weeks, the file is gone. Copy the folder now.16 - Trusting
tmp/. Gemini CLI writes sessions to~/.gemini/tmp/**/*.jsonl.12 Some cleanup scripts and reboots wipetmp/. If the session matters, copy it out before the shell closes. - Confusing memory with per-session transcript. A vendor "memory" is persistent, cross-conversation context (see Copy your AI memory into a file you own). A transcript is one file per session. Different artifacts; back up both, and know which is which.
- Assuming Copilot's JSONL is a transcript. Copilot CLI writes OpenTelemetry events — a receipt of what happened, not a replay of what was said.13 Set expectations before you need to recover.
- Publishing a raw transcript without redacting. The JSONL contains every prompt and file the assistant touched — including secrets you accidentally put into source notes. Before you drop a session into a public gist, redact first.
Frequently asked
Seven questions readers actually ask — three drawn verbatim from the Hacker News thread that started the story, two from the ecosystem tools that read the same files, and two from OpenAI and Cursor's own most-searched help queries. Each answer points back into the section above, so a skimmer can jump straight to the paths and skip the theory.
Where does Claude Code save my sessions on disk?
~/.claude/projects/<project>/<session>.jsonl on macOS and Linux; %USERPROFILE%\.claude\projects\... on Windows; anywhere CLAUDE_CONFIG_DIR points if you have set it.37 The adjacent ~/.claude/history.jsonl is your rolling prompt log.6
Doesn't /rewind do this?
No. The /rewind command reverts state inside a live session; the JSONL files persist across sessions and let you recover files the live session has already discarded — including work from sessions you closed hours or days ago.
If it doesn't, why are those files kept in .claude?
They are kept, but not forever. Anthropic's default cleanupPeriodDays is 30, at which point they are deleted on startup.16 Back them up before the sweep.
Could snapshots via tmutil be used to protect against this on macOS?
Yes. Time Machine snapshots of your home tree pick up ~/.claude/, ~/.codex/, and friends alongside every other note. Any point-in-time backup with the same reach — restic, borg, cp -a, ZFS snapshots — works the same way. Back the folder up like any other note.
How do I export my ChatGPT history and data? Settings → Data Controls → Export data. OpenAI emails a download link, usually within a few hours, up to 7 days; the link expires 24 hours after it arrives.15 The mechanism is server-side, not a local JSONL. Details: Own your AI chat history.
Where does Cursor store chat history?
The best public answer today is ~/.cursor/projects/**/*.jsonl, verified via the open-source claudecodeui provider spec11; Cursor's own docs do not publicly document this path. Confirm against your install with find ~/.cursor -name '*.jsonl'.
How much am I spending on Claude Code?
Same source, different tool. ccusage reads the same ~/.claude/projects/**/*.jsonl you would grep for a lost file and turns it into per-day and per-project cost totals. The session file is doing double duty.
The one-line practice
The vendor-neutral discipline compresses to one line worth memorizing: know where your assistant writes the session, back that folder up like any other note, and grep it like any other note. The receipt is a plain file. The tool that wrote it is optional. The folder on your disk is what makes the record yours.
Rikkert ten Klooster wrote the recovery tool because his backup had not run for a month; Simon Willison wrote the transcript viewer because the file already had every decision in it; Steph Ango wrote the philosophy years earlier — apps are ephemeral, files have a chance to last.1741 The tools change. The practice does not: name the file, own the folder, and treat every session as the note it already is.
MNMNOTE keeps its own notes as plain Markdown on your own device — the same file-over-app discipline this post recommends for your session logs. mnmnote.com
Footnotes
-
Rikkert ten Klooster,
claude-file-recoveryREADME (v1, MIT), 2026-02-25.https://github.com/hjtenklooster/claude-file-recovery/blob/main/README.md. ↩ ↩2 ↩3 ↩4 -
Rikkert ten Klooster (
rikk3rt), "Show HN: Claude-File-Recovery," Hacker News item 47182387, 2026-02-27.https://news.ycombinator.com/item?id=47182387. ↩ -
Anthropic, "Explore the .claude directory," Claude Code Docs — Path under
~/.claude/…projects/<project>/<session>.jsonl… Full conversation transcript. Accessed 2026-07-02.https://code.claude.com/docs/en/claude-directory. ↩ ↩2 ↩3 -
Simon Willison, "A new way to extract detailed transcripts from Claude Code," simonwillison.net, 2025-12-25.
https://simonwillison.net/2025/Dec/25/claude-code-transcripts/. ↩ ↩2 ↩3 -
Yi Huang, "Inside Claude Code: The Session File Format and How to Inspect It," databunny on Medium, 2026-02-20.
https://databunny.medium.com/inside-claude-code-the-session-file-format-and-how-to-inspect-it-b9998e66d56b. (Uses asessions/<uuid>.jsonlsub-structure that disagrees with Anthropic's live doc; trust the primary.) ↩ ↩2 -
Anthropic, "Explore the .claude directory" —
history.jsonl: every prompt with timestamp and project path, used for up-arrow recall. Accessed 2026-07-02.https://code.claude.com/docs/en/claude-directory. ↩ ↩2 -
Anthropic, "Explore the .claude directory" — Windows path resolution and
CLAUDE_CONFIG_DIRoverride. Accessed 2026-07-02.https://code.claude.com/docs/en/claude-directory. ↩ ↩2 -
Linda (
withLinda),claude-JSONL-browserREADME. Accessed 2026-07-02.https://github.com/withLinda/claude-JSONL-browser/blob/main/README.md. ↩ -
OpenAI, "Codex Configuration Reference," developers.openai.com. Accessed 2026-07-02.
https://developers.openai.com/codex/config-reference. ↩ -
ccusage/ccusage,rust/crates/ccusage/src/adapter/codex/paths.rs(~/.codex/sessions,~/.codex/archived_sessions,CODEX_HOME). Accessed 2026-07-02.https://github.com/ccusage/ccusage/blob/main/rust/crates/ccusage/src/adapter/codex/paths.rs. ↩ -
siteboon/claudecodeui,server/modules/providers/README.md— Cursor provider:~/.cursor/projects/**/*.jsonl. Accessed 2026-07-02.https://github.com/siteboon/claudecodeui/blob/main/server/modules/providers/README.md. ↩ ↩2 -
siteboon/claudecodeui,server/modules/providers/README.md— Gemini provider:~/.gemini/tmp/**/*.jsonl. Accessed 2026-07-02.https://github.com/siteboon/claudecodeui/blob/main/server/modules/providers/README.md. ↩ ↩2 -
ccusage/ccusage,rust/crates/ccusage/src/adapter/copilot/paths.rs—~/.copilot/otel/andCOPILOT_OTEL_FILE_EXPORTER_PATH. Accessed 2026-07-02.https://github.com/ccusage/ccusage/blob/main/rust/crates/ccusage/src/adapter/copilot/paths.rs. ↩ ↩2 ↩3 -
Aider, "Options reference,"
--input-history-file/--chat-history-file/--llm-history-filedefaults;aider/args.py. Accessed 2026-07-02.https://aider.chat/docs/config/options.html. ↩ -
OpenAI Help Center, "How do I export my ChatGPT history and data?" — 7-day delivery window, 24-hour link expiry. Accessed 2026-07-02.
https://help.openai.com/en/articles/7260999-how-do-i-export-my-chatgpt-history-and-data. ↩ ↩2 -
Anthropic, "Explore the .claude directory" — auto-cleanup:
cleanupPeriodDaysdefault 30. Accessed 2026-07-02.https://code.claude.com/docs/en/claude-directory. ↩ ↩2 ↩3 ↩4 -
Steph Ango, "File over app," stephango.com, 2023-07-01 (revised through 2026).
https://stephango.com/file-over-app. ↩ ↩2