feat(refinery): Auto-detect rig from cwd for refinery commands

All gt refinery subcommands (start, stop, status, queue, attach) now
accept an optional rig argument. If not provided, the rig is inferred
from the current working directory.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Steve Yegge
2025-12-22 13:38:14 -08:00
parent adfa4d5451
commit db87ec7b7b
4 changed files with 71 additions and 49 deletions
+2 -2
View File
@@ -341,7 +341,7 @@ func runMQRetry(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := args[0]
mrID := args[1] mrID := args[1]
mgr, _, err := getRefineryManager(rigName) mgr, _, _, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
@@ -385,7 +385,7 @@ func runMQReject(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := args[0]
mrIDOrBranch := args[1] mrIDOrBranch := args[1]
mgr, _, err := getRefineryManager(rigName) mgr, _, _, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
+1 -1
View File
@@ -15,7 +15,7 @@ import (
func runMQList(cmd *cobra.Command, args []string) error { func runMQList(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := args[0]
_, r, err := getRefineryManager(rigName) _, r, _, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
+67 -45
View File
@@ -4,11 +4,8 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"path/filepath"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/steveyegge/gastown/internal/config"
"github.com/steveyegge/gastown/internal/git"
"github.com/steveyegge/gastown/internal/refinery" "github.com/steveyegge/gastown/internal/refinery"
"github.com/steveyegge/gastown/internal/rig" "github.com/steveyegge/gastown/internal/rig"
"github.com/steveyegge/gastown/internal/style" "github.com/steveyegge/gastown/internal/style"
@@ -34,61 +31,70 @@ into integration branches and ultimately to main.`,
} }
var refineryStartCmd = &cobra.Command{ var refineryStartCmd = &cobra.Command{
Use: "start <rig>", Use: "start [rig]",
Short: "Start the refinery", Short: "Start the refinery",
Long: `Start the Refinery for a rig. Long: `Start the Refinery for a rig.
Launches the merge queue processor which monitors for polecat work branches Launches the merge queue processor which monitors for polecat work branches
and merges them to the appropriate target branches. and merges them to the appropriate target branches.
If rig is not specified, infers it from the current directory.
Examples: Examples:
gt refinery start gastown gt refinery start gastown
gt refinery start gastown --foreground`, gt refinery start gastown --foreground
Args: cobra.ExactArgs(1), gt refinery start # infer rig from cwd`,
Args: cobra.MaximumNArgs(1),
RunE: runRefineryStart, RunE: runRefineryStart,
} }
var refineryStopCmd = &cobra.Command{ var refineryStopCmd = &cobra.Command{
Use: "stop <rig>", Use: "stop [rig]",
Short: "Stop the refinery", Short: "Stop the refinery",
Long: `Stop a running Refinery. Long: `Stop a running Refinery.
Gracefully stops the refinery, completing any in-progress merge first.`, Gracefully stops the refinery, completing any in-progress merge first.
Args: cobra.ExactArgs(1), If rig is not specified, infers it from the current directory.`,
Args: cobra.MaximumNArgs(1),
RunE: runRefineryStop, RunE: runRefineryStop,
} }
var refineryStatusCmd = &cobra.Command{ var refineryStatusCmd = &cobra.Command{
Use: "status <rig>", Use: "status [rig]",
Short: "Show refinery status", Short: "Show refinery status",
Long: `Show the status of a rig's Refinery. Long: `Show the status of a rig's Refinery.
Displays running state, current work, queue length, and statistics.`, Displays running state, current work, queue length, and statistics.
Args: cobra.ExactArgs(1), If rig is not specified, infers it from the current directory.`,
Args: cobra.MaximumNArgs(1),
RunE: runRefineryStatus, RunE: runRefineryStatus,
} }
var refineryQueueCmd = &cobra.Command{ var refineryQueueCmd = &cobra.Command{
Use: "queue <rig>", Use: "queue [rig]",
Short: "Show merge queue", Short: "Show merge queue",
Long: `Show the merge queue for a rig. Long: `Show the merge queue for a rig.
Lists all pending merge requests waiting to be processed.`, Lists all pending merge requests waiting to be processed.
Args: cobra.ExactArgs(1), If rig is not specified, infers it from the current directory.`,
Args: cobra.MaximumNArgs(1),
RunE: runRefineryQueue, RunE: runRefineryQueue,
} }
var refineryAttachCmd = &cobra.Command{ var refineryAttachCmd = &cobra.Command{
Use: "attach <rig>", Use: "attach [rig]",
Short: "Attach to refinery session", Short: "Attach to refinery session",
Long: `Attach to a running Refinery's Claude session. Long: `Attach to a running Refinery's Claude session.
Allows interactive access to the Refinery agent for debugging Allows interactive access to the Refinery agent for debugging
or manual intervention. or manual intervention.
If rig is not specified, infers it from the current directory.
Examples: Examples:
gt refinery attach gastown`, gt refinery attach gastown
Args: cobra.ExactArgs(1), gt refinery attach # infer rig from cwd`,
Args: cobra.MaximumNArgs(1),
RunE: runRefineryAttach, RunE: runRefineryAttach,
} }
@@ -113,20 +119,36 @@ func init() {
} }
// getRefineryManager creates a refinery manager for a rig. // getRefineryManager creates a refinery manager for a rig.
func getRefineryManager(rigName string) (*refinery.Manager, *rig.Rig, error) { // If rigName is empty, infers the rig from cwd.
func getRefineryManager(rigName string) (*refinery.Manager, *rig.Rig, string, error) {
// Infer rig from cwd if not provided
if rigName == "" {
townRoot, err := workspace.FindFromCwdOrError()
if err != nil {
return nil, nil, "", fmt.Errorf("not in a Gas Town workspace: %w", err)
}
rigName, err = inferRigFromCwd(townRoot)
if err != nil {
return nil, nil, "", fmt.Errorf("could not determine rig: %w\nUsage: gt refinery <command> <rig>", err)
}
}
_, r, err := getRig(rigName) _, r, err := getRig(rigName)
if err != nil { if err != nil {
return nil, nil, err return nil, nil, "", err
} }
mgr := refinery.NewManager(r) mgr := refinery.NewManager(r)
return mgr, r, nil return mgr, r, rigName, nil
} }
func runRefineryStart(cmd *cobra.Command, args []string) error { func runRefineryStart(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := ""
if len(args) > 0 {
rigName = args[0]
}
mgr, _, err := getRefineryManager(rigName) mgr, _, rigName, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
@@ -152,9 +174,12 @@ func runRefineryStart(cmd *cobra.Command, args []string) error {
} }
func runRefineryStop(cmd *cobra.Command, args []string) error { func runRefineryStop(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := ""
if len(args) > 0 {
rigName = args[0]
}
mgr, _, err := getRefineryManager(rigName) mgr, _, rigName, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
@@ -172,9 +197,12 @@ func runRefineryStop(cmd *cobra.Command, args []string) error {
} }
func runRefineryStatus(cmd *cobra.Command, args []string) error { func runRefineryStatus(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := ""
if len(args) > 0 {
rigName = args[0]
}
mgr, _, err := getRefineryManager(rigName) mgr, _, rigName, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
@@ -242,9 +270,12 @@ func runRefineryStatus(cmd *cobra.Command, args []string) error {
} }
func runRefineryQueue(cmd *cobra.Command, args []string) error { func runRefineryQueue(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := ""
if len(args) > 0 {
rigName = args[0]
}
mgr, _, err := getRefineryManager(rigName) mgr, _, rigName, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return err return err
} }
@@ -320,11 +351,15 @@ func runRefineryQueue(cmd *cobra.Command, args []string) error {
} }
func runRefineryAttach(cmd *cobra.Command, args []string) error { func runRefineryAttach(cmd *cobra.Command, args []string) error {
rigName := args[0] rigName := ""
if len(args) > 0 {
rigName = args[0]
}
townRoot, err := workspace.FindFromCwdOrError() // Use getRefineryManager to validate rig (and infer from cwd if needed)
_, _, rigName, err := getRefineryManager(rigName)
if err != nil { if err != nil {
return fmt.Errorf("not in a Gas Town workspace: %w", err) return err
} }
// Session name follows the same pattern as refinery manager // Session name follows the same pattern as refinery manager
@@ -340,19 +375,6 @@ func runRefineryAttach(cmd *cobra.Command, args []string) error {
return fmt.Errorf("refinery is not running for rig '%s'", rigName) return fmt.Errorf("refinery is not running for rig '%s'", rigName)
} }
// Verify rig exists
rigsConfigPath := filepath.Join(townRoot, "mayor", "rigs.json")
rigsConfig, err := config.LoadRigsConfig(rigsConfigPath)
if err != nil {
rigsConfig = &config.RigsConfig{Rigs: make(map[string]config.RigEntry)}
}
g := git.NewGit(townRoot)
rigMgr := rig.NewManager(townRoot, rigsConfig, g)
if _, err := rigMgr.GetRig(rigName); err != nil {
return fmt.Errorf("rig '%s' not found", rigName)
}
// Attach to the session // Attach to the session
return t.AttachSession(sessionID) return t.AttachSession(sessionID)
} }
+1 -1
View File
@@ -287,7 +287,7 @@ func runRefineryStatusLine(rigName string) error {
} }
// Get refinery manager using shared helper // Get refinery manager using shared helper
mgr, _, err := getRefineryManager(rigName) mgr, _, _, err := getRefineryManager(rigName)
if err != nil { if err != nil {
// Fallback to simple status if we can't access refinery // Fallback to simple status if we can't access refinery
fmt.Printf("%s MQ: ? |", AgentTypeIcons[AgentRefinery]) fmt.Printf("%s MQ: ? |", AgentTypeIcons[AgentRefinery])