feat: add gt mail mark-read command for desire path (bd-rjuu6)

Adds mark-read and mark-unread commands that allow marking messages
as read without archiving them. Uses a "read" label to track status.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
beads/crew/fang
2026-01-11 00:03:35 -08:00
committed by Steve Yegge
parent 2c73cf35f1
commit 1418b1123a
4 changed files with 196 additions and 9 deletions

View File

@@ -371,6 +371,61 @@ func (m *Mailbox) markReadLegacy(id string) error {
return m.rewriteLegacy(messages)
}
// MarkReadOnly marks a message as read WITHOUT archiving/closing it.
// For beads mode, this adds a "read" label to the message.
// For legacy mode, this sets the Read field to true.
// The message remains in the inbox but is displayed as read.
func (m *Mailbox) MarkReadOnly(id string) error {
if m.legacy {
return m.markReadLegacy(id)
}
return m.markReadOnlyBeads(id)
}
func (m *Mailbox) markReadOnlyBeads(id string) error {
// Add "read" label to mark as read without closing
args := []string{"label", "add", id, "read"}
_, err := runBdCommand(args, m.workDir, m.beadsDir)
if err != nil {
if bdErr, ok := err.(*bdError); ok && bdErr.ContainsError("not found") {
return ErrMessageNotFound
}
return err
}
return nil
}
// MarkUnreadOnly marks a message as unread (removes "read" label).
// For beads mode, this removes the "read" label from the message.
// For legacy mode, this sets the Read field to false.
func (m *Mailbox) MarkUnreadOnly(id string) error {
if m.legacy {
return m.markUnreadLegacy(id)
}
return m.markUnreadOnlyBeads(id)
}
func (m *Mailbox) markUnreadOnlyBeads(id string) error {
// Remove "read" label to mark as unread
args := []string{"label", "remove", id, "read"}
_, err := runBdCommand(args, m.workDir, m.beadsDir)
if err != nil {
if bdErr, ok := err.(*bdError); ok && bdErr.ContainsError("not found") {
return ErrMessageNotFound
}
// Ignore error if label doesn't exist
if bdErr, ok := err.(*bdError); ok && bdErr.ContainsError("does not have label") {
return nil
}
return err
}
return nil
}
// MarkUnread marks a message as unread (reopens in beads).
func (m *Mailbox) MarkUnread(id string) error {
if m.legacy {
@@ -686,15 +741,11 @@ func (m *Mailbox) Count() (total, unread int, err error) {
}
total = len(messages)
if m.legacy {
for _, msg := range messages {
if !msg.Read {
unread++
}
// Count messages that are NOT marked as read (including via "read" label)
for _, msg := range messages {
if !msg.Read {
unread++
}
} else {
// For beads, inbox only returns unread
unread = total
}
return total, unread, nil