@dennisonbertram/lgrep
AAI-powered semantic code search.
Install
agr install @dennisonbertram/lgrep --target claudeThis artifact does not publish files for Claude.
Document
{ "name": "lgrep", "version": "0.2.1", "description": "Semantic code search CLI with local and Postgres-backed cloud profiles", "type": "module", "main": "dist/index.js", "module": "dist/index.js", "types": "dist/index.d.ts", "exports": { ".": { "types": "./dist/index.d.ts", "import": "./dist/index.js" } }, "bin": { "lgrep": "dist/cli/index.js", "lgrep-mcp": "dist/mcp/index.js" }, "files": [ "dist//*.js", "dist//.js.map", "dist/**/.d.ts", "dist/viewer/**", "README.md", "LICENSE" ], "scripts": { "start": "bash ./scripts/start-hosted-server.sh", "build": "tsup && npm run build:viewer", "build:test-binaries": "node scripts/ensure-test-binaries.mjs --force", "dev": "tsup --watch", "build:viewer": "vite build --config viewer/vite.config.ts", "dev:viewer": "vite --config viewer/vite.config.ts", "pretest": "node scripts/ensure-test-binaries.mjs", "test": "vitest run", "test:cloud-smoke": "bash scripts/cloud-smoke.sh", "test:watch": "vitest", "test:coverage": "vitest run --coverage", "lint": "eslint src --ext .ts", "type-check": "tsc --noEmit", "release:check": "npm run type-check && npm run build && npm test && npm pack --dry-run", "prepublishOnly": "npm run type-check && npm run build && npm test" }, "engines": { "node": ">=18.17" }, "keywords": [ "search", "semantic-search", "code-search", "embeddings", "ollama", "anthropic", "openai", "groq", "ai", "llm", "local", "cli", "vector-search", "rag", "code-intelligence", "developer-tools" ], "author": "Dennison Bertram dennison@dennisonbertram.com", "license": "MIT", "repository": { "type": "git", "url": "git+https://github.com/dennisonbertram/lgrep.git" }, "homepage": "https://github.com/dennisonbertram/lgrep#readme", "bugs": { "url": "https://github.com/dennisonbertram/lgrep/issues" }, "publishConfig": { "access": "public" }, "dependencies": { "@ai-sdk/anthropic": "^2.0.56", "@ai-sdk/cohere": "^2.0.21", "@ai-sdk/groq": "^2.0.33", "@ai-sdk/openai": "^2.0.87", "@babel/parser": "^7.28.5", "@babel/traverse": "^7.28.5", "@babel/types": "^7.28.5", "@lancedb/lancedb": "^0.13.0", "@modelcontextprotocol/sdk": "^1.25.1", "@solidity-parser/parser": "^0.20.2", "ai": "^5.0.113", "apache-arrow": "^21.1.0", "chalk": "^5.3.0", "chokidar": "^5.0.0", "commander": "^12.1.0", "ignore": "^7.0.5", "ollama": "^0.5.11", "open": "^11.0.0", "ora": "^8.1.1", "pg": "^8.13.1", "tree-sitter": "^0.25.0", "tree-sitter-c": "^0.24.1", "tree-sitter-cpp": "^0.23.4", "tree-sitter-go": "^0.25.0", "tree-sitter-java": "^0.23.5", "tree-sitter-python": "^0.25.0", "tree-sitter-rust": "^0.24.0", "voyageai": "^0.1.0", "zod": "^4.2.1" }, "devDependencies": { "@eslint/js": "^9.39.2", "@radix-ui/react-select": "^2.2.6", "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", "@tailwindcss/postcss": "^4.1.18", "@types/babel__traverse": "^7.28.0", "@types/node": "^22.10.2", "@types/pg": "^8.11.10", "@types/react": "^19.2.7", "@types/react-dom": "^19.2.3", "@typescript-eslint/eslint-plugin": "^8.50.0", "@typescript-eslint/parser": "^8.50.0", "@vitejs/plugin-react": "^5.1.2", "@vitest/coverage-v8": "^2.1.8", "autoprefixer": "^10.4.23", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "cytoscape": "^3.33.1", "cytoscape-fcose": "^2.2.0", "eslint": "^9.39.2", "lucide-react": "^0.562.0", "postcss": "^8.5.6", "react": "^19.2.3", "react-dom": "^19.2.3", "s3rver": "^3.7.1", "tailwind-merge": "^3.4.0", "tailwindcss": "^4.1.18", "tsup": "^8.3.5", "typescript": "^5.7.2", "vite": "^7.3.0", "vitest": "^2.1.8" } }
Repository README
Describes dennisonbertram/lgrep as a whole, which may contain artifacts other than this one. Where this artifact had no useful description of its own, its summary was taken from here.
lgrep
AI-powered semantic code search. Find code by meaning, not just text.
Search for "authentication logic" and find OAuth handlers, JWT validation, and session management — even if those words never appear in the code. Built-in code intelligence finds dead code, circular dependencies, and shows blast radius before refactoring.
Install
Requires Node.js >= 18.17.
npm install -g lgrep
lgrep init
lgrep init walks you through the two supported first-run paths:
Local- local index and local cacheCloud- Postgres-backed index and Postgres-backed cache
From Source
git clone https://github.com/dennisonbertram/lgrep && cd lgrep
npm install --legacy-peer-deps
npm run build
node dist/cli/index.js init
Quick Start
lgrep init
lgrep doctor
lgrep list
lgrep search "user authentication logic"
lgrep search --usages "validateUser"
lgrep search --definition "UserService"
lgrep context "add rate limiting"
lgrep intent "what calls awardBadge"
Agent Integration
lgrep install --target claude
lgrep install --target codex
lgrep install --target mcp
lgrep install --target all
lgrep install --target all --global --server-url https://lgrep.example.com --server-auth-token <token>
Targets:
claudeinstalls the Claude skill, the SessionStart hook, and repo-localCLAUDE.mdguidance by defaultcodexwrites guidance intoAGENTS.mdor~/.codex/AGENTS.mdwhen--globalis usedmcpconfigures lgrep as an MCP serverallinstalls all three
Session start behavior:
- In local mode, the Claude SessionStart hook can clean stale state and start local watchers automatically.
- In cloud mode, the SessionStart hook verifies the hosted service is reachable and tells agents when a repo is simply unbound on first run, with concrete next steps (
lgrep project list,lgrep worktree bind, or local indexing). - Codex currently uses installed
AGENTS.mdinstructions as its startup ritual. OpenAI’s documented Codex surfaces today areAGENTS.mdandnotify, not a SessionStart-style hook. - For Codex or manual sessions, start with
lgrepfirst. Uselgrep doctorfor local setup/debugging, orlgrep worktree resolvepluslgrep project listfor hosted connectivity and first-run binding checks.
For a machine-wide hosted setup, use:
lgrep install --target all --global \
--server-url https://lgrep.example.com \
--server-auth-token <token>
That persists the hosted URL and token into the active lgrep profile, updates ~/.claude/CLAUDE.md, updates ~/.codex/AGENTS.md, and carries the same hosted settings into the MCP config.
The intended workflow is:
- Install lgrep integration.
- Let the SessionStart hook prepare local or hosted lgrep automatically when Claude starts.
- If hosted, use
lgrep worktree resolveto confirm the current worktree binding. If it says no match, treat that as a first-run unbound repo, not a generic outage. - Use
lgrep search,lgrep callers,lgrep impact, orlgrep contextbefore broadrg/grepsearches.
Commands
Core
| Command | Purpose |
|---|---|
lgrep index <path> | Index a directory (--update, --force, --name) |
lgrep search <query> | Semantic search (--usages, --definition, --type) |
lgrep context <task> | Build context for LLM tasks (--max-tokens, --depth) |
lgrep intent <prompt> | Natural language command routing |
lgrep list | List all indexes |
lgrep watch <path> | Auto-update index on file changes |
lgrep stop <name> | Stop a watcher |
lgrep delete <name> | Delete an index |
lgrep clean | Remove failed/stale/zombie indexes |
lgrep init | Guided setup for local or cloud profiles |
lgrep profile | Manage named local/cloud profiles |
lgrep worktree resolve | Show which hosted project/worktree the current git worktree resolves to |
lgrep worktree bind | Create or repair an explicit hosted binding for the current git worktree |
lgrep server | Run or inspect the shared hosted query service |
lgrep server bootstrap | Bootstrap a hosted project, worktrees, and token |
lgrep server install-remote <ssh-target> | Provision a self-hosted server over SSH and optionally configure this machine globally |
lgrep server token | Create and inspect scoped hosted query tokens |
Code Intelligence
| Command | Purpose |
|---|---|
lgrep dead | Functions with zero callers |
lgrep similar | Duplicated function bodies |
lgrep cycles | Circular dependency chains |
lgrep unused-exports | Exported but never imported symbols |
lgrep breaking | Calls with mismatched argument counts |
lgrep rename <old> <new> | Preview rename impact |
lgrep callers <symbol> | All callers of a function |
lgrep deps <module> | Module dependency graph |
lgrep impact <symbol> | Blast radius of a change |
Analysis & Exploration
| Command | Purpose |
|---|---|
lgrep graph | Visualize dependencies in a web UI (--mode calls|deps) |
lgrep analyze <path> | One-off code structure analysis (--symbols, --deps, --calls) |
lgrep symbols [query] | Quick symbol lookup (-k function, -f auth.ts) |
lgrep explain <target> | AI-powered explanation of a file or symbol |
lgrep stats | Index statistics |
lgrep logs | Watcher daemon logs (-f to follow) |
lgrep daemon | Manage in-memory query daemons (start|stop|list) |
All commands support --json for scripting. Most support -i, --index and -l, --limit.
Embedding Providers
| Provider | Speed | Best For | Setup |
|---|---|---|---|
| OpenAI | ~50ms | General (recommended) | OPENAI_API_KEY |
| Voyage | ~100ms | Code search | VOYAGE_API_KEY |
| Cohere | ~50ms | Multilingual | COHERE_API_KEY |
| Ollama | ~1-5s | Privacy, offline | lgrep init |
lgrep config model auto # auto-detect (default)
lgrep config model voyage:voyage-code-3 # explicit
LLM Providers (Summarization)
Auto-detected. Priority: Groq > Anthropic > OpenAI > Ollama.
lgrep config summarizationModel auto # default
lgrep config summarizationModel groq:llama-3.1-8b-instant # explicit
Project Config
Create .lgrep.json in your repo root to skip --index flags:
{
"index": "my-project",
"root": "src"
}
Remote Storage
For cloud mode, lgrep defaults to Postgres for both the index and the cache. S3/R2 is still supported as an advanced/manual path, but it is no longer the default onboarding route.
See docs/guides/remote-storage.md for setup.
Hosted Query Service Preview
You can also run lgrep behind a shared HTTP query service instead of giving every agent direct database credentials.
Fastest Self-Hosted Path
For a Mac mini, Hetzner box, or any SSH-accessible machine:
export LGREP_DATABASE_URL="postgres://user:password@host:5432/lgrep"
lgrep server install-remote user@host \
--server-url https://lgrep.example.com
That will:
- install
lgrepon the remote host - install a supported Node runtime when the host's system
nodeis too old - install Linux build/runtime prerequisites when the host needs them
- provision a
launchd, workingsystemd, ortmuxservice runner - create a remote token-store file for hosted auth
- configure this machine globally for Claude, Codex, and MCP unless you pass
--skip-local-install
For the exact Hetzner/Mac-mini runbook, including the tmux tunnel/bootstrap flow for many local worktrees, see docs/guides/self-hosted-ssh-runbook.md.
Project Bootstrap
Then register a repo and its worktrees in the same hosted Postgres:
export LGREP_DATABASE_URL="postgres://user:password@host:5432/lgrep"
lgrep server bootstrap /path/to/repo \
--project repo-main \
--branch main \
--worktree 'feature-login|/path/to/repo-feature-login|feature/login'
Client Usage
After a global install, this machine can just use lgrep directly:
lgrep project info repo-main
lgrep worktree list --project repo-main
lgrep search "authentication flow" --project repo-main
lgrep callers createSession --project repo-main --worktree feature-login
If you want to configure another client machine manually:
export LGREP_SERVER_URL="https://lgrep.example.com"
export LGREP_SERVER_AUTH_TOKEN="your-hosted-service-token"
lgrep project info repo-main
lgrep worktree list --project repo-main
lgrep search "authentication flow" --project repo-main
lgrep callers createSession --project repo-main --worktree feature-login
lgrep impact createSession --project repo-main --worktree feature-login
lgrep context "trace session token flow" --project repo-main --worktree feature-login
Hosted semantic search and hosted context need a real embedding provider on the server, such as OPENAI_API_KEY. Hosted search --definition and search --usages remain database-backed client flows today.
If you want MCP clients to use the hosted service without shell exports, run:
lgrep install --target mcp --global \
--server-url https://lgrep.example.com \
--server-auth-token <token>
Today this hosted path is a bearer-token-protected, single-tenant query layer for project/worktree discovery, semantic search, callers, impact, and context packages. For self-hosted SSH deployments, lgrep server install-remote provisions a filesystem-backed token store on the remote host, which is the recommended auth path today. For Railway and other stateless remote deployments, keep using the service-wide LGREP_SERVER_AUTH_TOKEN. See docs/guides/hosted-query-service.md for the hosted multi-worktree workflow, SSH self-host path, Railway deploy path, and current limits.
If You Want To Use Hosted Mode Today
This is the practical next step if your goal is "one hosted database, many worktrees":
- Create a
cloudprofile that points at Postgres. - Create one
projectfor your repo. - Create one
worktreeper branch or checkout you want searchable. - Run
lgrep server starton the machine that has Postgres access. - For self-hosted deployments, you can mint a scoped token with
lgrep server token create. - For Railway and similar remote deployments today, use the shared
LGREP_SERVER_AUTH_TOKENservice secret. - Point agents at
LGREP_SERVER_URLplusLGREP_SERVER_AUTH_TOKEN.
That is enough to start using hosted lgrep now.
What We Are Building Next
The next product step is not another setup step for you. It is feature expansion on top of the hosted query service:
- hosted HTTP MCP transport
- richer hosted code-intel coverage like definitions/usages and deeper impact analysis
- background sync and hosted indexing workers
Those will make the hosted path more useful for agents, but they are not required for the current multi-worktree setup.
Programmatic API
import { createEmbeddingClient, createAIProvider, detectBestProvider } from 'lgrep';
const embedder = createEmbeddingClient({ model: 'auto' });
const { embeddings } = await embedder.embed(['hello world']);
const ai = createAIProvider({ model: detectBestProvider() });
const explanation = await ai.generateText('Explain this code...');
Configuration
By default, lgrep reads config from the active profile. You can manage profiles with lgrep profile.
lgrep profile list
lgrep profile create cloud
lgrep profile use cloud
lgrep config # show all settings
lgrep config model # get one
lgrep config model auto # set one
lgrep doctor # check everything
You can still override everything with LGREP_HOME for a one-off isolated home:
LGREP_HOME="$HOME/Library/Application Support/lgrep-local" lgrep doctor
LGREP_HOME="$HOME/Library/Application Support/lgrep-local" lgrep index . --name my-project
License
MIT
Contributing
git clone https://github.com/dennisonbertram/lgrep && cd lgrep
npm install --legacy-peer-deps
npm run build
npm test
Maintainers: see docs/guides/releasing.md for npm release setup and the tag-based publish flow.
Trustgrade A
- passBody integrity
Whether the stored document is plausibly the kind of file the artifact declares, rather than something fetched by mistake.
- warnType matchbest-effort: server code not analyzed
Whether the artifact is really the kind of thing its metadata claims it is.
- passFreshness
How long since the source repository was last pushed to.
- passPrompt injection
Scans the artifact's own text for instructions aimed at your agent rather than at you.
- passLicense
Whether the source repository declares an SPDX license permissive enough to redistribute.
How the grade is calculated
Each check contributes 0 points when it passes, 1 when it warns, and 2 when it fails. The total maps to a letter:
- Aevery check passed
- Bone warning
- Ctwo warnings
- Dprompt injection or body integrity failed, or three warnings
- Fone of those failed, and something else is wrong
These are automated hygiene checks, not a security audit, and not a dependency or vulnerability scan. A grade of A means nothing was flagged — not that the artifact is safe.
Versions
git-1c8dd94d18602026-08-06