lean-ctx 3.9.14

Context Runtime for AI Agents with CCP. 71 MCP tools, 10 read modes, 95+ compression patterns, cross-session memory (CCP), persistent AI knowledge with temporal facts + contradiction detection, multi-agent context sharing, 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
//! SQLite-backed file-path flyweights for the PropertyGraph.

use rusqlite::{Connection, OptionalExtension, params};

/// Compact graph-local handle for one canonical path in the `paths` table.
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
pub(crate) struct FileId(i64);

impl FileId {
    pub(crate) fn raw(self) -> i64 {
        self.0
    }
}

/// Resolve or create the stable ID for `path` within this graph database.
pub(crate) fn intern(conn: &Connection, path: &str) -> anyhow::Result<FileId> {
    conn.execute(
        "INSERT INTO paths (path) VALUES (?1) ON CONFLICT(path) DO NOTHING",
        params![path],
    )?;
    let id = conn.query_row(
        "SELECT id FROM paths WHERE path = ?1",
        params![path],
        |row| row.get(0),
    )?;
    Ok(FileId(id))
}
#[cfg_attr(not(test), allow(dead_code))] // round-trip tested
pub(crate) fn get(conn: &Connection, path: &str) -> anyhow::Result<Option<FileId>> {
    Ok(conn
        .query_row(
            "SELECT id FROM paths WHERE path = ?1",
            params![path],
            |row| row.get(0).map(FileId),
        )
        .optional()?)
}
#[cfg_attr(not(test), allow(dead_code))] // round-trip tested
pub(crate) fn resolve(conn: &Connection, id: FileId) -> anyhow::Result<Option<String>> {
    Ok(conn
        .query_row(
            "SELECT path FROM paths WHERE id = ?1",
            params![id.raw()],
            |row| row.get(0),
        )
        .optional()?)
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::core::property_graph::CodeGraph;

    #[test]
    fn intern_deduplicates_and_round_trips() {
        let graph = CodeGraph::open_in_memory().unwrap();
        let first = intern(graph.connection(), "src/lib.rs").unwrap();
        let second = intern(graph.connection(), "src/lib.rs").unwrap();
        assert_eq!(first, second);
        assert_eq!(get(graph.connection(), "src/lib.rs").unwrap(), Some(first));
        assert_eq!(
            resolve(graph.connection(), first).unwrap().as_deref(),
            Some("src/lib.rs")
        );
    }
}