zag-cli 0.16.0

A unified CLI for AI coding agents — Claude, Codex, Gemini, Copilot, and Ollama
use anyhow::Result;
use zag_agent::session;

#[allow(clippy::too_many_arguments)]
pub(crate) fn run(
    provider: Option<String>,
    limit: Option<usize>,
    global: bool,
    name: Option<String>,
    tag: Option<String>,
    parent: Option<String>,
    json: bool,
    root: Option<&str>,
) -> Result<()> {
    let store = if global {
        session::SessionStore::load_all()?
    } else {
        session::SessionStore::load(root)?
    };
    let mut sessions = store.list();
    if let Some(ref p) = provider {
        sessions.retain(|s| s.provider == *p);
    }
    if let Some(ref n) = name {
        let n_lower = n.to_lowercase();
        sessions.retain(|s| {
            s.name
                .as_ref()
                .map(|sn| sn.to_lowercase().contains(&n_lower))
                .unwrap_or(false)
        });
    }
    if let Some(ref t) = tag {
        let t_lower = t.to_lowercase();
        sessions.retain(|s| s.tags.iter().any(|st| st.to_lowercase() == t_lower));
    }
    if let Some(ref parent_id) = parent {
        let proc_store = zag_agent::process_store::ProcessStore::load().unwrap_or_default();
        let child_session_ids: std::collections::HashSet<String> = proc_store
            .processes
            .iter()
            .filter(|e| {
                e.parent_session_id.as_deref() == Some(parent_id)
                    || e.parent_process_id.as_deref() == Some(parent_id)
            })
            .filter_map(|e| e.session_id.clone())
            .collect();
        sessions.retain(|s| child_session_ids.contains(&s.session_id));
    }
    if let Some(n) = limit {
        sessions.truncate(n);
    }
    if json {
        println!("{}", serde_json::to_string(&sessions)?);
        return Ok(());
    }
    if sessions.is_empty() {
        println!("No sessions found.");
        return Ok(());
    }
    println!(
        "{:<38} {:<20} {:<10} {:<12} CREATED",
        "SESSION ID", "NAME", "PROVIDER", "MODEL"
    );
    println!("{}", "-".repeat(110));
    for s in &sessions {
        let name_display = s
            .name
            .as_deref()
            .map(|n| {
                if n.len() > 18 {
                    format!("{}", &n[..17])
                } else {
                    n.to_string()
                }
            })
            .unwrap_or_else(|| "-".to_string());
        println!(
            "{:<38} {:<20} {:<10} {:<12} {}",
            s.session_id, name_display, s.provider, s.model, s.created_at
        );
    }
    Ok(())
}