Skip to content
| Marketplace
Sign in
Visual Studio Code>Other>Agent ShellsNew to Visual Studio Code? Get it now.
Agent Shells

Agent Shells

Edoardo Polito

|
3 installs
| (0) | Free
Launch and manage Claude and Codex agent shells in editor terminals
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Agent Shells

Claude and Codex sessions open as editor tabs, leaving the terminal panel available for build output and utility commands. The Agent Shells Activity Bar view keeps every live session reachable without a naming prompt.

Requirements

Claude and Codex run inside VS Code's own persistent editor terminals, so no external process manager is required. The durable session backend supports macOS and Linux; it does not provide a native Windows backend. Scrollback restored after a window reload is capped by terminal.integrated.persistentSessionScrollback (100 lines by default); raise that setting to keep more history across reloads.

Usage

Open Agent Shells from the Activity Bar and select /usage to open its terminal-style editor tab. The editor tab uses a dashboard meter icon. Its horizontal page navigation places /usage, the active OVERVIEW page, and muted non-interactive LIMITS, COSTS, and MODELS placeholders vertically centered beside the donut. The flat terminal screen uses aligned text, character meters, a lightweight animated ASCII donut, and the canonical Claude and Codex provider symbols. It reads usage recorded by Claude and Codex on this machine and refreshes every minute. Both provider columns reserve the same row order: tokens, USD API list-price estimate, provider account value, 5h limit, 1w limit, and provider-scoped limits. Claude uses its account-value row for extra-usage spend in the source currency. Codex uses it for a USD credit balance, unlimited, or n/a when no credit pool exists. Before each read, the panel asks the configured status-line producer to refresh any expired account data. That producer owns both provider protocols, the lock, and the 15-minute lease, so the status line and /usage share one request path and one snapshot. Fresh zero remains visible even when the provider reports no next reset time. Missing current values keep their reserved row and render an explicit unavailable or refresh-failed state instead of an expired percentage. Nonzero usage without a configured list price remains counted in tokens and excluded from the estimate, without adding model detail to the overview. The estimate is not a subscription charge, invoice total, or authenticated billing balance. Transcript stores remain read-only; only the shared status-line producer updates account state.

Select the Claude symbol to launch claude immediately, or select the Codex symbol to launch codex immediately. Each command starts in the active file's workspace folder. The first workspace folder is used when the active editor belongs elsewhere. The provider runs directly in a native persistent terminal editor tab through a small start-or-resume runner script kept under extension global storage. Reloading the VS Code window reconnects the same live provider process: VS Code restores the terminal tabs itself, restored rows appear in the tree immediately with their persisted titles, and Agent Shells re-binds each row to its terminal in the background through the shell process identifier the runner recorded. Quitting VS Code ends provider compute; the next launch reruns the runner, which resumes the recorded conversation in its original working directory once the session identity is known and starts fresh otherwise. Activity, attention, and title synchronization start as soon as a restored row is registered, and restoration never reveals or refocuses a tab. Selecting a row whose terminal is not bound yet never launches a second conversation while the recorded process is alive: the reveal waits for the re-binding and opens a fresh runner terminal only once the process is confirmed gone; a binding window that closes with the process still alive leaves the row waiting and reports it in the status bar. A click on an unbound row shows a short reconnecting status message and probes the recorded process, so a session whose terminal missed the reload snapshot resumes within seconds instead of holding the row inert for the whole binding window. Every restoration and terminal-binding step writes one structured record per session to the Agent Shells output log. Recovery records are scoped to the current VS Code workspace.

Select the history action to load previous non-active Claude and Codex sessions. The picker opens without a highlighted row, reads provider metadata and the first completed prompt, limits results to the open workspace, and resumes the selected session from its original working directory. Codex sessions attributed to Agent Shells remain visible across workspaces when / is their recorded working directory. Unrelated sessions outside the workspace remain excluded. When two windows try to resume the same session within the same brief launch window, a per-session reservation lets only one of those overlapping attempts proceed, and it is released as soon as the terminal is dispatched. It deduplicates concurrent launches only: a window that resumes the session after another window has already launched it is not blocked, so the same session can still end up in two terminals. While a reservation is held, it is keyed to the launching process and cleared if that process exits or stalls past a several-minute backstop. Live sessions prefix their title with compact recency such as (1.0h) once the latest persisted provider event is at least one displayed hour old. History uses the compact Last activity 0.4h ago wording at every age. New provider output resets this age even when no new user message exists. Its trash action hides an unwanted entry from later history views without deleting provider data. Both providers use the same persistent display-metadata store. Existing title-only records use the first-prompt preview as their description. Longer previews end with .... History never makes a model call.

