Guide
Sessions
Typed schemas for the transcript formats, and where each harness writes them.
Where
harness.sessions lists the locations, with scope: "data" and a note where the directory name is derived:
| Harness | Format | Path |
|---|---|---|
| Claude Code | JSONL | ~/.claude/projects/<dash-encoded-cwd>/*.jsonl |
| Codex CLI | JSONL, SQLite | ~/.codex/sessions/, ~/.codex/state_5.sqlite |
| Gemini CLI | JSON | ~/.gemini/history/<project-id>/ |
| Grok CLI | JSONL, JSON, SQLite | ~/.grok/sessions/<encoded-cwd>/<session-id>/updates.jsonl |
| OpenCode | SQLite | ~/.local/share/opencode/opencode.db |
| Pi | JSONL | ~/.pi/agent/sessions/<dash-encoded-cwd>/<timestamp>_<session-id>.jsonl |
| OMP | JSONL, SQLite | ~/.omp/agent/sessions/<dash-encoded-cwd>/…jsonl, history.db, agent.db |
| Antigravity | Protocol Buffers, JSONL, SQLite | ~/.gemini/antigravity-cli/conversations/ |
| Mastra Code | SQLite | ~/.local/share/mastracode/mastra.db |
| Freebuff | JSON, JSONL | ~/.config/manicode/projects/<project-name>/chats/<timestamp>/ |
| Cursor, Copilot | - | No known session location |
Each harness page has the full list with notes.
Types
Session schemas are types and nothing else. No runtime code, no validators, no dependency:
import type {
ClaudeSessionEntry,
ClaudeUserEntry,
ClaudeAssistantEntry,
CodexThread,
CodexLogEntry,
GeminiConversationRecord,
OpenCodeSession,
OpenCodeMessage,
OpenCodePart,
} from "@agntn/harnesses";
import { readFileSync } from "node:fs";
const entries = readFileSync(path, "utf8")
.split("\n")
.filter(Boolean)
.map((line) => JSON.parse(line) as ClaudeSessionEntry);
for (const entry of entries) {
if (entry.type === "assistant") {
entry.message.content; // ClaudeContentBlock[]: text, thinking, tool_use, tool_result
}
}
Fields whose upstream shape moves between releases are typed unknown on purpose. Narrow them at the call site with what you actually observe; a schema that claims more than the harness promises breaks on the next minor version.
What's covered
- Claude:
ClaudeSessionEntryas a union of user, assistant and summary entries, with content blocks and usage.ClaudeHistoryEntryforhistory.jsonl. - Codex:
CodexThread,CodexLogEntry,CodexHistoryEntry. - Gemini:
GeminiConversationRecordwith message records, thoughts, tool call records and token summaries. - OpenCode:
OpenCodeSession,OpenCodeMessageand the part union: text, reasoning, tool, file, subtask, step start and finish, snapshot, patch, agent, retry, compaction. PlusOpenCodeTodoandOpenCodeProject.
Grok, Pi, OMP, Antigravity, Mastra Code and Freebuff have their locations mapped and no schema yet. If you read one of those formats and have a stable shape, that is the contribution this package wants most.