Phase 1 of the realtime work: the SDK now has a WebSocket EventBus client
(branch sdk-event-bus, single commit off upstream/master, 24 unit tests). No
bridge code consumes it yet — Phase 2 will replace list_sync_loop with an
event-driven handler and persist last batch ids per group.
Held from upstream submission until a working bridge integration validates
the API surface.
Implement MOVE / UID MOVE (RFC 6851): resolve the target by IMAP path
(UTF-7 decoded), call the SDK move_mails for the selected messages, then
expunge them from the source view. Advertise the MOVE capability.
COPY is rejected with NO — Tuta folders are exclusive, so duplication
isn't supported; clients use MOVE instead.
FolderInfo gains the folder's list id so the target MailSet IdTuple can
be reconstructed. Pulls in the SDK move_mails (tuta-repo submodule bump).
Live-tested: a mail moved from one custom folder to a nested UTF-7 folder
lands in the target and leaves the source server-side.
Key the syncer, local store and IMAP server by Tuta MailSet folder id
instead of the system folder kind, so custom (and nested) folders are
first-class.
- tuta.rs: add FolderInfo; MailBackend.list_folders enumerates system +
custom folders via the SDK FolderSystem tree, building IMAP paths and
RFC 6154 special-use flags; load mails by the folder's entries list.
- store.rs: folder_kind INTEGER -> folder_id TEXT, schema v2 with a
migration that drops the cache tables and re-syncs (encrypted .eml
files survive).
- sync.rs: MailStore keyed by folder id; the syncer enumerates the live
folder list each cycle.
- imap/session.rs: dynamic LIST/SELECT/STATUS driven by the folder list;
drop the hardcoded six-folder mapping.
Pulls in the SDK FolderSystem tree (tuta-repo submodule bump).
Live-tested: 9 custom folders listed and selectable over IMAP, with
headers and decrypted bodies. Not yet covered: nested-folder paths,
modified UTF-7 for non-ASCII names, labels, and IMAP MOVE/COPY.