Semantic code search for CLI-driven agent workflows. Index your codebases, search with natural language, get precise results.
Built for local agent workflows in Claude Code and similar CLI environments.
LLMs work better with the right context. Grep finds text; this finds meaning. Ask for "authentication middleware" and get the actual auth logic, not every file that mentions "auth".
How it works:
- Index your codebase with tree-sitter AST parsing (functions, classes, methods — not arbitrary line splits)
- Embed chunks with Voyage AI (
voyage-4-largefor documents,voyage-4-litefor queries — same embedding space, asymmetric retrieval) - Search with either
pgvectoror Elasticsearch hybrid retrieval, thenrerank-2.5for precision - Query indexed content from the CLI with semantic search commands
Agent / CLI
│
├── cc2.sh
└── uv run code-context-manage
│
RetrievalPipeline
│ │ │
▼ ▼ ▼
Voyage AI PostgreSQL 16 Elasticsearch
voyage-4-lite + pgvector lexical + vector
(query embed) + pgvectorscale hybrid retrieval
rerank-2.5
(reranking)
Retrieval pipeline:
- Embed query with
voyage-4-lite(fast, shared space with indexed docs) - Retrieve candidates from the configured backend:
postgresusespgvector;elasticuses lexical + vector hybrid retrieval - Rerank:
rerank-2.5+ relative threshold (max(score_floor, top_score * factor)) - Dedup: overlap/containment + Jaccard similarity filtering
- Return: Markdown-formatted chunks with file paths, line numbers, relevance scores
- uv (Python package manager)
- Docker (for PostgreSQL)
- Voyage AI API key (free tier available)
git clone https://github.com/YOUR_USER/code-context-v2.git
cd code-context-v2
cp .env.example .env
# Edit .env — set CC2_VOYAGE_API_KEY and CC2_DATABASE_URLdocker compose up -dThis runs PostgreSQL 16 with pgvector + pgvectorscale on port 54329, and Elasticsearch on 9200.
uv syncuv run code-context-manage --index /path/to/your/projectUse either the direct Python entrypoint or the shell wrapper:
# List indexed projects
uv run code-context-manage --list
# Semantic search across a project
./cc2.sh search "auth middleware" -p my-project
# Search within one file
./cc2.sh search-file src/auth.ts "token validation" -p my-project
# Search indexed literature
./cc2.sh search-lit "dependency injection"The CLI search commands support optional output-shaping controls:
| Flag | Default | Effect |
|---|---|---|
--max-tokens |
unset | Per-request budget override. Clamped inside the retrieval pipeline. |
--include-tests |
off | Includes test/spec files when needed. |
--file-type |
unset | Restrict to code, docs, or all. |
--directory |
unset | Restrict results to a directory prefix. |
--json |
off | Emit machine-readable output for agent/tool consumption. |
Recommended defaults for agent workflows:
- Keep
include_tests=falseunless the user explicitly asks about tests. - Start with
--max-tokensbetween1800and3200for typical coding tasks. - Use
--jsonwhen another tool or agent will post-process the results.
Use --intent to steer reranking precision:
| Intent | Best for |
|---|---|
implementation |
Concrete runtime logic you will modify to ship a feature |
definition |
Types/interfaces/schemas/contracts/config declarations |
usage |
Call sites, integration points, consumer code |
debug |
Error paths, retries, fallbacks, validation failures, observability clues |
security |
Auth/authz, secret handling, sanitization, injection defenses |
performance |
Hot paths, caching, batching, query shape, contention points |
architecture |
Boundaries, adapters, orchestration, cross-module flow |
Default intent is implementation when omitted.
# Index a project (auto-generates ID from folder name)
uv run code-context-manage --index /path/to/project
# Index with custom ID
uv run code-context-manage --index /path/to/project --id my-project
# Check what changed (dry-run)
uv run code-context-manage --check my-project
# Sync only changed files
uv run code-context-manage --sync my-project
# Force full reindex
uv run code-context-manage --index /path/to/project --force
# Show statistics
uv run code-context-manage --stats
# Watch for changes (background daemon)
uv run code-context-manage --watch /path/to/project
# Remove orphaned data
uv run code-context-manage --list-booksThere's also cc2.sh — a bash wrapper with a gum-based TUI plus non-interactive commands like search, search-file, and search-lit.
| Language | Extensions | Parser |
|---|---|---|
| TypeScript | .ts, .tsx |
tree-sitter-typescript |
| JavaScript | .js, .jsx, .mjs, .cjs |
tree-sitter-javascript |
| Python | .py, .pyi |
tree-sitter-python |
| Java | .java |
tree-sitter-java |
Adding a new language requires a tree-sitter grammar and chunk type mappings in src/code_context/chunking/parser.py.
All settings use the CC2_ prefix via environment variables or the repository .env file:
| Variable | Default | Description |
|---|---|---|
CC2_DATABASE_URL |
— | PostgreSQL connection string (required) |
CC2_VOYAGE_API_KEY |
— | Voyage AI API key (required) |
CC2_EMBEDDING_MODEL_INDEX |
voyage-4-large |
Embedding model for indexing |
CC2_EMBEDDING_MODEL_QUERY |
voyage-4-lite |
Embedding model for queries |
CC2_VOYAGE_MAX_REQUESTS_PER_MINUTE |
1800 |
Global request pacing guardrail for Voyage API |
CC2_VOYAGE_MAX_IN_FLIGHT_REQUESTS |
8 |
Global max concurrent Voyage API calls |
CC2_VOYAGE_RETRY_MAX_ATTEMPTS |
5 |
Max retries for transient/rate-limit Voyage failures |
CC2_VOYAGE_RETRY_BASE_DELAY_MS |
250 |
Initial exponential backoff delay |
CC2_VOYAGE_RETRY_MAX_DELAY_MS |
5000 |
Retry delay ceiling |
CC2_VOYAGE_RETRY_JITTER_MS |
250 |
Extra random jitter to avoid retry bursts |
CC2_RERANK_MODEL |
rerank-2.5 |
Reranking model |
CC2_RERANK_TOP_K_OUTPUT |
8 |
Max final results returned by code search tools |
CC2_RERANK_RELATIVE_FACTOR |
0.75 |
Relative cutoff factor (threshold = top_score * factor) |
CC2_RERANK_SCORE_FLOOR |
0.40 |
Absolute minimum rerank score floor |
CC2_RETRIEVAL_BACKEND |
postgres |
Retrieval backend: postgres, elastic, or dual_shadow |
CC2_ELASTIC_ENABLED |
false |
Enable Elasticsearch indexing/search integration |
CC2_ELASTIC_URL |
http://localhost:9200 |
Elasticsearch endpoint |
CC2_ELASTIC_INDEX_NAME |
cc2-code-chunks-v1 |
Elasticsearch index for code chunks |
CC2_RESULT_MAX_TOKENS |
8000 |
Token budget for results |
CC2_SEARCH_LOG_PATH |
unset | Optional JSONL path for retrieval quality logs |
CC2_LOG_LEVEL |
INFO |
Logging verbosity |
See src/code_context/config.py for all available settings.
- Vector search: <50ms
- Reranking: <100ms
- Total CLI search response: <200ms
- Initial indexing: ~5-10 min for 1000 files
- Incremental sync: <2s per changed file
- Storage: ~100MB per 100k chunks
- Walk the project tree (skips
node_modules,.git,dist, etc.) - Hash each file with BLAKE3 — skip unchanged files
- Parse with tree-sitter into semantic chunks (functions, classes, methods)
- Small files (<200 lines) still extract symbol-level chunks; generic file chunks are dropped when symbol chunks exist
- Embed chunks with
voyage-4-largein batches - Store chunk metadata in PostgreSQL and, when enabled, dual-write searchable documents into Elasticsearch
- All operations are atomic — Ctrl+C won't corrupt the index
MIT
