Skip to main content

tracevault_cli/
config.rs

1use serde::{Deserialize, Serialize};
2use std::path::{Path, PathBuf};
3
4#[derive(Debug, Serialize, Deserialize)]
5pub struct TracevaultConfig {
6    pub agent: String,
7    pub server_url: Option<String>,
8    pub api_key: Option<String>,
9    pub org_slug: Option<String>,
10}
11
12impl Default for TracevaultConfig {
13    fn default() -> Self {
14        Self {
15            agent: "claude-code".to_string(),
16            server_url: None,
17            api_key: None,
18            org_slug: None,
19        }
20    }
21}
22
23impl TracevaultConfig {
24    pub fn config_dir(project_root: &Path) -> PathBuf {
25        project_root.join(".tracevault")
26    }
27
28    pub fn config_path(project_root: &Path) -> PathBuf {
29        Self::config_dir(project_root).join("config.toml")
30    }
31
32    pub fn to_toml(&self) -> String {
33        let mut out = format!("# TraceVault configuration\nagent = \"{}\"\n", self.agent);
34        if let Some(url) = &self.server_url {
35            out.push_str(&format!("server_url = \"{url}\"\n"));
36        }
37        if let Some(slug) = &self.org_slug {
38            out.push_str(&format!("org_slug = \"{slug}\"\n"));
39        }
40        out
41    }
42
43    /// Parse config from the TOML file using simple line-based parsing
44    /// (consistent with the existing resolve_credentials approach).
45    pub fn load(project_root: &Path) -> Option<Self> {
46        let path = Self::config_path(project_root);
47        let content = std::fs::read_to_string(path).ok()?;
48
49        let parse_field = |key: &str| -> Option<String> {
50            content
51                .lines()
52                .find(|l| l.starts_with(key))
53                .and_then(|l| l.split('=').nth(1))
54                .map(|s| s.trim().trim_matches('"').to_string())
55        };
56
57        Some(Self {
58            agent: parse_field("agent").unwrap_or_else(|| "claude-code".to_string()),
59            server_url: parse_field("server_url"),
60            api_key: parse_field("api_key"),
61            org_slug: parse_field("org_slug"),
62        })
63    }
64}