systemprompt-cli 0.2.1

Unified CLI for systemprompt.io AI governance: agent orchestration, MCP governance, analytics, profiles, cloud deploy, and self-hosted operations.
Documentation
use anyhow::Result;
use clap::Args;
use systemprompt_database::DbPool;
use systemprompt_runtime::AppContext;
use systemprompt_users::BannedIpRepository;

use crate::CliConfig;
use crate::commands::admin::users::types::{BanListOutput, BanSummary};
use crate::shared::CommandResult;

#[derive(Debug, Args)]
pub struct ListArgs {
    #[arg(long, default_value = "50")]
    pub limit: i64,

    #[arg(long)]
    pub source: Option<String>,
}

pub async fn execute(args: ListArgs, config: &CliConfig) -> Result<CommandResult<BanListOutput>> {
    let ctx = AppContext::new().await?;
    execute_with_pool(args, ctx.db_pool(), config).await
}

pub async fn execute_with_pool(
    args: ListArgs,
    pool: &DbPool,
    _config: &CliConfig,
) -> Result<CommandResult<BanListOutput>> {
    let ban_repository = BannedIpRepository::new(pool)?;

    let bans = match args.source {
        Some(ref source) => {
            ban_repository
                .list_bans_by_source(source, args.limit)
                .await?
        },
        None => ban_repository.list_active_bans(args.limit).await?,
    };

    let summaries: Vec<BanSummary> = bans
        .into_iter()
        .map(|b| BanSummary {
            ip_address: b.ip_address,
            reason: b.reason,
            banned_at: b.banned_at,
            expires_at: b.expires_at,
            is_permanent: b.is_permanent,
            ban_count: b.ban_count,
            ban_source: b.ban_source,
        })
        .collect();

    let output = BanListOutput {
        total: summaries.len(),
        bans: summaries,
    };

    Ok(CommandResult::table(output)
        .with_title("Banned IPs")
        .with_columns(vec![
            "ip_address".to_string(),
            "reason".to_string(),
            "banned_at".to_string(),
            "expires_at".to_string(),
            "is_permanent".to_string(),
        ]))
}