@@ -11,38 +11,28 @@ import (
1111 "github.com/spf13/viper"
1212)
1313
14- // ProviderConfig holds the configuration for a single LLM provider.
1514type ProviderConfig struct {
1615 APIKey string `mapstructure:"api_key"`
1716 Model string `mapstructure:"model"`
1817}
1918
20- // Config is the main configuration structure for the application.
2119type Config struct {
2220 Providers map [string ]ProviderConfig `mapstructure:"providers"`
2321 ActiveProvider string `mapstructure:"active_provider"`
2422}
2523
2624var cfg * Config
2725
28- // InitConfig initializes the configuration from environment variables and config files.
2926func InitConfig () {
3027 viper .SetConfigName (".lazycommit" )
3128 viper .SetConfigType ("yaml" )
32- home , err := os .UserHomeDir ()
33- if err != nil {
34- fmt .Println ("Error getting home directory:" , err )
35- os .Exit (1 )
36- }
37- viper .AddConfigPath ("." ) // Look in the current directory first
38- viper .AddConfigPath (home ) // Then home directory
39- viper .AddConfigPath (getConfigDir ()) // Finally ~/.config directory
29+ viper .AddConfigPath (getConfigDir ())
30+ viper .SetConfigFile (filepath .Join (getConfigDir (), ".lazycommit.yaml" ))
4031
41- // Set defaults based on available credentials
4232 if token , err := LoadGitHubToken (); err == nil && token != "" {
4333 viper .SetDefault ("active_provider" , "copilot" )
4434 viper .SetDefault ("providers.copilot.api_key" , token )
45- viper .SetDefault ("providers.copilot.model" , "openai/gpt-4o" ) // Use GitHub Models format
35+ viper .SetDefault ("providers.copilot.model" , "openai/gpt-4o" )
4636 } else {
4737 viper .SetDefault ("active_provider" , "openai" )
4838 viper .SetDefault ("providers.openai.model" , "gpt-3.5-turbo" )
@@ -51,7 +41,17 @@ func InitConfig() {
5141 viper .AutomaticEnv ()
5242
5343 if err := viper .ReadInConfig (); err != nil {
54- if _ , ok := err .(viper.ConfigFileNotFoundError ); ! ok {
44+ if _ , ok := err .(viper.ConfigFileNotFoundError ); ok {
45+ cfgDir := getConfigDir ()
46+ _ = os .MkdirAll (cfgDir , 0o755 )
47+ cfgPath := filepath .Join (cfgDir , ".lazycommit.yaml" )
48+ if writeErr := viper .WriteConfigAs (cfgPath ); writeErr != nil {
49+ fmt .Println ("Error creating default config file:" , writeErr )
50+ } else {
51+ fmt .Printf ("Created default config at %s\n " , cfgPath )
52+ }
53+ _ = viper .ReadInConfig ()
54+ } else {
5555 fmt .Println ("Error reading config file:" , err )
5656 }
5757 }
@@ -62,15 +62,13 @@ func InitConfig() {
6262 }
6363}
6464
65- // GetProvider returns the active provider's name.
6665func GetProvider () string {
6766 if cfg == nil {
6867 InitConfig ()
6968 }
7069 return cfg .ActiveProvider
7170}
7271
73- // GetActiveProviderConfig returns the configuration for the currently active provider.
7472func GetActiveProviderConfig () (* ProviderConfig , error ) {
7573 if cfg == nil {
7674 InitConfig ()
@@ -83,7 +81,6 @@ func GetActiveProviderConfig() (*ProviderConfig, error) {
8381 return & providerConfig , nil
8482}
8583
86- // GetAPIKey returns the API key for the active provider.
8784func GetAPIKey () (string , error ) {
8885 if cfg == nil {
8986 InitConfig ()
@@ -104,7 +101,6 @@ func GetAPIKey() (string, error) {
104101 return providerConfig .APIKey , nil
105102}
106103
107- // GetModel returns the model for the active provider.
108104func GetModel () (string , error ) {
109105 providerConfig , err := GetActiveProviderConfig ()
110106 if err != nil {
@@ -116,7 +112,6 @@ func GetModel() (string, error) {
116112 return providerConfig .Model , nil
117113}
118114
119- // SetProvider sets the active provider and saves the config.
120115func SetProvider (provider string ) error {
121116 if cfg == nil {
122117 InitConfig ()
@@ -126,7 +121,6 @@ func SetProvider(provider string) error {
126121 return viper .WriteConfig ()
127122}
128123
129- // SetModel sets the model for the active provider and saves the config.
130124func SetModel (model string ) error {
131125 if cfg == nil {
132126 InitConfig ()
@@ -136,7 +130,6 @@ func SetModel(model string) error {
136130 return viper .WriteConfig ()
137131}
138132
139- // SetAPIKey sets the API key for a specific provider and saves the config.
140133func SetAPIKey (provider , apiKey string ) error {
141134 if cfg == nil {
142135 InitConfig ()
@@ -145,23 +138,17 @@ func SetAPIKey(provider, apiKey string) error {
145138 return viper .WriteConfig ()
146139}
147140
148- // LoadGitHubToken tries to load a GitHub token with models scope from standard locations.
149141func LoadGitHubToken () (string , error ) {
150- // First check environment variable (recommended approach)
151142 if token := os .Getenv ("GITHUB_TOKEN" ); token != "" {
152143 return token , nil
153144 }
154145
155- // Also check for a GitHub Models specific token
156146 if token := os .Getenv ("GITHUB_MODELS_TOKEN" ); token != "" {
157147 return token , nil
158148 }
159149
160- // Fallback: try to find tokens from GitHub Copilot IDE installations
161- // Note: These tokens may not have the required 'models' scope
162150 configDir := getConfigDir ()
163151
164- // Try both hosts.json and apps.json files
165152 filePaths := []string {
166153 filepath .Join (configDir , "github-copilot" , "hosts.json" ),
167154 filepath .Join (configDir , "github-copilot" , "apps.json" ),
0 commit comments