feat(crew): Update gt crew start to use rig-first positional arg (gt-okk2z)

Changed command signature from `gt crew start [name...]` to
`gt crew start <rig> [name]` with --all flag support:

- Takes rig as first required positional argument
- Optional crew member name(s) as subsequent arguments
- --all flag to start all crew members in the rig
- Validates that either name or --all must be provided

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
slit
2026-01-02 12:45:55 -08:00
committed by Steve Yegge
parent c327ea2ca2
commit db316b0c3f
2 changed files with 59 additions and 48 deletions
+20 -18
View File
@@ -239,27 +239,29 @@ var crewPrevCmd = &cobra.Command{
} }
var crewStartCmd = &cobra.Command{ var crewStartCmd = &cobra.Command{
Use: "start [name...]", Use: "start <rig> [name]",
Short: "Start crew workspace(s) (creates if needed)", Short: "Start crew worker(s) in a rig",
Long: `Start one or more crew workspaces, creating them if they don't exist. Long: `Start crew workers in a rig, creating workspaces if they don't exist.
Takes the rig name as the first argument. Optionally specify a crew member name
to start just that worker, or use --all to start all crew members in the rig.
This is an alias for 'gt start crew'. It combines 'gt crew add' and 'gt crew at --detached'.
The crew session starts in the background with Claude running and ready. The crew session starts in the background with Claude running and ready.
The name can include the rig in slash format (e.g., greenplace/joe).
If not specified, the rig is inferred from the current directory.
Role Discovery:
If no name is provided, attempts to detect the crew workspace from the
current directory. If you're in <rig>/crew/<name>/, it will start that
workspace automatically.
Examples: Examples:
gt crew start joe # Start joe in current rig gt crew start gastown joe # Start joe in gastown rig
gt crew start greenplace/joe # Start joe in gastown rig gt crew start gastown --all # Start all crew in gastown rig
gt crew start beads/grip beads/fang # Start multiple crew members gt crew start beads # Error: specify name or --all
gt crew start joe --rig beads # Start joe in beads rig gt crew start beads grip fang # Start grip and fang in beads rig`,
gt crew start # Auto-detect from cwd`, Args: func(cmd *cobra.Command, args []string) error {
if len(args) < 1 {
return fmt.Errorf("requires at least 1 argument: the rig name")
}
if len(args) == 1 && !crewAll {
return fmt.Errorf("specify a crew member name or use --all to start all crew in the rig")
}
return nil
},
RunE: runCrewStart, RunE: runCrewStart,
} }
@@ -294,7 +296,7 @@ func init() {
crewRestartCmd.Flags().BoolVar(&crewAll, "all", false, "Restart all running crew sessions") crewRestartCmd.Flags().BoolVar(&crewAll, "all", false, "Restart all running crew sessions")
crewRestartCmd.Flags().BoolVar(&crewDryRun, "dry-run", false, "Show what would be restarted without restarting") crewRestartCmd.Flags().BoolVar(&crewDryRun, "dry-run", false, "Show what would be restarted without restarting")
crewStartCmd.Flags().StringVar(&crewRig, "rig", "", "Rig to use") crewStartCmd.Flags().BoolVar(&crewAll, "all", false, "Start all crew members in the rig")
crewStartCmd.Flags().StringVar(&crewAccount, "account", "", "Claude Code account handle to use") crewStartCmd.Flags().StringVar(&crewAccount, "account", "", "Claude Code account handle to use")
// Add subcommands // Add subcommands
+40 -31
View File
@@ -216,48 +216,57 @@ func runCrewRefresh(cmd *cobra.Command, args []string) error {
return nil return nil
} }
// runCrewStart is an alias for runStartCrew, handling multiple input formats. // runCrewStart starts crew workers in a rig.
// It supports: "name", "rig/name", "rig/crew/name" formats, or auto-detection from cwd. // args[0] is the rig name (required)
// Multiple names can be provided to start multiple crew members at once. // args[1:] are crew member names (optional, or use --all flag)
func runCrewStart(cmd *cobra.Command, args []string) error { func runCrewStart(cmd *cobra.Command, args []string) error {
// If no args, try to detect from current directory rigName := args[0]
if len(args) == 0 { crewNames := args[1:]
detected, err := detectCrewFromCwd()
// Get the rig manager and rig
crewMgr, r, err := getCrewManager(rigName)
if err != nil { if err != nil {
return fmt.Errorf("could not detect crew workspace from current directory: %w\n\nUsage: gt crew start <name>", err) return err
}
name := detected.crewName
if crewRig == "" {
crewRig = detected.rigName
}
fmt.Printf("Detected crew workspace: %s/%s\n", detected.rigName, name)
startCrewRig = crewRig
startCrewAccount = crewAccount
return runStartCrew(cmd, []string{name})
} }
// Process each name // If --all flag, get all crew members
if crewAll {
workers, err := crewMgr.List()
if err != nil {
return fmt.Errorf("listing crew: %w", err)
}
if len(workers) == 0 {
fmt.Printf("No crew members in rig %s\n", rigName)
return nil
}
for _, w := range workers {
crewNames = append(crewNames, w.Name)
}
}
// Start each crew member
var lastErr error var lastErr error
for _, name := range args { startedCount := 0
// Handle rig/crew/name format (e.g., "gastown/crew/joe" -> "gastown/joe") for _, name := range crewNames {
if strings.Contains(name, "/crew/") { // Set the start.go flags before calling runStartCrew
parts := strings.SplitN(name, "/crew/", 2) startCrewRig = rigName
if len(parts) == 2 && parts[0] != "" && parts[1] != "" {
name = parts[0] + "/" + parts[1]
}
}
// Set the start.go flags from crew.go flags before calling
startCrewRig = crewRig
startCrewAccount = crewAccount startCrewAccount = crewAccount
if err := runStartCrew(cmd, []string{name}); err != nil { // Use rig/name format for runStartCrew
fmt.Printf("Error starting %s: %v\n", name, err) fullName := rigName + "/" + name
if err := runStartCrew(cmd, []string{fullName}); err != nil {
fmt.Printf("Error starting %s/%s: %v\n", rigName, name, err)
lastErr = err lastErr = err
} else {
startedCount++
} }
} }
if startedCount > 0 {
fmt.Printf("\n%s Started %d crew member(s) in %s\n",
style.Bold.Render("✓"), startedCount, r.Name)
}
return lastErr return lastErr
} }