Mac dictation: Hammerspoon + Groq Whisper решение
- decisions/2026-05-05-mac-dictation-groq-hammerspoon.md: полный план, грабли с раскладкой, fallback на whisper-cpp, восстановление на новом Mac - notes/ru-geoblocked-services.md: реестр CDN с RU-блоком (cdn.spokenly, dl.wisprflow и пр.) + принципы обхода - snippets/mac-dictation/: рабочая версия скриптов и init.lua Триггер — одиночный Fn, Groq cloud first → tiny local fallback, вставка через hs.eventtap.event keycode 9 (минует ru-keymap warnings). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
86
snippets/mac-dictation/dictation-doctor.sh
Executable file
86
snippets/mac-dictation/dictation-doctor.sh
Executable file
@@ -0,0 +1,86 @@
|
||||
#!/bin/bash
|
||||
# Health-check для голосовой диктовки. Запускать когда «не работает».
|
||||
# Проверяет: Hammerspoon, Accessibility, init.lua, скрипт, модели, Groq, ffmpeg, mic, Fn-key поведение
|
||||
|
||||
set +e
|
||||
GREEN="\033[32m"; RED="\033[31m"; YELLOW="\033[33m"; CYAN="\033[36m"; RST="\033[0m"
|
||||
ok() { echo -e "${GREEN}✅ $1${RST}"; }
|
||||
fail() { echo -e "${RED}❌ $1${RST}"; ((FAILS++)); }
|
||||
warn() { echo -e "${YELLOW}⚠️ $1${RST}"; }
|
||||
hdr() { echo -e "\n${CYAN}── $1 ──${RST}"; }
|
||||
FAILS=0
|
||||
|
||||
hdr "1. Hammerspoon"
|
||||
if pgrep -x Hammerspoon >/dev/null; then ok "Hammerspoon запущен (pid $(pgrep -x Hammerspoon))"
|
||||
else fail "Hammerspoon не запущен → open -a Hammerspoon"; fi
|
||||
|
||||
if [ -f ~/.hammerspoon/init.lua ]; then ok "init.lua на месте"
|
||||
else fail "~/.hammerspoon/init.lua отсутствует"; fi
|
||||
|
||||
hdr "2. Accessibility (TCC)"
|
||||
TCC=$(echo " " | sudo -S sqlite3 "/Library/Application Support/com.apple.TCC/TCC.db" \
|
||||
"SELECT auth_value FROM access WHERE service='kTCCServiceAccessibility' AND client='org.hammerspoon.Hammerspoon'" 2>/dev/null)
|
||||
case "$TCC" in
|
||||
2) ok "Hammerspoon Accessibility: ALLOWED" ;;
|
||||
0) fail "Hammerspoon Accessibility: DENIED → System Settings → Universal Access → включить" ;;
|
||||
"") fail "Hammerspoon в TCC отсутствует → System Settings → Universal Access → добавить и включить" ;;
|
||||
*) warn "Hammerspoon TCC: $TCC (странное значение)" ;;
|
||||
esac
|
||||
|
||||
hdr "3. Скрипт диктовки"
|
||||
if [ -x ~/bin/groq-dictate.sh ]; then ok "~/bin/groq-dictate.sh executable"
|
||||
else fail "~/bin/groq-dictate.sh отсутствует или не +x"; fi
|
||||
|
||||
hdr "4. Зависимости"
|
||||
for cmd in ffmpeg jq curl whisper-cli osascript; do
|
||||
if command -v "$cmd" >/dev/null; then ok "$cmd найден ($(command -v $cmd))"
|
||||
else fail "$cmd не установлен → brew install $cmd"; fi
|
||||
done
|
||||
|
||||
hdr "5. Модели"
|
||||
if [ -f "$HOME/.cache/whisper-cpp/ggml-tiny-q5_1.bin" ]; then
|
||||
SIZE=$(ls -lh "$HOME/.cache/whisper-cpp/ggml-tiny-q5_1.bin" | awk '{print $5}')
|
||||
ok "whisper-cpp tiny: $SIZE"
|
||||
else
|
||||
warn "локальная модель whisper-cpp отсутствует (fallback будет недоступен)"
|
||||
fi
|
||||
|
||||
hdr "6. Groq API"
|
||||
HTTP=$(curl -sS -o /tmp/_groq_test.json -w "%{http_code}" --max-time 10 \
|
||||
-H "Authorization: Bearer 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" \
|
||||
https://api.groq.com/openai/v1/models 2>/dev/null)
|
||||
case "$HTTP" in
|
||||
200) ok "Groq API отвечает (HTTP 200)" ;;
|
||||
401) fail "Groq: 401 — ключ невалиден или просрочен" ;;
|
||||
403) fail "Groq: 403 — доступ запрещён (возможно, RU IP заблокирован)" ;;
|
||||
429) warn "Groq: 429 — rate limit, подожди" ;;
|
||||
000) fail "Groq не отвечает (нет сети?)" ;;
|
||||
*) fail "Groq HTTP $HTTP" ;;
|
||||
esac
|
||||
rm -f /tmp/_groq_test.json
|
||||
|
||||
hdr "7. Микрофон"
|
||||
DEFAULT_MIC=$(system_profiler SPAudioDataType 2>/dev/null | awk '/Default Input Device: Yes/{found=1} found && /Input Source:/{print $3, $4, $5; exit}')
|
||||
[ -n "$DEFAULT_MIC" ] && ok "Default mic: $DEFAULT_MIC" || warn "Не удалось определить default mic"
|
||||
|
||||
hdr "8. Fn-key behavior"
|
||||
FN_PREF=$(defaults read com.apple.HIToolbox AppleFnUsageType 2>/dev/null)
|
||||
case "$FN_PREF" in
|
||||
0) ok "Fn = 'действие не требуется' (правильно)" ;;
|
||||
1) warn "Fn = 'переключает источник ввода' — конфликт с диктовкой" ;;
|
||||
2) warn "Fn = 'эмодзи панель' — конфликт" ;;
|
||||
3) warn "Fn = 'начинает Apple Dictation' — КОНФЛИКТ! Поменяй на 'Не требуется'" ;;
|
||||
*) warn "Fn behavior unknown: $FN_PREF" ;;
|
||||
esac
|
||||
|
||||
hdr "9. Лог последних попыток"
|
||||
[ -f /tmp/groq-dictate.log ] && tail -10 /tmp/groq-dictate.log || warn "Лог пуст"
|
||||
|
||||
echo
|
||||
if [ $FAILS -eq 0 ]; then
|
||||
echo -e "${GREEN}═══ Всё в порядке ═══${RST}"
|
||||
exit 0
|
||||
else
|
||||
echo -e "${RED}═══ Найдено проблем: $FAILS ═══${RST}"
|
||||
exit 1
|
||||
fi
|
||||
Reference in New Issue
Block a user