From 196c3bbf9bdbc9e6fa5420cb89cd521470f366fd Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Mon, 29 Dec 2025 22:04:39 -0800 Subject: [PATCH] Fix gt sling --naked to bypass pane lookup for terminated polecats MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When slinging to an existing polecat with --naked flag, the code was still attempting to look up the tmux pane, which fails for terminated polecats. Now resolveTargetAgent accepts a skipPane parameter that bypasses the tmux pane and working directory lookup when true. This allows work to be slung to terminated polecats that will be restarted manually later. Also updated unsling to skip pane lookup since it only needs the agent ID. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- internal/cmd/sling.go | 19 ++++++++++++++----- internal/cmd/unsling.go | 3 ++- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/internal/cmd/sling.go b/internal/cmd/sling.go index 3c938dcb..f5d1af18 100644 --- a/internal/cmd/sling.go +++ b/internal/cmd/sling.go @@ -183,7 +183,8 @@ func runSling(cmd *cobra.Command, args []string) error { } } else { // Slinging to an existing agent - targetAgent, targetPane, _, err = resolveTargetAgent(target) + // Skip pane lookup if --naked (agent may be terminated) + targetAgent, targetPane, _, err = resolveTargetAgent(target, slingNaked) if err != nil { return fmt.Errorf("resolving target: %w", err) } @@ -340,13 +341,22 @@ func injectStartPrompt(pane, beadID, subject, args string) error { } // resolveTargetAgent converts a target spec to agent ID, pane, and hook root. -func resolveTargetAgent(target string) (agentID string, pane string, hookRoot string, err error) { +// If skipPane is true, skip tmux pane lookup (for --naked mode). +func resolveTargetAgent(target string, skipPane bool) (agentID string, pane string, hookRoot string, err error) { // First resolve to session name sessionName, err := resolveRoleToSession(target) if err != nil { return "", "", "", err } + // Convert session name to agent ID format (this doesn't require tmux) + agentID = sessionToAgentID(sessionName) + + // Skip pane lookup if requested (--naked mode) + if skipPane { + return agentID, "", "", nil + } + // Get the pane for that session pane, err = getSessionPane(sessionName) if err != nil { @@ -360,8 +370,6 @@ func resolveTargetAgent(target string) (agentID string, pane string, hookRoot st return "", "", "", fmt.Errorf("getting working dir for %s: %w", sessionName, err) } - // Convert session name back to agent ID format - agentID = sessionToAgentID(sessionName) return agentID, pane, hookRoot, nil } @@ -523,7 +531,8 @@ func runSlingFormula(args []string) error { } } else { // Slinging to an existing agent - targetAgent, targetPane, _, err = resolveTargetAgent(target) + // Skip pane lookup if --naked (agent may be terminated) + targetAgent, targetPane, _, err = resolveTargetAgent(target, slingNaked) if err != nil { return fmt.Errorf("resolving target: %w", err) } diff --git a/internal/cmd/unsling.go b/internal/cmd/unsling.go index b7eb810c..9ddd72da 100644 --- a/internal/cmd/unsling.go +++ b/internal/cmd/unsling.go @@ -71,7 +71,8 @@ func runUnsling(cmd *cobra.Command, args []string) error { var agentID string var err error if targetAgent != "" { - agentID, _, _, err = resolveTargetAgent(targetAgent) + // Skip pane lookup - unsling only needs agent ID, not tmux session + agentID, _, _, err = resolveTargetAgent(targetAgent, true) if err != nil { return fmt.Errorf("resolving target agent: %w", err) }