Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

25 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

🦜 Parrot

Speech to stdout.

Parrot is a tiny native macOS CLI-first speech-to-text tool. It listens for one spoken utterance, writes the finalized transcription to stdout, and exits.

parrot
parrot | pbcopy
text="$(parrot)"
codex exec "$(parrot)"
git commit -m "$(parrot)"
parrot >> notes.txt

Why Parrot?

Parrot turns speech into a Unix input primitive. It does not manage notes, own your workflow, or run as a background service. It listens once, transcribes once, writes text to stdout, and gets out of the way.

Think of it as cat for your microphone—with an intentional one-utterance boundary so every invocation produces one composable result.

Its CLI contract is small:

  • One utterance per invocation
  • Finalized text on stdout
  • Diagnostics on stderr
  • Meaningful exit codes
  • Composition with ordinary shell tools
  • Strict --on-device mode that never silently uses network recognition

Install

git clone git@github.com:swinton/parrot.git
cd parrot
make install

Installation creates:

~/Applications/Parrot.app
~/.local/bin/parrot

Ensure ~/.local/bin is on PATH. For zsh:

echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc
exec zsh

Verify the installation:

command -v parrot
parrot --version
parrot

Uninstall with:

make uninstall

Usage

Usage: parrot [OPTIONS]

Options:
  -h, --help
  --version
  --print-config
  --locale ID
  --timeout SECONDS
  --silence-duration SECONDS
  --on-device
  --verbose
  --debug-audio
  --live-debug
  • --locale en-US selects a recognition locale.
  • --timeout 30 sets a hard limit for the entire invocation, including the initial wait for speech.
  • --silence-duration 1.5 finalizes after that much continuous acoustic silence once speech has begun.
  • --on-device strictly requires Apple on-device recognition.
  • --verbose prints partial recognition to stderr.
  • --help and --version print command information.
  • --print-config prints effective settings without using the microphone.
  • --debug-audio and --live-debug expose development diagnostics.

Defaults are a 30-second hard timeout, 1.5 seconds of acoustic silence, and the current system locale. Apple may divide a long utterance into multiple internal recognition segments. Parrot keeps the microphone active across those segments and emits their combined transcript only when its own silence or timeout rule completes the invocation.

Silence detection uses microphone energy rather than transcript updates. Very quiet speech or unusually noisy rooms may affect the boundary. Use --debug-audio to inspect input levels and choose a longer silence-duration for long-form dictation. Because timeout remains a compatibility-preserving hard maximum, increase it as well when recording notes longer than 30 seconds.

Configuration

Parrot reads persistent settings from:

$XDG_CONFIG_HOME/parrot/config

When XDG_CONFIG_HOME is unset or empty, it uses:

~/.config/parrot/config

The file is optional and is not created automatically. Use a small key = value format with blank lines and # comments:

# Allow longer pauses and a five-minute long-form session.
silence-duration = 5
timeout = 300
locale = en-US
on-device = false
verbose = false

Supported keys are silence-duration, timeout, locale, on-device, and verbose. Command-line options override config values, which override built-in defaults. For example, this uses a two-second silence duration once while leaving the configured five-second value unchanged:

parrot --silence-duration 2

Inspect the resolved path and effective settings without activating the microphone:

parrot --print-config
parrot --print-config --timeout 10

Malformed files, unknown or duplicate keys, and invalid values produce a diagnostic with the config path and line number on stderr and exit with status 2. A missing config file is silently ignored.

Exit codes:

0  Transcription completed
1  Unexpected failure or interruption
2  Invalid arguments
3  Permission denied
4  Timeout or no speech
5  Speech recognizer unavailable
6  Audio input unavailable

Requirements

  • macOS 13 or newer
  • Apple Silicon Mac for the current locally built artifact
  • Xcode or a compatible Swift 6 toolchain to build
  • A microphone selected as the default macOS input

macOS 13 is the minimum because it keeps the native implementation small while covering the intended Apple Silicon workstation.

The Mac mini has no built-in microphone. Headless Mac mini installations need an attached USB or Bluetooth input device selected under System Settings > Sound > Input.

Permissions

On first use, macOS requests Microphone and Speech Recognition permission. The installed app's stable bundle identifier is dev.lobot.parrot.

Manage permissions under System Settings > Privacy & Security > Microphone and Speech Recognition. During development, reset decisions with:

tccutil reset Microphone dev.lobot.parrot
tccutil reset SpeechRecognition dev.lobot.parrot

Ad-hoc signing is used by default. It does not require a paid Apple Developer account, but rebuilding changes signed content and macOS may request permission again. A configured certificate can provide a stronger identity:

SIGNING_IDENTITY="Developer ID Application: Example" make install

Privacy

Parrot uses AVAudioEngine and Apple's Speech framework. It does not create temporary audio files or intentionally retain audio.

Without --on-device, Apple may use network-backed recognition depending on locale, OS capability, and system configuration. With --on-device, Parrot exits if strict on-device recognition is unavailable instead of silently falling back to the network.

See the full Privacy Notice for details about audio, transcripts, configuration, permissions, Apple Speech processing, and output destinations.

Troubleshooting

default microphone input is unavailable means Core Audio has no usable default input. Connect or select a microphone and inspect detected devices with:

system_profiler SPAudioDataType

For permission denial, enable Parrot in the Privacy & Security settings or reset the corresponding TCC decision. For recognizer-unavailable errors, try a supported locale without --on-device, and confirm network connectivity if on-device recognition is not required.

If command -v parrot returns nothing but ~/.local/bin/parrot --version works, add ~/.local/bin to PATH.

Development

swift build
swift test
swift run parrot --help
make app

Development diagnostics:

swift run parrot --debug-audio
swift run parrot --live-debug

The app bundle is written to dist/Parrot.app. Verify its signature with:

codesign --verify --deep --strict --verbose=2 dist/Parrot.app

Release checklist

  • Run swift build, swift test, and make app.
  • Verify parrot --help, parrot --version, and invalid-argument routing.
  • Complete the microphone, permissions, utterance, timeout, interruption, pipeline, command-substitution, locale, and strict on-device checks.
  • Run clean install, reinstall, signature verification, and uninstall checks.
  • Confirm versions in source and Info.plist agree.
  • Review privacy and known limitations before tagging a release.

The MVP intentionally excludes public distribution, notarization, Homebrew packaging, universal binaries, and non-macOS support. None of these are implied future commitments.

License

Parrot is available under the MIT License.

About

🦜 Parrot: Speech to stdout.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages