Storage Location
Sessions are stored under~/.claude/projects/:
<hash> is derived from the working directory path, so each project directory gets its own session namespace. Session IDs use the format <prefix><8 characters>.
JSONL Format
Each line in the.jsonl file is a self-contained JSON object. Four entry types are written:
| Entry type | When written | Notes |
|---|---|---|
user | On every user message | Written with await (blocking) for crash recovery |
assistant | On every assistant message | Written fire-and-forget (order-preserving queue) |
progress | During tool execution | Inline write; deduplicated on next query |
system/compact_boundary | After autoCompact runs | Marks where summarization occurred |
Persistence Strategy
Different message types use different write strategies, balancing durability against performance:src/utils/sessionStorage.ts (recordTranscript()) guarantees ordering without blocking the agent loop. This is the Fire-and-Forget Write design pattern — a background queue drains writes while the agent continues processing.
Resume Flow
Locate the session log
getLastSessionLog() scans ~/.claude/projects/<hash>/sessions/ and returns the most recently modified .jsonl file, or the file matching the --resume <id> argument.Parse the JSONL
Each line is parsed into its typed entry. Invalid or truncated lines (from a crash mid-write) are skipped.
Rebuild messages[]
user and assistant entries are converted back into MessageParam objects and pushed into the messages[] array in order. The compact_boundary entry signals that older messages have already been summarized.Restore compact boundary
If a
compact_boundary entry exists, messages[] is rebuilt starting from that boundary — the summarized history before it is prepended as a single assistant message containing the compact summary.CLI Flags
| Flag | Behavior |
|---|---|
--continue | Resumes the last session associated with the current working directory |
--resume <id> | Resumes a specific session by its session ID |
--fork-session | Creates a new session ID but copies the history from the last session — diverges from this point forward |
/resume Slash Command
Within an interactive session,/resume lists recent sessions and lets you jump to one without restarting the CLI:
~/.claude/projects/<hash>/sessions/, displays a summary of each session (start time, message count, last message preview), and replaces the current messages[] with the selected session’s history.
Session ID Format
Session IDs follow the pattern<prefix><8 alphanumeric characters>. The prefix encodes the session type:
| Prefix | Type |
|---|---|
b | Bash task |
a | Agent task |
r | Remote agent task |
t | In-process teammate task |
| (none) | Main interactive session |
a_f3a9b2c1 is an agent sub-task session.
Crash Recovery
Because user messages are written withawait (blocking), a crash during tool execution will always have the user’s last message in the JSONL log. On resume, the rebuilt messages[] will include that user message, and the agent will re-respond from that point — tools that were interrupted mid-execution will be re-run.