agentlog 0.1.2

CLI flight recorder for AI coding agents - capture, store, and replay AI sessions
Documentation
use crate::core::db::DbManager;
use crate::core::{db_path, ensure_initialized};
use crate::models::EventType;
use anyhow::Result;
use colored::Colorize;

pub async fn execute(session_id: String) -> Result<()> {
    let project_root = ensure_initialized()?;
    let db_file = db_path(&project_root);

    let db = DbManager::open(&db_file)?;

    let all_sessions = db.get_sessions()?;
    let matched_session = all_sessions
        .iter()
        .find(|s| s.session_id.starts_with(&session_id));

    let full_session_id = match matched_session {
        Some(s) => s.session_id.clone(),
        None => {
            println!("{}", format!("Session '{}' not found.", session_id).red());
            return Ok(());
        }
    };

    let session_events = db.get_events_by_session(&full_session_id)?;

    if session_events.is_empty() {
        println!("{}", format!("Session '{}' not found.", session_id).red());
        return Ok(());
    }

    println!(
        "{}",
        format!("Replaying Session: {}", &full_session_id[..8])
            .bold()
            .underline()
    );
    println!();

    for (i, event) in session_events.iter().enumerate() {
        println!(
            "{}",
            format!(
                "[{}] {} - {:?}",
                i + 1,
                event.timestamp.format("%H:%M:%S"),
                event.r#type
            )
            .cyan()
        );

        match &event.r#type {
            EventType::SessionStart => {
                if let crate::models::Payload::SessionStart { cwd, command } = &event.payload {
                    println!("  Working directory: {}", cwd);
                    println!("  Command: {}", command);
                }
            }
            EventType::FileChange => {
                if let crate::models::Payload::FileChange {
                    file,
                    lines_added,
                    lines_removed,
                    ..
                } = &event.payload
                {
                    println!("  File: {}", file);
                    println!(
                        "  Changes: +{} -{}",
                        lines_added.to_string().green(),
                        lines_removed.to_string().red()
                    );
                }
            }
            EventType::SessionEnd => {
                if let crate::models::Payload::SessionEnd {
                    exit_code,
                    duration_ms,
                } = &event.payload
                {
                    let status = if *exit_code == 0 {
                        "Success".green()
                    } else {
                        format!("Exit {}", exit_code).red()
                    };
                    println!("  Status: {} | Duration: {}ms", status, duration_ms);
                }
            }
            _ => {
                println!("  {:?}", event.payload);
            }
        }
        println!();
    }

    Ok(())
}