Skip to main content

Local CLI tool for GitHub RAG, Call Graphs, and Codebase querying -- v2.0.0 - Forge

Project description

cpnlookup

Version 2.0.0 Forge Python 3.9+ MIT License Work in Progress

██████╗██████╗ ███╗   ██╗██╗      ██████╗  ██████╗ ██╗  ██╗██╗   ██╗██████╗
██╔════╝██╔══██╗████╗  ██║██║     ██╔═══██╗██╔═══██╗██║ ██╔╝██║   ██║██╔══██╗
██║     ██████╔╝██╔██╗ ██║██║     ██║   ██║██║   ██║█████╔╝ ██║   ██║██████╔╝
██║     ██╔═══╝ ██║╚██╗██║██║     ██║   ██║██║   ██║██╔═██╗ ██║   ██║██╔═══╝
╚██████╗██║     ██║ ╚████║███████╗╚██████╔╝╚██████╔╝██║  ██╗╚██████╔╝██║
 ╚═════╝╚═╝     ╚═╝  ╚═══╝╚══════╝ ╚═════╝  ╚═════╝ ╚═╝  ╚═╝ ╚═════╝ ╚═╝

Forged for faster indexing and smarter retrieval.

cpnlookup is a local-first CLI tool for indexing and querying GitHub repositories through natural language — without ever running git clone. It combines FAISS vector similarity search with a SQLite-backed static call graph to deliver a Hybrid RAG pipeline that understands both the semantic meaning and structural relationships of a codebase, entirely on your own machine.

This project is under active development. See Known Limitations and Roadmap for current status.


Features

Remote indexing — Fetches repository file trees and raw content via the GitHub API. Supports Python source files and Markdown documentation.

Logic-aware chunking — Uses Python's ast module to parse source files into meaningful units (functions and classes) rather than splitting on arbitrary character counts or line boundaries.

Static call graph construction — Performs static analysis to identify function invocations and stores a directed call graph in SQLite. Used at query time to expand retrieval context with structurally adjacent code.

Hybrid RAG retrieval — Combines FAISS vector similarity search with bidirectional call graph traversal. Top-k vector matches are retrieved first, then both their callees and callers are included to give the LLM full architectural context.

Incremental indexing — File content is hashed on index. Re-indexing only fetches, chunks, and embeds files that have actually changed. Unchanged files reuse their stored embedding vectors.

Write consistency — An index_status flag is written to SQLite at the start of every indexing run and cleared only on clean completion. Interrupted runs are detected and reported on next use.

Local inference — All inference is handled by a locally running Ollama instance (default: Mistral). No source code, queries, or embeddings leave your machine.

Global registry — A registry of all locally indexed repositories is maintained, allowing management of multiple indexes from a single interface.


Architecture

GitHub API  (file tree + SHAs — one call)
    |
    v
Change detection  (compare SHAs against stored file_hash in SQLite)
    |
    |-- Unchanged files  -->  reuse stored embedding BLOBs
    |-- New / changed    -->  fetch content  -->  chunk  -->  embed
    v
AST / Regex Chunker
    |-- Python   -->  ast module       -->  function / class chunks
    |-- Markdown -->  regex headers    -->  section chunks
    v
Embedding Model  (sentence-transformers/all-MiniLM-L6-v2)
    |
    +---> Embedding BLOBs stored in SQLite  (chunks.embedding)
    +---> FAISS index rebuilt from all BLOBs  (faiss.index)
    +---> Static call graph  (SQLite: graph_nodes, graph_edges)
    |
    v
Query pipeline
    |-- Vector search    (top-k FAISS matches via faiss_id)
    |-- Graph traversal  (callers + callees, bidirectional)
    v
Local LLM via Ollama  -->  Response

Each indexed repository produces a .cpnlookup/ directory containing index.db and faiss.index. A global registry at ~/.cpnlookup/registry.json tracks all indexes on the local system.


Installation

Prerequisites: Python 3.9+, Ollama running locally, and a GitHub Personal Access Token (Classic) with repo scope.

ollama pull mistral
pip install cpnlookup
lookup auth <your_github_token>

Usage

lookup                             # Welcome screen and quick start
lookup desc                        # Project info, version history, acknowledgements
lookup profile <username>          # Browse a user's repositories
lookup init <username>/<repo>      # Index a repository
lookup ask "How does X work?"      # Query the codebase in natural language
lookup functions                   # List all indexed functions and classes
lookup indexed                     # List all locally indexed repositories
lookup config <key> <value>        # Configure model or search depth
lookup clone <username>/<repo>     # Git clone a repository
lookup drop                        # Remove the local index for the current repository

Known Limitations

The following limitations are understood, documented for transparency, and tracked in the roadmap.

