2026-03-14 18:10:22 -04:00
|
|
|
// cli/journal.rs — journal subcommand handlers
|
|
|
|
|
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
use anyhow::{bail, Context, Result};
|
2026-04-13 17:44:33 -04:00
|
|
|
use crate::hippocampus as memory;
|
2026-03-14 18:10:22 -04:00
|
|
|
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
pub fn cmd_tail(n: usize, full: bool, provenance: Option<&str>, dedup: bool) -> Result<()> {
|
2026-03-14 18:10:22 -04:00
|
|
|
let path = crate::store::nodes_path();
|
|
|
|
|
if !path.exists() {
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
bail!("No node log found");
|
2026-03-14 18:10:22 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
use std::io::BufReader;
|
|
|
|
|
let file = std::fs::File::open(&path)
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
.with_context(|| format!("open {}", path.display()))?;
|
2026-03-14 18:10:22 -04:00
|
|
|
let mut reader = BufReader::new(file);
|
|
|
|
|
|
|
|
|
|
// Read all entries, keep last N
|
|
|
|
|
let mut entries: Vec<crate::store::Node> = Vec::new();
|
|
|
|
|
while let Ok(msg) = capnp::serialize::read_message(&mut reader, capnp::message::ReaderOptions::new()) {
|
|
|
|
|
let log = msg.get_root::<crate::memory_capnp::node_log::Reader>()
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
.with_context(|| "read log")?;
|
2026-03-14 18:10:22 -04:00
|
|
|
for node_reader in log.get_nodes()
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
.with_context(|| "get nodes")? {
|
2026-03-14 18:10:22 -04:00
|
|
|
let node = crate::store::Node::from_capnp_migrate(node_reader)?;
|
|
|
|
|
entries.push(node);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 19:11:17 -04:00
|
|
|
// Filter by provenance if specified (substring match)
|
2026-03-26 18:41:10 -04:00
|
|
|
if let Some(prov) = provenance {
|
|
|
|
|
entries.retain(|n| n.provenance.contains(prov));
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 19:11:17 -04:00
|
|
|
// Dedup: keep only the latest version of each key
|
|
|
|
|
if dedup {
|
|
|
|
|
let mut seen = std::collections::HashSet::new();
|
|
|
|
|
// Walk backwards so we keep the latest
|
|
|
|
|
entries = entries.into_iter().rev()
|
|
|
|
|
.filter(|n| seen.insert(n.key.clone()))
|
|
|
|
|
.collect();
|
|
|
|
|
entries.reverse();
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-14 18:10:22 -04:00
|
|
|
let start = entries.len().saturating_sub(n);
|
|
|
|
|
for node in &entries[start..] {
|
|
|
|
|
let ts = if node.timestamp > 0 && node.timestamp < 4_000_000_000 {
|
|
|
|
|
crate::store::format_datetime(node.timestamp)
|
|
|
|
|
} else {
|
|
|
|
|
format!("(raw:{})", node.timestamp)
|
|
|
|
|
};
|
|
|
|
|
let del = if node.deleted { " [DELETED]" } else { "" };
|
|
|
|
|
if full {
|
2026-03-26 17:48:44 -04:00
|
|
|
println!("--- {} (v{}) {} via {} w={:.3}{} ---",
|
2026-03-14 18:10:22 -04:00
|
|
|
node.key, node.version, ts, node.provenance, node.weight, del);
|
2026-03-26 17:48:44 -04:00
|
|
|
println!("{}\n", node.content);
|
2026-03-14 18:10:22 -04:00
|
|
|
} else {
|
|
|
|
|
let preview = crate::util::first_n_chars(&node.content, 100).replace('\n', "\\n");
|
2026-03-26 17:48:44 -04:00
|
|
|
println!(" {} v{} w={:.2}{}",
|
2026-03-14 18:10:22 -04:00
|
|
|
ts, node.version, node.weight, del);
|
2026-03-26 17:48:44 -04:00
|
|
|
println!(" {} via {}", node.key, node.provenance);
|
2026-03-14 18:10:22 -04:00
|
|
|
if !preview.is_empty() {
|
2026-03-26 17:48:44 -04:00
|
|
|
println!(" {}", preview);
|
2026-03-14 18:10:22 -04:00
|
|
|
}
|
2026-03-26 17:48:44 -04:00
|
|
|
println!();
|
2026-03-14 18:10:22 -04:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
pub async fn cmd_journal_tail(n: usize, full: bool, level: u8) -> Result<()> {
|
|
|
|
|
let entries = memory::journal_tail(None, Some(n as u64), Some(level as u64), None).await?;
|
2026-04-13 15:23:10 -04:00
|
|
|
for entry in entries {
|
|
|
|
|
if full {
|
|
|
|
|
println!("--- {} ---", entry.key);
|
|
|
|
|
println!("{}\n", entry.content);
|
|
|
|
|
} else {
|
|
|
|
|
let first_line = entry.content.lines().next().unwrap_or("(empty)");
|
|
|
|
|
println!("{}: {}", entry.key, first_line);
|
|
|
|
|
}
|
|
|
|
|
}
|
2026-04-12 21:54:34 -04:00
|
|
|
Ok(())
|
2026-03-14 18:14:52 -04:00
|
|
|
}
|
|
|
|
|
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
pub async fn cmd_journal_write(name: &str, text: &[String]) -> Result<()> {
|
2026-03-14 18:14:52 -04:00
|
|
|
if text.is_empty() {
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
bail!("journal write requires text");
|
2026-03-14 18:14:52 -04:00
|
|
|
}
|
poc-memory: POC_MEMORY_DRY_RUN=1 for agent testing
All mutating commands (write, delete, rename, link-add, journal write,
used, wrong, not-useful, gap) check POC_MEMORY_DRY_RUN after argument
validation but before mutation. If set, process exits silently — agent
tool calls are visible in the LLM output so we can see what it tried
to do without applying changes.
Read commands (render, search, graph link, journal tail) work normally
in dry-run mode so agents can still explore the graph.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 18:09:56 -04:00
|
|
|
super::check_dry_run();
|
2026-04-12 22:15:53 -04:00
|
|
|
let body = text.join(" ");
|
2026-03-14 18:14:52 -04:00
|
|
|
|
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>
2026-04-13 18:05:04 -04:00
|
|
|
let result = memory::journal_new(None, name, name, &body, Some(0)).await?;
|
2026-04-12 22:15:53 -04:00
|
|
|
println!("{}", result);
|
2026-03-14 18:14:52 -04:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|