use directories::ProjectDirs; use figment::{ Figment, providers::{Env, Format, Serialized, Toml}, }; use serde::{Deserialize, Serialize}; use std::path::PathBuf; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Settings { #[serde(default = "default_ollama_url")] pub ollama_url: String, #[serde(default = "default_model")] pub model: String, #[serde(default = "default_mode")] pub mode: String, // "plan" (read-only) for now } fn default_ollama_url() -> String { "http://localhost:11434".into() } fn default_model() -> String { "qwen3:8b".into() } fn default_mode() -> String { "plan".into() } impl Default for Settings { fn default() -> Self { Self { ollama_url: default_ollama_url(), model: default_model(), mode: default_mode(), } } } pub fn load_settings(project_root: Option<&str>) -> Result { let mut fig = Figment::from(Serialized::defaults(Settings::default())); // User file: ~/.config/owlen/config.toml if let Some(pd) = ProjectDirs::from("dev", "owlibou", "owlen") { let user = pd.config_dir().join("config.toml"); fig = fig.merge(Toml::file(user)); } // Project file: /.owlen.toml if let Some(root) = project_root { fig = fig.merge(Toml::file(PathBuf::from(root).join(".owlen.toml"))); } // Environment variables have highest precedence fig = fig.merge(Env::prefixed("OWLEN_").split("__")); fig.extract() }