sqlite-graphrag 1.2.8

Persistent GraphRAG memory for Claude Code, Codex, Cursor, and 27 AI agents — one self-contained ~19 MiB Rust binary, zero daemon. Never re-explain your codebase again. Hybrid retrieval (FTS5 BM25 + cosine similarity + multi-hop graph traversal) surfaces the right memory in milliseconds. Embedding and entity enrichment run as parallel REST calls against your cloud LLM — no fragile headless subprocesses, no ONNX runtime, no model downloads. Soft-delete with full version history, transactional atomic writes, BLAKE3-tracked mutations. OAuth-only: raw API keys ABORT the spawn.
Documentation
#![cfg(feature = "slow-tests")]

//! Suite 10 — smoke tests against the INSTALLED binary: search and database maintenance (#13–#19)
//!
//! Part of the smoke suite split by GAP-SG-210: the single file held 981 lines
//! and 26 tests, past the 800-line ceiling this project sets for itself. The
//! shared harness lives in `tests/smoke_support/`, which also documents why
//! this suite targets `~/.cargo/bin/sqlite-graphrag` instead of the build
//! output, and how it skips when nothing is installed.

#[path = "smoke_support/mod.rs"]
mod support;

use support::{assert_json_or_not_found, assert_json_stdout, Env};

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #13: hybrid-search
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_13_hybrid_search() {
    let env = Env::new();
    env.init();
    env.remember(
        "smoke-hybrid-01",
        "conteúdo para busca híbrida com FTS e vetorial",
    );
    let out = env
        .cmd()
        .args(["hybrid-search", "busca híbrida", "-k", "5"])
        .output()
        .expect("hybrid-search failed");
    assert_json_or_not_found(&out);
}

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #14: stats
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_14_stats() {
    let env = Env::new();
    env.init();
    let out = env.cmd().arg("stats").output().expect("stats failed");
    assert_json_stdout(&out);
    let json: serde_json::Value = serde_json::from_slice(&out.stdout).unwrap();
    assert!(
        json["memories"].as_i64().is_some(),
        "stats deve ter campo memories como inteiro: {json}"
    );
}

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #15: migrate
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_15_migrate() {
    let env = Env::new();
    env.init();
    let out = env.cmd().arg("migrate").output().expect("migrate failed");
    assert_json_stdout(&out);
    let json: serde_json::Value = serde_json::from_slice(&out.stdout).unwrap();
    assert_eq!(
        json["status"], "ok",
        "migrate deve retornar status=ok: {json}"
    );
}

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #16: namespace-detect
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_16_namespace_detect() {
    let env = Env::new();
    env.init();
    let out = env
        .cmd()
        .arg("namespace-detect")
        .output()
        .expect("namespace-detect failed");
    assert_json_stdout(&out);
    let json: serde_json::Value = serde_json::from_slice(&out.stdout).unwrap();
    assert!(
        json["namespace"].is_string(),
        "namespace-detect deve retornar campo namespace: {json}"
    );
}

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #17: optimize
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_17_optimize() {
    let env = Env::new();
    env.init();
    let out = env.cmd().arg("optimize").output().expect("optimize failed");
    assert_json_stdout(&out);
}

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #18: sync-safe-copy
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_18_sync_safe_copy() {
    let env = Env::new();
    env.init();
    let dest = env.tmp.path().join("snapshot.sqlite");
    let out = env
        .cmd()
        .args(["sync-safe-copy", "--dest", dest.to_str().unwrap()])
        .output()
        .expect("sync-safe-copy failed");
    assert_json_stdout(&out);
    assert!(dest.exists(), "snapshot deve ter sido criado em {dest:?}");
}

// ---------------------------------------------------------------------------
// Suite 10 — Smoke #19: vacuum
// ---------------------------------------------------------------------------

#[test]
#[ignore = "needs `cargo install --path .` first: validates the INSTALLED binary, not this build"]
fn smoke_19_vacuum() {
    let env = Env::new();
    env.init();
    let out = env.cmd().arg("vacuum").output().expect("vacuum failed");
    assert_json_stdout(&out);
}