5fe8f228c1
Add a read-only /ecosystem page that consumes the sibling services' JSON APIs (Nexus entities, Praxis attention, Hexis capabilities), fetched concurrently with honest per-panel error states. Siblings stay headless — mavweb is their human surface (arch §16). Wired via mavweb -nexus/-praxis/-hexis flags; mavweb joins the ecosystem compose network. Fix mobile horizontal overflow across all pages: .content is a flex child with default min-width:auto, so it refused to shrink below the tables' intrinsic width. min-width:0 lets wide tables pan inside .scroll instead of dragging the page sideways. Verified via CDP geometry check (scrollWidth === clientWidth at 430px). Also includes in-progress Ethos UI redesign, ecosystem deploy compose, and planning docs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2.5 KiB
2.5 KiB
Plan: Background Email Reader
Goal: Maven periodically polls configured IMAP mailboxes, extracts structured items (tasks, reminders, calendar events, important facts) via LLM, and writes them into the store through ipc.CoreAPI — discarding spam, newsletters, and noise.
Done when:
internal/email/package exists with IMAP idle+poll loop- New
emailblock inconfig.Config(mailboxes, poll interval, extraction model) - Extracted items land as
WriteFact/CreateReminder/WriteNoteviaipc.Client - Spam/promotions/social are silently dropped (Gmail
X-GM-LABELSor IMAP keyword check) - Integration test with a throwaway mailbox verifies the round-trip
Scope:
- New
internal/email/package — IMAP client (stdlibnet/mail+github.com/emersion/go-imapor rawnet/textproto) - Config extension:
config.Config.Emailblock withPollInterval,Accounts[](host, username, password/app-password, folders) - LLM extraction prompt (shared
internal/llm.Client) classifies each unseen message astask|reminder|event|fact|junkand fills slots — same GBNF-constrained pattern asinternal/router/llmrouter.go:routeGrammar - Extracted items written through
ipc.CoreAPIinterface (same seaminternal/voice/reactiveHandleruses) - Daemon lifecycle: wired in
cmd/mavend/main.goalongside the tick loop, starts after unlock deploy/mavend.jsongets the email block
Steps:
- Add
EmailConfigstruct tointernal/config/config.go(accounts, poll interval, folders to scan) - Create
internal/email/withPoller— IMAP connect,IDLEfor push, fallback to periodicSELECT INBOX+SEARCH UNSEEN - Implement message → plaintext conversion (
text/plainbody, strip HTML fromtext/htmlviagolang.org/x/net/htmlor simple regex) - Add LLM extraction via
internal/llm.Client.Complete()with a GBNF grammar that outputs{"type":"task|reminder|event|fact","key":"...","value":"...","when":"..."}— mirroringinternal/router/llmrouter.go:routeGrammar - Map extracted items to
ipc.WriteFactReq/ipc.CreateReminder/ipc.WriteNotecalls - Wire
Pollerintocmd/mavend/main.go— start on unlock, stop on context cancel - Test with a throwaway mailbox (Gmail app password or a self-hosted Dovecot); verify extraction accuracy
- Add
models/seeds/email_*.txtseed examples for the extraction classifier - Log poll stats (seen, extracted, junk, errors) through
log.Printf(consistent with existing pattern incmd/mavend/tick.go)