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

Agent Companion

Hanif Adeyemi

|
1 install
| (0) | Free
Notification and voice-control companion for Claude Code, with an architecture built to extend to other coding agents.
Installation
Launch VS Code Quick Open (Ctrl+P), paste the following command, and press enter.
Copied to clipboard
More Info

Agent Companion

A VS Code extension that notifies you when Claude Code needs your attention — a permission request, a question, a finished task, or a failure — and optionally lets you answer with your voice. Built with an architecture designed to extend to other coding agents (Codex CLI, Gemini CLI, …) later without touching notifications, voice, or the status bar.

The problem

You kick off a Claude Code task and switch away — another window, another room. Claude then:

  • asks for permission to run something,
  • asks you a question,
  • finishes,
  • or fails.

You don't notice until you wander back. Agent Companion watches for those moments and tells you.

How it works

Claude Code supports hooks — shell commands it invokes on events like PermissionRequest, Notification, Stop, and more, with structured JSON in and out. Agent Companion installs a small script as a hook command; that script talks to a localhost-only HTTP server the extension runs while VS Code is open. No terminal-output scraping, no polling, no guessing — see docs/ARCHITECTURE.md for the full research and design writeup, including what was verified against Claude Code's docs versus what still needs a live spot-check.

Installation

  1. Install the extension (from a .vsix — see Development — or the Marketplace once published).
  2. Run Agent Companion: Setup Claude Code Integration from the Command Palette.
  3. Pick Global (~/.claude/settings.json, every project) or Project (.claude/settings.json, this workspace only).
  4. Review the summary and confirm. Your existing settings file is backed up first (settings.json.bak-<timestamp>) and only Agent Companion's own hook entries are added — nothing else in the file is touched.

Run Agent Companion: Remove Claude Code Integration to reverse this at any time; it only removes the entries it added.

If your settings.json is malformed or already has a hand-edited entry that looks like ours, setup refuses to guess — it shows the exact JSON block to paste in yourself, in the "Agent Companion" output channel.

Features

Event Notification Sound
Permission requested "Claude needs permission — project" + command + risk tier configurable
Input required "Claude needs you — project" configurable
Completed "Claude finished — project" configurable
Failed "Claude failed — project" configurable
  • Status bar — $(robot) Claude: Working / $(bell) Claude: Needs You / etc. Click it for a list of active sessions and any pending permission requests, with Allow/Deny actions.
  • Risk classification — every permission request is tagged LOW / MEDIUM / HIGH / CRITICAL by deterministic rules (no model calls) before you ever see it. See src/permissions/RiskClassifier.ts.
  • Cross-platform sound — macOS (afplay), Windows (PowerShell SoundPlayer), Linux (paplay → aplay → ffplay, whichever is installed), isolated behind one interface. No sound files are bundled; defaults come from your OS (macOS system sounds, Windows SystemSounds, or the freedesktop sound theme on Linux if present). Set a custom path in settings for anything else.
  • Voice commands (optional, off by default) — see below.

Voice control — what's real and what isn't

Voice control is implemented end to end except the actual speech recognition engine, and this README says so plainly rather than pretending otherwise.

Working today:

  • A listening window opens only in direct response to a real pending permission request, for a configurable number of seconds, then closes. The microphone is never engaged on a timer or at startup.
  • A visible $(mic) Listening… status bar indicator shows exactly when it's active.
  • VoiceCommandParser recognizes Yes/Allow, No/Deny, Repeat, and "Open Claude" from a transcript and is fully unit tested.
  • The decision-routing logic is real: for LOW/MEDIUM risk, a recognized "yes" resolves the permission request immediately. For HIGH/CRITICAL risk, voice alone is never sufficient — it only surfaces a typed VS Code modal confirmation. This is enforced in PermissionManager itself, not just in the UI layer that calls it.

Not implemented: the microphone-to-text step. VS Code has no built-in speech-to-text API, and the realistic options — a native macOS SFSpeechRecognizer addon, or a local model like a small Whisper build run as a child process — both need a focused engineering spike and a dependency decision that this build deliberately didn't make for you. Enabling voice control today turns on the listening window and the mic indicator, honestly, with nothing behind them yet: no command will be recognized until a real SpeechRecognitionProvider replaces the built-in NullSpeechRecognitionProvider. The Agent Companion: Enable Voice Control command says this explicitly when you run it.

