Skip to content
Open
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
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
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,33 @@ migration in the same line.

## [Unreleased]

### Added

- **Cursor, opencode and Gemini CLI sessions are indexed, searched and resumed** alongside
Claude Code and Codex, labelled `cu`, `oc` and `gm`. 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 run --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

- **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
30 changes: 19 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, labelled `cc`,
`cx`, `cu`, `oc` and `gm`. 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,17 @@ 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 | `~/.cursor/chats/**/store.db` | `cursor-agent --resume <id>` |
| opencode | `~/.local/share/opencode/opencode.db` | `opencode run --session <id>` |
| Gemini CLI | `~/.gemini/tmp/**/chats/*.json` | `gemini --session-file <path>` |

Cursor and opencode keep sessions in SQLite; agsearch opens those 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.

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