feat: add --mail flag to gt rig reset to clear stale messages
Closes gt-48bs: gt rig reset now clears stale mail messages. - Non-pinned messages are closed with reason 'Cleared during reset' - Pinned messages have their content cleared but remain open - Works with both --mail flag and default reset (all state)
This commit is contained in:
@@ -547,6 +547,60 @@ func (b *Beads) ClearHandoffContent(role string) error {
|
||||
return b.Update(issue.ID, UpdateOptions{Description: &empty})
|
||||
}
|
||||
|
||||
// ClearMailResult contains statistics from a ClearMail operation.
|
||||
type ClearMailResult struct {
|
||||
Closed int // Number of messages closed
|
||||
Cleared int // Number of pinned messages cleared (content removed)
|
||||
}
|
||||
|
||||
// ClearMail closes or clears all open messages.
|
||||
// Non-pinned messages are closed with the given reason.
|
||||
// Pinned messages have their description cleared but remain open.
|
||||
func (b *Beads) ClearMail(reason string) (*ClearMailResult, error) {
|
||||
// List all open messages
|
||||
issues, err := b.List(ListOptions{
|
||||
Status: "open",
|
||||
Type: "message",
|
||||
Priority: -1,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("listing messages: %w", err)
|
||||
}
|
||||
|
||||
result := &ClearMailResult{}
|
||||
|
||||
// Separate pinned from non-pinned
|
||||
var toClose []string
|
||||
var toClear []*Issue
|
||||
|
||||
for _, issue := range issues {
|
||||
if issue.Status == StatusPinned {
|
||||
toClear = append(toClear, issue)
|
||||
} else {
|
||||
toClose = append(toClose, issue.ID)
|
||||
}
|
||||
}
|
||||
|
||||
// Close non-pinned messages in batch
|
||||
if len(toClose) > 0 {
|
||||
if err := b.CloseWithReason(reason, toClose...); err != nil {
|
||||
return nil, fmt.Errorf("closing messages: %w", err)
|
||||
}
|
||||
result.Closed = len(toClose)
|
||||
}
|
||||
|
||||
// Clear pinned messages
|
||||
empty := ""
|
||||
for _, issue := range toClear {
|
||||
if err := b.Update(issue.ID, UpdateOptions{Description: &empty}); err != nil {
|
||||
return nil, fmt.Errorf("clearing pinned message %s: %w", issue.ID, err)
|
||||
}
|
||||
result.Cleared++
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// MRFields holds the structured fields for a merge-request issue.
|
||||
// These fields are stored as key: value lines in the issue description.
|
||||
type MRFields struct {
|
||||
|
||||
@@ -71,14 +71,15 @@ var rigRemoveCmd = &cobra.Command{
|
||||
|
||||
var rigResetCmd = &cobra.Command{
|
||||
Use: "reset",
|
||||
Short: "Reset rig state (handoff content, etc.)",
|
||||
Short: "Reset rig state (handoff content, mail, etc.)",
|
||||
Long: `Reset various rig state.
|
||||
|
||||
By default, resets all resettable state. Use flags to reset specific items.
|
||||
|
||||
Examples:
|
||||
gt rig reset # Reset all state
|
||||
gt rig reset --handoff # Clear handoff content only`,
|
||||
gt rig reset --handoff # Clear handoff content only
|
||||
gt rig reset --mail # Clear stale mail messages only`,
|
||||
RunE: runRigReset,
|
||||
}
|
||||
|
||||
@@ -113,6 +114,7 @@ var (
|
||||
rigAddPrefix string
|
||||
rigAddCrew string
|
||||
rigResetHandoff bool
|
||||
rigResetMail bool
|
||||
rigResetRole string
|
||||
rigShutdownForce bool
|
||||
rigShutdownNuclear bool
|
||||
@@ -130,6 +132,7 @@ func init() {
|
||||
rigAddCmd.Flags().StringVar(&rigAddCrew, "crew", "main", "Default crew workspace name")
|
||||
|
||||
rigResetCmd.Flags().BoolVar(&rigResetHandoff, "handoff", false, "Clear handoff content")
|
||||
rigResetCmd.Flags().BoolVar(&rigResetMail, "mail", false, "Clear stale mail messages")
|
||||
rigResetCmd.Flags().StringVar(&rigResetRole, "role", "", "Role to reset (default: auto-detect from cwd)")
|
||||
|
||||
rigShutdownCmd.Flags().BoolVarP(&rigShutdownForce, "force", "f", false, "Force immediate shutdown")
|
||||
@@ -319,7 +322,7 @@ func runRigReset(cmd *cobra.Command, args []string) error {
|
||||
}
|
||||
|
||||
// If no specific flags, reset all; otherwise only reset what's specified
|
||||
resetAll := !rigResetHandoff
|
||||
resetAll := !rigResetHandoff && !rigResetMail
|
||||
|
||||
bd := beads.New(townRoot)
|
||||
|
||||
@@ -331,6 +334,20 @@ func runRigReset(cmd *cobra.Command, args []string) error {
|
||||
fmt.Printf("%s Cleared handoff content for %s\n", style.Success.Render("✓"), roleKey)
|
||||
}
|
||||
|
||||
// Clear stale mail messages
|
||||
if resetAll || rigResetMail {
|
||||
result, err := bd.ClearMail("Cleared during reset")
|
||||
if err != nil {
|
||||
return fmt.Errorf("clearing mail: %w", err)
|
||||
}
|
||||
if result.Closed > 0 || result.Cleared > 0 {
|
||||
fmt.Printf("%s Cleared mail: %d closed, %d pinned cleared\n",
|
||||
style.Success.Render("✓"), result.Closed, result.Cleared)
|
||||
} else {
|
||||
fmt.Printf("%s No mail to clear\n", style.Success.Render("✓"))
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user