WeaveDocs
Agentfs Mirror

Progress and Stats

Progress reporting and stats in `agentfs-mirror` — observable mirror sessions with per-file progress and aggregate metrics.

Purpose

Mirror engine with conflict resolution, sparse sync, progress reporting, checkpoint plans, stats, and watchers.

This page follows the real source shape for Agentfs Mirror and explains the workflow a developer is likely to use first.

Developer workflow

Start from the smallest constructor or builder, perform one meaningful operation, inspect the returned state, then add the relevant policy, storage, or network integration. The examples below should be expanded whenever the crate API changes.

Primary types to know

  • Checkpoint — local/agentfs-mirror/src/sync.rs
  • Conflict — local/agentfs-mirror/src/conflict.rs
  • ConflictResolver — local/agentfs-mirror/src/conflict.rs
  • FileInfo — local/agentfs-mirror/src/conflict.rs
  • FileStats — local/agentfs-mirror/src/stats.rs
  • Mirror — local/agentfs-mirror/src/mirror.rs
  • MirrorOptions — local/agentfs-mirror/src/options.rs
  • MirrorWatcher — local/agentfs-mirror/src/watcher.rs
  • Plan — local/agentfs-mirror/src/sync.rs
  • PlanOp — local/agentfs-mirror/src/sync.rs
  • ProgressReporter — local/agentfs-mirror/src/progress.rs
  • SparseOptions — local/agentfs-mirror/src/sparse.rs

Example shape

use agentfs_mirror::{ProgressEvent, ProgressReporter, SyncStats};
use std::path::PathBuf;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // ProgressReporter owns a multi-bar terminal renderer and an event channel.
    // Mirror engines forward ProgressEvent values to the cloned sender.
    let reporter = ProgressReporter::new();
    let tx = reporter.sender();

    // Simulate the events a real sync emits, then start the renderer task.
    tx.send(ProgressEvent::Started { total_files: 3, total_bytes: 4_096 })?;
    tx.send(ProgressEvent::FileStarted {
        path: PathBuf::from("/docs/README.md"),
        size: 1_024,
    })?;
    tx.send(ProgressEvent::FileCompleted {
        path: PathBuf::from("/docs/README.md"),
        success: true,
    })?;

    let mut stats = SyncStats::new();
    stats.files_processed = 3;
    stats.files_synced = 2;
    stats.files_skipped = 1;
    stats.bytes_transferred = 4_096;
    tx.send(ProgressEvent::Completed { stats: stats.clone() })?;

    reporter.start().await;
    println!(
        "synced {}/{} files ({} bytes), conflicts={}",
        stats.files_synced, stats.files_processed, stats.bytes_transferred, stats.conflicts,
    );
    Ok(())
}