remem-ai 0.4.9

Persistent memory for Claude Code and Codex — single binary, automatic context
Documentation
use anyhow::{bail, Result};

use crate::cli::types::ReviewAction;
use crate::db;
use crate::memory_candidate::review::{self, CandidateEdit};

pub(in crate::cli) fn run_review(action: ReviewAction) -> Result<()> {
    let mut conn = db::open_db()?;

    match action {
        ReviewAction::List { project, limit } => {
            let rows = review::list_pending(&conn, project.as_deref(), limit)?;
            if rows.is_empty() {
                println!("No pending memory candidates.");
                return Ok(());
            }
            println!("Pending memory candidates ({}):", rows.len());
            for row in rows {
                let project = row.project.as_deref().unwrap_or("<unknown project>");
                println!(
                    "  [{}] {} {} {} confidence={:.2} risk={} project={}",
                    row.id,
                    row.scope,
                    row.memory_type,
                    row.topic_key,
                    row.confidence,
                    row.risk_class,
                    project
                );
                println!("      text: {}", db::truncate_str(&row.text, 180));
                println!("      evidence: {}", row.evidence_event_ids);
                for evidence in row.evidence_preview {
                    println!("        {}", evidence);
                }
            }
        }
        ReviewAction::Approve { id } => {
            let Some(memory_id) = review::approve_candidate(&mut conn, id)? else {
                bail!("candidate {} not found", id);
            };
            println!("Approved candidate {}; promoted memory {}.", id, memory_id);
        }
        ReviewAction::Discard { id } => {
            if review::discard_candidate(&conn, id)? {
                println!("Discarded candidate {}.", id);
            } else {
                bail!("candidate {} not found or not pending_review", id);
            }
        }
        ReviewAction::Edit {
            id,
            text,
            topic_key,
            memory_type,
            scope,
        } => {
            let edit = CandidateEdit {
                scope,
                memory_type,
                topic_key,
                text,
            };
            let Some(memory_id) = review::edit_candidate(&mut conn, id, edit)? else {
                bail!("candidate {} not found", id);
            };
            println!("Edited candidate {}; promoted memory {}.", id, memory_id);
        }
    }

    Ok(())
}