Architecture & build
How the extension is put together, and how to build it from source. For what it does, see the home page.
Tech & performance
Section titled “Tech & performance”- Host: C# / .NET Framework 4.8 Visual Studio package (VSIX) for Visual Studio 2022 and 2026 (VS 17.0+).
- Chat UI: a WebView2 app built with Lit web components and Fluent UI Web Components, so the UI matches Visual Studio’s look and adapts to the active theme (light/dark). Fluent components are kept pure (no custom colour overrides), so theming stays consistent.
- TypeScript end to end, bundled by
esbuild into a single IIFE
dist/bundle.js; the host↔web message contracts are generated from the C# source (one source of truth, no hand-kept duplicates). - CLI pane: a real terminal via
ConPTY
(
Microsoft.Terminal.Wpf), so the interactive CLI renders exactly as in a native shell. - Lazy everything, by design. The guiding principle is nothing is built, read or started until it’s actually needed: the extension is meant to be fast, fast, fast. Everything loads on demand and tears down when idle; work you don’t do costs nothing.
- Tuned for performance and low memory:
- Chat history is lazy: pages of 50 read from the
.jsonlon demand, heavy blocks (images, sub-agent transcripts, full diffs) fetched only when opened; nothing loaded up front. - Session metadata is read with head+tail 64 KB windows, never loading whole files.
- The MCP server and event listeners start/stop lazily on the first/last open pane.
- The WebView is Shadow-DOM + static styles, minimising reflow and style recalculation; CSS/TS are kept lean (linted, no dead rules) for fast paint and small bundles.
- Chat history is lazy: pages of 50 read from the
How the CLI is started
Section titled “How the CLI is started”- Settings are loaded from the user, project and local files (
--setting-sources user,project,local), so yourpermissions.allowanddenyapply as in a terminal. - The IDE tools (
mcp__vs__*) are pre-approved: they never raise a permission prompt, in any mode. - A profile’s variables are applied first and the extension’s own last, so a profile cannot
override
CLAUDE_CODE_ENTRYPOINT(nor, in a CLI pane,FORCE_CODE_TERMINALandCLAUDE_CODE_SSE_PORT).CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTINGis set only while Keep file checkpoints is on. - Visual Studio started from inside a Claude Code session does not pass that session’s identity
on:
CLAUDECODE,CLAUDE_CODE_SESSION_ID,CLAUDE_CODE_CHILD_SESSIONand the related variables are removed from everyclaude.exeit starts. - A resumed session starts in the permission mode it was last in, read from its transcript; a new one in Initial permission mode.
- The CLI runs in a job object: it is killed with Visual Studio, never left behind.
Everything builds from a single solution; the WebView build is hooked into MSBuild.
# Build the VSIX (also runs the WebView build via the BuildWebViewSrc MSBuild target)msbuild cv4vs-agents.slnx /t:Build /p:Configuration=Debug# F5 in Visual Studio launches a second (experimental) VS instance with the extension loaded.WebView UI (src/Corsinvest.VisualStudio.Agents/Chat/WebViewSrc/):
npm run build # gen-bridge + esbuild → dist/bundle.jsnpm run dev # esbuild --watch while iterating on the chat UInpm run typechecknpm run lintRequirements: the CLI is installed separately (npm i -g @anthropic-ai/claude-code) and driven with
the claude-vscode entrypoint.