Skip to content

Порт под macOS (Apple Silicon), горячие клавиши для Mac, тип интервью QA - #2

Open
sheniatskii wants to merge 10 commits into
Magerko:mainfrom
sheniatskii:feat/macos-port
Open

sheniatskii wants to merge 10 commits into
Magerko:mainfrom
sheniatskii:feat/macos-port

Conversation

@sheniatskii

Copy link
Copy Markdown

Что сделано

Порт под macOS (Apple Silicon), Windows-сборка не меняется

  • Распознавание: на darwin не скачиваю Windows zip и не вызываю tar.exe. whisper-server ищется в локальной Metal-сборке (<userData>/asr/metal), в PATH, /opt/homebrew/bin и /usr/local/bin. Если его нет, UI подсказывает brew install whisper-cpp; для сборки с Metal добавлен scripts/build-whisper-mac.sh. На Mac убран вариант CUDA.
  • Защита окон от захвата: displayProtectionSupported() возвращает true на darwin (NSWindowSharingNone). В UI это по-прежнему подано как «не гарантия».
  • Системный звук и разрешения: audio: 'loopback' работает на macOS в Electron 45 без флагов. Проверено вручную: при выданном разрешении приходит дорожка System audio:live с реальным сигналом. Микрофон запрашивается через askForMediaAccess. Без «Запись экрана и системного аудио» UI показывает понятную причину и кнопки, которые открывают нужный раздел System Settings. getSources() больше не зависает при ошибке.
  • PDF: «DOMMatrix is not defined». pdfjs вызывает new DOMMatrix() при загрузке модуля, а полифил берёт из @napi-rs/canvas, нативный бинарник которого есть только для ОС, где делали npm install. Теперь, если canvas не грузится, подставляется заглушка: для извлечения текста этого хватает. @napi-rs/canvas стал прямой зависимостью и распаковывается из asar.
  • package.json: target dmg arm64, скрипт dist:mac, hardened runtime + entitlements (audio-input), в Info.plist добавлены NSMicrophoneUsageDescription, NSScreenCaptureUsageDescription и NSAudioCaptureUsageDescription.
  • Тексты UI: упоминания DPAPI/Windows на macOS заменены на нейтральные («Связка ключей», NSWindowSharingNone, правильный путь к данным).

Горячие клавиши на macOS

  • Сочетания показываются символами ⌃⌥H, ⌃⌥↩, ⌃⌥⌫; на Windows всё как раньше.
  • Запись сочетания читает физическую клавишу (e.code): Option+H больше не записывается как «˙», а на кириллической раскладке записывается латиница (это исправление действует и на Windows). ⌘ записывается как Command.
  • Сочетания по умолчанию остаются ⌃⌥: на macOS это обычная схема для глобальных клавиш утилит, а ⌘⌥H и подобные заняты системой и браузерами.

Тип интервью «QA / тестирование»

Новый пресет профиля с подсказкой для модели: тест-дизайн, пирамида тестов, баг-репорты, API- и UI-автоматизация, SQL, CI, flaky-тесты.

Проверка

  • npm run typecheck: без ошибок
  • npm test: 113 тестов проходят (новые: mac-port, pdf-fallback, keys)
  • npm run dev на macOS 27 (Apple Silicon): приложение запускается, системный звук захватывается
  • Не проверено: сборка и установка .dmg, Windows-сборка на реальной машине

Заметка для разработки на Mac

macOS проверяет разрешение на запись экрана у процесса, который запустил Electron. Поэтому при npm run dev из Terminal, iTerm или VS Code разрешение нужно выдать этому терминалу или IDE. У собранного .dmg такой проблемы нет: Copilot запросит разрешение от своего имени.

🤖 Generated with Claude Code

DenysShcheniatskyi and others added 9 commits October 31, 2026 15:19
- ASR: на darwin ищу whisper-server в локальной Metal-сборке, PATH и Homebrew
  вместо Windows zip/tar.exe; подсказка brew install whisper-cpp в UI,
  scripts/build-whisper-mac.sh для сборки с Metal
- Защита окон от захвата включена на darwin (NSWindowSharingNone)
- Разрешения macOS: микрофон через askForMediaAccess, понятная ошибка и
  кнопки в настройках при отсутствии «Запись экрана и системного аудио»;
  getSources больше не зависает при отказе
- PDF: заглушка DOMMatrix, если @napi-rs/canvas не грузится на целевой ОС
- package.json: dmg arm64, dist:mac, hardened runtime + entitlements,
  NSMicrophone/NSScreenCapture/NSAudioCaptureUsageDescription
- Тексты UI без DPAPI/Windows на macOS

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- pretty() показывает «⌃⌥H» на macOS и «Ctrl + Alt + H» на Windows (lib/keys.ts)
- запись сочетания читает физическую клавишу (e.code): Option+H больше не даёт «˙»,
  кириллическая раскладка записывает латиницу; ⌘ записывается как Command
