scryer-engine 0.3.0

Tree-sitter AST indexing and reference resolution engine for Scryer code intelligence
use std::fs;
use std::path::Path;

use scryer_db::{Project, ScryerDb};
use scryer_engine::{EngineService, IndexOptions, IndexReport};
use tempfile::tempdir;

/// Register `root` as a project in `db` and index it with `options`.
pub async fn index_dir(
    db: &ScryerDb,
    root: &Path,
    options: IndexOptions,
) -> anyhow::Result<(u64, IndexReport)> {
    let (project, _, report) = index_dir_keeping_service(db, root, options).await?;
    Ok((project, report))
}

/// Like [`index_dir`], and hands back the service, so a later `index_file` or
/// `index_project` of the same project runs on the same instance.
pub async fn index_dir_keeping_service(
    db: &ScryerDb,
    root: &Path,
    options: IndexOptions,
) -> anyhow::Result<(u64, EngineService, IndexReport)> {
    let project = {
        let mut conn = db.lock().await;
        Project::create()
            .slug("fixture".to_string())
            .root_path(root.to_string_lossy().to_string())
            .default_branch("main".to_string())
            .is_active(true)
            .created_at("2026-10-08T00:00:00Z".to_string())
            .updated_at("2026-10-08T00:00:00Z".to_string())
            .exec(&mut *conn)
            .await?
    };
    let service = EngineService::new(db.clone()).with_index_options(options);
    let report = service.index_project(project.id, root).await?;
    Ok((project.id, service, report))
}

/// Write `files` (relative path, content) into a temp directory and index them into a fresh
/// in-memory database.
pub async fn index_files(
    files: &[(&str, &str)],
    options: IndexOptions,
) -> anyhow::Result<(ScryerDb, u64)> {
    let temp = tempdir()?;
    for (path, content) in files {
        let full = temp.path().join(path);
        if let Some(parent) = full.parent() {
            fs::create_dir_all(parent)?;
        }
        fs::write(full, content)?;
    }
    let db = ScryerDb::new_in_memory().await?;
    let (project, _) = index_dir(&db, temp.path(), options).await?;
    Ok((db, project))
}