Files
knowledge-base/decisions/2026-05-05-mac-dictation-groq-hammerspoon.md
dttb bf565f1392 mmfb/lionart-1c: SSH + фикс efsaveragent + накопленный backlog vault-а
Сегодня (mmfb / LionART 1C):
- projects/mmfb/lionart-1c.md — новый файл: VM 100 на pve LionART
  (WIN-70M2VEJIKEF, 10.253.1.240, Win Server 2022, 1С+SQL+Effector Saver),
  SSH-доступ claude/Kl@udeD1ag!2026 заведён, RDP под Администратор + 2FA.
- projects/mmfb/proxmox-inventory.md — hostname WIN-70M2VEJIKEF в VM 100.
- decisions/2026-05-28-mmfb-effector-saver-locked-admin.md — диагноз
  цикла 7038 (SCM-пароль разъехался с .\Администратор) + lockout учётки,
  и пошаговое решение (disable службы → ADSI unlock → LogonUser-проверка
  → sc.exe config password= → start auto).

Накопившийся backlog (без отдельной правки в эту сессию):
- decisions/: buzharovo (recon, migration-plan, 1c-licensing), sergey
  (instagram iPhone fakeip), amneziavpn macOS v1/v2 incompat, benelux
  compromise 2026-05-20, glavtorg autologon off, omni domain+update.
- projects/: benilux README, buzharovo README+server1c, dttb
  (nextcloud-talk-bot, npm-proxy-hosts, proxmox-inventory, vpn-clients),
  glavtorg, sergey README, projects/_index.
- claude-memory/: benelux, omniroute.
- snippets/mac-dictation/groq-dictate.sh.
- notes/claude/: ~80 авто-сохранённых транскриптов сессий за май.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 12:33:03 +03:00

6.9 KiB
Raw Permalink Blame History

2026-05-05 — Mac dictation: Hammerspoon + Groq Whisper

Контекст

Олег на Intel MacBook Pro (i9-9880H, 2019), нужна голосовая диктовка для русского. Все современные приложения (superwhisper PRO, VoiceInk, Spokenly Parakeet) либо требуют Apple Silicon, либо платную PRO-лицензию ($150-250). Бесплатный free-tier у superwhisper исчерпан и валидируется на их сервере (см. feedback_superwhisper_no_license).

Решение

Свой скрипт + Hammerspoon + Groq Whisper API:

  • Hammerspoon ловит глобальный hotkey ⌘⇧D
  • Bash скрипт toggle-режим: первый запуск → ffmpeg запись с микрофона; второй → стоп → POST в Groq → текст в /tmp/groq-dictate.last
  • Lua callback в Hammerspoon читает файл, кладёт в pasteboard, нажимает Cmd+V через hs.eventtap.keyStroke
  • Groq Whisper-large-v3-turbo — бесплатно ~14400 запросов/день, 0.5с на 4-сек запись, RU IP не блочится

Файлы

  • ~/bin/groq-dictate.sh — скрипт записи + Groq POST + fallback на whisper-cpp + write to /tmp/groq-dictate.last
  • ~/bin/dictation-doctor.sh — health-check всех компонентов (Hammerspoon / TCC / зависимости / Groq / mic / Fn-key); запускать когда «не работает»
  • ~/.hammerspoon/init.lua — Fn (одиночное нажатие) trigger через eventtap, paste через hs.eventtap.keyStroke
  • ~/.cache/whisper-cpp/ggml-tiny-q5_1.bin — 31MB локальная модель для offline fallback
  • Groq API key — в reference_groq_api.md private memory

Финальный hotkey

Fn (Globe) одиночное нажатие — toggle (старт/стоп). Срабатывает быстрее ⌘⇧D, освобождает руки. Apple Dictation на двойное Fn остаётся (если не отключить «Нажатие клавиши Fn» в System Settings → Keyboard).

Критические грабли (и фиксы)

  1. Hammerspoon Accessibility кеширует статус — после Enable в System Settings нужен killall Hammerspoon && open -a Hammerspoon, иначе Hammerspoon продолжает показывать WARNING и hotkey не работает.

  2. hs.hotkey.bind({"cmd","shift"}, "d", ...) на русской раскладке выдаёт warning key 'd' not found in active keymap; using ANSI-standard US keyboard layout as fallback, returning '2'. Решение: биндить по числовому keycodehs.hotkey.bind({"cmd","shift"}, 2, ...) (2 = физическая клавиша D). Так работает на любой раскладке.

  3. osascript -e 'tell application "System Events" to keystroke "v" using command down' на русской раскладке вместо Cmd+V вставляет UTF-8 байты текста как символы → получается мусор типа —В—ь—А—∞—ь—В? для строки «Ты меня слышишь?». Решение: никогда не использовать keystroke для paste. Использовать hs.eventtap.keyStroke({"cmd"}, "v") напрямую из Lua (отправляет настоящий low-level KeyDown event).

  4. Toggle через PID-файл/tmp/groq-dictate.pid. Если процесс упал/убит — удалить руками. Скрипт устойчив: kill -INT корректно закрывает .wav, ждёт до 0.5с дописать заголовок.

  5. ffmpeg avfoundation :0 = default mic. Если нужен другой — ffmpeg -f avfoundation -list_devices true -i "".

  6. PATH в Hammerspoon при автозапуске пустой — ffmpeg: command not found. Симптом: после перезагрузки Mac диктовка не работает, в логе command not found. Лечится export PATH="/usr/local/bin:/opt/homebrew/bin:/usr/bin:/bin:/usr/sbin:/sbin" в начале скрипта. ВАЖНО: doctor использует mой shell PATH и потому видит ffmpeg — НЕ показатель что Hammerspoon тоже видит. Проверять через env -i HOME=$HOME bash -c 'PATH=/usr/bin:/bin ~/bin/groq-dictate.sh'.

Стоимость

  • Hammerspoon бесплатный
  • Groq бесплатный (14400 req/day, ~120 минут диктовки в день — намного больше нужного)
  • Итого: 0₽

Альтернативы которые НЕ подошли

  • superwhisper — free tier 530 сек, потом сервер бракует
  • VoiceInk — официально Apple Silicon only, на Intel CPU крутит большую модель часами
  • Spokenlycdn.spokenly.app блокирует RU IP (3.8 KB/s), Parakeet требует Neural Engine
  • Wispr Flowdl.wisprflow.com блокирует RU IP, плюс $144/год Pro для регулярного использования
  • MacWhisper — $59 lifetime + не пробовали (всё уже работало бесплатно)
  • OpenWhispr — 273MB dmg в GitHub, не докачался

Связано

Воспроизведение на новом Mac

brew install --cask hammerspoon
brew install whisper-cpp jq ffmpeg
mkdir -p ~/bin ~/.hammerspoon ~/.cache/whisper-cpp

# скопировать ~/bin/groq-dictate.sh + ~/bin/dictation-doctor.sh → chmod +x
# скопировать ~/.hammerspoon/init.lua

# скачать локальную fallback-модель (31 MB, GitHub не блочит RU)
curl -sSL -o ~/.cache/whisper-cpp/ggml-tiny-q5_1.bin \
  "https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-tiny-q5_1.bin?download=true"

open -a Hammerspoon
# Hammerspoon Preferences → Enable Accessibility → System Settings → включить
killall Hammerspoon && open -a Hammerspoon  # ОБЯЗАТЕЛЬНО после grant — кеш

# System Settings → Клавиатура → Нажатие клавиши Fn → "Действие не требуется"
~/bin/dictation-doctor.sh  # должно быть всё зелёное

Готово. Fn → говори → Fn — текст вставится в активное окно.