systemprompt-cli 0.12.0

Unified CLI for systemprompt.io AI governance: agent orchestration, MCP governance, analytics, profiles, cloud deploy, and self-hosted operations.
Documentation
use std::path::PathBuf;

use anyhow::{Context, Result};
use clap::Args;

use super::logs_db::execute_db_mode;
use super::logs_disk::{execute_disk_mode, execute_follow_mode};
use super::types::AgentLogsOutput;
use crate::CliConfig;
use crate::shared::CommandResult;

#[derive(Debug, Args)]
pub struct LogsArgs {
    #[arg(help = "Agent name (optional - shows all agent logs if not specified)")]
    pub agent: Option<String>,

    #[arg(
        long,
        short = 'n',
        default_value = "50",
        help = "Number of lines to show"
    )]
    pub lines: usize,

    #[arg(long, short, help = "Follow log output continuously (disk only)")]
    pub follow: bool,

    #[arg(long, help = "Force reading from disk files instead of database")]
    pub disk: bool,

    #[arg(long, help = "Custom logs directory path")]
    pub logs_dir: Option<String>,
}

pub(super) async fn execute(
    args: LogsArgs,
    config: &CliConfig,
) -> Result<CommandResult<AgentLogsOutput>> {
    let logs_path = match args.logs_dir.as_deref() {
        Some(dir) => PathBuf::from(dir),
        None => PathBuf::from(
            systemprompt_models::Config::get()
                .context("agent log directory requires an initialised profile")?
                .logs_path(),
        ),
    };

    if args.follow {
        return execute_follow_mode(&args, config, &logs_path);
    }

    if args.disk {
        return execute_disk_mode(&args, config, &logs_path);
    }

    match execute_db_mode(&args, config).await {
        Ok(result) => Ok(result),
        Err(e) => {
            tracing::debug!(error = %e, "DB log query failed, falling back to disk");
            execute_disk_mode(&args, config, &logs_path)
        },
    }
}