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

Arcturn

arcturn

|
1 install
| (0) | Free
The Arcturn coding agent in VS Code — terminal integration, native sidebar, and honest cost accounting, all driven by the same engine as the CLI.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Arcturn for VS Code

Arcturn (✦) is an interactive coding agent. This extension puts it in your editor — but it is a client, never a second copy of the agent. Everything it can do, the arcturn CLI can do, because it is the same engine, the same ~/.arcturn config, the same sessions, and the same permission rules. A session you start in a terminal is the same session the sidebar will resume.

That is deliberate. If a capability is not in the engine, this extension does not have it either.

Two doors, one engine

Extension-first. Install the extension, open a folder, run Arcturn: Open. If the CLI is not on your machine, you get one notification offering to install it. Accepting types npm install -g arcturn into a visible terminal — you watch exactly what runs. Nothing installs silently.

CLI-first. Already have arcturn on your PATH? The extension finds it and uses it. It never installs over the top of what you have, and it never writes to your ~/.arcturn config. If you keep the binary somewhere unusual, point arcturn.cliPath at it.

Either way, the extension launches the TUI by typing a command into a terminal, so you can always read what it ran and re-run it yourself.

Commands

Command ID Default keybinding What it does
Arcturn: Open arcturn.open ctrl+alt+a / cmd+alt+a Launches the TUI in a terminal named Arcturn. One per workspace folder; running it again focuses the one you have.
Arcturn: Send Selection arcturn.sendSelection ctrl+alt+m / cmd+alt+m Types @path/to/file.ts:12-34 into the Arcturn terminal — and nothing else. No newline: you finish the sentence and press Enter.
Arcturn: Send File arcturn.sendFile — The same, with no line range. Also on the explorer's right-click menu, so it works with no editor open.
Arcturn: Install CLI arcturn.installCli — Runs the install in a terminal on demand, for when you dismissed the notification.
Fix with Arcturn arcturn.fixDiagnostic — A code action on any diagnostic. Sends the file, the range, and the problem reporter's own words. Not marked as the preferred fix, so it never displaces a real quick fix or hijacks fix-on-save.
Arcturn: Select Model arcturn.selectModel — Quick-pick fed by the engine's model catalog (listModels): every registered model with its context window, price per Mtok and whether the engine holds a credential for it, the ones you have keys for first. Plus anything the session announced, arcturn.defaultModel, and a free-text entry for an id the catalog does not carry. Switches the model for the live session.
Arcturn: Show Sessions arcturn.showSessions — Opens the sidebar's own history view — every session for this folder, searchable, newest first, with its id and how long ago it started. Pick one to resume it, or start a new one. The panel's history button opens the same view.
Arcturn: New Session arcturn.newSession — Starts a new session in the sidebar.
Arcturn: Abort Run arcturn.abortRun — Stops the turn in flight.
Arcturn: Show Cost arcturn.showCost — The breakdown behind the status bar figure.
Arcturn: Reconnect arcturn.reconnect — Restarts arcturn serve and reattaches after the engine dies.
Arcturn: Toggle Active File Context arcturn.toggleActiveEditorContext — Turns off — or back on — the panel's habit of including the file you have open with your next message. Same switch as arcturn.context.activeEditor and as the chip's own dismiss control.
Arcturn: Show Log arcturn.showLog — Opens the Arcturn Sidebar output channel — everything the engine wrote, redacted, plus which environment the extension resolved. This is where you look when something did not start.

The last eight drive the sidebar, so they are hidden from the palette when arcturn.serve.enabled is off — with no serve there is no engine behind them, and six entries that can only fail is not a menu.

The code action becomes available once the extension has activated — that is, after you have run an Arcturn command or opened the Arcturn view once in this window. The activation events are deliberately narrow (no "*"), and this is what that costs.

Settings

Setting Default What it does
arcturn.cliPath (empty) Path to the arcturn executable. Empty means search PATH. ~ is expanded. If it points at something that is not runnable, Arcturn tells you so rather than quietly falling back to PATH — otherwise you would be running a different engine than the one you named.
arcturn.defaultModel (empty) Passed to the engine as --model when a terminal is launched from the extension. Empty means the engine's own default.
arcturn.serve.enabled true Run arcturn serve for the native sidebar. Turn it off for terminal integration only; the Arcturn view goes away with it.
arcturn.serve.port 0 Loopback port for arcturn serve. 0 picks an ephemeral port, which is what you want.
arcturn.context.activeEditor true Include the file you have open with your next panel message. See below.

The file you have open

The panel watches which file is in front of you and shows it as a chip above the composer — dashed border, an eye — so "explain this function" is a sentence you can just type. Select something and the chip names the lines: src/auth.ts:12-40.

