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(())
}