Repository navigation
Mail: read-only mail, end to end (slice 1) - #25
Merged
Merged
Conversation
…nts for mail, syncs Inbox and Sent, keeps up through events and mail.changes, threads by Message-ID, and the page lists and reads it The hub asks the manager for `mail` at write (a hub registered before asks once), follows the mail accounts it lists, and keeps them in mail tables of its own (hub/src/mail): mailboxes, the newest 500 of Inbox and Sent, keeping up through mail.arrived, mail.changed and mail.changes, a relist on 410, and moves that keep the hub's message. Threads come from the server's thread id, else In-Reply-To and References (now on summaries, dither-accounts 515f26d), else the subject. The page gets Mail in the rail: views, mailboxes, a reader with quotes folded and text made from HTML-only mail, read state kept on the hub after a second in view, and a Mail group in Accounts and Settings. Access that ends keeps the mail a day, with "Delete now". Later slices plug in through the routes table, MailHub's events, schema-*.sql files and the page's slots (docs/mail.md). The design is in docs/mail-design.md with the owner's decisions. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…baseline's node counts for the rail's entry Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Slice 1 of email: read-only mail, end to end. It follows
docs/mail-design.md§12.1 (copied into the repo, with §14 recorded as the owner decided). What works and how to run it is indocs/mail.md.What changed
Hub (
packages/hub/src/mail/)mailat write on all accounts, in a new registration. A hub that registered before asks once, throughmailToAsk.MailAccessis off, unreachable, pending, denied or granted. While it is pending or denied, the hub readsself()every 60 s and on each account list, and "Ask again" sends a new request. Mail accounts are added only on the manager's page.mail.arrivedis stored at once.mail.changedqueues a coalesced changes pass, andmoreis followed. Timers are insurance, and a gap, a reconnect, the account coming online and the hub starting each catch up. A 410 relists the mailbox.seen_local), set after 1 s in view.mail.flagis never called.DELETE /api/mail/accounts/:id. This is implemented, not left as a seam.mail, and there are the mail events of §5. The journal and/api/synccarry mail for a client that comes back.FakeMailBackendserves both the tests and--demo, whose world gains a mail account.Protocol
mail.ts: all of §5's views and events. Fields later slices fill say which slice.mail-iface.ts: a copy of dither-accounts' interface types.accounts-sync --checkcompares them, and they match master 515f26d.mailId,'email'added toNetwork(not toNETWORKS), and its entries in the per-network tables.Web
set-mailblock: status, "Sending is off: ", links to the manager, and "Delete now".mailRevsignal.Hooks for slices 2-7
hub/src/mail/routes.tsROUTERS: aMailRouter(hub)returns routes. It runs once per hub, so a slice also subscribes there.MailHub.on(...):ingested,deleted,opened,read,body,account.hub/src/mail/schema-<name>.sql: a slice's own tables, loaded afterschema.sql.MailQueue.gateandonStart: slice 2's budgets.MAIL_LIMITSinhub/src/mail/limits.ts, includingsyncDays(the horizon).web/src/ui/mail/slots.tsx:BODY_RENDERERS,MESSAGE_ACTIONS,THREAD_ACTIONSandROW_WRAPPERS(swipes).How it was verified
bun run typecheckandbun run testpass (hub 615, web 198, and the rest).mail-thread: a table of 22 cases, with and without the §13 headers.mail-store.mail-sync: first-sync order,more, 410, IMAP and Proton-like moves, unknown removed ids, arrived before changes, gap, the manager down and back,limited, access ending, and the delta sync matching a fresh bootstrap.mail-modelandmail-text.mail-remote.test.tspassed 7/7 against a throwaway dither-accounts manager with animapaccount on its Dovecot and SMTP sink, on ports 18580-18589. It covered the grant flow, first sync with threading from summaries, a body viamail.get, IDLE keep-up, another client's flags, another client's move (same hub message), and a UIDVALIDITY change, which relists. It skips without the checkout or Dovecot.scripts/verify-mail.tspassed 49/49 on a fresh demo hub, at 390 px with touch and on desktop, in dither-dark and dither-light. It found no page errors and no sideways overflow, and checked list → thread → back (button and history), quote folding, read-here after 1 s, and the HTML-only text with no script.verify-perf: the load average was about 6, and times moved up to 40% between runs of the same code, so I alternated branch, origin/main, branch. Renders are the same as main. A cold load at 4× took 3,692 ms on main, and 2,533 ms and 3,777 ms on the branch. The main bundle is +3 KB. DOM nodes are +9 (the rail's Mail entry). I updated only the four exact*.nodescounts inperf-baseline.json, by hand. Notes are indocs/perf.md.verify-phone: one failure, "dragging the dialog down closes it". origin/main fails the same check on this machine, so it is not from this branch.What I could not verify
mail.send(slice 5) are untested.🤖 Generated with Claude Code