Skip to main content

lean_ctx/core/
config.rs

1use serde::{Deserialize, Serialize};
2use std::path::PathBuf;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(default)]
6pub struct Config {
7    pub ultra_compact: bool,
8    pub tee_on_error: bool,
9    pub checkpoint_interval: u32,
10    pub excluded_commands: Vec<String>,
11    pub custom_aliases: Vec<AliasEntry>,
12    /// Commands taking longer than this threshold (ms) are recorded in the slow log.
13    /// Set to 0 to disable slow logging.
14    pub slow_command_threshold_ms: u64,
15    #[serde(default)]
16    pub cloud: CloudConfig,
17}
18
19#[derive(Debug, Clone, Serialize, Deserialize, Default)]
20#[serde(default)]
21pub struct CloudConfig {
22    pub contribute_enabled: bool,
23    pub last_contribute: Option<String>,
24    pub last_sync: Option<String>,
25    pub last_model_pull: Option<String>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct AliasEntry {
30    pub command: String,
31    pub alias: String,
32}
33
34impl Default for Config {
35    fn default() -> Self {
36        Self {
37            ultra_compact: false,
38            tee_on_error: false,
39            checkpoint_interval: 15,
40            excluded_commands: Vec::new(),
41            custom_aliases: Vec::new(),
42            slow_command_threshold_ms: 5000,
43            cloud: CloudConfig::default(),
44        }
45    }
46}
47
48impl Config {
49    pub fn path() -> Option<PathBuf> {
50        dirs::home_dir().map(|h| h.join(".lean-ctx").join("config.toml"))
51    }
52
53    pub fn load() -> Self {
54        let path = match Self::path() {
55            Some(p) => p,
56            None => return Self::default(),
57        };
58        match std::fs::read_to_string(&path) {
59            Ok(content) => toml::from_str(&content).unwrap_or_default(),
60            Err(_) => Self::default(),
61        }
62    }
63
64    pub fn save(&self) -> Result<(), String> {
65        let path = Self::path().ok_or("cannot determine home directory")?;
66        if let Some(parent) = path.parent() {
67            std::fs::create_dir_all(parent).map_err(|e| e.to_string())?;
68        }
69        let content = toml::to_string_pretty(self).map_err(|e| e.to_string())?;
70        std::fs::write(&path, content).map_err(|e| e.to_string())
71    }
72
73    pub fn show(&self) -> String {
74        let path = Self::path()
75            .map(|p| p.to_string_lossy().to_string())
76            .unwrap_or_else(|| "~/.lean-ctx/config.toml".to_string());
77        let content = toml::to_string_pretty(self).unwrap_or_default();
78        format!("Config: {path}\n\n{content}")
79    }
80}