1use crate::{
2 agents::Agent,
3 detect::{detect, AGENT_MAP},
4 runner::DetectOptions,
5};
6use dirs::home_dir;
7use ini::Ini;
8use std::{
9 env,
10 path::{Path, PathBuf},
11};
12
13#[derive(PartialEq, Clone, Debug, Eq, Hash)]
14pub enum DefaultAgent {
15 Prompt,
16 Agent(Agent),
17}
18
19pub struct Config {
20 default_agent: DefaultAgent,
21 global_agent: Agent,
22}
23
24impl Default for Config {
25 fn default() -> Self {
26 Config {
27 default_agent: DefaultAgent::Prompt,
28 global_agent: Agent::Npm,
29 }
30 }
31}
32
33impl Config {
34 pub fn assign(&self) -> Self {
35 let home = home_dir().unwrap_or(PathBuf::from("~/"));
36 let custom_rc_path = env::var("NI_CONFIG_FILE");
37 let default_rc_path = home.join(".nirc");
38 let rc_path = if let Ok(custom_rc_path) = custom_rc_path {
39 custom_rc_path
40 } else {
41 default_rc_path.to_string_lossy().to_string()
42 };
43
44 let mut config = Self::default();
45
46 if Path::new(&rc_path).exists() {
47 let conf = Ini::load_from_file(&rc_path).unwrap();
48 let section = conf.section(None::<String>).unwrap();
49 let default_agent = section.get("default_agent");
50 let global_agent = section.get("global_agent");
51 if let Some(default_agent) = default_agent {
52 let default_agent = AGENT_MAP.get(default_agent);
53 if let Some(default_agent) = default_agent {
54 config.default_agent = DefaultAgent::Agent(default_agent.clone());
55 }
56 }
57 if let Some(global_agent) = global_agent {
58 let global_agent = AGENT_MAP.get(global_agent);
59 if let Some(global_agent) = global_agent {
60 config.global_agent = global_agent.clone();
61 }
62 }
63 }
64
65 config
66 }
67}
68
69pub fn get_config() -> Config {
70 let mut config = Config::default().assign();
71 let mut options = DetectOptions::default();
72 options.programmatic = true;
73 let agent = detect(options);
74 if let Some(agent) = agent {
75 config.default_agent = DefaultAgent::Agent(agent);
76 }
77 config
78}
79
80pub fn get_default_agent(programmatic: bool) -> DefaultAgent {
81 let Config { default_agent, .. } = get_config();
82 let ci = env::var("CI");
83
84 if default_agent == DefaultAgent::Prompt && (programmatic == true || ci.is_ok()) {
85 return DefaultAgent::Agent(Agent::Npm);
86 }
87 default_agent
88}
89
90pub fn get_global_agent() -> Agent {
91 let Config { global_agent, .. } = get_config();
92 global_agent
93}