Skip to content
| Marketplace
Sign in
Visual Studio Code>Programming Languages>IntentNavNew to Visual Studio Code? Get it now.
IntentNav

IntentNav

AnandShah

| (0) | Free
Navigate your codebase by intent, not filename. Ask "Where is payment failing?" and jump straight to the code.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

IntentNav

License VS Code Engine Version Stars Issues TypeScript Strict PRs Welcome

Navigate your codebase by intent, not by filename.

Developers think in intents — "where is payment failing?", "show me the retry logic", "where do we validate JWT tokens?" — not in filenames. IntentNav turns that natural-language intent directly into ranked, clickable code locations, right inside VS Code.

Traditional:                         IntentNav:

Ctrl+P                               Cmd/Ctrl + Shift + I
→ login.ts                           → "Where is the login flow handled?"
→ search manually                    → ranked, explained results
→ inspect code                       → Enter
→ search callers                     → exact code, in context

It is not a chatbot. There's no conversation, no generic Q&A panel. You type an intent, you get a ranked list of real code locations with a one-line reason for each, and pressing Enter takes you straight there.

Table of contents

  • Example queries
  • Works with zero configuration
  • Architecture
  • Privacy
  • Supported languages
  • Commands
  • Configuration
  • Installation
  • Development
  • Known limitations
  • Roadmap
  • Contributing
  • Security
  • Changelog
  • License

Example queries

  • "Where is payment failing?"
  • "Show API retry logic"
  • "Where is authentication handled?"
  • "Where do we validate JWT tokens?"
  • "Find checkout validation"
  • "Where is this error thrown?" (with an error line selected)
  • "Where do we call Stripe?"

Works with zero configuration

IntentNav's MVP requires no API key, no cloud service, and no internet connection. It is built entirely on:

  • VS Code's native language services (executeDocumentSymbolProvider) for accurate symbols
  • A dependency-free regex-based fallback analyzer for languages without a rich language server
  • Deterministic, dictionary-based intent classification and query expansion
  • A local, explainable, multi-signal ranking model

External AI providers (Anthropic, OpenAI, Azure OpenAI, Ollama) are entirely optional and off by default. Enabling one only ever adds a short natural-language explanation on top of results that local ranking already found, or an optional semantic-similarity signal — it never replaces the core pipeline.

Architecture

IntentNav is explicitly not search query → ripgrep → results. It's a layered retrieval pipeline that always runs multiple signals in parallel and combines them into one explainable score:

                 ┌─────────────────┐
  raw query  →   │   QueryParser    │  deterministic intent classification +
                 │ (IntentProvider) │  concept-map term expansion
                 └────────┬─────────┘
                          │ QueryAnalysis
                          ▼
                 ┌─────────────────────────────┐
                 │      RetrievalPipeline       │
                 │  (SemanticSearchProvider)    │
                 │                              │
                 │  for every indexed symbol:   │
                 │   • lexical / content match  │
                 │   • symbol-name match        │
                 │   • path / folder match      │
                 │   • error-handling patterns  │
                 │   • import relationships     │
                 │   • call relationships       │
                 │   • recency / context match  │
                 │   • (optional) semantic sim. │
                 └────────┬─────────────────────┘
                          │ scored candidates
                          ▼
                 ┌─────────────────┐
                 │      Ranker      │  weighted sum → sorted SearchResult[]
                 └────────┬─────────┘
                          │
                          ▼
                 ┌─────────────────┐
                 │   IntentSearch   │  QuickPick UI: preview / open / related /
                 │   (ui layer)     │  copy / explain
                 └──────────────────┘

How ranking works

Every candidate (a function, method, class, or whole file) gets a score:

