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})
|
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.
|
// MRFields holds the structured fields for a merge-request issue.
|
||||||
// These fields are stored as key: value lines in the issue description.
|
// These fields are stored as key: value lines in the issue description.
|
||||||
type MRFields struct {
|
type MRFields struct {
|
||||||
|
|||||||
@@ -71,14 +71,15 @@ var rigRemoveCmd = &cobra.Command{
|
|||||||
|
|
||||||
var rigResetCmd = &cobra.Command{
|
var rigResetCmd = &cobra.Command{
|
||||||
Use: "reset",
|
Use: "reset",
|
||||||
Short: "Reset rig state (handoff content, etc.)",
|
Short: "Reset rig state (handoff content, mail, etc.)",
|
||||||
Long: `Reset various rig state.
|
Long: `Reset various rig state.
|
||||||
|
|
||||||
By default, resets all resettable state. Use flags to reset specific items.
|
By default, resets all resettable state. Use flags to reset specific items.
|
||||||
|
|
||||||
Examples:
|
Examples:
|
||||||
gt rig reset # Reset all state
|
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,
|
RunE: runRigReset,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,6 +114,7 @@ var (
|
|||||||
rigAddPrefix string
|
rigAddPrefix string
|
||||||
rigAddCrew string
|
rigAddCrew string
|
||||||
rigResetHandoff bool
|
rigResetHandoff bool
|
||||||
|
rigResetMail bool
|
||||||
rigResetRole string
|
rigResetRole string
|
||||||
rigShutdownForce bool
|
rigShutdownForce bool
|
||||||
rigShutdownNuclear bool
|
rigShutdownNuclear bool
|
||||||
@@ -130,6 +132,7 @@ func init() {
|
|||||||
rigAddCmd.Flags().StringVar(&rigAddCrew, "crew", "main", "Default crew workspace name")
|
rigAddCmd.Flags().StringVar(&rigAddCrew, "crew", "main", "Default crew workspace name")
|
||||||
|
|
||||||
rigResetCmd.Flags().BoolVar(&rigResetHandoff, "handoff", false, "Clear handoff content")
|
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)")
|
rigResetCmd.Flags().StringVar(&rigResetRole, "role", "", "Role to reset (default: auto-detect from cwd)")
|
||||||
|
|
||||||
rigShutdownCmd.Flags().BoolVarP(&rigShutdownForce, "force", "f", false, "Force immediate shutdown")
|
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
|
// If no specific flags, reset all; otherwise only reset what's specified
|
||||||
resetAll := !rigResetHandoff
|
resetAll := !rigResetHandoff && !rigResetMail
|
||||||
|
|
||||||
bd := beads.New(townRoot)
|
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)
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user