feat(mail): add numeric index support to 'gt mail read'

Allow reading messages by their inbox position (e.g., 'gt mail read 3')
in addition to message ID. The inbox display now shows 1-based index
numbers for easy reference.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
dementus
2026-01-21 17:31:26 -08:00
committed by beads/crew/emma
parent 785d9adfef
commit b612df0463
2 changed files with 35 additions and 10 deletions

View File

@@ -154,15 +154,21 @@ Examples:
} }
var mailReadCmd = &cobra.Command{ var mailReadCmd = &cobra.Command{
Use: "read <message-id>", Use: "read <message-id|index>",
Short: "Read a message", Short: "Read a message",
Long: `Read a specific message (does not mark as read). Long: `Read a specific message (does not mark as read).
The message ID can be found from 'gt mail inbox'. You can specify a message by its ID or by its numeric index from the inbox.
The index corresponds to the number shown in 'gt mail inbox' (1-based).
Examples:
gt mail read hq-abc123 # Read by message ID
gt mail read 3 # Read the 3rd message in inbox
Use 'gt mail mark-read' to mark messages as read.`, Use 'gt mail mark-read' to mark messages as read.`,
Aliases: []string{"show"}, Aliases: []string{"show"},
Args: cobra.ExactArgs(1), Args: cobra.ExactArgs(1),
RunE: runMailRead, RunE: runMailRead,
} }
var mailPeekCmd = &cobra.Command{ var mailPeekCmd = &cobra.Command{

View File

@@ -5,6 +5,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"os" "os"
"strconv"
"strings" "strings"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -80,7 +81,7 @@ func runMailInbox(cmd *cobra.Command, args []string) error {
return nil return nil
} }
for _, msg := range messages { for i, msg := range messages {
readMarker := "●" readMarker := "●"
if msg.Read { if msg.Read {
readMarker = "○" readMarker = "○"
@@ -98,11 +99,13 @@ func runMailInbox(cmd *cobra.Command, args []string) error {
wispMarker = " " + style.Dim.Render("(wisp)") wispMarker = " " + style.Dim.Render("(wisp)")
} }
fmt.Printf(" %s %s%s%s%s\n", readMarker, msg.Subject, typeMarker, priorityMarker, wispMarker) // Show 1-based index for easy reference with 'gt mail read <n>'
fmt.Printf(" %s from %s\n", indexStr := style.Dim.Render(fmt.Sprintf("%d.", i+1))
fmt.Printf(" %s %s %s%s%s%s\n", indexStr, readMarker, msg.Subject, typeMarker, priorityMarker, wispMarker)
fmt.Printf(" %s from %s\n",
style.Dim.Render(msg.ID), style.Dim.Render(msg.ID),
msg.From) msg.From)
fmt.Printf(" %s\n", fmt.Printf(" %s\n",
style.Dim.Render(msg.Timestamp.Format("2006-01-02 15:04"))) style.Dim.Render(msg.Timestamp.Format("2006-01-02 15:04")))
} }
@@ -111,9 +114,9 @@ func runMailInbox(cmd *cobra.Command, args []string) error {
func runMailRead(cmd *cobra.Command, args []string) error { func runMailRead(cmd *cobra.Command, args []string) error {
if len(args) == 0 { if len(args) == 0 {
return errors.New("msgID argument required") return errors.New("message ID or index required")
} }
msgID := args[0] msgRef := args[0]
// Determine which inbox // Determine which inbox
address := detectSender() address := detectSender()
@@ -123,6 +126,22 @@ func runMailRead(cmd *cobra.Command, args []string) error {
return err return err
} }
// Check if the argument is a numeric index (1-based)
var msgID string
if idx, err := strconv.Atoi(msgRef); err == nil && idx > 0 {
// Numeric index: resolve to message ID by listing inbox
messages, err := mailbox.List()
if err != nil {
return fmt.Errorf("listing messages: %w", err)
}
if idx > len(messages) {
return fmt.Errorf("index %d out of range (inbox has %d messages)", idx, len(messages))
}
msgID = messages[idx-1].ID
} else {
msgID = msgRef
}
msg, err := mailbox.Get(msgID) msg, err := mailbox.Get(msgID)
if err != nil { if err != nil {
return fmt.Errorf("getting message: %w", err) return fmt.Errorf("getting message: %w", err)