Skip to content

About

Command line search over local Claude Code and Codex conversation transcripts.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

agsearch

Search your local coding conversation history from the command line.

Claude Code and Codex record conversations as .jsonl transcripts. agsearch searches both Stores by default, so you do not need to remember which Harness you used.

$ agsearch "borrow checker"
claude · d712581e · E:\projects\rust\demo · Lifetimes and the borrow checker · 2026-06-02 · main
  [14] user: how do I satisfy the borrow checker here without cloning
  [16] assistant: …the borrow checker is complaining because the reference outlives…
  … +3 more  ›  agsearch show d712581e

$ agsearch show d712581e        # reopen the whole conversation
$ agsearch current             # inspect the Session that invoked this command

Why

The transcripts use Harness-specific layouts and JSON formats. agsearch turns them into six jobs:

  • find a conversation with agsearch <query>
  • read a conversation with agsearch show <id>
  • inspect the Current Session with agsearch current
  • preserve a conversation with agsearch export <id> <file>
  • analyse what went wrong with agsearch --failed or --stats
  • measure token Usage with agsearch usage or agsearch usage <id>

Status: early. agsearch is at 0.x. Verbs and flags can still change between minor versions. Open an issue if something breaks for you.

Install

Prebuilt binaries for Linux, macOS, and Windows are attached to each GitHub Release. The installers put the agsearch binary onto your PATH:

# Linux / macOS
curl --proto '=https' --tlsv1.2 -LsSf https://github.com/Hazzajenko/agent-conversation-search/releases/latest/download/agsearch-installer.sh | sh
# Windows
powershell -ExecutionPolicy Bypass -c "irm https://github.com/Hazzajenko/agent-conversation-search/releases/latest/download/agsearch-installer.ps1 | iex"

With a Rust toolchain:

cargo install agsearch          # from crates.io
# or, from a clone of this repo
cargo install --path .

agsearch reads $CLAUDE_CONFIG_DIR or ~/.claude for Claude Code and $CODEX_HOME or ~/.codex for Codex. For OpenCode it reads opencode.db in $XDG_DATA_HOME/opencode or ~/.local/share/opencode, on every platform. Use --claude-dir <PATH>, --codex-dir <PATH>, or --opencode-dir <PATH> to override a Store. A missing Store is skipped. Search, show, sessions, projects, --failed, and --stats cover OpenCode Sessions. An OpenCode Failure is a tool call with status error. A shell command that exits non-zero but completes is not a Failure. For an OpenCode Session, -l prints <path to opencode.db>#<session id>, and show - accepts that form.

Windows and WSL keep separate histories. Run agsearch in the environment that has the Sessions, or point the Store flags at the other environment.

The core workflow

Every verb is welded together by one identifier: the short session-id. It is a git-style unique prefix. It is the shortest prefix of the session-id that no other Session in any Store shares, with at least 8 characters. search and --failed print it, and show resolves it. That is the whole loop. Find something, copy its id, open it:

$ agsearch "diesel migration"      # find, then note the id in each header
$ agsearch show 4c28878f           # read the full transcript
$ agsearch show 4c28878f --around 220   # read just the turns around turn 220

You can also pipe by path instead of copying ids:

$ agsearch -l "diesel migration" | agsearch show -   # open the first match

Verbs

search (the default)

agsearch <query> searches the current directory's Project for a case-insensitive substring, grouped by Session, newest first. It is the default verb, so the word search is optional (agsearch foo ≡ agsearch search foo).

Flag Effect
-e, --regex treat the query as a regular expression
-s, --case-sensitive match case-sensitively
--thinking also search assistant thinking blocks
--tools also search tool calls and tool results
--all-content search everything (--thinking --tools)
-m, --max-per-session <N> cap matches shown per Session (0 = unlimited, default 3)
-l, --files print only matching file paths, for piping
--file <SELECTOR> list file Touches by File Selector. With a Query, search text only inside Sessions touching the file
--written with --file, show only write Touches (Edit, Write, MultiEdit, NotebookEdit, Codex apply_patch, OpenCode edit, write, and patch)
--harness <claude|codex|opencode> search only one Harness
--include-subagents include Codex subagent Sessions and OpenCode child sessions and mark them in output
--include-current include the Current Session Family (excluded by default)

By default only Prompts, Replies, and Titles are searched. Thinking and tool content are opt-in.

Search covers historical conversations. When a Harness identifies the Current Session, search excludes its Current Session Family. This prevents a search from matching the Prompt that started the search.

Pass --include-current to include the family. Pass --session current to search the top-level Current Session directly, or --session current-thread to search the calling thread. At the top level that is the same Session. From a spawned worker it is the worker's own thread. A Session id selects that Session even when it belongs to the family.

The exclusion also covers --failed and --stats. When --include-subagents is active, it hides every worker in the family. Outside a supported Harness, no Current Session is available and search excludes nothing.

