Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .claude-plugin/marketplace.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@
{
"name": "agsearch",
"source": "./",
"description": "Search your past Claude Code and Codex sessions from inside Claude"
"description": "Search your past Claude Code, Codex, Cursor, opencode and Gemini CLI sessions from inside Claude"
}
],
"description": "agsearch: search your past Claude Code and Codex sessions from inside Claude"
"description": "agsearch: search your past Claude Code, Codex, Cursor, opencode and Gemini CLI sessions from inside Claude"
}
2 changes: 1 addition & 1 deletion .claude-plugin/plugin.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "agsearch",
"description": "Search your past Claude Code and Codex sessions from inside Claude",
"description": "Search your past Claude Code, Codex, Cursor, opencode and Gemini CLI sessions from inside Claude",
"version": "0.1.0",
"author": { "name": "Dev Dalia" },
"homepage": "https://github.com/devcodes9/agsearch",
Expand Down
31 changes: 31 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,39 @@ migration in the same line.

## [Unreleased]

### Added

- **Cursor, opencode and Gemini CLI sessions are indexed, searched and resumed** alongside
Claude Code and Codex. Cursor keeps each chat as a SQLite store under
`~/.cursor/chats/`, opened read-only, reading message records and skipping the binary and
image blobs beside them; it resumes with `cursor-agent --resume <id>`. Gemini keeps one JSON
object per session under `~/.gemini/tmp/`, and resumes with `gemini --session-file <path>`
because its `--resume` takes a project-scoped index number rather than a stable id.
opencode keeps every session in one database, so it also resumes by id
(`opencode --session <id>`) but is read as a whole.
On a 852-session corpus, adding 101 Cursor sessions moved held-out ranking by +0.004, so
existing searches are unaffected.
- **A transcript file may now hold more than one session.** The indexer took the first row's
id as the id for the entire file, which is right for a file per session and wrong for a
harness that keeps them all in one database: every session but the first was unreachable.
It now registers each session a file contains, and reading one filters to it. No change for
Claude Code, Codex, Cursor or Gemini, which write one session per file.

### Changed

- **The source column spells the tool out** (`claude`, `codex`, `cursor`, `opencode`,
`gemini`) instead of a two-letter code. `cc` and `cx` were guessable with two harnesses and
are not with five. The name is now stored once per harness and used for the column, the
assistant turn label and the preview, so those cannot drift apart, and the column width is
derived from the longest name so adding a harness cannot misalign the list.

- **Harnesses are described by one source table instead of a ternary in five places.** Adding
an agent was supposed to be one line, but the file extension, the parser used for preview,
the row label, the preview label and the resume command each decided for themselves what a
source was, and two of them had already drifted (`codex` against `cx`). They now read one
record per harness, so a new agent is a parser plus one entry. Behaviour for Claude Code and
Codex is unchanged; the cache format bumps to 7 and reindexes once on first run.

- **Piped output is shaped for the program reading it.** `-n` and `read` are what a coding
agent sees, and an agent pays per character for what a terminal gets free. Behind the same
not-a-terminal test the colour seam already uses: session ids shorten to the shortest prefix
Expand Down
33 changes: 22 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

<p align="center">
Ranked full-text search across the coding-agent sessions already on your machine.<br>
<strong>Claude Code</strong> and <strong>Codex CLI</strong> today, more next.
<strong>Claude Code</strong>, <strong>Codex</strong>, <strong>Cursor</strong>, <strong>opencode</strong> and <strong>Gemini CLI</strong>.
</p>

<p align="center">
Expand All @@ -16,8 +16,8 @@
</p>

agsearch indexes the local transcripts your coding agents already write. Search them in one
ranked list, preview the matching lines, and resume the original Claude Code or Codex session.
Everything stays on your machine.
ranked list, preview the matching lines, and resume the original session in the tool it came
from. Everything stays on your machine.

<p align="center"><img src="https://raw.githubusercontent.com/devcodes9/agsearch/main/docs/demo.gif" alt="Searching 52 sessions; the second query is misspelled and still lands on the right one" width="100%"></p>

Expand All @@ -42,10 +42,9 @@ uvx agsearch -n "stripe tax id"

- **Full-conversation search.** Search user prompts and assistant replies, not only titles and
session metadata.
- **One list for both tools.** Claude Code and Codex sessions appear together, labelled `cc`
and `cx`. Adding another agent is a parser plus a source entry, with no change to search or
ranking — [Gemini CLI and opencode](https://github.com/devcodes9/agsearch/issues/40) are the
tracked candidates.
- **One list for every tool.** Sessions from all five agents appear together, each row named
after the tool it came from. Adding another agent is a parser plus one entry in the source
table, with no change to search or ranking.
- **Ranked results.** BM25 ranking favors focused sessions and shows matching lines in context.
- **Preview, read, or resume.** Inspect a match, open the transcript in a pager, or return to the
original session.
Expand Down Expand Up @@ -156,8 +155,8 @@ Either way it needs the `agsearch` binary, which the installation section above
| <kbd>Ctrl-Y</kbd> | Copy the resume command |
| <kbd>Ctrl-/</kbd> | Toggle the preview pane |

Selecting a result starts `claude --resume` or `codex resume` from the session's project
directory. The current query is copied to the clipboard so you can find the same text after
Selecting a result resumes the session in the tool that created it, from that session's
project directory. The current query is copied to the clipboard so you can find the same text after
resuming.

For a global shortcut, see the
Expand Down Expand Up @@ -189,8 +188,20 @@ words, and the first result is not guaranteed to be the session you intended.

agsearch reads:

- `~/.claude/projects/**/*.jsonl`
- `~/.codex/sessions/**/*.jsonl`
| Agent | Read from | Resumed with |
| --- | --- | --- |
| Claude Code | `~/.claude/projects/**/*.jsonl` | `claude --resume <id>` |
| Codex | `~/.codex/sessions/**/*.jsonl` | `codex resume <id>` |
| cursor-cli | `~/.cursor/projects/**/agent-transcripts/` | `cursor-agent --resume <id>` |
| opencode | `~/.local/share/opencode/opencode.db` | `opencode --session <id>` |
| Gemini CLI | `~/.gemini/tmp/**/chats/*.json` | `gemini --session-file <path>` |

opencode keeps sessions in SQLite; agsearch opens it read-only and reads message records
only. Gemini's `--resume` takes a project-scoped index number rather than a stable id, so
resume goes through the transcript file instead.

Cursor and Gemini are read from their CLI's storage. Chats made in the Cursor IDE are kept
elsewhere and are not indexed, which is why the column names the CLI.

Its cache lives under `~/.cache/agsearch/`. Transcript parsing and ranking happen locally, and
only changed files are reparsed.
Expand Down
Loading