systemprompt-cli 0.42.0

Unified CLI for systemprompt.io AI governance: agent orchestration, MCP governance, analytics, profiles, cloud deploy, and self-hosted operations.
Documentation
//! `admin bridge` subcommand: operator tools for the bridge helper.
//!
//! Exposes [`BridgeCommands`] for enrolling device-certificate fingerprints,
//! issuing one-shot session exchange codes, listing active bridge sessions,
//! and rotating the ed25519 manifest signing seed.
//!
//! Copyright (c) systemprompt.io — Business Source License 1.1.
//! See <https://systemprompt.io> for licensing details.

mod enroll_cert;
mod issue_code;
mod list;
mod rotate_signing_key;
mod types;

use crate::context::CommandContext;
use crate::shared::render_result;
use anyhow::{Result, anyhow};
use clap::Subcommand;
use std::sync::Arc;
use systemprompt_database::DbPool;
use systemprompt_identifiers::UserId;
use systemprompt_users::{UserAdminService, UserRepository, UserService};

pub(super) async fn resolve_user_id(pool: &DbPool, reference: &UserId) -> Result<UserId> {
    let reference = reference.as_str().trim();
    if reference.is_empty() {
        return Err(anyhow!("user_id cannot be empty"));
    }

    let admin_service =
        UserAdminService::new(UserService::new(Arc::new(UserRepository::new(pool)?)));
    admin_service
        .find_user(reference)
        .await?
        .map(|user| user.id)
        .ok_or_else(|| anyhow!("no user with id, email, or name '{reference}'"))
}

#[derive(Debug, Subcommand)]
pub enum BridgeCommands {
    #[command(about = "Enroll a device certificate fingerprint for a user")]
    EnrollCert(enroll_cert::EnrollCertArgs),

    #[command(about = "Issue a one-shot session exchange code for the bridge helper")]
    IssueCode(issue_code::IssueCodeArgs),

    #[command(about = "List active bridge sessions (recent heartbeats)")]
    List(list::ListArgs),

    #[command(
        about = "Generate a fresh ed25519 manifest signing seed and persist it to the secrets file"
    )]
    RotateSigningKey(rotate_signing_key::RotateSigningKeyArgs),
}

pub async fn execute(cmd: BridgeCommands, ctx: &CommandContext) -> Result<()> {
    match cmd {
        BridgeCommands::EnrollCert(args) => {
            let result = enroll_cert::execute(args, ctx).await?;
            render_result(&result, &ctx.cli);
            Ok(())
        },
        BridgeCommands::IssueCode(args) => {
            let result = issue_code::execute(args, ctx).await?;
            render_result(&result, &ctx.cli);
            Ok(())
        },
        BridgeCommands::List(args) => {
            let result = list::execute(args, ctx).await?;
            render_result(&result, &ctx.cli);
            Ok(())
        },
        BridgeCommands::RotateSigningKey(args) => {
            let result = rotate_signing_key::execute(args, &ctx.cli)?;
            render_result(&result, &ctx.cli);
            Ok(())
        },
    }
}