Ранняя pre-alpha. Corvo в активной разработке — возможны ошибки. Пока не полагайтесь на неё как на единственный почтовый клиент и храните резервные копии важной почты.

Что нового

0.7.22026-08-17

Добавлено

  • Кнопка «Собрать» в окне «Контакты» — пересобирает адресную книгу из всей

скачанной почты, не дожидаясь новых писем. Полезно после догрузки истории

или добавления ящика. Нажимать можно сколько угодно: счётчики частоты

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

0.7.12026-08-17

Исправлено

  • Адресная книга оставалась пустой. Контакты собирались только из новых

писем, а вся уже скачанная почта их не пополняла — открыв «Контакты», вы

видели пустой список. Теперь при первом запуске книга заполняется из

накопленных писем.

  • «Контакты» было не найти — пункт прятался в настройках. Теперь он в

боковой панели, рядом с папками и аккаунтами.

0.7.02026-08-17

Добавлено

  • Адресная книга. Контакты собираются сами из переписки — и те, кто писал

вам, и те, кому писали вы. Свои адреса в книгу не попадают.

  • Подсказки адресов при написании письма — в полях «Кому» и «Копия»

дополняется тот адрес, который набираете сейчас; выше те, кому пишете чаще.

  • Окно «Контакты» (Настройки → Контакты): поиск, добавление и правка

вручную, заметки, удаление, кнопка «Написать».

  • Импорт и экспорт vCard (.vcf) — перенос контактов из другого почтового

клиента и обратно. Понимаются выгрузки Thunderbird, Outlook, Google и

Яндекса, включая кириллицу в старом формате Outlook.

Имя, введённое вручную, автосбор не перезаписывает: если вы записали

«Марина, бухгалтерия», следующее письмо не вернёт служебное «noreply».

0.6.02026-08-12

Исправлено

  • Удаление писем не доходило до сервера. Письмо исчезало из списка, но на

сервере оставалось: операция падала с «UID MOVE No such folder» и после семи

повторов отбрасывалась. Папки только добавлялись в кэш и никогда не

удалялись, поэтому копились записи папок, которых на сервере уже нет — у

Яндекса на роль «Корзина» приходилось три записи, и выбиралась произвольная.

Теперь синхронизация убирает папки, отсутствующие на сервере, а для операций

выбирается реально работающая папка.

  • После запуска до пяти минут показывалась старая почта — синхронизация

шла только по интервалу. Теперь она стартует сразу при открытии приложения.

  • Очередь операций копила мусор: записи удалённых аккаунтов и давние

неудачи оставались в базе навсегда. Добавлена автоматическая уборка.

  • В «Отправленных» и «Черновиках» показывался отправитель — то есть вы

сами, и список выглядел как письма от себя. Теперь в строке отображается

адресат, как и ожидается от почтового клиента.

Добавлено

  • «Всегда показывать картинки от этого отправителя» — кнопка «Всегда» в

плашке блокировки; письма от доверенных отправителей открываются с

картинками сразу.

  • Настройка окна отмены отправки (сразу / 5 / 10 / 30 секунд) — раньше

окно было жёстко 10 секунд, а настройка ни на что не влияла.

  • Выбор папки для вложений — нативный диалог в настройках; раньше вложения

всегда сохранялись в системные «Загрузки».

  • Счётчик непрочитанных в подсказке трея — видно количество, не открывая окно.

Внутреннее

  • Тесты критической логики: очередь операций (повторы, задержка, терминальные

отказы, UIDVALIDITY), отправка (отмена, отложенная отправка, восстановление

после сбоя), правила фильтрации, доверенные отправители, санитайзер писем.

  • Санитайзер: регрессионные тесты на класс атак «разметка проходит фильтр, но

опасна при отрисовке» (label[for], CSS-псевдоклассы, скрытие через opacity).

  • Убрано глобальное разрешение dead_code: мёртвый код удалён, дублирование

SQL в движке синхронизации устранено, осознанные исключения помечены точечно.

  • Миграции V011 (доверенные отправители) и V012 (очередь операций больше не

хранит копии учётных данных, которые устаревали при смене настроек аккаунта).

0.5.22026-07-15

Внутреннее

  • scripts/release.ps1 сам настраивает подпись обновления: ключ берёт из

$HOME\.corvo\corvo_updater.key, пароль — из $HOME\.corvo\corvo_updater.pass

(шифрование DPAPI, привязано к учётке Windows). Пароль спрашивается один раз,

дальше деплой идёт без вопросов. Раньше про переменные окружения приходилось

помнить, и сборка падала на бандле («A public key has been found, but no

private key»), а публикация — на отсутствующем .sig.

Исправлено (этап B ТЗ — честная синхронизация)

  • B1. Сервер — источник правды. Письмо, удалённое с телефона или в

веб-интерфейсе, теперь исчезает и в Corvo: после синка папка сверяется с

сервером (UID SEARCH ALL), и всё, чего на сервере нет, удаляется из

локального кэша. Раньше кэш только рос и расходился с ящиком.

  • B1. Флаги по всему кэшу. Прочитанное/помеченное подхватывается для всех

писем папки, а не только в окне последних 500 UID — старое письмо больше не

висит непрочитанным навсегда. Письма с неотправленными операциями в очереди

по-прежнему не затираются серверными флагами.

  • B2. Догрузка истории. Список писем больше не упирается в последние 500:

при прокрутке вниз ядро догружает более старые письма страницами по 200

(messages_load_older, миграция V010 — колонка folders.history_complete).

Дойдя до начала ящика, список показывает «Это все письма» и на сервер больше

не ходит.

Изменено

  • D2. Виртуализация списка (react-virtuoso): в DOM держатся только видимые

строки. Без этого догруженные тысячи писем (B2) сделали бы прокрутку тяжёлой.

Липкие заголовки дат и раскрытие цепочек сохранены.

  • C2. Пул IMAP-соединений (≤ 3 на аккаунт, проверка живости через NOOP).

Синхронизация, открытие письма, скачивание вложения и очередь операций

переиспользуют соединения вместо полного входа (TCP+TLS+LOGIN) на каждое

действие. Это устраняет причину ошибок лимита одновременных сессий у Яндекса —

в A7 мы лечили симптом автоповтором.

Добавлено

  • Иконка в системном трее (desktop). Меню: «Открыть Corvo», «Написать

письмо», «Проверить почту», «Выход»; левый клик по иконке разворачивает окно.

  • Сворачивание в трей вместо закрытия. Кнопка «Закрыть» прячет окно, и

Corvo продолжает проверять почту и слать уведомления в фоне. Отключается в

настройках («При закрытии сворачивать в трей»).

  • Автозапуск вместе с системой (tauri-plugin-autostart) — переключатель в

настройках. При автозапуске приложение стартует сразу в трей (--minimized),

без мелькания окна.

0.5.12026-07-15
  • Трей и автозапуск с системой
0.5.02026-07-15

Исправлено (аудит целостности и безопасности)

  • Порча данных при синке (критично). upsert_message на ветке обновления

возвращал чужой rowid (last_insert_rowid), из-за чего FTS-индекс портился

каждым синком, а автоправила могли применяться к постороннему письму (вплоть

до удаления не того письма на сервере). Переведено на RETURNING id.

  • Отправка после отмены (критично). Воркер очереди отправки перетирал

статус cancelled — письмо могло уйти после успешного «Отменить». Перевод в

sending теперь только WHERE status='queued'.

  • Потеря писем из очереди отправки при аварийном завершении между sending

и SMTP: зависшие записи возвращаются в очередь при старте.

  • UIDVALIDITY в очереди операций. Отложенные offline-операции больше не

выполняются при смене UIDVALIDITY папки (миграция V009) — исключено

удаление/перемещение не того письма.

  • Пропавшие письма при >500 новых за синк (обработка старейших первыми,

без «дыры» в кэше) и пере-обработка верхнего письма каждый цикл.

  • Атомарность записи тела и вложений (одна транзакция); атомарные миграции.
  • Безопасность: SSRF-фильтр приватных адресов при загрузке внешних

картинок; точечная замена только в src (ссылки/текст не портятся); CSP

iframe письма переведена с unsafe-inline на nonce; проверка источника

postMessage; горячие клавиши не срабатывают при открытых диалогах.

  • Стабильность IMAP: одна сессия на аккаунт на батч операций (меньше риск

бана за частые логины); управляемые IDLE-воркеры (новый аккаунт

подхватывается без перезапуска, удалённый — останавливается);

пер-аккаунтный замок синка; устойчивость к «отравленному» мьютексу БД.

  • UI: устранены гонки при переключении папок/аккаунтов/поиска; откат

optimistic-действий с уведомлением; тихие ошибки загрузки теперь видимы;

счётчики непрочитанного считаются по всем аккаунтам; вложения передаются

как base64 вместо массива чисел (быстрее и легче по памяти).

Прочее

  • Новая иконка приложения (конверт на фирменном градиенте): обновлены

src-tauri/icons/*, добавлен исходник app-icon.png для tauri icon

(desktop/Android/iOS).

  • Мобильная раскладка (этап 1). Отзывчивый слой только для мобильных

платформ (Android/iOS): экран «Входящие» со списком писем, нижний лист

«Ящики/папки», чтение письма полноэкранно, FAB «Написать» (хук useIsMobile,

components/mobile/MobileApp). На десктопе не активируется ни при какой ширине

окна (гейт по платформе). Дальше — поиск, мобильный композер, экран

аккаунтов/настроек, свайпы, планшетный split-view.

  • Подготовка к Android-сборке. Desktop-only крейты (keyring, opener,

tauri-plugin-updater/process) изолированы под cfg(not android); секреты

вынесены в core::secret_store (desktop — keyring, Android — файловый

бэкенд); команды окна/открытия ссылок гейтированы под cfg(desktop).

TLS переведён с native-tls/OpenSSL на rustls + ring (IMAP через ручной

rustls-поток imap_client::connect_tls_stream; lettre/reqwest/oauth2 —

фичи rustls) — Perl/OpenSSL для сборки больше не нужны. Инструкция —

docs/ANDROID.md.

  • Этап B: честный синк (реконсиляция удалений/флагов, папки).
0.4.112026-07-07

Добавлено

  • A8: картинки в письмах. (1) Inline-картинки cid: — MIME-разбор извлекает

inline-части (Content-ID, image/*), в теле src="cid:…" заменяется на

data:-URL (лимит 5 МБ, после ammonia): логотипы Госуслуг видны сразу и

офлайн. (2) Внешние http(s)-картинки по кнопке «Показать» скачиваются ядром

(messages_inline_remote_images: таймаут 10 с, ≤10 МБ, ≤20 шт., только

image/*) и встраиваются как data:-URL; результат кэшируется

(message_bodies.html_with_images, миграция V008) — после этого картинки

доступны офлайн, а IP не светится при каждом открытии. Пока картинки скрыты —

без «битых» иконок (спрятаны в CSS iframe). Глобальный CSP приложения не

ослаблен. Вложения хранят mime_type и content_id. Unit-тесты на cid и

извлечение внешних src.

Исправлено

  • A7: понятная причина ошибки загрузки письма. Общий разбор ошибок

(api/error.ts): панель чтения показывает реальный текст (а не общее

«Не удалось загрузить письмо») и кнопку «Повторить». При ограничении числа

IMAP-подключений (типично для Яндекса) — понятный текст и один автоповтор

через 3 с. Тот же разбор применён в композере и диалогах аккаунта.

0.4.102026-07-07

Этап A ТЗ v0.5.0 (часть 3) + улучшение UX.

Добавлено

  • A3: реальная проверка соединения. Кнопка «Проверить соединение» в диалоге

добавления аккаунта теперь действительно подключается: IMAP — вход по паролю

с таймаутом 10 с и LOGOUT, SMTP — доступность сервера и TLS. Результат

показывается раздельно по каждому протоколу со спиннером на время проверки.

Ошибки человекочитаемые и различают неверный пароль («ошибка аутентификации»)

и недоступность сервера («сервер недоступен»). Заглушка test_imap_connection

осталась только для базовой валидации входных данных. Добавлены Rust

unit-тесты классификатора ошибок.

  • Переключатель цепочек писем в настройках. «Группировать письма в цепочки»

(Вкл/Выкл): при выключении каждое письмо отображается отдельной строкой без

группировки по теме. Настройка сохраняется в БД (по умолчанию — включено).

  • Лицензионное соглашение (EULA). Единый текст (LICENSE.md) в трёх местах:

экран лицензии в установщике (NSIS, bundle.licenseFile), раздел «О программе»

в приложении (кнопка «Лицензионное соглашение») и страница на сайте

([corvo_license], ссылка в подвале). Программа распространяется бесплатно;

правообладатель — физическое лицо, применимое право — РФ.

  • A5: копия отправленных писем в папке «Отправленные». После успешной

отправки приложение кладёт письмо в папку с ролью sent через IMAP APPEND

(флаг \Seen). Для провайдеров, которые сохраняют копию сами (Яндекс, Mail.ru,

Gmail), APPEND не делается — во избежание дубликатов. Поведение настраивается

по каждому ящику (миграция V006, галочка в «Настройках ящика»). Ошибка APPEND

не считается ошибкой отправки: письмо помечается отправленным, а в событии

outbox:status приходит appendFailed, и показывается ненавязчивый тост.

  • A6: цитирование в ответе, Cc и реальные получатели. Ответ и пересылка

теперь цитируют оригинал (HTML-цитата blockquote с атрибуцией

«{дата}, {отправитель} пишет:», фолбэк — текст; курсор над цитатой).

«Ответить всем» собирает получателей из отправителя, «Кому» и «Копии» (минус

свой адрес, без дублей; Cc уходит в Cc). В шапке письма показываются реальные

адресаты («Кому: …, и ещё N», раскрытие по клику — полный список То/Копия).

При синке сохраняются Cc (cc_addrs) и цепочка References (миграция V007);

ответ уходит с корректными In-Reply-To/References (id в угловых скобках),

поэтому попадает в тред у получателя.

Исправлено

  • A4: роли папок через SPECIAL-USE и запрет молчаливого удаления. Роли папок

определяются по атрибутам RFC 6154 (\Sent, \Drafts, \Trash, \Junk,

\Archive, \All), эвристика по имени — только фолбэк; INBOX всегда

«Входящие». Если Корзина не найдена, удаление не выполняется безвозвратно

молча: команда возвращает TRASH_NOT_FOUND, а приложение спрашивает

«Удалить безвозвратно?» и повторяет с явным подтверждением. Из самой Корзины

удаление требует подтверждения «Удалить навсегда?». Автоправило delete без

Корзины пропускается с предупреждением в лог. Добавлены Rust unit-тесты

маппинга SPECIAL-USE и фолбэк-эвристики.

0.4.92026-07-07

Исправлено

  • Усилен мост ссылок в письме (перехват средней кнопки/Ctrl-клика, Enter,

запрет сабмита форм) — переход по ссылке гарантированно уходит в браузер.

  • Понятные ошибки загрузки письма: панель чтения показывает конкретную

причину, а ядро логирует детальную ошибку команды (Ошибка команды: …).

  • Полнотекстовый поиск больше не падал — в запросе FTS5 использовался алиас

таблицы в MATCH (x MATCH ?), из-за чего SQLite выдавал «no such column: x»

и поиск всегда возвращал пусто. Теперь используется имя таблицы messages_fts.

0.4.82026-07-07

Этап A ТЗ v0.5.0 (часть 1): критические дефекты.

Исправлено

  • A1: синхронизация не выбивает из письма/папки. IDLE-события, ручная и

периодическая синхронизация больше не переключают активную папку и не

сбрасывают выделение/скролл — список текущего вида перечитывается и мерджится

(syncAccount теперь только запускает синк, новый refreshCurrentList

перечитывает вид). Если открытое письмо удалено на сервере — панель чтения

закрывается с ненавязчивым тостом. Добавлен минимальный тост-механизм в сторе.

  • A2: ссылки в письмах открываются в системном браузере. iframe письма

получил безопасный мост (sandbox="allow-scripts", CSP `script-src

'unsafe-inline'): клик по ссылке уходит в ядро (shell_open_url` с валидацией

схемы http/https и unit-тестами), mailto: открывает композер; при наведении

внизу панели виден реальный URL. Прочие схемы (javascript/file/data) игнорируются.

0.4.72026-07-06
  • Настройки ящика, все папки, объединённый inbox опция
0.4.72026-07-06

Изменено

  • Объединённый inbox стал опцией. По умолчанию приложение открывает

ящик пользователя (его «Входящие»), а не «Все входящие» всех ящиков.

«Все входящие» и смарт-папки (Непрочитанные / С вложениями / Отложенные)

показываются только при включённой настройке «Объединённый inbox (все ящики

вместе)».

  • Видны ВСЕ папки ящика. Сайдбар больше ничего не скрывает и не схлопывает:

показываются входящие, все системные и все пользовательские папки под своими

реальными именами (со счётчиками непрочитанных).

Исправлено

  • Панель быстрых действий при наведении больше не перекрывает кнопку разворота

цепочки — счётчик/шеврон цепочки перенесён левее темы письма.

Добавлено

  • Настройки ящика (правый клик по аккаунту → «Настройки ящика»): название,

параметры подключения (IMAP/SMTP хосты и порты) и подпись для писем.

  • Авто-уведомление о новой версии — приложение само проверяет обновления при

запуске и периодически, пока открыто. Если вышла новая версия: системное

уведомление + плашка в приложении с кнопкой «Обновить сейчас» / «Позже».

Технически

  • Команда accounts_update (имя + подключение); настройка unified_inbox;

initApp выбирает стартовый вид по настройке; компонент AccountSettingsDialog.

0.4.62026-07-06

Добавлено

  • Обратная связь в приложении — в настройках пункт «Обратная связь

(замечания и предложения)»: открывает письмо с предзаполненным получателем

it@konstmax.ru (отправляется из аккаунта пользователя).

0.4.52026-07-06

Исправлено

  • Две иконки настроек — убрана дублирующая шестерёнка из подвала сайдбара.

Настройки открываются одной кнопкой-шестерёнкой в титлбаре (вверху справа).

  • Видимость дублирующих папок — если у ящика две папки одной роли (напр.

«Sent» и «Отправленные»), одна остаётся системным пунктом, а вторая теперь

показывается в разделе «Папки» под своим именем (раньше пряталась).

0.4.42026-07-06

Исправлено

  • Кракозябры в именах папок (напр. «&BB4EQgQ…»). Нелатинские имена IMAP-папок

приходят в кодировке modified UTF-7 (RFC 3501); теперь они декодируются при

отображении в сайдбаре и заголовке списка. В БД имя остаётся «серверным»

(mUTF-7) — как требуется для IMAP-операций.

0.4.32026-07-06

Добавлено

  • Установщик (NSIS .exe) и система автообновлений (Tauri updater).

- В приложении: диалог «О программе» (Настройки → О программе) с версией и

кнопкой «Проверить обновления»; скачивание, установка и перезапуск.

- Сборка: bundle.targets = nsis, createUpdaterArtifacts, подписанные

артефакты; endpoint https://corvo-mail.ru/update/latest.json.

- Раздача обновлений: веб-корень сайта corvo-mail.ru

(/var/www/fsk/data/www/corvo-mail.ru/update), без Docker.

- Скрипт релиза: scripts/publish-update.ps1 (формирует latest.json и

заливает установщик в веб-корень по scp).

- Гайд: docs/UPDATES.md (ключи, каталог, сборка, публикация).

Технически

  • Плагины tauri-plugin-updater и tauri-plugin-process; JS

@tauri-apps/plugin-updater / @tauri-apps/plugin-process; разрешения

updater:default, process:default в capabilities.

0.4.22026-07-04

Добавлено

  • Экран настроек (шестерёнка в сайдбаре), значения сохраняются в БД:

- тема оформления (светлая/тёмная/системная);

- плотность списка писем (обычная/плотная — плотная скрывает превью текста);

- интервал автосинхронизации (1/5/15/30 мин) — периодически синхронизирует

все аккаунты;

- уведомления о новых письмах (вкл/выкл) — реально гейтит показ уведомлений

в IDLE-воркере;

- быстрый переход к правилам фильтрации.

Технически

  • Миграция V005__settings.sql (таблица app_settings, JSON);

repo_settings + реальные settings_get/settings_set; в сторе — settings,

loadSettings, updateSettings; периодический синк и открытие настроек — в App.

0.4.12026-07-04

Добавлено

  • Счётчики непрочитанных у папок в сайдбаре (число справа от папки, как в

вебе провайдера) — для системных и пользовательских папок активного аккаунта.

  • Горячие клавиши (стиль Gmail): J/K — следующее/предыдущее письмо,

C — написать, R — ответить, E — архивировать, # — удалить,

/ — фокус на поиск, ? — справка по клавишам, Esc — закрыть. Клавиши

игнорируются при вводе в поля и при открытом композере.

Технически

  • Команда folders_unread_counts + repo_messages::unread_counts; в сторе —

unreadCounts и действия `selectNext/selectPrev/archiveSelected/trashSelected/

replySelected; глобальный обработчик клавиш в App, компонент ShortcutsHelp`.

0.4.02026-07-04

Добавлено

  • Полнотекстовый поиск (FTS5) — Этап 6. Поиск по заголовкам и телам писем

всех аккаунтов с задержкой ввода (debounce). Операторы: from:, to:,

subject:, has:attachment, in: (роль или имя папки),

before:YYYY-MM-DD, after:YYYY-MM-DD; свободный текст комбинируется с ними.

Результаты группируются в цепочки, совпадения подсвечиваются.

  • Индексация заголовков — при синхронизации, тел — при открытии письма;

результаты чистятся из индекса при удалении писем.

Технически

  • Миграция V004__fts_rebuild.sql: messages_fts пересоздана как обычная FTS5

(не contentless — иначе невозможны DELETE/UPDATE для переиндексации);

разовая индексация заголовков уже загруженных писем.

  • repo_messages::search (FTS MATCH + SQL-фильтры), парсер операторов в

commands::search; fts::index_message вызывается из sync_engine.

0.3.122026-07-04

Исправлено

  • Пользовательские папки не показывались в сайдбаре. Отображались только

системные папки (с ролью), а обычные папки аккаунта (напр. «1С документооборот»,

«БИТРИКС») скрывались, хотя синхронизировались и хранились в БД. Добавлен

раздел «Папки» со всеми пользовательскими папками активного аккаунта (клик —

открыть, drag-and-drop писем — поддержан). Вложенные папки показываются

последним сегментом (Parent/Child → Child), полное имя — в подсказке.

0.3.112026-07-04

Добавлено

  • Правила фильтрации входящих — Этап 5 завершён. Условие «поле

(Отправитель / Тема / Кому) содержит подстроку» → действие: переместить в

папку (Архив / Спам / Корзина), отметить прочитанным, в избранное или удалить.

Управление — в диалоге (шестерёнка в сайдбаре): добавление, включение/

выключение, удаление правил. Правила применяются к новым входящим при

синхронизации (первичный бэкап и служебные папки не затрагиваются).

Технически

  • Миграция V003__rules.sql (таблица rules); repo_rules (CRUD);

команды rules_list/rules_add/rules_set_enabled/rules_delete; применение —

в sync_engine (действия ставятся в очередь операций с retry).

0.3.102026-07-04

Добавлено

  • Отложить письмо (snooze). В контекстном меню — пресеты «На час»,

«Сегодня вечером», «Завтра утром», «Через неделю». Отложенное письмо

пропадает из «Входящих»/смарт-папок и появляется в новой смарт-папке

«Отложенные»; по наступлении срока автоматически возвращается во

«Входящие». В папке «Отложенные» — пункт «Вернуть во Входящие» (снять отложку).

Технически

  • Ядро: messages_snooze (проставляет snoozed_until), messages_snoozed

(snoozed_until > now); выборки inbox/smart учитывают

snoozed_until IS NULL OR <= now (авто-возврат без фонового воркера).

0.3.92026-07-04

Добавлено

  • Группировка писем в цепочки (треды). Ядро вычисляет thread_key

(корневой message-id по References → In-Reply-To → собственный

message-id) и сохраняет его при синхронизации. В списке письма одной

переписки сворачиваются в один пункт с счётчиком; шеврон разворачивает

цепочку — вложенные письма показываются под представителем. Представитель —

самое свежее письмо; непрочитанность/вложение/звезда агрегируются по всей

цепочке. Группировка работает и в объединённом inbox (между аккаунтами).

Технически

  • imap_client: разбор References/In-Reply-To (ids_from_header).
  • repo_messages::upsert_message: параметр thread_key.
  • sync_engine::compute_thread_key; во фронтенде — агрегатор цепочек в

MessageList и поля threadKey/dateUtc в модели отображения.

0.3.82026-07-04

Исправлено

  • Входящие загружались не полностью. При первичной синхронизации окно

писем бралось по UID (UIDNEXT − 500). Из-за удалённых писем UID'ы разрежены,

поэтому «последние 500 UID» содержали лишь несколько реальных писем. Теперь

первый синк берёт последние ~500 писем по порядковому номеру (sequence,

диапазон EXISTS−500 : EXISTS) — это всегда ровно N самых свежих писем,

независимо от «дыр» в UID. Инкрементальный синк по-прежнему по UID > last_seen.

  • Дублирование системных папок в сайдбаре (напр. «Отправленные», «Корзина»

дважды): на одну роль сервер может отдавать несколько папок (Sent и

Отправленные). Теперь в сайдбаре показывается один пункт на роль.

Технически

  • select_info теперь возвращает и EXISTS; добавлен fetch_headers_recent

(выборка по sequence); разбор FETCH вынесен в envelope_from_fetch.

0.3.72026-07-04

Добавлено

  • Объединённый inbox «Все входящие» — единый список писем всех аккаунтов

(папки с ролью inbox), отсортированный по дате. Отдельный пункт в самом

верху сайдбара; открывается по умолчанию при старте.

  • Смарт-папки «Непрочитанные» и «С вложениями» теперь работают по всем

аккаунтам сразу (реальные выборки из БД, а не заглушки).

  • В объединённых списках цветная полоска и аватар письма окрашиваются в цвет

аккаунта-отправителя (стабильная палитра по позиции аккаунта).

Изменено

  • Кнопка «Обновить» (в титлбаре и над списком) в объединённом/смарт-режиме

синхронизирует все аккаунты и перечитывает представление.

  • Персональный inbox аккаунта в сайдбаре больше не дублирует «Все входящие»:

под аккаунтом остаются Отправленные, Черновики, Архив, Спам, Корзина.

  • Заголовок центральной панели отражает текущее представление (папку/смарт-папку).

Технически

  • Ядро: messages_unified / messages_unread / messages_with_attachments

(JOIN folders, фильтр role='inbox', учёт snoozed_until); в модель

Message добавлено поле account_id.

0.3.62026-07-04

Исправлено

  • Первичная синхронизация тянула все заголовки папки (1:*) и «висела» на

больших ящиках (напр. Яндекс). Теперь при первом синке грузятся только

последние ~500 UID на папку (по UIDNEXT), как и предписывает ТЗ.

0.3.52026-07-04

Исправлено

  • Автоопределение хостов для доменов Яндекса ya.ru и yandex.com

(раньше распознавался только yandex.ru).

0.3.42026-07-04

Добавлено

  • Удаление аккаунта из UI (правый клик по аккаунту в сайдбаре) с очисткой

секретов из keyring (пароль и OAuth-токены).

0.3.32026-07-04

Исправлено

  • OAuth: access-токен теперь хранится и используется напрямую (в keyring —

JSON access+refresh+срок), refresh вызывается только по истечении. Это

устраняет ошибку Обновление токена не удалось: Server returned error response

(Яндекс отвергал лишний refresh; его токен и так долгоживущий).

  • Повторный вход по тому же email обновляет токены, а не падает на уникальности.
0.3.22026-07-04

Изменено

  • Детальное логирование ошибок OAuth-входа IMAP (получение токена / XOAUTH2) —

чтобы видеть реальную причину, а не генерализованное сообщение.

0.3.12026-07-04

Исправлено

  • OAuth: браузер на Windows открывался через cmd start, из-за чего URL

авторизации обрезался на первом & и терялся client_id (ошибка Яндекса

«отсутствует client_id»). Теперь используется rundll32 FileProtocolHandler.

0.3.02026-07-04

Этап 4 завершён: OAuth 2.0 (Яндекс, Mail.ru) работает.

Добавлено

  • XOAUTH2 для IMAP (SASL) и SMTP — OAuth-аккаунты читают и отправляют

почту по access-токену.

  • Единый вход account_manager::open_imap (пароль или OAuth) и

get_access_token (обновление по refresh-токену) — используются во всех

путях: синхронизация, чтение тела, вложения, очередь операций, отправка,

сохранение черновика.

0.2.92026-07-04

Добавлено

  • Иконка приложения (ворон, выныривающий из конверта; палитра 1B «Про»):

src-tauri/icons/* + bundle.icon в конфиге; исходники в assets/brand/.

Изменено

  • OAuth переведён на OOB-поток (verification_code): вместо loopback-порта

(который Яндекс не регистрирует) пользователь подтверждает доступ в браузере и

вставляет код. Redirect URI для Яндекса: https://oauth.yandex.ru/verification_code.

Двухшаговые команды accounts_oauth_start + accounts_add_oauth.

0.2.82026-07-03

Этап 4 (слайс 1): OAuth 2.0 для Яндекс и Mail.ru.

Добавлено

  • OAuth-поток по RFC 8252: системный браузер + локальный loopback-редирект +

PKCE; обмен кода на токены (oauth2).

  • Ключи client_id/client_secret читаются из oauth.json в каталоге данных

приложения (шаблон oauth.json.example, в репозиторий не коммитится).

  • Команда accounts_add_oauth; кнопки «Войти через Яндекс / Mail.ru» в диалоге

добавления аккаунта; refresh-токен хранится в системном keyring.

0.2.72026-07-03

Этап 3 завершён.

Добавлено

  • WYSIWYG-редактор письма (TipTap): тулбар — жирный, курсив, маркированный

и нумерованный списки, цитата; письмо отправляется как multipart/alternative

(HTML + текст). Зависимости: @tiptap/react, @tiptap/starter-kit, @tiptap/pm.

0.2.62026-07-03

Этап 3 (хвост):

Добавлено

  • Сохранение черновика на сервере (IMAP APPEND в папку Drafts с флагом

\Draft) — кнопка «Черновик» в композере.

0.2.52026-07-03

Исправлено

  • Отправка почты: ошибка SMTP 501 Syntactically invalid EHLO argument(s) —

для EHLO теперь используется домен из адреса отправителя, а не имя

компьютера (которое могло содержать недопустимые символы, напр. кириллицу).

0.2.42026-07-03

Этап 3 (продолжение):

Добавлено

  • Вложения в композере: прикрепление файлов (multipart/mixed), чипы с

размером и удалением, предупреждение при размере > 20 МБ.

  • Подписи per-account: редактор в композере (сохраняется локально по

аккаунту), автоподстановка в конец новых писем.

0.2.32026-07-03

Добавлено

  • Показ результата отправки в UI: тост «Письмо отправлено» / «Не удалось

отправить: …» (подписка на событие outbox:status).

  • Логирование отправки в app.log (успех — info, ошибка — warn) для диагностики.
0.2.22026-07-03

Этап 3 (продолжение):

Добавлено

  • Ответить всем — получатели собираются из отправителя и списка «Кому»

(без своего адреса).

  • Автосохранение черновика нового письма (localStorage) с восстановлением

при повторном открытии «Написать»; очистка после отправки.

0.2.12026-07-03

Этап 3 (частично): отправка почты и композер.

Добавлено

  • SMTP-отправка через lettre (implicit TLS на 465 / STARTTLS на 587).
  • Очередь исходящих outbox + фоновый воркер; окно отмены отправки (undo,

10 сек) с тостом «Отменить»; статусы через событие outbox:status.

  • Композер: новое письмо («Написать»), ответ и пересылка — с

цитированием и заголовками In-Reply-To / References.

  • Отложенная отправка (выбор даты/времени).
  • Проверки перед отправкой: пустая тема, упомянуто вложение без файла.
0.2.02026-07-03

Закрыт Этап 2 (синхронизация, push, операции) и финализирован дизайн.

Добавлено

  • Инкрементальная синхронизация с проверкой UIDVALIDITY: докачиваются только

новые письма (UID > last_seen), обновляются флаги в недавнем окне, при смене

UIDVALIDITY — полный ресинк папки.

  • IMAP IDLE: фоновые воркеры на INBOX каждого аккаунта; при новых письмах —

системное уведомление (tauri-plugin-notification) и авто-подтягивание.

  • Персистентная очередь операций (op_queue, миграция V002) с фоновым

воркером: смена флагов, перемещение, удаление уходят на сервер с retry и

экспоненциальным backoff; работает в оффлайне (optimistic-UI локально).

  • Двунаправленная синхронизация флагов/папок с сервером (STORE, MOVE, EXPUNGE).
  • Контекстное меню письма, быстрые действия при наведении, drag-and-drop

писем в папки.

  • Индикатор состояния соединения аккаунта (online/offline/reauth) через событие

account:connection_state.

  • Финальный дизайн: нативный оконный chrome Windows (кастомный титлбар,

кнопки свернуть/развернуть/закрыть, перетаскивание, Segoe UI, decorations:false).

Изменено

  • Заголовки писем декодируются через mail-parser (RFC 2047, кодировки charset)

вместо ручного разбора.

  • Плашка блокировки изображений показывается только при наличии реальных

внешних картинок в письме.

  • Обновлены токены дизайн-системы (textMuted) под финальный макет.

Удалено

  • Демонстрационные данные интерфейса — только реальная почта.
0.1.02026-07-02

Этапы 0–1: каркас и чтение почты.

Добавлено

  • Каркас Tauri 2 + React 18 + TypeScript + Vite; SQLite с системой миграций

(V001), логирование tracing в файл, базовые модули ядра.

  • Трёхпанельный интерфейс в дизайне «Corvo 1B — Про», светлая/тёмная темы.
  • Добавление IMAP-аккаунта по паролю (keyring), автоопределение хостов для

Яндекс/Mail.ru/Gmail/Outlook/Rambler, реальная проверка соединения.

  • Синхронизация папок и заголовков, список писем из БД с группировкой по датам.
  • Чтение письма: докачка тела, разбор MIME (mail-parser), санитизация HTML

(ammonia), рендер в sandbox-iframe с CSP, блокировка удалённых изображений.

  • Вложения: список, скачивание в «Загрузки», открытие системным приложением,

предупреждение об исполняемых расширениях.

[Не выпущено]: https://gitflic.ru/project/konstmax13/corvo

[0.3.6]: https://gitflic.ru/project/konstmax13/corvo

[0.3.5]: https://gitflic.ru/project/konstmax13/corvo

[0.3.4]: https://gitflic.ru/project/konstmax13/corvo

[0.3.3]: https://gitflic.ru/project/konstmax13/corvo

[0.3.2]: https://gitflic.ru/project/konstmax13/corvo

[0.3.1]: https://gitflic.ru/project/konstmax13/corvo

[0.3.0]: https://gitflic.ru/project/konstmax13/corvo

[0.2.9]: https://gitflic.ru/project/konstmax13/corvo

[0.2.8]: https://gitflic.ru/project/konstmax13/corvo

[0.2.7]: https://gitflic.ru/project/konstmax13/corvo

[0.2.6]: https://gitflic.ru/project/konstmax13/corvo

[0.2.5]: https://gitflic.ru/project/konstmax13/corvo

[0.2.4]: https://gitflic.ru/project/konstmax13/corvo

[0.2.3]: https://gitflic.ru/project/konstmax13/corvo

[0.2.2]: https://gitflic.ru/project/konstmax13/corvo

[0.2.1]: https://gitflic.ru/project/konstmax13/corvo

[0.2.0]: https://gitflic.ru/project/konstmax13/corvo

[0.1.0]: https://gitflic.ru/project/konstmax13/corvo