History represents user sessions rather than every provider transcript. Every Claude SDK entrypoint, Codex exec session, child agent, and promptless record is excluded because it cannot be resumed as a user conversation. Claude IDE context blocks such as ide_opened_file, ide_selection, and ide_diagnostics are removed from prompt descriptions while human text in the same record remains intact. Slash commands retain their command name and arguments without Claude's XML envelope.

Live sessions start with provider-owned names such as Claude Session 1 and Codex Session 2, with the newest session at the top of the Agent Shells tree. Each terminal editor receives its provider icon when it is created; a tab reconnected after a window reload can come back with the default terminal icon instead, because VS Code has no way to re-apply an icon to a live terminal (the tree row keeps its provider icon either way). A native spinner replaces the Agent Shells row icon while either provider is processing a turn. Claude keeps the spinner while any main-session subagent remains active. An account icon takes precedence while either provider is blocked on a question, permission approval, MCP elicitation, or Codex safety-buffering choice, and the provider icon returns when the request resolves. Claude state changes come from side-effect-only lifecycle hooks and persisted provider events. Codex attention icons use the local app-server observer by default; open sessions reconnect after a socket interruption, and Codex terminals still open with file-backed activity monitoring if observation is unavailable. By default, Ctrl+C in a focused managed terminal clears stale spinner, attention, and subagent state, then forwards the interrupt to the provider. It never removes a title, because interrupting is a normal way to steer an agent mid-turn and a committed title must survive it. Explicit terminal skip-shell settings remain authoritative. A later provider event restores its current state. POSIX hosts run Claude and Codex through the login shell via the runner script. Provider exit closes the editor terminal and removes its tree row. The first active Claude or Codex prompt previews a bounded title once in the row and terminal without writing recovery or display metadata. Codex and Claude prompts start one semantic title request from the submitted first prompt, and its result persists immediately as the final title: reloads, interrupts, and later completed prompts read it back instead of regenerating, so the name a session gets is the name it keeps. Only a manual rename or a provider-sourced title replaces it. A prompt-text fallback appears only when generation fails, and the first completed prompt may then upgrade that fallback. The wheel scrolls real terminal scrollback for every provider, and text selection with copy and paste stays native VS Code behavior. The terminal turns wheel input into arrow keys whenever it shows an alternate buffer, and arrow keys recall and can resubmit previous provider messages, so Codex launches with tui.alternate_screen=never and runs inline like Claude, keeping conversation history in the normal buffer. An attached image does not block the later text prompt from naming the session. Several empty Codex terminals can coexist. The extension records ownership before terminal creation, then associates a provider thread with the closest eligible unmatched launch inside a narrow startup scheduling boundary. A claimed thread identifier cannot move to another row. Closing an owner before its deferred thread persists reserves that thread for history instead of transferring its title to another live row. A failed metadata process attempt receives one delayed retry within a 60-second attempt boundary. Exhausted attempts retain the fallback and write the provider, full session identifier, operation, failure category, attempt count, safe output lengths, fallback outcome, and persistence outcome to the Agent Shells output log without prompt or generated text. Transient Claude discovery failures log the same qualified identity and retry instead of terminating live attachment. A later extension activation or explicit resume can run one fresh enrichment cycle; polling cannot. Both providers store normalized title, description, and new-record provenance together by provider and session identifier. Legacy records remain authoritative. Once live attachment finds a transcript, pending title polling rereads that file directly instead of rescanning the provider history. Codex terminal-title updates are disabled for sessions launched by the extension, preventing the workspace directory from replacing the session name. The pencil action persists a user-supplied name and updates the Agent Shells row and terminal editor tab. A rename made before the first completed prompt keeps polling until a real prompt description can be stored. Activating a managed terminal editor tab selects its matching Agent Shells row without moving focus. Option+Command+C copies the selected provider session identifier while the Agent Shells view is focused, or the active provider session identifier while a managed terminal is focused. Codex identity attaches as soon as the owned provider record is known, independently of whether its first task can drive a title. A missing selection or provider identity reports the unresolved state without changing the clipboard. Close the terminal to remove the session from the tree, or use the X action beside the session to close it from the view. Either explicit close ends the session and removes its recovery record and runner state. VS Code window shutdown and reload detach instead, so the session record survives for restoration.

