systemprompt-cloud 0.2.0

systemprompt.io Cloud infrastructure - API client, credentials, OAuth
Documentation
use std::path::{Path, PathBuf};

use crate::constants::{dir_names, file_names};

#[derive(Debug, Clone)]
pub struct DiscoveredProject {
    root: PathBuf,
    systemprompt_dir: PathBuf,
}

impl DiscoveredProject {
    #[must_use]
    pub fn discover() -> Option<Self> {
        let cwd = match std::env::current_dir() {
            Ok(dir) => dir,
            Err(e) => {
                tracing::debug!(error = %e, "Failed to get current directory for project discovery");
                return None;
            },
        };
        Self::discover_from(&cwd)
    }

    #[must_use]
    pub fn discover_from(start: &Path) -> Option<Self> {
        let mut current = start.to_path_buf();
        loop {
            let systemprompt_dir = current.join(dir_names::SYSTEMPROMPT);
            if systemprompt_dir.is_dir() {
                return Some(Self {
                    root: current,
                    systemprompt_dir,
                });
            }
            if !current.pop() {
                break;
            }
        }
        None
    }

    #[must_use]
    pub fn from_root(root: PathBuf) -> Self {
        let systemprompt_dir = root.join(dir_names::SYSTEMPROMPT);
        Self {
            root,
            systemprompt_dir,
        }
    }

    #[must_use]
    pub fn root(&self) -> &Path {
        &self.root
    }

    #[must_use]
    pub fn systemprompt_dir(&self) -> &Path {
        &self.systemprompt_dir
    }

    #[must_use]
    pub fn credentials_path(&self) -> PathBuf {
        self.systemprompt_dir.join(file_names::CREDENTIALS)
    }

    #[must_use]
    pub fn tenants_path(&self) -> PathBuf {
        self.systemprompt_dir.join(file_names::TENANTS)
    }

    #[must_use]
    pub fn session_path(&self) -> PathBuf {
        self.systemprompt_dir.join(file_names::SESSION)
    }

    #[must_use]
    pub fn sessions_dir(&self) -> PathBuf {
        self.systemprompt_dir.join(dir_names::SESSIONS)
    }

    #[must_use]
    pub fn profiles_dir(&self) -> PathBuf {
        self.systemprompt_dir.join(dir_names::PROFILES)
    }

    #[must_use]
    pub fn profile_dir(&self, name: &str) -> PathBuf {
        self.profiles_dir().join(name)
    }

    #[must_use]
    pub fn profile_config(&self, name: &str) -> PathBuf {
        self.profile_dir(name).join(file_names::PROFILE_CONFIG)
    }

    #[must_use]
    pub fn profile_secrets(&self, name: &str) -> PathBuf {
        self.profile_dir(name).join(file_names::PROFILE_SECRETS)
    }

    #[must_use]
    pub fn docker_dir(&self) -> PathBuf {
        self.systemprompt_dir.join(dir_names::DOCKER)
    }

    #[must_use]
    pub fn storage_dir(&self) -> PathBuf {
        self.systemprompt_dir.join(dir_names::STORAGE)
    }

    #[must_use]
    pub fn is_initialized(&self) -> bool {
        self.systemprompt_dir.is_dir()
    }

    #[must_use]
    pub fn has_credentials(&self) -> bool {
        self.credentials_path().exists()
    }

    #[must_use]
    pub fn has_tenants(&self) -> bool {
        self.tenants_path().exists()
    }

    #[must_use]
    pub fn has_session(&self) -> bool {
        self.session_path().exists()
    }

    #[must_use]
    pub fn has_profile(&self, name: &str) -> bool {
        self.profile_dir(name).is_dir()
    }
}