Model or dataset
spaceamoeba-t/tapq avatar
spaceamoeba-t/tapq

TapQ: a voice channel between your coding agents and your earbuds

Multi-modal voice agent for your AI agents. Talk with Claude Code, Codex, and others by voice: answer their prompts, give instructions, ask what they did. Or just nod.

707 stars11 forksSwiftApache-2.0

At a glance

What is it?
TapQ is a macOS runtime that sits between coding agents and AirPods, speaking approval prompts into your ear and turning a spoken answer, a nod or a shake back into the response the agent's hook was waiting for. It suits someone running several agents in parallel who cannot keep a terminal in front of them, and it depends on an undocumented-looking gesture layer plus a cloud speech backend in its more capable mode.
Who is it for?
TapQ is worth trying for a developer who runs several coding agents in parallel and keeps getting pulled back to a terminal to answer approval prompts, because the hook-based design means the agent blocks on the same prompt it would have shown anyway, and because the answer path back through the hook is the agent's own mechanism rather than a side channel.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 36 days ago.
What is it written in?
Mainly Swift, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 20, 2026, and from our analysis. They are not legal advice.

Editorial analysis

It speaks the prompt, and it hands the answer back through the agent's own hook

TapQ is described as a multi-modal voice agent for AI agents, and the pitch is that supervising agents no longer needs a screen. It works today with Claude Code, Codex, Cursor and OpenCode, on AirPods and macOS.

The mechanism has a shape worth understanding before the features. An agent stops for a permission, a question or a choice, and its hook sends that event to the TapQ runtime and waits for an answer. The runtime speaks the prompt through the earbuds, opens a response window, and listens. Your answer comes back through the same hook, so the agent receives exactly what it expected to receive from its own prompt.

That last part is the design decision that makes the rest work. The documentation is explicit that anything TapQ cannot answer, a multi-select prompt, a missed gesture, a failed voice pipe, falls back to the agent's on-screen prompt exactly as if TapQ were not installed. And everything TapQ does unprompted is spoken and attributed, and none of it can approve anything.

That last clause is the safety property, and it is worth reading twice. TapQ can read a status question to you, and it can carry a message you dictated, but approval stays a human act. The four listed capabilities are: speaking every prompt, so that prompts from every open session arrive as one spoken queue; reporting a finished run and taking the next instruction; answering questions about the work by reading the agents' own transcripts; and taking goals and follow-ups, including starting a session when nothing is running at all.

A whole afternoon of agent turns, as a transcript of speech

The documentation includes a worked example of an afternoon with two agents, and it reads like a script:

code
Claude Code: Run swift test. Approve?
  "yes"
Codex: Run python migrate.py. Approve?
  "no, tell Codex to keep the old table names"
  Queued for Codex.
  "who's waiting?"
  Nothing is waiting. Claude Code finished the migration.
  "when Claude Code finishes the changelog, rerun the tests"
  After Claude Code finishes: rerun the tests — noted.

Three things in that exchange are capabilities rather than dialogue. The negative answer carries an instruction, so the answer to an approval prompt can be a dictation, not just yes or no. The status question, who is waiting, is answered by reading the agents' own transcripts and returning a sentence instead of making you open a tab. And the follow-up, rerun the tests when a named agent finishes, is a rule that is remembered rather than a thing you have to be present for.

That last one is the point of the tool. A queued instruction means the agent turn ends in your ear and the next one starts there, so an agent that finishes while you are making coffee still gets its follow-up.

The repository layout shows how the pieces are separated. There is a Sources/ directory for the Swift code, an Executables/ directory, a Tests/ directory, and separate bench/, ml/, scripts/ and docs/ directories. The ml/ directory is where a recogniser would live, and the bench/ directory suggests the performance work is being done on the on-device path rather than only in the cloud path. There is also a Package.swift at the root, a CLAUDE.md, a TROUBLESHOOTING.md and a SECURITY.md.

Gestures come from the AirPods motion stream, not from a second device

The input side is where TapQ differs from a voice assistant. AirPods report head motion, and TapQ recognises a set of gestures on-device: a double nod, a double shake, a double tilt, and a stem tap. Those map to approve, deny, next or previous option, and confirm.

So answering a prompt does not strictly require speech at all. A double nod approves, a double shake denies, and a double tilt steps through the options. The stem tap is a confirm, which is the gesture you would use for the case where the agent asks you to pick one of several things and you are walking through them.

The recognition is on-device, which is what makes the gesture path work without a network round trip and without sending anything about your movements to a server.

There is a second, more interesting sensor use. The same motion sensors register the vibration of your own speech, because the bone-conduction path from your jaw reaches the earbud. With --wearer-gate enabled, speech that does not coincide with that vibration is ignored, so a colleague or a video cannot answer on your behalf. The documentation is direct about the threat model: the point is that a voice assistant that approves things should not be approvable by anyone else in the room.

That is a small feature with real consequences, and it is the kind of detail that separates a research prototype from something you would leave running all day.

Two speech backends, and the difference is what leaves your machine

Speech recognition has two configurations, and the difference is a privacy decision rather than a quality setting.

With --voice-backend openai-realtime, your speech is sent to OpenAI's realtime API only while a response window is open. The model turns what you said into one of a fixed set of actions: approve, deny, select an option, queue an instruction for an agent, answer a question about status or an agent's transcript, set a follow-up, or start a task.

The constraint on that model is important and is stated plainly: it can speak only what TapQ passes it, and it cannot answer a prompt on its own. So the language model is a parser over a fixed action set, not a conversation partner. That is what keeps the design safe, and it is also why the action set is enumerated.

The default on-device backend matches a fixed vocabulary instead, with no network involved.

The distinction determines what your project can do. If your workflow needs free-form dictation, like telling an agent to keep the old table names in a migration, the fixed vocabulary will not carry it and the cloud backend is the one that can. If your workflow is mostly approve and deny, the on-device backend covers it and nothing is transmitted.

Between prompts there is also an attention mode. With --attention wake, an on-device recogniser listens for a phrase when no window is open, so you can start a session with nothing running.

Installing the agent side is a single command

The integration with the agents is not something you configure by hand. The documentation gives the install command as `tapq integration <agent> install`.

That adds a hook, for Claude Code, Codex and Cursor, or a plugin, for OpenCode. When the agent stops for a permission, a question or a choice, or finishes a turn, the hook sends that event to the runtime and waits for the answer.

The per-agent adapter is what makes this work across four different tools, since each has its own mechanism for stopping and asking. TapQ keeps one runtime and one set of gestures, and the adapter is the part that differs.

The badges at the top of the readme set the platform envelope: Swift 6.0, macOS 14 or newer, and a Linux portable core. The Linux badge is a qualifier on the core rather than a claim of full support, since the AirPods motion path, the wearer gate and the on-device recognition are described in terms of what a Mac can do. The project also ships a badge for a Linux portable core, which is the piece of the runtime that is not tied to the Mac.

The release history is a list of betas: v0.5.0-beta.2 with a live voice loop from 2026-08-08, TapQ 0.4.0-beta.1 from 2026-08-03, and v0.3.0 from 2026-08-02. The last push to the repository was on 2026-09-16, the repository is not archived, and the licence is Apache-2.0 with a NOTICE file and a TRADEMARKS.md alongside it.

Where TapQ is the wrong tool

The first limit is that it needs a wearable and a quiet room. The gesture path assumes AirPods, and the wearer gate assumes that the only person speaking is the person wearing them. A developer on a desk with a monitor, working on one agent at a time, gains nothing from a voice round trip and loses the ability to see the prompt at a glance. The tool's own premise, that agents run in parallel and pull you back to a screen, is the premise it is built on, and if you do not have that problem, this is not the solution to it.

The second is the cloud dependency in the more capable mode. With the openai-realtime backend, your spoken instructions are sent to a third-party API, during the response window only, but that is still your code, your task names and your agent's prompts leaving the machine in spoken form. The on-device backend avoids it by giving up free-form dictation. There is no third option described in the project documentation.

The third is the beta state. Three of the three recent releases are betas or a beta-tagged build, and the newest carries a live voice loop in its name, which is a description of a feature in motion rather than a settled one. The plugin and hook surface of the underlying agents also changes, and TapQ has to keep four adapters in step with tools that move quickly.

The fourth is that this is macOS only for the full product. The Linux portable core covers part of it, but the AirPods motion path, the wearer gate and the on-device recogniser are described as Mac capabilities.

The fifth is the accessibility angle, which cuts both ways. The topics list accessibility and hands-free, and a voice interface for a supervisor who cannot use a screen is a real benefit. But the same gesture set that makes it usable hands-free is the thing that will misfire in a moving train or a noisy room, and a misfired double nod is a misfired approval.

Editorial conclusion

TapQ is worth trying for a developer who runs several coding agents in parallel and keeps getting pulled back to a terminal to answer approval prompts, because the hook-based design means the agent blocks on the same prompt it would have shown anyway, and because the answer path back through the hook is the agent's own mechanism rather than a side channel. It is the wrong tool for a single agent on a single monitor, and the wrong tool if you cannot accept a voice assistant in the room at all. Before you install it, check the three things the documentation states: the platform floor of macOS 14 or newer with Swift 6, which excludes the Linux portable core from being the whole product; the privacy mode you are choosing, since the default on-device backend matches a fixed vocabulary while --voice-backend openai-realtime sends your speech to a cloud API during the response window; and the fallback behaviour, since anything TapQ cannot answer falls back to the agent's unchanged on-screen prompt and TapQ itself can never approve anything.

Frequently asked questions

How do I install TapQ for my coding agent?

Run tapq integration <agent> install, which adds a hook to Claude Code, Codex or Cursor, or a plugin to OpenCode. The hook sends stop events to the TapQ runtime and waits for the answer, which then returns through the same hook. The project needs macOS 14 or newer and Swift 6.0.

What can the TapQ voice backend do with what I say?

With --voice-backend openai-realtime the model turns speech into one of a fixed set of actions: approve, deny, select an option, queue an instruction for an agent, answer a question about status or a transcript, set a follow-up, or start a task. It can only speak what TapQ passes it and cannot answer a prompt on its own. The default on-device backend matches a fixed vocabulary instead.

Can someone else in the room approve a prompt for me in TapQ?

Not with the --wearer-gate option enabled. The same motion sensors that register the gestures also register the vibration of your own speech, and speech that does not coincide with it is ignored, so a colleague or a video cannot answer on your behalf. Without that option, that protection is not applied.

Official sources

  1. License: Apache-2.0
  2. Project website
  3. README
  4. Releases
  5. spaceamoeba-t/tapq on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/spaceamoeba-t-tapq.svg)](https://hysenlabs.com/projects/spaceamoeba-t-tapq)