RepoSense — AI That Explains YOUR Codebase

Generic AI coding assistants explain code the way a textbook would. RepoSense explains code the way an engineer who has read your repository would: every answer is grounded in your actual files, symbols, relationships, and Git history, with clickable citations back to the source.
Generic AI tells you what code usually means. RepoSense tells you what your code means.
Table of contents
Features
- 🧠 Persistent knowledge graph of your repository — files, functions, classes, imports, calls, API routes, tests — kept up to date incrementally as you edit.
- 💬 Evidence-first chat — every non-trivial answer comes back with a Sources list of real file paths, line ranges, and commit hashes, validated against the actual filesystem/Git history before being shown.
- 🕸️ Interactive graph view, scoped to a symbol's immediate relationships rather than dumping the whole repository at once.
- 🕵️ Git-aware "why" answers — commit history, blame, and (opt-in) GitHub/GitLab/Bitbucket pull-request and issue context.
- 🔌 Provider-agnostic — Anthropic, OpenAI-compatible endpoints, Azure OpenAI, Ollama (fully local), or VS Code's built-in Language Model API.
- 🔍 Hybrid retrieval — lexical + local offline semantic search + graph expansion, with an optional real neural-embedding vector store layered on top.
- 🔒 Local-first and privacy-conscious — the whole repository is never sent to an LLM; secrets are excluded from indexing and redacted before any external call.
- ⌨️ Full keyboard coverage — every user-facing command has a default keybinding.
- 🎛️ Dedicated settings UI, in addition to standard VS Code settings.
What it does
On activation, RepoSense scans your workspace (respecting .gitignore), parses source files into a persistent knowledge graph (files, functions, classes, imports, calls, API routes, tests…), builds a local retrieval index, and pulls in Git history where relevant. Ask it questions in the chat panel:
- "Where is authentication handled?"
- "What will be affected if I rename this function?"
- "Why was this code introduced?"
- "Trace this request from the API endpoint to the database."
Every non-trivial answer comes back with a Sources list — real file paths, line ranges, and commit hashes — and RepoSense validates those citations against the actual filesystem/Git history before showing them, flagging anything it can't verify instead of presenting it as fact.
Installation
RepoSense isn't (yet) published to the VS Code Marketplace. Install it from a .vsix release:
- Download the latest
.vsix from the Releases page (or build one yourself — see Packaging).
- In VS Code: Extensions view →
... menu → Install from VSIX... → select the file.
- Reload the window if prompted.
- Open a folder — RepoSense will offer to index it.
Or install from source — see Getting started (development).
Architecture
src/
├── extension.ts # activation, wiring, file watchers
├── commands/ # command palette + context menu handlers
├── chat/ # webview chat panel
├── indexing/
│ ├── scanner.ts # .gitignore-aware workspace scan
│ ├── parsers/ # LanguageParser implementations (TS/JS via TS compiler API,
│ │ # regex-based Python/Java/Go/Rust, plaintext/docs)
│ ├── chunker.ts # splits oversized chunks for retrieval
│ └── indexer.ts # RepositoryIndexer: orchestrates full + incremental indexing
├── graph/
│ └── knowledgeGraph.ts # in-memory graph + query primitives (callers, dependents, …)
├── retrieval/
│ ├── lexicalSearch.ts # keyword/symbol search
│ ├── semanticSearch.ts # local, dependency-free TF-IDF "embeddings"
│ ├── vectorStore.ts # real dense-vector store (cosine top-K, JSON persistence)
│ ├── remoteEmbeddingProvider.ts / azureEmbeddingProvider.ts # optional neural embeddings
│ ├── hybridRetriever.ts # combines lexical + semantic + dense vectors + graph + git
│ └── contextBuilder.ts # assembles the minimal, redacted context sent to the LLM
├── git/
│ ├── gitAnalyzer.ts # shells out to the local `git` CLI (history, blame, …)
│ └── githubProvider.ts / gitlabProvider.ts / bitbucketProvider.ts # opt-in PR/issue context
├── llm/
│ ├── providers/ # Anthropic, OpenAI-compatible, Azure OpenAI, Ollama, VS Code LM API
│ └── prompts/ # evidence-first system prompt
├── security/
│ └── secretRedactor.ts # secret file/pattern detection + redaction before any LLM call
├── storage/
│ └── persistentStore.ts # repo-scoped JSON store (graph, chunks, file hashes, vectors, embedding cache)
├── citation/
│ └── citationResolver.ts # verifies the model's citations actually exist
└── ui/ # status bar, onboarding, scoped graph visualization, settings webview, CodeLens
Design principles this implements
- Local-first, evidence-first. The whole repository is never sent to an LLM. Retrieval builds a small, ranked, token-budgeted context package for each question; only that package is sent.
- Hallucination guard. Every file/line/commit citation the model produces is checked against the real filesystem and
git log before being shown as verified.
- Provider-agnostic.
LLMProvider is a plain interface; Anthropic, any OpenAI-compatible endpoint, Azure OpenAI, Ollama (fully local), and VS Code's built-in Language Model API are implemented behind it. Switch via reposense.provider.
- Secrets never reach the model.
.env-style files and private keys are skipped entirely during indexing; anything that still looks like a credential is redacted before being sent to any provider.
- Incremental by default. A file watcher re-parses only changed files (by content hash) rather than rebuilding the whole index on every save.
- Extensible graph. New node/edge kinds, and new
LanguageParser implementations for additional languages, plug in without touching retrieval or the chat layer.
Getting started (development)
npm install
npm run compile # or: npm run watch
Then press F5 in VS Code (with this folder open) to launch an Extension Development Host with RepoSense loaded. Open any folder/repo in that host window — RepoSense will offer to index it.
Configuring a model provider
Run RepoSense: Set API Key (stores the key in VS Code's encrypted Secret Storage, not settings.json), then set reposense.provider and reposense.model in Settings. To run fully local, set reposense.provider to ollama and make sure Ollama is running locally with a chat-capable model pulled.
Azure OpenAI: set reposense.provider to azure-openai, then set reposense.azureOpenAI.endpoint (e.g. https://my-resource.openai.azure.com) and reposense.azureOpenAI.deployment (your chat model's deployment name, not its underlying model name — Azure routes by deployment). Set the API key via RepoSense: Set API Key as usual. reposense.azureOpenAI.apiVersion defaults to 2024-06-01; override it if your resource requires a different one. Azure's wire format differs from plain OpenAI-compatible endpoints (a deployment-scoped URL, an api-key header instead of Authorization: Bearer, a required api-version query parameter), so it's a separate provider (src/llm/providers/azureOpenAIProvider.ts) rather than a baseUrl override on the OpenAI-compatible one. The same applies to embeddings: set reposense.embeddingProvider to azure-openai and reposense.azureOpenAI.embeddingDeployment (usually a different deployment than the chat model).
You can also configure everything above from RepoSense: Open Settings, a dedicated settings UI with live token/key status.
Commands and keybindings
Every command below (except the two CodeLens-only ones) has a default keybinding using a ctrl+alt+r (cmd+alt+r on macOS) chord prefix — press the prefix, release, then the second key. Rebind any of them via Preferences: Open Keyboard Shortcuts and searching "RepoSense".
| Command |
Keybinding |
What it does |
RepoSense: Ask About Repository |
ctrl+alt+r a |
Prompts for a question, answers with citations |
RepoSense: Explain This Code |
ctrl+alt+r e |
Explains the current selection, using it as retrieval scope |
RepoSense: Explain Architecture |
ctrl+alt+r x |
High-level architecture overview |
RepoSense: Trace Function |
ctrl+alt+r t |
Shows callers/callees for a symbol from the graph directly |
RepoSense: Find Dependents |
ctrl+alt+r d |
Shows everything with an edge pointing at a symbol |
RepoSense: Rebuild Index |
ctrl+alt+r r |
Full re-scan and re-parse, with progress + cancellation |
RepoSense: Show Index Status |
ctrl+alt+r s |
Node/edge/file counts, last index time |
RepoSense: Cancel Indexing |
ctrl+alt+r c |
Cancels an in-progress index |
RepoSense: Show Knowledge Graph |
ctrl+alt+r g |
Interactive, scoped (not whole-repo) graph view for a symbol |
RepoSense: Open Chat Panel |
ctrl+alt+r o |
Focuses the chat view |
RepoSense: Set API Key |
ctrl+alt+r k |
Stores your provider API key in Secret Storage |
RepoSense: Set GitHub Token |
ctrl+alt+r h |
Stores a GitHub token to enable optional PR/issue context |
RepoSense: Set GitLab Token |
ctrl+alt+r l |
Stores a GitLab token to enable optional MR/issue context |
RepoSense: Set Bitbucket Token |
ctrl+alt+r b |
Stores a Bitbucket token to enable optional PR/issue context |
RepoSense: Open Settings |
ctrl+alt+r , |
A dedicated settings UI with live token/key status, complementing the native Settings page |
RepoSense: Explain Symbol / RepoSense: Trace Symbol |
(none) |
Used internally by CodeLens, which supplies the exact symbol id as an argument — a bare keybinding can't provide that argument, so binding one would fire the command against an undefined symbol. Use the CodeLens above a function/class, or RepoSense: Ask About Repository / RepoSense: Trace Function instead. |
Testing
npm test
test/ contains unit and integration tests for the pieces that don't require a running VS Code instance — the scanner's .gitignore handling, every language parser's symbol/edge extraction, the knowledge graph's query primitives, secret redaction, citation validation, all forge (GitHub/GitLab/Bitbucket) and LLM/embedding providers (including Azure OpenAI), the dense vector store, and full pipeline integration tests. They run under plain Node with assert (no @vscode/test-electron dependency needed for this test slice) — a minimal vscode module stub (test/stubs/vscode.js) lets modules that log via the shared logger run outside a real extension host.
Packaging
npm run package # produces a .vsix via @vscode/vsce
Current MVP scope and known limitations
This MVP prioritizes a working, evidence-grounded pipeline over exhaustive language coverage:
- TypeScript/JavaScript get real AST-based parsing (functions, classes, interfaces, imports, call graphs, API routes) via the TypeScript compiler API in single-file syntactic mode (no cross-file type checker, to keep incremental indexing fast).
- Python, Java, Go, Rust use a lighter regex-based extractor rather than a real AST/tree-sitter grammar. It produces function/class locations and relationship edges: heuristic call-graph edges (by identifier name, same
unresolved: placeholder mechanism the TS parser uses) for all four languages, plus inheritance-style edges for all four: real extends/implements edges for Python (class Dog(Animal)) and Java (extends/implements clauses), Go struct-embedding detection (an extends edge for type Dog struct { Animal; ... }), and Rust trait-impl detection (impl Trait for Type → an implements edge, where both endpoints may be unresolved placeholders since the impl block is very often in a different file than either definition). Being regex-based, all of this will have more false positives/negatives than the TS parser's AST-based extraction. This is the intended seam (LanguageParser) for dropping in a real tree-sitter-backed parser per language later.
- Semantic search always runs a local, dependency-free TF-IDF/cosine-similarity index (zero cost, zero network, zero setup). An optional real dense
VectorStore (reposense.embeddingProvider: "remote" or "azure-openai") layers neural embeddings on top, with a content-hash-keyed cache so unchanged chunks are never re-embedded.
- PR/issue integration: GitHub, GitLab, and Bitbucket Cloud are all supported behind a common
ForgeProvider interface and fully opt-in (reposense.forge.enabled: true plus a matching token). The provider is auto-detected from the origin remote. GitHub's provider is verified against the real, live api.github.com; GitLab/Bitbucket are verified against mocked responses matching their documented API shapes. Self-hosted GitHub Enterprise and Bitbucket Server/Data Center are not supported.
- Package size: bundling the full
typescript package for AST parsing makes the packaged .vsix several MB larger than a typical extension (~22MB unpacked). A production release would likely vendor a trimmed subset or move to a WASM-based parser (e.g. tree-sitter) to shrink this.
- The extension has been verified through compilation, an extensive automated test suite, a standalone pipeline script against a real git repository, and live calls to the real Anthropic and GitHub APIs — but has not yet been run inside an actual VS Code Extension Development Host in this development environment. If you hit UI-level issues, please open an issue.
Privacy
- Indexing happens entirely on-disk, locally. The index (
storage/persistentStore.ts) lives under VS Code's per-workspace storage directory, not inside your repository.
- Nothing is sent to an external LLM provider until you ask a question, and only the retrieved, redacted evidence for that specific question is sent — never the whole repository.
.env, private keys, and similarly named files are excluded from indexing entirely (security/secretRedactor.ts); a regex-based redaction pass also runs on every chunk immediately before it's sent to a provider.
- Telemetry is off by default (
reposense.telemetryEnabled) and this MVP does not implement any telemetry collection.
Contributing
Contributions are welcome! Please read CONTRIBUTING.md for how to set up your environment, coding conventions, and how to submit a pull request. Everyone participating is expected to follow the Code of Conduct.
Security
Please do not open a public issue for security vulnerabilities. See SECURITY.md for how to report one responsibly.
Changelog
See CHANGELOG.md for release notes.
License
MIT © Anand Shah
Made with ❤️ by Anand Shah for the developer community.