Introduction
vexp is a local-first reliability layer for AI coding agents. Its context engine builds a live dependency graph of your codebase and serves your agent only the code that matters for the task; when the agent declares the task done, vexp verifies the work mechanically against that same graph. Session memory persists across days, and an optional local AI layer compresses prompts and context further. Everything runs on your machine.
The VS Code extension is the primary distribution. A standalone CLI (npm install -g vexp-cli) is available for terminal-only workflows. Both bundle the same native engine and MCP server — no external dependencies, no account required. The VS Code extension needs no Node runtime; the npm CLI requires Node 20 or later.
How it works
Index
vexp parses your source files and builds a graph stored at .vexp/index.db (local, gitignored). A small manifest.json with per-file content hashes is committed to git, teammates rebuild incrementally from the manifest in seconds.
Traverse
Given a natural-language task, vexp identifies the pivot nodes that matter via semantic search + graph traversal. Session memories from previous work are surfaced too.
Capsule
Pivot files are returned in full; supporting files as compact skeletons (signatures only). The result fits the configured token budget, typically 8 000 tokens.
Installation
Pick a distribution. The VS Code extension is the fastest path; the CLI is for terminal-only setups (Claude Code, Codex, scripts, remote machines).
Install from the Extensions panel
Open Extensions (Ctrl+Shift+X / ⌘⇧X), search for vexp, and click Install.
The extension bundles the native engine for your platform. There is no Node runtime to install, no separate compilation, and nothing to download afterwards. Open a project folder and click the vexp: not indexed status-bar item (or run vexp: Start Indexing) to build the index; already-indexed projects start their daemon automatically.
vexp.binaryPath in Settings to point at a locally-built vexp-core.Platform support
| Platform | Minimum OS |
|---|---|
| Linux x64 | Ubuntu 20.04+, Debian 11+, RHEL/Rocky 8+, WSL2 |
| Linux arm64 | Same minimum as Linux x64 |
| macOS Intel | macOS 11 (Big Sur) or later |
| macOS Apple Silicon | macOS 11 (Big Sur) or later |
| Windows x64 | Windows 10 or later |
| Windows ARM64 | Windows 11 on ARM; runs the x64 binary via built-in emulation |
First Run
Pick your distribution below. Both paths end with the same result: a working index, a configured AI agent, and a daemon that auto-restarts when needed, usually within 30 seconds on a typical project.
- Index with one click. Open a project folder — the first time, the status bar shows
vexp: not indexed; click it (or runvexp: Start Indexing) to build the index. On an already-indexed project the daemon starts automatically when the folder opens. The status bar showsvexp: indexingwhile it works, thenvexp: 1.2k · 0/20when ready (node count plus daily-call usage; numbers are abbreviated k/M). - Agents are configured. vexp sets up the AI agents the project itself shows (Claude Code, Cursor, Copilot, Codex, and more) and writes the right config file for each. A tool found only on this machine is offered once per project (see Supported Agents). Run
vexp: Project Setuporvexp: Setup Agents(multi-select) from the Command Palette to set up more. - No login hook is installed. The daemon starts when you open the folder or when an agent calls a tool. Want it warm after every reboot? Run
vexp autostart installfrom the CLI (optional, per-user, no admin needed). - Your AI agent just works. If the daemon was ever killed, it auto-restarts the next time an agent calls a tool, no manual management. Use the sidebar panel to monitor or stop it.
- NotePersonal mode: enable
vexp.personalModein Settings to skip writing shared-repo files (.claude/CLAUDE.md,.cursor/rules/vexp.mdc, git hooks). Useful when you want vexp on someone else's repo without changing their files.
VS Code Features
Beyond what your AI agent calls via MCP, vexp gives you visible feedback directly in VS Code (works the same in Cursor and Windsurf).
Sidebar panel
Click the vexp icon in the Activity Bar to open a sidebar with:
- Status header (running / indexing / starting / connecting / stopped / error / workspace cap reached / not initialized) and live index stats (nodes, edges, files, uptime, agent sessions).
- Activity (7 days): prompts analyzed, and the parts that add up to it: silences, orientations served and, when there are any, Held out (A/B) for the measurement holdback (disable with
holdback_pct = 0in.vexp/vexp.toml) and Past hook budget for orientations that finished after the agent stopped waiting. - Measured savings (tool calls) section — appears once at least one measured tool call exists — with a period selector (today, 7 / 14 / 30 / 60 / 90 days) and an Export Report button that writes a markdown report to
.vexp/token-savings-report.md. - Local LLM section with Install / Start / Disable / Check-updates / Status buttons, plus a one-time notification that offers to enable it.
- Contextual actions that follow daemon state: while running — Stop Indexing, Force Re-index, Generate Context Capsule, Add / Connect Repository, Setup Agents, Settings, View Daemon Logs; while stopped — Start Indexing, Setup Agents, Activate License, View Daemon Logs.
- Repository cards (status dot with an 'indexing NN%' badge while indexing, repo alias and path, node / edge / file counts, last-indexed time). A toggle shows or hides empty repos.
The panel auto-refreshes every 10 seconds.
CodeLens
Functions, methods, classes, interfaces, enums, and other indexed symbols in TypeScript, JavaScript, Python, Go, Rust, Java, C#, C, C++, Ruby, and Bash get an inline annotation once the file is indexed: first vexp: analyze impact, then N dependents across M files (plus | K cross-repo when cross-repo dependents exist). Click it to open the impact graph for that symbol. Available on every paid plan (Pro, Team, and lifetime tiers); not on the free plan.
Hover
Hover an exported TypeScript/JavaScript declaration (a line containing the export keyword) to see its dependents count, cross-repo usage, and top 5 callers. Available on every paid plan.
Status bar
The left-side status bar shows the current state. Clicking it opens your license status — except in the vexp: not indexed state (click starts indexing) and the vexp: workspace cap state (click opens the logs).
| State | Meaning |
|---|---|
vexp: not indexed | Never indexed yet; click to start indexing |
vexp: indexing NN% | Indexing in progress (progress percentage shown when known) |
vexp: 1.2k nodes | Healthy, plan with no node cap (Team, Lifetime Tier 4) |
vexp: 1.8k/2.0k | At ≥ 50 % of the node cap (yellow); shown when no daily quota is displayed — with a daily quota the same state renders as vexp: 1.8k · 12/20 |
vexp: 1.8k · 12/20 | Plans with a node cap (Starter, Pro, Lifetime Tier 1–3): daily-call usage after node count; warning (yellow) at ≥75% of the daily cap |
vexp: daily limit reached | Daily call limit reached (red): Starter pauses until midnight UTC; on a paid plan only the counted tools are refused until then |
vexp: 2.0k/2.0k | Node limit reached (red); the tooltip says how many source files were left out and the estimated size of the whole project |
vexp: workspace cap | Concurrent-workspace limit for your plan reached (yellow); click opens logs |
vexp: starting… | Daemon booting |
vexp: stopped | Daemon not running |
vexp: disabled | vexp.enabled is off in Settings |
vexp: error | Daemon failed, check logs |
Linked repos in VS Code
The active workspace's .vexp/workspace.json governs how repos are linked. See Multi-Repo Workspaces for the cross-repo features.
Commands
Everything you'll actually type, organized by where you type it.
Command Palette
Open the palette (Ctrl+Shift+P / ⌘⇧P), type vexp, and pick:
vexp: Project SetupSet up the agents this project shows (and those chosen for it before), write config files, ask about each tool found only on this machine, and ask once about git hooks.vexp: Setup AgentsMulti-select picker of all supported agents (Space to toggle, Enter to confirm). Tools found only on this machine are marked; what you pick is remembered for this project.vexp: Setup Multi-Repo WorkspacePick additional repos; vexp creates .vexp/workspace.json and enables cross-repo queries.vexp: Generate Context Capsule for Current TaskType a task description; vexp opens a panel with the pivot files and supporting skeletons.vexp: Show Impact Graph for Symbol at CursorOpen a panel showing what depends on the symbol you have selected.vexp: Show File SkeletonPick a detail level and see the file's structure without bodies.vexp: Show Index StatusOpen a panel with node / edge / file counts and uptime.vexp: Start IndexingStart the daemon if it's not running.vexp: Stop IndexingGracefully stop the daemon.vexp: Force Re-indexConfirm, then fully restart the daemon and re-index the project.vexp: Activate License KeyPaste a Pro / Team license key.vexp: Show License StatusSee plan, expiry, and links to manage your subscription.vexp: Show Token SavingsFocus the vexp sidebar panel, where the token-savings figures live.vexp: Verify Completion (parse errors, broken imports, impacted tests)Run the same mechanical completion check as vexp verify and write the report to the 'vexp verify' output channel; the summary is shown as a notification.vexp: Restart Daemon (after updates or config changes)Restart the daemon in place from the palette — the remedy for version-skew warnings from Doctor.vexp: Doctor (diagnose daemon, license, hooks)One-page health report: binary vs daemon version, index status, license, hooks wiring. The first thing to run when something feels off.vexp: Shield Scan (PII and secrets any AI agent can read)Scan comments and string literals for PII and secrets any AI agent could read. Masked previews only, everything stays local.vexp: SettingsOpen VS Code Settings filtered to vexp options.MCP Tools
Your AI agent uses these tools through MCP. You won't call them directly, your agent does, but it helps to know what each one does.
| Tool | Purpose | When to use |
|---|---|---|
run_pipeline | Primary tool. Context search + impact analysis + memory recall in one call. Auto-detects intent. | Every task |
verify_done | Horizon: mechanical completion check on the session’s changes: parse errors, broken imports, untouched dependents, impacted tests (the exact test files to RUN, with shared helpers flagged for UPDATE), docs drift. File:line evidence, free on every plan. Repeat calls on an unchanged tree return the cached verdict instantly. | Before declaring a multi-file task complete |
get_context_capsule | Lightweight context search with relevant memories. | Quick lookups |
get_impact_graph | What breaks if a symbol changes. Cross-repo supported. | Before refactoring |
search_logic_flow | Execution paths between two symbols. | Debugging |
get_skeleton | Token-efficient file structure (minimal / standard / detailed). | Exploring unfamiliar code |
get_session_context | Observations from current and previous sessions. | Recalling earlier work |
search_memory | Cross-session search with a "why this surfaced" rationale. | Finding past decisions |
save_observation | Persist an insight; optionally linked to a symbol for staleness tracking. | Recording context |
expand_vexp_ref | Retrieves the original code behind a [V-REF:xxxx] marker (12 hex chars) found in compressed vexp output. Free on every plan. | When compressed output references a V-REF |
index_status | Indexing health, stats, available repo aliases; when the plan’s node cap left files out, how many and the estimated size of the whole project. | Checking health |
workspace_setup | Generates agent configuration files. | First-time setup |
index_incremental | Live incremental or full re-index of a repo without restarting the daemon; built for push/PR-webhook pipelines. Pro/Team, native MCP server only. | CI / webhook reindex |
pr_impact | Changed symbols of a base..head git diff with their downstream dependents, most-impactful first. Pro/Team, native MCP server only. | PR-review automation |
run_pipeline, get_skeleton, expand_vexp_ref, verify_done; three via the Node MCP wrapper). Listing is not availability: every tool on this page stays callable even when unlisted. Set VEXP_ALL_TOOLS=1 on the MCP server to advertise the full plan-gated list.run_pipeline at a glance
run_pipeline replaces the older multi-step workflow with a single call that picks the right strategy for your task.
For multi-repo workspaces, scope a query with repos: ["backend", "shared"].
run_pipeline, get_context_capsule, and get_skeleton count against the Starter daily quota (20 / day, resets midnight UTC). Memory and status tools never count against it, on any plan. Impact, flow, and workspace_setup are Pro/Team features: on Starter they are not available as tools, and run_pipeline skips the impact and flow steps. Once the daily quota is spent, the daemon stops until the quota resets at midnight UTC, so no tool answers until then.Session Memory
vexp remembers what your agent explored, decided, and learned, automatically, across sessions and days. Memories are linked to the code graph, so when the underlying code changes, related memories are flagged stale (your agent sees that the past decision may no longer apply).
How it works
- Auto-capture. Every vexp tool call your agent makes becomes a compact observation in the local database.
- Auto-surface.
run_pipelineandget_context_capsuleinclude relevant memories in the result, no extra tool calls needed. - Each result explains itself. A short rationale tells the agent why this memory surfaced (matching the task, recent activity, related code, etc.).
- Staleness tracking. When code linked to a memory changes, the memory is marked stale and demoted in ranking, but still shown with a warning so the agent can re-evaluate.
The three memory tools
All three are included on every plan, Starter included, and none of them count against the daily quota. Note that on Starter they still stop answering once that quota is spent, because the daemon shuts down until it resets at midnight UTC:
get_session_context, observations from the current and previous sessions.search_memory, cross-session search across everything vexp has captured.save_observation, manually record an insight. Optionally link it to a symbol so it gets flagged when that symbol changes. Manually saved observations persist permanently. Auto-captured observations are ephemeral: when a session is compressed they are rolled into a session summary and pruned.
Supported Agents
vexp detects and configures 17 AI coding agents. Running vexp setup writes the correct configuration file for each agent it sets up, including tool-usage instructions tailored to that agent. For Windsurf and Kiro, setup also pre-approves the vexp tools in the MCP entry (alwaysAllow / autoApprove), so those agents never prompt per call. Every vexp tool also declares what it does in MCP terms (read-only, or writing only vexp's own local data), so Codex no longer asks permission before each vexp call and codex exec with approvals set to never no longer refuses them.
Which agents get set up. An agent the project itself shows is set up without asking: its own folder or file in the project (.claude, .cursor, opencode.json, …; for Codex a project .codex/config.toml, never AGENTS.md or anything else vexp writes), or an agent you chose for this project before. A tool found only on this machine (Codex's login, sessions or history under ~/.codex or CODEX_HOME, the ~/.claude folder, Antigravity's ~/.gemini/antigravity, Cline's VS Code storage) is not set up on its own. VS Code asks once per project, one question per tool: Set up / Not here / Never. vexp setup lists such a tool unselected, and without a terminal skips it and prints the command that adds it.
The answers live in ~/.vexp/agent-consent.json (per project, plus a list of tools you never want), shared by the extension and the CLI. Set up, or picking the tool in vexp setup, vexp setup-agents or vexp use, records yes. Not here records no for this project and removes what vexp wrote there for that tool (its AGENTS.md block when no other tool set up here reads it, its .codex hooks), keeping your own text and files. Never says no for every project on this machine, does the same cleanup, and removes vexp's machine-wide entry for that tool (Codex, Antigravity, Cline) when it names no project or this one; ~/.claude.json is never touched. Closing the question answers nothing: it comes back at the next start.
vexp setup --interventions installs an opt-in Stop hook that runs the Horizon completion check once per session (default setup does not install it); on opencode and Kilo Code the check runs at session idle through the default-on vexp plugin; every agent can call verify_done directly or run vexp verify headless.| Agent | Files written | Transport |
|---|---|---|
| Claude Code | .claude/CLAUDE.md + ~/.claude.json + .claude/hooks/ (vexp-hint.sh, vexp-search.sh, vexp-restore.sh; registered in .claude/settings.json). The Grep/Glob deny hook vexp-guard.sh is written only with vexp setup --guard-strict | stdio |
| Cursor | .cursor/rules/vexp.mdc + .cursor/mcp.json + .cursor/hooks/vexp-edit-hint.sh (via .cursor/hooks.json) | stdio |
| Windsurf / Devin Desktop | .windsurf/rules/vexp.md + ~/.codeium/windsurf/mcp_config.json (Cascade, user scope) + .devin/mcp_config.json (Devin Local); with Devin Desktop Next installed, also ~/.codeium/windsurf-next/mcp_config.json; earlier releases wrote .windsurf/mcp.json, which Cascade does not read | stdio |
| GitHub Copilot | .github/copilot-instructions.md + .vscode/mcp.json | stdio |
| Zed | .zed/rules.md + .zed/settings.json | stdio |
| Continue.dev | .continue/config.json | stdio |
| Cline | .clinerules + machine-global cline_mcp_settings.json (per installed VS Code variant) | stdio |
| Codex | AGENTS.md + ~/.codex/config.toml + .codex/hooks.json + .codex/vexp-hint.sh (.codex/vexp-hint.cmd on Windows) | stdio, direct (default); opt-in HTTP via VEXP_CODEX_TRANSPORT=http (CLI) or the vexp.codexMcpTransport VS Code setting, on 127.0.0.1:7821 by default (per-workspace override in .vexp/mcp.port); the HTTP entry always routes to one project |
| Opencode | AGENTS.md + mcp key in opencode.json(c) + .opencode/plugin/ (vexp-hint.js, vexp-compress.js) | stdio |
| Kilo Code | .kilocode/rules/vexp.md + mcp key in kilo.jsonc (.kilo/kilo.jsonc or root kilo.jsonc) + .kilo/plugin/ (vexp-hint.js, vexp-compress.js) | stdio |
| Kiro | .kiro/steering/vexp.md + .kiro/settings/mcp.json | stdio |
| Augment | .augment/guidelines.md | instructions only (no MCP file) |
| Trae | .trae/rules/project_rules.md + .trae/mcp.json | stdio |
| Firebase Studio | .idx/airules.md + .idx/mcp.json | stdio |
| Antigravity | AGENTS.md + ~/.gemini/antigravity/mcp_config.json | stdio (machine-global MCP config) |
| ZCode | AGENTS.md + mcp.servers key in .zcode/config.json (or .agents/mcp.json when the project already keeps its servers there, since ZCode stops reading that file once a .zcode config exists) + the orientation hook in ~/.zcode/cli/config.json (user scope: ZCode runs no project-level hooks) | stdio (binary, no node) |
| Friday Code | friday.md at the project root (the same mandate as AGENTS.md, appended to your own rules and refreshed on every vexp update) | instructions only (Friday Code connects to vexp on its side) |
Claude Desktop is two surfaces, not one. The desktop app hosts a Claude Code pane, and that pane is Claude Code: it reads ~/.claude.json and the project's .claude/ hooks, so the Claude Code row above already covers it and vexp setup needs nothing extra. Because those hooks inject context into the prompt rather than showing up as tool calls, vexp can be working there without ever appearing in the transcript. The app's plain chat is the other surface: it speaks MCP through claude_desktop_config.json and is not written by vexp setup. A chat with no repository open has nothing to index, so most people never need that entry, add it only if you want vexp in the plain chat pinned to one workspace.
Antigravity note. Antigravity reads the cross-tool AGENTS.md (v1.20.3+) together with GEMINI.md and .agent/rules/, and keeps its MCP servers in a machine-global file: ~/.gemini/antigravity/mcp_config.json. vexp registers its server there once and resolves the workspace per-session, so one configuration serves every project you open.
Codex note. vexp's entry in ~/.codex/config.toml names no project: Codex starts vexp in each session's own folder, so every project gets its own index. An entry an earlier release pinned to one project is rewritten this way the next time vexp sets Codex up. In a folder that is not a vexp project, vexp answers with no tools and says why, instead of failing Codex's start. To make every Codex session use one project's index, whatever folder it starts in, run vexp use <path> --pin; vexp use --unpin undoes it.
Codex runs a project hook only after you trust it. When vexp writes or changes its orientation hook, VS Code shows this step once and vexp setup prints it: in the Codex extension for VS Code, open the Codex panel > Settings > Hooks and trust vexp-hint; in a terminal, run codex in the project, type /hooks and approve vexp-hint (trust the folder first if Codex asks). On Windows the hook is registered as cmd /d /c call "<project>\.codex\vexp-hint.cmd", which runs whether Codex starts it through PowerShell or cmd, and the terminal and the VS Code extension keep separate approvals, so approve it in each one you use. After updating from 3.2.5 on Windows, approve it once more: its command changed. vexp doctor shows which approvals are in place.
VS Code forks & Open VSX. The vexp extension also runs in the AI-IDE forks of VS Code, Antigravity, Cursor, Windsurf, Kiro, VSCodium, whose Extensions views are backed by the Open VSX registry (the Microsoft Marketplace is licensed to Microsoft products only). Search for “vexp” there, or use “Install from VSIX” with the same .vsix we ship for VS Code, no fork-specific build needed. Trae ships its own extension store and accepts the VSIX directly.
Windows + WSL2
Inside WSL2, vexp is simply Linux: install the linux-x64 CLI or extension in the WSL side and everything, daemon, index, MCP server, runs there. The one thing to keep straight is that your agents live on both sides of the boundary, and each side reads its own configuration. vexp setup runs inside WSL, so it can only write WSL-side files.
| Agent runs | Reads its config from | What to do |
|---|---|---|
| In the WSL remote of your editor (Cursor, VS Code + Copilot, Trae, Kiro, …) | Project-level files inside the repo (.cursor/mcp.json, .vscode/mcp.json, …) | Nothing extra, vexp setup inside WSL covers them |
| In the WSL shell (Claude Code, Codex CLI, opencode) | The WSL home (~/.claude.json, ~/.codex/config.toml, AGENTS.md) | Nothing extra, vexp setup inside WSL covers them |
| As a Windows desktop app (Codex app, Claude Desktop) — and Windsurf / Devin Desktop: even with a WSL folder open, Cascade starts MCP servers on the Windows side | The Windows profile (C:\Users\<you>\…), never the WSL home | Add the entry by hand on the Windows side, bridged through wsl.exe (below) |
| The same folder opened both in a Dev Container (or WSL / SSH remote) and on the Windows host | Hook scripts and MCP entries in the repo bake the binary path of the environment that ran setup (/root/.vscode-server/…/vexp-core vs C:\Users\…\vexp-core.exe) | Each side needs its own paths: the extension re-pins them when it activates in the other environment; if a file still points across, run vexp: Setup Agents there |
Concretely: the Codex desktop app reads C:\Users\<you>\.codex\config.toml, not the WSL ~/.codex/config.toml that vexp setup writes. Claude Desktop reads %APPDATA%\Claude\claude_desktop_config.json, and the Microsoft Store build relocates it to %LOCALAPPDATA%\Packages\Claude_*\LocalCache\Roaming\Claude\claude_desktop_config.json.
Bridging a Windows app to vexp in WSL
The entry goes in the Windows-side config and crosses into WSL with wsl.exe. Two rules: environment variables set in the MCP entry do not propagate through wsl.exe (that would need WSLENV), so set them on the command line inside WSL instead; and launch via bash -lc so a version-managed Node (nvm) is on PATH. To find the server path, run npm root -g inside WSL and append /vexp-cli/mcp/mcp-server.cjs.
Cascade reads that one file and no project-level one; quit and reopen Windsurf after editing it. Devin Desktop Next (the beta build) is a separate install with its own copy at %USERPROFILE%\.codeium\windsurf-next\mcp_config.json; the same entry goes there. vexp setup run inside WSL prints this entry filled in with your real paths, ready to paste. Devin Local (the agent in Devin Desktop) reads .devin/mcp_config.json from the project, which setup writes; if it too runs on the Windows side, the same entry goes in %APPDATA%\devin\mcp_config.json.
With more than one distro installed, pin it: args = ["-d", "Ubuntu", "--", …]. These bridged entries pin one workspace by design, a Windows-side config cannot follow whichever WSL project you happen to open, so point VEXP_WORKSPACE at the repo that app should use.
vexp doctor runs inside WSL and cannot see Windows-side configs: if an agent ignores vexp even though setup reported success, first check which side of the boundary that agent reads its config from. In a WSL remote, editor extensions install into the WSL extension host, let the editor pick the package (it selects linux-x64) rather than hand-downloading a VSIX.Multi-Repo Workspaces
vexp can index multiple repositories as a unified workspace and detect relationships between them, entirely on your machine. Useful for monorepos split across repos, frontend + backend pairs, and microservices.
Setup
Create .vexp/workspace.json in your primary repo, or click Add / Connect Repository in the sidebar, or run vexp in a terminal and pick Repos & Workspace to list connected repos or add one from the CLI (the plan's repo limit is enforced; a running daemon indexes the new repo automatically).
Paths are relative to the folder that contains the .vexp/ directory: use "." for that root itself, and a subfolder (packages/api) or a sibling (../shared-lib) for every other repo. Listing the root with "." is optional — the primary is always served, and always under its folder name as its alias (an alias you write on the "." entry is ignored). The workspace_id key is also accepted in place of name.
Index the workspace
A workspace is indexed as a whole, not one repo at a time. After creating workspace.json, index every repo in the list in one step, then point your agent's MCP server at the workspace root.
Open the workspace root (the folder holding .vexp/workspace.json), or click Add / Connect Repository. vexp loads every repo in the list and indexes any that aren't up to date.
vexp index run inside any single repo of a workspace indexes the entire workspace, not just that folder. Your plan's repo limit still applies, repos beyond it are skipped with a note in the output. If the daemon is already running you don't need to restart it — it watches workspace.json and picks up a newly added repo automatically within a few seconds.Cross-repo edge detection
vexp automatically detects five kinds of relationship across repos:
| Type | How vexp detects it | Example |
|---|---|---|
| API contract | OpenAPI / Swagger spec files (openapi.yaml/.yml/.json, swagger.json/.yaml, api.yaml/.yml — at the repo root or under src/, api/, docs/, spec/); each declared endpoint is linked to the workspace's other repos as potential consumers | Backend exposes /api/users; frontend fetches it |
| Shared types | package.json dependency matching between repos | Both repos import @company/shared-types |
| Env contract | .env.example keys matched to process.env / os.environ usage | Backend defines DATABASE_URL; worker reads it |
| Manifest reference | JSON manifest entries that name another workspace repo by alias or by a relative path into it | catalog.json points at ../shared-lib/schema |
| Doc authority link | Links in README.md, AUTHORITY.md, INDEX.md, MANIFEST.md, CATALOG.md, REFERENCES.md or ARCHITECTURE.md that point at a sibling repo (GitHub URL or relative path); links inside code fences are ignored | README says "the contract lives in ../api-spec/" |
Querying across repos
run_pipelineandget_context_capsulequery all indexed repos by default.- Scope with
repos: ["backend"]. - Use
cross_repo: trueonget_impact_graphandsearch_logic_flowto trace across repo boundaries. - Use
repo: "alias"onget_skeletonto target a specific repo — the alias is the onerun_pipelineprints next to each file. The alias is optional: an absolute path pins its repo, and a repo-relative path is looked up in the primary first, then in every connected repo. - Call
index_statusto see available repo aliases. - From the CLI:
vexp capsule --repos backend,shared,vexp impact <fqn> --cross-repo,vexp flow <start> <end> --cross-repo.
Git worktrees and parallel agents
Agent harnesses create a linked git worktree per parallel task (Claude Code under .claude/worktrees/, Cursor's background agents, or your own git worktree add). A worktree is a full copy of the checkout, and it is the same project, and vexp treats it that way everywhere. The generated git hooks detect a linked worktree from .git's own gitdir line — no path convention, so every agent is covered — and skip per-worktree indexing (set VEXP_WORKTREE_INDEX=1 to opt back in); the login supervisor (vexp serve) never resurrects worktree daemons after a reboot and staggers the daemons it does bring back. A new worktree needs no setup of its own: it takes the answer you gave for its repository, so the first agent session in a worktree of a repository set up with vexp indexes it in the background (a worktree of a repository that never had vexp is left alone); until it is complete, answers say they cover only the files indexed so far. On Windows, agents connected through vexp's Node MCP server still need vexp index in a new worktree. That index is kept out of git, so git worktree remove works without --force and takes it along once the session has ended. A daemon started in a worktree shares one license slot with its repository, is not revived at boot, and stops about a minute after the worktree is removed. On Windows a file in use cannot be deleted, so removing a worktree while a vexp daemon runs in it leaves the folder behind; the daemon then stops and the folder can be deleted. To have the index ready before the first prompt, run vexp index from the script your tool runs when it creates a worktree (a Codex local environment's setup script, for example), or set VEXP_WORKTREE_INDEX=1. Submodules are separate projects and are untouched by all of this.
Codex across several workspaces
Nothing to switch: Codex's vexp entry names no project, so each Codex session uses the index of the folder it starts in. To make every Codex session use one workspace instead, run vexp use <workspacePath> --pin; vexp use --unpin undoes it.
.vexp/ during setup.Local LLM (optional)
vexp ships an optional on-device AI layer that improves prompt preprocessing and compresses the context further. Everything runs on your machine, no cloud, no account, no code leaving your laptop.
Multi-language prose compression: language detection covers 15 languages: English, Italian, French, German, Spanish, Portuguese, Russian, Chinese, Japanese, Korean, Arabic, Hindi, Turkish, Dutch, Polish.
Install & manage
One-time download (~3.5 GB). Files stay on disk after a disable, so re-enabling is instant. Requires at least 6 GB of RAM; below that the installer declines and vexp stays on the built-in rule-based compressor. On NVIDIA Linux/Windows machines, a one-time CUDA plugin (~62 MB) and CUDA 12 runtime (~550 MB) are also downloaded automatically.
The sidebar's Local LLM section shows the model status and these buttons:
- Install LLM (primary, blue), when not yet installed. A one-time first-run notification (Enable now / Learn more / Not now) also offers this.
- Start LLM (primary, blue), when installed but disabled.
- Check LLM updates (secondary), shown only while the LLM is active; compares your model with upstream without downloading.
- Disable LLM (red, destructive), when active. Files stay on disk.
- LLM Status, writes the full diagnostic (hardware, files, backends registered) to the 'vexp: LLM' output channel.
Extension users need none of these commands: the sidebar's Install LLM / Start LLM / Disable LLM buttons drive the bundled binary directly. One thing to know either way: the daemon builds its compressor when it starts, so enabling the model changes nothing until the daemon is restarted — vexp: Restart Daemon from the Command Palette, or vexp daemon-cmd restart. When the sidebar shows "LLM is configured but this daemon is running the rule compressor", that is the case it describes; the banner carries a Restart daemon button and the Start/Install actions offer the restart themselves.
GPU acceleration
Works the same in both distributions. On Apple Silicon, Metal is detected and used automatically; Intel Macs run the model on CPU by design. On Linux or Windows with an NVIDIA GPU, CUDA is detected and used automatically, no flag or environment variable is needed. If no usable GPU is found, inference silently falls back to CPU. GPU preference is a config setting: prefer_gpu = false under [llm] in ~/.vexp/config.toml forces CPU inference. flash_attention = "auto" | "on" | "off" (same [llm] table; env default VEXP_FLASH_ATTENTION) — set "off" if your GPU crashes while running the model.
NVIDIA GPUs are supported on Linux and Windows; a one-time CUDA plugin download is fetched automatically. The first GPU inference may take a few seconds to warm up.
GPU offload requires an NVIDIA driver at least as new as CUDA 12.8 (570.xx or newer); on older drivers inference falls back to CPU until the driver is updated. If a GPU attempt ever crashes the daemon, vexp writes ~/.vexp/gpu-unusable and runs the model on CPU from then on. Delete that file after a driver update to retry the GPU (upgrading vexp retries once automatically). If the file says the crash happened while running the model, delete it and set flash_attention = "off" under [llm] to keep the GPU.
Use your own server (optional)
Instead of the ~3.5 GB download, point vexp at any OpenAI-compatible server via endpoint / endpoint_model / endpoint_api_key under [llm] in ~/.vexp/config.toml (llama.cpp llama-server, LM Studio, vLLM, Ollama /v1, AMD Lemonade, FastFlowLM on Ryzen AI NPUs). The endpoint is tried first at daemon start, with automatic fallback to the local model, then the rule-based compressor.
Share one model across environments
The model is a single ~3.5 GB GGUF file, identical on every platform, stored under the OS data directory: ~/.local/share/vexp/models/vexp-devmind-v1/ on Linux (/root/.local/share/… in a container running as root), ~/Library/Application Support/vexp/models/… on macOS, %APPDATA%\vexp\models\… on Windows. Every Dev Container, WSL distro or machine that installs it downloads its own copy unless you share one. Three ways, best first:
One shared volume. Mount a named Docker volume at the default models directory in every container; install once, and in every other container vexp setup-llm --install (or the sidebar's Install LLM) finds the file already there, verifies its size and skips the download — the step only writes that container's config.
Reuse the host's copy. The same mount as a bind mount of the host folder (source=${localEnv:APPDATA}/vexp/models on Windows) needs no second copy at all. The model is memory-mapped, and reading it through Docker Desktop's file sharing is slow: the first calls after a start can exceed timeout_ms, which falls back to the rule compressor for that call. Fine when disk space matters more than warm-up time.
One server, many clients. Serve the GGUF once on the host (llama.cpp llama-server, LM Studio, Ollama) and point every environment at it with endpoint as above — http://host.docker.internal:8080/v1 from a container. No model files anywhere else, and inference runs on the host's GPU, which containers only get with the NVIDIA container toolkit. Any other location works too: model_path under [llm] in ~/.vexp/config.toml names the file directly. The CUDA plugin is per-platform and is not shared.
Configuration
vexp works out of the box. Tune it via VS Code settings, .vexp/vexp.toml, environment variables, or ignore files.
VS Code settings
All under the vexp. prefix in Settings or your settings.json:
| Setting | Type | Default | Description |
|---|---|---|---|
vexp.enabled | boolean | true | Master toggle for the extension |
vexp.guardStrict | boolean | false | Install the Grep/Glob deny hooks when configuring agents (opt-in). When off, agent setup removes any previously installed vexp guard hooks. |
vexp.maxContextTokens | number | 8000 | Maximum tokens per context capsule |
vexp.skeletonDetail | enum | "standard" | minimal / standard / detailed |
vexp.gitHooksInstall | boolean | true | Off: vexp removes its git hooks from this clone and does not reinstall them, like answering Skip; back on, they return (or the hooks question is asked). The index still refreshes through the file watcher |
vexp.multiRepo.enabled | boolean | true | Multi-repo workspace support |
vexp.multiRepo.workspaceConfig | string | ".vexp/workspace.json" | Path to the workspace config |
vexp.telemetry.enabled | boolean | false | Anonymous usage telemetry (opt-in; never code content) |
vexp.mcpPort | number | 7821 | MCP HTTP port, used only when vexp.codexMcpTransport is set to http |
vexp.codexMcpTransport | enum | "direct" | How vexp configures the Codex IDE MCP server (direct stdio vs VS Code-managed HTTP); a config you wrote by hand is left untouched |
vexp.binaryPath | string | "" | Override the vexp-core binary path (escape hatch) |
vexp.logLevel | enum | "warn" | error / warn / info / debug |
vexp.personalMode | boolean | false | Skip agent configs + git hooks for this workspace |
vexp.hideInternalFiles | boolean | true | Hide .vexp internal files from the explorer |
.vexp/vexp.toml
Optional file at .vexp/vexp.toml inside the repo (all keys top-level — no [index] table). Useful for ranking hints and indexing limits:
In a multi-repo workspace, the primary workspace's .vexp/vexp.toml is the default for every connected repository. A connected repo needs its own file only where it wants to differ, and any key it sets there wins for that repo; keys it leaves out come from the workspace. So raising max_file_size_kb once on the primary applies to all of them.
The file may be UTF-8, with or without a byte-order mark, or UTF-16 as Windows PowerShell and Notepad save it. A file that cannot be read or parsed, or that has a setting of the wrong type, gets one warning in the log naming the file (and the setting); the whole file is then ignored and the defaults apply (in a connected repo, the workspace's settings). vexp still starts.
Delivery boundary
vexp indexes the working tree — shipped code, tests, docs, anything .gitignore does not cover. A project delivered as a package (a WordPress plugin ZIP, an npm tarball) ships a subset, and the file that says which is not .gitignore: it is .distignore (wp dist-archive) or .npmignore. When the repo root has one of those — or delivery_ignore names your own gitignore-syntax file — run_pipeline adds a header line > delivery boundary: .distignore — 2 of 5 pivots are outside the package and tags each such pivot (not shipped), so a file:line citation says whether the code is delivered. Ranking is unchanged; without such a file the output is exactly as before. It is an annotation, not a check of the package contents.
A source file over max_file_size_kb is not indexed at all: its symbols and the calls it makes are invisible to impact,search and run_pipeline. Every such skip is recorded in .vexp/coverage.json, flagged by vexp doctor and the index_status tool, printed after vexp index, and disclosed in the header of every pipeline answer. Files matching exclude_patterns are out by choice: they are not counted as oversized and never appear in the coverage warning — after adding a pattern, run vexp index once to refresh coverage.json.
Environment variables
| Variable | When to set it |
|---|---|
VEXP_CORE_PATH | Bundled binary won't run, point at a locally-built vexp-core |
VEXP_HOME | Override the home directory used for ~/.vexp/ state (license, config, daemon registry). Set this when running inside a sandboxed environment (e.g. Codex, containers, CI) where the OS-resolved home directory differs from the real user profile. Must be an absolute path. |
VEXP_NO_AUTOSTART_INSTALL=1 | Don't install login autostart on first vexp setup |
VEXP_PORT=<port> | MCP HTTP port (default 7821), set if 7821 is taken |
VEXP_TRACE=1 | Verbose trace mode, same as -i/--trace (IPs / tokens / home paths redacted) |
VEXP_NO_AUTOSTART=1 | Disable the lazy daemon/MCP bootstrap the CLI performs before most commands |
VEXP_OFFLINE=1 | Stay fully offline: disables all license network calls (14-day grace applies) |
VEXP_SKIP_UPDATE_CHECK=1 | Skip the advisory npm update check (same as --skip-update-check) |
VEXP_WORKSPACE=<path> | Pin workspace resolution (honored before CLAUDE_PROJECT_DIR); vexp doctor warns when a global pin points at the wrong repo |
VEXP_OUTPUT_MODE=<v2|legacy> | Default for the output_mode config key |
VEXP_TESTS_GATE=<off|instruct|run> | Per-session override of tests_gate |
VEXP_AMBIENT_DECAY=<n> | Override ambient_decay_after |
Manifest & git
.vexp/index.db is local-only (gitignored by default). .vexp/manifest.json contains a small list of content hashes and is committed to git, clones rebuild incrementally from it (typically < 5 s on a 5 000-file repo). The pre-commit hook refreshes the manifest but does not stage it into your commit automatically; opt in with stage_manifest = true in .vexp/vexp.toml. A merge driver auto-resolves manifest conflicts. Git hooks (pre-commit, post-checkout, post-merge) keep the index in sync. Existing hooks coexist via marker-delimited blocks.
VS Code asks once per project whether to install them. Skip is remembered for this clone in .vexp/git-hooks.declined (never committed, so a teammate does not inherit it): vexp removes the hooks it had installed and the daemon no longer puts them back. vexp hooks remove, personal mode and the vexp.gitHooksInstall setting turned off record the same answer (the last two withdraw it once you undo them); vexp hooks install reinstalls them and withdraws it. Without the hooks the index still refreshes: the daemon watches the tree while it runs and reconciles it periodically.
core.hooksPath (e.g. husky), hooks installed in .git/hooks never run — vexp detects and reports this.Ignore files
vexp honours .gitignore, .ignore, .vexpignore and .vexp_ignore at every level of the tree, plus .git/info/exclude and git's global excludes file, all in gitignore syntax: negations, rules starting with a slash (/chatlogs/) and bare folder names work as in git. The live watcher applies exactly the rules of a full scan, together with exclude_patterns, the size and minified limits and the secret filter, so a file saved while vexp runs is indexed only if a full index would include it. A change to an ignore file in the project or to .git/info/exclude applies within seconds, without a restart, and a file it excludes is removed from the index with its change notes. Common directories are excluded by default: node_modules, .git, .vexp, target, dist, .next, __pycache__, build, vendor, Pods, DerivedData, .expo, venv, .venv, site-packages, .tox, .gradle, .m2, bin/Debug, bin/Release, obj, coverage, .nyc_output, test-results, playwright-report. Nested git checkouts (worktrees, submodules) are pruned as whole subtrees, and minified assets (*.min.js, *.min.css, *.bundle.js, ...) are skipped by filename.
Notes kept in the repository. A Markdown file that records the questions you ask vexp is, by construction, the strongest text match for those same questions. Since 3.2.0 a documentation section that records a question (a Q1: label, an expected/got note, a list of questions) is demoted the way CHANGELOG files already are, and files under notes/, journal/, diary/ or scratch/ are treated as records, as are the reports an agent writes when it is done (MISSION_ACCOMPLISHED.md, fixes_summary_final.md); a FAQ that states the question it answers is not touched. Agent instruction files and folders (.claude/, CLAUDE.md, AGENTS.md) rank as repository furniture. The pivot's why line names the rule (quotes the question, diary path). To take a folder out of the index entirely, add it to .vexpignore (/notes/ for a root-anchored rule); an exclude_patterns entry also matches the same name at any depth, so prefer .vexpignore for one specific folder.
Supported Languages
vexp parses 36 languages plus Markdown, CSS/SCSS/LESS stylesheets included. 32 have a dedicated tree-sitter grammar with language-specific extraction. For Vue, Svelte and Astro the <script> block (and Astro's --- frontmatter) is parsed as TypeScript; for Razor/Blazor the @code/@functions blocks are parsed as C#. Symbols keep their real file line numbers, and every component file gets a component node searchable by name. Templates/markup are not parsed. SQL indexes DDL, tables, views, functions, indexes, triggers from migrations and schema files. In Ruby, the methods ActiveRecord generates from has_many, has_and_belongs_to_many, has_one, belongs_to and scope (posts, post_ids, build_author, ...) are indexed as methods of their model since 3.3.1, and so is what delegate defines since 3.3.2. Ruby calls written without parentheses (author.posts, post.author.full_name) are linked through the class the receiver names, its superclasses and the modules it includes; a public_send with a computed name is reported by vexp impact as a dynamic call. Markdown is indexed via a structural heading scan (no tree-sitter). The doc comment directly above a declaration is indexed as the symbol's docstring - JSDoc, Python, Go and Rust since the beginning; Dart ///, C# /// <summary> (XML stripped), Javadoc and Doxygen blocks, Kotlin, Scala, Swift, C, C++, Objective-C, PHP, Ruby, Bash, PowerShell, Lua and OCaml since 3.2.0 - so a plain-English question can match the words of your comments, not only the words inside identifiers. Licence headers, trailing remarks and pragma lines are not docstrings, and secret-shaped values in a comment are masked before they are stored.
| Language | Extensions |
|---|---|
| TypeScript | .ts, .tsx |
| JavaScript | .js, .jsx, .mjs, .cjs |
| Python | .py |
| Go | .go |
| Rust | .rs |
| Java | .java |
| C# | .cs |
| C | .c, .h |
| C++ | .cpp, .cc, .cxx, .hpp, .hh, .hxx |
| Ruby | .rb |
| Bash | .sh, .bash |
| Kotlin | .kt, .kts |
| Scala | .scala, .sc |
| Swift | .swift |
| Dart | .dart |
| PHP | .php, .module, .install, .inc, .theme, .profile, .engine (Drupal) |
| Elixir | .ex, .exs |
| Haskell | .hs |
| OCaml | .ml, .mli |
| Lua | .lua |
| R | .r, .R |
| Zig | .zig |
| HCL / Terraform | .tf, .hcl |
| Objective-C | .m, .mm |
| Clojure | .clj, .cljs, .cljc |
| F# | .fs, .fsx, .fsi |
| Dockerfile | Dockerfile, Dockerfile.* (matched by filename, not extension) |
| Vue | .vue |
| Svelte | .svelte |
| Astro | .astro |
| Razor / Blazor | .razor, .cshtml |
| SQL | .sql, .ddl, .dml |
| PowerShell | .ps1, .psm1, .psd1 |
| Groovy / Gradle | .groovy, .gvy, .gradle |
| Julia | .jl |
| CSS / SCSS / LESS | .css, .scss, .less |
manifest.json, refs.json, index.json, catalog.json, examples.json, samples.json, registry.json, openapi.json, swagger.json, and *.manifest.json / *-manifest.json / *_manifest.json variants (same for catalog/examples/samples/registry) — are structurally indexed (top-level entries become searchable nodes, up to 500 per file). package.json, lockfiles, tsconfig*.json and other tool configs are never indexed, and nothing under .vexp/ is.Markdown indexing
Markdown files (.md, .mdx, .markdown) are first-class index nodes. Each file becomes a Document node (named after the file stem); each ATX heading (# through ######) becomes a nested Section node; each http:// or https:// URL becomes a Link node (URLs inside fenced code blocks are skipped).
Planning documents, spec.md, plan.md, tasks.md, README.md, ADRs under docs/adr/, RFCs under docs/rfcs/, get a ranking boost when an agent searches for design or architecture context. Surfaced through run_pipeline and get_skeleton like code files.
Documentation-only repositories
A folder with no source code at all is a valid workspace: a knowledge base, a handbook, a tree of ADRs and specs. Run vexp setup in it from the CLI. The VS Code extension activates on a folder that holds source files or an existing .vexp/manifest.json, so in a Markdown-only folder run vexp setup once, or vexp: Setup Agents from the Command Palette, and it picks the index up from there.
What is matched. vexp matches the words of the task against document names, headings and section text, then ranks by structure. There are no embeddings: a question that shares no word with a section does not reach it on its own, which is why it works best through an agent, which turns a loose question into the terms your documents use. Sections come from ATX headings (#); a file with no headings is a single Document node, so the only thing vexp can return for it is the whole file.
What ranks lower. Ranking was tuned on code repositories, where a record of a change is never the answer. Three path rules matter in a knowledge base. A dated file name (2026-09-14-retro.md) and the folders notes/, journal/, diary/, scratch/, blog/, posts/ and releases/ mark a record, which ranks well below a reference document. A folder named exactly like a locale code (fr/, de/, it/, pt-br/) is read as a translation and left out of the answer. If meeting minutes or an it/ department folder are what you need to retrieve, name them otherwise (minutes/vendor-sync-september.md, it-department/).
To see what happened to a document you expected, name it: vexp capsule "who approves a refund?" --explain refunds.md runs the same retrieval and says where that file left it and which rule applied.
Troubleshooting
Pick your distribution for the distro-specific issues, then check the cross-distro table below for the rest.
| Symptom | Diagnose | Fix |
|---|---|---|
| Extension does nothing | Run 'vexp: Doctor (diagnose daemon, license, hooks)' from the Command Palette — the health report lands in the 'vexp doctor' Output channel | Open a folder with a supported source file (or .vexp/manifest.json) |
| Index never updates | vexp: Show Index Status | vexp: Force Re-index |
| Bundled binary won't run | See the binary error in the Output panel | Set vexp.binaryPath in Settings |
| macOS "unidentified developer" | Only affects binaries copied or downloaded by hand (quarantined files) | Install via npm or the marketplace (never quarantined). For a hand-copied binary: xattr -d com.apple.quarantine <path> |
| Sidebar empty / no repos | Check status header in the sidebar | Use vexp: Start Indexing or reload the window |
| Copilot Chat shows no vexp tools / no vexp MCP server | Run vexp doctor (it checks .vscode/mcp.json); in VS Code: Command Palette → MCP: List Servers → vexp → Show Output | MCP tools exist only in Chat Agent mode (tools picker → "MCP Server: vexp"); the folder open in VS Code must be the one you set up; on spawn node ENOENT re-run vexp setup (it pins the absolute node path); on Copilot Business/Enterprise an admin must enable the "MCP servers in Copilot" policy |
| Hand-downloaded VSIX won't install / wrong platform | Check the file name ends in your platform (e.g. linux-x64) | Install from the marketplace so the editor picks the platform; for manual installs use the platform-specific .vsix from Open VSX |
Cross-distro issues
These apply whether you use the VS Code extension or the CLI.
| Symptom | Diagnose | Fix |
|---|---|---|
| Agent can't reach vexp | vexp daemon-cmd status | Re-run vexp setup, or run vexp doctor to diagnose daemon/MCP state |
| Port 7821 in use | vexp daemon-cmd status | Set vexp.mcpPort (VS Code) or VEXP_PORT (CLI) and re-run vexp setup |
| Daily limit reached (Starter) | Status bar shows "daily limit reached" | Wait until midnight UTC, or upgrade to Pro |
MCP entry runs the editor itself (Cursor.exe …mcp-server.cjs) — connection dies with MCP error -32000 | Open the agent's mcp.json: the command is the editor executable instead of node | Re-run vexp setup — it writes a real node and repairs the broken entry instead of adopting it |
vexp resolved the workspace to the home directory (agents that spawn MCP servers from ~, e.g. Antigravity) | vexp doctor shows resolves to: /home/<you> | Fixed (the ~/.vexp state dir no longer counts as a workspace); to pin a project for such an agent, set VEXP_WORKSPACE in a project-scoped MCP config |
| Codex never gets vexp’s per-prompt orientation | vexp doctor (Codex section: project trust and hook approval, per place on Windows) | Approve the hook once: Codex panel > Settings > Hooks > trust vexp-hint, or run codex in the project and type /hooks. On Windows approve it in each place you use Codex, and once more after updating from 3.2.5 |
| Daemon refuses to start / status bar shows vexp: workspace cap | vexp daemons | Free a slot with vexp stop <workspace>, then start the daemon again — concurrent-workspace ceilings are per plan (Starter 1, Pro 4, Team 8) |
| LLM "no backends are loaded" | vexp setup-llm --status | Run vexp setup-llm --status — its runtime library check names what is missing and prints the fix; if plugin files are missing, re-run vexp setup-llm --install (on NVIDIA machines it downloads the CUDA plugin and runtime) |
| LLM out of disk | du -sh ~/.local/share/vexp/models | vexp setup-llm --disable, then delete the models folder |
| GPU crash / LLM silently on CPU after a crash | vexp setup-llm --status (shows a 'GPU in use' verdict and the reason) | vexp writes ~/.vexp/gpu-unusable after a GPU crash and runs the model on CPU. Update the NVIDIA driver to ≥ 570.xx, then delete ~/.vexp/gpu-unusable to retry the GPU (upgrading vexp also retries automatically). If the crash happened while running the model, set flash_attention = "off" under [llm] in ~/.vexp/config.toml to keep the GPU. |
| LLM “Backends registered: 0” on minimal Linux images (Replit, distroless, trimmed containers) | vexp setup-llm --status | Fixed (libgomp.so.1 is bundled app-local); on older releases run apt-get install libgomp1 |
| Pro license shows as FREE / 2000 nodes in sandboxed env (Codex, containers) | Run vexp doctor (it reports license state under the resolved home, no daemon needed), or check .vexp/daemon.log for home_dir= — the daemon logs it at startup. (vexp index shows it only with VEXP_LOG_LEVEL=info.) | Set VEXP_HOME to the real user home in your MCP/agent config (e.g. VEXP_HOME=C:\Users\yourname) |
| Session cost explodes on long-context models (1M-token context windows) | Check the agent transcript: the context keeps growing past ~200k tokens with no compaction | On 1M-context sessions every turn re-bills the entire context as cache reads, so any loop that inflates turns multiplies cost. Use the vexp defaults (no strict deny guard), keep run_pipeline to one orientation call per task, and compact or restart the session when the context passes a few hundred thousand tokens |
| Not sure what's wrong / agent can't reach vexp | vexp doctor | Read-only check of workspace drift, stale daemons, Codex transport, and license (works without a running daemon). |
| Want logs | vexp daemon-cmd logs --follow | Or open .vexp/daemon.log directly |
| Want to send us a bug report | vexp doctor --report | Attach .vexp/vexp-report.md to your message (see below): doctor output, tool-call ledger, log warnings, config — secrets masked, paths visible |
.vexp/daemon.log and the index log .vexp/vexp.log are the next stop. .vexp/vexp.log is auto-truncated to its last 500 lines when it exceeds 2 MB; .vexp/daemon.log is rotated on every daemon start — the previous boot's log is kept as .vexp/daemon.log.1.Sending a bug report
vexp doctor --report writes .vexp/vexp-report.md: the doctor output as printed, the tool-call ledger of the last 30 days (per tool: calls, median, p95, max, how many ran past 30 s, how many ended with no result, and the ten slowest calls), the warnings and errors from the daemon log with repeats collapsed, and your vexp.toml. It never contains prompt text or file contents — parameters are reported by length only — and secret-shaped values are masked throughout. File paths are visible, so read it once, then send it to staff@vexp.dev or attach it to your issue. The ledger is read straight from the index database, so the report works with the daemon down. --report <file> picks another path.
The report is deliberately mechanical: numbers and log lines, nothing anyone has to second-guess. If you want your agent's observations next to it, paste this prompt into the same session and send the file it produces:
Uninstall
A complete removal has two parts: remove the distribution you installed, then (optionally) clean up what vexp wrote on disk. Nothing vexp writes is hidden or system-level, everything lives in your home directory and your project folders.
- Stop the daemon. Command Palette →
vexp: Stop Indexing, or use the stop button in the vexp sidebar panel. - Uninstall the extension. Extensions panel → gear icon on
vexp→ Uninstall, or from a terminal:The native engine is bundled inside the extension, so it is removed with it.bash$ code --uninstall-extension Vexp.vexp-vscode - Clean up leftovers. See the table below. If you also installed the npm CLI, follow the CLI tab as well.
Leftover data (optional cleanup)
These are safe to delete once vexp is removed. All of them are plain files and directories, no registry entries, no system services.
| What | Where | Notes |
|---|---|---|
| Per-project index | .vexp/ | In each project root: index database, logs, workspace.json. Delete the folder. |
| Global state | ~/.vexp/ | License files, device id, autostart marker and log, and your answers about which agents to set up (agent-consent.json). Deleting removes your local license copy - keep your key to re-activate later. |
| Local LLM models (~3.5 GB) | ~/.local/share/vexp/models (Linux) · ~/Library/Application Support/vexp/models (macOS) · %APPDATA%\vexp\models (Windows) | Only present if you installed the optional local LLM. |
| Agent config entries | .claude/CLAUDE.md, .cursor/rules/vexp.mdc, AGENTS.md, … | vexp sections are marker-delimited - delete the block between the vexp markers. Also remove the "vexp" server entry from MCP configs (~/.claude.json, .cursor/mcp.json, .vscode/mcp.json) and the vexp-guard PreToolUse hook from .claude/settings.json. |
If you skipped autostart uninstall
Removed the CLI before running vexp autostart uninstall? The login hook is a single per-user file, delete whichever exists:
| Platform | File |
|---|---|
| Linux (systemd) | ~/.config/systemd/user/vexp.service |
| Linux (XDG) | ~/.config/autostart/vexp.desktop |
| Linux (shell profile) | Block between # vexp-autostart-begin and # vexp-autostart-end in ~/.bashrc / ~/.zshrc / ~/.profile |
| macOS | ~/Library/LaunchAgents/io.vexp.serve.plist |
| Windows | vexp-serve.vbs in the Start Menu Startup folder (%APPDATA%\Microsoft\Windows\Start Menu\Programs\Startup) |
Privacy & Security
vexp is designed for codebases you can't send to the cloud. Everything runs on your machine.
- Local-only by default. Zero network calls for parsing, indexing, or querying. Outbound calls are limited to: (1) a once-a-day license check-in that sends only your license token, an anonymous device id and the vexp version — opt out with
VEXP_OFFLINE=1, which disables all license network calls (vexp keeps a 14-day grace period); (2) an advisory CLI update-availability check against the npm registry — cached 4 hours, never blocks a command, and skippable withVEXP_SKIP_UPDATE_CHECK=1or--skip-update-check; (3) the explicit, opt-in local-LLM model download when you runvexp setup-llm. Nothing else ever leaves your machine. - No code execution during indexing. vexp parses your code with tree-sitter; indexing and querying never execute it. The one exception is opt-in and explicit:
vexp verify --run-tests(ortests_gate = "run") runs your repo's own test suite, bounded, at your request. - Telemetry is opt-in. Telemetry is opt-in and off by default. The
vexp.telemetry.enabledsetting exists for future use; today vexp transmits nothing. - Distribution integrity. Binaries ship exclusively through npm (with registry integrity checksums) and the VS Code / OpenVSX marketplaces; there is no browser-download channel. macOS binaries carry the Apple toolchain's standard ad-hoc signature and are not Developer-ID notarised today: npm and marketplace installs are never quarantined, so Gatekeeper does not evaluate them. If your security policy requires notarised or countersigned artifacts, contact us about the enterprise distribution line.
- Secret filtering (default on). Files named like credentials are dropped at index time:
.env,.env.production,.env.local,id_rsa,*.pem,*.key,secrets.yaml,secret.md,password.json,credentials.toml, and similar filename-boundary matches. - Template files allowlisted.
.env.example,.env.sample,.env.template,.env.test,secrets.example.*, andsecrets.sample.*are not excluded, they document contracts, not secrets. - Filename boundary matching. Legitimate source files that just contain the word
secret,password, orcredentialin their name, e.g.src/secret-manager.ts, are not excluded. - Custom exclusions. Add patterns to
.vexpignore(gitignore syntax; the older.vexp_ignorename is also honored), or setexclude_patterns = ["generated/**", "vendor/**"]at the top level of.vexp/vexp.toml— repo-root-relative globs; a bare pattern likedist/**also matches at any depth. To disable the secret filter entirely, setfilter_secrets = falseat the top level of.vexp/vexp.toml.
Plans & Quotas
Quotas at a glance. For prices and the upgrade button, see the full pricing on the homepage.
| Plan | Nodes | Repos | Daily calls |
|---|---|---|---|
| Starter (Free) | 2,000 | 1 | 20 / day (resets midnight UTC) |
| Pro | 50,000 | 3 | 1,000 / day |
| Team | unlimited | unlimited | 1,500 / day per workspace |
| Lifetime Tier 1 | 10,000 | 1 | 500 / day |
| Lifetime Tier 2 | 50,000 | 3 | 1,000 / day |
| Lifetime Tier 3 | 100,000 | unlimited | 1,200 / day |
| Lifetime Tier 4 | unlimited | unlimited | 1,500 / day |
run_pipeline, get_context_capsule, and get_skeleton. Memory tools and index status never count, on any plan. Impact graphs and flow analysis are paid-plan features, not part of Starter. Ambient hints and the orientation seed are infrastructure and never count against the budget.What happens at the limits
- At 80 % of the node cap, the VS Code extension shows a warning (once per session, on any node-capped plan). CLI-only setups get no 80 % warning.
- At 100 % of the node cap, new nodes stop being added. Your existing index keeps working, no data loss. The VS Code notice and status-bar tooltip, the
index_statustool andvexp indexsay how many source files were left out and the estimated size of the whole project, the two numbers you need to sizeexclude_patternsor pick a plan. The tooltip andindex_statusdrop it once the index fits under the cap again. - At 20 daily calls, the next call to a quota-affected tool returns a limit-reached error and the daemon shuts down. This stops every vexp tool, not just the quota-affected ones, until the quota resets at midnight UTC. Nothing is lost: your index and session memories are kept on disk and are there when it comes back (or upgrade to Pro/Team, whose ceilings interactive use never reaches).
License activation
Run vexp: Activate License Key from the Command Palette and paste your key, or click the magic link in the activation email, vexp activates without any further input.
Daily check-in
Once a day, vexp checks in with vexp.dev from every setup: VS Code, the CLI, or an AI agent running vexp on its own. The check-in sends your license token, an anonymous device id (a random string stored in ~/.vexp/device.id) and the vexp version, nothing else. It registers the machine against your plan's device limit and keeps your license current. Set VEXP_OFFLINE=1 to turn it off; nothing then renews your license key either, so a paid plan lasts until the key's own expiry (30 days after its last renewal) and returns at the next check-in.
Offline use
vexp refreshes your license quietly in the background whenever you're online. If you stay offline, you keep working at your current plan for at least 14 days; after that vexp falls back to your license key itself, which keeps the paid plan until its own expiry date. Only when that also lapses does vexp drop to Starter — no data loss, and your plan returns automatically the next time you're online.
Account portal
Manage your subscription, devices, and team at vexp.dev/account (magic-link login). Team owners can add or remove members; each member logs in independently.
Device limit
Each license covers a limited number of devices: Pro 4, Team 4 per seat, Lifetime Tier 1 and Tier 2 one, Tier 3 five, Tier 4 ten. A machine counts from its first check-in, right away when you activate your key and otherwise within a day. Each environment with its own home folder counts as a device of its own: WSL next to Windows, or a dev container. On a lifetime license, a machine over the cap runs at Starter limits until you free a slot at vexp.dev/account/devices — your key stays valid, and the plan returns automatically on that machine once a slot is free. A slot is freed only when you remove a device there.