daemon status: add in-flight tasks, recent completions, and node history command

Show running/pending tasks with elapsed time, progress, and last 3
output lines. Show last 20 completed/failed jobs from daemon log.
Both displayed before the existing grouped task view.

Add 'poc-memory history KEY' command that replays the append-only node
log to show all versions of a key with version number, weight, timestamp,
and content preview. Useful for auditing what modified a node.
This commit is contained in:
ProofOfConcept 2026-03-06 21:38:33 -05:00
parent f4c4e1bb39
commit 851fc0d417
2 changed files with 134 additions and 0 deletions

View file

@ -107,6 +107,7 @@ fn main() {
"journal-ts-migrate" => cmd_journal_ts_migrate(),
"load-context" => cmd_load_context(&args[2..]),
"render" => cmd_render(&args[2..]),
"history" => cmd_history(&args[2..]),
"write" => cmd_write(&args[2..]),
"import" => cmd_import(&args[2..]),
"export" => cmd_export(&args[2..]),
@ -1547,6 +1548,57 @@ fn cmd_render(args: &[String]) -> Result<(), String> {
Ok(())
}
fn cmd_history(args: &[String]) -> Result<(), String> {
if args.is_empty() {
return Err("Usage: poc-memory history KEY".into());
}
let key = args.join(" ");
// Replay the node log, collecting all versions of this key
let path = store::nodes_path();
if !path.exists() {
return Err("No node log found".into());
}
use std::io::BufReader;
let file = std::fs::File::open(&path)
.map_err(|e| format!("open {}: {}", path.display(), e))?;
let mut reader = BufReader::new(file);
let mut versions: Vec<store::Node> = Vec::new();
while let Ok(msg) = capnp::serialize::read_message(&mut reader, capnp::message::ReaderOptions::new()) {
let log = msg.get_root::<poc_memory::memory_capnp::node_log::Reader>()
.map_err(|e| format!("read log: {}", e))?;
for node_reader in log.get_nodes()
.map_err(|e| format!("get nodes: {}", e))? {
let node = store::Node::from_capnp(node_reader)?;
if node.key == key {
versions.push(node);
}
}
}
if versions.is_empty() {
return Err(format!("No history found for '{}'", key));
}
eprintln!("{} versions of '{}':\n", versions.len(), key);
for (i, node) in versions.iter().enumerate() {
let preview: String = node.content.chars().take(200).collect();
let preview = preview.replace('\n', "\\n");
eprintln!(" v{} (w={:.3}, {}): {}",
node.version, node.weight, node.timestamp, preview);
}
// Show latest full content
if let Some(latest) = versions.last() {
eprintln!("\n--- Latest content (v{}) ---", latest.version);
print!("{}", latest.content);
}
Ok(())
}
fn cmd_write(args: &[String]) -> Result<(), String> {
if args.is_empty() {
return Err("Usage: poc-memory write KEY < content\n\