use crate::config::{db_path, find_vyctor_root, load_config};
use crate::daemon::is_daemon_running;
use crate::storage::Storage;
use anyhow::Result;
use colored::Colorize;
pub async fn run() -> Result<()> {
let root = find_vyctor_root()?;
let config = load_config()?;
println!("{}", "Vyctor Status".bold());
println!();
println!("{}", "Location:".bold());
println!(" Root: {}", root.display());
println!(" Config: {}", root.join("vyctor.config.toml").display());
println!();
println!("{}", "Configuration:".bold());
println!(
" 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!(
" Chunk overlap: {} chars",
config.indexing.chunk_overlap.to_string().cyan()
);
println!();
let db_file = db_path()?;
if db_file.exists() {
match Storage::open_readonly(&db_file, config.embedding.dimensions) {
Ok(storage) => {
match storage.get_stats() {
Ok(stats) => {
println!("{}", "Index Statistics:".bold());
println!(" Files indexed: {}", stats.file_count.to_string().green());
println!(" Total chunks: {}", stats.chunk_count.to_string().cyan());
println!(
" Content size: {}",
format_bytes(stats.total_content_size).cyan()
);
if let Some(last) = stats.last_indexed {
println!(" Last indexed: {}", last.dimmed());
}
if let Ok(metadata) = std::fs::metadata(&db_file) {
println!(
" Database size: {}",
format_bytes(metadata.len() as usize).cyan()
);
}
}
Err(e) => {
println!("{} Could not read index stats: {}", "!".yellow(), e);
}
}
}
Err(_e) => {
if let Some(pid) = is_daemon_running(&root) {
println!("{}", "Index Statistics:".bold());
println!(
" {} Database locked by watcher daemon (PID {})",
"!".yellow(),
pid
);
println!(" Stop daemon to view detailed stats: vyctor watch --stop");
} else {
println!("{} Could not open database", "!".yellow());
println!(" The VSS extension may not be installed.");
}
}
}
} else {
println!("{}", "Index:".bold());
println!(
" {} No index found. Run 'vyctor sync' to create one.",
"!".yellow()
);
}
println!();
println!("{}", "File Patterns:".bold());
println!(" Include:");
for pattern in config.indexing.include.iter().take(5) {
println!(" • {}", pattern);
}
if config.indexing.include.len() > 5 {
println!(" ... and {} more", config.indexing.include.len() - 5);
}
println!(" Exclude:");
for pattern in config.indexing.exclude.iter().take(5) {
println!(" • {}", pattern);
}
if config.indexing.exclude.len() > 5 {
println!(" ... and {} more", config.indexing.exclude.len() - 5);
}
Ok(())
}
fn format_bytes(bytes: usize) -> String {
const KB: usize = 1024;
const MB: usize = KB * 1024;
const GB: usize = MB * 1024;
if bytes >= GB {
format!("{:.2} GB", bytes as f64 / GB as f64)
} else if bytes >= MB {
format!("{:.2} MB", bytes as f64 / MB as f64)
} else if bytes >= KB {
format!("{:.2} KB", bytes as f64 / KB as f64)
} else {
format!("{} bytes", bytes)
}
}