- EmailRepository: add searchEmails(accountId, mailboxPath, query)
- EmailRepositoryImpl: UID SEARCH with OR SUBJECT/TEXT criteria,
fetch ENVELOPE+FLAGS for matching UIDs
- EmailListScreen: toggle search bar in AppBar; submit triggers server
search; results replace the stream list; ESC/back closes search
- Refactored list into _buildList() shared by stream and search views
- README/PLAN.md updated
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- enough_mail: use uidFetchMessage/uidMarkSeen/uidMarkFlagged/uidMove/
uidMarkDeleted/uidExpunge, remove non-existent isUidSequence param,
fix SmtpClient construction and use quit() not disconnect()
- Drift: add @DataClassName('MailboxRow') to avoid ugly 'Mailboxe',
alias core model imports to resolve type name conflicts
- EmailsCompanion.insert: uid/receivedAt are required, not Value<T>
- Lint: remove unrecognised rules (prefer_const_collections,
avoid_returning_null_for_future), add missing mounted guards after await
- Tests: fix html_utils expectations to match trim() behaviour,
add explicit Map casts in email_model_test for avoid_dynamic_calls
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
IMAP/SMTP email client with offline-first architecture:
sync engine writes to Drift (SQLite), UI reads reactively
from the local DB. enough_mail vendored under packages/.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>