- 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>
87 lines
4.2 KiB
Bash
Executable File
87 lines
4.2 KiB
Bash
Executable File
#!/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
|