@@ -11,37 +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 (home )
38- viper .AddConfigPath ("." ) // Also look in the current directory
29+ viper .AddConfigPath (getConfigDir ())
30+ viper .SetConfigFile (filepath .Join (getConfigDir (), ".lazycommit.yaml" ))
3931
40- // Set defaults based on available credentials
4132 if token , err := LoadGitHubToken (); err == nil && token != "" {
4233 viper .SetDefault ("active_provider" , "copilot" )
4334 viper .SetDefault ("providers.copilot.api_key" , token )
44- viper .SetDefault ("providers.copilot.model" , "openai/gpt-4o" ) // Use GitHub Models format
35+ viper .SetDefault ("providers.copilot.model" , "openai/gpt-4o" )
4536 } else {
4637 viper .SetDefault ("active_provider" , "openai" )
4738 viper .SetDefault ("providers.openai.model" , "gpt-3.5-turbo" )
@@ -50,7 +41,17 @@ func InitConfig() {
5041 viper .AutomaticEnv ()
5142
5243 if err := viper .ReadInConfig (); err != nil {
53- 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 {
5455 fmt .Println ("Error reading config file:" , err )
5556 }
5657 }
@@ -61,15 +62,13 @@ func InitConfig() {
6162 }
6263}
6364
64- // GetProvider returns the active provider's name.
6565func GetProvider () string {
6666 if cfg == nil {
6767 InitConfig ()
6868 }
6969 return cfg .ActiveProvider
7070}
7171
72- // GetActiveProviderConfig returns the configuration for the currently active provider.
7372func GetActiveProviderConfig () (* ProviderConfig , error ) {
7473 if cfg == nil {
7574 InitConfig ()
@@ -82,7 +81,6 @@ func GetActiveProviderConfig() (*ProviderConfig, error) {
8281 return & providerConfig , nil
8382}
8483
85- // GetAPIKey returns the API key for the active provider.
8684func GetAPIKey () (string , error ) {
8785 if cfg == nil {
8886 InitConfig ()
@@ -115,7 +113,6 @@ func GetAPIKey() (string, error) {
115113 return apiKey , nil
116114}
117115
118- // GetModel returns the model for the active provider.
119116func GetModel () (string , error ) {
120117 providerConfig , err := GetActiveProviderConfig ()
121118 if err != nil {
@@ -127,7 +124,6 @@ func GetModel() (string, error) {
127124 return providerConfig .Model , nil
128125}
129126
130- // SetProvider sets the active provider and saves the config.
131127func SetProvider (provider string ) error {
132128 if cfg == nil {
133129 InitConfig ()
@@ -137,7 +133,6 @@ func SetProvider(provider string) error {
137133 return viper .WriteConfig ()
138134}
139135
140- // SetModel sets the model for the active provider and saves the config.
141136func SetModel (model string ) error {
142137 if cfg == nil {
143138 InitConfig ()
@@ -147,7 +142,6 @@ func SetModel(model string) error {
147142 return viper .WriteConfig ()
148143}
149144
150- // SetAPIKey sets the API key for a specific provider and saves the config.
151145func SetAPIKey (provider , apiKey string ) error {
152146 if cfg == nil {
153147 InitConfig ()
@@ -156,23 +150,17 @@ func SetAPIKey(provider, apiKey string) error {
156150 return viper .WriteConfig ()
157151}
158152
159- // LoadGitHubToken tries to load a GitHub token with models scope from standard locations.
160153func LoadGitHubToken () (string , error ) {
161- // First check environment variable (recommended approach)
162154 if token := os .Getenv ("GITHUB_TOKEN" ); token != "" {
163155 return token , nil
164156 }
165157
166- // Also check for a GitHub Models specific token
167158 if token := os .Getenv ("GITHUB_MODELS_TOKEN" ); token != "" {
168159 return token , nil
169160 }
170161
171- // Fallback: try to find tokens from GitHub Copilot IDE installations
172- // Note: These tokens may not have the required 'models' scope
173162 configDir := getConfigDir ()
174163
175- // Try both hosts.json and apps.json files
176164 filePaths := []string {
177165 filepath .Join (configDir , "github-copilot" , "hosts.json" ),
178166 filepath .Join (configDir , "github-copilot" , "apps.json" ),
0 commit comments