The root
Sessions live under $GROK_HOME/sessions, where $GROK_HOME defaults to ~/.grok.
Grok CLI guide: session storage
Grok is the odd one of the three: a session is not a file, it is a directory. The CLI writes several files per session, including a summary index it keeps current as the conversation runs, so nothing has to scan a transcript head to know what a session is about.
xAI
Sessions live under $GROK_HOME/sessions, where $GROK_HOME defaults to ~/.grok.
The layout is sessions/<encoded-project-path>/<uuidv7>/. The outer directory groups by project, the inner one is the session, and a UUIDv7 sorts chronologically because its leading bits are a timestamp.
Each session directory holds summary.json, updates.jsonl, chat_history.jsonl, rewind_points.jsonl and signals.json. The transcript is split across more than one of these, so reading only chat_history gives you a partial view.
The project path shown for a session should come from info.cwd inside summary.json, never from decoding the group directory name. When a path is too long to encode into a directory name, Grok falls back to a shorter slug, and at that point the directory name no longer round-trips.
The Grok home directory holds auth.json at its top level, and that file is a bare OIDC token. Only the sessions subdirectory is safe to hand to a tool. Termdeck confines its agent to that subdirectory for exactly this reason.
Compare
| Claude Code | Codex CLI | Grok CLI | |
|---|---|---|---|
| Root directory | ~/.claude/projects | $CODEX_HOME/sessions | $GROK_HOME/sessions |
| One session is | One .jsonl file | One .jsonl rollout file | A directory of files |
| Grouped by | Slugged project path | Date, as YYYY/MM/DD | Slugged project path |
| Path from project + id | Derivable | Not derivable, resolve by id | Derivable |
| Old sessions | Left as plain .jsonl | Compressed to .jsonl.zst | Left as plain files |
| Built-in index | None, scan the tree | session_index.jsonl | summary.json per session |
Termdeck drives all three from one console, so the differences above stop being three separate habits to remember.
FAQ
Grok splits a session across several files: a summary index, an update stream, the chat history, rewind points and signals. Giving each session its own directory keeps those five together and lets the CLI update the summary without rewriting the transcript.
The info.cwd field inside summary.json. The directory name looks like an encoded path but does not always round-trip, because paths too long to encode fall back to a shorter slug, so decoding the directory name is only a fallback.
No. auth.json sits at the top level of that directory and holds a live OIDC access and refresh token. Copy only the sessions subdirectory if you are moving history between machines.
Grok records rewind points in their own file so the CLI can roll a conversation back to an earlier state. They are session metadata rather than transcript content, which is why they are stored separately from chat history.
Claude Code, Codex and Grok in one browser console