Universal terminal UI for browsing, searching, reading, annotating, and resuming AI coding sessions across multiple assistant tools — including an AI chat that answers questions about your own session archive.
agent-sessions indexes local conversation stores from supported coding assistants into one SQLite database, then exposes them through a fast Textual TUI, a small CLI, and an in-app research agent that can dig through the archive for you and hand back exact resume commands.
| Provider | Status | Session location |
|---|---|---|
| Claude Code | Supported | ~/.claude/projects/ |
| Codex | Supported | ~/.codex/sessions/ |
| Droid (FactoryAI) | Supported | ~/.factory/sessions/ |
| Cursor | Supported | ~/Library/Application Support/Cursor/ |
| OpenCode | Supported | ~/.local/share/opencode/ (opencode.db, plus the pre-2026 storage/ tree) |
Install from this repository:
pipx install git+https://github.com/ovachiever/agent-sessions.gitFor optional AI summaries, semantic search, and chat:
pipx install "agent-sessions[ai] @ git+https://github.com/ovachiever/agent-sessions.git"
export OPENAI_API_KEY="sk-..."From a clone, for development:
git clone https://github.com/ovachiever/agent-sessions.git
cd agent-sessions
pip install -e ".[dev]"
pytestThere is no PyPI release: the agent-sessions name on PyPI belongs to an unrelated project, so pip install agent-sessions installs different software.
agent-sessions
aisThe first launch indexes available provider stores. Press i in the TUI to reindex later.
Common CLI commands:
agent-sessions providers --status
agent-sessions search "find me the sessions where we worked on auth token refresh"
agent-sessions search "harness:codex project:api after:7d natural language search"
agent-sessions --stats
agent-sessions --reindex
agent-sessions --generate-embeddings
agent-sessions resolve --cwd ~/code/api --harness codex --near 1786128000| Key | Action |
|---|---|
/ |
Search sessions, or find within an open transcript (n / Shift+N cycle matches) |
s |
Cycle search sort order: relevance, newest, oldest |
f |
Cycle provider filter |
t |
Load full transcript |
? |
Open the chat panel, or return focus to it if open (Escape closes) |
z |
Toggle chat fullscreen |
Ctrl+R |
Toggle recent-chats list (chat open) |
Ctrl+Y |
Copy chat transcript (chat open) |
Ctrl+T |
Add tag to selected session |
Ctrl+N |
New chat when the chat panel is open; otherwise add note to selected session |
y |
Copy full transcript |
c |
Copy visible transcript message |
r |
Resume selected session |
Enter |
Copy resume command |
i |
Reindex sessions |
Tab |
Switch parent/sub-agent panes |
Shift+Tab |
Focus detail panel |
Escape |
Back: collapse chat, exit transcript to session details, clear search, or close find |
q |
Quit |
Search is session-level and hybrid:
- FTS5 keyword search over indexed messages and session metadata.
- Optional semantic search over embedded transcript chunks when
agent-sessions[ai]andOPENAI_API_KEYare available. - Natural-language query cleanup for prompts like
find me the sessions where we worked on X. - Inline filters for provider, project, time range, and annotation tags.
- Match explanations in CLI output and the TUI detail panel.
- Child/sub-agent matches propagate to the parent session result.
Examples:
auth middleware
find me the sessions where we worked on webhook replay handling
harness:claude-code React component
project:api after:7d JWT refresh
before:2026-04-01 indexing
#tag:breakthrough semantic searchSupported filters:
| Filter | Meaning |
|---|---|
harness:name |
Provider name, such as codex, claude-code, droid, cursor, or opencode |
project:name |
Project name or path substring |
after:value |
Session modified after ISO date or relative value like 7d, 2w, 24h |
before:value |
Session modified before ISO date or relative value |
#tag:name |
Sessions with a matching annotation tag |
Press ? to open the chat panel and ask questions about your archive in plain English: "which session was the caching bug fixed in?", "what did we decide about the auth flow last month?". Requires agent-sessions[ai] and OPENAI_API_KEY.
The chat runs a research agent over the local index. It resolves scope (projects, tags, time windows), searches transcripts with the same hybrid FTS + semantic machinery as / search, reads focused message windows around its hits, and answers with evidence: every session it cites carries a citation label and the exact resume command to reopen it.
- Sessions the chat recommends are auto-selected in the session list — press
Escapethenrto resume the top recommendation directly. - Large retrievals are paged, so the agent can read arbitrarily long transcripts across as many tool calls as it needs without exceeding the model's context window.
- If a model request fails mid-turn, the chat reports the error and keeps the retrieval work already done; the conversation stays usable.
- Conversations persist in the index database.
Ctrl+Rlists recent chats,Ctrl+Nstarts a new one,Ctrl+Ycopies the visible chat,zgoes fullscreen. - The model defaults to
gpt-5.6withxhighreasoning effort; override with theAGENT_SESSIONS_CHAT_MODELenvironment variable.
After a crash takes a terminal down, each harness's own store is the surviving record of what was running. resolve answers the question a restore engine needs: which conversation was open in this directory around this time, and what command reopens it.
agent-sessions resolve --cwd ~/code/api --harness codex --near 1786128000It prints one JSON object on stdout — ranked candidates with resume commands, diagnostics on stderr — and refreshes the index for just that directory first, unless --no-reindex is passed. --window widens how far from --near a session may end and still count; --limit caps candidates.
resolve-batch answers many directories from a single index pass, reading {"requests": [...]} on stdin:
echo '{"requests":[{"cwd":"~/code/api","harness":"codex","near":1786128000}]}' \
| agent-sessions resolve-batchRestore engines fire a burst of resolves at once; the batch form pays for one refresh rather than one per directory.
Press t on a session to stream the full transcript into a selectable text view; Escape returns to the session detail view you were in before. Transcript search uses /, n, and Shift+N inside the transcript view. The indexed transcript loader falls back to provider-native parsing when a provider format needs special handling.
Annotations are stored outside cache at:
~/.local/share/agent-sessions/annotations/{session_id}.json
In the TUI:
Ctrl+Tadds a tag.Ctrl+Nadds a note.
During Claude Code sessions, an optional local UserPromptSubmit hook can capture #tag:name and #note text markup. Pure annotation prompts can be blocked from reaching the model; mixed prompts pass through with annotation markup stripped.
Tags and notes sync into the SQLite index during reindex and are shown in the session detail panel.
AI features are opt-in and require agent-sessions[ai] plus OPENAI_API_KEY.
- Chat Q&A uses
gpt-5.6withxhighreasoning effort (override the model withAGENT_SESSIONS_CHAT_MODEL). Session title summaries usegpt-5.5over a bounded head-and-tail slice of the transcript. - Semantic search uses
text-embedding-3-smallembeddings over session chunks. - Embeddings are cached in SQLite. Use
agent-sessions --generate-embeddingsto backfill chunks that were indexed before AI features were enabled. - API calls carry bounded timeouts so a stalled provider degrades gracefully instead of blocking the TUI.
The core TUI, provider parsing, transcript browsing, annotations, and keyword search work without AI dependencies.
| Data | Location |
|---|---|
| SQLite index (sessions, messages, chunks, chats) | ~/.cache/agent-sessions/sessions.db |
| Legacy summary cache | ~/.cache/agent-sessions/summaries.json |
| Metadata cache | ~/.cache/agent-sessions/metadata.json |
| Annotation files | ~/.local/share/agent-sessions/annotations/ |
Chat conversations live in the same SQLite index (schema v4). The index is disposable — deleting it loses chat history and cached summaries but nothing else; source sessions remain in each provider's own store and reindex from scratch.
Providers implement SessionProvider and return normalized Session objects plus user/assistant messages:
from pathlib import Path
from agent_sessions.providers import register_provider
from agent_sessions.providers.base import SessionProvider
@register_provider
class MyProvider(SessionProvider):
name = "my-tool"
display_name = "My Tool"
icon = "T"
color = "blue"
def get_sessions_dir(self) -> Path:
return Path.home() / ".my-tool" / "sessions"
def discover_session_files(self) -> list[Path]:
...
def parse_session(self, path: Path):
...
def get_session_messages(self, session) -> list[dict]:
...
def get_resume_command(self, session) -> str:
return f"my-tool --resume {session.id}"Incremental indexing asks each provider when a session last changed. The default reads the session file's own mtime; a provider whose sessions are not single files — database rows, virtual paths — overrides get_session_mtime(path, session_id) to report change time in epoch seconds.
pip install -e ".[dev]"
pytestRelease-facing files are kept at the repository root. Local notes, generated metadata, caches, and other non-release artifacts belong in ignored .dev/.
MIT. See LICENSE.
