forked from kent/consciousness
Convert store and CLI to anyhow::Result for cleaner error handling
Replace Result<_, String> with anyhow::Result throughout: - hippocampus/store module (persist, ops, types, view, mod) - CLI modules (admin, agent, graph, journal, node) - Run trait in main.rs Use .context() and .with_context() instead of .map_err(|e| format!(...)) patterns. Add bail!() for early error returns. Add access_local() helper in hippocampus/mod.rs that returns Result<Arc<Mutex<Store>>> for direct local store access. Fix store access patterns to properly lock Arc<Mutex<Store>> before accessing fields in mind/unconscious.rs, mind/mod.rs, subconscious/learn.rs, and hippocampus/memory.rs. Co-Authored-By: Proof of Concept <poc@bcachefs.org>
This commit is contained in:
parent
5db00e083f
commit
b8db8754be
17 changed files with 282 additions and 295 deletions
|
|
@ -1,24 +1,23 @@
|
|||
// cli/admin.rs — admin subcommand handlers
|
||||
|
||||
use anyhow::{Context, Result};
|
||||
use crate::hippocampus as memory;
|
||||
use crate::store;
|
||||
use crate::hippocampus::store;
|
||||
|
||||
fn install_default_file(data_dir: &std::path::Path, name: &str, content: &str) -> Result<(), String> {
|
||||
fn install_default_file(data_dir: &std::path::Path, name: &str, content: &str) -> Result<()> {
|
||||
let path = data_dir.join(name);
|
||||
if !path.exists() {
|
||||
std::fs::write(&path, content)
|
||||
.map_err(|e| format!("write {}: {}", name, e))?;
|
||||
std::fs::write(&path, content)?;
|
||||
println!("Created {}", path.display());
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn cmd_init() -> Result<(), String> {
|
||||
pub async fn cmd_init() -> Result<()> {
|
||||
let cfg = crate::config::get();
|
||||
|
||||
// Ensure data directory exists
|
||||
std::fs::create_dir_all(&cfg.data_dir)
|
||||
.map_err(|e| format!("create data_dir: {}", e))?;
|
||||
std::fs::create_dir_all(&cfg.data_dir)?;
|
||||
|
||||
// Install filesystem files (not store nodes)
|
||||
install_default_file(&cfg.data_dir, "instructions.md",
|
||||
|
|
@ -27,17 +26,17 @@ pub fn cmd_init() -> Result<(), String> {
|
|||
include_str!("../../defaults/on-consciousness.md"))?;
|
||||
|
||||
// Initialize store and seed default identity node if empty
|
||||
let mut store = store::Store::load()?;
|
||||
let count = store.init_from_markdown()?;
|
||||
let arc = memory::access_local()?;
|
||||
let mut store = arc.lock().await;
|
||||
let count = store.init_from_markdown().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
for key in &cfg.core_nodes {
|
||||
if !store.nodes.contains_key(key) && key == "identity" {
|
||||
let default = include_str!("../../defaults/identity.md");
|
||||
store.upsert(key, default)
|
||||
.map_err(|e| format!("seed {}: {}", key, e))?;
|
||||
store.upsert(key, default).map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
println!("Seeded {} in store", key);
|
||||
}
|
||||
}
|
||||
store.save()?;
|
||||
store.save().map_err(|e| anyhow::anyhow!("{}", e))?;
|
||||
println!("Indexed {} memory units", count);
|
||||
|
||||
// Create config if none exists
|
||||
|
|
@ -49,11 +48,9 @@ pub fn cmd_init() -> Result<(), String> {
|
|||
});
|
||||
if !config_path.exists() {
|
||||
let config_dir = config_path.parent().unwrap();
|
||||
std::fs::create_dir_all(config_dir)
|
||||
.map_err(|e| format!("create config dir: {}", e))?;
|
||||
std::fs::create_dir_all(config_dir)?;
|
||||
let example = include_str!("../../config.example.jsonl");
|
||||
std::fs::write(&config_path, example)
|
||||
.map_err(|e| format!("write config: {}", e))?;
|
||||
std::fs::write(&config_path, example)?;
|
||||
println!("Created config at {} — edit with your name and context groups",
|
||||
config_path.display());
|
||||
}
|
||||
|
|
@ -62,7 +59,7 @@ pub fn cmd_init() -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn cmd_fsck() -> Result<(), String> {
|
||||
pub fn cmd_fsck() -> Result<()> {
|
||||
let mut store = store::Store::load()?;
|
||||
|
||||
// Check cache vs log consistency
|
||||
|
|
@ -96,7 +93,7 @@ pub fn cmd_fsck() -> Result<(), String> {
|
|||
if cache_issues > 0 {
|
||||
eprintln!("{} cache inconsistencies found — rebuilding from logs", cache_issues);
|
||||
store = log_store;
|
||||
store.save().map_err(|e| format!("rebuild save: {}", e))?;
|
||||
store.save().context("rebuild save")?;
|
||||
}
|
||||
|
||||
// Check node-key consistency
|
||||
|
|
@ -153,10 +150,11 @@ pub fn cmd_fsck() -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn cmd_dedup(apply: bool) -> Result<(), String> {
|
||||
pub async fn cmd_dedup(apply: bool) -> Result<()> {
|
||||
use std::collections::{HashMap, HashSet};
|
||||
|
||||
let mut store = store::Store::load()?;
|
||||
let arc = memory::access_local()?;
|
||||
let mut store = arc.lock().await;
|
||||
let duplicates = store.find_duplicates()?;
|
||||
|
||||
if duplicates.is_empty() {
|
||||
|
|
@ -329,30 +327,31 @@ pub fn cmd_dedup(apply: bool) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cmd_health() -> Result<(), String> {
|
||||
pub async fn cmd_health() -> Result<()> {
|
||||
let result = memory::graph_health(None).await
|
||||
.map_err(|e| e.to_string())?;
|
||||
?;
|
||||
print!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cmd_topology() -> Result<(), String> {
|
||||
pub async fn cmd_topology() -> Result<()> {
|
||||
let result = memory::graph_topology(None).await
|
||||
.map_err(|e| e.to_string())?;
|
||||
?;
|
||||
print!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn cmd_daily_check() -> Result<(), String> {
|
||||
let store = store::Store::load()?;
|
||||
pub async fn cmd_daily_check() -> Result<()> {
|
||||
let arc = memory::access_local()?;
|
||||
let store = arc.lock().await;
|
||||
let report = crate::neuro::daily_check(&store);
|
||||
print!("{}", report);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn cmd_import(files: &[String]) -> Result<(), String> {
|
||||
pub fn cmd_import(files: &[String]) -> Result<()> {
|
||||
if files.is_empty() {
|
||||
return Err("import requires at least one file path".into());
|
||||
anyhow::bail!("import requires at least one file path");
|
||||
}
|
||||
|
||||
let mut store = store::Store::load()?;
|
||||
|
|
@ -383,7 +382,7 @@ pub fn cmd_import(files: &[String]) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn cmd_export(files: &[String], export_all: bool) -> Result<(), String> {
|
||||
pub fn cmd_export(files: &[String], export_all: bool) -> Result<()> {
|
||||
let store = store::Store::load()?;
|
||||
|
||||
let targets: Vec<String> = if export_all {
|
||||
|
|
@ -394,7 +393,7 @@ pub fn cmd_export(files: &[String], export_all: bool) -> Result<(), String> {
|
|||
files.sort();
|
||||
files
|
||||
} else if files.is_empty() {
|
||||
return Err("export requires file keys or --all".into());
|
||||
anyhow::bail!("export requires file keys or --all");
|
||||
} else {
|
||||
files.iter().map(|a| {
|
||||
a.strip_suffix(".md").unwrap_or(a).to_string()
|
||||
|
|
@ -408,7 +407,7 @@ pub fn cmd_export(files: &[String], export_all: bool) -> Result<(), String> {
|
|||
Some(content) => {
|
||||
let out_path = mem_dir.join(format!("{}.md", file_key));
|
||||
std::fs::write(&out_path, &content)
|
||||
.map_err(|e| format!("write {}: {}", out_path.display(), e))?;
|
||||
.with_context(|| format!("write {}", out_path.display()))?;
|
||||
let section_count = content.matches("<!-- mem:").count() + 1;
|
||||
println!("Exported {} ({} sections)", file_key, section_count);
|
||||
}
|
||||
|
|
@ -419,9 +418,9 @@ pub fn cmd_export(files: &[String], export_all: bool) -> Result<(), String> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn cmd_status() -> Result<(), String> {
|
||||
pub async fn cmd_status() -> Result<()> {
|
||||
let result = memory::graph_topology(None).await
|
||||
.map_err(|e| e.to_string())?;
|
||||
?;
|
||||
print!("{}", result);
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue