ankurCES/whisperWhy

Local-first dictation for macOS, notch style — whisper.cpp (Metal) STT + local-LLM cleanup, pasted at the cursor. Fully on-device.

2

stars

22

commits

Swift

primary language

Sep 9, 2026

updated

dictation
local-first
macos
menubar-app
ollama
privacy
speech-to-text
swift
transcription
voice-to-text
whisper-cpp
Browse cluster: Whisper Speech Recognition & Deployment

README

WhisperWhy logo

WhisperWhy

Local-first dictation for macOS, notch style.
Press your hotkey combo, speak, press again — cleaned-up text lands at your cursor.
No audio, transcript, or text ever leaves the machine.

macOS 14+ Swift 5.9 whisper.cpp LLM cleanup License: MIT

A free, fully-local take on Wispr Flow / FreeFlow with a top-of-screen notch pill: a compact animated logo + "WhisperWhy" wordmark pinned at the top-center of your display.

Press your configurable hotkey combo (default ⌘⇧Space, record any modifier+key in Settings) anywhere in macOS — or click the notch logo — speak, press again to stop. Your words are transcribed on-device by whisper.cpp (Metal), cleaned up by a local LLM (Ollama by default — fillers removed, grammar fixed, intent formatted), and pasted into whatever text field the cursor is in. The notch never shows the transcript — it just animates a checkmark when the paste lands.


Install (one line)

curl -fsSL https://raw.githubusercontent.com/ankurCES/whisperWhy/main/install.sh | bash

This checks prerequisites (installs cmake via Homebrew if missing), clones the repo to ~/.whisperwhy, builds vendored whisper.cpp with Metal, downloads a whisper model (~148 MB), builds and signs WhisperWhy.app, installs it to /Applications, and pulls llama3.2:3b if Ollama is running.

Overrides: WW_DIR=… (checkout dir) · WW_MODEL=small.en (whisper model) · WW_NO_OLLAMA=1 · WW_NO_BREW=1.

Then launch it:

open /Applications/WhisperWhy.app

Manual build

Requirements: macOS 14+, Xcode or CLT, CMake (brew install cmake).

git clone https://github.com/ankurCES/whisperWhy.git
cd whisperWhy
make whisper      # clone + build vendored whisper.cpp (Metal on)
make model        # download ggml-base.en (~148 MB) into models/
make              # swiftc → build/WhisperWhy.app (ad-hoc signed)
make install      # copy to /Applications
make run          # launch from build/

Other targets: make smoke (transcribe a bundled sample through the real model, no GUI), make test (unit tests), make typecheck, make model MODEL=small.en, make uninstall.

Permissions

macOS will ask on first use — all are required for the full pipeline:

PermissionWhy
MicrophoneDictation capture
AccessibilityPaste the final text at the focused cursor
Input MonitoringGlobal hotkey-combo tap (click-to-dictate works without it)
Speech RecognitionOnly if you switch to the Apple Speech engine

Use it

  1. Put the cursor in any text field.
  2. Press your hotkey combo (or click the notch logo) and speak — the pill opens with a live equalizer and timer. Press the combo (or click the logo again) to stop; Esc cancels.
  3. The pill animates transcribing → cleaning up, draws a checkmark, and the cleaned text is pasted. The transcript is never displayed.

The tray icon opens Settings: STT engine (whisper.cpp or Apple Speech), whisper model path/language, LLM endpoint + model, cleanup toggle, custom system prompt, hotkey combo recorder, and a Request Microphone Permission button with live status.

Configure