score = semanticScore   * semanticWeight        (default 0.35)
      + symbolScore     * symbolWeight          (default 0.20)
      + contentScore    * contentWeight         (default 0.15)
      + pathScore       * pathWeight             (default 0.10)
      + errorHandlingScore * errorHandlingWeight (0.08)
      + importRelationshipScore * importRelWeight (0.05)
      + callRelationshipScore * callRelWeight     (0.05)
      + recencyOrContextScore * recencyWeight     (0.02)
  • semanticScore — cosine similarity from an optional embedding provider; 0 when none is configured (the default).
  • symbolScore / contentScore / pathScore — term-overlap between the (concept-expanded) query and the symbol name / comments+strings / file path, with light stemming so "failing", "failed", "fails" all match "fail".
  • errorHandlingScore — only active for error/debugging-flavored queries; rewards try/catch/throw patterns found via VS Code symbol ranges or the regex fallback.
  • importRelationshipScore / callRelationshipScore — reward code that's actually wired into the rest of the codebase over orphaned code.
  • recencyOrContextScore — boosts your current selection/file, with a small recency fallback otherwise.

All eight weights are configurable (intentNav.semanticWeight, intentNav.symbolWeight, etc.), and every score is explainable: pick "Explain result" (or the lightbulb button) and IntentNav tells you exactly which signals fired, in plain English — never a black box.

Query understanding without an LLM

QueryParser deterministically:

  1. Tokenizes and strips stop-words from the query.
  2. Splits identifier-style words (camelCase, snake_case).
  3. Expands each domain term via a concept dictionary — e.g. payment → charge, transaction, checkout, refund, stripe, ... and failing → error, exception, catch, throw, declined, ...
  4. Classifies the query into an intent category (debugging, error-origin, error-handling, validation, integration, workflow-feature, symbol-lookup, ...) using hint phrases ("thrown" vs "handled", etc.).

This is what lets "Where is payment failing?" find code that never contains the word "failing" at all — code that throws PaymentError, catches provider exceptions, or returns a declined status.

Performance and indexing

Indexing is designed to stay out of your way, even in large repositories:

  • Batched, async, non-blocking. Files are indexed in small concurrent batches with progress reported via VS Code's window progress indicator — the UI thread is never blocked on a big scan.
  • Incremental after the first pass. File watchers (create/change/delete) plus onDidSaveTextDocument feed a 400ms-debounced queue, so only the handful of files you actually touched get re-indexed — never the whole workspace.
  • Warm-started from an on-disk cache. IndexCache persists the index to VS Code's per-workspace storage folder after every rebuild (debounced, so rapid saves don't each trigger a disk write). On the next window open, that cached snapshot is loaded and made searchable immediately, while a full re-index runs in the background to reconcile it with whatever changed since the last session — so a reopened large repo doesn't start from zero.
  • Never destructively cleared mid-scan. A rebuild upserts files as they're (re)discovered and only removes entries for files that turn out to be genuinely gone, so search results stay available throughout a rebuild instead of going blank.

Privacy

Privacy is a first-class feature, not a settings-page footnote:

  • By default, your source code never leaves your machine. Indexing, search, ranking, and snippet extraction are 100% local.
  • The on-disk index cache (symbol names, extracted comments/strings, file paths — derived data, not full file contents) is written only to VS Code's own per-workspace storage folder on your machine, never synced or uploaded anywhere.
  • No telemetry ships source code, ever — intentNav.enableTelemetry (off by default) would only ever cover anonymous, code-free usage counters, and no such telemetry is currently implemented.
  • Enabling an external provider (intentNav.provider: "anthropic", "openai", or "azure-openai", plus intentNav.enableAI: true) sends only the already-extracted snippet (capped) and your query for a single explanation call — never the full file, never the repository.
  • API keys are stored via VS Code's SecretStorage, never written into workspace files or logged.

Supported languages

Symbols come from VS Code's built-in executeDocumentSymbolProvider wherever a language server is available, so accuracy scales with whatever extensions you have installed. When no provider is available (or returns nothing), IntentNav falls back to its own regex-based analyzer, which has explicit support for:

TypeScript · TSX · JavaScript · JSX · Python · Java · Go · Rust · C# · C/C++

Adding another language means adding one entry to SUPPORTED_EXTENSIONS (src/utils/ignore.ts) and, optionally, a fallback symbol pattern in src/index/CodeAnalysis.ts — no rewrite required.

Commands

