Code Context V2 — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited Code Context V2 (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
<p align="center"> <img src="assets/logo.png" alt="Code Context v2" width="600"> </p>
<p align="center"> Semantic code search for CLI-driven agent workflows. Index your codebases, search with natural language, get precise results. </p>
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:
voyage-4-large for documents, voyage-4-lite for queries — same embedding space, asymmetric retrieval).env.example (or embedded LanceDB/SQLite alternatives), then rerank-2.5 for precisionAgent / CLI
│
├── cc2.sh
└── uv run code-context-manage
│
RetrievalPipeline
│ │
▼ ▼
Voyage AI local vector store
voyage-4-lite Postgres/pgvector
(query embed) LanceDB/SQLite fallback
rerank-2.5
(reranking)Retrieval pipeline:
voyage-4-lite (fast, shared space with indexed docs)CC2_CODE_BACKEND=sqlite), or PostgreSQL/pgvector (CC2_CODE_BACKEND=postgres)rerank-2.5 + relative threshold (max(score_floor, top_score * factor))Code layout:
src/code_context/retrieval/ — retrieval facade plus focused helpers for intent resolution, result controls, cross-file context, and quality loggingsrc/code_context/db/ — DatabasePool facade delegating to domain-specific stores for code, projects, memory, and bookssrc/code_context/chunking/ — tree-sitter parsing, chunk models, and post-processing/splitting helperssrc/code_context/indexing/ — filesystem and indexing support helpers used by Indexersrc/code_context/cli/ — user-facing entrypoints plus shared runtime/search/sync/watcher helpersThe public APIs stay centered on RetrievalPipeline, DatabasePool, Indexer, and the CLI entrypoints; the internal modules are split to keep those surfaces stable while reducing coupling.
git clone https://github.com/enzodevs/code-context-v2.git
cd code-context-v2
cp .env.example .env
# Edit .env: set CC2_VOYAGE_API_KEY and keep CC2_CODE_BACKEND=postgresThe recommended local backend is PostgreSQL/pgvector + pgvectorscale via the Timescale Docker image (CC2_CODE_BACKEND=postgres), using the compose service on 127.0.0.1:25432.
docker volume create code-context-pgdata
docker compose up -d postgresPostgreSQL data is stored in the external Docker volume code-context-pgdata, mounted at the image's active PGDATA path (/home/postgres/pgdata/data). This protects the cc2 index from normal compose lifecycle commands, including docker compose down -v. Do not remove the volume with docker volume rm code-context-pgdata unless you intentionally want to delete the index.
No Docker available? Set CC2_CODE_BACKEND=lancedb in .env to use embedded LanceDB at ~/.local/share/cc2/lancedb. Experimental SQLite + FTS5 + sqlite-vec is also available with CC2_CODE_BACKEND=sqlite.
uv syncuv run code-context-manage --index /path/to/your/projectProject indexing respects .gitignore by default. Pass --include-gitignored only when you intentionally want to index files matched by gitignore rules.
Use either the direct Python entrypoint or the shell wrapper:
# List indexed projects
uv run code-context-manage --list
# Semantic search from inside an indexed repo (project inferred from cwd)
./cc2.sh search "auth middleware"
# Explicit project override when running outside the repo or targeting another project
./cc2.sh search "auth middleware" -p my-project
# Opt in to graph expansion from dense chunk hits
./cc2.sh search "auth middleware" -p my-project --graph
# Search within one file (also infers project from cwd)
./cc2.sh search-file src/auth.ts "token validation"
# 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. |
--graph | off | Opts CLI search into graph expansion. By default expansion favors deterministic high-value edges such as CALLS, REFERENCES, TESTS, DOCUMENTS, IMPORTS, and USES_TABLE, and avoids broad SAME_FILE fanout. Can also be enabled for CLI search with CC2_GRAPH_SEARCH_ENABLED=true. |
--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:
include_tests=false unless the user explicitly asks about tests.--max-tokens between 1800 and 3200 for typical coding tasks.--json when another tool or agent will post-process the results.For CLI code search commands, -p/--project is optional when your current working directory is inside an indexed project root.
cc2.sh passes the caller cwd through to the Python CLI.project_root that contains the cwd.-p when running outside the repo, targeting another indexed project, or overriding cwd-based resolution.Copy .mcp.json.example into your MCP client config and replace /path/to/code-context-v2 with this repository path.
{
"mcpServers": {
"code-context": {
"command": "uv",
"args": ["--directory", "/path/to/code-context-v2", "run", "code-context"],
"env": {
"CC2_VOYAGE_API_KEY": "${CC2_VOYAGE_API_KEY}",
"CC2_DATABASE_URL": "postgresql://coderag:your_password@localhost:25432/coderag"
}
}
}
}MCP clients should call list_projects first, then pass the returned project id as the explicit project argument to search tools. The CLI can infer the project from the current working directory; MCP calls do not receive that cwd context. Graph expansion is available through CLI --graph, CC2_GRAPH_SEARCH_ENABLED=true, or the MCP search tools' graph argument.
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.
Retrieval changes should be measured with local benchmark suites when available. Suite definitions live in benchmarks/retrieval/*.json, but those JSON files are ignored because they often reference local indexed project IDs and private repository paths.
# List local benchmark-enabled projects
uv run python -m scripts.benchmark_retrieval --list
# Run one local project suite
uv run python -m scripts.benchmark_retrieval my-project
# Compare against a saved local baseline
uv run python -m scripts.benchmark_retrieval my-project --compare baseline-v1
# Run all local benchmark suites and save a combined baseline
uv run python -m scripts.benchmark_retrieval all --save hybrid-v1
# Run with graph expansion enabled
uv run python -m scripts.benchmark_retrieval my-project --graph
# A/B compare dense-only vs dense + graph expansion in one run
# Prints graph-derived candidate/final counts, added/removed expected files,
# worsened top results, surviving edge types, and token impact.
uv run python -m scripts.benchmark_retrieval my-project --compare-graphSee benchmarks/retrieval/README.md for the local suite schema.
# 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
# Include files matched by .gitignore
uv run code-context-manage --index /path/to/project --include-gitignored
# 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
# List indexed books
uv run code-context-manage --list-books
# Initialize additive graph tables (does not reindex code)
uv run code-context-manage graph init
# Build the phase-1 graph from the existing code index
uv run code-context-manage graph build --project my-project
uv run code-context-manage graph build --project my-project --phase existing-index
# Add Phase 2 deterministic source relations incrementally (no code reindex)
uv run code-context-manage graph build --project my-project --phase deterministic
# Check graph backfill status and edge counts by type
uv run code-context-manage graph status --project my-project
# Create a project memory root with a MEMORY.md hub
./cc2.sh memory init
# Index a Markdown memory root
./cc2.sh memory index .pi/memory --project my-project
# Search indexed memory
./cc2.sh memory search "refresh token rotation" --project my-projectStandalone memory entrypoint also exists:
uv run code-context-memory init
uv run code-context-memory index .pi/memory --project my-project
uv run code-context-memory search "refresh token rotation" --project my-projectSee docs/memory.md for the memory layout, MEMORY.md hub pattern, and filters.
For the full documentation index, see docs/README.md.
There'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 |
| Go | .go | tree-sitter-go |
| Rust | .rs | tree-sitter-rust |
| SQL | .sql | tree-sitter-sql |
| PHP | .php | tree-sitter-php |
| Vue | .vue | file-level Vue SFC chunks |
| Markdown docs | .md, .mdx | document chunking |
| JSON/YAML/TOML/CSS/HTML | .json, .yaml, .yml, .toml, .css, .html, .htm | file-level chunks where appropriate |
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_CODE_BACKEND | postgres in .env.example | Code index backend: recommended postgres, no-Docker lancedb, or experimental sqlite |
CC2_LANCEDB_URI | ~/.local/share/cc2/lancedb | Embedded LanceDB storage directory for code and memory index data |
CC2_LANCEDB_LOCK_TIMEOUT_S | 60 | Seconds to wait for another cc2 process to release the local LanceDB file lock |
CC2_SQLITE_VEC_PATH | ~/.local/share/cc2/sqlite/code.db | Experimental SQLite + FTS5 + sqlite-vec code index database path |
CC2_SQLITE_LOCK_TIMEOUT_S | 60 | Seconds to wait for SQLite file locks |
CC2_DATABASE_URL | postgresql://...@localhost:25432/coderag | PostgreSQL/pgvector connection string for code, books, graph, and MCP paths |
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 | 1950 | Global request pacing guardrail for Voyage API |
CC2_VOYAGE_MAX_TOKENS_PER_MINUTE | 2700000 | Global token pacing guardrail for Voyage API |
CC2_VOYAGE_MAX_IN_FLIGHT_REQUESTS | 32 | Global max concurrent Voyage API calls |
CC2_INDEX_EMBEDDING_FLUSH_CHUNKS | 5000 | Chunks to accumulate for cross-file embedding batches during project indexing/sync |
CC2_LANCEDB_WRITE_BATCH_FILES | 500 | Files per LanceDB write transaction during project indexing/sync |
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_RERANK_FILE_SUPPORT_WEIGHT | 0.06 | Small post-rerank boost for files with many strong retrieved chunks |
CC2_RESULT_MAX_TOKENS | 8000 | Token budget for results |
CC2_SEARCH_LOG_PATH | unset | Optional JSONL path for retrieval quality logs |
CC2_HYBRID_SEARCH_ENABLED | true | Enable dense + LanceDB FTS + exact-symbol candidate fusion before rerank |
CC2_HYBRID_LEXICAL_K | 50 | Max lexical candidates retrieved for hybrid search |
CC2_HYBRID_RRF_RANK_CONSTANT | 60 | Reciprocal rank fusion constant used to merge candidate channels |
CC2_HYBRID_DENSE_WEIGHT | 1.0 | Dense retrieval weight in hybrid fusion |
CC2_HYBRID_LEXICAL_WEIGHT | 0.8 | Lexical retrieval weight in hybrid fusion |
CC2_HYBRID_EXACT_SYMBOL_WEIGHT | 1.2 | Exact symbol retrieval weight in hybrid fusion |
CC2_EXACT_SYMBOL_SEARCH_ENABLED | true | Allow exact symbol-name candidate retrieval inside hybrid search |
CC2_EXACT_SYMBOL_MIN_LENGTH | 3 | Minimum identifier length for exact symbol candidate extraction |
CC2_LOG_LEVEL | INFO | Logging verbosity |
See src/code_context/config.py for all available settings.
node_modules, vendor, .git, dist, Laravel runtime/generated dirs, etc.)voyage-4-large in batches.env.example uses PostgreSQL/pgvector, with LanceDB and SQLite alternatives availablecc2 sync if an interrupted process leaves a project partially indexedSupported code languages include TypeScript, JavaScript, Python, Java, Go, Rust, SQL, PHP, and Vue single-file components. PHP files get class/function/method chunks; Vue SFCs are indexed as file-level chunks.
Laravel defaults skip Composer dependencies, runtime/cache output, built frontend assets, PHPUnit cache files, Pi/local MCP scratch, and generated Wayfinder route/action files.
This project uses uv for dependency management and Ruff for linting. ty is configured warning-only as a fast type-checking signal while the existing type backlog is migrated.
uv sync --dev
uv run ruff check .
uv run ty check
uv run pytestMaintainer and coding-agent guidance lives in AGENTS.md.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.