package config import ( "fmt" "os" "path/filepath" "gopkg.in/yaml.v3" ) // Config holds the application configuration type Config struct { // LLM Configuration APIURL string `yaml:"api_url"` Model string `yaml:"model"` ContextSize int `yaml:"context_size"` APIKey string `yaml:"api_key"` // System Prompt Prompt string `yaml:"prompt"` // MCP Server Configuration MCPServers map[string]MCPServer `yaml:"mcp_servers"` } // MCPServer represents a single MCP server configuration (stdio transport only) type MCPServer struct { Command string `yaml:"command"` Args []string `yaml:"args,omitempty"` Env map[string]string `yaml:"env,omitempty"` } // Load reads and parses the YAML configuration file from ~/.config/tell-me.yaml func Load() (*Config, error) { // Get home directory homeDir, err := os.UserHomeDir() if err != nil { return nil, fmt.Errorf("failed to get home directory: %w", err) } // Build config path configPath := filepath.Join(homeDir, ".config", "tell-me.yaml") // Check if config file exists if _, err := os.Stat(configPath); os.IsNotExist(err) { return nil, fmt.Errorf("config file not found at %s. Please create it from tell-me.yaml.example", configPath) } // Read YAML file data, err := os.ReadFile(configPath) if err != nil { return nil, fmt.Errorf("failed to read config file: %w", err) } // Parse YAML var cfg Config if err := yaml.Unmarshal(data, &cfg); err != nil { return nil, fmt.Errorf("failed to parse config file: %w", err) } // Set defaults if cfg.ContextSize == 0 { cfg.ContextSize = 16000 } // Validate required fields if cfg.APIURL == "" { return nil, fmt.Errorf("api_url is required in config") } if cfg.Model == "" { return nil, fmt.Errorf("model is required in config") } if cfg.Prompt == "" { return nil, fmt.Errorf("prompt is required in config") } return &cfg, nil }