remem-ai 0.6.79

Local-first coding agent memory for Claude Code and OpenAI Codex
Documentation
use std::collections::BTreeMap;

use rusqlite::Connection;

use crate::db;

pub(super) fn with_candidate_source_kind_detail(conn: &Connection, mut detail: String) -> String {
    let Some(source_detail) = candidate_source_kind_detail(conn) else {
        return detail;
    };
    detail.push_str("; ");
    detail.push_str(&source_detail);
    detail
}

fn candidate_source_kind_detail(conn: &Connection) -> Option<String> {
    let now = chrono::Utc::now().timestamp();
    let stats = db::query_candidate_promotion_stats(conn, now).ok()?;
    if stats.is_empty() {
        return None;
    }
    #[derive(Default)]
    struct SourceSummary {
        total: i64,
        pending: i64,
        shadow_would_promote: i64,
    }
    let mut by_source: BTreeMap<String, SourceSummary> = BTreeMap::new();
    for stat in stats {
        let entry = by_source.entry(stat.source_kind).or_default();
        entry.total += stat.total;
        if stat.review_status == "pending_review" {
            entry.pending += stat.total;
        }
        if stat.block_reason.as_deref() == Some("summary_gate_shadow") {
            entry.shadow_would_promote += stat.total;
        }
    }
    Some(format!(
        "candidate_sources={}",
        by_source
            .into_iter()
            .map(|(source, summary)| format!(
                "{}:total={},pending={},shadow_would_promote={}",
                source, summary.total, summary.pending, summary.shadow_would_promote
            ))
            .collect::<Vec<_>>()
            .join(",")
    ))
}