Where Grok Build stores session history
Grok Build's visible history is updates.jsonl inside a session directory under ~/.grok/sessions/ by default. GROK_HOME overrides the data root.
$GROK_HOME/sessions/<encoded-cwd>/<session-id>/GROK_HOME defaults to ~/.grok. A relative value is resolved from the current working directory, the same way a relative path typed at a shell prompt would be, rather than from your home directory.
What is in a Grok Build session directory
updates.jsonl ← the transcript you want
summary.json ← list metadata, including info.cwd
chat_history.jsonl ← model context, NOT the display transcript
events.jsonl
rewind_points.jsonl
prompt_history.jsonl
prompt_context.json
system_prompt.txt
resources_state.json
announcement_state.json
*.lockTwo of these look like the transcript and only one is:
updates.jsonlis the authoritative user-visible event stream, the one the CLI rendered to you.chat_history.jsonlis what was fed to the model: compacted, reordered, with system scaffolding mixed in. Read as a transcript, it gives you something that never appeared on anyone's screen.
The .lock files exist because Grok writes these files concurrently. Take a copy before parsing if the session might still be live.
Which project a session belongs to
The group directory name encodes the working directory, but the authoritative answer is in summary.json:
jq -r '.info.cwd' ~/.grok/sessions/*/*/summary.json | sort | uniq -c | sort -rnReading a Grok Build session from the terminal
Extract visible user/assistant text chunks (streamed chunks are not merged):
jq -r 'select(.method=="session/update" or .method=="_x.ai/session/update")
| .params.update
| select(.sessionUpdate=="user_message_chunk" or .sessionUpdate=="agent_message_chunk")
| .content | if type=="array" then .[] else . end
| select(.type=="text") | .text // empty' \
~/.grok/sessions/<group>/<session-id>/updates.jsonlGet a session's title and timestamps without opening the transcript:
jq '{title, info}' ~/.grok/sessions/<group>/<session-id>/summary.jsonBecause a session is a directory, deleting one means removing the whole folder rather than unlinking a single file. Anything that manages Grok sessions has to treat the directory as the unit.
How do I resume this session?
Run grok --resume SESSION_ID from the project's directory with Grok Build installed. Resume in a terminal from the app; Grok does not have in-app chat.
Source and limitations
Implementation: Grok Build adapter. Upstream entry: xAI documentation.
Reference scope: checked against the Sessions Viewer 0.6.0 adapters on 2026-10-05, not a compatibility guarantee for every CLI release. Shell examples use macOS/Linux paths and require
jq(orsqlite3for opencode). Replace placeholders with real values and use your configured data root. Text extraction does not replay tools, images or the active branch of a session tree. Command regressions use downloadable synthetic samples, not private sessions. Check the capability and evidence matrix for tested scope. Browsing is distinct from resuming or editing data; see privacy and data handling.
The command above extracts text chunks, not a full replay of tool results, metadata or background-task notifications. See missing-session troubleshooting.
Or open it in an app
Sessions Viewer reads updates.jsonl and never chat_history.jsonl, groups sessions by info.cwd, and treats the directory as the storage unit: deleting moves the whole folder into a restorable trash instead of calling rm. It also reads Claude Code, Codex, Kimi Code, Pi, Antigravity CLI and opencode.
