vyctor 0.1.0

A fast CLI tool for semantic file search using vector embeddings
Documentation
//! Implementation of the `vyctor init` command

use crate::cli::ensure_daemon_running;
use crate::config::init_vyctor_dir;
use crate::indexer::Indexer;
use anyhow::Result;
use colored::Colorize;
use std::env;

/// Run the init command
pub async fn run(force: bool) -> Result<()> {
    let cwd = env::current_dir()?;

    println!("{} Initializing vyctor in {}", "".cyan(), cwd.display());

    // Initialize the .vyctor directory
    let config = init_vyctor_dir(&cwd, force)?;

    println!("{} Created vyctor.config.toml", "".green());

    // Show configuration summary
    println!();
    println!("{}", "Configuration:".bold());
    println!(
        "  Embedding provider: {}",
        format!("{:?}", config.embedding.provider).cyan()
    );
    println!("  Model: {}", config.embedding.get_model().cyan());
    println!(
        "  Dimensions: {}",
        config.embedding.dimensions.to_string().cyan()
    );
    println!(
        "  Chunk size: {} chars",
        config.indexing.chunk_size.to_string().cyan()
    );
    println!(
        "  Include patterns: {}",
        config.indexing.include.len().to_string().cyan()
    );
    println!(
        "  Exclude patterns: {}",
        config.indexing.exclude.len().to_string().cyan()
    );

    // Show reranker configuration
    if config.reranker.is_active() {
        println!(
            "  Reranker: {} ({})",
            format!("{:?}", config.reranker.provider).cyan(),
            config.reranker.get_model().cyan()
        );
        println!(
            "  Rerank top_k: {}",
            config.reranker.top_k.to_string().cyan()
        );
    } else {
        println!("  Reranker: {}", "disabled".dimmed());
    }

    // Check if API key is available
    match config.embedding.get_api_key() {
        Ok(_) => {
            println!();
            println!("{} Starting initial indexing...", "".cyan());

            // Create indexer and run initial indexing
            match Indexer::new(&cwd, &config) {
                Ok(indexer) => {
                    let result = indexer.index_all(false).await?;

                    println!();
                    println!("{}", "Indexing complete:".bold());
                    println!(
                        "  Files indexed: {}",
                        result.files_indexed.to_string().green()
                    );
                    println!(
                        "  Files skipped: {}",
                        result.files_skipped.to_string().yellow()
                    );
                    println!(
                        "  Chunks created: {}",
                        result.chunks_created.to_string().cyan()
                    );
                }
                Err(e) => {
                    println!("{} Could not initialize storage: {}", "!".yellow(), e);
                    println!("  You may need to install the DuckDB VSS extension.");
                    println!("  Run 'vyctor sync' to retry indexing after fixing the issue.");
                }
            }
        }
        Err(e) => {
            println!();
            println!(
                "{} {}",
                "!".yellow(),
                "API key not found. Skipping initial indexing.".yellow()
            );
            println!("  {}", e);
            println!();
            println!("  Set the environment variable and run 'vyctor sync' to index files.");
        }
    }

    println!();
    println!("{} Vyctor initialized successfully!", "".green().bold());

    // Auto-start daemon if configured
    ensure_daemon_running(&cwd, &config)?;

    println!();
    println!("Next steps:");
    println!("  • Edit vyctor.config.toml to customize indexing");
    println!("  • Run 'vyctor lookup \"your query\"' to search");
    if config.watch.auto_start {
        println!("  • Run 'vyctor watch --status' to check watcher status");
    } else {
        println!("  • Run 'vyctor watch --daemon' to auto-sync on file changes");
    }

    Ok(())
}