It is deliberately not the same chip as the ones you add with @. Those stay where you put them; this one follows your caret, and a row where the two looked identical would be a row that lies about which of its entries is stable.

A selection is an ask; an open file is not, and the chip now says which one you have:

what the chip says what goes with your message
src/auth.ts:12-40 · 29 lines of 4.2 KB those 29 lines, as an excerpt. The size is the file's, because that is what the engine measured before it sliced.
src/auth.ts one line naming the path. Arcturn reads the file itself, with its read tool, if your question turns out to need it.
src/auth.ts · escapes the workspace nothing, and the engine's own sentence about why.

The middle row used to read 4.2 KB, and used to mean it: an open file was attached whole. That was the wrong trade. (It then read path only, contents not sent for a while, which was true and still wrong: a disclaimer about transport, on screen every time the caret moved. The other two rows carry numbers you can act on; naming a file has none, so that row carries nothing.) packages/protocol/src/client.ts is 2,161 lines — about 22,600 input tokens, every single message, whether or not you asked about it; packages/cli/src/workflow.ts is 7,251 lines, about 81,200. Arcturn has a read tool and a path is enough for it to decide, so it now pays for the file on the turns where the answer is yes instead of on all of them. Hover the chip and it tells you exactly that, and what it is saving.

If you want the whole file in the message, that is what @ is for — an explicit attachment is never downgraded, however large it is.

The usual rules hold. The extension never reads the file — the engine does, from the path, where the permission engine can see the read happen. Every number on the chip is the engine's answer to resolveContext, not a stat the panel did. A file outside the workspace shows the engine's refusal instead of being quietly dropped. And nothing is attached that you cannot see before you press send.

Against an older engine that does not know how to be told a file is open, there is simply no chip, and a one-off warning says why. It will not fall back to sending you the whole file every message because your CLI is out of date; @ is still there when you want the file. Upgrade the CLI to get the chip back.

Three ways to turn it off, because some people will not want their editor watched: the setting, Arcturn: Toggle Active File Context in the palette, and the × on the chip itself — which switches the feature off rather than removing a chip that would be back on your next keystroke.

Default is on. The panel's own starter prompts say "the file I have open" and "the code I have selected"; with nothing watching, those buttons ask the model about a file it was never told and get a confident answer about nothing.

Where this actually is

Honest status, because a roadmap written as a feature list is a lie:

  • Stage 1 — the terminal integration: shipped. CLI provisioning with a version check, the Arcturn terminal, @-mentions from selection and file, and the diagnostic code action are all here and tested.
  • Stage 2 — the native sidebar: shipped. The chat webview, permission requests answered inline in the panel (with a native modal as the fallback when the panel cannot be brought into view), live cost in the status bar, the model picker, the sessions view and the reconnect path all speak the engine's WebSocket protocol — the same ProtocolClient verbs any other client gets, and nothing beyond them.

Neither stage has been through a long soak in daily use yet. The tests are real and the demo path in RFC 0004 §4 works; treat the mileage as young.

Two behaviours worth knowing about before they surprise you:

Some filenames cannot be mentioned. A mention is typed into a terminal, and the engine's mention grammar has exactly one quoting form with no escape for it. So a name containing a control character, a double quote, or the shell metacharacters $ + "" + \ ; | & < > !is refused with a message naming the offending character, rather than stripped down to something quotable — a stripped name points at a different file, which is a wrong answer delivered quietly. Spaces, quotes, brackets, braces,#, ~, *and?` are all fine; so is anything non-ASCII.

When the engine cannot start, it tells you what the engine said. If arcturn serve exits before it announces an address — no API key, a binary it cannot run, a model it cannot resolve — the sidebar shows a card carrying the engine's own stderr, unedited, with the buttons that are actually useful for it (Show Log, Choose a Model, Set CLI Path, Install CLI, Retry). The same words go to the Output channel, and a sidebar command invoked from the palette raises one error notification rather than opening an empty picker. The extension never rewords the engine's explanation: the engine is the part that knows which credential is missing.

arcturn.serve.enabled applies immediately. Turning it off shuts the sidebar and its arcturn serve process down there and then, rather than at the next window reload; a listening socket you believe you switched off is worse than a lost turn, and the session itself lives in the engine's store and resumes. Turning it back on starts a fresh one.

The :12-34 line range in a mention is parsed by the engine and narrows what gets injected: the model is given those lines, told they are an excerpt, and told which lines they are, so it does not answer as though it read the file. A range running past the end of the file is clamped and the clamp is stated; a range starting past the end is refused rather than quietly becoming the file's tail, which would be a different selection than the one you named.

Your shell's environment, and why the extension goes looking for it

