Steven
Steven5 мин. чтения

Четыре релиза за двадцать шесть часов: языковая сантехника и «bridge release»

GeekBye от v1.7.6 до v1.8.1: настройка языка, которая ни разу не покидала ноутбук, оверлей Cmd+/, показывающий твои настоящие горячие клавиши, версия без единого изменения в коде — и проблема курицы и яйца при миграции фида автообновлений.

Инженерия
Релизы
Десктоп
Релизы GeekBye
Четыре релиза за двадцать шесть часов: языковая сантехника и «bridge release»

Между утром четверга и вечером пятницы в феврале 2026 GeekBye выпустил четыре релиза: v1.7.6, v1.7.7, v1.8.0 и v1.8.1 — шестнадцать коммитов, около двадцати шести часов между первым тегом и последним. Ни один из них по отдельности не тянет на заголовок. Вместе они — портрет того, из чего на самом деле состоят недели мелких релизов: фича, наконец завершающая своё путешествие, оверлей для удобства, номер версии без единой строки кода внутри и один по-настоящему поучительный кусок release engineering.

Язык, который ни разу не покидал ноутбук

Настройка языка транскриптов есть в GeekBye с сентября 2025. Она работала — локально. Выбери испанский, и локальный пайплайн speech-to-text послушно транскрибировал испанский. Но прогрепай кодовую базу v1.7.5 на эту настройку — и найдёшь её ровно в трёх местах: в аудио-обработчике, в UI настроек и в хуке настроек. Не в API-клиенте. Не в трекере сессий. Четыре месяца каждый запрос, покидавший машину, был слеп к языку: записи сессий на бэкенде понятия не имели, какой язык они представляют, а AI-чат получал испанские транскрипты без единого намёка на то, что они испанские.

v1.7.6 — релиз, в котором настройка довершила своё путешествие: два коммита, один день. Старт аудиосессии теперь несёт transcriptLanguage в пейлоаде, а запрос stream-chat к AI получил то же поле, протянутое через маленький хелпер, который читает настройку и намеренно возвращает undefined, когда она равна auto или не задана, — чтобы старые бэкенды деградировали изящно, а не давились полем, которого не знают. В диффе прячется и тихий бонус-фикс: чтобы передать язык, старт сессии пришлось перенести после разрешения языка — что, как мы это читаем, заодно закрыло путь ошибки, в котором сессия могла стартовать (и засчитаться в лимиты), а мгновение спустя осиротеть, когда разрешение языка падало.

Урок обобщается: настройка не отгружена, когда у неё есть UI и эффект. Она отгружена, когда доходит до каждого потребителя, который должен о ней знать. Наша четыре месяца останавливалась на границе сети, и никто не заметил — потому что локальное поведение, то самое видимое, всё это время было корректным. (Для протокола: это был грубый первый заход на работу с языком; научить AI действительно отвечать на языке разговора — куда более поздняя глава этой истории.)

Cmd+/ — оверлей, который не врёт про твои горячие клавиши

Пользовательская фича v1.8.0 — оверлей горячих клавиш по Cmd+/ — 193 строки нового компонента и одно дизайн-решение, которое стоит украсть: он не рендерит захардкоженную шпаргалку. Он забирает живую конфигурацию шорткатов и рендерит customKeys || defaultKeys, так что пользователь, перемапивший клавиши, видит свои клавиши. Оверлей шорткатов, показывающий дефолты тому, кто их поменял, — это не документация; это дезинформация с приятной типографикой.

Остальное — мелкие штрихи корректности: оверлей позиционирует себя слева или справа от карточки приложения в зависимости от того, с какой стороны экрана есть место, и закрывается по Escape, по повторному Cmd+/ или по клику снаружи. Сам Cmd+/ вливается в ту же перенастраиваемую систему пресетов, что и любой другой шорткат, — и это важно, потому что Cmd+/ — это «toggle comment» (закомментировать) в большинстве редакторов, а инструмент для разработчиков не должен оккупировать редакторскую клавишу, которую нельзя переназначить.

«Bridge release» — мостовой релиз

Интересная инженерия случилась в номерах версий, на которые никто не взглянул бы дважды. v1.8.0 заодно мигрировал релизы проекта в новую организацию на GitHub — на поверхности организационная уборка, если бы не одно свойство десктопных автообновлений: URL фида зашит в бинарник. Каждая установка v1.8.0 опрашивает релизы новой организации. А каждая установка в дикой природе — все они v1.7.7 или старше — опрашивает старую, вечно, пока там что-нибудь не появится.

