Turn code tasks, diffs, and stack traces into local, relationship-aware context packs for coding agents.
See the code
Turn coding tasks into bounded, branch-aware context.
Search, indexing, and context generation run locally. Optional model profiles download pinned assets on first use.
Website · Architecture · Benchmarks · Contributing · Discussions
# Find code by intent
ig "where is refresh token rotated?"
# Build context from code and current changes
ig context "fix refresh-token races" --since main --budget 8000
Abridged output:
# ivygrep context
Budget: 7642 / 8000 estimated tokens
Coverage: 7 files | 2 primary | 1 definitions | 1 dependencies | 0 dependents | 2 callers | 0 references | 1 tests | 0 config | 0 docs
Candidates: 31 retrieved | 14 selected
## Evidence
### 1. src/auth/refresh.rs:118-166 [primary, definition]
Why: task anchor; changed implementation.
Signals: lexical, symbol, git change.
Search answers where. Context answers what an agent needs to change safely.
The context command combines task anchors with commits since the branch point, staged and dirty files,
issue or trace paths, and indexed relationships. It returns one bounded Markdown pack with path, lines,
role, reason, and retrieval signals. --since takes a branch or revision such as main, HEAD~3, or
@{upstream} and requires a Git worktree; omit it for non-Git directories.
# Homebrew on macOS or Linux
brew install bvolpato/tap/ivygrep
# Release installer on macOS or Linux
curl -fsSL https://raw.githubusercontent.com/bvolpato/ivygrep/main/install.sh | sh
# WinGet on Windows
winget install --id BrunoVolpato.ivygrep --exact
# Release installer on Windows
irm https://raw.githubusercontent.com/bvolpato/ivygrep/main/install.ps1 | iex
Installers select a compatible archive, verify its SHA-256 checksum, install ig, and report the selected backend. Apple Silicon uses Metal. NVIDIA Linux hosts use the Linux x86_64 CUDA build when CUDA 13 and compute capability 8.0 or newer are available. Other systems use portable local inference. GPU builds only speed up transformer profiles (IVYGREP_MODEL_PROFILE=code|code-hq|general); the default potion-code-16m-v2 profile runs on CPU. Run ig hardware to see detected hardware, compatibility limits, and the matching reinstall command.
Build from source on macOS or Linux:
git clone https://github.com/bvolpato/ivygrep.git && cd ivygrep
./build.sh
mkdir -p ~/.local/bin
install -m 0755 target/release/ig ~/.local/bin/ig
The first query indexes the current repository. The daemon then watches for changes and updates the index incrementally.
ig "where is authentication handled?" # hybrid semantic + lexical
ig --literal "handleAuth" # exact indexed lookup
ig --symbol calculate_tax # definitions
ig --refs calculate_tax # references and calls
ig --callers calculate_tax # caller chunks
ig "database migrations" src/api/ # path scope
ig --all "retry policy" # all indexed projects
ig --interactive "auth flow" # terminal UI
ig --web "auth flow" . # local Web UI
Useful controls include -n for result files, -C for context lines, --type
for language, --include/--exclude path globs, --lexical-only, --hash, and --json. --hash
uses lightweight local embeddings for faster startup and no model download,
with lower semantic quality. Run ig --help for full reference.
Standalone uppercase AND, OR, and NOT are Boolean operators. ig "settings NOT render" keeps
only results without render, and a malformed one-line expression such as a trailing OR fails with an
error instead of guessing. A query that spans several lines or has 13 or more words and is not a valid
Boolean expression, such as pasted issue text with SQL or an emphasized NOT, is searched as plain text
instead: the operator words count as ordinary words, and the results come with a warning that says so
(on stderr for the CLI, in warnings for MCP and the Web UI). A prompt that does parse is still a
Boolean query, so an uppercase NOT in it excludes the next term. To search those words as text, write
them in lowercase or wrap them in backticks or quotes.
Multi-line queries that read as pasted source rank the code that contains the snippet above one-line
definition signatures that share a few of its identifiers. Multi-paragraph prompts, pasted issue text,
and questions with a blank line rank as prose, with signature matches scored like body text. For pasted
error output, such as a traceback, a Caused by: chain, or a panicked at line, lexical, path,
hash-vector, and reranking signals ignore runtime values such as paths outside the workspace, ids, and
timestamps, and the static message text is matched against the code that raises it. Neural query vectors
still embed the original text.
On macOS laptops, background neural enhancement pauses on battery power (ig --status
shows Paused: Battery Power); set IVYGREP_ENHANCE_ON_BATTERY=1 to keep it running.
The lightweight hash tier keeps computing on battery so semantic results stay available.
However many workspaces change at once, at most two hash and two neural enhancement
workers run at a time (IVYGREP_ENHANCE_MAX_WORKERS); the rest wait in the daemon, and the
workspace searched or edited last goes first.
Index notes once. Watcher keeps them current, and queries use local semantic + lexical search by default:
ig --add ~/notes --wait-for-enhancement
ig -n 20 "what did we decide about cache invalidation?" ~/notes
Public MemoryQuest results (v1.2.7): 74.9% recall@20 at 87.63 ms warm p95. Benchmark measures retrieval only; answer accuracy is outside scope.
Codex and Claude Code packages install MCP configuration plus focused task-context skill:
codex plugin marketplace add bvolpato/ivygrep
codex plugin add ivygrep@ivygrep
claude plugin marketplace add bvolpato/ivygrep
claude plugin install ivygrep@ivygrep
Automatic setup detects the client, preserves existing configuration, writes the absolute ig path, verifies the MCP handshake, and runs a search:
ig agent install claude
ig agent install codex
ig agent install cursor
ig agent doctor
Restart an open client after installation. Manual MCP setup is also available:
claude mcp add -s user ig -- ig --mcp
codex mcp add ig -- ig --mcp
gemini mcp add --scope user --transport stdio ig ig --mcp
Cursor .cursor/mcp.json:
{"mcpServers":{"ig":{"type": "stdio", "command": "ig", "args": ["--mcp"]}}}
OpenCode opencode.json:
{"mcp":{"ig":{"type": "local", "command": ["ig", "--mcp"], "enabled": true}}}
Agents call ig_search for discovery. Set output=context_pack and budget_tokens=8000 when the task needs implementation context. Pass the absolute path to the active repository or worktree. Worktrees reuse the base index and store only changed chunks and tombstones.
Context packs can include definitions, callers, references, dependencies, dependents, tests, configuration, and docs.
Setup guides: Codex, Claude Code, Cursor, Gemini CLI, OpenCode, and MCP.
Recommended agent instruction:
Use ivygrep before broad filesystem scans. Pass absolute active worktree path.
Use natural-language queries for concepts and literal=true for identifiers.
For implementation, request output=context_pack with budget_tokens=8000.
Fresh indexing publishes lexical results before vector enhancement. Worktrees reuse base index and store only divergent chunks and tombstones. Partial workspace failures return warnings with valid hits; complete failure errors.
ivygrep supports 45 language and file types. Twenty-four use Tree-sitter AST chunking: Rust, Python, Go, JavaScript, TypeScript, Java, C, C++, C#, Kotlin, Scala, PHP, Ruby, Swift, Elixir, Zig, Bash, Haskell, OCaml, Lua, Dart, Objective-C, Perl, and Starlark.
Read architecture for storage, commit order, retrieval, worktrees, protocols, security boundaries, and module ownership.
On the deterministic synthetic one-million-chunk CC0 corpus, v1.2.7 median hash-only warm CLI p95 is 6.19 ms, controlled indexing reaches 150,576 chunks/s, and the final index is 0.42 GiB across three sequential trials. This is a scale and footprint measurement, not semantic quality or agent-task performance. Hardware, repository shape, index state, and load affect absolute results.
Latest measured release (v1.2.7) · Million-chunk methodology and historical paired study · Full benchmark dashboard
Runtime source, queries, embeddings, results, and indexes stay local. Neural
profiles download pinned model assets on first use unless cache is already
populated. Use --hash, ./build.sh --hash-only, or
cargo build --locked --no-default-features to avoid model downloads.
ig --web binds to loopback by default and always prints an authenticated URL: the Web API requires the per-daemon session token on loopback too, so other local users cannot read indexed code through it. The printed URL contains the token, so keep terminal output and logs that capture it private. The browser opens through an owner-only redirect file under the ivygrep app home, which keeps the token out of process arguments; set IVYGREP_NO_BROWSER=1 to skip the browser. A non-loopback listener still uses plain HTTP. Use a trusted network, Tailscale, or an encrypted tunnel, and never expose the listener directly to the internet. File contents, including non-ignored dotfiles, can appear in the local index and snippets.
Report vulnerabilities through a private security advisory. Release archives include checksums, SBOMs, and provenance.
Indexes and daemon state live in ~/.local/share/ivygrep on every OS (under %USERPROFILE% on Windows).
IVYGREP_HOME overrides that path; otherwise a non-empty XDG_DATA_HOME selects $XDG_DATA_HOME/ivygrep.
Model assets use the Hugging Face cache (HF_HOME, default ~/.cache/huggingface), which other tools may share.
There is no configuration file. Use CLI flags and the environment variables.
ig --status # tracked workspaces, index health, vector coverage, disk usage
ig --rm ~/notes # remove a saved index; defaults to current directory
ig --gc # remove indexes whose directory has been gone past the grace period
The daemon also removes the index of a directory that stays missing for seven days (IVYGREP_INDEX_GC_GRACE_SECS), and the overlay of a worktree removed with git worktree remove after ten minutes.
ig --doctor # diagnose index, daemon, watcher, and model health
ig --doctor --fix # repair a broken or stale index
ig --add . --force # rebuild current workspace index from scratch
ig hardware # inspect detected hardware and matching build
Open the URL ig --web prints: a bare http://127.0.0.1:4747/ returns 401 until
the browser has the session cookie that URL sets.
If ig --web opens a page that cannot load its redirect file, as snap-packaged
browsers on Ubuntu do for files under hidden directories, open the URL it prints.
Under WSL, a Windows browser can load the redirect file only through an opener
that translates Linux paths, such as wslview; otherwise open the printed URL.
Upgrade through the channel you installed from: brew upgrade ivygrep,
winget upgrade --id BrunoVolpato.ivygrep --exact, or rerun the installer. The
next command restarts a daemon from an older build; index format changes rebuild
existing indexes once on first use.
To uninstall, run brew uninstall ivygrep or winget uninstall --id BrunoVolpato.ivygrep --exact,
or delete ig from the installer directory (~/.local/bin or %LOCALAPPDATA%\ivygrep\bin unless
IVYGREP_INSTALL_DIR was set). Then stop any running ig --daemon process and delete the data directory.
./test.sh --quick
./test.sh
./bench.sh
Start with a good first issue, read CONTRIBUTING.md and architecture, or discuss an idea in Discussions.
MIT licensed. Maintained by Bruno Volpato.
Rust
78.2%
Python
18.6%
TypeScript
1.4%
Shell
1.4%
Turn code tasks, diffs, and stack traces into local, relationship-aware context packs for coding agents.
See the code
Turn coding tasks into bounded, branch-aware context.
Search, indexing, and context generation run locally. Optional model profiles download pinned assets on first use.
Website · Architecture · Benchmarks · Contributing · Discussions
# Find code by intent
ig "where is refresh token rotated?"
# Build context from code and current changes
ig context "fix refresh-token races" --since main --budget 8000
Abridged output:
# ivygrep context
Budget: 7642 / 8000 estimated tokens
Coverage: 7 files | 2 primary | 1 definitions | 1 dependencies | 0 dependents | 2 callers | 0 references | 1 tests | 0 config | 0 docs
Candidates: 31 retrieved | 14 selected
## Evidence
### 1. src/auth/refresh.rs:118-166 [primary, definition]
Why: task anchor; changed implementation.
Signals: lexical, symbol, git change.
Search answers where. Context answers what an agent needs to change safely.
The context command combines task anchors with commits since the branch point, staged and dirty files,
issue or trace paths, and indexed relationships. It returns one bounded Markdown pack with path, lines,
role, reason, and retrieval signals. --since takes a branch or revision such as main, HEAD~3, or
@{upstream} and requires a Git worktree; omit it for non-Git directories.
# Homebrew on macOS or Linux
brew install bvolpato/tap/ivygrep
# Release installer on macOS or Linux
curl -fsSL https://raw.githubusercontent.com/bvolpato/ivygrep/main/install.sh | sh
# WinGet on Windows
winget install --id BrunoVolpato.ivygrep --exact
# Release installer on Windows
irm https://raw.githubusercontent.com/bvolpato/ivygrep/main/install.ps1 | iex
Installers select a compatible archive, verify its SHA-256 checksum, install ig, and report the selected backend. Apple Silicon uses Metal. NVIDIA Linux hosts use the Linux x86_64 CUDA build when CUDA 13 and compute capability 8.0 or newer are available. Other systems use portable local inference. GPU builds only speed up transformer profiles (IVYGREP_MODEL_PROFILE=code|code-hq|general); the default potion-code-16m-v2 profile runs on CPU. Run ig hardware to see detected hardware, compatibility limits, and the matching reinstall command.
Build from source on macOS or Linux:
git clone https://github.com/bvolpato/ivygrep.git && cd ivygrep
./build.sh
mkdir -p ~/.local/bin
install -m 0755 target/release/ig ~/.local/bin/ig
The first query indexes the current repository. The daemon then watches for changes and updates the index incrementally.
ig "where is authentication handled?" # hybrid semantic + lexical
ig --literal "handleAuth" # exact indexed lookup
ig --symbol calculate_tax # definitions
ig --refs calculate_tax # references and calls
ig --callers calculate_tax # caller chunks
ig "database migrations" src/api/ # path scope
ig --all "retry policy" # all indexed projects
ig --interactive "auth flow" # terminal UI
ig --web "auth flow" . # local Web UI
Useful controls include -n for result files, -C for context lines, --type
for language, --include/--exclude path globs, --lexical-only, --hash, and --json. --hash
uses lightweight local embeddings for faster startup and no model download,
with lower semantic quality. Run ig --help for full reference.
Standalone uppercase AND, OR, and NOT are Boolean operators. ig "settings NOT render" keeps
only results without render, and a malformed one-line expression such as a trailing OR fails with an
error instead of guessing. A query that spans several lines or has 13 or more words and is not a valid
Boolean expression, such as pasted issue text with SQL or an emphasized NOT, is searched as plain text
instead: the operator words count as ordinary words, and the results come with a warning that says so
(on stderr for the CLI, in warnings for MCP and the Web UI). A prompt that does parse is still a
Boolean query, so an uppercase NOT in it excludes the next term. To search those words as text, write
them in lowercase or wrap them in backticks or quotes.
Multi-line queries that read as pasted source rank the code that contains the snippet above one-line
definition signatures that share a few of its identifiers. Multi-paragraph prompts, pasted issue text,
and questions with a blank line rank as prose, with signature matches scored like body text. For pasted
error output, such as a traceback, a Caused by: chain, or a panicked at line, lexical, path,
hash-vector, and reranking signals ignore runtime values such as paths outside the workspace, ids, and
timestamps, and the static message text is matched against the code that raises it. Neural query vectors
still embed the original text.
On macOS laptops, background neural enhancement pauses on battery power (ig --status
shows Paused: Battery Power); set IVYGREP_ENHANCE_ON_BATTERY=1 to keep it running.
The lightweight hash tier keeps computing on battery so semantic results stay available.
However many workspaces change at once, at most two hash and two neural enhancement
workers run at a time (IVYGREP_ENHANCE_MAX_WORKERS); the rest wait in the daemon, and the
workspace searched or edited last goes first.
Index notes once. Watcher keeps them current, and queries use local semantic + lexical search by default:
ig --add ~/notes --wait-for-enhancement
ig -n 20 "what did we decide about cache invalidation?" ~/notes
Public MemoryQuest results (v1.2.7): 74.9% recall@20 at 87.63 ms warm p95. Benchmark measures retrieval only; answer accuracy is outside scope.
Codex and Claude Code packages install MCP configuration plus focused task-context skill:
codex plugin marketplace add bvolpato/ivygrep
codex plugin add ivygrep@ivygrep
claude plugin marketplace add bvolpato/ivygrep
claude plugin install ivygrep@ivygrep
Automatic setup detects the client, preserves existing configuration, writes the absolute ig path, verifies the MCP handshake, and runs a search:
ig agent install claude
ig agent install codex
ig agent install cursor
ig agent doctor
Restart an open client after installation. Manual MCP setup is also available:
claude mcp add -s user ig -- ig --mcp
codex mcp add ig -- ig --mcp
gemini mcp add --scope user --transport stdio ig ig --mcp
Cursor .cursor/mcp.json:
{"mcpServers":{"ig":{"type": "stdio", "command": "ig", "args": ["--mcp"]}}}
OpenCode opencode.json:
{"mcp":{"ig":{"type": "local", "command": ["ig", "--mcp"], "enabled": true}}}
Agents call ig_search for discovery. Set output=context_pack and budget_tokens=8000 when the task needs implementation context. Pass the absolute path to the active repository or worktree. Worktrees reuse the base index and store only changed chunks and tombstones.
Context packs can include definitions, callers, references, dependencies, dependents, tests, configuration, and docs.
Setup guides: Codex, Claude Code, Cursor, Gemini CLI, OpenCode, and MCP.
Recommended agent instruction:
Use ivygrep before broad filesystem scans. Pass absolute active worktree path.
Use natural-language queries for concepts and literal=true for identifiers.
For implementation, request output=context_pack with budget_tokens=8000.
Fresh indexing publishes lexical results before vector enhancement. Worktrees reuse base index and store only divergent chunks and tombstones. Partial workspace failures return warnings with valid hits; complete failure errors.
ivygrep supports 45 language and file types. Twenty-four use Tree-sitter AST chunking: Rust, Python, Go, JavaScript, TypeScript, Java, C, C++, C#, Kotlin, Scala, PHP, Ruby, Swift, Elixir, Zig, Bash, Haskell, OCaml, Lua, Dart, Objective-C, Perl, and Starlark.
Read architecture for storage, commit order, retrieval, worktrees, protocols, security boundaries, and module ownership.
On the deterministic synthetic one-million-chunk CC0 corpus, v1.2.7 median hash-only warm CLI p95 is 6.19 ms, controlled indexing reaches 150,576 chunks/s, and the final index is 0.42 GiB across three sequential trials. This is a scale and footprint measurement, not semantic quality or agent-task performance. Hardware, repository shape, index state, and load affect absolute results.
Latest measured release (v1.2.7) · Million-chunk methodology and historical paired study · Full benchmark dashboard
Runtime source, queries, embeddings, results, and indexes stay local. Neural
profiles download pinned model assets on first use unless cache is already
populated. Use --hash, ./build.sh --hash-only, or
cargo build --locked --no-default-features to avoid model downloads.
ig --web binds to loopback by default and always prints an authenticated URL: the Web API requires the per-daemon session token on loopback too, so other local users cannot read indexed code through it. The printed URL contains the token, so keep terminal output and logs that capture it private. The browser opens through an owner-only redirect file under the ivygrep app home, which keeps the token out of process arguments; set IVYGREP_NO_BROWSER=1 to skip the browser. A non-loopback listener still uses plain HTTP. Use a trusted network, Tailscale, or an encrypted tunnel, and never expose the listener directly to the internet. File contents, including non-ignored dotfiles, can appear in the local index and snippets.
Report vulnerabilities through a private security advisory. Release archives include checksums, SBOMs, and provenance.
Indexes and daemon state live in ~/.local/share/ivygrep on every OS (under %USERPROFILE% on Windows).
IVYGREP_HOME overrides that path; otherwise a non-empty XDG_DATA_HOME selects $XDG_DATA_HOME/ivygrep.
Model assets use the Hugging Face cache (HF_HOME, default ~/.cache/huggingface), which other tools may share.
There is no configuration file. Use CLI flags and the environment variables.
ig --status # tracked workspaces, index health, vector coverage, disk usage
ig --rm ~/notes # remove a saved index; defaults to current directory
ig --gc # remove indexes whose directory has been gone past the grace period
The daemon also removes the index of a directory that stays missing for seven days (IVYGREP_INDEX_GC_GRACE_SECS), and the overlay of a worktree removed with git worktree remove after ten minutes.
ig --doctor # diagnose index, daemon, watcher, and model health
ig --doctor --fix # repair a broken or stale index
ig --add . --force # rebuild current workspace index from scratch
ig hardware # inspect detected hardware and matching build
Open the URL ig --web prints: a bare http://127.0.0.1:4747/ returns 401 until
the browser has the session cookie that URL sets.
If ig --web opens a page that cannot load its redirect file, as snap-packaged
browsers on Ubuntu do for files under hidden directories, open the URL it prints.
Under WSL, a Windows browser can load the redirect file only through an opener
that translates Linux paths, such as wslview; otherwise open the printed URL.
Upgrade through the channel you installed from: brew upgrade ivygrep,
winget upgrade --id BrunoVolpato.ivygrep --exact, or rerun the installer. The
next command restarts a daemon from an older build; index format changes rebuild
existing indexes once on first use.
To uninstall, run brew uninstall ivygrep or winget uninstall --id BrunoVolpato.ivygrep --exact,
or delete ig from the installer directory (~/.local/bin or %LOCALAPPDATA%\ivygrep\bin unless
IVYGREP_INSTALL_DIR was set). Then stop any running ig --daemon process and delete the data directory.
./test.sh --quick
./test.sh
./bench.sh
Start with a good first issue, read CONTRIBUTING.md and architecture, or discuss an idea in Discussions.
MIT licensed. Maintained by Bruno Volpato.
Rust
78.2%
Python
18.6%
TypeScript
1.4%
Shell
1.4%