Search previously only filtered the cached inbox. Now a query also runs an IMAP SEARCH
on the server and folds the matches into the cache, so messages beyond the synced
window surface in the results.
- ImapClient.search(query) ORs SUBJECT/FROM/BODY terms and fetches matching headers
(extracted a shared toFetchedMessage mapper, reused by fetchRecentInbox).
- MailRepository.searchServer inserts/updates matches into the message cache (no
pruning); MailboxViewModel triggers it from a debounced, deduplicated search query.
- assemble/test/lint green, including a new ImapClient test asserting SEARCH returns
only the matching message against GreenMail.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>