systemprompt-cli 0.15.0

Unified CLI for systemprompt.io AI governance: agent orchestration, MCP governance, analytics, profiles, cloud deploy, and self-hosted operations.
Documentation
use anyhow::{Context, Result, bail};
use std::fs;
use std::path::Path;
use systemprompt_config::ProfileBootstrap;
use systemprompt_models::profile::RateLimitsConfig;

use super::helpers::{load_profile_for_edit, save_profile};
use super::{ExportArgs, ImportArgs};
use crate::CliConfig;
use crate::interactive::require_confirmation;
use crate::shared::CommandOutput;

use super::super::types::{ExportOutput, ImportOutput};

pub(super) fn execute_export(args: &ExportArgs, _config: &CliConfig) -> Result<CommandOutput> {
    let profile = ProfileBootstrap::get()?;
    let limits = &profile.rate_limits;

    let content = match args.format.as_str() {
        "yaml" | "yml" => {
            serde_yaml::to_string(limits).context("Failed to serialize rate limits to YAML")?
        },
        "json" => serde_json::to_string_pretty(limits)
            .context("Failed to serialize rate limits to JSON")?,
        _ => bail!("Unknown format: {}. Valid formats: yaml, json", args.format),
    };

    fs::write(&args.output, &content)
        .with_context(|| format!("Failed to write to file: {}", args.output))?;

    let output = ExportOutput {
        path: args.output.clone(),
        format: args.format.clone(),
        message: format!("Exported rate limits to {}", args.output),
    };

    Ok(CommandOutput::card_value("Rate Limits Exported", &output))
}

pub(super) fn execute_import(args: &ImportArgs, config: &CliConfig) -> Result<CommandOutput> {
    let path = Path::new(&args.file);
    if !path.exists() {
        bail!("File not found: {}", args.file);
    }

    let content = fs::read_to_string(&args.file)
        .with_context(|| format!("Failed to read file: {}", args.file))?;

    let is_json = Path::new(&args.file)
        .extension()
        .is_some_and(|ext| ext.eq_ignore_ascii_case("json"));

    let new_limits: RateLimitsConfig = if is_json {
        serde_json::from_str(&content)
            .with_context(|| format!("Failed to parse JSON from: {}", args.file))?
    } else {
        serde_yaml::from_str(&content)
            .with_context(|| format!("Failed to parse YAML from: {}", args.file))?
    };

    require_confirmation("Proceed with import?", args.yes, config)?;

    let profile_path = ProfileBootstrap::get_path()?;
    let mut profile = load_profile_for_edit(profile_path)?;
    profile.rate_limits = new_limits;
    save_profile(&profile, profile_path)?;

    let output = ImportOutput {
        path: args.file.clone(),
        changes: vec![],
        message: format!(
            "Imported rate limits from {}. Restart services for changes to take effect",
            args.file
        ),
    };

    Ok(CommandOutput::card_value("Rate Limits Imported", &output))
}