The short answer
AgentSight v1.0.30 scans four provider-owned roots: Claude Code under ~/.claude/projects, Codex under $CODEX_HOME/sessions or ~/.codex/sessions, Gemini CLI under~/.gemini/tmp, and Cursor under ~/.cursor/projects. It recognizes provider-specific transcript formats, caches parsed candidates, deduplicates the visible session list, and limits ordinary discovery to the newest 25 sessions.
Codex is different when state_5.sqlite exists. AgentSight opens that database read-only, queries the newest thread records, and uses the recorded rollout path, model, token count, preview, working directory, and timestamps as a lightweight index. Full rollout events remain lazy: AgentSight reads only a bounded tail for summary metadata and parses the complete matching transcript only when detail is requested.
What AgentSight scans
| Agent | Discovery root | Recognized transcript | Session-ID path |
|---|---|---|---|
| Claude Code | ~/.claude/projects | JSONL beneath .claude | The transcript file stem is the session ID. |
| Codex | $CODEX_HOME/sessions when CODEX_HOME is an absolute path; otherwise ~/.codex/sessions | JSONL beneath .codex; current Codex can also be indexed through state_5.sqlite. | The scanner reads the bounded header and extracts the session_meta.id; the SQLite fast path already supplies the thread ID. |
| Gemini CLI | ~/.gemini/tmp | JSON session files beneath .gemini | The bounded JSON header supplies sessionId. |
| Cursor | ~/.cursor/projects | JSONL under an agent-transcripts path, including subagent activity | The parent transcript file stem is the session ID; duplicate candidates are collapsed. |
These are implementation paths, not a compatibility promise for every future upstream release. AgentSight deliberately classifies files by both provider-owned path and expected format rather than treating every JSON or JSONL file in a home directory as a session.
Discovery is an index first, transcript parsing second
A naive implementation could fully parse every historical transcript on every top or browser request. v1.0.30 avoids that. The native analysis layer keeps a session cache and first builds a candidate list ordered by update time. Ordinary list discovery is clamped to at most 25 sessions. It then removes duplicate display IDs, enriches Cursor entries, applies optional PID/text filters, and returns the bounded list.
Detail lookup uses a separate ID-to-path index. When a requested ID is not already present—or its stored path disappeared—the index is rebuilt from discovered session files. Only the matching candidate is refreshed and parsed. AgentSight checks that the parsed transcript still reports the requested session ID before returning it. This makes detail lookup an exact match rather than “the newest file that looks close.”
Why Codex gets a SQLite fast path
When ~/.codex/state_5.sqlite is readable, AgentSight opens it with SQLite read-only flags and queries the threads table ordered by updated_at_ms. The selected fields include the thread ID, rollout path, model, source-reported token total, preview, working directory, and timestamps. That is enough to construct a useful session row without initially parsing the entire rollout file.
For summary metadata that is not already in SQLite, the implementation reads at most the final 1 MiB of the rollout. A cache keyed by file path, length, and modification time avoids re-reading an unchanged tail. If callers later ask for prompts, LLM responses, or tool events, hydrate_session parses the matching rollout and merges the richer events back into the indexed record.
If the Codex state database is absent or cannot be opened, discovery does not fail globally. AgentSight falls back to the same cached transcript discovery used for the other providers.
Cursor needs special handling for subagents and duplicate windows
Cursor's parent transcript is not always the only file whose modification time matters. For a Cursor candidate, AgentSight also inspects sibling subagents/*.jsonl files and treats the newest child modification as part of the parent session's update time. That keeps a parent session fresh when work continues in a subagent transcript.
Cursor discovery can also produce more than one candidate with the same file stem. The deduplication pass prefers a candidate outside the special empty-window tree and otherwise chooses the newer candidate. This is provider-specific normalization, not a generic “same filename means same conversation” rule applied across agents.
Detail responses are bounded even after hydration
Lazy parsing prevents unnecessary work, but a single giant transcript can still be expensive to return. v1.0.30 therefore bounds hydrated detail. It retains at most 1,000 prompt events, 2,000 LLM responses, and 2,000 tool events. Prompt and response text each get a 2 MiB budget; tool command text gets 1 MiB. Per-tool process chains and path/domain collections are also capped before a session detail leaves the analysis layer.
These limits matter when using native sessions as evidence. A detail view is intentionally the bounded, recent representation AgentSight exposes—not an assertion that every byte of an arbitrarily large provider history was returned. Keep the provider-native file if an investigation requires the complete original transcript.
Why a local session can be missing
| Symptom | Implementation-level explanation to check |
|---|---|
| An old session is not in the normal list. | List discovery is intentionally bounded to the newest 25 candidates and applies a maximum-age window supplied by the caller. |
| Codex sessions disappeared after moving its home. | AgentSight honors CODEX_HOME only when it is an absolute path; otherwise it falls back to ~/.codex. |
| A transcript-shaped file is ignored. | Path ownership and extension both matter: Claude/Codex expect JSONL, Gemini expects JSON, and Cursor expects JSONL under agent-transcripts. |
| A Cursor duplicate is not shown twice. | Cursor candidates with the same stem are intentionally deduplicated, preferring non-empty and newer windows. |
| A direct detail lookup returns no session. | The indexed path must still exist, the candidate must parse, and the parsed session ID must exactly match the requested ID. |
The first troubleshooting step is therefore to check the provider's native state and the exact discovery root before assuming an eBPF or network problem. Local-session discovery is a filesystem/provider-state path; eBPF recording is a separate sensor. The no-eBPF evidence guide explains when to use each mode.
Discovery does not make provider state an independent system trace
This index is useful because provider-native state can be authoritative for session IDs, prompts, token fields, model metadata, and native tool records. It is not independent proof of every process, file, or network effect produced by the run. When that distinction matters, preserve the row provenance and combine the right sensors rather than promoting native transcript data into kernel evidence.
For row-level lineage and confidence semantics, see the audit provenance guide. For Docker-backed native discovery, where the same local logic runs inside a named container through a bounded bridge, see the Docker session architecture guide.
Primary sources
- AgentSight v1.0.30 session parser: discovery roots, path classification, Cursor deduplication, and session-file formats
- AgentSight v1.0.30 native analysis source: Codex SQLite preference, bounded indexing, ID resolution, caching, and lazy detail hydration
- AgentSight v1.0.30 README: native-session workflows and current platform boundary
- AgentSight v1.0.30 usage guide: top, bind, report, and vis behavior
Research scope: AgentSight v1.0.30 at commit 934f441eff8c, inspected on 31 August 2026. Provider storage formats can change independently; use the current AgentSight repository when validating a newer release.