Вот она, курица и яйцо: опубликуй следующий релиз только в новом репозитории — и весь существующий флот его никогда не увидит. Через шестнадцать минут после тега v1.8.0 в релизном скрипте приземлился новый флаг: --publish-owner, который переписывает, куда electron-builder заливает артефакты после сборки — явно «не затрагивая скомпилированный код приложения», как формулирует комментарий в коде. В этом весь трюк, и это ровно правильный шов: зашитый в бинарник фид и место загрузки артефактов — два разных решения, и миграции нужно расцепить их на один релиз. Собери v1.8.1, нацеленный на новый фид, залей его в старый репозиторий; старые клиенты видят там обновление, ставят его и просыпаются, опрашивая новую организацию. Сообщение коммита называет это «bridge release» — мостовым релизом, — и это правильное имя. v1.8.1 затегировали через два часа двадцать минут после v1.8.0. (Историю о том, откуда у этого проекта уважение к автообновлениям, граничащее со страхом, читай в автообновлении, которое сделало наше приложение неубиваемым.)

А v1.7.7? Один коммит. Сам бамп версии. Ни фикса, ни реверта, ни объяснения в истории — наше лучшее прочтение: публикация, которую пришлось перезапустить, и мы предпочтём признать это, чем выдумывать историю. Иногда номер версии существует потому, что выпуск софта — процесс из реального мира с икотой из реального мира, а не чистая функция дерева исходников. А почему 1.7 вообще стал 1.8: ни один коммит не говорит, но миграция фида — вот содержательная граница совместимости: каждый бинарник 1.8.x смотрит на другую организацию, чем любой бинарник 1.7.x, — и это заслуживает минорного бампа больше, чем любая фича.

Три вещи, которым нас научила эта неделя

  1. Проследи настройку до каждого потребителя. Языковое предпочтение было «готово» четыре месяца, пока бэкенд оставался слеп. Именно корректность видимого, локального поведения и позволила разрыву выжить — аудиторский вопрос звучит как «кто ещё должен знать это значение?» и задаётся на каждой границе.
  2. Рендери живой конфиг, а не документацию. Оверлей шорткатов читает тот же источник истины, которым пользуется система шорткатов. Всё остальное разъезжается при первой же кастомизации пользователя.
  3. Миграции фида нужен один релиз, живущий в обоих мирах. Новый фид в бинарнике, старый репозиторий для загрузки. Если твой релизный тулинг не умеет разделять эти две цели — добавь флаг до того, как он понадобится; наш прибыл через шестнадцать минут после того, как понадобился, что достаточно близко, чтобы засчитать.

Про предыдущую главу истории v1 — страница логина и ЕСТЬ демо (v1.7.5); а про весь путь — анатомию доведения софта до совершенства.

Похожие статьи

Три глагола, что держат Web Audio живым
Steven
Steven8 мин. чтения

Три глагола, что держат Web Audio живым

Два точечных релиза GeekBye, разделённые двумя месяцами и в двух разных файлах, преподали нашему аудиокоду один и тот же урок с противоположных концов: перестань обращаться с браузерным AudioContext как с одноразовым. Один релиз научился делать resume() контексту, который macOS тихо приостановил посреди записи; другой научился suspend() вместо close(), чтобы идущие подряд сессии перестали врезаться в навязанный Chromium потолок примерно в шесть контекстов. Resume, suspend, close — вот и весь сюжет.

Инженерия
Аудио
Десктоп
Отличить звонок от открытого приложения
Steven
Steven8 мин. чтения

Отличить звонок от открытого приложения

GeekBye умеет заметить, что ты присоединился к видеовстрече, и предложить её записать. Обнаружение оказывается лёгкой половиной — нативный Swift-бинарник читает заголовки окон каждые десять секунд. Трудная половина — точность: не срабатывать, когда Zoom просто открыт, не предлагать записать встречу, которую ты уже записываешь, и не заглушать микрофон в звонке, в котором ты на самом деле сидишь. Три релиза, и каждый из них — предохранитель, которому пришлось научиться не побеждать самого себя.

Инженерия
macOS
Десктоп
Убираем backend с пути загрузки
Steven
Steven7 мин. чтения

Убираем backend с пути загрузки

GeekBye записывает твой экран и сохраняет видео в твой Google Drive. Первая версия прогоняла каждую запись через собственные серверы GeekBye по пути туда; релизом позже файл шёл прямо с твоей машины на Drive, а backend был понижен до хранения единственного указателя. Интересная часть в том, как мало кода на самом деле содержит «прямая, возобновляемая» версия — потому что возобновляемость пришла из удаления proxy, а не из его написания.

Инженерия
Архитектура
Десктоп