When identity resolves only partly, search hides every family it can identify. If both Harnesses identify a Session, search excludes both families. If a family ancestor is missing from the Store, search still excludes the calling thread and its workers.

show reads a whole conversation

agsearch show <id> renders a Session as a readable transcript. Tool calls collapse to one-liners, failed tool calls are flagged, and thinking is hidden.

Flag Effect
--thinking expand assistant thinking blocks
--around <turn> show only the turns around this turn, such as a search hit
--context <N> turns of context on either side of --around (default 3)

<id> is a git-style prefix resolved across your whole history. current renders the top-level Current Session and current-thread renders the calling thread, which is the same Session at the top level. - reads a file path from stdin.

current inspects the invoking Session

agsearch current prints the Current Session identified by the Harness that launched the command: Harness, full Session ID, Project, title, source path, and whether the caller is a worker. It does not guess from the newest conversation.

Flag Effect
--id-only print only the full top-level Session ID
--path print only the source Session path

Claude identity comes from $CLAUDE_CODE_SESSION_ID. Codex identity comes from $CODEX_SESSION_ID for the top-level Session and $CODEX_THREAD_ID for the calling thread. At the top level those two identify the same Session. A spawned worker still resolves current to the top-level Session.

If no supported Harness identity is available, the command fails rather than picking a Session. If the identity is not in the configured Stores, it fails. If both Harnesses supply a valid identity, it reports the ambiguity until you pass --harness claude or --harness codex.

$ agsearch current
Harness: claude
Session: 11111111-aaaa-bbbb-cccc-ddddeeee0001
Project: E:\projects\demo
Title: Lifetimes and the borrow checker
Path: C:\Users\you\.claude\projects\E--projects-demo\11111111-aaaa-bbbb-cccc-ddddeeee0001.jsonl
Caller: top-level

$ agsearch current --id-only
11111111-aaaa-bbbb-cccc-ddddeeee0001

export preserves a Session snapshot

agsearch export <SESSION> <DEST> writes one point-in-time snapshot of one Session to one destination. The Session accepts a unique id prefix, current for the top-level Current Session, or current-thread for the calling thread. current exports only the top-level Session, never a combined family document. The destination is required. - writes the Export to standard output.

Flag Effect
--format markdown|raw readable document by default, or an exact raw copy
--force overwrite the destination when it already exists
--thinking expand assistant thinking blocks in Markdown Export

Readable Export (Markdown) is a portable document with provenance followed by the Transcript. Provenance carries the title, full Session ID, Harness, Project, source timestamp, export timestamp, and snapshot status, so the file identifies its origin without agsearch. The Transcript body uses the same renderer as show: Messages only, tool calls as compact one-liners, failed tool results flagged, thinking hidden unless --thinking is passed.

Raw Export (--format raw) copies the Harness Session file exactly, with no added metadata and no interactive confirmation beyond the explicit format option. It is the way to preserve the source data.

Every Export is a snapshot. It captures the content available when the command runs and finishes without waiting for the Harness. A Markdown snapshot renders every complete Record and ignores an incomplete trailing JSONL record. The document identifies itself as a snapshot so nobody mistakes it for a final transcript. A raw snapshot contains the source bytes captured by the operation.

An existing destination file is rejected unless --force is passed, so an earlier snapshot is never destroyed silently.

$ agsearch export 4c28878f transcript.md        # readable snapshot
$ agsearch export current transcript.md         # preserve the Current Session
$ agsearch export current-thread worker.md      # preserve only the calling thread
$ agsearch export 4c28878f - | less             # pipe through stdout
$ agsearch export 4c28878f raw.jsonl --format raw --force

sessions lists conversations

agsearch sessions lists the Sessions in scope, newest first, one per line. Use it when you want to reopen a recent conversation but don't remember anything to search for. Each row is paste-able into show.

$ agsearch sessions
codex · de151981 · E:\projects\rust\demo · Test app runtime and functionality · 2026-06-02
claude · d712581e · E:\projects\rust\demo · Lifetimes and the borrow checker · 2026-06-02 · main

projects lists projects

agsearch projects lists every Project across the whole Store, newest first, with how many Sessions each holds and when it was last touched. The name is the real path, recovered from the transcripts.

$ agsearch projects
E:\projects\rust\agent-conversation-search · 7 sessions · 2026-06-02
E:\projects\games\creature-game · 43 sessions · 2026-06-01

usage ranks Sessions by token Usage

agsearch usage ranks the Sessions in scope by total token Usage, biggest first. It counts tokens only, not money. Use it to find which conversations burned the most tokens. agsearch usage <id> shows one row per model call inside that Session, in turn order for Claude Code or file order for Codex token_count Records, with a total line.

$ agsearch usage
session   project               harness  title                     subagents  calls  input  cache-write  cache-read  output  total
aaaaaaaa  E:\projects\rust\demo  claude   Refactor auth middleware        0      2    215        1,200     165,000  10,600  177,015
bbbbbbbb  E:\projects\rust\demo  claude   Debug flaky test                0      1     80          200      12,000     900   13,180

$ agsearch usage aaaaaaaa
turn  timestamp                 model            input  cache-write  cache-read  output  total    subagent  preview
   2  2026-08-20T04:00:10.000Z  claude-opus-4-6    120          800      45,000   2,100   48,020            Draft the middleware refactor plan
   4  2026-08-20T04:00:20.000Z  claude-opus-4-6     95          400     120,000   8,500  128,995            Apply the edit to auth.rs
total                                               215        1,200     165,000  10,600  177,015            2 calls
Flag Effect
--sort {total,output,input,calls} rank by this column, default total. On the breakdown only total is valid. It sorts biggest first, and the default is turn order for Claude Code and file order for Codex
--limit <N> maximum Sessions in the ranking (default 20, ranking only)
--all, --project <substr>, --harness <claude|codex>, --since <when> scope the ranking like sessions (current Project by default)
--include-subagents list subagent threads as their own rows instead of folding them into the parent
--include-current put the Current Session Family back into the ranking (excluded by default)

Subagent threads fold into their parent row by default. The subagents column shows how many were folded. The breakdown of a parent includes its workers' calls marked in the subagent column, so its total matches the ranking row. Sessions with no Usage are omitted with a skipped N sessions with no usage line. The selector accepts the same forms as show: id prefix, current, current-thread. A Codex Session whose summed turns disagree with its final running total keeps the sums and warns on stderr.

Failure analysis

Find and aggregate failed tool calls by structure, independent of any Query. Failure analysis covers historical conversations. It excludes the Current Session Family unless you pass --include-current.

$ agsearch --failed                # list failed tool calls, joined to the command
$ agsearch --failed cargo          # filter failures by command / error text
$ agsearch --stats                 # aggregate into a counts table by tool + error
$ agsearch --stats
19  ✗ PowerShell  error:
 3  ✗ Edit        String to replace not found
… +2 more singleton signatures

One-off signatures fold into the trailing +N more line so the table stays readable at --all scale. If every row is a one-off, all rows are shown. Use --failed to see every failure individually.

Add --full to a --failed listing to print each failure's complete error text instead of the single salient line.

Scope and filters

These compose with search, --failed, --stats, and the listing verbs where noted:

Flag Effect Applies to
(default) the current directory's Project search, sessions, usage
--all every Project in your history search, sessions, usage
--project <substr> Projects whose name contains the substring search, sessions, projects, usage
--session <selector> one Session, selected by id-prefix, current, or current-thread. The selected Session remains included when it belongs to the Current Session Family search
--file <SELECTOR> list Touches of the selected file. With a Query, restrict Matches to touching Sessions search
--written with --file, keep only write Touches search
--include-current put the Current Session Family back into the results search, --failed, --stats, usage
--since <when> only Sessions/Projects touched since a duration (3d, 2w, 1h) or ISO date (2026-05-01) all

The default scope merges Sessions from both Harnesses by their encoded working directory. projects shows one row when both Harnesses used the same directory. Subagent threads stay excluded unless you pass --include-subagents. usage instead folds workers into the parent row unless you pass it. sessions and projects are inventory verbs. They keep listing and counting the Current Session. usage ranking excludes the Current Session Family like search and failure analysis.

Output and exit codes

  • Output is colorized on a TTY and plain when piped or under NO_COLOR.
  • "No matches" / "No sessions" / "No projects" / "No sessions with usage" exit 0. An empty result is not an error.
  • Bad input exits non-zero with a readable message. Bad input is an unparseable regex, an unparseable --since, an ambiguous id, a missing Session, unavailable or ambiguous current context, or an existing Export destination without --force.

As a Claude Code plugin

This repo also ships a Claude Code skill in skills/agsearch, declared in .claude-plugin/plugin.json. It lets Claude recall past conversations for you, for example "did we ever discuss X?" or "find the session where we set up Y". The skill is thin glue over the same binary, so install agsearch on your PATH first.

The plugin also ships /retro-sessions in skills/retro-sessions. It reads past sessions through agsearch and suggests repo changes that answer a focus you give it, for example /retro-sessions read my last 10 sessions and find where agents took too long to find information. Only you can start it.

Concepts

The precise vocabulary this tool is built around lives in CONTEXT.md: Harness, Project, Session, Record, Message, Query, Match, Failure, Usage, Store. The reasoning behind the bigger design decisions is in docs/adr/. They cover locating Projects, the verb/handoff model, failure grouping, and the listing verbs.

License

MIT.

About

Command line search over local Claude Code and Codex conversation transcripts.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages