mod cli;
mod commands;
mod config;
use anyhow::Result;
use cartog_mcp as mcp;
use clap::Parser;
use cli::{Cli, Command, RagCommand};
fn main() -> Result<()> {
let cli = Cli::parse();
let cartog_config = config::load_config();
let db_path = config::resolve_db_path(cli.db.clone(), &cartog_config);
let is_serve = matches!(cli.command, Command::Serve { .. });
let is_watch = matches!(cli.command, Command::Watch { .. });
let is_rag = matches!(
cli.command,
Command::Rag(RagCommand::Index { .. }) | Command::Rag(RagCommand::Setup)
);
let default_level = if is_serve || is_rag || is_watch {
"info"
} else {
"warn"
};
tracing_subscriber::fmt()
.with_writer(std::io::stderr)
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new(default_level)),
)
.init();
let token_budget = if cli.json { None } else { cli.tokens };
match cli.command {
Command::Index {
path,
force,
no_lsp,
} => commands::cmd_index(&db_path, &path, force, !no_lsp, cli.json),
Command::Outline { file } => commands::cmd_outline(&db_path, &file, cli.json, token_budget),
Command::Callees { name } => commands::cmd_callees(&db_path, &name, cli.json, token_budget),
Command::Impact { name, depth } => {
commands::cmd_impact(&db_path, &name, depth, cli.json, token_budget)
}
Command::Refs { name, kind } => {
commands::cmd_refs(&db_path, &name, kind, cli.json, token_budget)
}
Command::Hierarchy { name } => {
commands::cmd_hierarchy(&db_path, &name, cli.json, token_budget)
}
Command::Deps { file } => commands::cmd_deps(&db_path, &file, cli.json, token_budget),
Command::Stats => commands::cmd_stats(&db_path, cli.json),
Command::Search {
query,
kind,
file,
limit,
} => commands::cmd_search(
&db_path,
&query,
kind,
file.as_deref(),
limit,
cli.json,
token_budget,
),
Command::Map { tokens } => commands::cmd_map(&db_path, tokens, cli.json),
Command::Changes { commits, kind } => {
commands::cmd_changes(&db_path, commits, kind, cli.json, token_budget)
}
Command::Watch {
path,
debounce,
rag,
rag_delay,
} => commands::cmd_watch(&db_path, &path, debounce, rag, rag_delay),
Command::Serve { watch, rag } => {
let runtime = tokio::runtime::Runtime::new()?;
runtime.block_on(mcp::run_server(&db_path, watch, rag))
}
Command::Rag(rag_cmd) => match rag_cmd {
RagCommand::Setup => commands::cmd_rag_setup(cli.json),
RagCommand::Index { path, force } => {
commands::cmd_rag_index(&db_path, &path, force, cli.json)
}
RagCommand::Search { query, kind, limit } => {
commands::cmd_rag_search(&db_path, &query, kind, limit, cli.json, token_budget)
}
},
}
}