- connect() now cleans up any stale connection/event loop group before
creating a new one, preventing leaked resources after failed syncs
- disconnect() uses try? for both channel close and group shutdown so
"Already closed" errors don't prevent cleanup
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- insertMessages uses INSERT OR IGNORE on (mailboxId, uid) conflict instead of
crashing on UNIQUE constraint when messages are re-fetched after restart
- IMAPResponseHandler.sendCommand resumes any leaked previous continuation before
registering a new one, preventing DuplicateCommandTag errors
- add channelInactive handler to resume pending continuations on connection drop
- add error type to sync failure log for better diagnostics
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- remove deinit from IMAPConnection, SMTPConnection — syncShutdownGracefully
blocks and deadlocks if called on NIO event loop thread
- limit reconcileFlags to last 500 UIDs to avoid overwhelming the connection
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- detect and re-fetch bodies containing unparsed MIME content (boundary markers,
Content-Transfer-Encoding headers) from pre-MIMEParser code path
- fix MIMEParser section numbering: pass cumulative sectionPrefix in nested multiparts
instead of resetting to empty string
- generate snippet from parsed body text when envelope snippet is missing
- add pendingAction(id:) direct lookup to MailStore, avoid re-fetching all actions
- add updateSnippet method to MailStore
- fix IMAPIdleClient.selectInbox: use incrementing tag counter instead of hardcoded tag
- use static nonisolated(unsafe) ISO8601DateFormatter in ActionQueue (avoid repeated alloc)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- fix deferral resurfacing using VTODOParser.formatDateOnly instead of ISO8601 (date format mismatch)
- add SELECT mailbox before UID STORE in storeFlags (IMAP protocol requirement)
- pass credentials to SyncCoordinator so IDLE monitoring activates
- add selectedItem tracking to MailViewModel, wire List selection in GTD views
- fix startPeriodicSync to sleep-first, preventing duplicate sync on launch
- add deinit cleanup for EventLoopGroup in IMAPConnection, SMTPConnection
- use separate IMAP client for attachment downloads, avoid shared connection interference
- remove [weak self] from IMAPIdleClient actor Task to prevent orphaned connections
- fix isGTDPerspective to check selectedMailbox instead of items.isEmpty
- fix fetchBody to use complete RFC822 fetch instead of BODY[TEXT]
- reuse single IMAP connection per ActionQueue.flush() batch
- add requiresIMAP to ActionPayload for connection batching
- load task categories from label store instead of hardcoded empty array
- suppress NIOSSLHandler Sendable warnings via Package.swift unsafeFlags
- fix unused variable warnings across codebase
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extend IMAPClientProtocol with storeFlags, moveMessage, copyMessage,
expunge, appendMessage, capabilities methods. Implement all six in
IMAPClient actor using NIOIMAPCore typed commands. Add multi-part
command support to IMAPConnection/IMAPCommandRunner for APPEND.
MockIMAPClient tracks all write calls for testing. SyncCoordinator
detects mailbox roles from LIST attributes with name-based fallback.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>