A minimal macOS dictation daemon. Push-to-talk, on-device transcription, text inserted at the cursor.
Fork of digimata/parrot. The push-to-talk key and the input device are configurable from the menu bar here, and the default trigger is
⌥Xrather thanfn. See What's different.
Upstream hardcodes fn as the trigger and always records from the system default
input. Its README documents a --hotkey flag, but that flag was never implemented.
- Configurable shortcut. Menu bar → Change Shortcut, then press any
modifier + key. A bare modifier on its own also works, so
fn-to-talk is still available if you prefer the original feel. - Microphone picker. Menu bar → Microphone to record from a specific device instead of whatever macOS currently calls the default.
- Default is
⌥X. The key is swallowed while held, so it never types its character into whatever you're focused on.⌘⌥Xand friends are left alone.
Both settings persist in ~/Library/Preferences/parrot.plist.
This fork has no published release, so build it:
git clone https://github.com/lesly/parrot.git
cd parrot
swift build -c release
sudo cp .build/release/parrot /usr/local/bin/parrot
parrot setup # grants mic + accessibility, downloads the model
parrot install --launch-at-login # optional, runs in the background on loginDon't use upstream's
install.sh. It downloads a prebuilt binary fromdigimata/parrotreleases, which contains none of the changes above.
Requires: macOS 14+ on Apple Silicon (M1 or newer). Transcription runs on the Apple Neural Engine via CoreML — so it won't run on Intel.
The binary is unsigned, and macOS ties Accessibility and Microphone grants to a
binary's exact code signature. Replacing it revokes both, and the daemon then
records silence without any visible error (rms 0.000 in the log).
After every rebuild, open System Settings → Privacy & Security → Accessibility,
select parrot, remove it with −, then re-add it with + (press ⌘⇧G and
enter /usr/local/bin/parrot, since the picker hides /usr/local). Toggling it
off and on is not enough. Then restart the daemon:
launchctl unload ~/Library/LaunchAgents/com.digimata.parrot.plist
launchctl load ~/Library/LaunchAgents/com.digimata.parrot.plistSigning with a stable certificate makes this go away permanently.
- Run it. Either
parrot install --launch-at-login(daemonized, runs forever, lives in the menu bar), orparrotin any terminal tab. - Click into the text field you want to dictate into — Messages, the address bar, a Slack thread, anywhere a cursor blinks.
- Hold
⌥X, speak, release. A small pill appears at the bottom of the screen while the mic is hot. - The transcript types itself in at the cursor when you release. Usually within 200-300ms.
That's it. There is no record button, no stop button, no "send" — the hotkey is the whole interface.
Note:
⌥Xis the default. Pick your own from the menu bar icon → Change Shortcut, then press any modifier + key. Pressing and releasing a bare modifier binds that on its own, sofnalone still works if you prefer it.
parrot # run in the foreground (^C to quit)
parrot setup # one-time setup: permissions + model download
parrot install --launch-at-login # register a LaunchAgent (background daemon)
parrot install --uninstall # remove the LaunchAgent
parrot doctor # check mic + accessibility permissions
parrot models list # list available models
parrot models download <id> # pre-download a model
parrot --model whisper-large-v3-turbo # bigger, multilingual, slower first-run
parrot --no-overlay # disable the bottom-of-screen pillThere's no CLI flag for the shortcut or the microphone. Both live in the menu bar so they persist without editing the LaunchAgent. See What's different.
- Swift — single SPM executable target
- WhisperKit — Whisper inference via CoreML, ANE-accelerated
- AVAudioEngine — mic capture
- CGEventTap — global hotkey
- CGEvent — text injection at cursor
- NSWindow (borderless, click-through) — recording-indicator pill
See docs/architecture.md for design notes.
swift build -c release
.build/release/parrot --help