The Problem
Mac users who need offline, privacy‑preserving dictation must either rely on cloud services or on fragmented command‑line tools. Switching between local Whisper models, handling speaker diarisation, and exporting transcripts requires a bespoke UI and a secure storage path, which most existing utilities do not provide.
What This Does
Pindrop is a native macOS menu‑bar app that records audio, runs it through locally‑hosted WhisperKit (or optional cloud models), and writes the transcript to the clipboard or a searchable library.
- The launch flow starts in
Pindrop/AppCoordinator.swift, which builds the core services (AudioRecorder,StreamingSessionController,AIEnhancementService, etc.) and injects them into the SwiftUI hierarchy. Pindrop/Services/AudioRecorder.swiftmanages microphone permission and raw PCM capture.Pindrop/Services/StreamingSessionController.swiftstreams audio to WhisperKit and updates the UI in real time.- Post‑processing (grammar cleanup, speaker‑labeling) lives in
Pindrop/Services/AIEnhancementService.swift. - Transcription records are persisted via SwiftData models defined in
Pindrop/Models/TranscriptionRecordSchema.swift. - UI components under
Pindrop/UI/…render the menu‑bar icon, transcript list, and settings panels.
How It Is Wired
- Entry point – The Xcode project’s
@mainApp struct (generated by Xcode) instantiatesAppCoordinator. - Coordinator –
AppCoordinatorcreates singleton services and registers them with the SwiftUI environment. It also wires global hot‑keys (defined inPindrop/AppTestMode.swift). - Audio pipeline – When the user activates the hot‑key,
AudioRecorder.start()is called. It opens anAVAudioEngine, passes buffers toStreamingSessionController.startStreaming(), which forwards them to WhisperKit (viaWhisperKitSwiftPM package). - Transcription handling – WhisperKit returns incremental results;
StreamingSessionControllerpublishes them through a Combine publisher consumed by the UI. Once the session ends, the final transcript is stored via the SwiftData context (TranscriptionRecordSchema). - AI enhancement – If the user enables AI cleanup,
AIEnhancementService.enhance(transcript:)calls the selected endpoint (Apple Intelligence, Anthropic, OpenRouter, etc.) and writes the revised text back to the same record. - Persistence & export – The library view (
Pindraw/UI/Main/DictionaryPresentation.swift) reads from the SwiftData store, offers search, editing, and export (JSON/CSV) via helper functions inPindrop/Models/ExportHelpers.swift. - External effects – Clipboard writes are performed by
AppCoordinator.copyToClipboard(_:). No network activity occurs unless a cloud model or AI enhancement is selected; those calls are isolated inNetwork/…wrappers (not listed but referenced by the service files).
The internal import graph shows 5 modules with no circular dependencies, meaning each module imports only downstream utilities, keeping the blast radius limited to the coordinator and the service layer.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/pindrop.git
cd pindrop
# Open the Xcode project
open Pindrop.xcodeproj
# Build & run (⌘R) – the app appears as a menu‑bar icon.
No additional environment variables are required for the default offline mode. To enable cloud transcription or AI enhancement, add the appropriate API keys to the macOS Keychain via the Settings pane (UI driven, stored by KeychainService.swift).
Real‑World Use
A developer can bind a global hot‑key (configured in AppCoordinator) to start dictation while coding. As they speak, StreamingSessionController streams to WhisperKit, the live transcript appears in a floating overlay, and on completion the text is auto‑pasted into the active Xcode editor. The same workflow works in any macOS app that accepts clipboard input.
Code Health & Issues
Measured analysis (static)
- 46 High findings:
- Deep nesting (max depth 8) in
AppCoordinator.swift,AIEnhancementService.swift,AudioRecorder.swift. - Duplicated 6‑line blocks across 120 files (e.g., in
AppCoordinator.swift,StreamingSessionController.swift). - Oversized files (> 5 k lines) such as
AppCoordinator.swift,Generated/LocalizationMetadata.swift,Models/TranscriptionRecordSchema.swift. - 95 Medium, 0 Low – not listed individually.
Code‑health audit
- HIGH – Pin third‑party GitHub Actions to a commit SHA (
.github/workflows/*). - HIGH – No test suite despite 284 source files.
- MEDIUM – Declare least‑privilege
GITHUB_TOKENpermissions (.github/workflows/vercel-rebuild.yml). - MEDIUM – Move large binary (
Localization/Localizable.xcstrings, 5.8 MB) to Git LFS. - LOW – Add
timeout-minutesto workflow jobs (.github/workflows/ci.yml). - LOW – Add missing convention files (
.editorconfig,.gitattributes, formatter config).
The repo includes a license, CI (GitHub Actions), and contribution guidelines, but lacks Docker support, lockfiles, and a comprehensive test harness.
The Bottom Line
Pindrop delivers a fully native, offline dictation experience on macOS, with a clean SwiftUI UI and extensible AI enhancement hooks. The codebase is functional but suffers from high cognitive load, duplicated logic, and a lack of automated tests, which will increase maintenance risk for any team planning extensions. It is suitable for developers comfortable with Swift who need a private, on‑device transcription tool and are prepared to address the identified health concerns.