Dictator is a native macOS menu-bar app for dictation and screen-aware writing. Hold Fn to dictate, or hold Control-Option to speak an instruction that uses the focused window as context. Dictator inserts the result into the field that was focused when recording began; if no editable field was focused, it uses its private clipboard.
⚠️ Dictator is still in the early stages of development. Expect rough edges.
- Hold
Fn: record dictation - Hold
Control-Option: compose or transform text using the focused window Option-Command-V: paste the latest private-clipboard itemOption-Shift-Command-V: open the private clipboard
On macOS 26 and later, Apple On-Device is available without an API key and is the default for new installations. Its language model may require an initial download; after that, audio transcription stays on the Mac. SpeechTranscriber is preferred, with DictationTranscriber used when needed for the selected language or hardware.
Cloud speech-to-text adapters remain available: Groq, Cloudflare Workers AI, xAI, Deepgram, AssemblyAI, and Gladia. On macOS 14 and 15, these are the available speech providers and Groq remains the new-install default.
Optional cleanup adapters use BYOK credentials: Groq, Cloudflare Workers AI, Gemini, xAI, OpenRouter, and any OpenAI-compatible endpoint. Cleanup sends transcript text, never audio. When speech-to-text and cleanup use the same provider, Dictator reuses that provider credential unless you configure a separate cleanup credential. Keys are stored in macOS Keychain. Transcript history, vocabulary, styles, snippets, and private-clipboard data stay in local Application Support storage. Cloud recordings are sent to the selected speech provider and are not stored by Dictator after processing; the provider's own data-handling policy applies.
Screen Aware is a separate, disabled-by-default mode for composing or transforming text from the focused window. Hold Control-Option, speak an instruction, and release; Dictator transcribes the audio, captures only the focused window, and sends the image, spoken instruction, app and window details, and selected text when available to your selected vision-capable provider. Screen Aware supports Groq, Gemini, xAI, OpenRouter, and OpenAI-compatible endpoints. Focused-window images are never saved by Dictator; the selected provider's own data-handling policy applies.
Homebrew is the recommended installation method:
brew install --cask amalshaji/taps/dictatorDictator checks for updates once a day with Sparkle. It shows the release notes and always asks before installing. Automatic checks can be disabled under Settings → Updates, and Check for Updates… is also available from the app and menu-bar menus.
Stable updates are the default. Enable Receive canary updates under Settings → Updates to test early builds published after successful merges to main. Canary builds may be unstable. Disabling the setting keeps the installed build until a newer stable version is available; it does not downgrade the app.
Download Dictator-<version>-universal.dmg and SHA256SUMS.txt from the matching GitHub Release, then verify the download:
shasum -a 256 -c SHA256SUMS.txtOpen the DMG and drag Dictator to Applications. Release artifacts are Developer ID-signed and notarized by Apple, with the notarization ticket stapled to the DMG for Gatekeeper verification.
scripts/xcodegen.sh generate
xcodebuild -project Dictator.xcodeproj -scheme Dictator -configuration Debug -destination 'platform=macOS' build
xcodebuild -project Dictator.xcodeproj -scheme Dictator -configuration Debug -destination 'platform=macOS' testThe project wrapper downloads and checksum-verifies the repository-pinned XcodeGen version on first use.
Live integration tests read provider keys from .env and skip providers that are not configured. Every configured STT provider receives the same Tests/Fixtures/reference.wav input.
GROQ_API_KEY=
CLOUDFLARE_API_TOKEN=
CLOUDFLARE_ACCOUNT_ID=
XAI_API_KEY=
DEEPGRAM_API_KEY=
ASSEMBLYAI_API_KEY=
GLADIA_API_KEY=
GEMINI_API_KEY=
OPENROUTER_API_KEY=The app needs Microphone and Accessibility/Input Monitoring permission for recording, global shortcuts, focus detection, and insertion. Screen Recording permission is required only for Screen Aware.
Every successful CI run for a push to main publishes an immutable GitHub prerelease and adds it to the opt-in canary Sparkle channel. The latest ten canary releases and tags are retained. Canary releases never update Homebrew.
Stable releases remain review-gated:
- Manually run Build stable release from
mainand choosepatch,minor,major, orexplicit. When choosingexplicit, also enter the exact semantic version in theexplicit_versioninput. - The workflow validates the choice, creates a version-only release PR, and resolves the release identity from its candidate commit. If an earlier run already merged an unfinished version, the workflow safely reuses it instead of applying another bump.
- The workflow builds a Developer ID-signed universal app, notarizes and staples its DMG, then verifies and attests the DMG and checksum without creating a tag. Approve the generated release PR, review the completed preparation job, then approve its
stable-releaseenvironment deployment. - Finalization squash-merges the approved PR, proves the merged tree, version, and build match the verified artifacts, then creates the annotated
v<version>tag and public GitHub Release. It subsequently signs and deploys the Sparkle appcast and bootstraps or updatesCasks/dictator.rbinamalshaji/homebrew-taps.
Create a protected GitHub environment named stable-release with the repository owner as its required reviewer, self-review allowed, deployments restricted to main, and no secrets. A failed or expired preparation creates no tag; rerun the stable workflow with the same selection to reuse the open release PR or resume its merged version. If only update-channel publication fails after the release is public, repair it with the Publish update channels workflow and the same tag.
Configure a protected GitHub environment named release with:
APPLE_CERTIFICATE: the base64-encoded PKCS#12 (.p12) export containing the Developer ID Application certificate and private key.APPLE_CERTIFICATE_PASSWORD: the password used to protect the PKCS#12 export.APPLE_SIGNING_IDENTITY:Developer ID Application: Amal Shaji (6NJKY8HB47).APPLE_ID: the Apple Account used for notarization.APPLE_APP_SPECIFIC_PASSWORD: an app-specific password fornotarytool.APPLE_TEAM_ID:6NJKY8HB47.SPARKLE_PRIVATE_KEY: the private Ed25519 key whose public half is committed asSUPublicEDKey.HOMEBREW_TAP_TOKEN: a fine-grained token with Contents read/write access only toamalshaji/homebrew-taps.
Do not add required reviewers to the release environment if canaries must remain fully automatic.
Configure GitHub Pages to use GitHub Actions as its source. The publishing workflow keeps the signed feed on gh-pages for rollback and deploys that exact feed to https://amalshaji.github.io/dictator/appcast.xml with GitHub's Pages deployment action. Keep encrypted offline backups of both signing keys; losing the Sparkle private key prevents trusted key rotation for existing installations, while losing the Developer ID private key requires replacing the certificate and CI secret before another release can be signed.
