Skip to main content
Glama
by 8b-is
mod.rs2.37 kB
//! File History Tracking Module - The Ultimate Context-Driven System! //! //! Tracks all AI file manipulations in ~/.mem8/.filehistory/ //! with hash-based change detection and append-first operations. //! //! 🎸 The Cheet says: "Every file tells a story, let's remember them all!" use anyhow::Result; use chrono::{DateTime, Datelike, Timelike, Utc}; use serde::{Deserialize, Serialize}; use sha2::{Digest, Sha256}; use std::fs::{self, OpenOptions}; use std::io::Write; use std::path::{Path, PathBuf}; use std::time::{SystemTime, UNIX_EPOCH}; pub mod operations; pub mod tracker; pub use operations::*; pub use tracker::*; /// File history configuration pub struct FileHistoryConfig { /// Base directory for file history (default: ~/.mem8/.filehistory/) pub base_dir: PathBuf, /// Whether to auto-create directories pub auto_create: bool, /// Prefer append operations when possible pub prefer_append: bool, } impl Default for FileHistoryConfig { fn default() -> Self { let home = dirs::home_dir().unwrap_or_else(|| PathBuf::from(".")); Self { base_dir: home.join(".mem8").join(".filehistory"), auto_create: true, prefer_append: true, } } } /// Get timestamp at 10-minute resolution pub fn get_time_bucket() -> (String, u64) { let now = SystemTime::now() .duration_since(UNIX_EPOCH) .unwrap() .as_secs(); let datetime = DateTime::<Utc>::from(UNIX_EPOCH + std::time::Duration::from_secs(now)); let minute = datetime.minute() / 10 * 10; // Round down to 10-minute bucket let filename = format!( "{:04}{:02}{:02}_{:02}{:02}", datetime.year(), datetime.month(), datetime.day(), datetime.hour(), minute ); (filename, now) } /// Calculate SHA256 hash of file contents pub fn hash_file(path: &Path) -> Result<String> { let contents = fs::read(path)?; let mut hasher = Sha256::new(); hasher.update(&contents); Ok(format!("{:x}", hasher.finalize())) } /// Get project ID from path (uses canonical path as ID) pub fn get_project_id(path: &Path) -> Result<String> { let canonical = path.canonicalize()?; let mut hasher = Sha256::new(); hasher.update(canonical.to_string_lossy().as_bytes()); Ok(format!("{:x}", hasher.finalize())[..16].to_string()) }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/8b-is/smart-tree'

If you have feedback or need assistance with the MCP directory API, please join our Discord server