Every command has a default keybinding — all are remappable via VS Code's Keyboard Shortcuts editor (Preferences: Open Keyboard Shortcuts) if any combination conflicts with another extension you have installed.

Command Default keybinding Description
IntentNav: Navigate by Intent Ctrl/Cmd+Shift+I Main entry point — the live QuickPick search.
IntentNav: Search Workspace by Intent Ctrl/Cmd+Shift+Alt+I Same search via a plain input box (no live QuickPick).
IntentNav: Show Related Code Ctrl/Cmd+Shift+R Callers, dependencies, and tests for the symbol at your cursor. Also available by right-clicking inside the editor.
IntentNav: Rebuild Index Ctrl/Cmd+Shift+Alt+B Force a full re-index.
IntentNav: Open Settings Ctrl/Cmd+Shift+Alt+S Jump to intentNav.* settings.
IntentNav: Explain Result Ctrl/Cmd+Shift+Alt+E Explain the symbol at your cursor.
IntentNav: Set AI Provider API Key Ctrl/Cmd+Shift+Alt+K Securely store the API key for the currently configured intentNav.provider (Anthropic/OpenAI/Azure OpenAI), via VS Code SecretStorage.

Configuration

Setting Default Description
intentNav.maxResults 5 Results shown before "Show more".
intentNav.enableAI false Allow external AI providers.
intentNav.provider "local" local | anthropic | openai | azure-openai | ollama.
intentNav.azureOpenAIEndpoint "" Your Azure OpenAI resource endpoint, e.g. https://my-resource.openai.azure.com. Only used when intentNav.provider is "azure-openai".
intentNav.azureOpenAIDeploymentName "" The deployment name of your Azure OpenAI model. Only used when intentNav.provider is "azure-openai".
intentNav.azureOpenAIApiVersion "2024-06-01" Azure OpenAI REST API version to call. Only used when intentNav.provider is "azure-openai".
intentNav.indexIgnoredPaths [] Extra paths/globs to exclude from indexing.
intentNav.semanticWeight 0.35 Weight of semantic similarity (needs a provider).
intentNav.symbolWeight 0.20 Weight of symbol-name relevance.
intentNav.contentWeight 0.15 Weight of comment/string relevance.
intentNav.pathWeight 0.10 Weight of file-path relevance.
intentNav.enableTelemetry false Anonymous, code-free usage telemetry.

Using an external AI provider