Swapping in a real engine is isolated entirely behind src/voice/SpeechRecognitionProvider.ts — nothing else in VoiceManager or VoiceCommandParser needs to change.

Privacy & security

  • No network calls except loopback IPC between the extension and its own hook script. Nothing is ever sent to an external server.
  • The microphone is never active outside a bounded listening window tied to a real pending permission request, and voice control defaults to off.
  • Raw command text is held in memory only for the lifetime of a pending permission decision — never written to the log output channel or to disk. Session status (shown in the status bar) stores state and risk tier, not command text.
  • No command is ever auto-approved for HIGH or CRITICAL risk. A casual "yes" is never sufficient by itself for those tiers — see PermissionManager.resolve().
  • Hook installation never overwrites or removes settings it didn't add, always backs up first, and is fully reversible.

Settings

All under agentCompanion.*:

Setting Default Purpose
notifications.enabled true Desktop notifications on/off
notifications.onlyWhenUnfocused false Only notify when VS Code isn't focused (see limitation below)
sounds.enabled true Sounds on/off
sounds.volume 1 0.0–1.0, honored where the OS player supports it
sounds.permissionRequired / inputRequired / completed / failed "" Custom sound file path (empty = OS default)
voice.enabled false See Voice control
voice.listeningTimeoutSeconds 12 How long the mic window stays open
risk.warningsEnabled true Show the risk tier on permission notifications
hookScope global Default scope offered by Setup/Remove commands

Commands

  • Agent Companion: Setup Claude Code Integration
  • Agent Companion: Remove Claude Code Integration
  • Agent Companion: Enable Voice Control / Disable Voice Control
  • Agent Companion: Test Notification
  • Agent Companion: Test Permission Sound / Test Completion Sound
  • Agent Companion: Show Agent Status

Troubleshooting

  • No notifications at all — check the "Agent Companion" output channel; the IPC server logs the port it started on and every hook event it receives. If setup succeeded but nothing arrives, confirm claude --version actually reads the settings file you installed into (see the caveat in docs/ARCHITECTURE.md §1 — this was written without a local Claude Code CLI to verify against).
  • No sound on Linux — install pulseaudio-utils (for paplay) or ffmpeg (for ffplay), or set a custom sound path.
  • Setup refuses to run — your settings.json is malformed or has a hand-edited entry that looks like an old install. The output channel shows the exact JSON to paste in by hand.

Architecture overview

See docs/ARCHITECTURE.md for the full writeup. In short:

Claude Code hook → agent-companion-hook.cjs → localhost HTTP → ClaudeAdapter
                                                                     ↓
                                                            AgentEventBus (agent-agnostic)
                                                     ↓            ↓            ↓         ↓
                                          NotificationManager  StatusBar   VoiceManager  …

Nothing outside agents/claude/ knows Claude Code's payload shapes. A future agents/codex/CodexAdapter.ts implementing the same AgentAdapter interface plugs into the same bus without changing notifications, voice, status, or UI.

Development

npm install
npm run compile   # bundle with esbuild
npm run typecheck
npm run lint
npm test          # node:test — pure logic, no VS Code host required
npm run test:e2e  # downloads a real VS Code build and activates the extension in it

test:e2e is the real check: it launches an actual Extension Development Host and asserts the extension activates without throwing and all its commands register — not just that it typechecks.

Press F5 in VS Code (with this folder open) to launch an Extension Development Host interactively with the extension loaded.

Roadmap

V1 (this release): Claude Code, notifications, custom sounds, permission/completion/failure alerts, voice command parsing + risk-gated routing, deterministic risk classification.

V2: Codex CLI and Gemini CLI adapters, multiple simultaneous agent sessions, a richer dashboard, session summaries, stuck-agent detection, and a real speech-recognition backend.

V3: Mobile notifications, remote approval where it can be done safely, cross-device monitoring.

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