- README: колонка macOS в таблице горячих клавиш

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Новый пресет профиля с подсказкой для модели: тест-дизайн, пирамида тестов,
баг-репорты, API и UI-автоматизация, SQL, CI, flaky-тесты.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… размер окна

- Новый вид: панель с «Ответить / Снимок / Подробнее» и их клавишами, таймер
  сессии, «Стоп»; ряд последних фраз (клик — ответ на фразу); карточка с
  «Вопрос:» / «Ответ:», переключателем авто-ответа и «Очистить»
- Исправлен размер шрифта: --fs на body перекрывал значение из настроек
- Исправлена прозрачность: смена темы больше не делает окно непрозрачным
- Настройки ширины и высоты окна (overlay.size); ручное изменение размера
  сохраняется, компактный режим растёт под ответ до заданной высоты
- AppSnapshot.startedAt для таймера; язык оверлея ставится до рендера

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- LSUIElement в Info.plist: собранное приложение стартует как агент, виден
  только значок в строке меню
- Настройка window.hideFromDock (по умолчанию включена) и переключатель
  «Скрывать из Dock и ⌘Tab»; при выключении значок возвращается в Dock
- showDashboard выводит окно вперёд через app.focus, раз Dock не помогает
- mac.identity "-": ad-hoc подпись всего бандла (идентификатор app.copilot);
  без неё подпись была сломана и macOS считала приложение повреждённым

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…и и кнопки источников звука

- Локализация uk/en всего интерфейса и сообщений main-процесса: общий словарь
  src/shared/i18n (≈510 ключей) с подстановками {name}, язык переключается
  сразу; тест на полноту словаря
- Снимок экрана: «Вопрос из разговора» (последние 2 минуты транскрипта),
  «Своё задание» (текст пользователя), «Решить самостоятельно» (только снимок);
  язык ответа по тексту пользователя или разговору; тег task экранируется
- Контекст из документов не зависит от языка: ядро профиля (шапка, summary,
  skills резюме, начало вакансии) всегда в промпте, по вопросам о себе — всё
  резюме; документы приоритетнее общих знаний
- Настройка «Как отвечать»: инструкции пользователя в системном промпте
- Оверлей: кнопки микрофона и звука компьютера (красные при захвате,
  перечёркнуты при выключении), переключаются во время сессии
- Журнал срабатываний горячих клавиш; отказ в записи экрана больше не падает

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, иконка в строке меню

- ASR: один запуск whisper-server за раз (два одновременных ensure() оставляли
  сироту и падали на «Cannot read properties of null (reading 'transcribe')»);
  смена модели во время старта останавливает старый сервер; распознавание
  берёт актуальный сервер после проверки речи; регрессионный тест
- Ответ и тезисы рендерят **жирный** и `код` (акцентный цвет в оверлее),
  незакрытые ** во время стриминга скрываются
- Снимок экрана: Enter в пустом поле — «Решить самостоятельно», без дубля кнопки,
  защита от двойного Enter
- macOS: монохромная template-иконка в строке меню вместо цветной плитки
- Уточнён текст о прогреве модели Large v3 Turbo

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Настройка «Формат подсказки»: готовый текст и тезисы либо опорные тезисы
  («часть: примеры», каждая с новой строки, заголовок выделен); тезисы на языке
  ответа с примером на этом же языке; в режиме опор сразу генерируется
  подробный ответ и показывается под ними
- Кнопка «Поставить под камеру»: окно 400×550 по центру сверху, шрифт 110%
- Быстрый ввод вопроса в оверлее (✎, ⌃⌥Q): оверлей берёт фокус только на время
  ввода и возвращает его
- «Ответить» без новой реплики собеседника берёт последнюю фразу пользователя,
  если она похожа на вопрос; после ответа вслух — переответ
- Оверлей: без иконок у вопроса и ответа, единый размер шрифта, вопрос длиннее
  10 слов сворачивается с «…» и раскрывается по клику

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…рминов и история ответов

- Gemini 3+: уровень размышлений minimal для Flash (Flash-Lite по умолчанию
  minimal, «low» делал её медленнее), иначе low, при отказе — без параметра;
  запас токенов под размышления; токены размышлений в стоимости; тестовая
  картинка 256 px
- Промпт: заметки — собственная подготовка пользователя, ответ строится из
  них, в том числе на теоретические вопросы; опоры на языке ответа
- Режим сессии запоминается на главной и используется оверлеем, треем, ⌃⌥L и
  быстрым вводом; режим виден в оверлее
- Термины словаря уходят в whisper как подсказка (переключатель), повтор
  подсказки на тишине отбрасывается
- Оверлей: вопрос — одна приглушённая строка, вкладки «Ответ / Предыдущие» с
  ответами на прошлые вопросы сессии; лишние ** в опорах игнорируются

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants