From 71077e93dd53799da7b0cbdbca97c8dac6904752 Mon Sep 17 00:00:00 2001 From: aleiby Date: Sat, 24 Jan 2026 21:45:22 -0800 Subject: [PATCH] fix(mail): filter by read status in ListUnread for beads mode (#936) ListUnread() was returning all open messages in beads mode instead of filtering out messages marked as read. This caused `gt mail inbox --unread` to show all messages even when they had the "read" label. The fix unifies the code path for legacy and beads modes - both now filter by the msg.Read field, which is correctly populated from the "read" label via ToMessage(). Note: `gt mail read` intentionally does NOT mark messages as read (to preserve handoff messages). Users should use `gt mail mark-read` to explicitly mark messages as read. Fixes gt-izcp85 Co-authored-by: Claude Opus 4.5 --- internal/mail/mailbox.go | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/internal/mail/mailbox.go b/internal/mail/mailbox.go index 7f1e3d20..c1f85a55 100644 --- a/internal/mail/mailbox.go +++ b/internal/mail/mailbox.go @@ -281,22 +281,19 @@ func (m *Mailbox) listLegacy() ([]*Message, error) { } // ListUnread returns unread (open) messages. +// Filters out messages marked as read (via "read" label in beads mode). func (m *Mailbox) ListUnread() ([]*Message, error) { - if m.legacy { - all, err := m.List() - if err != nil { - return nil, err - } - var unread []*Message - for _, msg := range all { - if !msg.Read { - unread = append(unread, msg) - } - } - return unread, nil + all, err := m.List() + if err != nil { + return nil, err } - // For beads, inbox only returns open (unread) messages - return m.List() + var unread []*Message + for _, msg := range all { + if !msg.Read { + unread = append(unread, msg) + } + } + return unread, nil } // Get returns a message by ID.