On macOS, an app launched from the Dock, Spotlight or Finder is started by launchd and inherits launchd's environment — not your shell's. Nothing exported from ~/.zshrc, ~/.zprofile or ~/.bash_profile is there. A GUI-launched VS Code on a normal Mac has:

PATH=/usr/bin:/bin:/usr/sbin:/sbin        # no /opt/homebrew/bin, no nvm, no pnpm
ANTHROPIC_API_KEY                          # absent

Which is why "I installed the CLI and the extension can't find it" and "it says no API key found" are the same bug. Linux desktop launchers have the same problem. So, the first time it actually needs to start the engine — never at activation — the extension runs your own login shell, asks it to print its environment, and uses that for arcturn serve, for finding the arcturn binary, and for the --version probe.

  • Which shell. vscode.env.shell — the same one the integrated terminal opens. bash/zsh/ksh get -l -i -c; sh/dash/ash get -c only (dash rejects -l); fish gets -l -i -c; nushell gets -l -c (never -i, which opens a REPL); tcsh gets -i -c (its -l must be the only flag); pwsh gets -Login -Command. An unrecognised shell is tried as POSIX.
  • Once per window — unless it failed. A successful read is cached: not once per spawn, and Retry does not re-run your whole login shell for an answer that was already right. Edit your profile and reload the window, the same as for anything else VS Code reads at startup. A failed probe is different — it is the absence of an answer, not an answer — so Retry (and Arcturn: Reconnect) drops it and probes again.
  • Bounded. Five seconds. A profile that hangs cannot hang the extension — it falls back to VS Code's own environment and writes a line to Arcturn: Show Log saying so and saying what you lose by it. The "arcturn not found" notification says it too, so a wrong PATH never reads as "your install is broken".
  • Unambiguous. The shell is asked for env -0, so every variable is separated by a NUL — the one byte a variable's name or value cannot contain. A value with a newline in it therefore cannot be misread as declaring a new variable, which would otherwise be a way for anything that can set one environment variable to set any of them, PATH included. On a system whose env does not accept -0 (some BusyBox images), Arcturn refuses to parse rather than guessing, and falls back with the diagnostic above.
  • Nothing is logged. Your environment contains credentials. The Output channel gets a shell path, a variable count and a duration — never a name, never a value, and never the shell's own output, on the success path or the failure path. Values of credential-shaped variables are additionally registered with the log's redactor, so one reaching a diagnostic by some other route is blanked by value.
  • Your editor still wins. A variable VS Code already set is kept; the shell only fills in what is missing. PATH is merged, shell entries first, so arcturn resolves to the binary your terminal would run. VSCODE_*, ELECTRON_* and NODE_OPTIONS are never imported from a profile.

Not done on Windows, deliberately: a GUI process there already inherits the user's environment block and there is no login shell to replicate.

Still not handled: an environment that only exists once a shell has entered your project — a direnv/asdf/mise hook that fires on cd, or a key set by a shell function rather than exported — is invisible to this. The probe reads what env prints, and it deliberately does not cd into the workspace first: running your login shell inside a directory whose contents you have just opened is a bigger door than this fix needs. If your key lives in one of those, export it from a profile file, or point arcturn.defaultModel at a model whose credential the engine can already see.

Requirements

  • VS Code 1.93 or newer. That floor is load-bearing, not aspirational: onDidEndTerminalShellExecution is how the extension knows the agent is still the thing reading its terminal before it types into one, and that API was a proposal until 1.93. The extension previously claimed 1.90 and was simply inert there.
  • Node.js 20+ on the machine that runs the engine (the extension runs in the workspace host, so on a remote or dev container that means there, not on your laptop).
  • The arcturn CLI, which the extension will offer to install for you.

Arcturn is disabled in untrusted workspaces and in virtual ones. It runs an agent that reads, edits and executes in your working tree; that is not something to offer in a folder you have not trusted.

Building from source

From the repository root:

pnpm install
pnpm -C editors/vscode run build      # esbuild -> dist/extension.js
pnpm -C editors/vscode run package    # @vscode/vsce -> arcturn-vscode-0.2.0.vsix
npx vitest run editors/vscode         # the extension's own tests

Publishing to the Marketplace is a human's click, never a script's. The VSIX is the build artifact; what happens to it is a decision.


👤 Author

Sitharaj Seenivasan

  • 🌐 Website: sitharaj.in
  • 💼 LinkedIn: sitharaj08
  • 💻 GitHub: sitharaj88

☕ Support

If this project helps you, consider buying me a coffee — it keeps the work going.

Buy Me A Coffee

📄 License

Licensed under the Apache License 2.0. © 2026 Sitharaj Seenivasan.

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