package main import ( "bufio" "fmt" "os" "path/filepath" "strings" "github.com/pelletier/go-toml/v2" ) type Config struct { LLMProviderURL string `toml:"LLMProviderURL"` APIKey string `toml:"APIKey"` ShellType string `toml:"ShellType"` ModelName string `toml:"ModelName"` ColorScheme string `toml:"ColorScheme"` } func loadOrCreateConfig(path string) (*Config, error) { // Check if config file exists if _, err := os.Stat(path); os.IsNotExist(err) { fmt.Printf("Config file %s does not exist.\n", path) fmt.Printf("Would you like to create it? (Y/n) ") reader := bufio.NewReader(os.Stdin) response, err := reader.ReadString('\n') if err != nil { return nil, fmt.Errorf("failed to read response: %v", err) } response = strings.TrimSpace(strings.ToLower(response)) // Default to 'y' if empty, or check for 'n' to decline if response == "n" || response == "no" { return nil, fmt.Errorf("config file is required") } // Create config directory if it doesn't exist configDir := filepath.Dir(path) if err := os.MkdirAll(configDir, 0755); err != nil { return nil, fmt.Errorf("failed to create config directory: %v", err) } // Get config values from user config, err := promptForConfig() if err != nil { return nil, err } // Write config file file, err := os.Create(path) if err != nil { return nil, fmt.Errorf("failed to create config file: %v", err) } defer file.Close() encoder := toml.NewEncoder(file) if err := encoder.Encode(config); err != nil { return nil, fmt.Errorf("failed to write config file: %v", err) } fmt.Printf("Config file created at %s\n", path) return config, nil } // Config file exists, load it file, err := os.Open(path) if err != nil { return nil, fmt.Errorf("failed to open config file: %v", err) } defer file.Close() var config Config decoder := toml.NewDecoder(file) if err := decoder.Decode(&config); err != nil { return nil, fmt.Errorf("failed to parse config file: %v", err) } return &config, nil } func promptForConfig() (*Config, error) { reader := bufio.NewReader(os.Stdin) config := &Config{ LLMProviderURL: "https://openrouter.ai/api/v1/chat/completions", ShellType: "fish", ModelName: "anthropic/claude-sonnet-4", ColorScheme: "light", } // Ask questions in sequence fmt.Printf("LLM Provider URL [%s]: ", config.LLMProviderURL) urlInput, _ := reader.ReadString('\n') urlInput = strings.TrimSpace(urlInput) if urlInput != "" { config.LLMProviderURL = urlInput } fmt.Print("API Key: ") apiKey, _ := reader.ReadString('\n') config.APIKey = strings.TrimSpace(apiKey) if config.APIKey == "" { return nil, fmt.Errorf("API key is required") } fmt.Printf("Shell Type [%s]: ", config.ShellType) shellInput, _ := reader.ReadString('\n') shellInput = strings.TrimSpace(shellInput) if shellInput != "" { config.ShellType = shellInput } fmt.Printf("Model Name [%s]: ", config.ModelName) modelInput, _ := reader.ReadString('\n') modelInput = strings.TrimSpace(modelInput) if modelInput != "" { config.ModelName = modelInput } fmt.Printf("Color Scheme (light/dark) [%s]: ", config.ColorScheme) colorInput, _ := reader.ReadString('\n') colorInput = strings.TrimSpace(colorInput) if colorInput == "light" || colorInput == "dark" { config.ColorScheme = colorInput } else if colorInput != "" { fmt.Println("Invalid color scheme, using default (light)") } return config, nil }