Pi¶
pi stores each coding-agent conversation as an append-only JSONL transcript.
Because pi has no dedicated prompt-history store, --exhaustive is required
even for prompt-scope results. Assistant, tool, summary, and branch
records are available through the conversation scope. Targeted effort cannot
route this backend.
Base path: ~/.pi/agent (env override: PI_CODING_AGENT_DIR).
observed_version: pi v0.79.9 (observed 2026-06-21).
pi (the earendil-works “Pi Agent Harness”) groups transcripts by
working directory. The directory key is the cwd with its leading slash
stripped and /, \, and : replaced by -, wrapped in double
dashes (e.g. --home-d-work-python-agentgrep--). Each session file is
named <iso-timestamp>_<session-uuid>.jsonl.
Unlike Codex, Claude Code, or Grok, pi has no separate prompt-history log;
ordinary sessions use the JSONL transcript as their searchable surface.
--exhaustive projects user turns, while conversation and all scopes admit
assistant, tool, summary, and branch records. Pi’s optional context-mode SQLite
store is reserved for those explicit broad scopes.
The optional PI_CODING_AGENT_SESSION_DIR override points at the
sessions directory directly. When it is set, pi writes session files
flat into that directory with no per-working-directory subdirectory;
agentgrep then recovers the cwd from each session’s header rather than
the directory name.
Stores¶
- Role:
primary_chat- Format:
jsonl- Coverage:
default_search- Adapter:
pi.sessions_jsonl.v1
- Role:
app_state- Format:
sqlite- Coverage:
inspectable- Adapter:
pi.context_mode_sqlite.v1
- Role:
app_state- Format:
json_object- Coverage:
catalog_only- Adapter:
-
- Role:
instruction- Format:
md_frontmatter- Coverage:
catalog_only- Adapter:
-
- Role:
app_state- Format:
text- Coverage:
catalog_only- Adapter:
-
- Role:
app_state- Format:
opaque- Coverage:
catalog_only- Adapter:
-
pi.sessions¶
Append-only JSONL transcript, one file per session, grouped by working directory (--<encoded_cwd>--, leading slash stripped, / \ : -> -). Line 1 is a type:"session" header (id, timestamp, cwd; version is 3 and may be absent in v1 files). Each later line is a SessionEntry tagged union sharing id/parentId/timestamp: message wraps an LLM message (role user/assistant/toolResult, content string or content-blocks; assistant turns carry model/provider; a bashExecution role has no content and carries its shell command/output instead; error/aborted assistant turns carry a diagnostic errorMessage string in place of content); compaction/branch_summary carry a summary; session_info carries a user-set name. No separate prompt-history log or SQLite index backs ordinary sessions.
- Agent:
pi
- Role:
primary_chat- Format:
jsonl- Coverage:
default_search- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/sessions/--<encoded_cwd>--/<ts>_<session_uuid>.jsonl- Adapter:
pi.sessions_jsonl.v1- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
yes
The sole ordinary-session and deep-prompt pi store. User turns surface as prompts and assistant/tool turns as history via the shared role->kind mapping; compaction/branch summaries and session names are included as history text.
pi.context_mode_db¶
Per-project context-mode SQLite database, rooted at ~/.pi/context-mode/sessions/<project_hash>.db (outside the agent dir; the stem is sha256(project_dir)[:16], so it is a hashed cwd grouping holding multiple sessions, each row carrying its own session_id). The session_events table holds events (type = role/intent/decision/tool_call/file_read/blocker_resolved/data) with a JSON data payload, emitted as inspectable records; sibling session_meta/session_resume/tool_calls tables exist but only session_events is parsed.
- Agent:
pi
- Role:
app_state- Format:
sqlite- Coverage:
inspectable- Path:
${HOME}/.pi/context-mode/sessions/<project_hash>.db- Adapter:
pi.context_mode_sqlite.v1- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.settings¶
User preferences: selected models, themes, installed extension packages, and assorted UI/agent settings. Configuration, not chat content.
- Agent:
pi
- Role:
app_state- Format:
json_object- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/settings.json- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.auth¶
Provider API credentials. Documented but never enumerated.
- Agent:
pi
- Role:
app_state- Format:
json_object- Coverage:
private- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/auth.json- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.models¶
Custom model definitions and provider overrides. Created only when the user adds custom models.
- Agent:
pi
- Role:
app_state- Format:
json_object- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/models.json- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.themes¶
User-defined TUI colour schemes. Created only when the user adds themes.
- Agent:
pi
- Role:
app_state- Format:
json_object- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/themes/<theme>.json- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.tools¶
Directory of user-authored custom tool scripts. Created on demand.
- Agent:
pi
- Role:
app_state- Format:
opaque- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/tools/<tool>- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.bin¶
Managed binaries (e.g. fd, rg) pi downloads for its own use.
- Agent:
pi
- Role:
app_state- Format:
opaque- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/bin/<binary>- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.prompts¶
User-authored Markdown prompt templates, not conversation history. Created on demand.
- Agent:
pi
- Role:
instruction- Format:
md_frontmatter- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/prompts/<prompt>.md- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.debug_log¶
Runtime diagnostics log. Written only when debug logging is enabled.
- Agent:
pi
- Role:
app_state- Format:
text- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/pi-debug.log- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
pi.extensions_npm¶
Managed npm extension install root: package.json, package-lock.json, and node_modules/. Declared via the packages array in pi.settings.
- Agent:
pi
- Role:
app_state- Format:
opaque- Coverage:
catalog_only- Path:
${PI_CODING_AGENT_DIR or ${HOME}/.pi/agent}/npm/- Adapter:
-
- Data version:
-- Version strategies:
-- Observed:
pi v0.79.9 (observed 2026-06-21) (2026-06-21)
- Default search:
no
Record schemas¶
Session transcripts¶
pi.sessions files start with a session header; version is 3 and
may be absent in older (v1) files.
{"type": "session", "version": 3, "id": "019e5691-...",
"timestamp": "2026-05-23T20:41:01.417Z",
"cwd": "/home/d/work/python/agentgrep"}
Every later line is a SessionEntry sharing id / parentId /
timestamp (an append-only tree, not a flat list). A message entry
wraps an LLM message; role is user, assistant, or toolResult,
and content is a string or a content-blocks array. Assistant turns
carry model and provider inline. A bashExecution role has no
content; agentgrep joins its shell command and output as the
searchable text. Error/aborted assistant turns carry a diagnostic
errorMessage string in place of content.
{"type": "message", "id": "...", "parentId": "...",
"timestamp": "2026-05-23T20:41:05.000Z",
"message": {"role": "user",
"content": [{"type": "text", "text": "..."}],
"timestamp": 1779999665000}}
User turns surface as prompts and assistant / tool turns as history via
the shared role-to-kind mapping. compaction and branch_summary
entries contribute their summary text, and session_info contributes
its user-set name; model_change, thinking_level_change, custom,
and label entries are metadata only. Entry-level timestamps are
ISO-8601; the inner message.timestamp is unix-milliseconds and is used
only as a fallback.
Context-mode database¶
pi.context_mode_db is a per-project SQLite database at
~/.pi/context-mode/sessions/<project_hash>.db, rooted outside the agent dir.
The stem is sha256(project_dir)[:16], so it is a hashed cwd grouping holding
multiple sessions (each row carries its own session_id). Its session_events
table holds events (type = role/intent/decision/tool_call/file_read/
blocker_resolved/data) with a JSON data payload, emitted as inspectable
records; sibling session_meta/session_resume/tool_calls tables exist but
only session_events is parsed.
Project context¶
Store |
|
|
|
|---|---|---|---|
turn’s |
|
— |
|
— |
|
— |
Pi names a context-mode database after sha256(project_dir)[:16], and it
repeats that absolute project_dir on every session_events row — so a
record reports the working directory it came from and the digest Pi
filed it under. Both are searchable: --cwd reaches this store like any
other (lossless, straight from the column), and
cwd_hash: still answers with the digest Pi itself wrote. agentgrep reads
the digest off the file stem and never computes it from the recovered
path, and it admits the stem only when it has a digest’s shape, so a
hand-copied backup.db beside a real database does not publish its own
name as a project identity. The database is reachable at
--scope conversations, not at the default prompt scope.
The project_dir column arrived in a Pi migration. A database that
predates it reads back as records without a cwd rather than as no
records at all.
Pi records no git branch, so branch: does not reach this backend.
Documentary stores¶
The remaining pi.* rows are catalogued for completeness but not
searched: pi.settings, pi.models, pi.themes, pi.tools,
pi.bin, pi.prompts, pi.debug_log, and pi.extensions_npm (the
managed npm extension install root). pi.auth holds provider
credentials and is documented but never enumerated from disk.