# Sessions

> Session lifecycle: create, resume, continue, fork, compact, export; persistence layout; /new /resume /compact; grok sessions subcommands and ID constraints.

- Repository: xai-org/grok-build
- GitHub: https://github.com/xai-org/grok-build
- Human docs: https://grok-wiki.com/public/docs/xai-org-grok-build-90205de50458
- Complete Markdown: https://grok-wiki.com/public/docs/xai-org-grok-build-90205de50458/llms-full.txt

## Source Files

- `crates/codegen/xai-grok-pager/docs/user-guide/17-sessions.md`
- `crates/codegen/xai-grok-pager/src/sessions_cmd.rs`
- `crates/codegen/xai-grok-shell/src/session/mod.rs`
- `crates/codegen/xai-grok-shell/src/session/chat_persistence.rs`
- `crates/codegen/xai-grok-shell/src/session/compaction.rs`
- `crates/codegen/xai-chat-state/src/lib.rs`
- `crates/codegen/xai-grok-paths/src/lib.rs`

---

---
title: "Sessions"
description: "Session lifecycle: create, resume, continue, fork, compact, export; persistence layout; /new /resume /compact; grok sessions subcommands and ID constraints."
---

Grok Build persists every conversation as a **session** under `$GROK_HOME/sessions` (default `~/.grok/sessions`). The same on-disk layout backs the interactive TUI, headless `-p` runs, and ACP agent stdio. Session selection is resolved once from CLI flags (`--resume` / `-r`, `--continue` / `-c`, `--session-id` / `-s`, `--fork-session`) into a single startup intent, then materialized against the local JSONL store before the first turn. In-process chat history is owned by `ChatStateActor`; disk writes go through JSONL adapters (`updates.jsonl`, `chat_history.jsonl`, `summary.json`).

## What a session contains

A session is a durable conversation record, not just scrollback. It includes:

- User prompts and model responses
- Tool calls and tool results
- Plan / TODO state
- File snapshots for rewind
- Token and turn signals
- Optional subagent metadata (child sessions live in the normal sessions tree)

