@@ -11,6 +11,7 @@ import (
12 "github.com/charmbracelet/crush/internal/llm/models"
12 "github.com/charmbracelet/crush/internal/llm/models"
13 "github.com/charmbracelet/crush/internal/logging"
13 "github.com/charmbracelet/crush/internal/logging"
14+ "github.com/spf13/afero"
14 "github.com/spf13/viper"
15 "github.com/spf13/viper"
@@ -199,21 +200,62 @@ func Load(workingDir string, debug bool) (*Config, error) {
199 return cfg, nil
200 return cfg, nil
203+type configFinder struct {
209+func (f configFinder) Find(fsys afero.Fs) ([]string, error) {
210+ var configFiles []string
211+ configName := fmt.Sprintf("%s.json", f.appName)
213+ configName = fmt.Sprintf(".%s.json", f.appName)
216+ for _, p := range f.paths {
220+ paths = append(paths, os.ExpandEnv(p))
223+ for _, path := range paths {
228+ configPath := filepath.Join(path, configName)
229+ if exists, err := afero.Exists(fsys, configPath); err == nil && exists {
230+ configFiles = append(configFiles, configPath)
233+ return configFiles, nil
202// configureViper sets up viper's configuration paths and environment variables.
236// configureViper sets up viper's configuration paths and environment variables.
203func configureViper() {
237func configureViper() {
204− viper.SetConfigName(fmt.Sprintf(".%s", appName))
205 viper.SetConfigType("json")
238 viper.SetConfigType("json")
207− // Unix-style paths
240+ // Create the three finders
208− viper.AddConfigPath("$HOME")
241+ windowsFinder := configFinder{appName: appName, dotPrefix: false, paths: []string{
243+ fmt.Sprintf("$APPDATA/%s", appName),
244+ fmt.Sprintf("$LOCALAPPDATA/%s", appName),
247+ unixFinder := configFinder{appName: appName, dotPrefix: false, paths: []string{
209− viper.AddConfigPath(fmt.Sprintf("$XDG_CONFIG_HOME/%s", appName))
249+ fmt.Sprintf("$XDG_CONFIG_HOME/%s", appName),
210− viper.AddConfigPath(fmt.Sprintf("$HOME/.config/%s", appName))
250+ fmt.Sprintf("$HOME/.config/%s", appName),
212− // Windows-style paths
252+
213− viper.AddConfigPath(fmt.Sprintf("$USERPROFILE"))
253+ localFinder := configFinder{appName: appName, dotPrefix: true, paths: []string{
214− viper.AddConfigPath(fmt.Sprintf("$APPDATA/%s", appName))
254+ ".",
215− viper.AddConfigPath(fmt.Sprintf("$LOCALAPPDATA/%s", appName))
255+ }}
257+ // Use all finders with viper
258+ viper.SetOptions(viper.WithFinder(viper.Finders(windowsFinder, unixFinder, localFinder)))
217 viper.SetEnvPrefix(strings.ToUpper(appName))
259 viper.SetEnvPrefix(strings.ToUpper(appName))
218 viper.AutomaticEnv()
260 viper.AutomaticEnv()