@@ -57,7 +57,7 @@ type Provider struct {
58// Data defines storage configuration.
58// Data defines storage configuration.
59type Data struct {
59type Data struct {
60− Directory string `json:"directory"`
60+ Directory string `json:"directory,omitempty"`
63// LSPConfig defines configuration for Language Server Protocol integration.
63// LSPConfig defines configuration for Language Server Protocol integration.
@@ -86,7 +86,7 @@ type Config struct {
86 MCPServers map[string]MCPServer `json:"mcpServers,omitempty"`
86 MCPServers map[string]MCPServer `json:"mcpServers,omitempty"`
87 Providers map[models.ModelProvider]Provider `json:"providers,omitempty"`
87 Providers map[models.ModelProvider]Provider `json:"providers,omitempty"`
88 LSP map[string]LSPConfig `json:"lsp,omitempty"`
88 LSP map[string]LSPConfig `json:"lsp,omitempty"`
89− Agents map[AgentName]Agent `json:"agents"`
89+ Agents map[AgentName]Agent `json:"agents,omitempty"`
90 Debug bool `json:"debug,omitempty"`
90 Debug bool `json:"debug,omitempty"`
91 DebugLSP bool `json:"debugLSP,omitempty"`
91 DebugLSP bool `json:"debugLSP,omitempty"`
92 ContextPaths []string `json:"contextPaths,omitempty"`
92 ContextPaths []string `json:"contextPaths,omitempty"`
@@ -721,6 +721,52 @@ func setDefaultModelForAgent(agent AgentName) bool {
721 return false
721 return false
724+func updateCfgFile(updateCfg func(config *Config)) error {
726+ return fmt.Errorf("config not loaded")
729+ // Get the config file path
730+ configFile := viper.ConfigFileUsed()
731+ var configData []byte
732+ if configFile == "" {
733+ homeDir, err := os.UserHomeDir()
735+ return fmt.Errorf("failed to get home directory: %w", err)
737+ configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
738+ logging.Info("config file not found, creating new one", "path", configFile)
739+ configData = []byte(`{}`)
741+ // Read the existing config file
742+ data, err := os.ReadFile(configFile)
744+ return fmt.Errorf("failed to read config file: %w", err)
751+ if err := json.Unmarshal(configData, &userCfg); err != nil {
752+ return fmt.Errorf("failed to parse config file: %w", err)
757+ // Write the updated config back to file
758+ updatedData, err := json.MarshalIndent(userCfg, "", " ")
760+ return fmt.Errorf("failed to marshal config: %w", err)
763+ if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
764+ return fmt.Errorf("failed to write config file: %w", err)
724// Get returns the current configuration.
770// Get returns the current configuration.
725// It's safe to call this function multiple times.
771// It's safe to call this function multiple times.
726func Get() *Config {
772func Get() *Config {
@@ -765,7 +811,12 @@ func UpdateAgentModel(agentName AgentName, modelID models.ModelID) error {
765 return fmt.Errorf("failed to update agent model: %w", err)
811 return fmt.Errorf("failed to update agent model: %w", err)
768− return nil
814+ return updateCfgFile(func(config *Config) {
815+ if config.Agents == nil {
816+ config.Agents = make(map[AgentName]Agent)
818+ config.Agents[agentName] = newAgentCfg
771// UpdateTheme updates the theme in the configuration and writes it to the config file.
822// UpdateTheme updates the theme in the configuration and writes it to the config file.
@@ -777,52 +828,8 @@ func UpdateTheme(themeName string) error {
777 // Update the in-memory config
828 // Update the in-memory config
778 cfg.TUI.Theme = themeName
829 cfg.TUI.Theme = themeName
780− // Get the config file path
831+ // Update the file config
781− configFile := viper.ConfigFileUsed()
832+ return updateCfgFile(func(config *Config) {
782− var configData []byte
833+ config.TUI.Theme = themeName
783− if configFile == "" {
834+ })
784− homeDir, err := os.UserHomeDir()
786− return fmt.Errorf("failed to get home directory: %w", err)
788− configFile = filepath.Join(homeDir, fmt.Sprintf(".%s.json", appName))
789− logging.Info("config file not found, creating new one", "path", configFile)
790− configData = []byte(`{}`)
792− // Read the existing config file
793− data, err := os.ReadFile(configFile)
795− return fmt.Errorf("failed to read config file: %w", err)
801− var configMap map[string]interface{}
802− if err := json.Unmarshal(configData, &configMap); err != nil {
803− return fmt.Errorf("failed to parse config file: %w", err)
806− // Update just the theme value
807− tuiConfig, ok := configMap["tui"].(map[string]interface{})
809− // TUI config doesn't exist yet, create it
810− configMap["tui"] = map[string]interface{}{"theme": themeName}
812− // Update existing TUI config
813− tuiConfig["theme"] = themeName
814− configMap["tui"] = tuiConfig
817− // Write the updated config back to file
818− updatedData, err := json.MarshalIndent(configMap, "", " ")
820− return fmt.Errorf("failed to marshal config: %w", err)
823− if err := os.WriteFile(configFile, updatedData, 0o644); err != nil {
824− return fmt.Errorf("failed to write config file: %w", err)