Продолжение истории с заменой Granola

Вернувшись из отпуска, завершил переезд JS->TS (ушло где то 35 PRs на это)

Я начал улучшать UI (это моё любимое), понравилось как оно стало улучшаться и тут уже разыгрался азарт! Решил, что нужно придумать название.

Gristmill – «meeting notes, milled fine»

Главная идея: артефакты митинга принадлежат вам и вы можете обрабатывать их любыми инструментами.

Помните мой фейл в авто, когда отвалился мобильный хотспот и Granola потеряла 20 минут речи собеседника?

В Gristmill архитектура построена ровно наоборот:
1. Запись локально. Микрофон и системное аудио пишутся в два раздельных трека (Ogg/Opus) нативно через Swift/FFmpeg. Едешь в лифте, переключаешь VPN, падает Wi-Fi — пофиг, звук пишется прямо на диск и никуда не пропадет.

2. Record then process. Никакого ненадежного стриминга на лету. После созвона нажал «Stop» — готовый звук уходит на транскрибацию и диаризацию.

3. Транскрипт и саммари — это всего лишь артефакты. Не понравился результат или модель затупила? Нажал одну кнопку и пересобрал транскрипт другой моделью (хоть Gemini, хоть Deepgram, ElevenLabs, OpenAI или локальным Whisper/Llama/Sherpa). А исходное аудио всегда у тебя под рукой. Я пока что пользуюсь Deepgram, мне хватает.

Ещё по фичам:

- Speaker labels

Это фича, которая соотносит распарсенных спикеров в аудиозаписи с участниками созвона.

Как это сделать? Расковырять Granola!

Именно расковырять, а не сделать реверс-инжениринг! Это важно! Иначе, можно словить письмо счастья от OpenAI))

Я сначала думал, что такие крутые чуваки как Granola парсят участников как то по умному и хитром, но оказалось, что у них есть просто парсилка интерфейсов, и при этом даже не любых, а только Zoom (работает через MacOS Accessibility API), Google Meet (работает через Google Chrome extension) и Microsoft Teams (слава богу мне это чудо инженерной мысли не нужно, так что я с ним не разбирался).

Короче, расковырял это и стащил себе. Добавил ещё поддержку Телемоста, так же через такой же Chrome Extension.

Теперь, приложение должно понимать, кто в какой момент какую фразу сказал.

- Чат
Для чата я решил, что хочу использовать имеющуюся охапку подписок – opencode go, clinepass, z.ai, codex.
Но как сделать это проще? Выход – bb
Я пользуюсь им уже около месяца, оч нравится.
Добавил в Gristmill поддержку bb очень быстро и теперь есть возможность использовать любой harness, в том числе и даже claude code!

- Внешний доступ
Для доступа агентов к материалам созвона я решил, что сделаю cli + skill и его будут использовать как внутренние агенты (через bb), так и любые внешние, получилось очень удобно!

Ещё топовая фича - нескучные обои цветовые схемы: добавил в настройках возможность переключать акцентные цвета.

По самым крутым фичам пока что всё, но вот что ещё агенты делали:

- Strict TypeScript + Zod везде
Полностью убрали нетипизированный IPC-ад между процессами Electron. Все вызовы строго валидируются через контракты.

- Переезд на Oxlint / Oxfmt
Линтинг и форматирование теперь летают за миллисекунды, агенты не спотыкаются о кривые конфиги. Тут кстати тоже очень много времени ушло - около 4 дней работы, 27 issues, +77k / -23k LOC. Но зато теперь у меня есть:
- архитектурные границы в каждом из модулей (бэк, UI, chrome extension и т. д.)
- дефолтные no any, as unknown as T и т. д.
- кастомные правила под проект
- и ещё куча других правил, которые я стащил откуда-то

Сегодня я делаю репозиторий публичным. 📱 Gristmill

❗️Тут ещё важно проговорить дисклеймер – продукт сырой, но я вычистил его настолько, чтобы мне самому было комфортно пользоваться. Тут всё ещё можно наткнуться на неприятные особенности, а всевозможные комбинации настроек я не использовал, так что не могу гарантировать идеальный результат.
Это мой первый опыт опенсорса, так что принимаю issues и PRs.

❓ И вот ещё думаю, стоит ли делать прямой эфир с обзором проекта и запилом какой-нибудь фичи прям в лайве? Что думаете?

Лайк, репост,
✔️ Тимур Хахалев про AI Coding, подписывайтесь!
Открыть в Telegram
 
 
Back to Top