- 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>
- TaskStore directory changed from `tasks-<id>` to `<accountId>/tasks/` per spec
- TaskStore now created before SyncCoordinator and passed as `taskStore:` arg so deferral resurfacing works
- Use `mailStore.databaseWriter` instead of raw `dbPool` for consistency
- Remove unused `deferSelectedItem` stub (all callers use `deferItem(_:until:)` directly)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Import TaskStore, add optional taskStore property, add resurfaceDeferrals()
that clears expired email deferrals and deferred task deferUntil on each sync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
New model types: TaskStatus, TaskSummary, LabelInfo, ItemSummary.
GRDB records: TaskRecord, LabelRecord, ItemLabelRecord, DeferralRecord.
Database migrations v3_task, v3_label, v3_deferral with indexes.
MailStore query extensions for labels, item-labels, deferrals, task cache.
TaskStore module wrapping MailStore. Tests for all v3 tables and records.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- MailViewModel.setup() now creates SMTPClient provider when SMTP config is present,
passes it to ActionQueue so send actions work
- ActionQueue is passed to SyncCoordinator so pending actions flush before sync
- Add ensureBodyLoaded() to fetch message body via IMAP before opening compose
- ThreadDetailView uses callback instead of binding for compose requests,
allowing ContentView to fetch body before presenting sheet
- Add SMTPClient dependency to both app targets in project.yml
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>