systemprompt-runtime 0.64.0

Application runtime for systemprompt.io AI governance infrastructure. AppContext, lifecycle builder, extension registry, and module wiring for the MCP governance pipeline.
Documentation
//! Application-owned credential resolution for Git source synchronization.
//!
//! Copyright (c) systemprompt.io — Business Source License 1.1.
//! See <https://systemprompt.io> for licensing details.

use std::path::PathBuf;

use super::OrchestrationError;
use systemprompt_config::SecretsBootstrap;
use systemprompt_identifiers::{ManagedSourceId, UserId};
use systemprompt_marketplace::managed::{
    GitSyncRequest, GitSyncResult, ManagedRepository, SourceSpec,
};

#[derive(Debug, Clone)]
pub struct GitSourceOrchestrator {
    managed: ManagedRepository,
    scratch_root: PathBuf,
}

impl GitSourceOrchestrator {
    pub const fn new(managed: ManagedRepository, scratch_root: PathBuf) -> Self {
        Self {
            managed,
            scratch_root,
        }
    }

    pub async fn synchronize(
        &self,
        owner: &UserId,
        request: &GitSyncRequest,
    ) -> Result<GitSyncResult, OrchestrationError> {
        let credential = self.credential(owner, &request.source_id).await?;
        Ok(self
            .managed
            .sync_git_source_with_credential(
                owner,
                request,
                credential.as_deref(),
                &self.scratch_root,
            )
            .await?)
    }

    async fn credential(
        &self,
        owner: &UserId,
        source: &ManagedSourceId,
    ) -> Result<Option<String>, OrchestrationError> {
        match self.managed.get_source(owner, source).await? {
            SourceSpec::Git {
                credential_reference: Some(reference),
                ..
            } => {
                let secrets =
                    SecretsBootstrap::get().map_err(OrchestrationError::CredentialsUnavailable)?;
                let credential = secrets
                    .get(&reference)
                    .filter(|value| !value.is_empty())
                    .ok_or(OrchestrationError::CredentialUnresolved)?;
                Ok(Some(credential.clone()))
            },
            SourceSpec::Git {
                credential_reference: None,
                ..
            } => Ok(None),
            _ => Err(OrchestrationError::NotGitSource),
        }
    }
}