Call graph accuracy. The call graph is built via name-only static analysis. When a call to process() is detected, an edge is recorded to any indexed function named process regardless of module or class. Codebases with common function names will produce false edges. Dynamic dispatch — getattr, decorator-wrapped functions, factory patterns — is invisible to this analysis. The graph is a useful structural approximation, not a semantically precise call graph.

Language support. Only Python source files and Markdown documentation are supported. All other file types are skipped during indexing. Multi-language support via Tree-sitter is planned for V3.

Cold-start latency. Commands that invoke the embedding model still carry a load cost on first use per session. Lazy imports (shipped in v1.2.2) eliminated startup lag for non-model commands; a persistent model daemon to eliminate the remaining load cost is planned for a future v2.x release.

FAISS scalability. IndexFlatL2 performs exhaustive linear search. For repositories producing more than roughly 10,000 indexed chunks, query latency will degrade. Migration to IndexIVFFlat is planned for V3.


Roadmap

Version 2.0 — Forge ✦ current

Item Status Description
Write consistency ✅ Shipped index_status flag prevents corrupt index state on interrupted runs.
Incremental indexing ✅ Shipped SHA-based change detection. Only new or changed files are re-fetched, re-chunked, and re-embedded. Embedding BLOBs stored in SQLite for reuse.
Batched embedding ✅ Shipped All chunks encoded in a single batched model.encode() call.
Pre-index filtering ✅ Shipped Build artifacts, compiled output, and cache directories excluded. Test files retained.
Bidirectional graph traversal ✅ Shipped Callers and callees both included in context expansion.
Persistent model daemon ⏳ Planned Background process keeps embedding model warm between commands, eliminating remaining cold-start cost.

Version 3.0 — Intelligence and Scalability

Item Description
Tree-sitter parser Multi-language support — JS, TS, Rust, Go, C++. Replaces ast-based chunking.
BM25 sparse retrieval Keyword-based retrieval pass merged with FAISS dense search. Improves recall on exact symbol name queries.
Cross-encoder reranking Post-retrieval scoring of each candidate chunk against the query jointly. Filters low-relevance context before it reaches the LLM.
FAISS scalability upgrade Migrate from IndexFlatL2 to IndexIVFFlat with product quantization for large repositories.
Hierarchical indexing depth User-selectable modes: "focused" (main files, faster) and "comprehensive" (full context, slower).
Conversation memory Persistent, indexed chat history across sessions. Older turns summarised to avoid context window bloat.
Mermaid.js visualisation Visual call graph diagrams generated from graph_edges data.
Local LLM upgrade Evaluate qwen2.5-coder as an alternative default for improved code comprehension.

Version History

Version Codename Highlights
v1.0.0 Initial release. Hybrid RAG pipeline, GitHub API indexing, AST chunking, FAISS search, Ollama inference.
v1.1.1 Optimized Indexing Pre-index filtering, batched embedding, corrected runtime dependency declarations.
v1.2.2 Lazy Imports Heavy ML imports moved inside command functions. Non-model commands start instantly.
v2.0.0 Forge Write consistency, incremental indexing, embedding BLOB storage, bidirectional graph traversal, faiss_id mapping.

Privacy

No source code, query text, or generated embeddings are transmitted to any external service. Embedding generation runs locally via sentence-transformers. Inference is handled by your local Ollama instance. The GitHub API is used only to fetch the content of repositories you explicitly choose to index.


Acknowledgements

Developed by @projcjdevs. Special thanks to @2nieGarcia, @renzv-compsci, and @NIghtIngale340 for feedback and testing.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cpnlookup-2.0.0.tar.gz (19.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cpnlookup-2.0.0-py3-none-any.whl (18.9 kB view details)

Uploaded Python 3

File details

Details for the file cpnlookup-2.0.0.tar.gz.

File metadata

  • Download URL: cpnlookup-2.0.0.tar.gz
  • Upload date:
  • Size: 19.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for cpnlookup-2.0.0.tar.gz
Algorithm Hash digest
SHA256 5c00e8394a53611a4ae49e9108ab70beaba2f9cec0bd9d7ddc2e8051f62b71f3
MD5 0d7019e9c16cd9b169d0345c387545b3
BLAKE2b-256 9d3dcf5f954682619b6fc2f7f6bed1e10dd2cc8ab3ac7318949f4e0328cfd457

See more details on using hashes here.

File details

Details for the file cpnlookup-2.0.0-py3-none-any.whl.

File metadata

  • Download URL: cpnlookup-2.0.0-py3-none-any.whl
  • Upload date:
  • Size: 18.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.2

File hashes

Hashes for cpnlookup-2.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 5e1ba5c7f3da420000aed47a775148280f9e73790a4f91b01f18d1dc9fbbeed8
MD5 d298c26c8785b795f45de23456ed8cd4
BLAKE2b-256 69ac6d928e0c499bb589e04aafaa2f86517e2260c8789dc57762381e0e318653

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page