use crate::store::STORE_TABLE; use redb::{Database, ReadableTable}; use std::path::Path; use std::sync::Arc; pub fn init_redb(base: &Path) -> Arc { let redb_path = base.join("mcp_store.redb"); let db = Arc::new(redb::Database::create(&redb_path).expect("Failed to create redb database")); // Ensure the table exists and migrate legacy JSON files let write_txn = db.begin_write().expect("Failed to begin write txn on redb"); { let mut table = write_txn .open_table(STORE_TABLE) .expect("Failed to open STORE_TABLE"); let stores = vec![ ("knowledge_graph_master", "knowledge_graph_master.json"), ("audit_ledger", "audit_ledger.json"), ("sticky_notes", "sticky_notes.json"), ("tasks", "tasks.json"), ("snippets", "snippets.json"), ("adrs", "adrs.json"), ("preferences", "preferences.json"), ("error_fixes", "error_fixes.json"), ("pinned_files", "pinned_files.json"), ("session_summaries", "session_summaries.json"), ("handoff_memos", "handoff_memos.json"), ("env_fingerprints", "env_fingerprints.json"), ("env_requirements", "env_requirements.json"), ("milestones", "milestones.json"), ("environments", "environments.json"), ("pr_checklists", "pr_checklists.json"), ("tech_debts", "tech_debts.json"), ("gates", "gates.json"), ("context_workspaces", "context_workspaces.json"), ]; for (key, file_name) in stores.iter() { if table .get(*key) .expect("Failed to read from table") .is_none() { let json_path = base.join(file_name); if json_path.exists() && let Ok(data) = std::fs::read(&json_path) && serde_json::from_slice::(&data).is_ok() { table .insert(*key, data.as_slice()) .expect("Failed to insert migrated data"); let _ = std::fs::rename(&json_path, json_path.with_extension("json.migrated")); } } } } write_txn.commit().expect("Failed to commit db migration"); db }