Grok assigns a **UUIDv7** when it creates the ID. Clients may supply their own ID with `-s` / `--session-id` only when creating or naming a fork (see [Session ID constraints](#session-id-constraints)).

## Persistence layout

Base directory: `grok_home()/sessions/…` where `grok_home()` is `$GROK_HOME` or `~/.grok`.

Sessions are **grouped by working directory**. The cwd is encoded into a single path component:

| Encoding | When | Form |
| --- | --- | --- |
| URL-encode | Encoded name ≤ 255 bytes | Reversible via `urlencoding::decode` |
| Slug + BLAKE3 | Encoded name > 255 bytes | `{slug}-{16 hex}` (≤ 57 bytes); original path in `.cwd` inside the group dir |

```text
~/.grok/sessions/<encoded-cwd>/<session-id>/
  summary.json              # index metadata (title, model, parent, counts)
  updates.jsonl             # ACP session/update stream (authoritative for resume/export)
  chat_history.jsonl        # ConversationItems sent to the model API
  plan.json                 # TODO / task list
  plan_mode.json            # plan-mode UI state (when used)
  rewind_points.jsonl       # file snapshots for /rewind
  signals.json              # usage / turn counters
  feedback.jsonl            # user ratings and feedback
  btw_history.jsonl         # /btw side-question log (when used)
  compaction_checkpoints/   # post-compact restore points
  subagents/                # per-child meta; child sessions use the normal tree
```

<Info>
`updates.jsonl` is the source of truth for restore, replay, and `grok export`. `chat_history.jsonl` is the model-facing history (format version 1 = `ConversationItem`). `summary.json` is the index row used by pickers and `grok sessions list`.
</Info>

### `summary.json` fields (selected)

| Field | Role |
| --- | --- |
| `info` | Session id + cwd |
| `session_summary` / `generated_title` | Display title (manual rename sets `title_is_manual`) |
| `created_at` / `updated_at` / `last_active_at` | Timestamps |
| `num_messages` / `num_chat_messages` | Update vs chat counts |
| `current_model_id` | Model in use |
| `parent_session_id` | Fork / restore parent |
| `session_kind` | e.g. `fork`, `worktree`, `subagent` |
| `source_workspace_dir` | Worktree sessions: original workspace for grouping |
| `agent_name` | Agent definition to restore on resume |
| `worktree_label` | Human label for worktree groups in `grok sessions list` |

Chat messages append through a persistence channel (`ChannelChatPersistence` → `PersistenceMsg::Chat` / `ReplaceChatHistory` / `Flush`). Compaction replaces history and may write checkpoints under `compaction_checkpoints/`.

## Session ID constraints

| Rule | Behavior |
| --- | --- |
| Generated IDs | UUIDv7 (36-char string) |
| `-s` / `--session-id` | Must parse as a UUID; must **not** already exist under the target session directory |
| Resume | Use `-r` / `--resume` or `-c` / `--continue` — **not** `-s` |
| `-s` + resume/continue | Only valid with `--fork-session` (names the **child** UUID) |
| Overwrite model | Create-only for client IDs; resume never upserts over an existing id |

Preflight error strings include:

- `Error: --session-id must be a valid UUID (got '…').`
- `Error: Session ID … is already in use.`
- `Error: --session-id can only be used with --continue or --resume if --fork-session is also specified.`
- `Error: --fork-session requires --resume or --continue.`
- `Error: --fork-session cannot be combined with --worktree.`

## Create and leave sessions

### Interactive

| Action | Command / UI |
| --- | --- |
| Launch | `grok` creates a new session (or welcome → pick recent) |
| Fresh mid-session | `/new` (alias `/clear`) |
| Leave Grok | `/quit` (alias `/exit`) |
| Leave session, stay in app | `/home` (welcome screen) |
| Inspect current | `/session-info` (id, cwd, model, context usage) |
| Rename | `/rename <title>` (alias `/title`) |

### CLI create with fixed UUID

```bash
grok -s 019f6881-e1d4-7362-bdf8-73b3ab84a480 -p "Start automation run"
```

Fails if the value is not a UUID or if that id already has a session under the write cwd.

## Resume and continue

Startup flags classify into one intent: **NewAuto**, **NewWithId**, **Resume**, or **ForkFrom**.

| Flag | Meaning |
| --- | --- |
| `-r` / `--resume <id>` | Strict load of that session (error if missing) |
| `-r` / `--resume` (no value) | Most recent session for the **current cwd** |
| `-c` / `--continue` | Same as resume-most-recent for cwd |
| `--load` | Hidden alias of `--resume` |

`-r` and `-c` conflict with each other.

### Interactive resume

```text
/resume
```

Opens a session picker for the current workspace (no arguments). Type to filter by title; extended search also matches conversation content. `Ctrl+/` runs content search immediately. Active parent/fork tabs are managed with `/dashboard` (alias `/sessions` in the TUI — distinct from the `grok sessions` CLI).

Welcome-screen recent list also resumes by selection.

### Headless resume patterns

```bash
# New session (default)
grok -p "Hello"

# Resume by id (must exist)
grok -p "Continue where we left off" -r <session-id>

# Continue most recent in this directory
grok -p "What were we doing?" -c
```

Capture the id from JSON output:

```bash
grok -p "Hello" --output-format json | jq -r '.sessionId'
```

<Tip>
For multi-step CI, always pass the previous `sessionId` to `-r`. Do not reuse `-s` to open an existing session.
</Tip>

Sandbox profile on resume prefers the profile stored with the session; a mismatched `--sandbox` is refused rather than silently changing isolation mid-history.

## Fork

Fork copies conversation (and related state) into a **new** session id with `parent_session_id` set. Fork ids are also plain UUIDv7 (no source prefix), so length stays fixed across fork depth.

### Interactive

```text
/fork [--worktree|--no-worktree] [directive]
```

Optional `directive` becomes the fork’s first prompt. Worktree mode can isolate the fork in a new git worktree; omit both flags to be prompted. `--at <turn>` is not supported in current builds.

### CLI

```bash
# Fork most recent for cwd into a new id
grok -c --fork-session -p "Try an alternate approach"

# Fork a specific parent; name the child UUID
grok -r <parent-id> --fork-session -s <new-uuid> -p "Branching work"
```

`--fork-session` requires `-r` or `-c`. It cannot combine with `--worktree` at startup.

### Programmatic / ACP

Extension method `x.ai/session/fork` with payload fields such as `sourceSessionId`, `sourceCwd`, `newCwd`, optional `newSessionId`, and `sessionKind` (`fork` or `worktree`). Copy includes chat history, updates, plan state, and compaction segment archives when present.

Resume a session in a fresh worktree:

```bash
grok -w -r <session-id>
```

## Compact

Long histories are compressed so later turns fit the model context window.

### Manual

```text
/compact
/compact focus on the auth migration decisions
```

Optional text steers what the summarizer should preserve. Manual compact does not arm auto-compact suppression the same way failed auto-compact paths do.

### Auto-compact

When estimated tokens approach the model’s `context_window`, Grok auto-compacts (with UI notification). Related knobs:

- Model `context_window`
- Prefire lead: background first-pass of two-pass compact, default 10 percentage points early (`GROK_PREFIRE_LEAD_PERCENT`)
- Hidden CLI: `--compaction-mode` (`summary` \| `transcript` \| `segments`), `--compaction-detail`

Compaction rewrites `chat_history.jsonl`, records markers in `updates.jsonl`, and can write under `compaction_checkpoints/`. Forked sessions may keep an **inherited prefix** (`inherited_prefix_len`) that is preserved through later compacts.

## Export and delete

### Export transcript (Markdown)

```bash
grok export <session-id>                 # stdout
grok export <session-id> ./out.md        # file
grok export <session-id> --clipboard     # clipboard
```

Replays `updates.jsonl` through the ACP tracker and renders scrollback blocks to Markdown. Empty conversation content errors out.

### Trace / diagnostics bundle

```bash
grok trace <session-id>
```

Packages the session directory (and related artifacts) under `$GROK_HOME/trace-exports/` by default.

### Delete

```bash
grok sessions delete <session-id>
```

Removes local history (found by id across workspaces). When authenticated and not on a ZDR team, also attempts remote delete (idempotent; 404 is success).

## `grok sessions` CLI

Requires a subcommand:

| Subcommand | Flags | Behavior |
| --- | --- | --- |
| `list` | `-n` / `--limit` (default 20) | Recent sessions for **current cwd**, grouped by `worktree_label` |
| `search` | query, `-n` / `--limit` | Local SQLite FTS5 over titles/prompts + remote results (timeout falls back to local) |
| `delete` | `id` | Permanent delete (see above) |

```bash
grok sessions list
grok sessions list --limit 50
grok sessions search "rate limit"
grok sessions delete 019f6881-e1d4-7362-bdf8-73b3ab84a480
```

List columns: session id, created, updated, source status, summary (or first prompt line). Search prints score/snippet; remote-only hits are marked `(remote)`.

Auth for remote merge is best-effort: cached credentials or deployment key; interactive login is not forced for enterprise proxy setups.

## ACP agent sessions

Over agent stdio, clients own create/load:

```typescript
// Create
const { sessionId } = await connection.request("session/new", {
  cwd: "/path/to/project",
  mcpServers: [],
});

// Load
await connection.request("session/load", {
  sessionId: "existing-session-id",
  cwd: "/path/to/project",
  mcpServers: [],
});
```

The agent appends session updates automatically. Clients reconnect with `session/load` using the same id. Optional client `_meta.sessionId` on `session/new` must be a UUID and unused under the target cwd (same preflight as CLI `-s`).

## Interactive command map

| Command | Role |
| --- | --- |
| `/new` / `/clear` | New session |
| `/resume` | Picker → load prior session |
| `/dashboard` / TUI `/sessions` | Switch/rename/close active tabs (parent + forks) |
| `/fork` | Branch conversation (+ optional worktree) |
| `/compact` | Summarize history |
| `/rewind` | Restore files + truncate history to a prior prompt snapshot |
| `/rename` / `/title` | Set display title |
| `/session-info` | Current id, model, context fill |
| `/quit` / `/exit` | Exit Grok |
| `/home` | Welcome without quitting process |

<Warning>
`/rewind` restores **on-disk** file snapshots and truncates conversation. Changes after the chosen point are lost unless still recoverable from git. Esc Esc (within ~800ms, idle, empty prompt) can open the same rewind flow.
</Warning>

## Operational notes

- **Disk size**: Rewind snapshots dominate usage when many files change. Compact reduces model history size but does not always delete rewind artifacts.
- **Search index**: Keyword search uses a local FTS5 index over titles and prompts; remote search is additive and may time out.
- **ZDR teams**: Remote upload/delete is skipped; sessions stay local-only.
- **Cwd binding**: Resume-most-recent and `sessions list` are scoped to the process cwd’s encoded group. The same UUID under another encoded cwd is a different directory.
- **Subagents**: Child metadata under `subagents/`; full child histories use normal session paths (or explicit dirs under the parent when configured).

## Related pages

<CardGroup>
  <Card title="Headless mode" href="/headless-mode">
    `-p`, output formats, max-turns, and CI resume/continue patterns that depend on session ids.
  </Card>
  <Card title="Agent mode (ACP)" href="/agent-mode">
    JSON-RPC `session/new` and `session/load`, streaming updates, and shared runtime flags.
  </Card>
  <Card title="Slash commands" href="/slash-commands">
    Full interactive command surface including session, model, and memory builtins.
  </Card>
  <Card title="CLI reference" href="/cli-reference">
    Top-level `grok` commands and shared flags (`sessions`, `export`, `trace`, resume, worktree).
  </Card>
  <Card title="Subagents and personas" href="/subagents">
    Child agents, isolation, and how forked/worktree sessions relate to parent context.
  </Card>
  <Card title="Project rules and memory" href="/project-rules-and-memory">
    Cross-session memory vs per-session history; when AGENTS.md injects into the system prompt.
  </Card>
</CardGroup>
