lean-ctx 3.1.3

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
pub fn compress(output: &str) -> Option<String> {
    if let Some(r) = try_pytest(output) {
        return Some(r);
    }
    if let Some(r) = try_vitest(output) {
        return Some(r);
    }
    if let Some(r) = try_jest(output) {
        return Some(r);
    }
    if let Some(r) = try_go_test(output) {
        return Some(r);
    }
    if let Some(r) = try_rspec(output) {
        return Some(r);
    }
    None
}

fn try_pytest(output: &str) -> Option<String> {
    if !output.contains("test session starts") && !output.contains("pytest") {
        return None;
    }

    let mut passed = 0u32;
    let mut failed = 0u32;
    let mut skipped = 0u32;
    let mut time = String::new();
    let mut failures = Vec::new();

    for line in output.lines() {
        let trimmed = line.trim();
        if (trimmed.contains("passed") || trimmed.contains("failed") || trimmed.contains("error"))
            && (trimmed.starts_with('=') || trimmed.starts_with('-'))
        {
            for word in trimmed.split_whitespace() {
                if let Some(n) = word.strip_suffix("passed").or_else(|| {
                    if trimmed.contains(" passed") {
                        word.parse::<u32>().ok().map(|_| word)
                    } else {
                        None
                    }
                }) {
                    if let Ok(v) = n.trim().parse::<u32>() {
                        passed = v;
                    }
                }
            }
            if let Some(pos) = trimmed.find(" passed") {
                let before = &trimmed[..pos];
                if let Some(num_str) = before.split_whitespace().last() {
                    if let Ok(v) = num_str.parse::<u32>() {
                        passed = v;
                    }
                }
            }
            if let Some(pos) = trimmed.find(" failed") {
                let before = &trimmed[..pos];
                if let Some(num_str) = before.split_whitespace().last() {
                    if let Ok(v) = num_str.parse::<u32>() {
                        failed = v;
                    }
                }
            }
            if let Some(pos) = trimmed.find(" skipped") {
                let before = &trimmed[..pos];
                if let Some(num_str) = before.split_whitespace().last() {
                    if let Ok(v) = num_str.parse::<u32>() {
                        skipped = v;
                    }
                }
            }
            if let Some(pos) = trimmed.find(" in ") {
                time = trimmed[pos + 4..].trim_end_matches('=').trim().to_string();
            }
        }
        if trimmed.starts_with("FAILED ") {
            failures.push(
                trimmed
                    .strip_prefix("FAILED ")
                    .unwrap_or(trimmed)
                    .to_string(),
            );
        }
    }

    if passed == 0 && failed == 0 {
        return None;
    }

    let mut result = format!("pytest: {passed} passed");
    if failed > 0 {
        result.push_str(&format!(", {failed} failed"));
    }
    if skipped > 0 {
        result.push_str(&format!(", {skipped} skipped"));
    }
    if !time.is_empty() {
        result.push_str(&format!(" ({time})"));
    }

    for f in failures.iter().take(5) {
        result.push_str(&format!("\n  FAIL: {f}"));
    }

    Some(result)
}

fn try_jest(output: &str) -> Option<String> {
    if !output.contains("Tests:") && !output.contains("Test Suites:") {
        return None;
    }

    let mut suites_line = String::new();
    let mut tests_line = String::new();
    let mut time_line = String::new();

    for line in output.lines() {
        let trimmed = line.trim();
        if trimmed.starts_with("Test Suites:") {
            suites_line = trimmed.to_string();
        } else if trimmed.starts_with("Tests:") {
            tests_line = trimmed.to_string();
        } else if trimmed.starts_with("Time:") {
            time_line = trimmed.to_string();
        }
    }

    if tests_line.is_empty() {
        return None;
    }

    let mut result = String::new();
    if !suites_line.is_empty() {
        result.push_str(&suites_line);
        result.push('\n');
    }
    result.push_str(&tests_line);
    if !time_line.is_empty() {
        result.push('\n');
        result.push_str(&time_line);
    }

    Some(result)
}

fn try_go_test(output: &str) -> Option<String> {
    if !output.contains("--- PASS") && !output.contains("--- FAIL") && !output.contains("PASS\n") {
        return None;
    }

    let mut passed = 0u32;
    let mut failed = 0u32;
    let mut failures = Vec::new();
    let mut packages = Vec::new();

    for line in output.lines() {
        let trimmed = line.trim();
        if trimmed.starts_with("--- PASS:") {
            passed += 1;
        } else if trimmed.starts_with("--- FAIL:") {
            failed += 1;
            failures.push(
                trimmed
                    .strip_prefix("--- FAIL: ")
                    .unwrap_or(trimmed)
                    .to_string(),
            );
        } else if trimmed.starts_with("ok ") || trimmed.starts_with("FAIL\t") {
            packages.push(trimmed.to_string());
        }
    }

    if passed == 0 && failed == 0 {
        return None;
    }

    let mut result = format!("go test: {passed} passed");
    if failed > 0 {
        result.push_str(&format!(", {failed} failed"));
    }

    for pkg in &packages {
        result.push_str(&format!("\n  {pkg}"));
    }

    for f in failures.iter().take(5) {
        result.push_str(&format!("\n  FAIL: {f}"));
    }

    Some(result)
}

fn try_vitest(output: &str) -> Option<String> {
    if !output.contains("PASS") && !output.contains("FAIL") {
        return None;
    }
    if !output.contains(" Tests ") && !output.contains("Test Files") {
        return None;
    }

    let mut test_files_line = String::new();
    let mut tests_line = String::new();
    let mut duration_line = String::new();
    let mut failures = Vec::new();

    for line in output.lines() {
        let trimmed = line.trim();
        let plain = strip_ansi(trimmed);
        if plain.contains("Test Files") {
            test_files_line = plain.clone();
        } else if plain.starts_with("Tests") && plain.contains("passed") {
            tests_line = plain.clone();
        } else if plain.contains("Duration") || plain.contains("Time") {
            if plain.contains("ms") || plain.contains("s") {
                duration_line = plain.clone();
            }
        } else if plain.contains("FAIL")
            && (plain.contains(".test.") || plain.contains(".spec.") || plain.contains("_test."))
        {
            failures.push(plain.clone());
        }
    }

    if tests_line.is_empty() && test_files_line.is_empty() {
        return None;
    }

    let mut result = String::new();
    if !test_files_line.is_empty() {
        result.push_str(&test_files_line);
    }
    if !tests_line.is_empty() {
        if !result.is_empty() {
            result.push('\n');
        }
        result.push_str(&tests_line);
    }
    if !duration_line.is_empty() {
        result.push('\n');
        result.push_str(&duration_line);
    }

    for f in failures.iter().take(10) {
        result.push_str(&format!("\n  FAIL: {f}"));
    }

    Some(result)
}

fn strip_ansi(s: &str) -> String {
    crate::core::compressor::strip_ansi(s)
}

fn try_rspec(output: &str) -> Option<String> {
    if !output.contains("examples") || !output.contains("failures") {
        return None;
    }

    for line in output.lines().rev() {
        let trimmed = line.trim();
        if trimmed.contains("example") && trimmed.contains("failure") {
            return Some(format!("rspec: {trimmed}"));
        }
    }

    None
}