Skip to content

Latest commit

 

History

36 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ok-voice

Press a hotkey, speak, and paste the transcription at your cursor. ok-voice is a toggle-driven voice-to-text application for Linux on X11 using a configurable OpenAI-compatible Whisper endpoint.

  • Toggle mode: first press starts recording, second press stops
  • Batch transcription: uploads one completed WAV through the standard /v1/audio/transcriptions API; no Realtime API or WebSocket
  • Automatic language detection: no language configuration required
  • Unicode output: transfers UTF-8 through the X11 clipboard

Requirements

  • Babashka
  • parecord from PulseAudio utilities
  • xdotool
  • xclip
  • notify-send from libnotify
  • xbindkeys or another external hotkey manager
  • An X11 desktop session
  • An OpenAI-compatible transcription endpoint and Bearer credential

On Debian/Ubuntu:

sudo apt install pulseaudio-utils xdotool xclip libnotify-bin xbindkeys

Setup

Create the configuration directory and copy the example:

mkdir -p ~/.config/ok-voice
cp resources/config.example.yaml ~/.config/ok-voice/config.yaml
chmod 600 ~/.config/ok-voice/config.yaml

Edit ~/.config/ok-voice/config.yaml:

api-url: "https://whisper-turbo.twohundredok.com/v1/audio/transcriptions"
api-key: "your-api-key-here"
model: "large-v3-turbo"
allow-insecure-http: false

api-url must be the complete transcription endpoint, including /v1/audio/transcriptions. The request uses the OpenAI multipart fields file, model, and response_format=json, with Bearer authentication.

The following environment variables are used when the corresponding config value is absent:

Config Environment Default
api-url OPENAI_API_URL https://api.openai.com/v1/audio/transcriptions
api-key OPENAI_API_KEY none
model OPENAI_MODEL whisper-1

Remote plain-HTTP endpoints are rejected because they expose the credential and recorded audio. HTTPS is recommended. Localhost HTTP is allowed; another HTTP endpoint requires allow-insecure-http: true.

Never commit the real user configuration or an API key. The tracked resources/config.example.yaml contains placeholders only.

Hotkey

Add a binding to ~/.xbindkeysrc:

"cd ~/src/200ok/ok-voice/ && bb -m ok-voice.core"
    F9

Change the checkout path and key as needed, then reload xbindkeys:

xbindkeys --poll-rc

Usage

Run the application once to start recording:

bb -m ok-voice.core

Run the same command again to stop and transcribe. The Babashka task is also available as bb ok-voice. Notifications indicate recording, transcription, completion, and error states.

How it works

  1. The first invocation records 16 kHz mono audio from the default PulseAudio input into a temporary WAV file.
  2. The second invocation writes a runtime stop request.
  3. The recording process uploads the WAV to the configured OpenAI-compatible endpoint and reads the JSON text response.
  4. The original X11 window is activated and receives the transcript through the UTF-8 clipboard.
  5. Temporary WAV and runtime state files are removed.

Text insertion

The transcript is transferred through the X11 clipboard rather than typed as synthetic character keypresses. X11 keyboard events cannot represent arbitrary Unicode reliably; direct xdotool type input can corrupt characters such as German umlauts.

ok-voice restores the previous textual clipboard after pasting. It uses Shift+Insert for normal X11 applications and Ctrl+Shift+V for Kitty, selected from the target window's X11 class. xdotool remains responsible only for restoring window focus and sending the paste shortcut.

Development

clj-kondo --lint src --fail-level warning
git diff --check

Vibe coded

This project is 100% vibe coded with GSD. The full planning artifacts are in the .planning/ folder.

License

AGPL-3.0 - see LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages