Merge polecat/Scabrous: polecat done/reset commands (gt-s3m0)

This commit is contained in:
Steve Yegge
2025-12-19 01:54:40 -08:00
2 changed files with 125 additions and 0 deletions

View File

@@ -110,6 +110,39 @@ Example:
RunE: runPolecatSleep,
}
var polecatDoneCmd = &cobra.Command{
Use: "done <rig>/<polecat>",
Aliases: []string{"finish"},
Short: "Mark polecat as done with work and return to idle",
Long: `Mark polecat as done with work and return to idle.
Transitions: working/done/stuck → idle
Clears the assigned issue.
Fails if session is running (stop first).
Example:
gt polecat done gastown/Toast
gt polecat finish gastown/Toast`,
Args: cobra.ExactArgs(1),
RunE: runPolecatDone,
}
var polecatResetCmd = &cobra.Command{
Use: "reset <rig>/<polecat>",
Short: "Force reset polecat to idle state",
Long: `Force reset polecat to idle state.
Transitions: any state → idle
Clears the assigned issue.
Use when polecat is stuck in an unexpected state.
Fails if session is running (stop first).
Example:
gt polecat reset gastown/Toast`,
Args: cobra.ExactArgs(1),
RunE: runPolecatReset,
}
func init() {
// List flags
polecatListCmd.Flags().BoolVar(&polecatListJSON, "json", false, "Output as JSON")
@@ -124,6 +157,8 @@ func init() {
polecatCmd.AddCommand(polecatRemoveCmd)
polecatCmd.AddCommand(polecatWakeCmd)
polecatCmd.AddCommand(polecatSleepCmd)
polecatCmd.AddCommand(polecatDoneCmd)
polecatCmd.AddCommand(polecatResetCmd)
rootCmd.AddCommand(polecatCmd)
}
@@ -360,3 +395,57 @@ func runPolecatSleep(cmd *cobra.Command, args []string) error {
fmt.Printf("%s Polecat %s is now idle.\n", style.SuccessPrefix, polecatName)
return nil
}
func runPolecatDone(cmd *cobra.Command, args []string) error {
rigName, polecatName, err := parseAddress(args[0])
if err != nil {
return err
}
mgr, r, err := getPolecatManager(rigName)
if err != nil {
return err
}
// Check if session is running
t := tmux.NewTmux()
sessMgr := session.NewManager(t, r)
running, _ := sessMgr.IsRunning(polecatName)
if running {
return fmt.Errorf("session is running. Stop it first with: gt session stop %s/%s", rigName, polecatName)
}
if err := mgr.Finish(polecatName); err != nil {
return fmt.Errorf("finishing polecat: %w", err)
}
fmt.Printf("%s Polecat %s is now idle.\n", style.SuccessPrefix, polecatName)
return nil
}
func runPolecatReset(cmd *cobra.Command, args []string) error {
rigName, polecatName, err := parseAddress(args[0])
if err != nil {
return err
}
mgr, r, err := getPolecatManager(rigName)
if err != nil {
return err
}
// Check if session is running
t := tmux.NewTmux()
sessMgr := session.NewManager(t, r)
running, _ := sessMgr.IsRunning(polecatName)
if running {
return fmt.Errorf("session is running. Stop it first with: gt session stop %s/%s", rigName, polecatName)
}
if err := mgr.Reset(polecatName); err != nil {
return fmt.Errorf("resetting polecat: %w", err)
}
fmt.Printf("%s Polecat %s has been reset to idle.\n", style.SuccessPrefix, polecatName)
return nil
}

View File

@@ -245,6 +245,42 @@ func (m *Manager) Sleep(name string) error {
return m.SetState(name, StateIdle)
}
// Finish transitions a polecat from working/done/stuck to idle and clears the issue.
func (m *Manager) Finish(name string) error {
polecat, err := m.Get(name)
if err != nil {
return err
}
// Only allow finishing from working-related states
switch polecat.State {
case StateWorking, StateDone, StateStuck:
// OK to finish
default:
return fmt.Errorf("polecat is not in a finishing state (state: %s)", polecat.State)
}
polecat.Issue = ""
polecat.State = StateIdle
polecat.UpdatedAt = time.Now()
return m.saveState(polecat)
}
// Reset forces a polecat to idle state regardless of current state.
func (m *Manager) Reset(name string) error {
polecat, err := m.Get(name)
if err != nil {
return err
}
polecat.Issue = ""
polecat.State = StateIdle
polecat.UpdatedAt = time.Now()
return m.saveState(polecat)
}
// saveState persists polecat state to disk.
func (m *Manager) saveState(polecat *Polecat) error {
data, err := json.MarshalIndent(polecat, "", " ")