zeroski 0.0.1

zero.ski CLI — @-protocol dispatch, streaming chat, and trace feed for the Zero runtime
//! `zeroski traces` — list recent traces.
//!
//! If --agent is not given, we first call /api/me to discover the caller's
//! agent_id, then GET /traces/agent/:hex?limit=N. Output is pretty JSON so
//! it plays well with `jq`. No --follow yet (v0.1 adds WS + tail mode).

use anyhow::{anyhow, Result};
use serde_json::Value;

use crate::api::Client;
use crate::config::Config;

pub async fn run(cfg: &Config, agent: Option<String>, limit: u32) -> Result<()> {
    let client = Client::new(cfg)?;

    let agent_id = match agent {
        Some(a) => a,
        None => {
            let me: Value = client.get_json("/api/me").await?;
            me.get("agent_id")
                .and_then(Value::as_str)
                .map(str::to_string)
                .ok_or_else(|| {
                    anyhow!("/api/me did not return agent_id; pass --agent <hex> explicitly")
                })?
        }
    };

    if agent_id.len() != 32 || !agent_id.chars().all(|c| c.is_ascii_hexdigit()) {
        return Err(anyhow!("invalid agent_id: {agent_id} (expected 32-char hex)"));
    }

    let path = format!("/traces/agent/{agent_id}?limit={limit}");
    let resp: Value = client.get_json(&path).await?;
    println!("{}", serde_json::to_string_pretty(&resp)?);
    Ok(())
}