From db87ec7b7b31c800496897f471754d1213919840 Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Mon, 22 Dec 2025 13:38:14 -0800 Subject: [PATCH] feat(refinery): Auto-detect rig from cwd for refinery commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- internal/cmd/mq.go | 4 +- internal/cmd/mq_list.go | 2 +- internal/cmd/refinery.go | 112 ++++++++++++++++++++++--------------- internal/cmd/statusline.go | 2 +- 4 files changed, 71 insertions(+), 49 deletions(-) diff --git a/internal/cmd/mq.go b/internal/cmd/mq.go index 9471b31d..cbf71bf3 100644 --- a/internal/cmd/mq.go +++ b/internal/cmd/mq.go @@ -341,7 +341,7 @@ func runMQRetry(cmd *cobra.Command, args []string) error { rigName := args[0] mrID := args[1] - mgr, _, err := getRefineryManager(rigName) + mgr, _, _, err := getRefineryManager(rigName) if err != nil { return err } @@ -385,7 +385,7 @@ func runMQReject(cmd *cobra.Command, args []string) error { rigName := args[0] mrIDOrBranch := args[1] - mgr, _, err := getRefineryManager(rigName) + mgr, _, _, err := getRefineryManager(rigName) if err != nil { return err } diff --git a/internal/cmd/mq_list.go b/internal/cmd/mq_list.go index f5663458..b83a8394 100644 --- a/internal/cmd/mq_list.go +++ b/internal/cmd/mq_list.go @@ -15,7 +15,7 @@ import ( func runMQList(cmd *cobra.Command, args []string) error { rigName := args[0] - _, r, err := getRefineryManager(rigName) + _, r, _, err := getRefineryManager(rigName) if err != nil { return err } diff --git a/internal/cmd/refinery.go b/internal/cmd/refinery.go index 23d0d222..8161207b 100644 --- a/internal/cmd/refinery.go +++ b/internal/cmd/refinery.go @@ -4,11 +4,8 @@ import ( "encoding/json" "fmt" "os" - "path/filepath" "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/rig" "github.com/steveyegge/gastown/internal/style" @@ -34,61 +31,70 @@ into integration branches and ultimately to main.`, } var refineryStartCmd = &cobra.Command{ - Use: "start ", + Use: "start [rig]", Short: "Start the refinery", Long: `Start the Refinery for a rig. Launches the merge queue processor which monitors for polecat work branches and merges them to the appropriate target branches. +If rig is not specified, infers it from the current directory. + Examples: gt refinery start gastown - gt refinery start gastown --foreground`, - Args: cobra.ExactArgs(1), + gt refinery start gastown --foreground + gt refinery start # infer rig from cwd`, + Args: cobra.MaximumNArgs(1), RunE: runRefineryStart, } var refineryStopCmd = &cobra.Command{ - Use: "stop ", + Use: "stop [rig]", Short: "Stop the refinery", Long: `Stop a running Refinery. -Gracefully stops the refinery, completing any in-progress merge first.`, - Args: cobra.ExactArgs(1), +Gracefully stops the refinery, completing any in-progress merge first. +If rig is not specified, infers it from the current directory.`, + Args: cobra.MaximumNArgs(1), RunE: runRefineryStop, } var refineryStatusCmd = &cobra.Command{ - Use: "status ", + Use: "status [rig]", Short: "Show refinery status", Long: `Show the status of a rig's Refinery. -Displays running state, current work, queue length, and statistics.`, - Args: cobra.ExactArgs(1), +Displays running state, current work, queue length, and statistics. +If rig is not specified, infers it from the current directory.`, + Args: cobra.MaximumNArgs(1), RunE: runRefineryStatus, } var refineryQueueCmd = &cobra.Command{ - Use: "queue ", + Use: "queue [rig]", Short: "Show merge queue", Long: `Show the merge queue for a rig. -Lists all pending merge requests waiting to be processed.`, - Args: cobra.ExactArgs(1), +Lists all pending merge requests waiting to be processed. +If rig is not specified, infers it from the current directory.`, + Args: cobra.MaximumNArgs(1), RunE: runRefineryQueue, } var refineryAttachCmd = &cobra.Command{ - Use: "attach ", + Use: "attach [rig]", Short: "Attach to refinery session", Long: `Attach to a running Refinery's Claude session. Allows interactive access to the Refinery agent for debugging or manual intervention. +If rig is not specified, infers it from the current directory. + Examples: - gt refinery attach gastown`, - Args: cobra.ExactArgs(1), + gt refinery attach gastown + gt refinery attach # infer rig from cwd`, + Args: cobra.MaximumNArgs(1), RunE: runRefineryAttach, } @@ -113,20 +119,36 @@ func init() { } // 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 ", err) + } + } + _, r, err := getRig(rigName) if err != nil { - return nil, nil, err + return nil, nil, "", err } mgr := refinery.NewManager(r) - return mgr, r, nil + return mgr, r, rigName, nil } 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 { return err } @@ -152,9 +174,12 @@ func runRefineryStart(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 { return err } @@ -172,9 +197,12 @@ func runRefineryStop(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 { return err } @@ -242,9 +270,12 @@ func runRefineryStatus(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 { return err } @@ -320,11 +351,15 @@ func runRefineryQueue(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 { - return fmt.Errorf("not in a Gas Town workspace: %w", err) + return err } // 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) } - // 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 return t.AttachSession(sessionID) } diff --git a/internal/cmd/statusline.go b/internal/cmd/statusline.go index dbb61841..0acec428 100644 --- a/internal/cmd/statusline.go +++ b/internal/cmd/statusline.go @@ -287,7 +287,7 @@ func runRefineryStatusLine(rigName string) error { } // Get refinery manager using shared helper - mgr, _, err := getRefineryManager(rigName) + mgr, _, _, err := getRefineryManager(rigName) if err != nil { // Fallback to simple status if we can't access refinery fmt.Printf("%s MQ: ? |", AgentTypeIcons[AgentRefinery])