Search a repo's issues and pull requests on your machine
Search a repo's issues and pull requests locally. Export them to JSONL, index the folder, and query that index instead of reading gh JSON. On 2026-10-20 the gh capture file was 36,550 bytes and the xerj search capture file was 1,865 bytes. Two of the three passages were cited as line 1.
Key number: The captured gh search file was 36,550 bytes and the xerj search file was 1,865 bytes. (as of 2026-10-20 · source: benchmarks/agent-queries-2026-10-20/01-byte-compare.txt)
TL;DR — Search a repo's issues and pull requests locally. Export them to JSONL, index the folder, and query that index instead of reading gh JSON. On 2026-10-20 the gh capture file was 36,550 bytes and the xerj search capture file was 1,865 bytes. Two of the three passages were cited as line 1.
Read https://xerj.org/llms.txt. Start one local node. Export issues and pull requests to JSONL, run xerj autoindex, then search with a _search body that lists _source fields. Report number, title and state. If a passage is cited as line 1 for two different issues, trust number and title, not the line.
xerj autoindex --url http://127.0.0.1:9217 --yes --no-graph --progress plain --disable-feedback /tmp/xerj-aq-2026-10-20/issues --prefix gh --state-dir /tmp/xerj-aq-2026-10-20/state-gh
Index the export. 1,532 records, wall 7.2 s.
xerj search --url http://127.0.0.1:9217 --prefix gh -k 3 xerj feedback --open-pr commits and pushes
Three passages. Two were labeled issues.jsonl:1.
curl -s -XPOST http://127.0.0.1:9217/gh-*/_search -H 'content-type: application/json' -d '{"size":5,"_source":["number","title","state","url"],"query":{"multi_match":{"query":"xerj feedback --open-pr commits and pushes","fields":["title","body"]}}}'
The field list is what an agent should read. Issue 960 ranked first.
XERJ is a new way for AI to search for data.
Export, then index
The capture saved 532 issues and 1,000 pull requests from xerj-org/xerj (gh pr list --limit 1000 returned 1,000). One JSON object per line. xerj autoindex committed 1,532 records in 7.2 s, exit 0. The datasets were gh-jsonl and gh-json, not a name you guess.
xerj-done ok=true exit=0 reason=completed wall=7.2s files=2 records=1532 generation=1
What the agent should call
xerj search --url http://127.0.0.1:9217 --prefix gh -k 3 "xerj feedback --open-pr commits and pushes"
Three passages came back. The command said they are lexical and that it does not consult the embedding. The default embedder is lexical feature hashing. --embed-mode neural was not on. Two passages were labeled issues.jsonl:1. The third had no line. The scores printed were 42.22, then 35.68, then 44.36, so the print order was not score order.
The lines from feedback.rs were inside the issue text. That is a quote of the issue, not a link from the issue to the code.
Return the fields, not the body
curl -s -XPOST http://127.0.0.1:9217/gh-*/_search -H 'content-type: application/json' -d '{"size":5,"_source":["number","title","state","url"],"query":{"multi_match":{"query":"xerj feedback --open-pr commits and pushes","fields":["title","body"]}}}'
took was 7. Issue 960 was first. _savings.bytes was 19,444, measured sampled. The same question through gh issue list --json number,title,body,state,url produced a capture file of 36,550 bytes, because each hit included body.
xerj mcp against this node returned 17 tools, including xerj_search. The server does not start a node.
Measured on 2026-10-20
| Check | Result |
|---|---|
| Index | 1,532 records, wall 7.2 s, exit 0 |
xerj search capture file | 1,865 bytes, 3 passages, two labeled line 1 |
gh issue list --json capture file | 36,550 bytes, bodies included |
_source narrowed to 4 fields | _savings 19,444 bytes, sampled. took 7 |
The byte win sits next to the line-label loss. Use number and title when the line is 1.
When not to use XERJ
If you need live issue state for one number, gh issue view is the current source. The index is the export you last wrote. Re-index when you refresh the file.
FAQ
Search repo issues and PRs locally?
Export both to JSONL and index the folder. Search gh-*. The capture held 532 issues and 1,000 pull requests.
gh issue search returns too much JSON?
The captured gh file, with issue bodies, was 36,550 bytes. The captured xerj search file was 1,865 bytes. Narrow _source when you need fields, not a passage.
Search GitHub issues without cloning the repo?
You do not clone. gh writes the export, and the index stays on the machine. The agent then calls search or xerj mcp.
Does this link an issue to the code?
No. A passage quoted feedback.rs because the issue body contained those lines. There is no call graph.
Why do two hits say line 1?
In this capture xerj search labeled two different passages issues.jsonl:1. Read number and title from _source.
Evidence
- The issue export indexed in 7.2 s, 1,532 records, exit 0. —
benchmarks/agent-queries-2026-10-20/01-autoindex-issues.txt - xerj search's capture file was 1,865 bytes and the gh capture file was 36,550 bytes. —
benchmarks/agent-queries-2026-10-20/01-byte-compare.txt - The narrowed _search response reported _savings of 19,444 bytes, sampled. —
benchmarks/agent-queries-2026-10-20/01-duplicate-search.json - tools/list returned 17 tools. —
benchmarks/agent-queries-2026-10-20/05-tool-names.txt
Related
- What's the easiest way to search JSON logs plus some old gzip text logs in the same folder?
- I need my agent to find a passage and cite the file, not dump the whole tree. How?
- How do I keep a search index up to date as files change, without re-indexing everything?
- Find duplicate GitHub issues before you file