1use serde::Deserialize;
2use std::path::Path;
3
4#[derive(Debug, Default, Deserialize)]
8pub struct UserConfig {
9 #[serde(default)]
10 pub repo: RepoConfig,
11 #[serde(default)]
12 pub agent: AgentConfig,
13}
14
15#[derive(Debug, Default, Deserialize)]
16pub struct RepoConfig {
17 #[serde(default)]
18 pub register: RepoRegisterConfig,
19}
20
21#[derive(Debug, Default, Deserialize)]
22pub struct RepoRegisterConfig {
23 #[serde(default)]
24 pub hooks: Vec<Hook>,
25}
26
27#[derive(Debug, Clone, Deserialize)]
29pub struct Hook {
30 pub run: String,
31}
32
33#[derive(Debug, Default, Deserialize)]
34pub struct AgentConfig {
35 pub command: Option<String>,
38}
39
40impl UserConfig {
41 pub fn load(vex_home: &Path) -> Self {
42 let path = vex_home.join("config.yaml");
43 if !path.exists() {
44 return Self::default();
45 }
46 match std::fs::read_to_string(&path) {
47 Ok(content) => serde_yaml::from_str(&content).unwrap_or_default(),
48 Err(_) => Self::default(),
49 }
50 }
51
52 pub fn agent_command(&self) -> &str {
53 self.agent
54 .command
55 .as_deref()
56 .unwrap_or("claude --dangerously-skip-permissions")
57 }
58
59 pub fn register_hooks(&self) -> &[Hook] {
60 &self.repo.register.hooks
61 }
62}