A lightweight macOS menu bar app that turns a MuteMe USB button into a push-to-talk / tap-to-toggle control for Wispr Flow dictation, with the button's light showing whether you are dictating.
Limberwisk is an independent open-source project and is not affiliated with, endorsed by, or sponsored by MuteMe or Wispr Flow.
- Tap the button to start dictating, tap again to stop (hands-free).
- Hold the button to dictate while you hold it (push-to-talk).
- The light shows what is going on:
| Light | Meaning |
|---|---|
| Red | Idle |
| Green | Dictating |
| Blue | Wispr Flow is not running (touching the button does nothing) |
| Yellow | A problem: see the menu bar item, which says which (below) |
The light is best-effort: Limberwisk cannot read Wispr Flow's real state, so if you start or stop dictation another way the light can lag until the next touch.
The menu bar item (a microphone) shows the status (for example Status: Ready (MuteMe connected) or Status: Dictating) and lets you choose how long a touch must last to count
as a hold (250, 350 or 500 ms), turn on Start at Login, copy diagnostics for a bug report,
open the help page, and quit. It has no Dock icon.
Download Limberwisk.dmg,
the latest release (older versions are on the
Releases page). You can also
build it yourself; the DMG is written to dist/.
- Open the DMG and drag Limberwisk to Applications.
- A release that is not notarized (see the release notes) is refused by macOS the first time. On macOS 15 and later, try to open it, then go to System Settings > Privacy & Security and choose Open Anyway. On macOS 13 and 14, right-click the app and choose Open. Either way you are overriding Gatekeeper for an app that Apple has not checked, so only do it for a copy you trust.
- Quit the official MuteMe app if it is running: it competes for the button and resets the light. Limberwisk notices and offers to quit it for you.
Requires macOS 13 or later and Wispr Flow.
| You see | Likely cause and fix |
|---|---|
Status: MuteMe not connected |
The button is unplugged or on a charge-only cable |
Status: Wispr Flow not running |
Start Wispr Flow. Touches are ignored until then, on purpose, so the button never launches it |
Status: Official MuteMe app is running |
Click the warning row to quit it, or quit it yourself |
Status: Cannot open device |
Another program holds the button. Quit the official MuteMe app first |
Status: Wispr command failed |
Limberwisk could not reach Wispr Flow; check that it is installed and running |
Start at Login (installed app only) is greyed out |
It can only be turned on in the installed app, not when run from source |
Still stuck? Choose Copy Diagnostics from the menu and paste the result into an issue.
It contains versions, the device model and recent log lines (with your home folder removed),
and never audio or dictated text. The full log is in ~/Library/Logs/Limberwisk/.
| Device | USB ID | Status |
|---|---|---|
| MuteMe Original (current generation) | 0x3603:0x0001 |
Verified on hardware |
| MuteMe Mini variants | 0x3603:0x0002–0x0004 |
Untested |
| Legacy MuteMe Original / Mini | 0x20A0:0x42DA / 0x42DB |
Untested |
The untested devices are enabled on a best-effort basis; reports from owners are welcome.
The behaviour is specified in specs/spec.md. The pure-Python logic is
covered by unit tests that need no device, no Wispr Flow and no macOS frameworks, so they
also run on Linux CI.
nix-shell # tools: just, ruff, pytest, python
just validate # lint + format check + testsTo run against real hardware, set up the virtual environment described in
docs/releasing.md, then:
.venv/bin/python -m limberwisk # the menu bar app
.venv/bin/pytest tests/test_appkit_contract.py # checks the real macOS APIs (needs PyObjC)docs/manual-tests.md: everything that needs the real devicedocs/releasing.md: building the app and DMG, and cutting a releasescripts/: build, signing, measurement and hardware test scriptsspikes/: throwaway experiments that settled early questions
- Git hooks (
.githooks/, enabled bydirenv allow):commit-msgenforces Conventional Commits titles andpre-commitrunsjust validate. They only run locally; thevalidateworkflow (.github/workflows/validate.yml) runs the same checks in CI on every push and pull request as a backstop. - Automated PR review (
.github/workflows/pr-review.yml): needs the repository secretANTHROPIC_API_KEY(orCLAUDE_CODE_OAUTH_TOKEN) and/orOPENROUTER_API_KEY, and the action repository must be shared with this one under Settings > Actions > General. - Beads issue tracking:
.beads/is gitignored;.envrcprovisions a local database oncdinto the repo. - Template updates: the project was scaffolded with
Copier; run
copier updateto pull upstream tooling changes.