Skip to main content

systemprompt_cloud/paths/
discovery.rs

1use std::path::{Path, PathBuf};
2
3use crate::constants::{dir_names, file_names};
4
5#[derive(Debug, Clone)]
6pub struct DiscoveredProject {
7    root: PathBuf,
8    systemprompt_dir: PathBuf,
9}
10
11impl DiscoveredProject {
12    #[must_use]
13    pub fn discover() -> Option<Self> {
14        let cwd = match std::env::current_dir() {
15            Ok(dir) => dir,
16            Err(e) => {
17                tracing::debug!(error = %e, "Failed to get current directory for project discovery");
18                return None;
19            },
20        };
21        Self::discover_from(&cwd)
22    }
23
24    #[must_use]
25    pub fn discover_from(start: &Path) -> Option<Self> {
26        let mut current = start.to_path_buf();
27        loop {
28            let systemprompt_dir = current.join(dir_names::SYSTEMPROMPT);
29            if systemprompt_dir.is_dir() {
30                return Some(Self {
31                    root: current,
32                    systemprompt_dir,
33                });
34            }
35            if !current.pop() {
36                break;
37            }
38        }
39        None
40    }
41
42    #[must_use]
43    pub fn from_root(root: PathBuf) -> Self {
44        let systemprompt_dir = root.join(dir_names::SYSTEMPROMPT);
45        Self {
46            root,
47            systemprompt_dir,
48        }
49    }
50
51    #[must_use]
52    pub fn root(&self) -> &Path {
53        &self.root
54    }
55
56    #[must_use]
57    pub fn systemprompt_dir(&self) -> &Path {
58        &self.systemprompt_dir
59    }
60
61    #[must_use]
62    pub fn credentials_path(&self) -> PathBuf {
63        self.systemprompt_dir.join(file_names::CREDENTIALS)
64    }
65
66    #[must_use]
67    pub fn tenants_path(&self) -> PathBuf {
68        self.systemprompt_dir.join(file_names::TENANTS)
69    }
70
71    #[must_use]
72    pub fn session_path(&self) -> PathBuf {
73        self.systemprompt_dir.join(file_names::SESSION)
74    }
75
76    #[must_use]
77    pub fn sessions_dir(&self) -> PathBuf {
78        self.systemprompt_dir.join(dir_names::SESSIONS)
79    }
80
81    #[must_use]
82    pub fn profiles_dir(&self) -> PathBuf {
83        self.systemprompt_dir.join(dir_names::PROFILES)
84    }
85
86    #[must_use]
87    pub fn profile_dir(&self, name: &str) -> PathBuf {
88        self.profiles_dir().join(name)
89    }
90
91    #[must_use]
92    pub fn profile_config(&self, name: &str) -> PathBuf {
93        self.profile_dir(name).join(file_names::PROFILE_CONFIG)
94    }
95
96    #[must_use]
97    pub fn profile_secrets(&self, name: &str) -> PathBuf {
98        self.profile_dir(name).join(file_names::PROFILE_SECRETS)
99    }
100
101    #[must_use]
102    pub fn docker_dir(&self) -> PathBuf {
103        self.systemprompt_dir.join(dir_names::DOCKER)
104    }
105
106    #[must_use]
107    pub fn storage_dir(&self) -> PathBuf {
108        self.systemprompt_dir.join(dir_names::STORAGE)
109    }
110
111    #[must_use]
112    pub fn is_initialized(&self) -> bool {
113        self.systemprompt_dir.is_dir()
114    }
115
116    #[must_use]
117    pub fn has_credentials(&self) -> bool {
118        self.credentials_path().exists()
119    }
120
121    #[must_use]
122    pub fn has_tenants(&self) -> bool {
123        self.tenants_path().exists()
124    }
125
126    #[must_use]
127    pub fn has_session(&self) -> bool {
128        self.session_path().exists()
129    }
130
131    #[must_use]
132    pub fn has_profile(&self, name: &str) -> bool {
133        self.profile_dir(name).is_dir()
134    }
135}