Indexed grep + glob for AI agents
Project description
Indexed grep + glob for AI agents.
Ripgrep pays the full scan cost on every query. glep pays it once: a persistent, self-healing trigram index answers warm queries in 21-298 ms on a Linux-kernel-sized tree where ripgrep takes 1.4 s (21 ms in --ttl burst mode), with text output byte-compatible with ripgrep's, enforced by a 24-case differential harness in CI. No daemon.
Why
Coding agents call Grep and Glob dozens of times per session. On monorepo-scale projects each call costs seconds. glep replaces both with index-backed equivalents built on ripgrep's own crates (ignore, grep-searcher, regex-syntax), so correctness is inherited, not reimplemented.
When to use it
| Use glep | Stick with rg / fd |
|---|---|
| Agent sessions firing dozens of searches over one repo (the bundled hook reroutes Grep/Glob) | One-off searches in a tree you will never search again |
| Monorepos where rg takes 100ms+ per query; glep measured 21-298 ms at kernel scale | Small repos where rg already answers in under ~50ms |
Repeated glob listings: glep --files reads the manifest, no re-walk past the freshness sweep |
Ephemeral CI runners where the index never persists between runs |
Read-heavy bursts with --ttl 5 to amortize the freshness sweep |
rg features glep lacks: replacements, PCRE2, compressed files |
| Correctness-critical work: self-healing index, sound full-scan fallback | Corpora dominated by binaries or files over the 1MB cap (live-scanned anyway) |
--hidden includes dotfiles; .git itself is always excluded. --no-ignore always pays a full scan: it bypasses the index entirely (gitignore'd/.ignore'd trees must never enter the index), so it costs the same as rg --no-ignore, every time.
Numbers
Linux kernel 6.12 checkout: 86,605 files, ~1.5 GB. Apple Silicon macOS, hyperfine medians, warm filesystem cache, rg and fd at their default parallelism.
| Scenario | glep | glep --ttl 5 | ripgrep | fd |
|---|---|---|---|---|
| Rare pattern | 173 ms | 21 ms | 1.42 s | |
| Common pattern (~10k matches) | 298 ms | 90 ms | 1.54 s | |
| List all .c files (--files) | 242 ms | 44 ms | 92 ms | |
| Index build (one-time) | 24 s |
Default glep pays the self-healing freshness sweep (a stat of every file) on each query; --ttl amortizes it across read bursts. Index size: 154 MB, about 10% of the corpus. The parity harness pins byte-equality with rg's output; speed differs, bytes do not.
How it works
- A file-level trigram inverted index (the Russ Cox / csearch model) lives in
.glep/, memory-mapped, about 10% of corpus size measured on the kernel tree. - Every query self-heals: a fast parallel mtime sweep incrementally reindexes only what changed, then answers. No watcher, no background process.
- The regex becomes a trigram plan, postings intersection yields a handful of candidate files, and ripgrep's searcher runs over just those.
- Patterns trigrams can't narrow fall back to a full parallel scan: never a wrong answer, worst case is rg-speed.
Interface
glep 'fn parse_intent' src/ # content search (Grep replacement)
glep --files '**/*.py' # glob listing (Glob replacement)
glep --json 'pattern' # machine-readable output for agents (includes rg's closing summary event)
glep -c 'pattern' # per-file match counts (rg -c)
glep -l -i -F -U ... # files-with-matches, case-insensitive, fixed, multiline
glep -A 2 -B 1 'pattern' # context, or -C n for both sides
glep -g '*.rs' -t rust ... # glob and type filters
glep --hidden 'TODO' # include dotfiles (.git is always excluded)
glep --no-ignore ... # search ignored files too (live scan, index untouched)
glep --ttl 5 ... # skip the freshness sweep within a read burst
glep --max-filesize 2000000 ... # raise the 1MB index cap
glep index # explicit (re)build; lazy on first query
glep status # index stats
With an explicit path argument, bytes_printed in the summary can differ from rg's (rg prints ./-prefixed paths; glep prints them bare).
Ships with a Claude Code skill and a PreToolUse hook that routes built-in Grep/Glob calls through glep automatically.
Install
pip install glep # binary wheel, no Rust toolchain needed
# or
cargo install glep
Claude Code integration (skill + hook): claude/install.sh.
Cursor integration (hook): cursor/install.sh.
Status
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file glep-0.3.0-py3-none-win_amd64.whl.
File metadata
- Download URL: glep-0.3.0-py3-none-win_amd64.whl
- Upload date:
- Size: 1.6 MB
- Tags: Python 3, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a3bc3d70c4a3db2a963828b84b5281583f342b0b9fec4f044833d2048c0f80e
|
|
| MD5 |
e963e98f57f8983fdc9d7837b4ba1dc2
|
|
| BLAKE2b-256 |
8d3fe8d71582393f41e3eb3e45be6ed9b2aabb00a5721a42e2550bf099aeb0f6
|
File details
Details for the file glep-0.3.0-py3-none-musllinux_1_2_x86_64.whl.
File metadata
- Download URL: glep-0.3.0-py3-none-musllinux_1_2_x86_64.whl
- Upload date:
- Size: 2.0 MB
- Tags: Python 3, musllinux: musl 1.2+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
56a149b8f5e7d485c6a4178ab2badd430812848e53d48cf6166abd8c8e76e205
|
|
| MD5 |
c3d86b25ef80d475b434b640908281fe
|
|
| BLAKE2b-256 |
836fb249e958498779c13bab19c2d443678f45ea8f0c43e5f3f33ffb24e68893
|
File details
Details for the file glep-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl.
File metadata
- Download URL: glep-0.3.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3, manylinux: glibc 2.17+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c7e649450edc403058af9f2188f5adb4b77a285c832506e9f969fc2230e7b3ab
|
|
| MD5 |
948dade64f69285a3d65c683c894654d
|
|
| BLAKE2b-256 |
51fe737abf48779b6a87759e41619c418bd0afaa87e3ecda3c962860fcbf28d5
|
File details
Details for the file glep-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl.
File metadata
- Download URL: glep-0.3.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl
- Upload date:
- Size: 1.9 MB
- Tags: Python 3, manylinux: glibc 2.17+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9a4be6055421c09631a43bac0c50efe2ed6bcfb534e5ded9cb78810e1fc98fc6
|
|
| MD5 |
518761d46f6e841246e98d9e2afd20f1
|
|
| BLAKE2b-256 |
8f6055f27d900ecbfc619f91a8de2260403a71782574ed2db32e7e8fc2b31325
|
File details
Details for the file glep-0.3.0-py3-none-macosx_11_0_arm64.whl.
File metadata
- Download URL: glep-0.3.0-py3-none-macosx_11_0_arm64.whl
- Upload date:
- Size: 1.8 MB
- Tags: Python 3, macOS 11.0+ ARM64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a54f31999507ba8c294f0d7811645cabdd5556b391bc914cd9f93280fdc00070
|
|
| MD5 |
6d3f432302c6ce5f047236f036f51566
|
|
| BLAKE2b-256 |
713302f08acb83d0e8d2478149e89f57515c7ecb4f84f71b196df794c7c9e9a3
|
File details
Details for the file glep-0.3.0-py3-none-macosx_10_12_x86_64.whl.
File metadata
- Download URL: glep-0.3.0-py3-none-macosx_10_12_x86_64.whl
- Upload date:
- Size: 1.8 MB
- Tags: Python 3, macOS 10.12+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.14.1
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85b51c26c2fed9d4e6006d9480be56716deba4eadc6574d6ca970c1e92520e8a
|
|
| MD5 |
18d4cf6d9d475add341d4a958f557bdc
|
|
| BLAKE2b-256 |
b98cc30f86b019af77c46775f40d3c126b935274e5b3a0cf06ef1d12d23cb0d7
|