pub mod admin;
pub mod codemap;
pub mod context;
pub mod git;
pub mod memory;
pub mod render;
pub mod web;
use std::io::Write;
use std::path::Path;
use anyhow::{Context, Result};
use clap::Subcommand;
use rmcp::ErrorData as McpError;
use rmcp::model::CallToolResult;
use crate::config::DocumentsCliOverrides;
#[derive(Subcommand, Debug)]
pub enum ToolCmd {
#[command(subcommand)]
Query(codemap::QueryCmd),
#[command(subcommand)]
Git(git::GitCmd),
#[command(subcommand)]
Memory(memory::MemoryCmd),
#[command(subcommand)]
Web(web::WebCmd),
Telemetry {
#[arg(long)]
window: Option<String>,
#[arg(long)]
tool: Option<String>,
},
}
pub fn run_tool(tool: &str, result: Result<CallToolResult, McpError>) -> Result<CallToolResult> {
result.map_err(|e| anyhow::anyhow!("{tool}: {e}"))
}
pub fn run(
root: &Path,
view: &str,
documents: DocumentsCliOverrides,
json: bool,
cmd: ToolCmd,
) -> Result<()> {
let runtime = tokio::runtime::Builder::new_multi_thread()
.enable_all()
.build()
.context("build tokio runtime")?;
runtime.block_on(async move {
let server = context::build_server(root, view, documents)?;
let stdout = std::io::stdout();
let mut out = stdout.lock();
match cmd {
ToolCmd::Query(q) => codemap::run(&server, q, json, &mut out).await?,
ToolCmd::Git(g) => git::run(&server, g, json, &mut out).await?,
ToolCmd::Memory(m) => memory::run(&server, m, json, &mut out).await?,
ToolCmd::Web(w) => web::run(&server, w, json, &mut out).await?,
ToolCmd::Telemetry { window, tool } => {
admin::run_telemetry(&server, window, tool, json, &mut out).await?
}
}
out.flush().context("flush stdout")?;
Ok(())
})
}
pub fn run_cache(root: &Path, cmd: admin::CacheCmd, json: bool) -> Result<()> {
let stdout = std::io::stdout();
let mut out = stdout.lock();
admin::run_cache(root, cmd, json, &mut out)?;
out.flush().context("flush stdout")?;
Ok(())
}