use chrono::Utc;
use serde::Serialize;
use std::path::PathBuf;
use tracing::debug;
fn state_dir() -> PathBuf {
if let Ok(dir) = std::env::var("NEXUS_STATE_DIR") {
PathBuf::from(dir)
} else if let Some(dir) = dirs::state_dir() {
dir.join("nexus-memory-system")
} else {
std::env::var("HOME")
.map(|h| PathBuf::from(h).join(".local/state/nexus-memory-system"))
.unwrap_or_else(|_| std::env::temp_dir().join("nexus-memory-system"))
}
}
fn pulse_path() -> PathBuf {
state_dir().join("agent-pulse.json")
}
#[derive(Debug, Serialize)]
struct AgentPulse {
last_activity: String,
last_action: String,
memories_consolidated: u64,
files_processed: u64,
}
pub fn write_pulse(action: &str, memories_consolidated: u64, files_processed: u64) {
let path = pulse_path();
if let Some(parent) = path.parent() {
if let Err(e) = std::fs::create_dir_all(parent) {
debug!(error = %e, path = %parent.display(), "Failed to create state directory for pulse file");
return;
}
}
let pulse = AgentPulse {
last_activity: Utc::now().to_rfc3339(),
last_action: action.to_string(),
memories_consolidated,
files_processed,
};
match serde_json::to_string_pretty(&pulse) {
Ok(json) => {
if let Err(e) = std::fs::write(&path, json) {
debug!(error = %e, path = %path.display(), "Failed to write pulse file");
}
}
Err(e) => {
debug!(error = %e, "Failed to serialize pulse data");
}
}
}