Hold a key → speak → clean, punctuated text lands in whatever app you were typing in, in about a second. A native macOS dictation app: local or cloud transcription, LLM cleanup, and a recording HUD that lives in the notch.
Shriflow is push-to-talk dictation for your whole Mac, inspired by Wispr Flow (not affiliated). Hold Fn/Globe (or tap it to toggle), talk, release. Your speech is transcribed — on-device or in the cloud — then a fast LLM fixes grammar, punctuation, and filler words, and the result is pasted straight at your cursor: Chrome, Slack, VS Code, Terminal, anywhere. No text field focused? The transcript lands on your clipboard with a copy card instead. Secure/password fields are never touched.
Everything stays on your Mac: history and stats are local files, API keys live in the macOS Keychain, and with a local model the whole pipeline runs offline.
On a notched MacBook the recording indicator is a Dynamic-Island-style overlay: pure-black wings extend the camera housing, a small equalizer ripples while you speak, and errors or the copy-fallback card drop down below the notch. On external or non-notched displays it's a minimal dark pill at the bottom of the screen, Wispr-style. Either way it can never steal focus from the app you're dictating into (it's a non-activating panel by construction).
- Global push-to-talk — hold Fn/Globe to talk, quick-tap to toggle,
Escto cancel,⌥⇧Vre-pastes your last transcript. Every binding is rebindable with an in-app recorder. - Cloud transcription — Groq Whisper
large-v3-turboby default ($0.04/hr, ~228× realtime), plus OpenAI and Mistral. Bring your own key; keys are stored in the macOS Keychain. - Local transcription — whisper.cpp (Metal) with in-app model downloads (resumable, SHA-256 verified), or NVIDIA Parakeet via sherpa-onnx. Fully offline dictation.
- LLM cleanup — a fast model fixes grammar/punctuation and strips
"um, no wait, I mean" self-corrections. Default:
openai/gpt-oss-20bthrough the Vercel AI Gateway; Groq, Cerebras, and Gemini work too. Hard 1.2 s timeout — if the LLM is slow you get the raw transcript instead of waiting. - Offline fallback — if a cloud request fails and a local model is installed, it retries locally once.
- Smart injection — probes the focused element via Accessibility, pastes with clipboard save/restore (or types character-by-character where paste is hostile), and refuses secure fields.
- History + stats — day-grouped transcripts with copy/delete, total words, average WPM, and day streak. 100% local, one toggle to turn off or clear.
- Details — microphone picker, dictation start/stop sound themes, launch at login, menu-bar accessory mode, notch/pill placement setting.
- Honest failure states — if macOS revokes permissions (it does this after app updates/rebuilds), the app tells you with a banner and a fix-it button instead of dying silently.
Latency budget: ≤ 900 ms from key-release to pasted text for a ~10 s clip on the cloud path (finalize → upload+STT → LLM → inject, every stage timed).
- Native SDK (
vercel-labs/native) — Vercel's framework for real native apps. The UI is declarative.nativemarkup, the app logic is Zig, and it all compiles to a single native macOS binary. No Electron, no WebView, no JS runtime. - whisper.cpp (vendored, Metal + Accelerate) and sherpa-onnx (Parakeet) for on-device speech-to-text.
- Groq for cloud Whisper, and the Vercel AI Gateway for the cleanup LLM (one key, many models).
- Planned and built with Claude Code — the full phased execution plan the
agent fleet worked from is in
PLAN.md. - The macOS glue (CGEventTap hotkeys, AudioUnit mic capture, AX focus probe +
injection, the non-activating NSPanel HUD, Keychain) is hand-written
Zig/Obj-C in
src/platform/.
Requirements: an Apple Silicon Mac, Zig 0.16 (brew install zig), Xcode
command-line tools, and Node (for the Native SDK CLI).
git clone https://github.com/shrix1/shriflow.git
cd shriflow
# Native SDK CLI (pinned 0.4.1) — the repo reaches it via a committed symlink;
# recreate the symlink so it points at YOUR global install:
npm i -g @native-sdk/cli
ln -sfn "$(npm root -g)/@native-sdk/cli" vendor/native-sdk-cli
zig build # cloud-only build (fast)
zig build -Dlocal-stt=true # + whisper.cpp local engine (Metal)
zig build run # launchFirst launch opens an onboarding screen that walks you through the three macOS permissions (Microphone, Accessibility, Input Monitoring — the last two power the global hotkey and text injection). Then add a key in Settings (Groq for transcription, Vercel AI Gateway for cleanup — both have free tiers), or download a local model and skip the cloud entirely.
Install it like a real app:
./scripts/install.sh # build → package → /Applications/Shriflow.app
⚠️ The one macOS gotcha: TCC permissions are tied to the app's code signature. Ad-hoc dev builds get a new signature every rebuild, so macOS silently revokes Microphone/Accessibility/Input Monitoring — and every keyboard feature dies until you re-toggle them in System Settings. Shriflow shows a "Fix permissions" banner when this happens. To stop the churn, sign with a stable identity:SIGN_ID="Your Dev Cert" ./scripts/install.sh(details indocs/FIRST_RUN.mdandtests/platform-qa.md).
For the full first-run checklist see
docs/FIRST_RUN.md.
src/contracts.zig frozen cross-module contracts (types, Msg, command surface)
src/main.zig app root: Model, Msg, update(), the dictation pipeline
src/app.native declarative UI markup: main window, settings, onboarding
src/session.zig per-utterance state machine + engine bus
src/platform/ hotkeys, mic, AX focus/inject, permissions, notch/pill HUD
src/engines/ cloud STT + formatter clients, whisper.cpp, Parakeet, models
src/store/ settings JSON, Keychain keys, history JSONL + stats
PLAN.md the execution plan + decision log the agents built from
zig build # compile (ReleaseFast)
zig build test # unit tests
zig build run # launch
native check # markup + model-contract + manifest validation
native dev # hot-reload dev loop (edit src/app.native live)
zig build -Dautomation=true && ./zig-out/bin/shriflow & # automation-enabled run
./tests/ui_smoke.sh # boots the app and asserts every UI surface
./scripts/verify.sh # the full gate: check + tests + smoke
scripts/fetch-sherpa-onnx.sh # one-time: fetch the Parakeet runtimeMIT — see LICENSE. Vendored dependencies keep their own licenses (whisper.cpp MIT; Native SDK Apache-2.0). Not affiliated with Wispr.
