lean-ctx 3.1.5

Context Runtime for AI Agents with CCP. 42 MCP tools, 10 read modes, 90+ compression patterns, cross-session memory (CCP), persistent AI knowledge with temporal facts + contradiction detection, multi-agent context sharing + diaries, LITM-aware positioning, AAAK compact format, adaptive compression with Thompson Sampling bandits. Supports 24 AI tools. Reduces LLM token consumption by up to 99%.
Documentation
use crate::core::events::LeanCtxEvent;
use std::io::{BufRead, BufReader, Seek, SeekFrom};
use std::path::PathBuf;

pub struct EventTail {
    path: PathBuf,
    offset: u64,
}

impl EventTail {
    pub fn new() -> Self {
        let path = dirs::home_dir()
            .unwrap_or_default()
            .join(".lean-ctx")
            .join("events.jsonl");
        let offset = std::fs::metadata(&path).map(|m| m.len()).unwrap_or(0);
        Self { path, offset }
    }

    pub fn poll(&mut self) -> Vec<LeanCtxEvent> {
        let Ok(mut file) = std::fs::File::open(&self.path) else {
            return Vec::new();
        };
        let meta_len = file.metadata().map(|m| m.len()).unwrap_or(0);
        if meta_len < self.offset {
            self.offset = 0;
        }
        if meta_len == self.offset {
            return Vec::new();
        }

        let _ = file.seek(SeekFrom::Start(self.offset));
        let reader = BufReader::new(&file);
        let mut events = Vec::new();

        for line in reader.lines() {
            let Ok(line) = line else { break };
            if line.trim().is_empty() {
                continue;
            }
            if let Ok(event) = serde_json::from_str::<LeanCtxEvent>(&line) {
                events.push(event);
            }
        }

        self.offset = meta_len;
        events
    }
}