kiromi-ai-cli 0.2.2

Operator and developer CLI for the kiromi-ai-memory store: append, search, snapshot, regenerate, migrate-scheme, gc, audit-tail.
// SPDX-License-Identifier: Apache-2.0 OR MIT
//! `kiromi-ai-memory export --partition <p> --to <dir>`.

use kiromi_ai_memory::ListOpts;

use crate::cli::{ExportArgs, GlobalArgs};
use crate::cmd::append::parse_partitions;
use crate::error::{CliError, ExitCode};
use crate::runtime::Runtime;

pub(crate) async fn run(args: ExportArgs, globals: &GlobalArgs) -> Result<(), CliError> {
    let rt = Runtime::open(globals).await?;
    tokio::fs::create_dir_all(&args.to)
        .await
        .map_err(|e| CliError {
            kind: ExitCode::Backend,
            source: anyhow::anyhow!("create --to {}: {e}", args.to.display()),
        })?;

    let partitions = parse_partitions(&args.partition)?;
    let mut cursor: Option<String> = None;
    let mut written = 0_usize;
    loop {
        let mut opts = ListOpts::default();
        opts.limit = 200;
        opts.cursor = cursor.clone();
        opts.include_tombstoned = false;
        let page = rt.mem.list(partitions.clone(), opts).await?;
        for r in &page.items {
            let rec = rt.mem.get(r).await?;
            let kind = rec.content.kind().extension();
            let path = args.to.join(format!("{}.{}", r.id, kind));
            tokio::fs::write(&path, rec.content.as_str().as_bytes())
                .await
                .map_err(|e| CliError {
                    kind: ExitCode::Backend,
                    source: anyhow::anyhow!("write {}: {e}", path.display()),
                })?;
            written += 1;
        }
        match page.next_cursor {
            Some(c) => cursor = Some(c),
            None => break,
        }
    }
    if globals.json {
        println!(
            "{}",
            crate::output::to_json(&serde_json::json!({
                "written": written,
                "to": args.to.display().to_string(),
            }))
        );
    } else {
        println!("exported {written} memories to {}", args.to.display());
    }
    rt.mem.close().await?;
    Ok(())
}