English | 日本語
A menu-bar dictation app for macOS. Press a hotkey, talk, and the text lands at your cursor.
Built as a self-hosted replacement for paid dictation apps. Recognition runs on
Groq whisper-large-v3-turbo, whose free tier covers roughly
1,000 dictations per day — so day-to-day use costs nothing.
| Dictate | Hotkey to start, hotkey again to stop. The result is pasted at the cursor. |
| Cancel | Press Esc while recording or transcribing. The audio and the result are thrown away and nothing is pasted. |
| Nothing said, nothing pasted | Stop without saying anything and nothing is inserted. Silence and room noise are detected before the audio is sent, and Whisper's well-known made-up closings ("Thanks for watching") are dropped if they slip through. |
| Live caption | A panel at the bottom of the screen shows an input-level meter and what you are saying, as you say it. It keeps growing instead of scrolling away, so you can read back the whole utterance. |
| Edit by voice | Select text, press the edit hotkey, and say an instruction ("make this a list", "translate to English"). The selection is replaced with the result. |
| Paste again | If you dictated while nothing was focused, focus the right field and press the re-paste hotkey. |
| Settings window | Click a shortcut field and press the keys you want. Saving re-binds immediately — no restart. |
Japanese and English are detected automatically; no language switch to flip.
- The live caption never leaves your Mac. It uses Apple's on-device speech recognition purely for display. If a language cannot be recognised on-device, the caption is skipped rather than sending audio to a server. The text that actually gets pasted comes from Groq.
- The caption panel never takes keyboard focus. Paste targets the app you were typing in, so the panel is a non-activating, click-through window.
- Your clipboard is left alone. Dictated text is sent as keystrokes, not pasted, so it never
enters the clipboard and never fills up a clipboard manager like Clipy or Paste. The last result is
kept in the app, so the re-paste hotkey still works. Set
paste_via_clipboardif some app mangles the keystrokes and you want the old copy-and-⌘Vbehaviour back. - Pasting waits for your fingers. Synthesised keystrokes are merged with the modifier keys you
are physically holding, so firing them while
⌃⌘Vis still down delivers⌃⌘Vand types nothing. VoicePaste waits (briefly) for the modifiers to come up first. - Esc is borrowed, not taken. The cancel key is registered as a global hotkey only while a recording or a transcription is in flight, and released the moment it finishes. A modifier-less global hotkey held permanently would swallow Esc from every other app on the Mac.
SPEC.md documents the internals, including the failure modes above and how they were diagnosed.
It is written in Japanese.
Not yet — and honestly it would be a rewrite. If you want it, 👍 this issue (20 votes and I start), or comment there if you can help test on Windows (1 tester and I start immediately).
- macOS 13 or later (developed on macOS 26, Apple Silicon)
- Command Line Tools for Xcode (a full Xcode install is not required)
- A Groq API key — free at console.groq.com
git clone https://github.com/sasuumaker/voicepaste.git
cd voicepaste
./setup-signing.sh # once: creates a fixed self-signed certificate
./build.sh # produces build/VoicePaste.app
open build/VoicePaste.appThen open the menu-bar icon → 設定… (Settings) and paste your Groq API key.
setup-signing.sh exists because an ad-hoc signature changes on every rebuild, and macOS then treats
the app as a new one and drops its accessibility permission. A fixed certificate keeps the permission
across rebuilds. It creates its own keychain and never touches your login keychain.
Tick 「ログイン時に起動」 in the menu bar, or from a terminal:
./install-autostart.sh # register and start it now
./install-autostart.sh --uninstall # removeBoth do the same thing: they register a launchd user agent
(~/Library/LaunchAgents/com.sasuu.voicepaste.plist) that starts VoicePaste at login and restarts it
if it crashes. Quitting from the menu bar does not bring it back. The agent points at the app by
path, so rebuilding with build.sh keeps working.
The menu-bar switch only writes or removes that file, so it never disturbs the copy you are using — it takes effect from your next login. The script also loads it into launchd straight away.
| Permission | Used for | Without it |
|---|---|---|
| Microphone | Recording | Nothing is recorded |
| Accessibility | Sending keystrokes | Text falls back to the clipboard; paste manually |
| Speech Recognition | Live caption only | Recording and pasting work; the caption is skipped |
Settings live in ~/.config/voicepaste/config.json — outside the repository, so your API key is
never at risk of being committed. The settings window writes the same file.
{
"groq_api_key": "",
"model": "whisper-large-v3-turbo",
"hotkey_toggle": "cmd+slash",
"hotkey_paste_last": "ctrl+cmd+v",
"hotkey_edit": "ctrl+slash",
"cleanup_enabled": true,
"cleanup_model": "qwen/qwen3.8-27b",
"hud_enabled": true,
"live_caption_enabled": true,
"live_caption_locale": "ja-JP",
"paste_via_clipboard": false,
"input_device": "builtin"
}The key is read from groq_api_key first, then the GROQ_API_KEY environment variable.
cleanup_enabled runs the transcript through an LLM to add punctuation and drop fillers; turn it off
to paste exactly what Whisper heard. live_caption_locale only affects the on-screen caption — the
pasted text always comes from Whisper's own language detection. paste_via_clipboard is the escape
hatch back to copy-and-⌘V, for apps that do not accept synthesised keystrokes cleanly.
input_device picks the microphone: builtin (default — the Mac's built-in mic, even while AirPods are
connected, because AirPods mics hurt recognition accuracy), system (follow macOS's input setting), or a
device UID chosen from the Settings window.
Groq's free tier allows 2,000 transcription requests and 1,000 chat requests per day. One dictation uses one of each, so the chat limit is the binding one at roughly 1,000 dictations per day. Going over means requests are rejected, not billed.
On a paid plan the same usage is small: transcription is billed per hour of audio, and at around 30 dictations a day the total lands near a few tens of cents per month.
swift build
swift run VoicePasteTests # unit tests (no XCTest dependency; CLT-only environments)
swift run VoicePasteE2E # end-to-end, hits the real Groq API, needs a keyTests avoid XCTest so they run without a full Xcode install. The end-to-end test synthesises speech
with say, so the tricky paths (voice instructions, homophone mistakes) can be exercised without a
microphone.
MIT — see LICENSE.
English | 日本語
macOSのメニューバーに常駐する音声入力アプリです。ショートカットキーを押して喋ると、カーソル位置に文章が入ります。
有料の音声入力アプリを自作で置き換えるために作りました。認識は Groq の
whisper-large-v3-turbo を使います。無料枠だけで1日1,000回ほど喋れるので、日常的な利用では費用がかかりません。
| 音声入力 | ショートカットで開始、もう一度押して停止。カーソル位置に貼り付きます |
| 途中でやめる | 録音中・認識中に Esc を押すと、録った音も認識結果も捨てて、何も貼りません |
| 何も言わなければ何も貼らない | 何も言わずに止めると、何も入力されません。無音や部屋のノイズは送る前に見分け、すり抜けた「ご視聴ありがとうございました」のような決まり文句も捨てます |
| リアルタイム字幕 | 画面下のパネルに音量メーターと、喋っている内容がその場で出ます。流れて消えるのではなく溜まって伸びるので、話した全体を読み返せます |
| 音声で書き換え | 文章を選んで編集用のキーを押し、「これをリストにして」のように指示すると、選んだ部分が結果に置き換わります |
| もう一度貼る | どこにもフォーカスしていない状態で喋ってしまったとき、入れたい場所を選んでから押し直せます |
| 設定画面 | 欄をクリックして使いたいキーを押すだけ。保存すると再起動なしで切り替わります |
日本語と英語は自動で判別されるので、言語の切り替え操作は要りません。
- 字幕はMacの外に出ません。 画面表示にはApple内蔵のオンデバイス認識だけを使い、端末内で認識できない 言語のときは、サーバーへ音声を送らずに字幕を出さない判断をします。実際に貼り付ける文章はGroqが作ります
- 字幕パネルはキーボードのフォーカスを奪いません。 貼り付け先は「さっきまで入力していたアプリ」なので、 パネルは非アクティブ・クリック透過の窓にしてあります
- クリップボードには触りません。 認識した文章は貼り付けではなくキー入力として送るので、
クリップボードに入らず、ClipyやPasteのような履歴アプリが音声入力の結果で埋まりません。
直前の結果はアプリ内に持っているので、もう一度貼るキーはそのまま使えます。
文字が化けるアプリがあったときは
paste_via_clipboardで従来のコピー&⌘Vに戻せます - 貼り付けは指が離れるのを待ちます。 合成したキー入力は実際に押されているキーと合わさるため、
⌃⌘Vを押したまま送ると相手には⌃⌘Vとして届き、何も入りません - Escは借りるだけです。 取り消し用のEscを登録するのは録音中と認識中だけで、終わったらすぐ返します。 修飾キーなしのキーをずっと登録すると、他のアプリのEsc(ダイアログを閉じる等)まで横取りしてしまうためです
内部の詳細と、上記のような不具合をどう切り分けたかは SPEC.md に書いてあります。
- macOS 13以降(開発環境は macOS 26 / Apple Silicon)
- Xcodeのコマンドラインツール(Xcode本体は不要)
- Groq の APIキー(console.groq.com で無料)
git clone https://github.com/sasuumaker/voicepaste.git
cd voicepaste
./setup-signing.sh # 初回だけ: 固定の自己署名証明書を作る
./build.sh # build/VoicePaste.app ができる
open build/VoicePaste.appそのあとメニューバーのアイコン →「設定…」でGroqのAPIキーを入れてください。
setup-signing.sh があるのは、署名が毎回変わるとmacOSが別アプリとみなして、アクセシビリティの許可が
そのたびに外れるからです。固定の証明書を使うと、作り直しても許可が維持されます。専用のキーチェーンを
作るので、ログインキーチェーンには触れません。
メニューバーの「ログイン時に起動」にチェックを入れるか、ターミナルから:
./install-autostart.sh # 登録して、いますぐ起動する
./install-autostart.sh --uninstall # 解除するどちらも同じもので、launchd のユーザーエージェント
(~/Library/LaunchAgents/com.sasuu.voicepaste.plist)を登録します。ログインするたびに起動し、
異常終了したら立ち上がり直します。メニューバーから自分で終了したときは立ち上がりません。
アプリの場所を指しているだけなので、build.sh で作り直しても効き続けます。
メニューのチェックはこの登録ファイルを置く・消すだけなので、いま使っているVoicePasteには影響せず、 次回ログインから効きます。スクリプトのほうは、その場で launchd に読み込ませるところまでやります。
| 権限 | 用途 | 無いとどうなるか |
|---|---|---|
| マイク | 録音 | 何も録音されません |
| アクセシビリティ | キー入力の送信 | クリップボードに入るので、手動で貼れます |
| 音声認識 | リアルタイム字幕のみ | 録音と貼り付けは動き、字幕だけ出ません |
設定は ~/.config/voicepaste/config.json にあります。リポジトリの外なので、APIキーを
誤ってコミットする心配はありません。設定画面も同じファイルを書き換えます。
{
"groq_api_key": "",
"model": "whisper-large-v3-turbo",
"hotkey_toggle": "cmd+slash",
"hotkey_paste_last": "ctrl+cmd+v",
"hotkey_edit": "ctrl+slash",
"cleanup_enabled": true,
"cleanup_model": "qwen/qwen3.8-27b",
"hud_enabled": true,
"live_caption_enabled": true,
"live_caption_locale": "ja-JP",
"paste_via_clipboard": false,
"input_device": "builtin"
}APIキーは groq_api_key を先に見て、無ければ環境変数 GROQ_API_KEY を使います。
cleanup_enabled は、認識結果をLLMに通して句読点を補い、フィラーを除去する設定です。
オフにすると、認識したままの文章が貼られます。live_caption_locale は画面に出す字幕だけに効く設定で、
貼り付ける文章は常にWhisperの言語自動判定に従います。paste_via_clipboard は、キー入力をうまく
受け取れないアプリがあったときに、従来のコピー&⌘V へ戻すための逃げ道です。
input_device は録音に使うマイクです。builtin(既定。AirPodsをつないでいてもMacの内蔵マイクで録ります。AirPodsのマイクは認識精度が落ちるため)、system(macOSのサウンド設定に従う)、または設定画面で選んだ機器のUIDです。
Groqの無料枠は、認識が1日2,000回、整形が1日1,000回です。音声入力1回で両方を1回ずつ使うので、 厳しい方の整形側で 1日およそ1,000回 が上限になります。超えた場合は課金ではなく、 リクエストが一時的に弾かれるだけです。
有料プランでも金額は小さく、認識は音声1時間あたりの課金なので、1日30回ほど使う程度なら 月に数十セント規模に収まります。
swift build
swift run VoicePasteTests # ユニットテスト(XCTest非依存。CLTのみの環境向け)
swift run VoicePasteE2E # 実際のGroq APIを叩くE2Eテスト。APIキーが要りますXcode本体が無くても動くようにXCTestを使っていません。E2Eテストは say で音声を合成するので、
音声指示や同音異義語の誤変換といった厄介な経路を、マイクなしで検証できます。
MIT — LICENSE を参照してください。