|
|
@@ -56,7 +56,7 @@ type Provider struct {
|
|
|
|
|
|
// Data defines storage configuration.
|
|
|
type Data struct {
|
|
|
- Directory string `json:"directory"`
|
|
|
+ Directory string `json:"directory,omitempty"`
|
|
|
}
|
|
|
|
|
|
// LSPConfig defines configuration for Language Server Protocol integration.
|
|
|
@@ -80,7 +80,7 @@ type Config struct {
|
|
|
MCPServers map[string]MCPServer `json:"mcpServers,omitempty"`
|
|
|
Providers map[models.ModelProvider]Provider `json:"providers,omitempty"`
|
|
|
LSP map[string]LSPConfig `json:"lsp,omitempty"`
|
|
|
- Agents map[AgentName]Agent `json:"agents"`
|
|
|
+ Agents map[AgentName]Agent `json:"agents,omitempty"`
|
|
|
Debug bool `json:"debug,omitempty"`
|
|
|
DebugLSP bool `json:"debugLSP,omitempty"`
|
|
|
ContextPaths []string `json:"contextPaths,omitempty"`
|
|
|
@@ -704,6 +704,52 @@ func GetUsername() (string, error) {
|
|
|
return currentUser.Username, nil
|
|
|
}
|
|
|
|
|
|
+func updateCfgFile(updateCfg func(config *Config)) error {
|
|
|
+ if cfg == nil {
|
|
|
+ return fmt.Errorf("config not loaded")
|
|
|
+ }
|
|
|
+
|
|
|
+ // Get the config file path
|
|
|
+ configFile := viper.ConfigFileUsed()
|
|
|
+ var configData []byte
|
|
|
+ if configFile == "" {
|
|
|
+ homeDir, err := os.UserHomeDir()
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to get home directory: %w", err)
|
|
|
+ }
|
|
|
+ configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
|
|
|
+ slog.Info("config file not found, creating new one", "path", configFile)
|
|
|
+ configData = []byte(`{}`)
|
|
|
+ } else {
|
|
|
+ // Read the existing config file
|
|
|
+ data, err := os.ReadFile(configFile)
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to read config file: %w", err)
|
|
|
+ }
|
|
|
+ configData = data
|
|
|
+ }
|
|
|
+
|
|
|
+ // Parse the JSON
|
|
|
+ var userCfg *Config
|
|
|
+ if err := json.Unmarshal(configData, &userCfg); err != nil {
|
|
|
+ return fmt.Errorf("failed to parse config file: %w", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ updateCfg(userCfg)
|
|
|
+
|
|
|
+ // Write the updated config back to file
|
|
|
+ updatedData, err := json.MarshalIndent(userCfg, "", " ")
|
|
|
+ if err != nil {
|
|
|
+ return fmt.Errorf("failed to marshal config: %w", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
|
|
|
+ return fmt.Errorf("failed to write config file: %w", err)
|
|
|
+ }
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
|
|
|
if cfg == nil {
|
|
|
panic("config not loaded")
|
|
|
@@ -734,7 +780,12 @@ func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
|
|
|
return fmt.Errorf("failed to update agent model: %w", err)
|
|
|
}
|
|
|
|
|
|
- return nil
|
|
|
+ return updateCfgFile(func(config *Config) {
|
|
|
+ if config.Agents == nil {
|
|
|
+ config.Agents = make(map[AgentName]Agent)
|
|
|
+ }
|
|
|
+ config.Agents[agentName] = newAgentCfg
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
// UpdateTheme updates the theme in the configuration and writes it to the config file.
|
|
|
@@ -746,52 +797,8 @@ func UpdateTheme(themeName string) error {
|
|
|
// Update the in-memory config
|
|
|
cfg.TUI.Theme = themeName
|
|
|
|
|
|
- // Get the config file path
|
|
|
- configFile := viper.ConfigFileUsed()
|
|
|
- var configData []byte
|
|
|
- if configFile == "" {
|
|
|
- homeDir, err := os.UserHomeDir()
|
|
|
- if err != nil {
|
|
|
- return fmt.Errorf("failed to get home directory: %w", err)
|
|
|
- }
|
|
|
- configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
|
|
|
- slog.Info("config file not found, creating new one", "path", configFile)
|
|
|
- configData = []byte(`{}`)
|
|
|
- } else {
|
|
|
- // Read the existing config file
|
|
|
- data, err := os.ReadFile(configFile)
|
|
|
- if err != nil {
|
|
|
- return fmt.Errorf("failed to read config file: %w", err)
|
|
|
- }
|
|
|
- configData = data
|
|
|
- }
|
|
|
-
|
|
|
- // Parse the JSON
|
|
|
- var configMap map[string]any
|
|
|
- if err := json.Unmarshal(configData, &configMap); err != nil {
|
|
|
- return fmt.Errorf("failed to parse config file: %w", err)
|
|
|
- }
|
|
|
-
|
|
|
- // Update just the theme value
|
|
|
- tuiConfig, ok := configMap["tui"].(map[string]any)
|
|
|
- if !ok {
|
|
|
- // TUI config doesn't exist yet, create it
|
|
|
- configMap["tui"] = map[string]any{"theme": themeName}
|
|
|
- } else {
|
|
|
- // Update existing TUI config
|
|
|
- tuiConfig["theme"] = themeName
|
|
|
- configMap["tui"] = tuiConfig
|
|
|
- }
|
|
|
-
|
|
|
- // Write the updated config back to file
|
|
|
- updatedData, err := json.MarshalIndent(configMap, "", " ")
|
|
|
- if err != nil {
|
|
|
- return fmt.Errorf("failed to marshal config: %w", err)
|
|
|
- }
|
|
|
-
|
|
|
- if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
|
|
|
- return fmt.Errorf("failed to write config file: %w", err)
|
|
|
- }
|
|
|
-
|
|
|
- return nil
|
|
|
+ // Update the file config
|
|
|
+ return updateCfgFile(func(config *Config) {
|
|
|
+ config.TUI.Theme = themeName
|
|
|
+ })
|
|
|
}
|