kodegraf-cli 0.1.0

Structural code intelligence for AI coding assistants — CLI
use anyhow::Result;
use kodegraf_core::build;
use kodegraf_core::config::Config;
use kodegraf_core::graph::GraphStore;

pub fn run() -> Result<()> {
    let repo_root = kodegraf_core::config::find_repo_root()?;
    let config_path = Config::config_path(&repo_root);
    let db_path = Config::graph_db_path(&repo_root);

    if !config_path.exists() {
        anyhow::bail!(
            "Kodegraf is not initialized in this project.\n\
             Run `kodegraf init` first."
        );
    }

    let config = Config::load(&config_path)?;
    let store = GraphStore::open(&db_path)?;

    println!("Building knowledge graph...");
    let result = build::full_build(&repo_root, &config, &store)?;

    let stats = store.get_stats()?;

    println!();
    println!("Build complete.");
    println!("  Files parsed:  {}", result.files_parsed);
    println!("  Files skipped: {}", result.files_skipped);
    println!("  Nodes: {}", stats.total_nodes);
    println!("  Edges: {}", stats.total_edges);
    println!(
        "  Languages: {}",
        if stats.languages.is_empty() {
            "(none)".to_string()
        } else {
            stats.languages.join(", ")
        }
    );

    Ok(())
}

pub fn run_update() -> Result<()> {
    let repo_root = kodegraf_core::config::find_repo_root()?;
    let config_path = Config::config_path(&repo_root);
    let db_path = Config::graph_db_path(&repo_root);

    if !config_path.exists() {
        anyhow::bail!(
            "Kodegraf is not initialized in this project.\n\
             Run `kodegraf init` first."
        );
    }

    let config = Config::load(&config_path)?;
    let store = GraphStore::open(&db_path)?;

    println!("Updating knowledge graph (incremental)...");
    let result = build::incremental_update(&repo_root, &config, &store, "HEAD~1")?;

    println!();
    println!("Update complete.");
    println!("  Files parsed:  {}", result.files_parsed);
    println!("  Files skipped: {}", result.files_skipped);
    println!("  Nodes created: {}", result.nodes_created);
    println!("  Edges created: {}", result.edges_created);

    Ok(())
}

/// Fast update for PostToolUse hooks — silent, skips edge resolution.
pub fn run_fast_update() -> Result<()> {
    let repo_root = kodegraf_core::config::find_repo_root()?;
    let config_path = Config::config_path(&repo_root);
    let db_path = Config::graph_db_path(&repo_root);

    // Silently exit if not initialized — hooks shouldn't crash
    if !config_path.exists() || !db_path.exists() {
        return Ok(());
    }

    let config = Config::load(&config_path)?;
    let store = GraphStore::open(&db_path)?;

    // Silent — no stdout output so we don't pollute the AI conversation
    build::fast_update(&repo_root, &config, &store)?;

    Ok(())
}