Sessions remain in the Claude and Codex stores after their terminal closes. The extension treats those stores as read-only and stores display metadata and hidden-history markers in VS Code extension state.

Each activation performs one bounded local repair pass over missing display metadata after restored terminals either reach first paint or report a bounded failure. Manual and unclassified legacy cache values remain authoritative. Metadata derived from a provably incomplete first turn is removed. Regular Claude sessions use completed-turn ai-title records, and every other prompted missing record receives a deterministic local fallback. The repair pass never invokes Luna. Resume repeats the same local guarantee before creating the live surface, so a failed earlier write cannot recreate an unnamed row.

Settings

agentShells.experimentalCodexAttention is enabled by default. It prepares the local Codex app server and waits for its WebSocket observer before launching the terminal against the same endpoint. Pending approvals and user-input requests then replace the working spinner with the account icon until the request resolves. If preparation fails, the terminal launches as an ordinary Codex session without attention observation. Turning the setting off always uses that ordinary launch path.

Architecture

src/extension.ts composes the extension lifecycle and registers the owned controller, tree, provider clients, usage panel, and disposables. src/extensionRuntime.ts keeps storage paths, setting lookup, attention wiring, and background startup out of that composition flow.

src/sessions/ owns user workflows and provider-neutral live state. SessionController coordinates start, resume, reveal, rename, copy, interrupt, close, restore, and history selection through SessionSurface. The durableSession.ts boundary persists recovery records and the per-session start-or-resume runner state owned by sessionRunner.ts, behind nativeTerminal.ts, which keeps vscode.Terminal out of the controller. History discovery, ownership, resume locking, display metadata, activity, and tree presentation remain separate modules under the same domain.

src/providers/provider.ts defines the composed launch, history, identity, activity, attention, title, and presentation capabilities used by stable session orchestration. src/providers/registry.ts is the only composition point that imports concrete providers. src/providers/claude/ and src/providers/codex/ own their formats and capability implementations without cross-importing or importing session orchestration. Dependency rules and a provider-locality syntax check reject concrete provider imports and provider-name branches across stable source outside provider-owned and usage boundaries. A synthetic third provider enters through the production registry, so a new provider is one implementation directory and one registry entry rather than a distributed conditional change.

Codex WebSocket framing remains separate from application server lifecycle. src/usage/ reads provider stores without modifying them, asks the shared status-line producer to refresh expired account data, prices decoded transcript usage, renders deterministic markup, and owns the webview panel. Browser code and styles live under resources/usage/ and load through the webview resource boundary.

History and activation repair never invoke semantic generation. Metadata synchronization owns fallback precedence, provenance-aware replacement, and workflow-level call guards, while the generator owns its bounded process attempt and one delayed retry. Codex attention aggregates parent and descendant thread waits before projecting one state onto the managed parent row. Usage collection imports no provider credentials or protocols; the status-line producer deduplicates account refreshes under its existing lock and lease.

Development

Run commands from the agent-shells directory:

  • npm run quality:static checks typed lint rules, formatting, dependency boundaries, cycles, dead files, unused exports, and unused dependencies.
  • npm run typecheck checks strict TypeScript source and the browser dashboard JavaScript boundary.
  • npm run test:unit compiles the extension and runs every nested unit test.
  • npm run test:extension runs activation, terminal, tree, and webview smoke checks in the Extension Development Host.
  • npm run package:validate compiles and inspects the VSIX inventory.
  • npm run audit:dependencies rejects dependency vulnerabilities at moderate severity or higher.
  • npm run test:coverage writes a diagnostic coverage report without imposing a repository-wide percentage target.
  • npm run check runs the complete local quality, type, unit, Extension Host, package, and dependency boundary.

The monorepo root .pre-commit-config.yaml applies file hygiene first, then staged ESLint and Prettier checks, architecture analysis, strict typing, unit tests, and dependency auditing for package changes. Rule exceptions stay at the narrowest verified file or test boundary and carry their invariant beside the configuration.

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