From 42d8944f713680f6aa728cdd725dc5abf8ccbecf Mon Sep 17 00:00:00 2001 From: Steve Yegge Date: Tue, 23 Dec 2025 04:47:07 -0800 Subject: [PATCH] feat: default crew name to 'max', support town-level override - Add DefaultCrewName constant ('max') to config package - Add default_crew_name field to MayorConfig for town-level override - Update gt rig add to resolve crew name: --crew flag > town config > default - Update help text to reflect new default Priority: --crew flag > MayorConfig.DefaultCrewName > config.DefaultCrewName ('max') --- internal/cmd/rig.go | 22 +++++++++++++++++----- internal/config/types.go | 14 +++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/internal/cmd/rig.go b/internal/cmd/rig.go index 06a875dd..36d0b407 100644 --- a/internal/cmd/rig.go +++ b/internal/cmd/rig.go @@ -48,7 +48,7 @@ This creates a rig container with: - plugins/ Rig-level plugin directory - refinery/rig/ Canonical main clone - mayor/rig/ Mayor's working clone - - crew/main/ Default human workspace + - crew/max/ Default human workspace - witness/ Witness agent directory - polecats/ Worker directory (empty) @@ -141,7 +141,7 @@ func init() { rigCmd.AddCommand(rigShutdownCmd) rigAddCmd.Flags().StringVar(&rigAddPrefix, "prefix", "", "Beads issue prefix (default: derived from name)") - rigAddCmd.Flags().StringVar(&rigAddCrew, "crew", "main", "Default crew workspace name") + rigAddCmd.Flags().StringVar(&rigAddCrew, "crew", "", "Crew workspace name (default: from town config or 'max')") rigResetCmd.Flags().BoolVar(&rigResetHandoff, "handoff", false, "Clear handoff content") rigResetCmd.Flags().BoolVar(&rigResetMail, "mail", false, "Clear stale mail messages") @@ -163,6 +163,18 @@ func runRigAdd(cmd *cobra.Command, args []string) error { return fmt.Errorf("not in a Gas Town workspace: %w", err) } + // Resolve crew name: --crew flag > town config > default constant + crewName := rigAddCrew + if crewName == "" { + // Try loading MayorConfig for default_crew_name + mayorConfigPath := filepath.Join(townRoot, "mayor", "config.json") + if mayorCfg, err := config.LoadMayorConfig(mayorConfigPath); err == nil && mayorCfg.DefaultCrewName != "" { + crewName = mayorCfg.DefaultCrewName + } else { + crewName = config.DefaultCrewName + } + } + // Load rigs config rigsPath := filepath.Join(townRoot, "mayor", "rigs.json") rigsConfig, err := config.LoadRigsConfig(rigsPath) @@ -188,7 +200,7 @@ func runRigAdd(cmd *cobra.Command, args []string) error { Name: name, GitURL: gitURL, BeadsPrefix: rigAddPrefix, - CrewName: rigAddCrew, + CrewName: crewName, }) if err != nil { return fmt.Errorf("adding rig: %w", err) @@ -210,12 +222,12 @@ func runRigAdd(cmd *cobra.Command, args []string) error { fmt.Printf(" ├── plugins/ (rig-level plugins)\n") fmt.Printf(" ├── refinery/rig/ (canonical main)\n") fmt.Printf(" ├── mayor/rig/ (mayor's clone)\n") - fmt.Printf(" ├── crew/%s/ (your workspace)\n", rigAddCrew) + fmt.Printf(" ├── crew/%s/ (your workspace)\n", crewName) fmt.Printf(" ├── witness/\n") fmt.Printf(" └── polecats/\n") fmt.Printf("\nNext steps:\n") - fmt.Printf(" cd %s/crew/%s # Work in your clone\n", filepath.Join(townRoot, name), rigAddCrew) + fmt.Printf(" cd %s/crew/%s # Work in your clone\n", filepath.Join(townRoot, name), crewName) fmt.Printf(" bd ready # See available work\n") return nil diff --git a/internal/config/types.go b/internal/config/types.go index b1f2d959..05bb8732 100644 --- a/internal/config/types.go +++ b/internal/config/types.go @@ -17,11 +17,12 @@ type TownConfig struct { // MayorConfig represents town-level behavioral configuration (mayor/config.json). // This is separate from TownConfig (identity) to keep configuration concerns distinct. type MayorConfig struct { - Type string `json:"type"` // "mayor-config" - Version int `json:"version"` // schema version - Theme *TownThemeConfig `json:"theme,omitempty"` // global theme settings - Daemon *DaemonConfig `json:"daemon,omitempty"` // daemon settings - Deacon *DeaconConfig `json:"deacon,omitempty"` // deacon settings + Type string `json:"type"` // "mayor-config" + Version int `json:"version"` // schema version + Theme *TownThemeConfig `json:"theme,omitempty"` // global theme settings + Daemon *DaemonConfig `json:"daemon,omitempty"` // daemon settings + Deacon *DeaconConfig `json:"deacon,omitempty"` // deacon settings + DefaultCrewName string `json:"default_crew_name,omitempty"` // default crew name for new rigs } // DaemonConfig represents daemon process settings. @@ -38,6 +39,9 @@ type DeaconConfig struct { // CurrentMayorConfigVersion is the current schema version for MayorConfig. const CurrentMayorConfigVersion = 1 +// DefaultCrewName is the default name for crew workspaces when not overridden. +const DefaultCrewName = "max" + // RigsConfig represents the rigs registry (mayor/rigs.json). type RigsConfig struct { Version int `json:"version"`