The Problem

Users on macOS need a fast, offline voice‑to‑text tool that integrates with the OS (menu bar, global shortcuts) without sending audio to the cloud. Existing solutions either rely on heavyweight cloud APIs or lack tight macOS UI integration, resulting in latency, privacy concerns, and poor user experience.

What This Does

VoiceInk is a native macOS app (requires macOS 14+) that captures microphone input, runs it through local AI transcription models, and inserts the resulting text wherever the cursor is positioned. The core logic lives in the VoiceInk/ source tree:

  • AppDelegate.swift – application entry point; registers menu bar UI (MenuBarManager.swift), global hotkeys (HotkeyManager.swift), and the recording pipeline.
  • CoreAudioRecorder.swift – low‑level audio capture using CoreAudio, feeds raw buffers to AudioFileProcessor.swift.
  • TranscriptionServiceRegistry.swift + concrete services (NativeAppleTranscriptionService.swift, CloudTranscription/*) – select and invoke the appropriate transcription backend.
  • Models/Transcription.swift & Models/TranscriptionModel.swift – data structures that travel from the service back to UI components (Views/Recorder/AudioVisualizerView.swift, Views/History/TranscriptionHistoryView.swift).

The UI layer (Views/*) is pure SwiftUI; it consumes the model objects and updates the menu bar popover, mini‑recorder window, or on‑screen overlay.

How It Is Wired

Execution starts in AppDelegate.swift (the @main entry). On applicationDidFinishLaunching it:

  1. Instantiates MenuBarManager → creates the menu bar icon and binds actions to MenuBarManager.showMiniRecorder.
  2. Starts HotkeyManager → registers global shortcuts that call Recorder.startRecording() (found in Recorder.swift).
  3. Recorder.startRecording creates a CoreAudioRecorder instance, which streams PCM frames to AudioFileProcessor.process(buffer:).
  4. The processor writes a temporary audio file and hands the file URL to TranscriptionServiceRegistry.shared.activeService.transcribe(url:).
  5. The selected service (default NativeAppleTranscriptionService) returns a Transcription model; Recorder posts this to NotificationCenter.
  6. UI observers in Views/Recorder/AudioVisualizerView.swift and Views/History/TranscriptionHistoryView.swift receive the notification and update the SwiftUI state, causing the text to appear in the active document via CursorPaster.swift.

All side‑effects (file writes, keychain access for API keys, user defaults) are confined to the Services/ layer. No circular import edges were detected; the import graph consists of a flat hierarchy of Swift files.

How To Use It

# Clone the repo
git clone https://github.com/moses-y/VoiceInk
cd VoiceInk

# Build with Xcode (project file included) or make
make          # invokes xcodebuild as defined in Makefile
open VoiceInk.xcodeproj

No additional configuration files are required. If you wish to use a cloud transcription provider, place the API key in the macOS Keychain; Services/APIKeyManager.swift reads it at runtime. Run the app from Xcode or the generated .app bundle; the menu bar icon appears, and the default global shortcut (⌥⌘R as defined in HotkeyManager.swift) starts/stops recording.

Real‑World Use

A technical writer installs VoiceInk, configures a shortcut, and activates the mini‑recorder while drafting a document. Each utterance is transcribed locally within seconds and injected at the cursor position, eliminating the need to switch to a separate dictation window. The writer can also enable “Power Mode” (PowerMode/PowerModeSessionManager.swift) to load per‑application prompts automatically when switching between IDE, email client, and word processor.

Code Health & Issues

  • HIGH – Deep nesting (59 occurrences, e.g., Models/CustomPrompt.swift, Notifications/AnnouncementView.swift). Indentation depth up to 11 makes control flow hard to follow.
  • HIGH – Duplicated code blocks (≈190 repeating 6‑line snippets across 44 files such as CoreAudioRecorder.swift, AudioDeviceManager.swift). Refactor into shared helpers.
  • HIGH – No test suite – repository contains 184 source files but no test files. Add unit/UI tests for each public API and integrate into CI.
  • HIGH – No CI pipeline – no GitHub Actions or other build automation. Add a workflow that runs make (or xcodebuild) on push and pull request.
  • Repository hygiene – tests present: no; CI: no; Dockerfile: no; licence: yes (GPL‑3.0); lockfile: no; committed secrets: none.

The Bottom Line

VoiceInk delivers a tightly integrated, offline voice‑to‑text experience for macOS, with a clear SwiftUI UI and modular service layer. However, the codebase suffers from deep nesting and duplicated snippets, and it lacks automated testing and CI. Engineers planning to extend or maintain the project should first address these hygiene gaps to reduce regression risk. Suitable for teams comfortable with native macOS development who need on‑device transcription with a customizable UI.