package main import ( "context" "fmt" "os" "sort" "strings" "github.com/spf13/cobra" "github.com/steveyegge/beads/internal/syncbranch" ) var configCmd = &cobra.Command{ Use: "config", Short: "Manage configuration settings", Long: `Manage configuration settings for external integrations and preferences. Configuration is stored per-project in .beads/*.db and is version-control-friendly. Common namespaces: - jira.* Jira integration settings - linear.* Linear integration settings - github.* GitHub integration settings - custom.* Custom integration settings Examples: bd config set jira.url "https://company.atlassian.net" bd config set jira.project "PROJ" bd config get jira.url bd config list bd config unset jira.url`, } var configSetCmd = &cobra.Command{ Use: "set ", Short: "Set a configuration value", Args: cobra.ExactArgs(2), Run: func(_ *cobra.Command, args []string) { // Config operations work in direct mode only if err := ensureDirectMode("config set requires direct database access"); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } key := args[0] value := args[1] ctx := context.Background() // Special handling for sync.branch to apply validation if strings.TrimSpace(key) == syncbranch.ConfigKey { if err := syncbranch.Set(ctx, store, value); err != nil { fmt.Fprintf(os.Stderr, "Error setting config: %v\n", err) os.Exit(1) } } else { if err := store.SetConfig(ctx, key, value); err != nil { fmt.Fprintf(os.Stderr, "Error setting config: %v\n", err) os.Exit(1) } } if jsonOutput { outputJSON(map[string]string{ "key": key, "value": value, }) } else { fmt.Printf("Set %s = %s\n", key, value) } }, } var configGetCmd = &cobra.Command{ Use: "get ", Short: "Get a configuration value", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { // Config operations work in direct mode only if err := ensureDirectMode("config get requires direct database access"); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } key := args[0] ctx := context.Background() var value string var err error // Special handling for sync.branch to support env var override if strings.TrimSpace(key) == syncbranch.ConfigKey { value, err = syncbranch.Get(ctx, store) } else { value, err = store.GetConfig(ctx, key) } if err != nil { fmt.Fprintf(os.Stderr, "Error getting config: %v\n", err) os.Exit(1) } if jsonOutput { outputJSON(map[string]string{ "key": key, "value": value, }) } else { if value == "" { fmt.Printf("%s (not set)\n", key) } else { fmt.Printf("%s\n", value) } } }, } var configListCmd = &cobra.Command{ Use: "list", Short: "List all configuration", Run: func(cmd *cobra.Command, args []string) { // Config operations work in direct mode only if err := ensureDirectMode("config list requires direct database access"); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } ctx := context.Background() config, err := store.GetAllConfig(ctx) if err != nil { fmt.Fprintf(os.Stderr, "Error listing config: %v\n", err) os.Exit(1) } if jsonOutput { outputJSON(config) return } if len(config) == 0 { fmt.Println("No configuration set") return } // Sort keys for consistent output keys := make([]string, 0, len(config)) for k := range config { keys = append(keys, k) } sort.Strings(keys) fmt.Println("\nConfiguration:") for _, k := range keys { fmt.Printf(" %s = %s\n", k, config[k]) } }, } var configUnsetCmd = &cobra.Command{ Use: "unset ", Short: "Delete a configuration value", Args: cobra.ExactArgs(1), Run: func(cmd *cobra.Command, args []string) { // Config operations work in direct mode only if err := ensureDirectMode("config unset requires direct database access"); err != nil { fmt.Fprintf(os.Stderr, "Error: %v\n", err) os.Exit(1) } key := args[0] ctx := context.Background() if err := store.DeleteConfig(ctx, key); err != nil { fmt.Fprintf(os.Stderr, "Error deleting config: %v\n", err) os.Exit(1) } if jsonOutput { outputJSON(map[string]string{ "key": key, }) } else { fmt.Printf("Unset %s\n", key) } }, } func init() { configCmd.AddCommand(configSetCmd) configCmd.AddCommand(configGetCmd) configCmd.AddCommand(configListCmd) configCmd.AddCommand(configUnsetCmd) rootCmd.AddCommand(configCmd) }