clipmem 0.4.0

macOS clipboard memory backed by SQLite and searchable from agent runtimes
Documentation
use super::*;

pub(in crate::cli) fn render_stats_human(envelope: &StatsEnvelope) -> String {
    let theme = HumanTheme::detect();
    let stats = &envelope.stats;
    let mut out = header(&theme, "clipmem Archive Stats");
    let _ = writeln!(
        out,
        "Generated {}  Filters: {}",
        format_timestamp_short(&envelope.generated_at),
        render_filter_summary(&envelope.applied_filters)
    );
    out.push('\n');

    push_kpi(&mut out, "Snapshots", format_count(stats.snapshot_count));
    push_kpi(
        &mut out,
        "Capture events",
        format_count(stats.capture_event_count),
    );
    push_kpi(
        &mut out,
        "Unique apps",
        format_count(stats.unique_app_count),
    );
    push_kpi(
        &mut out,
        "Total size",
        format_bytes(stats.total_bytes as u64),
    );
    push_kpi(
        &mut out,
        "Avg snapshot",
        format_bytes(stats.average_bytes_per_snapshot.round().max(0.0) as u64),
    );
    push_kpi(
        &mut out,
        "Avg captures",
        format!("{:.2}", stats.average_captures_per_snapshot),
    );
    push_kpi(&mut out, "Dedupe ratio", format_percent(stats.dedupe_ratio));
    push_kpi(
        &mut out,
        "Observed",
        format!(
            "{} to {}",
            stats
                .first_observed_at
                .as_deref()
                .map(format_timestamp_short)
                .unwrap_or_else(|| "none".to_string()),
            stats
                .last_observed_at
                .as_deref()
                .map(format_timestamp_short)
                .unwrap_or_else(|| "none".to_string())
        ),
    );
    push_kpi(
        &mut out,
        "Archive span",
        stats
            .archive_span_seconds
            .map(|seconds| format_duration_seconds(seconds.max(0) as u64))
            .unwrap_or_else(|| "0s".to_string()),
    );
    let dedupe_pct = (stats.dedupe_ratio * 100.0).clamp(0.0, 100.0);
    let dedupe_bar = theme.bar(dedupe_pct.round() as usize, 100, 24);
    let _ = writeln!(
        out,
        "Dedupe meter:     {} {}",
        dedupe_bar,
        theme.score(stats.dedupe_ratio, &format!("{dedupe_pct:.1}%"))
    );
    out.push('\n');

    push_content_mix(&mut out, &theme, stats);
    push_top_apps(&mut out, &theme, stats);
    push_activity(&mut out, stats);
    push_leaderboards(&mut out, &theme, stats);
    out
}

pub(in crate::cli) fn push_content_mix(out: &mut String, theme: &HumanTheme, stats: &StatsReport) {
    let _ = writeln!(out, "{}", theme.section("Content Mix"));
    if stats.kind_breakdown.is_empty() {
        out.push_str("none\n\n");
        return;
    }
    out.push_str(&separator(WIDTH, false));
    out.push('\n');
    let _ = writeln!(
        out,
        "{:<14}  {:>10}  {:>10}  Impact",
        "Kind", "Snapshots", "Size"
    );
    out.push_str(&separator(WIDTH, false));
    out.push('\n');
    let max = stats
        .kind_breakdown
        .iter()
        .map(|entry| entry.snapshot_count)
        .max()
        .unwrap_or(1);
    for entry in &stats.kind_breakdown {
        let _ = writeln!(
            out,
            "{:<14}  {:>10}  {:>10}  {}",
            truncate_cell(&entry.kind, 14),
            format_count(entry.snapshot_count),
            format_bytes(entry.total_bytes as u64),
            theme.bar(entry.snapshot_count, max, BAR_WIDTH)
        );
    }
    out.push('\n');
}

pub(in crate::cli) fn push_top_apps(out: &mut String, theme: &HumanTheme, stats: &StatsReport) {
    let _ = writeln!(out, "{}", theme.section("Top Apps"));
    if stats.top_apps.is_empty() {
        out.push_str("none\n\n");
        return;
    }
    out.push_str(&separator(WIDTH, false));
    out.push('\n');
    let _ = writeln!(out, "{:<30}  {:>10}  Impact", "App", "Events");
    out.push_str(&separator(WIDTH, false));
    out.push('\n');
    let max = stats
        .top_apps
        .iter()
        .map(|entry| entry.capture_event_count)
        .max()
        .unwrap_or(1);
    for entry in &stats.top_apps {
        let _ = writeln!(
            out,
            "{:<30}  {:>10}  {}",
            truncate_cell(&entry.app, 30),
            format_count(entry.capture_event_count),
            theme.bar(entry.capture_event_count, max, BAR_WIDTH)
        );
    }
    out.push('\n');
}

pub(in crate::cli) fn push_activity(out: &mut String, stats: &StatsReport) {
    out.push_str("Activity\n");
    out.push_str(&separator(60, false));
    out.push('\n');
    push_kpi(
        out,
        "Busiest hour",
        peak_bucket(&stats.busiest_hours)
            .map(|entry| {
                format!(
                    "{}:00 UTC ({} events)",
                    entry.bucket, entry.capture_event_count
                )
            })
            .unwrap_or_else(|| "none".to_string()),
    );
    push_kpi(
        out,
        "Busiest weekday",
        peak_bucket(&stats.busiest_weekdays)
            .map(|entry| format!("{} ({} events)", entry.bucket, entry.capture_event_count))
            .unwrap_or_else(|| "none".to_string()),
    );
    out.push('\n');
}

pub(in crate::cli) fn push_leaderboards(out: &mut String, theme: &HumanTheme, stats: &StatsReport) {
    let _ = writeln!(out, "{}", theme.section("Leaderboards"));
    if let Some(snapshot) = &stats.most_recopied_snapshot {
        let _ = writeln!(out, "Most re-copied");
        push_leaderboard_row(out, theme, snapshot);
    } else {
        out.push_str("Most re-copied: none\n");
    }
    push_leaderboard(out, theme, "Largest snapshots", &stats.largest_snapshots);
    push_leaderboard(
        out,
        theme,
        "Most captured snapshots",
        &stats.most_captured_snapshots,
    );
}

pub(in crate::cli) fn push_leaderboard(
    out: &mut String,
    theme: &HumanTheme,
    title: &str,
    entries: &[StatsSnapshotLeaderboardEntry],
) {
    let _ = writeln!(out);
    let _ = writeln!(out, "{title}");
    if entries.is_empty() {
        out.push_str("none\n");
        return;
    }
    for entry in entries {
        push_leaderboard_row(out, theme, entry);
    }
}

pub(in crate::cli) fn push_leaderboard_row(
    out: &mut String,
    theme: &HumanTheme,
    entry: &StatsSnapshotLeaderboardEntry,
) {
    let app = entry.app_name.as_deref().unwrap_or("unknown");
    let preview = if entry.preview_text.trim().is_empty() {
        "(no preview)"
    } else {
        entry.preview_text.trim()
    };
    let _ = writeln!(
        out,
        "  [{}] {:>5} captures  {:<7} {:>8}  {}  {}",
        theme.id(entry.snapshot_id),
        entry.capture_count,
        entry.kind,
        format_bytes(entry.total_bytes as u64),
        format_timestamp_short(&entry.last_observed_at),
        truncate_cell(&format!("{} - {}", app, preview.replace('\n', " ")), 42)
    );
}