Sessions are stored under ~/.omp/agent/sessions/<cwd-dir>/<timestamp>_<id>.jsonl, grouped per working directory. One file is one session; one line is one entry. Entries are never rewritten in place — the file is safe to tail -f while a session is live and safe to copy mid-turn. For the user-facing resume / branch / share workflow, see Sessions.

Entry envelope

Every line is a JSON object with a type discriminator, an 8-character id, a parentId threading it into the tree, and a timestamp. The leaf isn’t an entry — it’s an implicit pointer at the newest reachable id.

FieldTypeNotes
typestringDiscriminator; see entry types below.
idstring (8 hex)Random 8-hex, collision-checked within the file.
parentIdstring | nullParent entry id; null for the first message.
timestampISO 8601UTC, second precision or finer.

Entry and session ids

Entry ids are random 8-character hex strings, collision-checked within the file. Session ids are time-ordered UUIDs (v7), so lexicographic sort matches creation order and a short prefix is enough for --resume. Branch and fork operations preserve entry ids; a fork copies the entries verbatim into a new file, gives the header a fresh session id, and records the source in parentSession.

Session header

The first line of every file is a session header carrying the schema version, working directory, optional title, and (on forks) a parentSession lineage marker.

{
  "type": "session",
  "version": 3,
  "id": "1f9d29",
  "timestamp": "2026-05-14T10:12:03Z",
  "cwd": "/Users/me/src/api",
  "title": "refactor importer"
}
FieldTypeNotes
type"session"Header discriminator.
versionnumberSchema version; current is 3.
idstringSession id; matches the filename.
cwdstringAbsolute working directory at session start.
titlestring?Human label shown in pickers; set by /rename.
parentSessionstring?Lineage marker: the source session id (fork) or session file path (branch into a new file).

Message entries

A message entry wraps the agent message verbatim, with its role and a content array. Tool calls ride inside the assistant message’s content as toolCall blocks; each tool result is its own message entry with role: "toolResult", threaded into the tree as a child like any other entry.

{"type":"message","id":"1f9d2a0b","parentId":null,"timestamp":"…","message":{"role":"user","content":[{"type":"text","text":"refactor the importer to stream"}]}}
{"type":"message","id":"1f9d2b0c","parentId":"1f9d2a0b","timestamp":"…","message":{"role":"assistant","content":[{"type":"text","text":"Reading the file first."},{"type":"toolCall","id":"toolu_01","name":"read","arguments":{"path":"src/importer.ts"}}],"usage":{},"stopReason":"toolUse"}}
{"type":"message","id":"1f9d2c0d","parentId":"1f9d2b0c","timestamp":"…","message":{"role":"toolResult","toolCallId":"toolu_01","toolName":"read","content":[{"type":"text","text":"…file contents…"}],"isError":false}}

Content block types

BlockRoleShape
textany{ type, text }
toolCallassistant{ type, id, name, arguments }id is the tool-call id; arguments is the JSON the model emitted.
toolResult messageown entry{ role, toolCallId, toolName, content, isError }toolCallId matches the toolCall.id; content is a content array (typically a single text block).
thinkingassistant{ type, thinking } — extended-thinking output when the provider supports it.

Other entry types

TypeWhat it records
model_changeActive model swapped (/model or role cycle). Carries model and role.
mode_changePlan mode toggled on or off.
thinking_level_changeExtended-thinking budget changed for subsequent turns.
service_tier_changeProvider service tier (priority, batch) changed.
labelBookmark on another entry. Carries targetId and label; points at an entry id, and compaction never deletes entries, so labels survive it.
compactionMarks where compaction replaced older turns. Carries summary, firstKeptEntryId, and tokensBefore.
branch_summarySummary of an abandoned branch, written when /tree moves the leaf away.
session_initSubagent sessions only; captures the system prompt, initial task, tool list, and any output schema for debugging/replay.
custom / custom_messageExtension state — opaque payloads written by hooks, custom tools, or plugins.
ttsr_injectionRecords which TTSR rule names have been injected, so rules fire once per branch.
mcp_tool_selectionHousekeeping — which MCP tools were exposed for this session.

A worked example

A trimmed session showing the header, two turns with a tool call, a model change, a label, and a compaction:

{"type":"session","version":3,"id":"019700f1-1a2b-7c3d-8e4f-aabbccddeeff","timestamp":"2026-05-14T10:12:03Z","cwd":"/Users/me/src/api","title":"refactor importer"}
{"type":"message","id":"1f9d2a0b","parentId":null,"timestamp":"…","message":{"role":"user","content":[{"type":"text","text":"refactor the importer to stream"}]}}
{"type":"message","id":"1f9d2b0c","parentId":"1f9d2a0b","timestamp":"…","message":{"role":"assistant","content":[{"type":"text","text":"Reading the file first."},{"type":"toolCall","id":"toolu_01","name":"read","arguments":{"path":"src/importer.ts"}}],"stopReason":"toolUse"}}
{"type":"message","id":"1f9d2c0d","parentId":"1f9d2b0c","timestamp":"…","message":{"role":"toolResult","toolCallId":"toolu_01","toolName":"read","content":[{"type":"text","text":"…file contents…"}],"isError":false}}
{"type":"model_change","id":"1f9d2d0e","parentId":"1f9d2c0d","timestamp":"…","model":"anthropic/claude-opus","role":"default"}
{"type":"label","id":"1f9d2e0f","parentId":"1f9d2d0e","timestamp":"…","targetId":"1f9d2a0b","label":"pre-refactor"}
{"type":"compaction","id":"1f9d2f10","parentId":"1f9d2e0f","timestamp":"…","summary":"…","firstKeptEntryId":"1f9d2c0d","tokensBefore":48211}

Reading a session as a file

From a shell, omp -p 'read /path/to/session.jsonl' renders the file with hashline anchors, so you can quote any entry by id and feed the line back into a follow-up turn without reformatting. See CLI reference for --export and other headless flags.\n

Ask Docs

AI assistant to help answer questions about the documentation. Answers are read-only and cite docs/source.

Hi! How can I help you with the documentation today? Answers are read-only and cite docs/source.

Ctrl+Enter to send