All external providers are optional and off by default (see Privacy). To enable one:

  1. Set intentNav.provider to "anthropic", "openai", or "azure-openai", and intentNav.enableAI to true.
  2. For Azure OpenAI specifically, also set intentNav.azureOpenAIEndpoint (your resource endpoint, e.g. https://my-resource.openai.azure.com) and intentNav.azureOpenAIDeploymentName (the deployment name you created in Azure AI Studio / Azure OpenAI Studio) — these aren't secrets, so they're plain settings rather than something the API-key command asks for.
  3. Run IntentNav: Set AI Provider API Key (Ctrl/Cmd+Shift+Alt+K) and paste your key. It's stored via VS Code's SecretStorage, never in a settings file.

If a key or required setting is missing, or the request fails for any reason, IntentNav silently falls back to the local, offline explanation — enabling AI can never make results disappear, only add a short summary on top of what local ranking already found.

Installation

git clone https://github.com/AnandShah10/intentnav.git
cd intentnav
npm install
npm run compile

Then press F5 in VS Code to launch an Extension Development Host with IntentNav loaded, open any real repository in that window, and press Ctrl/Cmd+Shift+I.

Development

src/
  extension.ts              activation: wires everything together
  commands/                 command registration + status bar
  search/
    QueryParser.ts          deterministic intent classification
    Ranker.ts                weighted, explainable scoring model
    RetrievalPipeline.ts     lexical + symbol + structural + semantic retrieval
    IntentEngine.ts          top-level facade used by the UI
  index/
    WorkspaceIndexer.ts      full + incremental indexing, file watchers
    SymbolIndexer.ts         per-file symbol extraction (VS Code API + fallback)
    FileIndexer.ts           file discovery, respecting ignore rules
    IndexStore.ts            in-memory index + import/caller lookups
    IndexCache.ts            on-disk cache for instant warm-start on reopen
    CodeAnalysis.ts          dependency-free regex analyzer (imports/exports/
                              comments/strings/fallback symbols)
  providers/
    LocalIntentProvider.ts, LocalSearchProvider.ts   default, offline
    EmbeddingProvider.ts     Noop (default) + Ollama scaffold
    AIProvider.ts            Local (default) + optional Anthropic explanation
  navigation/
    Navigator.ts             open/reveal in the editor
    RelatedCode.ts           callers, dependencies, tests, sibling symbols
    SnippetExtractor.ts      smart logical-region extraction
  ui/
    IntentSearch.ts          the QuickPick experience
    ResultRenderer.ts        formatting
  config/Settings.ts         typed `intentNav.*` settings wrapper
  utils/                     pure, dependency-free helpers (heavily unit tested)
  types/                     shared interfaces (no vscode dependency)

Running tests

npm test

Unit tests cover QueryParser (intent classification across the example queries from the spec), Ranker (score ordering, error-handling gating, explanation generation, and configurable weights), and matchesContext (precise selection/file/symbol context matching) — all pure, vscode-free modules that run under plain Vitest with no editor instance required.

npm run test:integration

Runs the integration suite (test/suite/) inside a real, downloaded VS Code instance via @vscode/test-electron, with the fixture project at test/fixtures/sample-project/ opened as the workspace. This exercises the vscode-dependent code paths the unit tests can't reach:

  • indexer.test.ts — file discovery and ignore rules, symbol extraction and kinds, import-relationship detection, incremental re-indexing after a save
  • navigation.test.ts — opening the correct file/line, clamping out-of-range lines instead of throwing, clipboard copy format
  • edgeCases.test.ts — empty/whitespace queries, no-match queries, binary files never indexed, index cleanup after file deletion, a malformed file not corrupting the rest of the index, rebuildIndex completing without throwing

The first run downloads a VS Code test binary (cached afterward), so it needs normal internet access and takes longer than the unit suite.

Packaging as a VSIX

npm install -g @vscode/vsce
npm run compile
vsce package

This produces intentnav-0.1.0.vsix, installable via Extensions: Install from VSIX... in VS Code.

Known limitations

  • The regex-based fallback symbol extractor (used only when no VS Code symbol provider is available) uses brace/indentation counting and can occasionally mis-detect the end of a function whose signature contains an inline object type literal (e.g. function f(): { x: string } { ... }) — the primary executeDocumentSymbolProvider path does not have this issue.
  • "Call relationship" scoring is name-based (does it appear referenced elsewhere), not a true call graph — accurate call graphs generally require full type information per language.
  • Semantic search only activates when an embedding provider is explicitly configured; the default local mode is lexical/symbol/structural only.
  • The on-disk cache (see below) speeds up the next window open, but the very first index of a brand-new workspace is always a full scan — there's nothing to warm-start from yet.

Roadmap

The architecture was built so these can be added without a rewrite:

  • Real embedding-based semantic search (local model or cloud), wired through the existing EmbeddingProvider interface
  • Git history awareness ("what changed here recently and why")
  • Stack-trace-driven navigation ("paste this stack trace, jump to the failure")
  • "Why is this failing?" / "Where should I fix this?" — reasoning on top of the same retrieval pipeline
  • Cross-repository and team-shared indexes
  • Personalized ranking based on your own navigation history

Contributing

Contributions are very welcome — see CONTRIBUTING.md for the dev workflow, coding conventions, and how to submit a PR. Please also review our CODE_OF_CONDUCT.md.

Security

Found a security issue? Please don't open a public issue — see SECURITY.md for responsible disclosure instructions.

Changelog

See CHANGELOG.md for release history.

License

MIT © Anand Shah — see LICENSE for details.


Made with ❤️ by Anand Shah for the developer community

  • Contact us
  • Jobs
  • Privacy
  • Manage cookies
  • Terms of use
  • Trademarks
© 2026 Microsoft