Rewrite selected text — or dictate by voice — anywhere on your Mac with a keyboard shortcut. Select text → press ⇧⌘R → Claude rewrites it and pastes it back in place. Or hit your dictation hotkey → speak → the transcription (optionally cleaned up by Claude) is pasted at your cursor. Rewriting uses the Anthropic (Claude) API by default, or an optional on-device model (no API key, fully offline); speech-to-text always runs 100% on-device with Whisper.
RewriteDB is an open-source reimagining of the (now abandoned) RewriteCmd app. It fixes the bug that broke the original: when using the Claude API, model IDs are no longer baked into the binary — the model list is fetched live from Anthropic, so it stays current automatically (retired models drop off and new ones appear with no app update). It also goes further than the original with an optional on-device model and voice dictation.
┌─────────────────┐ ⇧⌘R ┌────────────────┐ rewrite ┌────────────────────┐
│ Any macOS app │ ───────▶ │ RewriteDB │ ───────────▶ │ Claude API │
│ (selected text) │ ◀─────── │ (menu-bar app) │ ◀─────────── │ ·or· local model │
└─────────────────┘ paste └────────────────┘ result └────────────────────┘
- Features · Requirements · Install · First run · Usage
- How it works · Project structure · Build from source · Testing · Troubleshooting · Uninstall
- Contributing · Security · Releasing · License
- Global hotkey rewrite — works in any app (Mail, Slack, Notion, IDEs, browsers…).
- Local rewrite option (offline, no API key) — don't want to pay for the API? In Settings → Rewrite, set the primary provider to Local (on-device) and download a small model (Qwen3-4B-Instruct, Q4_K_M, ~2.5 GB) that runs entirely on your Mac via llama.cpp. Keep both configured and toggle anytime; the model loads on first use and unloads when idle to free memory.
- Automatic fallback — make Claude your primary and enable Fall back to the other provider; if Claude is unavailable (offline, rate-limited, or a server error) RewriteDB transparently rewrites with the local model instead, so a rewrite never just fails when you're offline.
- On-device voice dictation — press a hotkey, speak, and the transcription pastes at your cursor.
Powered by local Whisper (
large-v3-turbo) via whisper.cpp — audio never leaves your Mac. Three actions: Dictate (raw transcript), Dictate + Clean (transcript → Claude cleanup → paste), and the classic rewrite of selected text. - History — recover any past rewrite or dictation. Entries are badged by kind (Rewrite / Dictation / Dictation + Clean); copy the before, the after, or a transcript back to the clipboard. Local, newest 100.
- Bring your own Anthropic API key — stored in the macOS Keychain; only ever sent to
api.anthropic.com. - Live, self-updating model list — fetched from
GET /v1/models; pick any current model, no app update needed. - Unlimited custom instructions — each with its own name, system prompt, and global shortcut. Seeded with Auto Clean (⇧⌘R), Formal, Friendly, and Translate to English. No paywall.
- First-run onboarding wizard — a guided window takes a new user from install to working in about a minute: choose Claude / on-device / both, then grant access, add a key, and download models with every step verified live (Continue unlocks only once the check actually passes). Re-runnable from the menu ("Run Setup Again…").
- Animated menu-bar icon — a custom Equalizer waveform that reads at a glance: idle · listening (bars bounce) · working (shimmer) · setup-needed (pulse) · error. A template image, so it adapts to light/dark menu bars and inverts on highlight.
- Guided setup — the menu lists exactly what's missing — for rewriting and dictation — with one-click fixes; a consistent status badge shows readiness across every screen.
- In-app updates — Check for Updates… downloads and installs new signed releases (showing the release notes first); permissions carry across updates.
- Launch at login toggle.
- Native Swift + SwiftUI menu-bar app. No Dock icon. No telemetry.
To run the app (the recommended prebuilt install):
- An Apple Silicon Mac on macOS 13.3 (Ventura) or later — developed and used on macOS 15. (No Intel build.)
- An Anthropic API key for cloud rewriting and Dictate + Clean — optional if you only use the on-device rewrite model — https://console.anthropic.com/settings/keys.
- For local (offline) rewriting: a one-time ~2.5 GB on-device model download (in-app). No API key needed.
- For dictation: a microphone and a one-time ~1.6 GB Whisper model download (in-app).
No developer tools are needed to run RewriteDB. Building from source additionally needs Xcode Command Line Tools (full Xcode not required) — see Build from source.
This is how to get RewriteDB — most people should start here. Download the prebuilt, signed app; no toolchain, no building. Apple Silicon (arm64), macOS 13.3+.
- Download the latest
RewriteDB-vX.Y.Z.zipfrom the Releases page and unzip it. - Move RewriteDB.app to /Applications.
- RewriteDB is signed with a self-signed certificate but not notarized by Apple (it's free and
open-source, with no paid Apple Developer account), so macOS quarantines it after download. Clear
that once — in Terminal:
…or double-click it, dismiss the "can't be opened" dialog, then go to System Settings → Privacy & Security, scroll to Security, and click Open Anyway (admin password). (macOS Sequoia removed the old Control-click → Open shortcut.)
xattr -dr com.apple.quarantine /Applications/RewriteDB.app
- Launch it — the onboarding wizard walks you through setup (see First run).
Updates are automatic. RewriteDB checks for new releases and offers a one-click Check for Updates… (menu bar) that shows the release notes before installing — one click fetches and installs it for you, and because releases share a stable signing identity, your permissions carry over. (Optional: verify the download's SHA-256 against the release notes.)
Prefer to build it yourself? See Build from source — that path is for contributors and doesn't auto-update.
The easiest path: the onboarding wizard opens automatically on first launch and walks you through everything below — choosing a rewrite provider, granting Accessibility, adding a key and/or downloading models, and (optionally) setting up dictation — verifying each step as you go. You can reopen it anytime from the menu bar → Run Setup Again….
Prefer to do it manually? Equivalent steps:
- Grant Accessibility access. Click the menu-bar icon → Grant Accessibility access…, enable RewriteDB, then quit and relaunch. (Required to copy your selection and paste the result back.)
- Add your API key and pick a model. Menu bar → Settings… → Rewrite, paste your key, Save (this also fetches the model list), then pick a model. (Skip this if you'll only use the local rewrite model — see below.)
The menu-bar icon settles into its idle Equalizer state once Accessibility + a usable provider are set.
Optional — rewrite offline with no API key (Settings → Rewrite): set the primary provider to Local (on-device) and Download model (~2.5 GB, one time). Rewrites then run entirely on your Mac — no key, no network. Both providers can be set up at once; switch the primary anytime, or enable Fall back to the other provider to use the local model automatically whenever Claude is unavailable.
Optional — set up dictation (Settings → Dictation): (1) Download the Whisper model (~1.6 GB, on-device), (2) Grant Microphone access, (3) set a hotkey for Dictate and/or Dictate + Clean. Each step shows a ✓ when done, and the menu-bar icon only flags unfinished dictation setup once you've started (a rewrite-only user is never nagged).
Rewrite selected text:
- Select text in any app.
- Press ⇧⌘R (Auto Clean), or pick an instruction from the menu-bar icon.
- The selection is replaced in place with the rewrite — from Claude or the local model, whichever you've set as primary (the icon spins while it works).
Dictate by voice:
- Press your Dictate or Dictate + Clean hotkey (Settings → Dictation). The menu-bar icon pulses while listening.
- Speak, then press the hotkey again to stop. The icon spins while it transcribes on-device (and, for Dictate + Clean, runs the transcript through your rewrite provider — Claude or the local model).
- The text is pasted at your cursor.
Add, edit, reorder, and assign shortcuts to instructions under Settings → Instructions — unlimited, free. Recover any past rewrite or dictation from History (menu → History…).
| Concern | Implementation |
|---|---|
| App shell | SwiftUI MenuBarExtra (macOS 13+), LSUIElement (no Dock icon) |
| Global hotkey | KeyboardShortcuts (pinned to 1.15.0 — see note) |
| Capture / replace | Synthesize ⌘C to copy, run the rewrite (Claude API or on-device model), write result to the clipboard, synthesize ⌘V (then restore your clipboard) |
| API | Raw HTTPS via URLSession — POST /v1/messages, GET /v1/models, anthropic-version: 2023-06-01 |
| Local rewriting | Optional on-device Qwen3-4B-Instruct (Q4_K_M) via the prebuilt llama.cpp XCFramework — same CLT-friendly binary-target approach as Whisper (embedded Metal, no metal toolchain, GPU-accelerated); loads on first use, unloads when idle |
| API key storage | macOS Keychain (Security framework) |
| Settings persistence | UserDefaults (instructions, rewrite provider + fallback, selected model, cached model list, dictation prefs) |
| Launch at login | SMAppService.mainApp |
| Live permission status | Polls AXIsProcessTrusted() only while access is missing, then stops |
| Speech-to-text | Local Whisper (large-v3-turbo) via the prebuilt whisper.cpp XCFramework — a SwiftPM binary target with a precompiled Metal library, so it builds under CLT (no metal toolchain) yet is GPU-accelerated at runtime |
| Audio capture | AVAudioEngine → 16 kHz mono via AVAudioConverter; kept in memory only, never written to disk |
| On-device models | Downloaded once to Application Support (Whisper ~1.6 GB; local rewrite model ~2.5 GB); fully offline afterward. Both load lazily and unload after ~4 min idle |
| History | Before/after (or transcript) of each action as JSON in Application Support (newest 100) |
KeyboardShortcuts is pinned to 1.15.0 because newer versions use the SwiftUI
#Previewmacro, whose macro plugin ships only with full Xcode — soswift buildunder the Command Line Tools can't expand it. 1.15.0 is the newest release without#Previewand has the full API used here.
Sources/
RewriteDBKit/ # Pure, dependency-free logic (unit-tested)
Instruction.swift # instruction model + seeded defaults
AnthropicModel.swift # model decoding + default-model selection
AnthropicClient.swift # Messages/Models API client + pure parsing helpers
HistoryEntry.swift # history model (kind + before/after) with legacy-safe decode
RewriteProvider.swift # rewrite backend selector (Anthropic API | local on-device) + fallback order
RewritePrompt.swift # wraps to-rewrite text as inert data (so a dictated request is cleaned, not answered)
WordDiff.swift # pure word-level LCS diff for the History before/after view
RewriteDB/ # The menu-bar app (UI, permissions, hotkeys, dictation, local LLM)
RewriteDBApp.swift, AppState.swift
Services/ # Keychain, RewriteService, LaunchAtLogin, Accessibility, ShortcutsRegistry, HistoryStore,
# MicrophonePermissions, ModelStatus, WhisperEngine, WhisperModelStore, DictationService,
# LocalLLMEngine, LocalLLMModelStore (llama.cpp rewrite provider)
Views/ # MenuBarContent, HistoryView, WaveformIcon (animated menu-bar glyph),
# StatusBadge, OnboardingWizard, + Settings tabs (Rewrite / Instructions / Dictation / General)
RewriteDBTests/ # Dependency-free test runner (`swift run RewriteDBTests`)
Scripts/
setup-signing.sh # one-time: create local signing identity (dev builds)
setup-ci-signing.sh # one-time: provision the CI release-signing secrets
build-app.sh # build + bundle (embeds whisper.framework + llama.framework) + sign RewriteDB.app
run.sh # build if needed, then launch
Resources/Info.plist # LSUIElement, bundle id, version, microphone usage string
Most people don't need this — install the prebuilt app instead (it also auto-updates). This section is for hacking on RewriteDB. Source builds use a different signing identity than releases and do not receive in-app updates.
Needs Xcode Command Line Tools (xcode-select --install) — full Xcode is not required.
One-liner — clone, set up signing, build, and launch:
git clone https://github.com/danb235/rewritedb.git && cd rewritedb && ./Scripts/setup-signing.sh && ./Scripts/build-app.sh && ./Scripts/run.shOr step by step:
git clone https://github.com/danb235/rewritedb.git && cd rewritedb
./Scripts/setup-signing.sh # ONE TIME: local self-signed cert so permissions persist (see below)
./Scripts/build-app.sh # compiles + assembles RewriteDB.app (downloads deps on first run)
./Scripts/run.sh # launches it (builds first if needed)An Equalizer-waveform icon appears in your menu bar (no Dock icon); first launch opens the onboarding
wizard (see First run). You can also open Package.swift in Xcode if you have the full
IDE installed.
./Scripts/setup-signing.sh creates a local, self-signed code-signing certificate in your login
keychain (it never leaves your Mac; this is not notarization and needs no Apple Developer account).
It matters because macOS ties both the Accessibility grant and Keychain access to the app's exact
code signature. An ad-hoc signature (the default codesign --sign -) changes on every rebuild, so
each rebuild would silently revoke your permissions — the classic "the toggle is on but it still doesn't
work" symptom. A stable certificate fixes this permanently: the app's identity stays constant across
rebuilds, so you grant access once. (Your local dev identity is separate from the CI identity that
signs releases — so switching between a source build and an installed release re-grants once.)
The pure logic (models, default selection, API response parsing, error extraction, the rewrite-input
framing) is covered by a small dependency-free test runner — XCTest and swift-testing aren't fully
usable without full Xcode, so the tests run anywhere swift does:
swift run RewriteDBTestsIt exits non-zero on any failure, and runs on every push via GitHub Actions (CI).
- Hotkey does nothing. Make sure RewriteDB has Accessibility access (menu bar → Grant…), then
quit and relaunch — macOS only applies a new grant on relaunch. The menu-bar icon shows
⚠️ until it's ready. - Permissions look enabled but the app says they're missing (often right after an update or a rebuild).
macOS ties the grant to the app's code signature, so a signature change (e.g. a source build → an
installed release, or a rebuild without a stable cert) can leave a stale "on" toggle that no longer
applies. Toggle RewriteDB off then on in System Settings → Privacy & Security → Accessibility
(and Microphone), or reset and re-grant:
then quit and relaunch. Releases all share one identity, so update-to-update this won't recur. If it instead recurs on every source rebuild, you're building without a stable cert — run
tccutil reset Accessibility com.opensource.rewritedb tccutil reset Microphone com.opensource.rewritedb
./Scripts/setup-signing.shonce (see Build from source), rebuild, then reset and grant one final time. - "No text selected." Ensure text is actually selected and the app supports ⌘C/⌘V.
- Local rewrite says the model isn't installed. Settings → Rewrite → set primary to
Local (on-device) → Download model (~2.5 GB, one time). While it downloads, the menu-bar
⚠️ - "To rewrite text" checklist shows the step; switch the primary back to Anthropic API anytime.
- Dictation is greyed out / "Download speech model". Open Settings → Dictation and download the
Whisper model (~1.6 GB, one time). Dictation also needs Microphone access (Settings → Dictation →
Grant…) — the menu-bar
⚠️ + "To dictate" checklist point you to whatever's missing. - "RewriteDB can't be opened" (downloaded app). It's self-signed but not notarized. Clear the
quarantine flag —
xattr -dr com.apple.quarantine /Applications/RewriteDB.app— or open it once, then System Settings → Privacy & Security → Open Anyway. (Sequoia removed the Control-click → Open trick.)
- Quit RewriteDB (menu bar → Quit RewriteDB). If Launch at login is on, turn it off first (Settings → General) so no login item is left behind.
- Delete the app:
rm -rf /Applications/RewriteDB.app # …or wherever you keep it
That's all you need to stop using it. To also remove everything it stored — the on-device models (several GB), history, settings, cached data, and your saved API key:
rm -rf ~/Library/"Application Support"/RewriteDB # models (~4 GB) + history
rm -f ~/Library/Preferences/com.opensource.rewritedb.plist # settings, instructions, shortcuts
rm -rf ~/Library/Caches/com.opensource.rewritedb
rm -rf ~/Library/HTTPStorages/com.opensource.rewritedb
defaults delete com.opensource.rewritedb 2>/dev/null || true # UserDefaults (in case it's cached)
security delete-generic-password -s com.opensource.rewritedb 2>/dev/null || true # your Anthropic API keyThen revoke the macOS permission grants (removes the leftover RewriteDB rows from System Settings):
tccutil reset Accessibility com.opensource.rewritedb
tccutil reset Microphone com.opensource.rewritedbThat's the complete footprint — RewriteDB keeps no other state and sends no telemetry. (If you also ran
it from source with swift run, dev builds additionally use a RewriteDB UserDefaults domain:
defaults delete RewriteDB.)
Easiest: run the /release Claude Code skill (optionally
/release <x.y.z|patch|minor|major>). It curates the notes from every change since the last tag,
updates the CHANGELOG, shows a preview to approve, then pushes the tag and watches the workflow. Users
can then update in-app.
Or do it by hand:
- Move the relevant
## [Unreleased]items inCHANGELOG.mdinto a new## [X.Y.Z] - YYYY-MM-DDsection and commit. - Tag and push:
git tag vX.Y.Z && git push origin vX.Y.Z. .github/workflows/release.ymlruns the tests, builds + version-stampsRewriteDB.app, zips it, and publishes a GitHub Release whose notes are that CHANGELOG section (+ install steps + SHA-256).
One-time: stable release signing (recommended). So the in-app updater's grants persist across
updates (macOS ties Accessibility/Microphone to the signing identity), releases are signed with a
stable self-signed identity stored as repo secrets RDB_SIGNING_P12 (base64) and
RDB_SIGNING_PASSWORD. Provision (or later rotate) them with one command:
./Scripts/setup-ci-signing.sh # generates the CI "RewriteDB Self-Signed" identity + sets both secretsWithout these secrets the release still builds (ad-hoc signed) — but each update resets macOS
permissions, so users must re-grant. (Scripts/setup-signing.sh is the separate local identity for
your own build-app.sh dev builds; end users only ever see the CI identity above.)
Contributions are welcome — see CONTRIBUTING.md for how to build (Command Line Tools only), run the tests, and open a PR, and ARCHITECTURE.md for a tour of the code. By participating you agree to the Code of Conduct.
Your API key stays in the macOS Keychain and is only sent to Anthropic; dictation and local rewriting run entirely on-device; there's no telemetry. To report a vulnerability, see SECURITY.md.
Inspired by the original RewriteCmd (rewritecmd.com). This is an independent, open-source rebuild and is not affiliated with it.
MIT — see LICENSE.