fix: Parse rig/name format in crew commands

All crew commands now accept "rig/name" syntax (e.g., "beads/emma")
in addition to requiring --rig flag. The rig is extracted from the
first path component.

Affected commands:
- gt crew at
- gt crew restart
- gt crew refresh
- gt crew remove
- gt crew rename
- gt crew status
- gt crew pristine

🤖 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-25 11:33:54 -08:00
parent e0a2187636
commit f808b3bd51
5 changed files with 70 additions and 4 deletions

View File

@@ -19,6 +19,13 @@ func runCrewAt(cmd *cobra.Command, args []string) error {
// Determine crew name: from arg, or auto-detect from cwd
if len(args) > 0 {
name = args[0]
// Parse rig/name format (e.g., "beads/emma" -> rig=beads, name=emma)
if rig, crewName, ok := parseRigSlashName(name); ok {
if crewRig == "" {
crewRig = rig
}
name = crewName
}
} else {
// Try to detect from current directory
detected, err := detectCrewFromCwd()

View File

@@ -69,6 +69,21 @@ func crewSessionName(rigName, crewName string) string {
return fmt.Sprintf("gt-%s-crew-%s", rigName, crewName)
}
// parseRigSlashName parses "rig/name" format into separate rig and name parts.
// Returns (rig, name, true) if the format matches, or ("", original, false) if not.
// Examples:
// - "beads/emma" -> ("beads", "emma", true)
// - "emma" -> ("", "emma", false)
// - "beads/crew/emma" -> ("beads", "crew/emma", true) - only first slash splits
func parseRigSlashName(input string) (rig, name string, ok bool) {
// Only split on first slash to handle edge cases
idx := strings.Index(input, "/")
if idx == -1 {
return "", input, false
}
return input[:idx], input[idx+1:], true
}
// crewDetection holds the result of detecting crew workspace from cwd.
type crewDetection struct {
rigName string

View File

@@ -15,6 +15,13 @@ import (
func runCrewRemove(cmd *cobra.Command, args []string) error {
name := args[0]
// Parse rig/name format (e.g., "beads/emma" -> rig=beads, name=emma)
if rig, crewName, ok := parseRigSlashName(name); ok {
if crewRig == "" {
crewRig = rig
}
name = crewName
}
crewMgr, r, err := getCrewManager(crewRig)
if err != nil {
@@ -59,6 +66,13 @@ func runCrewRemove(cmd *cobra.Command, args []string) error {
func runCrewRefresh(cmd *cobra.Command, args []string) error {
name := args[0]
// Parse rig/name format (e.g., "beads/emma" -> rig=beads, name=emma)
if rig, crewName, ok := parseRigSlashName(name); ok {
if crewRig == "" {
crewRig = rig
}
name = crewName
}
crewMgr, r, err := getCrewManager(crewRig)
if err != nil {
@@ -143,6 +157,13 @@ func runCrewRefresh(cmd *cobra.Command, args []string) error {
func runCrewRestart(cmd *cobra.Command, args []string) error {
name := args[0]
// Parse rig/name format (e.g., "beads/emma" -> rig=beads, name=emma)
if rig, crewName, ok := parseRigSlashName(name); ok {
if crewRig == "" {
crewRig = rig
}
name = crewName
}
crewMgr, r, err := getCrewManager(crewRig)
if err != nil {

View File

@@ -14,6 +14,14 @@ import (
func runCrewRename(cmd *cobra.Command, args []string) error {
oldName := args[0]
newName := args[1]
// Parse rig/name format for oldName (e.g., "beads/emma" -> rig=beads, name=emma)
if rig, crewName, ok := parseRigSlashName(oldName); ok {
if crewRig == "" {
crewRig = rig
}
oldName = crewName
}
// Note: newName is just the new name, no rig prefix expected
crewMgr, r, err := getCrewManager(crewRig)
if err != nil {
@@ -59,6 +67,10 @@ func runCrewPristine(cmd *cobra.Command, args []string) error {
if len(args) > 0 {
// Specific worker
name := args[0]
// Parse rig/name format (e.g., "beads/emma" -> rig=beads, name=emma)
if _, crewName, ok := parseRigSlashName(name); ok {
name = crewName
}
worker, err := crewMgr.Get(name)
if err != nil {
if err == crew.ErrCrewNotFound {

View File

@@ -31,6 +31,18 @@ type CrewStatusItem struct {
}
func runCrewStatus(cmd *cobra.Command, args []string) error {
// Parse rig/name format before getting manager (e.g., "beads/emma" -> rig=beads, name=emma)
var targetName string
if len(args) > 0 {
targetName = args[0]
if rig, crewName, ok := parseRigSlashName(targetName); ok {
if crewRig == "" {
crewRig = rig
}
targetName = crewName
}
}
crewMgr, r, err := getCrewManager(crewRig)
if err != nil {
return err
@@ -38,13 +50,12 @@ func runCrewStatus(cmd *cobra.Command, args []string) error {
var workers []*crew.CrewWorker
if len(args) > 0 {
if targetName != "" {
// Specific worker
name := args[0]
worker, err := crewMgr.Get(name)
worker, err := crewMgr.Get(targetName)
if err != nil {
if err == crew.ErrCrewNotFound {
return fmt.Errorf("crew workspace '%s' not found", name)
return fmt.Errorf("crew workspace '%s' not found", targetName)
}
return fmt.Errorf("getting crew worker: %w", err)
}