Skip to main content

Voice-to-prompt for developers. Hold a button, speak, release — structured prompts on your clipboard in under a second.

Project description

Invoke

PyPI Python License

Voice-to-prompt for developers.

Hold a button, speak, release. Your words hit the clipboard (or auto-paste at your cursor) in under a second. GPU-accelerated local transcription via Whisper — no cloud round-trip for speech-to-text.

Optionally run your transcription through an AI reformatter to clean it up into structured prompts for Claude Code, Cursor, Windsurf, Copilot, or raw text.

Install

# CLI only (headless, any platform)
pip install getinvoke

# With GUI (system tray + overlay)
pip install getinvoke[gui]

# Or use pipx for isolated install
pipx install getinvoke

Note: The CLI command is dictate, not invoke, to avoid conflict with the pyinvoke task runner.

Quick Start

# Check your setup (GPU, mic, settings)
dictate health

# Run the setup wizard
dictate setup

# Start dictating (headless mode)
dictate run

# Start with GUI (requires [gui] extras)
dictate run  # auto-detects GUI availability

Default workflow: Hold Mouse5 (forward side button) → speak → release → text on clipboard.

How It Works

 YOU SPEAK into your mic
     │
     ▼
 ┌─────────────────────────────┐
 │  WHISPER (runs locally)     │
 │  Model: distil-large-v3     │
 │  GPU (CUDA) or CPU          │
 │  No internet. No API key.   │
 │                              │
 │  Output: raw transcription   │
 │  "uh so like fix the um     │
 │   auth middleware thing"     │
 └──────────────┬──────────────┘
                │
                ▼
 ┌─────────────────────────────┐
 │  AI REFORMATTER (optional)  │
 │                              │
 │  Takes raw speech and       │
 │  reshapes it based on the   │
 │  selected MODE:             │
 │                              │
 │  Claude Code → conversational│
 │  Cursor → @file references  │
 │  Commit → git commit msg    │
 │  Raw → just clean up speech │
 │  none → SKIP (no AI call)   │
 │                              │
 │  Backend options:            │
 │  • openrouter (cloud API)   │
 │  • claude-cli (local CC)    │
 │  • ollama (fully local)     │
 │  • none (skip AI entirely)  │
 └──────────────┬──────────────┘
                │
                ▼
 ┌─────────────────────────────┐
 │  CLIPBOARD + AUTO-PASTE     │
 │  "Fix the auth middleware   │
 │   to validate JWT tokens    │
 │   before checking roles"    │
 └─────────────────────────────┘

Platform Support

Platform CLI GUI (tray + overlay) Installer GPU
Windows pip install getinvoke pip install getinvoke[gui] Download .exe CUDA (NVIDIA)
macOS pip install getinvoke pip install "getinvoke[gui]" Download .dmg MLX (Apple Silicon)
Linux pip install getinvoke pip install getinvoke[gui] pip install getinvoke[gui,wayland] CUDA (NVIDIA)

Comparison

Feature Invoke whisper.cpp CLI nerd-dictation macOS Dictation
Local Whisper Yes Yes Yes No
AI reformatting 5 backends No No No
Code-aware modes 8 modes No No No
Project context Auto-detected No No No
GPU acceleration CUDA + MLX CUDA/Metal No
Privacy mode Yes (fully offline) Yes Yes No
Cross-platform Win/Linux/Mac Win/Linux/Mac Linux Mac only
pip installable Yes No No

Requirements

  • Python 3.11+
  • NVIDIA GPU (CUDA) or Apple Silicon (MLX) recommended — works on CPU but slower
  • Windows, Linux, or macOS

CLI Commands

Command Description
dictate run Start Invoke (auto-detects GUI vs headless)
dictate run --headless Force headless mode
dictate run --no-beep Start without audio feedback
dictate health Check GPU, model, mic, API keys, config
dictate devices List audio input devices
dictate modes List available target modes
dictate history View dictation history
dictate setup Run setup wizard
dictate setup --cli Force CLI wizard (no GUI)
dictate config View all configuration
dictate config mode cursor Set a config value
dictate license status Check license status
dictate license activate <key> Activate a license
dictate install Create Windows Startup shortcut
dictate transcribe <file> One-shot WAV transcription
dictate logs View log file

Configuration

Key Settings

Setting Default Options
reformatter_backend none openrouter, claude-cli, ollama, none
mode claude-code claude-code, cursor, windsurf, copilot, raw, commit, pr
whisper_model distil-large-v3 Any faster-whisper model
whisper_device auto auto, cuda, cpu
hotkey mouse5 mouse5, mouse4, ctrl+shift+d, or any key combo
auto_paste false true = insta-dump at cursor
audio_device system default Device index from dictate devices
beep_enabled true true / false
sound_preset default default, subtle, arcade, minimal, icq, aim, dial-up
language en en, auto, or any Whisper language code

Set values quickly from the terminal:

dictate config mode cursor
dictate config reformatter_backend claude-cli
dictate config auto_paste true

AI Reformatter Backends

Backend Where it runs What you need Cost
openrouter Cloud (OpenRouter API) OPENROUTER_API_KEY ~$0.001/dictation
claude-cli Local (your Claude Code) Claude Code installed Part of your CC plan
ollama Local (your machine) Ollama running on localhost:11434 Free, no internet
none Skipped entirely Nothing Free — raw Whisper output only

Target Modes

Mode What the AI does with your speech
claude-code Formats as a conversational prompt for Claude Code
cursor Adds @file references, structured for Cursor's chat
windsurf Cascade-style prompt for Windsurf
copilot GitHub Copilot Chat format
raw Cleans up filler/grammar only — no prompt structure
commit Turns your description into a git commit message
pr Turns your description into a PR title + body

Custom Hotkeys

The settings GUI has a Record... button to capture any key combo. Or set it from the CLI:

dictate config hotkey "ctrl+shift+r"
dictate config hotkey mouse5

Supports modifier combos (ctrl+shift+d, alt+f2), mouse buttons (mouse4, mouse5), and single keys.

Ollama Setup

# Install Ollama (https://ollama.com)
ollama pull llama3.2

# Configure Invoke to use it
dictate config reformatter_backend ollama
dictate config ollama_model llama3.2
# Default URL: http://localhost:11434

Custom Vocabulary

Boost Whisper recognition for domain-specific terms:

dictate config custom_vocab "KeyGrip,OpenRouter,pyproject,FastAPI,pynput"

History

dictate history            # Recent entries
dictate history -n 20      # Last 20
dictate history -s "fix"   # Search

History retention defaults to 30 days. Change with dictate config history_retention_days 90.

Audio Feedback

  • Short high tick — recording started (hotkey pressed)
  • Rising chirp — done, text is on clipboard / pasted
  • Disable with dictate run --no-beep or dictate config beep_enabled false

Sound Presets

Choose from 7 sound themes:

Preset Vibe
default Original Invoke sounds
subtle Softer, lower tones
arcade Retro game-style chirps
minimal Single short ticks
icq Classic ICQ vibes
aim AIM buddy list chirps
dial-up Modem handshake tones
dictate config sound_preset icq

Preview all sounds in Settings > General > Sound theme > Preview.

Linux Notes

  • Audio stream stays open to avoid ALSA/PipeWire latency on every hotkey press
  • If using pip install on modern Debian/Ubuntu, use pipx install getinvoke instead (PEP 668)

X11

Auto-paste requires xdotool:

sudo apt install xdotool   # Debian/Ubuntu
sudo dnf install xdotool   # Fedora

Wayland

Wayland requires a few extra steps for full functionality. Run dictate health at any point to check your setup.

Mouse hotkeys (mouse4/mouse5)

pynput can't capture global mouse events on Wayland. Invoke uses evdev instead, reading directly from /dev/input:

# 1. Install the wayland extra
pip install getinvoke[wayland]

# 2. Add yourself to the input group, then reboot
sudo usermod -a -G input $USER
sudo reboot

Keyboard hotkeys (e.g. ctrl+shift+d) work on Wayland without any extra steps.

Clipboard

On Wayland, wl-clipboard is required so text lands on the native Wayland clipboard (not the X11 one):

sudo dnf install wl-clipboard   # Fedora
sudo apt install wl-clipboard   # Debian/Ubuntu

Auto-paste

Auto-paste works for XWayland apps (Electron apps like Signal, VS Code, Chrome) via xdotool. Install it as above.

For native Wayland apps on KDE or Sway, also install wtype:

sudo dnf install wtype

GNOME limitation: GNOME's compositor doesn't support the virtual keyboard protocol, so auto-paste only works into XWayland apps on GNOME. For terminals (Claude Code, etc.), auto-paste is not possible on Wayland — text is on your clipboard, paste manually with Ctrl+Shift+V.

App type Auto-paste works?
Electron apps (Signal, VS Code, Chrome) Yes — via xdotool (XWayland)
Native Wayland apps on KDE/Sway Yes — via wtype
Native Wayland apps on GNOME No — paste manually with Ctrl+V
Terminal emulators No — paste manually with Ctrl+Shift+V

System Tray (GUI mode)

When installed with pip install getinvoke[gui], Invoke runs in the system tray with:

  • State indicator (idle / recording / processing / error)
  • Current AI backend + model displayed
  • Mode switcher (right-click menu)
  • License management
  • Settings editor
  • Open logs
  • Quit

Use dictate-gui to launch without a console window.

Building the Windows Installer

See the installer README for details on building the .exe installer with PyInstaller + Inno Setup.

Development

pip install -e ".[dev,gui]"
ruff check src/ tests/
ruff format src/ tests/
pytest

Architecture

src/getinvoke/
  engine.py       # Core pipeline engine (FrontendProtocol + InvokeEngine)
  app.py          # GUI frontend wrapper (GuiFrontend + InvokeApp)
  terminal.py     # Rich terminal frontend (TerminalFrontend)
  cli.py          # Click CLI commands
  setup_cli.py    # Terminal-based setup wizard
  clipboard.py    # Copy + auto-paste via pynput
  config.py       # Settings from config.json / env vars / .env
  context.py      # Project context loader (18 file types + git)
  feedback.py     # Audio cues (beeps/chirps)
  history.py      # SQLite dictation history
  hotkey.py       # Global hotkey listener (mouse/keyboard)
  license.py      # Lemon Squeezy license validation (7-day trial)
  license_gui.py  # License activation dialog (tkinter, GUI only)
  modes/          # 7 target mode system prompts
  overlay.py      # Recording/processing overlay (tkinter, GUI only)
  recorder.py     # Push-to-talk audio capture (sounddevice)
  reformatter.py  # LLM reformatting (OpenRouter/Claude CLI/Ollama/none)
  settings_gui.py # Settings editor (tkinter, GUI only)
  transcriber.py  # Whisper model loading + transcription
  tray.py         # System tray icon + menu (pystray, GUI only)
  updater.py      # Auto-updater (GitHub releases + pip-aware)
  window.py       # Active window/file detection
  wizard.py       # First-run setup wizard (tkinter, GUI only)

installer/
  invoke.spec     # PyInstaller build config
  invoke.iss      # Inno Setup installer script
  build.ps1       # Local build script

License

MIT — see THIRD-PARTY-LICENSES.txt for bundled dependency licenses.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

getinvoke-0.10.4.tar.gz (129.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

getinvoke-0.10.4-py3-none-any.whl (124.7 kB view details)

Uploaded Python 3

File details

Details for the file getinvoke-0.10.4.tar.gz.

File metadata

  • Download URL: getinvoke-0.10.4.tar.gz
  • Upload date:
  • Size: 129.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for getinvoke-0.10.4.tar.gz
Algorithm Hash digest
SHA256 0b836e08605a08d0144dc5254631a532503cb1974f5d2314296c63362ade5bc6
MD5 b44bff38ff3cea0432fc43b7cb44c0c3
BLAKE2b-256 262a13e2b80e7aa9ec23ff828a215704100b9ba129eb0783d01f2904b18c4984

See more details on using hashes here.

Provenance

The following attestation bundles were made for getinvoke-0.10.4.tar.gz:

Publisher: publish-pypi.yml on zmroth/invoke

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file getinvoke-0.10.4-py3-none-any.whl.

File metadata

  • Download URL: getinvoke-0.10.4-py3-none-any.whl
  • Upload date:
  • Size: 124.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for getinvoke-0.10.4-py3-none-any.whl
Algorithm Hash digest
SHA256 87dce0977f35de6b4e4c9ce373821f592a9f6346787ebe1a6c24ce76eeada530
MD5 bc1d2cb9efd922e3630f95285dbaa3b5
BLAKE2b-256 dc471579f871bb70287d6ef0186c79cc9898d254f4cacc1051b069e4e371a2ec

See more details on using hashes here.

Provenance

The following attestation bundles were made for getinvoke-0.10.4-py3-none-any.whl:

Publisher: publish-pypi.yml on zmroth/invoke

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page