Skip to content

Latest commit

 

History

92 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

A pixel-art Babel fish cycling through the states idle, listening, thinking, speaking and cancel

Jarvis

A voice assistant that fits in one bash file.

Claude as its brain, the shell as its hands, and a pixel-art Babel fish as its face.

Record → transcribe → think → speak runs on any Linux box: PipeWire, Python 3, voxtype, Claude Code, Piper. Only his hands and his face need Omarchy.

Documentation · Drive the state machine · Français


SUPER + ALT + J          press to speak, press again to answer
« Hey Jarvis »           the same, without touching the keyboard
SUPER + ALT + ESCAPE     stop whatever is in flight

Say « mets le thème clair » and the theme changes. Ask « pourquoi ma dernière commande a échoué ? » and he reads your shell history and tells you. Say « corrige le bug de scroll dans mon projet web » and he dispatches a background coding session and reports back when it lands.

He answers in the language you spoke. He remembers yesterday. When he cannot do something he writes down why, and later — while idle — he reads those notes back and distils them into lessons he keeps.

What is worth stealing here

Even if you never run it, four things in this repository are designed to be read and taken:

  • A state machine that cannot drift from its documentation. Eight states, nine events, 38 of the 72 pairs legal — written out in prose above the code in bin/jarvis-fsm.sh and frozen into a test fixture, so the table and the paragraph explaining it fail together or not at all. Drive it in your browser.

  • Cancelling that actually cancels. The state file records what the machine is doing; a record beside it records which attempt is doing it. Every stage carries the epoch it started on and goes quiet if that moved. Each external stage runs in its own process group, because killing the group is what reaches the subprocesses claude spawned for its own tools — a bare pid never does, which is why aborting used to do nothing at all.

  • A memory that consolidates itself. Failures are written down as they happen. When he is idle, a separate session reads them back and distils them into lessons that become part of his persona. Interruptions go in a different file on purpose: one line in the failure log was enough to schedule a session that rewrites his personality, so pressing a key was manufacturing permanent character changes.

  • A test suite for a voice assistant. More than 250 assertions, entirely offline: a fake brain, a fake voice, a fake microphone that really dies on a signal. No quota, no network, no sound, no microphone taken.


Will this run on your machine?

Honestly: partly, unless your machine looks a lot like mine. Jarvis is three layers, and they fail independently, so it is worth knowing which one you are getting.

Layer What it gives you What it needs
The voice loop record → transcribe → think → speak, the whole conversation Linux, PipeWire, voxtype, Claude Code, Piper, Python 3 — portable
The hands changing your theme, brightness, network, windows, launching apps Omarchy and Hyprland — its CLI is his hands
The body the fish in the corner, the speech bubble, the typed prompt bar Quickshell via omarchy-shell

Layer one runs anywhere with a microphone. Layers two and three are written against a specific desktop and will not pretend otherwise: every call into them is || true, so on a plain Linux box Jarvis still listens, thinks and speaks — he just has nothing to touch and no face to make.

The reference machine is an M2 MacBook Pro running Asahi Linux under macarchy (Omarchy plus a macOS-shaped layer). bootstrap.sh fetches an arm64 or amd64 Piper build depending on where you run it.

You also need a Claude account: the brain is claude -p, invoked once per exchange. Nothing else in the pipeline leaves the machine.

Install

git clone https://github.com/macarchy/jarvis.git ~/Work/jarvis
cd ~/Work/jarvis
./bootstrap.sh      # Piper, its voices, the Whisper model, the wake venv
./install.sh        # the CLI symlink, the mascot plugin, the user units
omarchy-jarvis doctor

bootstrap.sh downloads ~300 MB that the repository deliberately does not carry (see THIRD_PARTY.md); it is resumable and running it twice fetches nothing. install.sh is idempotent too — re-running it is the supported way to update after a git pull.

doctor is the answer to "is it working?": every dependency, green or red, no guessing. Whatever it says is red, docs/troubleshooting.md explains.

Install claude and voxtype yourself — they have accounts and configuration of their own and are not Jarvis's to manage.

What leaves your machine

This matters more than the feature list, so it is here and not in an appendix. The long version is docs/privacy.md.

  • Your speech is transcribed locally. Whisper runs on your CPU. Audio never leaves the machine and the recording is overwritten by the next one.
  • Your transcript goes to Anthropic, because the brain is Claude by default — unless you point him at a local model, see "The local brain" below, in which case nothing leaves at all. So does anything Claude reads while answering you — and that can include a screenshot or your clipboard, but only when you ask for it in that exchange, never on his own initiative, and every use is logged.
  • The wake daemon holds the microphone open whenever it runs. It is optional (--skip-wake), it matches audio locally against a small model, and it records nothing until it fires.
  • Everything he does is written down in memory/trace/ — every command, every result. That file is how he answers "why did you do that?". It is also a plain-text log of your day on your own disk.

You can turn off his autonomy entirely by editing SOUL.md: rondes: non stops the hourly inspection, reves: non stops the memory consolidation, silence: 23-7 gives him hours where he does nothing unbidden.

Reflexes

Some requests never needed a model. "What time is it" is answered by date, in two hundred milliseconds, exactly.

memory/REFLEXES.md is a four-column tab-separated table — pattern, command, slot, spoken sentence — read before the brain. The pattern is a regular expression anchored on the whole transcript, exactly like memory/NOISE.md: that anchoring is what keeps "why is the sound so loud?" away from the volume command.

It exists mostly for one reason. Offline, asked the time, the local model answered "it is 2:37 pm" at 11 pm, with total confidence, in Jarvis's exact spoken format. A plausible wrong value is worse than a refusal. What date or /sys can state exactly, the brain no longer gets to guess.

omarchy-jarvis reflexe? "quelle heure est-il"          # which row matches
omarchy-jarvis reflexe? --run "quelle heure est-il"    # and what it would say

The file is yours: add, remove, fix. omarchy-jarvis doctor rejects a malformed table, and a destructive command is refused at load — the table does not go through .claude/settings.json, this is its only gate.

The local brain

By default Jarvis thinks with Claude, which needs the network. He can also talk to any OpenAI-compatible server — llama-server, LM Studio, Ollama, LocalAI, vLLM — and so answer you on a plane.

Three lines in SOUL.md, under "Réglages":

- cerveau: auto          # auto | nuage | local
- cerveau-url: http://127.0.0.1:8099
- cerveau-modele: Qwen3.5-4B

cerveau-modele carries two roles: it is the id sent to the server — llama-server ignores it, LM Studio and Ollama need it — and it is also what Jarvis says out loud when asked which brain he is thinking with. Put your model's real name in it.

auto follows the cloud's health: Claude while it answers, the local model once it stops, and a retry towards the cloud every ten minutes (JARVIS_BRAIN_RETRY). The Control Center carries the same switch under "Âme", and says where your words are going right now.

What he loses offline. The local brain has no tools at all: no Bash, no screen reading, no web search. So he can neither act on the machine nor read the time, the battery or the weather — and memory/OFFLINE_PROMPT.md explicitly forbids him to invent them, because without that instruction a 4B model answers "it is 2:37 pm" at 11 pm, with total confidence. What he keeps: talking, explaining, translating, telling a story, remembering the thread.

Running the server. On this M2 MacBook under Asahi, llama.cpp built with the Vulkan backend (Honeykrisp driver) is about 1.7x faster than CPU at prefill and 1.3x at generation. With a 4B model at Q4_K_M the first spoken sentence lands in one to three seconds.

systemctl --user enable --now jarvis-brain.service

install.sh installs the unit but never enables it for you. --reasoning off is mandatory there: a thinking model streams its reasoning into reasoning_content, burns its token budget and never says a word.

How it works

One utterance, five stages, each with a handle on disk so it can be stopped:

press ─▶ pw-record ─▶ voxtype (whisper) ─▶ claude -p ─▶ piper ─▶ pw-play
          record          stt                brain       voice    play

Underneath is an explicit state machine — eight states, nine events, and only 38 of the 72 pairs are legal. It lives in bin/jarvis-fsm.sh, written out in prose above the code, and it is frozen into tests/fixtures/transitions.txt so it cannot drift from its own documentation without turning a test red.

The machine, drivable — press the events, watch the fish change, and watch the illegal pairs be refused with the reason. Thirty seconds there beats reading this section.

The part worth stealing if you build something similar: the state file records what the machine is doing, and a record beside it records which attempt is doing it. Every stage remembers the epoch it entered on and goes quiet if it has moved. That, plus running each external stage in its own process group, is what makes cancelling real — killing the group is what reaches the subprocesses claude spawned for its own tools, which a bare pid never does.

Touch Bar — with macarchy-touchbar installed, the plugin is also a touchbar-module: the fish sits on the bar itself, where the mic key used to be — tap to press, long-press to open his Control Center page. The bar is his while he works: it fills with a meter while he listens (fed by the wake daemon), types the transcript out as he thinks, and types his reply as it is spoken; a ✕ interrupts. bin/jarvis and jarvis-wake.py publish over macarchy-touchbar macarchy.jarvis state|heard|reply|level|emote|abort — no different from the FSM signalling any other listener. install.sh copies plugin/touchbar.py with the rest of the plugin, and the daemon picks it up on macarchy-touchbar reload.

Making him yours

SOUL.md is who he is — tone, humour, whether he uses tu or monsieur, his language, which of the three French voices speaks, his quiet hours, and the five pieces his fish is assembled from. Edit it freely; it takes effect on the next conversation.

CLAUDE.md is what he can do — the commands that are his hands, written as a prompt. Adding a capability usually means one paragraph there and one line in .claude/settings.json.

« Hey Jarvis » is trained on native English. Say it the English way (héï djâ-vis); a natural French accent slides under the model. A fresh clone has no accent verifier, so the threshold defaults to 0.30 — train your own with wake/train-verifier and it rises to 0.8.

Development

./tests/run        # the whole pipeline, fully offline

The suite stubs claude, piper, voxtype, pw-record, pw-play and omarchy-shell, and redirects state and memory into a sandbox. It takes no microphone, makes no sound, spends no tokens and never touches your real memory. If it does any of those, that is a bug.

CONTRIBUTING.md has the house style and the rules that keep the machine honest.

License

MIT — see LICENSE. The downloaded pieces have licenses of their own; THIRD_PARTY.md lists them.

About

A bilingual voice assistant for Linux: Whisper transcribes locally, Claude thinks, the shell is its hands

Topics

Resources

Code of conduct

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages