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