scryer-mcp 0.3.0

Model Context Protocol (MCP) server for Scryer code intelligence
//! Register a session's working directory as a project and index it in the background.

use std::path::{Path, PathBuf};

use scryer_db::{Project, ProjectRegistry, is_registrable_root};
use scryer_engine::EngineService;

/// Register `cwd` as a project and start indexing it in the background, unless a registered
/// project already contains it.
///
/// Returns the new project, or `None` when nothing was registered: `cwd` is already inside a
/// project, or does not look like a project root (see [`is_registrable_root`]), e.g. an editor
/// launched from the home directory.
///
/// The project is marked as building before this returns, so a query that arrives before the
/// background index starts waits for it instead of answering from an empty index.
pub async fn ensure_cwd_registered(
    registry: &ProjectRegistry,
    engine: &EngineService,
    cwd: &Path,
) -> anyhow::Result<Option<Project>> {
    if registry.resolve_path(cwd).await.is_some() {
        return Ok(None);
    }
    if !is_registrable_root(cwd) {
        tracing::info!(
            "Not registering {}: not inside a registered project and not a project root",
            cwd.display()
        );
        return Ok(None);
    }
    let project = registry.register_or_update(cwd, None).await?;
    engine.mark_building(project.id);
    let engine = engine.clone();
    let indexed = project.clone();
    tokio::spawn(async move {
        let root = PathBuf::from(&indexed.root_path);
        if let Err(e) = engine.index_project(indexed.id, &root).await {
            tracing::warn!("Initial index of {} failed: {e}", root.display());
        }
    });
    Ok(Some(project))
}