NIM CodeAI coding assistant for VS Code — NVIDIA NIM, OpenAI, Anthropic Claude, Google Gemini, Groq, and Sarvam AI in one panel. Chat, explain, refactor, and fix code with state-of-the-art models. Switch between Nemotron, GPT-5, Claude Opus, Gemini 2.5, Groq-hosted GPT-OSS, Sarvam 105B, and more without leaving your editor — each provider uses its own API key, stored securely in your OS keychain. No API key? Start instantly with Auto mode — a free agent (tools + file edits) with automatic multi-provider failover, 5 requests per day, no sign-up required. Sign in (optional) for 25. In one line
Key points🔓 Free to start — no API key, no sign-up, no credit card. Auto mode runs the real agent loop — file edits and terminal included, on a lean 17-tool roster that fits the free gateway's limits — through a built-in gateway that fails over across providers automatically. 5 agent runs per day (25 if you sign in — entirely optional), resetting at midnight UTC. A run is one thing you ask for, however many steps it takes to do it. Install and be working in under a minute. 🔌 Offline coding agent — your machine, your model. Point 🔒 Private coding agent — nothing goes anywhere you didn't pick. Your code, prompts, and responses go to one place only: the provider of the model you selected. With a local endpoint, that means your code never leaves your machine. The webview UI runs under a strict Content Security Policy and makes zero network requests of its own, and all agent file access is scoped to your workspace root. 🔑 Keys live in your OS keychain — never on disk. Each provider's key goes into VS Code SecretStorage (Keychain / Credential Manager / libsecret). Never written to 🧠 Bring any model — six providers, or your own. NVIDIA NIM (default), OpenAI, Anthropic Claude, Google Gemini, Groq, and Sarvam AI — each with its own key, and only the selected model's key is ever required. Add your own model ids from the UI with no extension update. Reasoning-effort control (Low / Medium / High) on models that support it. ⚡ A real agent, not a chat box. Built-in tools: read/write/edit files, ripgrep + natural-language semantic search, terminal with background shells, diagnostics, code review, and scoped sub-agent delegation. Up to 6 independent read-only calls run concurrently; anything that mutates runs strictly one at a time, in order. ⚡ One button runs the whole engineering loop. Autonomous Engineering Mode takes a goal and a dollar budget and runs a fixed pipeline: survey the repository, plan, implement, run your build/lint/tests, fix what they catch and re-run them, review the diff for security and for correctness (in parallel), then offer to commit. The order is enforced by NIM Code rather than requested from the model, so the security review cannot be quietly skipped. The budget is checked before each stage, not billed after it — a mission that runs out stops and tells you what it did not do. One approval up front, a restore point before anything changes, and a live card you can stop. 🛡️ You approve what it changes. Four approval modes. Every write shows a real VS Code diff before it lands. 🔁 Runs in the background, and queues up work. Agents keep working while you keep coding — a status-bar counter tracks live runs and you get a toast on completion. Stack up a task queue to run jobs sequentially, each honoring the current mode, model, and approval settings. 🧩 Extend it without forking it. MCP servers (stdio) merge their tools straight into the agent's roster. Lifecycle hooks ( 📌 It remembers — across turns, sessions, and teammates. Three distinct layers: a read-only 💰 Costs are visible, not a surprise. Per-message token usage and dollar estimate, a live context-budget bar, and prompt caching to cut the cost of repeated large-context calls. 📊 Telemetry is anonymous unless you choose to sign in — opt out with one setting. Signed out, it carries only VS Code's anonymized machine id, the extension version, the VS Code version, and your OS. Signed in, events link to your account id so credits follow you across machines — but never your email, code, prompts, responses, file paths, project names, model ids, or keys. Disable with How it works
Everything runs in the extension host on your machine. There is no NIM Code server in the path — except the optional free Auto-mode gateway, which you can bypass entirely by using your own key or a local model. FeaturesAuto mode — free agent tier, no key neededStart immediately without an API key. Auto mode runs the full agent loop — real file edits and terminal access, not just chat — through a built-in OpenAI-compatible routing gateway. The gateway key's server-side model routing fails over across providers automatically (e.g. Groq → NVIDIA → Google), so the free tier stays available even when one backend is busy or down. It carries a deliberately reduced tool roster (17 of the 37, and no MCP tools): the free gateway has a tight per-minute token limit, and a smaller roster keeps each request small enough to land on the capable primary model instead of failing over to a weaker fallback. Full Agent mode gets every tool. Reading, editing, searching, the terminal, git status and diff, deleting and renaming, problem diagnostics, and Planner Mode are all included. Notably it also gets Auto does still get a short workspace overview (a trimmed file tree, tighter than the one full Agent mode receives). It used to get none at all, on the theory that every saved token helped — but with no idea what the workspace contained, the agent opened each turn with a
Four modes: two free, two on your own keyThe mode picker in the composer toolbar groups the four modes by who pays for the request — the free tiers first, since a fresh install can use those immediately:
The two Online modes need no API key and no setup — install the extension and send a message. The two Local modes use the key for the selected model's provider (or a local endpoint such as Ollama or LM Studio, which needs no key at all). The two free allowances are separate: running out of Online Chat leaves Online Agent's untouched, and vice versa. Chat gets the larger number because it is far cheaper to serve — a chat message is one model call, whereas an agent turn runs the tool loop for up to 30, resending the whole conversation each step. Signing in (optional)NIM Code works fully without an account, and always will. Signing in does exactly one thing: it raises the Online Agent allowance from 5 requests a day to 25. Nothing else changes — no feature is gated behind it, Online Chat's 20 messages are unaffected, and the Local modes never touch the hosted gateway at all.
Sign-in is Google-only. One button, one consent screen, no provider chooser — the extension asks for Google and nothing else. Run NIM Code: Sign In from the command palette, or press Continue with Google in the account strip directly above the composer. It opens The account UI is two places, and they never both apply. Signed out on one of the two free tiers, the strip above the composer states the offer in real numbers, and restates it as an out-of-requests notice once you actually run out — the one moment signing in is worth something. On the Local (own-key) modes it is not shown at all, since an account changes nothing there. Signed in, that strip disappears entirely and your avatar appears at the right of the panel header; its menu holds your name, your email and Sign out. NIM Code: Sign Out does the same thing. Your credential is stored in the OS keychain alongside your provider API keys — never in settings, never in a file, and never sent to the webview. What is stored on our side is your email address, which provider you signed in with, and your daily credit count. We never receive your password. Without a signed-in account the daily counter lives only on your machine, which is why the signed-in allowance is the enforceable one — the server can count what a browser-side counter cannot. Inviting people (optional)Signed-in users get an invite link, in three places:
Invite in the account menu opens the fuller panel, which is also where you redeem a code
somebody gave you. The whole surface is behind When someone joins through your link, both of you get 5 bonus credits — a one-time top-up, not a permanent increase.
Bonus credits are a second currency, deliberately separate from the daily allowance:
That last point is the design: a permanent daily increase is a subscription given away for free that can never be withdrawn, so invites pay in one-time credits instead. It also means there is no cap on how many people you can invite. An invite only counts once the person you invited has genuinely used the product — a verified email, at least 5 Auto requests, across two separate days. Signing up alone earns nothing, which is what keeps the programme from being farmed. Chat modes stream a reply and nothing else — no file edits, no terminal. For those, use an Agent mode. Multi-provider, multi-model chatPick any model from the dropdown, grouped by provider: NVIDIA NIM (default), OpenAI (GPT-4 and GPT-5 families), Anthropic (Claude), Google (Gemini), and Groq (GPT-OSS 120B; add Agent modeLet NIM Code act autonomously on your workspace. It reads, searches, writes, and refactors files; runs terminal commands; queries git; runs code reviews; tracks its own progress; and opens files directly in your editor. Built-in agent tools:
Smarter tool useThree behaviors that make Agent mode work the way Claude Code / Cursor-class agents do:
Self-Test Until FixedMost coding agents stop when they finish writing. NIM Code stops when the code works. When an agent turn has changed files, it can't just end. Before the turn closes, NIM Code runs the project's own checks and shows you a live card:
Anything red goes straight back to the agent with the failing output, it fixes it, and the checks run again — until they pass or the budget runs out. Either way the transcript ends with a plain statement of what happened, so you never have to guess whether "done" meant "working". It works with no configuration. Checks are detected from the project itself — Six things it deliberately does not do, each of which is how this kind of feature usually goes wrong:
The agent can also call Tune it with Symbol-aware readingReading a whole file to find one function is the most common way an agent wastes context — a 1,200-line file costs thousands of tokens, and the answer was thirty lines of it. NIM Code uses the language servers VS Code already has running (no extra parser, nothing added to the extension's size) to offer cheaper alternatives:
Each degrades gracefully: with no language extension installed for a file type, the tools say so and point at Sub-agent delegationFor large or exploratory tasks, the agent can spin off a scoped sub-agent via the Right-click code actionsSelect any code, then right-click (or press MCP (Model Context Protocol) supportConnect your own local MCP servers (stdio transport) via Tools are sent only to the turns that need them. MCP tool definitions are the one part of the roster NIM Code doesn't author — their descriptions and schemas come straight from your server — so connecting a few servers used to add their full cost to every request, on every step of a loop. Now the turn is matched against your server and tool names: naming a server pulls in its entire toolset (you usually need to list before you create), an unnamed server can still be reached through an individual tool's own name or description, and a turn that matches nothing sends no MCP tools at all. Routing is skipped entirely when your whole MCP roster is small enough that narrowing it wouldn't pay. If the agent ever needs something it can't see, Every MCP server carries a trust level (
The default is deliberately the restrictive one. Set Lifecycle hooksRun your own shell commands around Agent-mode events via
Each event holds matcher groups: Tool-call approval & Plan modeChoose how much confirmation Agent mode needs before acting — Manual, Edit automatically, Auto, or Plan (read-only investigation with no file/shell access) — via the approval-mode dropdown next to the model picker. File writes show a VS Code diff editor to review before applying. Your edits win while a confirmation is open. A pending approval can sit there as long as you like, so the agent re-checks the file the instant you approve and refuses to write if it moved in the meantime — you saved it, switched branches, or another background run touched it. It also catches an unsaved buffer you started typing into, which never reaches disk for a timestamp check to see. Nothing is written, and the agent is told to re-read the file and redo the edit against your version. The gate covers MCP tools too, not just the built-ins: a connected server's tools are confirmed or blocked according to its Planner Mode (plan → approve → execute)In Plan mode the agent investigates read-only, then publishes a structured plan (a titled, numbered list of steps) as a review card instead of diving straight into edits — the understand → analyze → plan → show → execute flow. Review the steps and click Approve & execute to let the agent carry them out (it switches to Edit-automatically and proceeds), or Dismiss to refine your request and have it re-plan. The plan is produced by the agent's Repo intelligence (it knows your project — without asking an AI)Most of what an assistant needs to know about your repository is not a matter of opinion. Where a stack frame points is arithmetic. What imports a file is a graph. What changed there last week is one NIM Code builds a deterministic index of all of it, and answers from that instead of guessing — no model call, no tokens, no waiting. Its sharpest use is failures. When something breaks, you usually get a stack trace and a shrug. Here, the error is resolved before the agent even sees it:
When a failure isn't recognised, nothing is invented. You get the evidence — line, symbol, diagnostics, recent commits, dependents — clearly labelled as evidence, and the model reasons from it instead of spending six searches rediscovering it. That last part is where the speed comes from. The agent used to answer "why did this fail?" with a round of It knows more than errors. Ask the agent anything about the shape of the project:
Co-change deserves a callout, because nothing else can tell you: two files that change together in 80% of commits are coupled even if neither imports the other. That's the fact that catches the half-finished change — the schema you updated whose handler you forgot. Every agent turn also carries a small Where you'll see it:
Every source degrades on its own: no git history, no semantic index, or no language server each cost one section of an answer, never the answer. Switch it off with Code DNA — it learns how your project is writtenRepo intelligence above answers what is in your repository. This answers the question a generated file actually gets wrong: how does your team write code here. A model that knows your stack will still hand you a default-exported class component in a codebase of named-export function components, put a test in NIM Code reads your repository once and writes down what it found:
The model never sees that page. It gets the compressed digest, appended to the
That's the whole idea: derive it once from your code, spend a few dozen tokens a turn stating the conclusions, and stop paying for the agent to rediscover your project in every new conversation. It says nothing rather than guessing. A convention is only ever asserted when enough files voted and they overwhelmingly agree — the counts beside each line are exactly that vote, and they're shown so you can check them. A codebase that genuinely mixes both styles produces no line at all, because telling the agent "no default exports" in a repo that has fifty of them is worse than telling it nothing: it will start "fixing" the ones it meets. Framework-mandated files are excluded from the vote for the same reason — a Next.js It's a file you can correct, and it stays out of your project. The result lives in NIM Code's own storage, keyed by workspace folder — nothing is written into your tree, so it never shows up in It relearns when your manifests or your file set change, and at most weekly otherwise. To force it after a refactor that changed how the code is written without adding a dependency, run Switch it off with Agent teams (parallel specialists)
Ask for something substantial — "add OAuth login" — and the agent can field a team instead of doing it all in one context. The architect explores once, and everyone else gets its notes. This is the point of the feature rather than a detail. Sub-agents each start with a blank slate, so a naive team rediscovers your codebase once per member — the same searching, billed four times. Here only the architect explores; its brief names the exact files, symbols and patterns to use, and the coder and tester start from that. They read, they don't hunt. Only the parts that genuinely can be parallel are. A coder can't implement a design that doesn't exist yet, so it waits for the architect. The coder and tester genuinely can work at once — the tester writes against the interface the brief describes — so they do, and the card shows both running. You approve the file scope once, not every write. Before anything starts you get a single prompt naming exactly which files each member may touch (Coder — You can watch it happen. A live card shows every member, its status, its file scope, and what it's doing right now. You get the thinking, not just the diff. The design brief and the review are published as artifacts, so you can read them properly. Your agent gets a short summary back rather than four transcripts, which keeps the conversation cheap. Nothing here is unattended. A checkpoint is taken before the team runs, so the whole thing is one undo. Your project's real build/lint/test commands run afterwards through Self-Test Until Fixed, and anything newly broken comes back to be fixed. Roles are elastic — a refactor may need no tester, a small change no architect — and the agent picks only what the goal warrants. Tests are opt-in: a tester joins only when you actually ask for tests. It is the most expensive thing the agent can do, so it is reserved for substantial work: it never appears on the free Auto tier, and it stays out of the agent's toolkit entirely on ordinary turns. Switch it off with Autonomous Engineering Mode (one button, whole pipeline)Everything above is one capability at a time: you ask, the agent works, you read the reply. Autonomous Engineering Mode is the whole loop — you type a goal, set a budget, and press one button.
Behind it:
The order is enforced by NIM Code, not requested from the model. This is the whole point. Ask an agent to "build it, test it, then review it for security" and it reliably does the first, usually the second, and forgets the third once its context is full of build output. Here the pipeline is a loop in the extension: every stage you ticked either runs or says on the card why it didn't. Nothing is quietly skipped. It explores once. The Understand stage is the only one that surveys your repository, and its brief is handed to every stage after it — so the coder, the security reviewer and the reviewer read rather than re-hunt. Without that, eight fresh contexts rediscover the same codebase eight times. The budget is a limit, not a receipt. Set Model: Auto routes per stage. Each stage gets the cheapest model that can actually do its job — a repository survey doesn't need your most expensive model, and a security review does. It only ever picks from providers you have keys for, and picking a specific model instead turns routing off entirely and uses that one throughout. Either way the card shows which model each stage actually ran on, because a routing promise you can't audit isn't worth much. With no keys at all, the whole mission runs on the free Auto tier. You approve once, up front. A single prompt names the stages, the budget, the file scope, whether the terminal runs, and whether your project's test commands will be executed. Inside that scope the mission works without interrupting you — which is the point of a feature that runs for minutes unattended. Committing asks a second time, with the real commit message and the real file list, because consent to "a mission that may commit" isn't consent to a specific commit. Decline and the changes simply stay in your working tree. A restore point is taken before anything changes, so the entire mission is one undo from the Checkpoints panel. You can watch it, and stop it. A live card shows every stage, its status, its model, what it's doing right now, and a spend meter that fills as the budget is consumed. Stop is on the card itself. The context brief, the plan, the security report and the review are published as artifacts so you can read them properly, and a summary lands in the transcript. Stages are à la carte. Untick Implement and it becomes an audit — the later stages read whatever is already uncommitted in your working tree. Untick everything but Security and you get a focused security pass over your current diff. (Fix errors needs Run tests: without it there is no failure to act on, and the launcher says so before you start.) Open it from the ⚡ button in the chat header or Artifacts (rendered deliverables)Sometimes what you want back isn't a change to your code — it's a thing: an architecture diagram, a chart of some numbers, a one-page design doc, a working HTML prototype. Pasting that into a chat transcript flattens it into text, and writing it into your repository with Artifacts are the third option. The document is published as a card in the chat, rendered — a real diagram, a real chart, real formatted prose. Click Open and it expands into a full panel beside your editor.
Switch it off with GPU-aware local models — what your machine can actually runPoint In the model picker, every local model carries a badge — Fits, Tight, Spills or CPU — with its real size beside the context window ( In the composer, the endpoint chip becomes live VRAM headroom — Before a model crawls, a one-line notice appears above the composer: " Two things make the verdicts trustworthy rather than decorative:
The KV cache is computed from the model's real layer, head and embedding dimensions when the server can supply them (Ollama's Servers understood natively: Ollama (sizes, quantisation, architecture, live residency), LM Studio ( With no NVIDIA GPU nothing is invented: NIM Code says it could not find one, names your CPU and system RAM, and sizes models against RAM instead — "expect single-digit tokens per second". A server that reports VRAM residency anyway (Apple Silicon, AMD, Intel Arc) is still believed, because it knows where it put the bytes and Probing is gated three ways — the feature is on, the endpoint is local, and the chat panel is visible — and stops entirely after repeated failure, so a background window never spends a process every five seconds. On the NVIDIA cloud endpoint nothing is spawned at all. Turn the whole thing off with Background agentsDispatch an agent task and keep working — it runs asynchronously while you switch chat sessions, start other tasks, or code in the editor. Multiple runs can be in flight at once, each tied to its own session.
Checkpoints & undoAn agent run can edit a dozen files and run a build before you get a chance to read what it did. Checkpoints give you a way back: NIM Code snapshots the workspace before the agent's first change of a turn, and again after every step that changed something.
Task queue (run tasks sequentially)Background agents run concurrently; the Task queue is the opposite tool — line up several tasks and run them one at a time, each starting only once the previous one finishes. Useful when tasks build on each other (refactor → update call sites → update tests) and running them at once would have them fighting over the same files.
Live agent task listFor multi-step tasks, the agent maintains a visible todo checklist (via the Reasoning effort controlFor reasoning-capable models, pick Low, Medium, or High effort from the dropdown next to the model picker to trade off response speed against depth of reasoning. Semantic codebase searchRun NIM Code: Index Codebase for Semantic Search from the Command Palette to build a local embedding index of your workspace (via Retrieval is hybrid: an embedding search and a literal-identifier search run together and their rankings are fused, because embeddings are good at "where do we handle rate limiting" and bad at "where is The same command also maps your project's import graph, which backs the MemoryAgent mode automatically loads three sources of memory into its system prompt on every turn:
Image attachments (vision)Paste a screenshot directly into the chat input to attach it to your message — handy for sharing UI bugs, error dialogs, or design mockups. Up to 4 images per message. In Auto and Online Chat the hosted gateway picks the model, and it routes an image-carrying request to a vision-capable one — so screenshots work without choosing a model yourself. In local Chat and Agent modes the request goes to the model you picked, so that model needs the Inline completion (ghost text)Suggestions appear inline as you type, in any language. Press It is off by default, and that is deliberate — completion sends a request on nearly every keystroke, so switching it on silently would spend your provider credits on a feature you did not ask for. Enable it with NIM Code: Toggle Inline Completion or
|
| Mention | Attaches |
|---|---|
@path/to/file.ts |
The file's contents (capped at 8k characters) |
@src/features/ |
That folder's listing |
@SymbolName |
The symbol's definition, found via your language server, with its file and line |
@diff |
Your current uncommitted changes |
@problems |
Everything in the Problems panel |
Mentions are parsed from your message, not tracked as you click, so pasting or typing @src/auth.ts by hand works exactly like picking it from the menu. Anything you attach this way takes precedence over automatic retrieval — a mentioned file is attached in full, and the auto-context block skips it rather than spending its budget echoing a fragment of the same file back. Mentioned paths get the same workspace containment as every agent file tool, so @../../.ssh/id_rsa is refused rather than read.
Auto-attached editor selection
Whatever text you have highlighted in the active editor shows up as a chip above the chat input automatically — no need to click an attach button. The chip tracks your selection live (it updates as you select something else, and clears when you deselect); click the close button on the chip to detach it for the next message. It's sent as fenced, file/line-labeled context alongside whatever you type.
Slash commands
Type / in the chat input to trigger context-aware prompts using your active editor selection. (Unlike @-mentions, which work anywhere in a message, / only applies at the start — it selects a mode for the whole turn.)
| Command | Alias | Description |
|---|---|---|
/explain |
Explain what the selected code does | |
/fix |
Find and fix bugs in the selection | |
/review |
Code-review the selection for quality and correctness | |
/refactor |
/ref |
Restructure code for readability and maintainability |
/optimize |
/opt |
Improve performance and reduce complexity |
/test |
Generate unit tests for the selection | |
/document |
/doc |
Write JSDoc / docstring comments for the selection |
/debug |
Diagnose an error or stack trace | |
/summary |
Summarize what a file or directory does | |
/security |
Review code for security vulnerabilities | |
/migrate |
Migrate code to a new version or framework |
Skills (reusable prompt packages)
Beyond the fixed built-in slash commands, you can define your own skills — reusable, shareable prompt packages stored as Markdown files. Each skill is a .md file with optional frontmatter and a prompt body:
---
name: refactor-react
description: Idiomatic React refactor
version: 1.0.0
---
You are a React expert. Refactor the following code to be idiomatic and
accessible, preserving behavior. Explain each change briefly.
{{selection}}
{{input}}
- Where they live:
<workspace>/.nimcode/skills/*.md(git-committed, shared with your team), a machine-global user directory (personal, cross-workspace), and a set that ships with NIM Code. A workspace skill overrides a user skill, which overrides a built-in one of the same name. - Invoke them: type
/in the chat — skills appear in the autocomplete alongside built-in commands, tagged skill. Pick one (e.g./refactor-react) and the skill's prompt is applied to that turn, in whatever mode (Chat/Agent) you're in. - Placeholders:
{{selection}}is replaced with your attached editor selection and{{input}}with whatever you type after the trigger. A skill with no placeholders simply has your input appended. - Live reload: adding, editing, or deleting a skill file refreshes the
/picker immediately (no reload needed). - Install shared skills: run NIM Code: Install Skill from URL and paste a raw
.mdURL to drop a teammate's or community skill into.nimcode/skills/.
Skills that load themselves
A convention only helps if it's applied, and the turns that most need one are the turns nobody thinks to type /nextjs on. So NIM Code detects what the project is built with and loads the matching skills itself:
Next.js · React · TypeScript · Prisma · Vitest detected
✓ nextjs ✓ prisma ← loaded in full
testing security ← listed; loaded on demand
A skill opts in with one line of frontmatter:
---
name: nextjs
description: Next.js App Router conventions
when: nextjs, react
---
- What's detected: the stack and languages NIM Code already derives for the
## This projectcontext block — frameworks (Next.js, React, Vue, Svelte, Angular, Express, NestJS…), tooling (Prisma, Tailwind, Zod, Vitest, Jest, Playwright, Vite), the package manager, and every language above a 5% share of your source files. Tags come in pairs, sowhen: frontendmatches any of the UI frameworks without naming them all. - What ships:
nextjs,react,typescript,prisma,testing,securityandfrontend. Drop a same-named file in.nimcode/skills/to replace one with your team's version — it wins outright, so what you read in the file is what the agent gets. - What it costs: the highest-scoring few skills go into the prompt in full under a hard budget; the rest are listed by name and pulled in with the
load_skilltool only when the task turns out to need one. A skill that isn't relevant to the turn costs about fifteen tokens, not five hundred — which matters because the agent loop resends its prefix on every one of its steps. - Relevance beats detection. Naming a skill or its technology in your message ("add a Prisma migration") promotes it ahead of everything merely detected, and activates a skill like
securitythat has no dependency to detect in the first place. - You can see it. A line above the conversation names the detected stack and which skills were loaded versus merely offered — an influence on the answer that you can't see is one you can't correct.
- Opting out: a skill with no
when:is manual-only, exactly as before. Turn the whole mechanism off withnimcode.skills.autoLoad. Detection reuses Repo Intelligence, sonimcode.repoIntel.enabledoff also stops automatic activation (/namestill works).
Streaming responses
Responses stream token-by-token so you see output immediately, with full cancel support mid-stream.
Code blocks that match your editor
Snippets in the chat are syntax-highlighted with your actual VS Code theme, not a generic one — so a Python function reads the same in the chat panel as it does in the editor beside it. Dark+/Light+, Monokai, Dracula, Nord, One Dark Pro, Solarized, GitHub, Material, Catppuccin, Tokyo Night and others are matched directly; a theme with no exact match falls back to VS Code's own Dark+/Light+ rather than something unrelated. Switching themes re-colors the chat live, with no reload.
32 languages are highlighted, including diff, and grammars load on demand so the first snippet isn't waiting on languages you never use. A webview can't read the editor's token colors directly (VS Code exposes UI colors as CSS variables but not per-scope syntax colors), so the theme is matched by name and shipped with the extension.
Copy code blocks
Every code block in the chat output has a Copy button always visible in the header bar. Click it to copy the code to your clipboard in one click, or use Insert (appears on hover) to paste it directly at the cursor.
Mermaid diagram rendering
Fenced ```mermaid code blocks render as inline diagrams (flowcharts, sequence diagrams, class diagrams, etc.) instead of plain code — handy for architecture or sequence explanations. A Copy button on the diagram header copies the raw diagram source. Falls back to the raw text while a diagram is still streaming in or if it fails to parse.
Request-scoped context
Every Agent request used to carry the same maximal prompt: the full tool roster, a workspace overview, and all three memory layers, whether or not the turn had anything to do with your code. Since the agent loop resends that prefix on every step — up to 30 per turn — an irrelevant block isn't paid for once, it's paid for repeatedly.
NIM Code now decides per turn. "Explain async/await" gets the system prompt and a read/search core, and nothing about your workspace. "Refactor the auth module across these twelve files" gets everything, fitted to a token budget in priority order: what you attached with @ first, then your selection, then retrieved code, then memory, then general orientation. Anything that doesn't fit is dropped with a stated reason rather than silently shrinking everything.
Run NIM Code: Explain Last Request Context to see exactly what was included, what was dropped and why, and how the estimate compared to what the provider billed. Toggle with nimcode.context.planner; cap the prefix explicitly with nimcode.context.maxPrefixTokens.
File relevance: only the code the request is about
Deciding which blocks a turn can afford still left one question open — which files. Retrieval answered it with a handful of snippets and nothing else did, so a turn about login.ts might carry three unrelated fragments and no sense of what sits around it.
NIM Code now ranks every file in the workspace against each Agent request, fusing the signals it already has: what you attached with @, your editor selection, paths you typed in the message, what the semantic index retrieved, which files declare the identifiers you named, what imports (or is imported by) those files, and what has historically been committed alongside them. The result is three tiers:
- High — included as outlines: every signature with its line number, roughly a tenth the size of the file. Enough for the agent to jump straight to
read_filewith a line range instead of pulling a whole module to find one function. - Medium — listed by name with a one-line reason, no content. About ten tokens a file, and it replaces the
list_files/search_codebaseround-trip the agent would otherwise spend a whole prompt on to learn the same thing. - Excluded — not sent, but counted, so you can see the size of what was skipped.
A line above the conversation reports the outcome — Context: 4 files · 6,240 tok · 88% saved — and expands to the full breakdown with the reason each file was picked. Every assistant message keeps its own copy, so scrolling back through a conversation shows what each answer actually saw. The settings dashboard's Context & retrieval section shows the last request's selection under the switches that govern it.
About that percentage. It compares what was sent against what was considered and rejected — files the scorer ranked out, plus context blocks the budget refused — not against your whole repository, which would produce a flattering number that says nothing about the decision. Pricing the rejected files needs the semantic index, so without one (NIM Code: Index Codebase) the ranking still works and the savings figure is shown as unmeasured rather than estimated.
Costs nothing extra per turn: no model call, and no second embedding call — the semantic signal reuses the retrieval the turn already ran. Toggle with nimcode.context.relevance. It is skipped automatically for conversational turns (there is no code to rank) and on the free Auto tier, whose tighter budget is better spent on orientation.
It remembers what it already looked at
A turn is rebuilt from the conversation, and tool results never survived it — so the agent used to reopen every turn by rediscovering the workspace. Ask it to create a file, then ask it to fill that file in, and it would re-list the directory and re-read the file it had just written one turn earlier, before doing any actual work.
NIM Code now keeps a per-workspace record of what it has already established — directories it listed, files it read, files it wrote — and carries it into later turns and later sessions, so a new chat in the same folder starts oriented instead of exploring from scratch. It records what was established, never file contents, which is what makes it safe to keep: a stale claim about a file is detectable, a stale copy of the file is not.
Every entry is stamped with the file's size and modification time and re-checked before it's used. Anything that changed — by the agent's own edit, your edit in the editor, a branch switch, a teammate's commit — is dropped from the list, so the agent re-reads exactly what actually moved and trusts the rest. The record is machine-local (kept in the extension's own storage, not in your repo), so nothing appears in git status.
Context budget report
Run NIM Code: Explain Last Request Context to see exactly what the last Agent turn sent: every context block (system prompt, tool definitions, memory, @-mentions, retrieved code, conversation history, accumulated tool results) with its token cost and share of the request, which blocks were dropped and why, and how the estimate compared with the token count the provider actually billed. A multi-step turn shows each step, so you can see the transcript growing across the loop.
Token budget indicator
The composer's status line reports how much of the model's context window the conversation is using — Context 49k/200k — taken from the prompt tokens the last response actually consumed, so it reflects the history really sent rather than an estimate of the next request. It appears only once a response has reported usage. Past 60% a thin bar joins it (amber, turning red past 80%), because below that threshold the number alone is enough and a bar is just decoration.
Per-message token usage & cost
Each assistant turn's footer shows the tokens that turn consumed, and — for models with published metered pricing (OpenAI, Anthropic, Google, Groq, Sarvam AI) — an estimated USD cost at list prices (e.g. 1,240 tok · $0.0083). Cached prompt tokens are billed at each provider's discounted cache-read rate, so the cost reflects prompt caching. Models without published pricing (the NIM free tier, self-hosted / local endpoints, unknown custom ids) show the token count only, with no dollar figure.
Prompt caching
Repeated large-context calls — the same system prompt, project memory, and tool roster resent on every step of the Agent loop — reuse a cached prefix instead of being reprocessed from scratch, cutting cost and latency. NIM Code marks the stable prefix (system prompt + the latest turn) with a cache_control breakpoint for Anthropic (Claude) models; OpenAI caches automatically with no marker needed. When a response is served partly from cache, the message footer shows (N cached) next to its token count. Toggle with nimcode.promptCaching (default on). Providers without prompt-cache support are unaffected.
Within-turn context pruning
Auto-compaction (below) bounds a long conversation. This bounds a long turn. During an agent run the model's transcript grows with every tool result and the whole thing is resent on each step — so a file read at step 2 is still being paid for at step 25. Once a turn's transcript grows past its budget, older results that can simply be fetched again are replaced with a one-line receipt (read_file(src/auth.ts) → 412 lines, 8.2k chars; call it again if you still need the detail), and an earlier read of a file that was later re-read is marked superseded.
The three most recent results are always kept verbatim, and results of anything that changed something — writes, edits, deletes, terminal commands, MCP calls — are never elided at any age, because unlike a read they cannot be reproduced. Toggle with nimcode.context.pruneToolResults.
Auto-compaction of long conversations
Once a session's history exceeds the recent-turns window (20 by default), older turns are no longer silently dropped — they're folded into a rolling summary (via a small extra model call) and kept in context alongside the most recent turns verbatim. The summary is cached and only re-generated as further turns push past it, so long-running sessions keep continuity without an unbounded context cost.
Secure API key storage
Every provider's API key (NVIDIA NIM, OpenAI, Anthropic, Google, Groq, Sarvam AI) is stored in the OS keychain via VS Code SecretStorage — never in settings files or workspace storage.
Persistent sessions
All conversations are saved locally and accessible from the session list (the Conversations button). Rename, delete, or switch between sessions at any time. Saves are atomic and retried if the file is momentarily locked (a sync client, antivirus); if saving genuinely fails, NIM Code says so rather than quietly dropping your history.
Support the project
The yellow ☕ Coffee pill next to the NIM Code title in the chat header opens buymeacoffee.com/vijayj in your browser. It's a plain link — entirely optional, nothing is sent from the extension when you click it, and no part of NIM Code is gated behind it.
Feedback & suggestions
The red Report a bug button in the settings dashboard header opens a short form. Only the message is required — name and email are optional, so a report can be completely anonymous, and they're never prefilled or remembered between submissions. If you do enter an email it is checked for a valid address when you leave the field, so a typo doesn't cost you the reply. Nothing else is attached: no code, prompts, conversation history, file paths, workspace or model information. The report is sent from the extension host (the webview has no network access) to https://ai-gateway-beta.vercel.app/api/v1/feedback — or the standby host, if that one cannot be reached — and the dialog tells you whether it went through.
Report a failed request
When a request fails, the red Request failed card in the transcript — and the error banner above the composer — gain a Report error button. One click sends it; there's no dialog and nothing to fill in. The button then reads Reported. If the send itself fails it says so and offers a retry.
It contains diagnostics only — never any part of your conversation. What goes in it:
- the error message the provider returned, its error code, and the HTTP status
- which surface failed (chat, agent, or the panel banner)
- the model, provider and mode, and how long the request ran before failing
- opaque session and stream ids
- VS Code's anonymized install id, the NIM Code and VS Code versions, and your OS
What does not go in it: your prompt, the model's output (even the partial output already on screen), tool names, file paths, and workspace or repository names. The wire format rejects unknown fields outright, so those cannot be added by accident. Reports are sent from the extension host (the webview has no network access) to https://ai-gateway-beta.vercel.app/api/v1/bug-reports, or the standby host if that one cannot be reached.
Quick Start
Prefer an interactive walkthrough? Run NIM Code: Getting Started from the Command Palette — it covers the same steps below inside VS Code itself. The chat panel's empty state offers the same Take the guided tour link whenever the panel is tall enough to show it.
Option A — No API key (Auto mode)
- Install NIM Code from the VS Code Marketplace.
- Click the N icon in the Secondary Side Bar — the right-hand panel, toggled with
Ctrl+Alt+B(or pressCtrl+Shift+N). - The mode picker in the composer toolbar defaults to Online Agent — start typing and press Enter to send.
Online Agent gets 5 free requests per day (25 if you sign in) and Online Chat gets 20, counted separately. The composer's status line shows how many remain for the mode you are in; once they're used up the composer is disabled until the quota resets at midnight UTC. The Local modes have no cap — they run on your own key.
Option B — Full access (Chat & Agent modes)
1. Get an API key from the provider you want to use
| Provider | Where to get a key | Key prefix |
|---|---|---|
| NVIDIA NIM (default) | build.nvidia.com → API Keys → Generate Personal Key | nvapi- |
| OpenAI | platform.openai.com → API keys | sk- |
| Anthropic | console.anthropic.com → API keys | sk-ant- |
| Google (Gemini) | aistudio.google.com → Get API key | AIza |
| Groq | console.groq.com → API Keys | gsk_ |
| Sarvam AI | dashboard.sarvam.ai → API Keys | sk_ |
You only need a key for the provider(s) whose models you actually pick.
2. Install NIM Code
Search "NIM Code" in the Extensions panel (Ctrl+Shift+X) or install from the VS Code Marketplace.
3. Set your API key
Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and run:
NIM Code: Set API Key
Pick the provider, then paste the key when prompted. The key is validated against the provider before it's saved. Repeat for any other providers you want to use.
4. Start chatting
Click the N icon in the Secondary Side Bar (the right-hand panel), or press Ctrl+Shift+N / Cmd+Shift+N.
Modes
| Mode | Icon | API key | Model | Tools | Best for |
|---|---|---|---|---|---|
| Auto | sparkles | Not required | Free routing gateway with auto-failover (always) | All tools (+ MCP) | Free agentic tasks, 5/day |
| Chat | speech bubble | Selected model's provider | Any model (NIM, OpenAI, Anthropic, Google, Groq, Sarvam AI) | Chat only | Q&A, explanations, code review |
| Agent | lightning bolt | Selected model's provider | Any model (NIM, OpenAI, Anthropic, Google, Groq, Sarvam AI) | All tools (+ MCP) | Multi-step tasks, file edits |
Switch modes with the mode picker in the composer toolbar. Each entry carries a one-line summary of what that mode can do plus a badge showing what it has left — 5/5 for a free tier (25/25 signed in), turning red at 0/5, and ∞ for the own-key modes — so both the capability and the remaining quota are visible while you choose rather than after.
Agent Mode
Set the composer's mode picker to Local Agent (or Online Agent to run on the free tier). NIM Code will plan and execute multi-step tasks autonomously, showing each tool call as it runs.
Example prompts:
- "Search for all
TODOcomments in.tsfiles and fix them one by one" - "Run
pnpm run lint, find the errors withget_diagnostics, and fix them all" - "Read
src/api/users.ts, add Zod input validation, and open the file when done" - "List all
.test.tsfiles, find untested functions withsearch_codebase, and write the missing tests"
Tip: Use Chat mode for questions and explanations. Use Agent for tasks that require reading or changing files.
Tool-call approval modes
The Mode dropdown next to the model picker (visible in Agent mode) controls how much confirmation the agent needs before acting:
| Mode | File edits (write/rename) | Deletes & terminal commands |
|---|---|---|
| Manual | Asks for approval | Asks for approval |
| Edit automatically | Applies immediately | Asks for approval |
| Auto | Applies immediately | Asks for approval |
| Plan | Blocked — read-only | Blocked — read-only |
When a confirmation is required, NIM Code opens a VS Code diff editor (for file writes) or a prompt describing the action, with Accept/Reject buttons — reject and the agent reports it and adjusts its approach. Plan mode never touches the filesystem or shell; the agent investigates and proposes a plan as text instead.
Supported Models
NIM Code ships with curated models from six providers, grouped in the picker. Add any other model via the Add custom model button, the settings dashboard's Models & modes section (which can also edit an existing entry), or Settings → NIM Code → customModels — no extension update needed.
Set the context window when you add a model. The Add-model flow asks for it, and it is worth getting right: it sizes how much of a file one read returns and how long a turn keeps what it read. A model added without one is assumed to hold 32,768 tokens, so a large-context model left undeclared quietly gets a small model's budgets — the picker flags this as "assumes 32k context" on any custom model that never declared one.
Note: the curated OpenAI, Anthropic, and Groq models are currently hidden from the model picker. Their providers still work — add the model id you want via Add custom model (choose OpenAI, Anthropic, or Groq as the provider) and it appears in the picker as usual. Sessions already using one of those ids keep running against the right provider.
NVIDIA NIM (default provider)
| Model | ID | Context | Best for |
|---|---|---|---|
| Llama 3.1 8B (Auto mode) | Built-in proxy | 128K | Free tier — no key needed |
| Nemotron Super 120B (default) | nvidia/nemotron-3-super-120b-a12b |
1M | NVIDIA-tuned reasoning and code |
| Llama 3.2 11B Vision | meta/llama-3.2-11b-vision-instruct |
131K | Understands pasted screenshots and images |
OpenAI (hidden from the picker — add via customModels)
| Model | ID | Context | Best for |
|---|---|---|---|
| GPT-5 | gpt-5 |
400K | Flagship reasoning |
| GPT-5 mini | gpt-5-mini |
400K | Fast, cost-efficient reasoning |
| GPT-4.1 | gpt-4.1 |
1M | Strong coding, huge context |
| GPT-4.1 mini | gpt-4.1-mini |
1M | Balanced speed and capability |
| GPT-4o | gpt-4o |
128K | Multimodal general-purpose |
| GPT-4o mini | gpt-4o-mini |
128K | Low latency, low cost |
Anthropic (hidden from the picker — add via customModels)
| Model | ID | Context | Best for |
|---|---|---|---|
| Claude Opus 4.8 | claude-opus-4-8 |
1M | Most capable — long-horizon agentic work |
| Claude Sonnet 5 | claude-sonnet-5 |
1M | Near-Opus coding quality at Sonnet cost |
| Model | ID | Context | Best for |
|---|---|---|---|
| Gemini 2.5 Pro | gemini-2.5-pro |
1M | Strong reasoning, huge context |
| Gemini 2.5 Flash | gemini-2.5-flash |
1M | Fast, cost-efficient multimodal |
Groq (hidden from the picker — add via customModels)
| Model | ID | Context | Best for |
|---|---|---|---|
| GPT-OSS 120B | openai/gpt-oss-120b |
128K | Open-weight reasoning |
Sarvam AI
| Model | ID | Context | Best for |
|---|---|---|---|
| Sarvam 105B | sarvam-105b |
128K | Flagship Indian-language reasoning and agentic work |
Sarvam enables reasoning by default and charges its reasoning tokens against max_tokens, so NIM Code sends reasoning_effort: null unless you pick a reasoning effort — and caps output at 4096 tokens, the ceiling on Sarvam's Starter plan. On a Pro or Business plan you can raise it per-model via nimcode.customModels.
Sarvam 30B is not available through Sarvam's API. It was retired — it appears in neither
GET /v1/modelsnorGET /v2/models, and requesting it returns a 400. Its open weights are still published under Apache 2.0, so you can run it yourself behind an OpenAI-compatible server (Ollama, vLLM, LM Studio) and reach it as a NIM-provider custom model vianimcode.baseUrl. Sarvam also hostssarvam-105b-conversations(chat-tuned) on/v1and open-weightglm5.2/gemma4on/v2— add any of them via Add custom model with providersarvam, settingnimcode.sarvamBaseUrltohttps://api.sarvam.ai/v2for the/v2ones.
Popular NIM models to add via customModels:
| Model ID | Context | Best for |
|---|---|---|
meta/llama-3.3-70b-instruct |
128K | Latest Llama, strong coding |
qwen/qwen2.5-coder-32b-instruct |
32K | Code generation |
deepseek-ai/deepseek-r1 |
64K | Step-by-step reasoning |
nvidia/llama-3.1-nemotron-70b-instruct |
128K | NVIDIA-tuned Nemotron 70B |
mistralai/mistral-large-2-instruct |
128K | Multilingual, strong tool use |
Notes: The Auto free tier and semantic codebase indexing (embeddings) always use the NIM provider, regardless of the picked chat model.
nimcode.temperatureis ignored for models that reject it (Anthropic's current Claude models; OpenAI's GPT-5/o-series reasoning models).
Commands & Keyboard Shortcuts
| Command | Shortcut (Win/Linux) | Shortcut (Mac) | Description |
|---|---|---|---|
NIM Code: Open Chat |
Ctrl+Shift+N |
Cmd+Shift+N |
Open or focus the NIM Code chat panel |
NIM Code: New Chat Session |
Ctrl+Shift+L |
Cmd+Shift+L |
Start a fresh conversation |
NIM Code: Set API Key |
— | — | Pick a provider (NVIDIA NIM, OpenAI, Anthropic, Google, Groq, Sarvam AI) and save its key securely |
NIM Code: Clear API Key |
— | — | Pick a provider and remove its stored key |
NIM Code: Sign In |
— | — | Optional — raises the Online Agent allowance from 5/day to 25/day. Opens accounts.google.com; nothing else is shown |
NIM Code: Sign Out |
— | — | Clear the stored session and return to the 5/day allowance |
NIM Code: Index Codebase for Semantic Search |
— | — | Build the local embedding index for search_codebase_semantic |
NIM Code: Rebuild Project DNA |
— | — | Relearn this project's conventions and rewrite the cached project profile |
NIM Code: Verify Workspace |
— | — | Run the project's build/lint/test checks now and show the result on the verification card |
NIM Code: Explain Last Request Context |
— | — | Show what the last Agent turn's prompt was made of, block by block, with estimated vs. billed tokens |
NIM Code: Install Skill from URL |
— | — | Fetch a skill .md from a URL into .nimcode/skills/ |
NIM Code: Restore Checkpoint... |
— | — | Rewind the workspace (and optionally the conversation) to an earlier snapshot |
NIM Code: Compare with Checkpoint... |
— | — | Diff the workspace against an earlier snapshot |
NIM Code: Clear Checkpoints |
— | — | Delete every recorded restore point for this workspace |
NIM Code: Toggle Inline Completion |
— | — | Turn ghost-text completion on or off (off by default) |
| Explain / Fix / Review / Refactor / Generate Tests / Document | — (right-click or Ctrl+.) |
— | Run a slash command on the current editor selection |
| Send message | Enter |
Enter |
Send the typed message |
| New line in message | Shift+Enter |
Shift+Enter |
Insert a line break without sending |
| Browse history | ↑ / ↓ |
↑ / ↓ |
Navigate previously sent messages |
All commands are also accessible via the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) — search "NIM Code". NIM Code: Open Settings Dashboard opens the visual settings editor described under Configuration.
Configuration
Settings dashboard
Click the gear in the composer, run NIM Code: Open Settings Dashboard, or use the gear in the chat view's title bar. It opens as an editor tab laid out like an admin console: a persistent section rail down the left — Overview, Providers & keys, Models & modes, Request tuning, Context & retrieval, Verification, Inline completion, Checkpoints, Agents & automation, Memory/skills/artifacts, MCP servers, Hooks, Privacy & safety — and a content column beside it.
It opens on an Overview: how many providers have a key, how many settings you have changed (with a one-click reset), how many MCP servers are active, whether verification is on, plus your active mode and models, your invite link, and a button to rebuild the codebase index. Each tile links into the section that would change it.
Sections are colour-coded into three families, and the same colour follows a section from the rail to its tile to its heading: green for the AI itself (models, request tuning, inline completion, agents), blue for your own material (providers and keys, context, memory, checkpoints), and amber for anything that reaches out of the editor or limits what can (verification, MCP servers, hooks, privacy). Colour is never the only signal — every tile states its status in words as well.
Everything the extension can be configured with is in the sections, plus the things VS Code's own settings editor cannot do:
- Provider rows pair each base URL with whether a key is stored for it, a link to that provider's console, and a note where a loopback endpoint needs no key at all. Setting a key still opens VS Code's native password prompt — the key never enters the web page.
- Structured editors for the settings that are otherwise hand-written JSON: custom models (with an actionable warning when one has no declared context window), MCP servers (with an inline enable switch and a trust selector), verification checks, and lifecycle hooks — whose matcher field evaluates your regex live against the real tool roster and tells you which tools it matches before you save it.
- Search across labels, setting ids, descriptions and enum options;
/orCtrl/Cmd+Ffocuses it. - Go to setting (
Ctrl/Cmd+K) jumps straight to any setting by name or id, from anywhere on the page — it reveals the row first if the Advanced toggle, the current search or the Changed filter was hiding it. - Changed in the header narrows the page to just the settings that differ from their defaults — the fastest answer to "what did I actually change?". The Overview's Changed tile is the same view.
- Per-setting scope, so any setting can be written to your User settings or overridden for this workspace. A coloured bar down the left edge of each row shows which layer a value came from, and a workspace override names the user value it is shadowing. The four machine-scoped settings (
mcpServers,hooks,verification.checks,gpu.smiPath) are User-only and say why. - Advanced settings are collapsed behind a toggle, but are still matched by search.
- Sliders on the settings with a small fixed range — retries, temperature, fix rounds, completion debounce and token budget — sitting beside the number field rather than replacing it, so an exact value can still be typed or pasted.
- Human number entry on durations, sizes and token counts: type
15m,1m30s,2gbor200kand the field converts it. An entry it cannot read keeps your text and says so rather than storing a guess. - Row actions (the
⋯button on any row) copy a setting's id or its"id": valueJSON for a bug report, open VS Code's own settings editor filtered to that one setting, and move the value between User and Workspace from the keyboard.
Three tools live on the page alongside the settings that govern them, rather than in the chat sidebar:
- Project memory sits in the Memory section — the entry list for
.nimcode/memory.md, with inline edit, TODO checkboxes and a manual add row. It belongs here because memory is a property of the workspace, so it reads the same whichever conversation is open. - Checkpoints sits in the Checkpoints section. Restore points are taken per conversation, so it opens on a conversation picker (defaulting to the most recent) and lists that conversation's timeline with Compare, Restore and Clear all. The inline transcript markers still work where they always did.
- Report a bug is the red button in the header.
Changes apply immediately, as they do in VS Code's own settings editor — there is no Save button. Reset on any row (or per section) clears it back to the default.
Moving a configuration between machines
Export in the Overview's Maintenance card writes the settings you have changed to a JSON file; Import reads one back and shows you exactly what it would change — old value → new value, per setting — before anything is written.
Two things are deliberate about it. API keys are never exported: keys live in your OS keychain rather than in settings, so there is nothing in the file to leak, and MCP servers are left out by default because their env blocks hold plaintext values. And the settings that run commands on your machine — hooks, verification.checks and mcpServers — are grouped separately in the preview and arrive unchecked, so importing a profile someone sent you never silently gains the ability to run shell commands.
VS Code's built-in settings editor still works for everything, and the dashboard header links to settings.json directly.
Editing settings.json directly
Open Settings (Ctrl+,) and search "NIM Code", or edit settings.json:
{
// Base URL for the NIM provider's OpenAI-compatible API — change for
// on-premise deployments or local servers (Ollama, LM Studio, vLLM, …)
"nimcode.baseUrl": "https://integrate.api.nvidia.com/v1",
// Per-provider base URL overrides. openaiBaseUrl / groqBaseUrl / sarvamBaseUrl
// are handy for OpenAI-compatible gateways; leave anthropicBaseUrl /
// googleBaseUrl empty to use each provider SDK's default endpoint.
"nimcode.openaiBaseUrl": "https://api.openai.com/v1",
"nimcode.anthropicBaseUrl": "",
"nimcode.googleBaseUrl": "",
"nimcode.groqBaseUrl": "https://api.groq.com/openai/v1",
"nimcode.sarvamBaseUrl": "https://api.sarvam.ai/v1",
// Mode the chat panel starts in when it is first opened ("auto" | "chat" | "agent").
// Switching modes mid-session is not persisted — a fresh panel starts here again.
"nimcode.defaultChatMode": "auto",
// Fallback default model, overridden by defaultChatModel / defaultAgentModel
"nimcode.defaultModel": "nvidia/nemotron-3-super-120b-a12b",
// Model selected automatically when Chat mode is active
"nimcode.defaultChatModel": "nvidia/nemotron-3-super-120b-a12b",
// Model selected automatically when Agent mode is active — use a strong tool-use model
"nimcode.defaultAgentModel": "nvidia/nemotron-3-super-120b-a12b",
// ── Local GPU awareness ──
// Read this machine's GPU (nvidia-smi) and the local model server's catalog,
// so the picker can say which models fit in VRAM. Off = no probing at all.
"nimcode.gpu.enabled": true,
// Absolute path to nvidia-smi. Machine-scoped, because NIM Code runs it.
// Empty = search PATH, %SystemRoot%\System32, C:\Program Files\NVIDIA
// Corporation\NVSMI, /usr/bin, /usr/local/bin and /usr/lib/wsl/lib.
// Any program printing nvidia-smi CSV will do — a path ending in .js is run
// with the bundled Node, which is how the GPU path can be exercised on a
// machine with no NVIDIA card (see scripts/fake-nvidia-smi.js).
"nimcode.gpu.smiPath": "",
// VRAM held back for the desktop when judging fit, in MiB. Your browser and
// compositor hold VRAM a model cannot have, and that grows during a session.
"nimcode.gpu.vramReserveMb": 1024,
// Context length assumed when sizing a model's KV cache. NOT the model's
// advertised maximum: Ollama serves num_ctx 4096 by default regardless, so
// sizing a 128k model against 128k would call a model that runs fine a spill.
"nimcode.gpu.assumedContextTokens": 8192,
// Idle timeout in milliseconds *between* streamed chunks (default: 120 000 = 2 min).
// Resets on every token, so it caps mid-stream silence, not total length.
"nimcode.requestTimeoutMs": 120000,
// How long to wait for the *first* token (default: 300 000 = 5 min). Covers
// connection, upload and the model's prefill, which grows with prompt size —
// so long agent turns need more headroom here than between chunks.
"nimcode.firstTokenTimeoutMs": 300000,
// Automatic retry attempts on transient errors (0–5)
"nimcode.maxRetries": 3,
// Max time in milliseconds run_terminal lets a shell command run before
// killing it (default: 900 000 = 15 min). Set to 0 for no timeout — the
// command then only stops on exit or user cancellation. A "still running"
// heartbeat is posted to the chat every 15s while a command is in flight.
// Verification checks use nimcode.verification.timeoutMs instead.
"nimcode.terminalTimeoutMs": 900000,
// Sampling temperature — lower = more deterministic (0–2). Ignored for
// models that reject it (Anthropic Claude; OpenAI GPT-5/o-series).
"nimcode.temperature": 0.2,
// In Agent mode, auto-include the active file (path + cursor snippet) as
// context when no explicit selection is attached (default: true)
"nimcode.agentIncludeActiveFile": true,
// Embedding model used to build the local semantic codebase index
// ("NIM Code: Index Codebase" command) and the search_codebase_semantic tool
"nimcode.embeddingModel": "nvidia/nv-embedqa-e5-v5",
// After the agent writes/edits a file, auto-collect its errors/warnings from
// language servers and feed them back to the model (default: true)
"nimcode.autoDiagnostics": true,
// Self-Test Until Fixed. After an agent turn changes files, run the project's
// own checks (diagnostics on the changed files, then build/type-check, lint,
// tests) before the turn may end, and send anything NEWLY red back to be
// fixed. A turn that changed nothing is never verified.
"nimcode.verification.enabled": true,
// Explicit checks, replacing auto-detection. Machine-scoped: these run from
// the verification gate, so a cloned repo's .vscode/settings.json must not be
// able to define them. Empty = detect from the project.
"nimcode.verification.checks": [
// { "kind": "build", "command": "pnpm run typecheck" },
// { "kind": "test", "command": "pytest -q", "cwd": "services/api" }
],
// Fix rounds allowed per turn before the run stops and reports what is still
// red. 0 = report without ever enforcing. The loop also stops early when a
// round reproduces the identical failure.
"nimcode.verification.maxFixRounds": 3,
// Per-check timeout. Shorter than terminalTimeoutMs on purpose, because these
// run automatically. 0 is not accepted. A timeout is inconclusive, never a
// fix round.
"nimcode.verification.timeoutMs": 300000,
// Include the test suite. Off = diagnostics, build and lint only.
"nimcode.verification.runTests": true,
// Auto-retrieve the most relevant indexed code snippets as context for each
// Agent request; requires "NIM Code: Index Codebase" (default: true)
"nimcode.autoContext": true,
// Choose context blocks by what the turn is asking for, within a token budget,
// instead of including every available block every time. (default: true)
"nimcode.context.planner": true,
"nimcode.context.relevance": true,
// Hard cap in tokens on an Agent request's fixed prefix (system prompt, memory,
// retrieved code, workspace context). 0 = derive it from the model's window.
"nimcode.context.maxPrefixTokens": 0,
// Send only the tools a turn plausibly needs rather than the whole roster
// (~7,500 input tokens, resent on every step of a loop that can run 30 of
// them). The agent can call load_tools to widen its own roster. (default: true)
"nimcode.context.dynamicTools": true,
// Within one agent turn, replace stale tool results with a one-line receipt
// instead of resending them verbatim every step. Writes, deletes and terminal
// results are never elided; the 3 most recent are always kept. (default: true)
"nimcode.context.pruneToolResults": true,
// Inline (ghost-text) completion as you type. OFF by default: it sends a request
// on nearly every keystroke and always uses your own provider key (never the free
// Auto tier). Toggle with "NIM Code: Toggle Inline Completion".
"nimcode.completion.enabled": false,
// Empty = use defaultChatModel. Pick the fastest, cheapest model you have.
"nimcode.completion.model": "",
// Pause after your last keystroke before requesting (0–2000 ms)
"nimcode.completion.debounceMs": 250,
// Maximum length of one suggestion (16–512 tokens)
"nimcode.completion.maxTokens": 128,
// Language ids to complete in; ["*"] means all
"nimcode.completion.languages": ["*"],
// Allow suggestions spanning several lines
"nimcode.completion.multiline": true,
// Cache the stable prompt prefix (system prompt, project memory, tools) to cut
// cost/latency on repeated calls. Adds a cache_control breakpoint for Anthropic;
// OpenAI caches automatically regardless. Cached tokens show as "(N cached)". (default: true)
"nimcode.promptCaching": true,
// One anonymous heartbeat per active day (machine id, extension version,
// VS Code version, OS — never code, prompts, paths, or keys) so we can count
// active users. VS Code's own telemetry.telemetryLevel always wins. (default: true)
"nimcode.telemetry.enabled": true,
// Build a deterministic index of your repository — structure, import graph,
// commit history, source maps — and answer from it instead of guessing. When a
// command fails, the error is resolved to the exact source line (through
// bundled output), its cause and its fix, with no AI call at all, and handed
// to the agent attached to the failure. (default: true)
"nimcode.repoIntel.enabled": true,
// Code DNA: learn this project's own conventions from its own source — the
// stack, and the house style it is actually written in (named vs. default
// exports, function vs. class components, path aliases vs. relative imports,
// where tests live). Cached in NIM Code's storage, never in your project,
// and correctable via its "pinnedRules"; only a compressed
// PROJECT_RULES: digest reaches the model. (default: true)
"nimcode.projectDna.enabled": true,
// Autonomous Engineering Mode: one button that runs a whole pipeline against
// a goal you type — survey, plan, implement, run your build/lint/tests, fix
// what they catch, review for security and correctness, offer to commit. The
// order is enforced by NIM Code, not requested from the model. Off hides the
// launcher. (default: true)
"nimcode.missions.enabled": true,
// What the mission launcher's Budget field starts at, in US dollars. Spend is
// metered across every model call a mission makes and checked BEFORE each
// stage, so a mission that runs out stops and says what it did not do.
// (default: 0.25)
"nimcode.missions.defaultBudgetUsd": 0.25,
// Hard token limit for one mission. Not a duplicate of the dollar budget: a
// mission on a local model or the free tier has no published price, so its
// dollar meter never moves and could never stop it. This is what bounds those
// runs. (default: 2000000)
"nimcode.missions.tokenCeiling": 2000000,
// Let the agent field a team of specialist sub-agents for substantial work:
// an architect explores once and writes a design brief, then a coder (and
// optionally a tester) work from it in parallel in separate file scopes, then
// a reviewer checks the result. You approve the file scopes once, up front.
// Off removes the tool entirely, so it costs no tokens. (default: true)
"nimcode.agentTeams.enabled": true,
// Let the agent publish artifacts — diagrams, charts, documents and standalone
// pages you see rendered beside the conversation. They live in NIM Code's own
// storage, never your repository. Off removes the tool from the roster
// entirely, so it costs no tokens; existing artifacts still render.
// (default: true)
"nimcode.artifacts.enabled": true,
// Open the artifact panel automatically whenever one is published. Off by
// default — a panel taking editor focus mid-turn interrupts whatever you were
// reading, and every card has an Open button. (default: false)
"nimcode.artifacts.autoOpenPanel": false,
// Snapshot the workspace around every Agent step that may change files, so a
// run can be rewound from the dashboard's Checkpoints section. Snapshots live in a private
// repository inside NIM Code's storage — your .git is never touched, and a
// folder that isn't a git repo gets checkpoints too. (default: true)
"nimcode.checkpoints.enabled": true,
// Extra gitignore-style patterns to leave out of checkpoints, on top of your
// own .gitignore and a built-in list (node_modules/, dist/, build/, .venv/…).
// Excluded files are never rewound by a restore.
"nimcode.checkpoints.exclude": [],
// Restore points kept per conversation. Older rows drop off the timeline;
// use "NIM Code: Clear Checkpoints" to reclaim the disk. (default: 50)
"nimcode.checkpoints.maxPerSession": 50,
// Above this many trackable files, checkpoints switch themselves off rather
// than walking the whole tree on every Agent step. (default: 20000)
"nimcode.checkpoints.maxFiles": 20000,
// When the checkpoint store for a workspace grows past this size, NIM Code
// offers to delete it at startup. Nothing is deleted without asking. (default: 1024)
"nimcode.checkpoints.maxStorageMb": 1024,
// Per-workspace, team-shared project memory (.nimcode/memory.md):
// the project_memory tool, the dashboard's Memory section, and prompt injection (default: true)
"nimcode.projectMemory.enabled": true,
// Auto-distill durable decisions/TODOs into .nimcode/memory.md when a long
// session is compacted. Off by default — it writes a git-committed file.
"nimcode.projectMemory.autoCapture": false,
// Additional models shown in the picker. "provider" selects which API
// serves the model: "nim" (default — the endpoint at nimcode.baseUrl),
// "openai", "anthropic", "google", "groq", or "sarvam".
//
// Set "contextWindow" to the model's real limit. It is not cosmetic: it
// sizes how much of a file one read returns and how long a turn keeps what
// it read. Omitted, a model is assumed to hold 32,768 tokens — so a
// large-context model left undeclared gets a small model's budgets and will
// re-read the same file instead of holding it.
"nimcode.customModels": [
{
"id": "meta/llama-3.3-70b-instruct",
"label": "Llama 3.3 70B",
"contextWindow": 128000,
"capabilities": ["chat", "tools"]
},
{
"id": "gpt-4o-2024-11-20",
"label": "GPT-4o (pinned)",
"provider": "openai",
"contextWindow": 128000,
"capabilities": ["chat", "tools", "vision"]
}
],
// Shell commands run around Agent-mode events (machine-scoped).
// Exit code 2 = blocking; the hook's stderr is sent back to the model.
"nimcode.hooks": {
// Block edits to lock files; guard is a script that exits 2 to deny.
"PreToolUse": [
{
"matcher": "write_file|edit_file|delete_file",
"hooks": [{ "type": "command", "command": "node scripts/guard-edit.js" }]
}
],
// Auto-format every file the agent writes.
"PostToolUse": [
{
"matcher": "write_file|edit_file",
"hooks": [{ "type": "command", "command": "prettier --write \"$NIMCODE_PROJECT_DIR\"", "timeout": 30 }]
}
],
// Don't let the agent stop until the type-checker is clean.
"Stop": [
{
"hooks": [{ "type": "command", "command": "pnpm run typecheck 1>&2 || exit 2" }]
}
]
}
}
Each hook command receives the event payload as JSON on stdin and these environment variables: NIMCODE_HOOK_EVENT (PreToolUse / PostToolUse / Stop), NIMCODE_TOOL_NAME (the tool being called), and NIMCODE_PROJECT_DIR (the workspace root, also the command's working directory). Exit 0 for success, exit 2 to block (stderr is forwarded to the model); any other non-zero exit is logged but does not affect the run.
On-premise / self-hosted NIM
"nimcode.baseUrl": "http://localhost:8000/v1"
Everything else — API key, model IDs, streaming, tool use — works identically against a local NIM deployment.
Moving the Panel
NIM Code opens in the Secondary Side Bar — the right-hand panel, like GitHub Copilot Chat — which you can show or hide with Ctrl+Alt+B / Cmd+Alt+B. To move it somewhere else:
- Right-click the N icon in the Secondary Side Bar
- Pick another location (e.g. Move to Primary Side Bar to dock it on the left), or just drag the icon where you want it
VS Code remembers this permanently.
Privacy & Security
| Concern | How NIM Code handles it |
|---|---|
| API keys | Each provider's key (NVIDIA NIM, OpenAI, Anthropic, Google, Groq, Sarvam AI) is stored in the OS keychain (VS Code SecretStorage). Never written to disk or settings files. |
| Auto mode key | Baked into the extension bundle at build time (from the build environment, never committed to source). Routed only through the NIM Code gateway, which fails over across providers — your traffic is not logged or stored. |
| Chat data | Sent only to the selected model's provider: integrate.api.nvidia.com (or your custom baseUrl), api.openai.com, api.anthropic.com, generativelanguage.googleapis.com, api.groq.com, or api.sarvam.ai. Never sent anywhere else — in particular, never included in telemetry. |
| Telemetry | Usage analytics — modes, models, token counts, errors. Anonymous unless you sign in, in which case events link to your account id (never your email). Never your code, prompts, paths or keys. A one-time notice on first use points at the switch. VS Code's own telemetry.telemetryLevel always wins. See Telemetry below — turn down with nimcode.telemetry.detail, off with nimcode.telemetry.enabled. |
| Account | Only if you sign in: your email address and sign-in provider are stored by the gateway to attach your daily credits to an account. Never sent to our analytics providers. Sign out to stop, or ask us to delete it. |
| Feedback form | Sent only when you fill it in and press Send. Contains exactly what you typed — the message, plus a name and email only if you chose to enter them. Nothing is prefilled, stored, or attached automatically. |
| Error reports | Sent only when you press Report error on a failed request. Diagnostics only: the provider's error text and code, the HTTP status, the model/provider/mode, how long the request ran, opaque session and stream ids, the anonymized install id, the extension and VS Code versions, and your OS. Never your prompt, the model's output, tool names, file paths, or workspace names. |
| Webview | Runs under a strict Content Security Policy — no external network requests from the UI layer, and the script nonce is drawn from a cryptographic RNG. |
| Workspace Trust | NIM Code stays disabled in Restricted Mode. It edits files, runs terminal commands, and launches MCP servers and nimcode.hooks shell commands, none of which is safe against a repository you have not vetted — so opening an untrusted folder gets you no agent until you trust it. |
| Agent file access | All file operations are scoped to your VS Code workspace root. Every path the agent supplies is checked before use: absolute paths, UNC paths and .. traversal that would climb above the root are refused, and the agent is told why. (This is lexical containment — it does not follow a symlink that already lives inside your workspace but points outside it.) |
| MCP tool calls | Gated by each server's trust level — see MCP support. The default confirms every call and blocks them entirely in Plan mode. |
Telemetry
NIM Code sends usage analytics so we can see how it is actually used — which modes and models people reach for, what they cost in tokens, and where things fail.
If you are signed out — the default, and a fully supported way to use NIM Code — everything is identified only by VS Code's own anonymized machine id (vscode.env.machineId), which is not tied to you, your account, or your email.
If you sign in, events are linked to your account id instead, so your usage and daily credits follow you across machines. We also record which sign-in provider you used and whether you are on the free or paid plan. Your email address is never sent to our analytics providers — it is held only by the gateway that issues your credits. Signing out returns events to being anonymous.
What is never sent, by construction. Your code, prompts, model responses, reasoning, tool arguments or results, diffs, terminal output, file or workspace paths, repository or branch names, MCP server names, skill names, custom model ids, raw session ids, API keys, your email address, or your referral code. Every outgoing property is produced by one typed builder (src/extension/services/analytics/events.ts) with tests asserting the exact key set of each event — a property that isn't declared there cannot be sent.
Country is derived by our analytics provider from the network connection. We never send your IP address, and it is discarded once the country is derived.
The events
| Event | How often | What it carries |
|---|---|---|
extension_active |
Once per install per day | NIM Code / VS Code / OS versions, time zone, UI language, whether you have your own API key and for which providers, endpoint kind (nim-cloud / local / custom — never the URL), default model, whether you are signed in and with which provider, your plan, and counts of MCP servers, custom models and skills |
turn_completed |
Once per message you send | Mode (Online Agent / Local Chat / Local Agent), model, provider, success or error code, duration, agent steps, which built-in tools ran (every MCP tool is reported as just mcp), token counts, estimated cost, and the length of your message |
llm_usage |
Batched, ~every 30 min | Input and output tokens per model, per provider, per surface, per feature, and per endpoint kind (local / nim-cloud / custom / vendor — a kind, never the URL) — including background work like history compaction that no per-message event covers |
feature_used |
First use of a feature each day | Which feature, nothing else |
daily_summary |
Once per day | Turn, tool, error and completion counts |
auth_signed_in / auth_signed_out / auth_failed |
When you sign in or out | Which provider, whether it was your first sign-in, days since install; on failure, which stage and an error code (never a message) |
credits_exhausted |
When a daily allowance runs out | Which tier, whether you were signed in, the limit |
referral_redeemed / referral_link_copied |
On those actions | How many credits were granted, how many people have joined — never the code itself |
A custom model id is reported as the literal custom, never the id itself. Token counts the provider did not report are estimated and flagged as such, so an approximation is never presented as a measurement. The endpoint kind on llm_usage is what distinguishes tokens spent on a model running on your own machine from tokens spent on a hosted one — it is derived from nimcode.baseUrl, and the URL itself is never sent.
One more signal, outside the table above: an anonymous uninstall ping (just the machine id — nothing else) sent when you uninstall the extension. It's best-effort, since VS Code runs it as a bare process right before deleting the extension, and it honors the same nimcode.telemetry.enabled toggle as everything else — turning telemetry off stops it too, immediately, not just on your next uninstall.
Turning it down or off
Send only aggregates — you keep every token, model and country metric, and drop the per-message event:
"nimcode.telemetry.detail": "aggregate"
Send nothing at all:
"nimcode.telemetry.enabled": false
or set VS Code's global telemetry.telemetryLevel to "off" — that always takes precedence, so if you have VS Code telemetry disabled, NIM Code sends nothing regardless of its own setting. Turning telemetry off also discards anything already buffered, so events queued before you opted out are never sent afterwards.
Analytics are batched, sent fire-and-forget from the extension host, and can never delay or fail a chat.
Troubleshooting
"Set your … API key" banner
This banner appears in Chat or Agent mode when the selected model's provider has no key saved — e.g. picking a Claude model without an Anthropic key. Click Set Key (or run NIM Code: Set API Key and pick the provider), or switch to Auto mode to start chatting immediately with no key.
401 / authentication errors on one provider only
Keys are per-provider. Run NIM Code: Set API Key, pick the failing provider, and re-enter its key — the error message names which provider rejected the request.
Auto mode daily limit reached
The counter resets at midnight UTC; until then the composer is disabled. Press Continue with Google in the strip above the composer (or run NIM Code: Sign In) to raise the allowance from 5/day to 25/day, or switch to Chat mode with your own NVIDIA NIM API key for unlimited usage.
Slow or no response with large models (Nemotron Super 120B)
Increase nimcode.firstTokenTimeoutMs in Settings — large models can take several minutes to produce their first token on complex prompts. Use nimcode.requestTimeoutMs instead if a response starts fine but dies part-way through.
A long agent turn times out with "no response after Ns"
The request that stalled is usually just large: the agent loop re-sends the whole transcript on every step, so the later steps of a long turn carry the most. The error names the step and its approximate input size; run NIM Code: Explain Last Request Context to see what filled it. The step is retried once automatically before the turn gives up. Raise nimcode.firstTokenTimeoutMs, or start a new session to shed transcript.
The agent repeats the same paragraph over and over
A turn that repeats itself now stops with "the model kept repeating the same tool call without making progress" instead of burning its whole step budget. The usual trigger is a tool that keeps failing — the agent loses a way to look things up, starts working from memory, and goes in circles. If you saw this alongside "The search tool failed", that was search_codebase being unable to find the ripgrep VS Code ships; it now falls back to an in-process scan (slower, same results) instead of failing.
The agent describes a tool call but nothing happens — no file is read or edited
Some models write their tool calls as text (<tool_call> <function=read_file> …) instead of using the real tool-call channel, and some write their reasoning as literal <think>…</think>. NIM Code now recovers the common formats automatically, so the call runs and the markup never reaches the transcript. If a model's format is one it can't recover, the turn stops with "the model wrote its tool call as plain text" rather than looping — that is a limitation of the model behind the current mode, not of your workspace, so switch models in the picker.
"Could not reach … Check your network connection."
This now means what it says — a genuine connectivity or endpoint problem (offline, a wrong nimcode.baseUrl, a local server that isn't running). Faults inside NIM Code itself report separately and point you at the output log instead, so this message is no longer a catch-all.
"NIM Code could not save your chat history"
A write to the extension's sessions.json failed. On Windows the usual cause is another process briefly holding the file — OneDrive syncing the storage folder, or antivirus scanning it. Each write is retried automatically, and saving resumes on its own as soon as one succeeds; you'll only see this notification if the retries were also blocked. Messages sent while it persists are kept in memory but lost when the window closes, so exclude the extension's global storage folder from sync/scanning if it keeps happening.
"Some NIM Code settings are invalid" Only the settings named in the warning fall back to their defaults — everything else you configured is kept. Click Open Settings to open the settings dashboard on the first offending row and fix its value; the warning won't repeat until the set of invalid settings changes.
Rate limit errors NIM Code retries automatically with exponential backoff. Persistent errors indicate you have reached your NVIDIA NIM free-tier limit.
search_codebase fails
NIM Code uses VS Code's bundled ripgrep (rg) binary — no separate installation is needed.
Agent writes unexpected content
Use Chat mode with /review first to validate the model understands your codebase before switching to Agent.
Requirements
- VS Code 1.90.0 or later
- An API key for the provider you want to use — NVIDIA NIM, OpenAI, Anthropic, Google, Groq, or Sarvam AI (Auto mode requires no key)
- Node.js 20+ (development only)
Contributing
Bug reports and feature requests: vjwarboy13@gmail.com
Local development
pnpm install # install all dependencies
pnpm run build # compile extension + webview
# Press F5 in VS Code to launch the Extension Development Host
For incremental development, run these in two separate terminals:
pnpm run watch:webview # Vite --watch for the React UI
pnpm run watch:extension # esbuild --watch for the extension host
Builds carry the PostHog project key by default, so an Extension Development Host
session counts as an active user like any install. To keep your own machine out of
the numbers, either set "nimcode.telemetry.enabled": false in your user settings,
or build with the key blanked:
POSTHOG_KEY= pnpm run build # PowerShell: $env:POSTHOG_KEY = ''; pnpm run build
Pointing a build at a local gateway
Everything that works without your own API key — Auto and Online Chat, sign-in, feedback, bug reports, invite links — talks to the hosted gateway, and those domains are written down in exactly one place:
// src/shared/config/gateway.ts
export const GATEWAY_ORIGIN = 'https://ai-gateway-beta.vercel.app';
export const GATEWAY_FALLBACK_ORIGIN = 'https://ai-gateway-bay.vercel.app';
Change the first to http://localhost:3000, run pnpm run build, and the
extension host, the webview and the bundle all follow — there is nothing else to
edit, and nothing to remember to change back beyond that line. It lives under
src/shared/ because the webview needs it too, and the webview cannot import from
src/extension/.
The second is a standby, and it is what a local gateway makes convenient: a request the primary cannot serve at all — nothing listening on localhost, DNS failure, or a 404 from a deployment that has been renamed or removed — is retried against it, and later traffic sticks with whichever origin answered. Only those failures move it. A rejection the gateway meant to send (401, 422, a rate limit) and a 5xx are the same answer at either host, so they are reported rather than re-sent, and a timeout is never retried elsewhere — it would only double the wait.
To redirect a single endpoint instead of the whole domain, set it at build time:
FEEDBACK_URL=http://localhost:8787 pnpm run build
AUTO_PROXY_BASE_URL, FEEDBACK_URL, BUG_REPORT_URL and GATEWAY_BASE_URL each
override one endpoint, and only when actually set — an ordinary build compiles the
constants above. An override replaces the pair rather than heading it: it names
the one host you meant, so nothing quietly falls back off it.
Scripts
| Script | Purpose |
|---|---|
pnpm run build |
Full production build (webview + extension host) |
pnpm run watch:webview |
Rebuild webview on file changes |
pnpm run watch:extension |
Rebuild extension host on file changes |
pnpm run typecheck |
Type-check both tsconfigs without emitting |
pnpm run lint |
Run ESLint across all source files |
pnpm run format |
Auto-format with Prettier |
pnpm run test |
Run unit tests (Vitest) |
pnpm run test:e2e |
Run end-to-end tests (Playwright) |
pnpm run rebuild:electron |
Rebuild the native better-sqlite3 module for VS Code's Electron ABI — run before F5 |
pnpm run rebuild:node |
Rebuild better-sqlite3 for plain Node — run before pnpm run test |
pnpm run package |
Build and pack a .vsix installable file |
pnpm run publish |
Publish to the VS Code Marketplace |
Native module note:
better-sqlite3is a compiled addon. Vitest runs under plain Node, while the Extension Development Host (F5) runs under VS Code's bundled Electron — a different Node ABI. IfF5throwscommand 'nimcode.*' not foundfor every command, the native binary is almost certainly built for the wrong ABI; runpnpm run rebuild:electronand relaunch. See CLAUDE.md for details.
License
MIT © 2026 Vijay