8000 GitHub - rezkam/SpeakFlow: You speak 3× faster than you type. SpeakFlow is a keyboard you talk to. · GitHub
[go: up one dir, main page]

Skip to content
rezkamPublic

About

You speak 3× faster than you type. SpeakFlow is a keyboard you talk to.

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

SpeakFlow

SpeakFlow

You speak 3x faster than you type. SpeakFlow is a keyboard you talk to.

A macOS menu bar app that turns your voice into text — anywhere.
Press a hotkey, speak naturally, and your words appear in whatever app you're using.

Real-time interim results that refine as you speak  ·  On-device voice activity detection powered by Apple Neural Engine

macOS 26+ Swift 6 Install with Homebrew

Install with Homebrew

brew tap rezkam/speakflow
brew install --cask speakflow

Transcription Providers

SpeakFlow supports four transcription modes across three providers. Switch between them from the Transcription tab in settings.

Deepgram Nova-3 Mistral Voxtral Realtime Mistral Voxtral Mini ChatGPT (GPT-4o)
Mode Streaming Streaming Batch Batch
How it works Audio streams over WebSocket; text appears as you speak Audio streams over WebSocket with sub-500ms latency Full recording sent after each chunk Full recording sent after each chunk
Latency ~300ms <500ms After chunk completes After chunk completes
Best for Live dictation, long-form writing Low-latency multilingual dictation Batch transcription with speaker diarization Short notes, high-accuracy single takes
Extras Smart formatting, interim results 13 languages, auto-detection Speaker diarization, temperature control —
Requires Deepgram API key Mistral API key Mistral API key (shared) ChatGPT login

API Keys

Deepgram — offers a free $200 credit, no credit card required.

  1. Sign up at deepgram.com/pricing
  2. Create an API key in the Deepgram console
  3. Paste it into SpeakFlow via the Providers tab in settings

Mistral — one API key unlocks both Voxtral Realtime (streaming) and Voxtral Mini (batch).

  1. Sign up at console.mistral.ai
  2. Create an API key in the Mistral console
  3. Paste it into SpeakFlow via the Providers tab in settings

Installation

Homebrew (recommended)

brew tap rezkam/speakflow
brew install --cask speakflow

To update to the latest version:

brew upgrade --cask speakflow

To uninstall:

brew uninstall --cask speakflow

From DMG

  1. Download SpeakFlow.dmg from the Releases page
  2. Open the DMG and drag SpeakFlow to Applications
  3. Launch SpeakFlow — the settings window opens automatically
  4. Grant Accessibility and Microphone permissions from the General tab
  5. Add an API key (Deepgram or Mistral) or log in to ChatGPT from the Providers tab

Build from Source

git clone https://github.com/rezkam/SpeakFlow.git
cd SpeakFlow
swift build -c release --product SpeakFlow

# Or build and install a signed production-version .app locally,
# without notarizing or publishing it:
make local

# To build a local release candidate with an RC display suffix:
make rc

Requires macOS 26+ and Swift 6.2+ (Xcode 26 or later).

For artifact-only local review, use a fresh directory under .agents and keep assembly separate from installation:

mkdir .agents/rc-review-unique
bash scripts/build-portable-release.sh --scratch-path .agents/rc-review-unique/build
bash scripts/stage-local-rc.sh .agents/rc-review-unique/stage .agents/rc-review-unique/build/release

The staging helper refuses existing outputs and destinations outside .agents. It assembles resources and an icon, uses a separate local-review bundle ID, and ad-hoc signs, verifies and privacy-scans only the staged app. It never installs, launches, quits the installed app, queries signing identities, notarizes or publishes. This is not Developer ID or Gatekeeper validation. Unlike this path, make rc and make local replace the installed app and launch a smoke test.

In-app updates

Stable distribution builds use Sparkle with an Updates page in the settings sidebar. The app checks automatically by default. Downloading and restarting each require an explicit click. Restart is blocked while dictation, final transcription, or pending text insertion is active. The application menu and menu bar both open Updates. Direct downloads and Homebrew installations use the same in-app update flow.

Release builds require SPEAKFLOW_UPDATE_PUBLIC_KEY (base64 Ed25519 public key) and SPEAKFLOW_UPDATE_PRIVATE_KEY_FILE (a private file containing the base64 32-byte signing seed). Generate and retain the key using Sparkle's generate_keys tool. Keep the private key outside the repository and restrict access to release maintainers. Losing it prevents existing installations from trusting new updates.

The release script embeds the public key, verifies the private/public pair, signs the final notarized DMG and appcast, verifies both signatures, and uploads both assets to the same stable release. By default, installed apps discover the feed at the repository's releases/latest/download/appcast.xml URL. Set SPEAKFLOW_UPDATE_FEED_URL before packaging to use a different stable HTTPS feed. Local and RC builds leave the updater disabled so they cannot enter the stable update channel. Publishing still uses the existing release confirmation flow.

The Homebrew tap workflow marks the cask auto_updates true. Homebrew remains a valid way to upgrade; an in-app update does not invoke Homebrew or require its CLI. An older installation without the updater needs one manual upgrade to adopt it.

For local end-to-end verification, a debug-only test bundle can set both SPEAKFLOW_UPDATE_VERIFICATION=1 and SPEAKFLOW_ISOLATED_STORAGE=1. This skips microphone and hotkey setup, uses isolated stores, and permits a signed appcast on http://localhost. SPEAKFLOW_UPDATE_APPEARANCE=dark exercises the dark theme in that bundle. Release builds cannot enable this mode.

Permissions

SpeakFlow needs two permissions, both granted from the General tab in settings:

  • Accessibility — required to type transcribed text into any app. Clicking "Grant Access" opens System Settings where you toggle SpeakFlow on.
  • Microphone — required to hear your voice. Clicking "Grant Access" shows the macOS permission dialog.

Permissions are never requested automatically on launch — you choose when to grant them.

Troubleshooting Accessibility

Released SpeakFlow builds are signed with a Developer ID certificate and notarized. Accessibility permission normally survives a standard release upgrade. If macOS stops recognizing Accessibility after replacing the app with a manual or locally built copy:

  1. Open System Settings → Privacy & Security → Accessibility
  2. Turn SpeakFlow off, then on again
  3. If that does not help, remove the old SpeakFlow entry and re-add SpeakFlow.app from /Applications
  4. Restart SpeakFlow

Usage

Microphone selection

Choose an input under General → Audio input → Microphone, or open the menu bar dropdown and select Microphone to see the device list. System Default follows the macOS input. An explicit device choice is remembered locally.

If the selected device disconnects, SpeakFlow switches to the system input and shows the active input in settings. Manual changes during recording apply to the next recording. Reconnecting a preferred device does not interrupt an ongoing fallback recording.

Menu Bar

Use Close Control Panel to hide the settings window while keeping SpeakFlow available in the menu bar. Select Quit SpeakFlow when you want to fully exit the app. Command-Q and Dock Quit close only the control panel so they do not interrupt the menu-bar service.

Hotkeys

SpeakFlow activates with a global hotkey — press it to start dictation, press it again to stop. Choose your preferred hotkey in the General tab:

Hotkey Description
⌃⌃ (Double-tap Control) Tap the Control key twice quickly
⌃⌥D Control + Option + D
⌃⌥Space Control + Option + Space
⇧⌘D Shift + Command + D

During Recording

Key Action
Hotkey Stop recording and transcribe
Escape Cancel recording — discard audio, insert nothing
Enter Stop recording; after transcription completes, press Enter in the target app (useful for sending messages in chat apps)

Escape cancels the recording from any app, even after you switch away. Enter is captured only while the recording's app has focus, once per recording; a second Enter goes to the app. Either key held with Shift, Option, Command, or Control (for example Shift+Enter for a new line) goes to the app unchanged.

Text is inserted into whichever app was focused when you started recording. If you switch to a different app during transcription, typing pauses automatically and resumes when you return — text never goes to the wrong app. In streaming mode, words appear in real-time as you speak. In batch mode, text appears after you stop.

Configurable Settings

All settings are in the Transcription tab:

  • Interim results (Deepgram streaming) — partial text appears and refines as you speak. Each update only retypes the changed portion, so there's no flickering. Disable for final-only output.
  • Voice activity detection (batch) — a neural network runs locally on Apple Silicon to detect speech in real-time. Silent and noise-only chunks are filtered out before transcription, saving API calls. Adjustable sensitivity threshold.
  • Auto-end — enabled by default in both streaming and batch modes. The shared silence duration defaults to 10 seconds and is configurable from 1–30 seconds.
  • Smart formatting (Deepgram streaming) — automatic punctuation and capitalization.
  • Endpointing (Deepgram streaming) — controls how quickly Deepgram detects the end of an utterance (100–3000ms).
  • Speaker diarization (Mistral batch) — identifies different speakers in the transcription.
  • Temperature (Mistral batch) — controls output variability. 0 gives deterministic results; higher values produce more varied output.

Features

  • Real-time streaming transcription — words appear as you speak with Deepgram Nova-3 or Mistral Voxtral Realtime; interim results refine in-place using smart diff (only changed characters are retyped, no flickering)
  • Batch transcription — record first, transcribe after with GPT-4o via ChatGPT or Mistral Voxtral Mini (with optional speaker diarization)
  • On-device voice activity detection — a neural network model runs locally on Apple Silicon to distinguish speech from silence in real-time; no audio leaves your machine until speech is confirmed
  • Automatic turn detection — when you stop speaking, silence is detected and the session ends automatically (works in both modes — local VAD for batch, server-side for streaming)
  • Smart chunking — in batch mode, audio is split at natural sentence boundaries detected by silence analysis
  • Noise filtering — silent and noise-only chunks are filtered before transcription, saving API calls and improving accuracy
  • Focus-safe text insertion: text targets the captured field and pauses during focus changes. Streaming edits require readable accessibility text and selection, with acknowledgement after each edit. If verification fails, delivery stops and automatic Enter is withheld; review the text and start a new dictation. Editors without this accessibility support cannot receive streaming edits.
  • Launch at login — runs quietly in the menu bar

Testing

  • Main feature regression gate: make test-regression-core
  • Full test suite: make test
  • Thread-safety sweep: make test-tsan
  • Live E2E suites (manual/pre-release): make test-live-e2e-all uses fresh isolated storage, not the installed app's login. For transcription, explicitly set SPEAKFLOW_E2E_AUTH_FILE to a deliberately exported credentials JSON file, or pass --auth-file FILE to scripts/run-live-e2e.sh. The file has accessToken, refreshToken, accountId, optional idToken, and lastRefresh (seconds since 2001-01-01 UTC). Treat it as a secret, keep it out of git and logs, and obtain/export it through a separately approved authentication step. No installed credentials are discovered or copied automatically. Import is local; actual transcription can refresh credentials and contact the provider only when the live suite runs. Do not combine bootstrap with --silence-only.

If local SwiftPM lock contention occurs, run the regression gate with an isolated build path: SPEAKFLOW_SWIFT_SCRATCH_PATH=/tmp/speakflow-regression-build make test-regression-core

Regression feature mapping is documented in: docs/REGRESSION_TEST_MATRIX.md

Audio Pipeline

Streaming (Deepgram)

  1. Capture: 16 kHz, mono, 16-bit PCM from the selected microphone
  2. Stream — raw audio is sent over WebSocket to Deepgram Nova-3 with the selected language
  3. Interim results — partial transcriptions appear immediate 6C08 ly as you speak
  4. Smart diff — when text updates, only the changed suffix is retyped (common prefix is preserved)
  5. Final results — server finalizes each utterance with punctuation and formatting
  6. Auto-end — after the configured silence duration (default 10 seconds) of server-detected silence following speech, the session ends

Streaming (Mistral Voxtral Realtime)

  1. Capture: 16 kHz, mono, 16-bit PCM from the selected microphone
  2. Stream — raw audio is base64-encoded and sent over WebSocket to Mistral's realtime transcription API
  3. Delta accumulation — incremental text fragments arrive as transcription.text.delta messages and are displayed as interim results
  4. Segment finalization — the server emits transcription.segment with timing info, producing a final result and resetting the delta buffer
  5. Auto-end — after configurable silence following speech, the session ends

Batch (ChatGPT)

  1. Capture: 16 kHz, mono, 16-bit PCM from the selected microphone
  2. Voice activity detection — a lightweight neural model runs on Apple Neural Engine, classifying 32ms frames as speech or silence
  3. Speech segmentation — hysteresis thresholds with 3-second silence debounce avoid false ends during natural pauses
  4. Chunking — audio is buffered and sent at the configured interval, waiting for natural pauses
  5. Auto-end — after the configured silence duration (default 10 seconds) of confirmed silence following speech, the session ends
  6. Transcription — speech chunks are sent to the ChatGPT transcription backend (GPT-4o Transcribe); results arrive in order and are typed into the active app

Batch (Mistral Voxtral Mini)

  1. Capture: 16 kHz, mono, 16-bit PCM from the selected microphone
  2. Voice activity detection — same on-device neural model as ChatGPT batch mode
  3. Speech segmentation — same hysteresis and silence debounce logic
  4. Chunking — audio is buffered as WAV and sent via multipart POST to Mistral's /v1/audio/transcriptions endpoint
  5. Auto-end — after the configured silence duration (default 10 seconds) of confirmed silence following speech, the session ends
  6. Transcription — Voxtral Mini processes each chunk; optional speaker diarization identifies different speakers in the output

License

Apache License, Version 2.0

About

You speak 3× faster than you type. SpeakFlow is a keyboard you talk to.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

0