Ollama is the default cleanup provider (http://localhost:11434, llama3.2:3b — any model works):

brew install ollama && ollama serve &
ollama pull llama3.2:3b

Point the base URL at any OpenAI-compatible server (/v1 is appended automatically) — Ollama, LM Studio, llama.cpp server, Groq, OpenAI. Disable cleanup entirely in Settings to paste raw whisper output.

Features

Local STTwhisper.cpp (ggml models, Metal accelerated) or Apple on-device Speech
LLM cleanupFiller removal, grammar, punctuation via any OpenAI-compatible endpoint
Paste anywhereSynthetic ⌘V at the focused cursor; clipboard snapshotted + restored; transient pasteboard markers keep clipboard managers from recording dictation
HotkeyConfigurable modifier+key combo (record in Settings); press to start, press again to stop; Esc cancels
Notch UIAnimated logo + "WhisperWhy" wordmark; click the logo to dictate. Recording → live equalizer + timer; processing → traveling wave + rotating status words; done → animated checkmark; transcript never shown
Tray iconStatus-item menu: Settings, model download, quit
Keyboard-layout aware⌘V resolves the V key via the current input source (non-ANSI layouts work)

Architecture

Sources/
  App.swift                  @main SwiftUI shim
  AppDelegate.swift          tray menu, wiring, lifetime
  HotkeyManager.swift        CGEvent tap: press-to-toggle combo, Esc cancel
  AudioRecorder.swift        AVAudioEngine → 16 kHz mono PCM WAV
  WhisperSTT.swift           whisper.cpp C interop (module map, Metal)
  AppleSpeechService.swift   on-device SFSpeechRecognizer fallback
  LLMCleanupService.swift    OpenAI-compatible /chat/completions cleanup
  TranscriptCore.swift       pure: finalize text, WAV decode (unit-tested)
  PasteService.swift         clipboard snapshot → ⌘V → restore
  DictationController.swift  pipeline orchestration
  NotchPanel.swift           borderless non-activating NSPanel
  NotchWindowController.swift top-center placement, state sizing
  NotchViewModel/RootView    pill states + SwiftUI chrome
  SettingsStore/View         UserDefaults-backed settings + SwiftUI form

Pipeline: hotkey → record → WAV → whisper → LLM cleanup → pasteboard → ⌘V. make smoke proves the STT half without a GUI; make test covers the pure cores; an Ollama round-trip proves the cleanup half.

Roadmap

  • Launch-at-login wiring (setting is stored; SMAppService hookup pending)
  • Multi-display placement (currently follows NSScreen.main)
  • Optional streaming/partial transcripts
  • Signed + notarized release builds

Attribution

Design ideas and mechanisms borrowed with gratitude from FreeFlow (event-tap hotkeys, paste pipeline, transient pasteboard markers, keyboard-layout key resolution) and codenotch (non-activating notch panel, top-center placement, status item). STT by whisper.cpp. Logo generated programmatically (AppKit).

License

MIT

Contributors

luminordagent

22 commits

ankurCES/whisperWhy

Local-first dictation for macOS, notch style — whisper.cpp (Metal) STT + local-LLM cleanup, pasted at the cursor. Fully on-device.

2

stars

22

commits

Swift

primary language

Sep 9, 2026

updated

dictation
local-first
macos
menubar-app
ollama
privacy
speech-to-text
swift
transcription
voice-to-text
whisper-cpp
Browse cluster: Whisper Speech Recognition & Deployment

README

WhisperWhy logo

WhisperWhy

Local-first dictation for macOS, notch style.
Press your hotkey combo, speak, press again — cleaned-up text lands at your cursor.
No audio, transcript, or text ever leaves the machine.

macOS 14+ Swift 5.9 whisper.cpp LLM cleanup License: MIT

A free, fully-local take on Wispr Flow / FreeFlow with a top-of-screen notch pill: a compact animated logo + "WhisperWhy" wordmark pinned at the top-center of your display.

Press your configurable hotkey combo (default ⌘⇧Space, record any modifier+key in Settings) anywhere in macOS — or click the notch logo — speak, press again to stop. Your words are transcribed on-device by whisper.cpp (Metal), cleaned up by a local LLM (Ollama by default — fillers removed, grammar fixed, intent formatted), and pasted into whatever text field the cursor is in. The notch never shows the transcript — it just animates a checkmark when the paste lands.


Install (one line)

curl -fsSL https://raw.githubusercontent.com/ankurCES/whisperWhy/main/install.sh | bash

This checks prerequisites (installs cmake via Homebrew if missing), clones the repo to ~/.whisperwhy, builds vendored whisper.cpp with Metal, downloads a whisper model (~148 MB), builds and signs WhisperWhy.app, installs it to /Applications, and pulls llama3.2:3b if Ollama is running.

Overrides: WW_DIR=… (checkout dir) · WW_MODEL=small.en (whisper model) · WW_NO_OLLAMA=1 · WW_NO_BREW=1.

Then launch it:

open /Applications/WhisperWhy.app

Manual build

Requirements: macOS 14+, Xcode or CLT, CMake (brew install cmake).

git clone https://github.com/ankurCES/whisperWhy.git
cd whisperWhy
make whisper      # clone + build vendored whisper.cpp (Metal on)
make model        # download ggml-base.en (~148 MB) into models/
make              # swiftc → build/WhisperWhy.app (ad-hoc signed)
make install      # copy to /Applications
make run          # launch from build/

Other targets: make smoke (transcribe a bundled sample through the real model, no GUI), make test (unit tests), make typecheck, make model MODEL=small.en, make uninstall.

Permissions

macOS will ask on first use — all are required for the full pipeline:

PermissionWhy
MicrophoneDictation capture
AccessibilityPaste the final text at the focused cursor
Input MonitoringGlobal hotkey-combo tap (click-to-dictate works without it)
Speech RecognitionOnly if you switch to the Apple Speech engine

Use it

  1. Put the cursor in any text field.
  2. Press your hotkey combo (or click the notch logo) and speak — the pill opens with a live equalizer and timer. Press the combo (or click the logo again) to stop; Esc cancels.
  3. The pill animates transcribing → cleaning up, draws a checkmark, and the cleaned text is pasted. The transcript is never displayed.

The tray icon opens Settings: STT engine (whisper.cpp or Apple Speech), whisper model path/language, LLM endpoint + model, cleanup toggle, custom system prompt, hotkey combo recorder, and a Request Microphone Permission button with live status.

Configure

Ollama is the default cleanup provider (http://localhost:11434, llama3.2:3b — any model works):

brew install ollama && ollama serve &
ollama pull llama3.2:3b

Point the base URL at any OpenAI-compatible server (/v1 is appended automatically) — Ollama, LM Studio, llama.cpp server, Groq, OpenAI. Disable cleanup entirely in Settings to paste raw whisper output.

Features

Local STTwhisper.cpp (ggml models, Metal accelerated) or Apple on-device Speech
LLM cleanupFiller removal, grammar, punctuation via any OpenAI-compatible endpoint
Paste anywhereSynthetic ⌘V at the focused cursor; clipboard snapshotted + restored; transient pasteboard markers keep clipboard managers from recording dictation
HotkeyConfigurable modifier+key combo (record in Settings); press to start, press again to stop; Esc cancels
Notch UIAnimated logo + "WhisperWhy" wordmark; click the logo to dictate. Recording → live equalizer + timer; processing → traveling wave + rotating status words; done → animated checkmark; transcript never shown
Tray iconStatus-item menu: Settings, model download, quit
Keyboard-layout aware⌘V resolves the V key via the current input source (non-ANSI layouts work)

Architecture

Sources/
  App.swift                  @main SwiftUI shim
  AppDelegate.swift          tray menu, wiring, lifetime
  HotkeyManager.swift        CGEvent tap: press-to-toggle combo, Esc cancel
  AudioRecorder.swift        AVAudioEngine → 16 kHz mono PCM WAV
  WhisperSTT.swift           whisper.cpp C interop (module map, Metal)
  AppleSpeechService.swift   on-device SFSpeechRecognizer fallback
  LLMCleanupService.swift    OpenAI-compatible /chat/completions cleanup
  TranscriptCore.swift       pure: finalize text, WAV decode (unit-tested)
  PasteService.swift         clipboard snapshot → ⌘V → restore
  DictationController.swift  pipeline orchestration
  NotchPanel.swift           borderless non-activating NSPanel
  NotchWindowController.swift top-center placement, state sizing
  NotchViewModel/RootView    pill states + SwiftUI chrome
  SettingsStore/View         UserDefaults-backed settings + SwiftUI form

Pipeline: hotkey → record → WAV → whisper → LLM cleanup → pasteboard → ⌘V. make smoke proves the STT half without a GUI; make test covers the pure cores; an Ollama round-trip proves the cleanup half.

Roadmap

  • Launch-at-login wiring (setting is stored; SMAppService hookup pending)
  • Multi-display placement (currently follows NSScreen.main)
  • Optional streaming/partial transcripts
  • Signed + notarized release builds

Attribution

Design ideas and mechanisms borrowed with gratitude from FreeFlow (event-tap hotkeys, paste pipeline, transient pasteboard markers, keyboard-layout key resolution) and codenotch (non-activating notch panel, top-center placement, status item). STT by whisper.cpp. Logo generated programmatically (AppKit).

License

MIT

Contributors

luminordagent

22 commits

Languages

Swift

88.8%

Makefile

6.5%

Shell

4.8%