JARVIS puts a voice on top of Claude Code, and routes every spawned process through an env scrubber
JARVIS — a voice assistant for Claude Code. Talk to your Mac and he brainstorms a project with you, builds it, and tells you out loud when a Claude Code session needs you. macOS, on your Claude subscription, no API key.
At a glance
- What is it?
- JARVIS is a macOS voice assistant that brainstorms a project out loud, writes the agreed design to disk, then drives a real claude -p session through plan, review and execute. The interesting design choice is not the orb: it is claude_env.child_env(), which strips every ANTHROPIC_* variable before any Claude Code process starts.
- Who is it for?
- Adopt JARVIS if you already pay for Claude Code, work on macOS, and want a spoken design phase plus a dashboard that shows which of your sessions is blocked on a human. Do not adopt it if you need a TTS-independent setup, a non-macOS host, or per-run cost in dollars rather than subscription window percentages.
- Can I use it commercially?
- Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
- Is it still maintained?
- Yes. The repository last received commits 6 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem is not speech recognition, it is the gap between deciding and building
Most voice assistants stop at transcription. JARVIS is aimed at a narrower and more annoying gap: you have decided what to build, but turning that decision into a running Claude Code session means writing a spec, opening a terminal, pasting a prompt, and then polling the session to see whether it is waiting on you. The README frames the conversation itself as the design phase. He asks one question at a time, offers two or three approaches, and the documentation states he does not start anything until you have agreed on one. The audience is a single developer on macOS who already pays for Claude Code and wants the design conversation to leave a file behind rather than evaporate. It is not a team tool and not a CI tool. The dashboard is described as six tabs (Runs, Sessions, Memory, Specs, Projects, Usage), which tells you the intended user is one person watching their own machine, not an organisation aggregating builds.
What actually happens between a spoken sentence and a claude -p process
The flow has a fixed order, and the order is the point. You talk. The brain, which the README describes as a Claude Code process running on your subscription, asks questions until an approach is settled. The agreed design is then written to docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md inside the project being built, and the README is explicit that this happens before a single process is spawned. Only then does a build start: a real claude -p session handed a brief instructing it to write a phased plan, review that plan against the spec, and execute task by task under test-driven development, ticking the plan's checkboxes as it goes. Progress is read from those checkboxes rather than inferred. Separately, JARVIS watches every Claude Code session on the machine, not only the ones it started, and can post a message into one or answer a permission prompt for a session running in Terminal.app by pressing a single key. Long-term memory is a folder of Markdown files, one fact per file, with an index the brain always sees. Every process JARVIS starts becomes a row in SQLite with prompt, project, status, token usage and the full event stream.
The env scrubber is the most defensible decision in the repository
claude_env.py defines SCRUBBED_ENV_PREFIXES = ("CLAUDE_CODE_", "ANTHROPIC_") and SCRUBBED_ENV_KEYS = {"CLAUDECODE"}. Every Claude Code process JARVIS spawns goes through claude_env.child_env(), which removes those variables first. The README gives the reason plainly: the CLI prefers an inherited ANTHROPIC_API_KEY over your login, and claude auth status keeps reporting loggedIn: true while billing moves onto the key. So the project removes the key instead of trusting its own call sites not to pass one. That is a design decision with a cost, and the cost is stated: if you leave a key in your .env, the startup check warns you it is there and the brain still never sees it. The trade-off is that anyone who deliberately wants an API key on the voice path cannot have one. That is the intended behaviour, not an oversight, but it means JARVIS is the wrong tool if your Claude Code setup depends on an API key for reasons of its own.
Getting it running, and the one key you cannot avoid
The README does not print an install command sequence, so the exact bootstrap is something to read from the repository rather than guess at here. What it does document is the runtime shape: a Python backend, a frontend that includes frontend/src/orb.ts, and a dashboard served at /dashboard. The one credential you must supply is FISH_API_KEY for Fish Audio, which gives JARVIS his voice. The README is unambiguous about the failure mode: there is no fallback, tts.py returns nothing without FISH_API_KEY, JARVIS goes silent, and his replies appear as text in the browser instead. The README also notes that swapping in a different TTS is a small, well-isolated file to replace. The release named v2.0.0 is described as the version that runs on your Claude subscription, so pinning to that tag is the sensible starting point. The orb animation is not a recording: the README states every pixel is frontend/src/orb.ts rendered live, that the audio driving the pulse is a synthetic speech-shaped envelope fitted to a measurement of the real analyser, and that scripts/make_orb_loop.py regenerates the loop.
Where the design gets thin: cost visibility and the silent-TTS trap
Two limitations are visible in the material without running anything. First, cost is expressed as subscription consumption, not money. The Usage tab shows the five-hour and seven-day windows and who spent them, and the README says the number that matters is how much of those two windows is gone rather than a dollar figure. If you need per-run spend in currency, this is the wrong instrument. Second, the TTS dependency has no graceful degradation beyond falling back to text in the browser, which is a functional change to the product rather than a degraded mode. Third, the licence metadata reports NOASSERTION. The README does not state terms, and the repository metadata does not resolve to a named licence, so anyone embedding this in a commercial workflow should read the actual licence file rather than assume permissive terms. None of these are defects in the mechanism. They are boundaries you should know before committing a workflow to it.
Against a plain terminal workflow, and against a generic TTS front end
The obvious alternative is what you already do: run claude in a terminal, keep the design in your head or in a scratch file, and check the window when you remember. The difference is not convenience, it is persistence and interruption. A terminal session leaves no SQLite row with the prompt, status, token usage and event stream, and it cannot tell you out loud that a different session on the same machine has been blocked on a permission prompt. JARVIS reads the plan's checkboxes to answer how far a build has got, which a terminal gives you only if you go and look. The second alternative is a general-purpose voice front end bolted onto an LLM API. That approach typically bills per token through an API key, which is exactly what claude_env.child_env() is built to prevent here. The trade is real in both directions: an API-key setup is portable to Linux and to CI, while JARVIS is macOS-only and inherits your subscription's two rate windows as a hard ceiling on how much you can build in a five-hour stretch.
Maintenance surface: what you are agreeing to keep working
The parts most likely to need attention are the parts that touch other software. The env scrubber depends on the CLI's variable names, so a rename upstream would need SCRUBBED_ENV_PREFIXES and SCRUBBED_ENV_KEYS updated. The build driver depends on claude -p accepting a brief and on the plan-file checkbox convention, which is a convention this project defines rather than one the CLI enforces. The session watcher depends on how Claude Code reports a blocked state, and the dashboard's Usage tab depends on what the CLI reports about the two windows, which the README describes as two windows and no separate per-model limit. The TTS layer depends on Fish Audio's API and on a key you hold. Memory is plain Markdown with an index, which is the cheapest thing here to maintain and the easiest to inspect. Long-term cost is therefore not the code but the coupling: every upstream change to Claude Code's environment variables, prompt interface or status reporting is a change JARVIS has to follow.
Who should install it, and what to check before you do
Install it if you are a macOS developer already on a Claude subscription, you want the design conversation to leave a spec file at docs/superpowers/specs/YYYY-MM-DD-<topic>-design.md, and you lose real time to sessions sitting blocked while you are looking elsewhere. Skip it if you need a host other than macOS, if you cannot or will not hold a Fish Audio key, or if your accounting requires per-run dollar figures rather than subscription window percentages. Before you commit, open claude_env.py and confirm the scrub list still matches what the CLI uses, then confirm the licence file states terms you can live with, since the metadata says NOASSERTION rather than naming one. Then check whether the release tagged v2.0.0 is the one you want, because that tag is described as the version that moved onto the subscription. If all three check out, the env scrubber is the reason to trust the rest: it is the one place where the project refuses to rely on its own discipline.
Editorial conclusion
Adopt JARVIS if you already pay for Claude Code, work on macOS, and want a spoken design phase plus a dashboard that shows which of your sessions is blocked on a human. Do not adopt it if you need a TTS-independent setup, a non-macOS host, or per-run cost in dollars rather than subscription window percentages. Before installing, verify three things in the repository: that claude_env.SCRUBBED_ENV_PREFIXES still covers ANTHROPIC_, that you are willing to hold a Fish Audio key since tts.py returns nothing without FISH_API_KEY, and that the licence file actually states terms, because the metadata reports NOASSERTION rather than a named licence.
Community notes