The Problem
Developers who spend most of their day dictating prompts to LLMs waste time switching between keyboard and microphone. A single‑command tool that records speech, transcribes it, optionally cleans the text, and places the result on the clipboard would eliminate that friction.
What This Does
voxpaste is a tiny CLI written in Python that talks to a speech‑to‑text provider (Mistral, OpenAI, Groq, Deepgram, or OpenRouter). The core logic lives in main.py, which defines 27 functions and 11 classes such as Provider, MistralProvider, CleaningProvider, and clean. The entry point is the main function (line 693). It orchestrates the workflow:
- Provider selection –
get_provider()readsVOXPASTE_PROVIDER(default mistral) and returns a concrete provider class. - Audio capture –
record_audio()usesportaudioto record from the microphone. - Transcription –
transcribe()sends the audio bytes to the chosen provider’s API. - Optional cleanup – When
--cleanis passed,get_cleaning_provider()selects a cleaning model andclean()runs a second inference call. - Result delivery –
copy_to_clipboard()invokes the system clipboard (xclipon Linux,pbcopyon macOS).
All external effects (network calls, model inference, subprocess execution, file I/O) are funneled through these five functions, making them the highest‑risk surface.
How It Is Wired
Execution starts at main in main.py (line 693). From there the internal call graph (8 resolved edges) follows a linear chain:
main → get_provider
→ record_audio
→ audio_to_wav_bytes
→ transcribe
→ get_cleaning_provider (if --clean)
→ clean (if --clean)
→ copy_to_clipboard
- Network / model calls –
get_providerbuilds the provider object;transcribeandcleaneach perform an HTTP request to the selected vendor’s API. - External command –
copy_to_clipboardrunsxclip/pbcopyviasubprocess.run. - File I/O –
audio_to_wav_byteswrites a temporary WAV file before sending it.
No other Python modules exist; the repository consists of a single source file, so the dependency graph is trivial (no circular imports, instability 0). The deep nesting detected (max indentation depth 7) makes the control flow in main.py hard to follow; refactoring into guard clauses would improve readability.
How To Use It
- Install (requires Python 3.11+ and
uvorpipx):
# Recommended with uv
uv tool install git+https://github.com/moses-y/voxpaste.git
The command installs the voxpaste entry point globally.
- Configure – Create a
.env(or export) with the provider key, e.g.:
export VOXPASTE_PROVIDER=mistral
export MISTRAL_API_KEY=sk-...
Keys for other providers follow the same pattern (OPENAI_API_KEY, GROQ_API_KEY, etc.) as documented in the README.
- Run – Basic transcription:
voxpaste
Cleaned output:
voxpaste --clean
The command records, transcribes, optionally cleans, and copies the text to the clipboard in one step.
Real‑World Use
A developer binds voxpaste to a hotkey in their window manager. While reviewing code, they press the shortcut, dictate a prompt, and the cleaned text appears instantly in their IDE’s clipboard, ready for a ChatGPT or Claude query. No manual copy‑paste or typing is required.
Code Health & Issues
- Critical – Workflow
.github/workflows/claude.ymlexposesCLAUDE_CODE_OAUTH_TOKEN; a malicious PR could exfiltrate the token. Fix: move secret‑using steps to aworkflow_runjob that never checks out PR code. - High – GitHub Actions reference tags (
anthropics/claude-code-action@v1). Fix: replace with fixed SHA commits. - Medium – No Dependabot/renovate config; add
.github/dependabot.ymlfor automatic updates. - Medium – No dependency‑vulnerability scan in CI; add
dependency-review-actionorosv-scanner. - Low – Jobs lack
timeout-minutes; set reasonable limits to avoid hung runs. - Medium (cognitive load) –
main.pyhas nesting depth 7; flatten with early returns or extract inner blocks. - Additional observations – No test suite, no lockfile (
uv.lockpresent but not used by CI), and the repository already includes a LICENSE.
The Bottom Line
voxpaste delivers a functional, single‑file CLI that turns speech into clipboard text with minimal latency. It is usable today but suffers from deep nesting, no automated tests, and several CI security misconfigurations that should be addressed before production deployment. Engineers comfortable with Python and willing to refactor the entry script will find it a solid foundation for voice‑first AI workflows.