use std::io::Write;
use anyhow::Result;
use clap::Subcommand;
use super::render::Emit;
use crate::mcp::BasemindServer;
#[derive(Subcommand, Debug)]
pub enum WebCmd {
Scrape {
url: String,
#[arg(long)]
no_index: bool,
#[arg(long)]
scope: Option<String>,
},
Crawl {
url: String,
#[arg(long)]
max_pages: Option<u32>,
#[arg(long)]
max_depth: Option<u32>,
#[arg(long)]
scope: Option<String>,
},
Map {
url: String,
#[arg(long)]
limit: Option<u32>,
},
}
#[cfg(feature = "crawl")]
pub async fn run(server: &BasemindServer, cmd: WebCmd, opts: &Emit, out: &mut impl Write) -> Result<()> {
use crate::mcp::params::*;
use super::render::emit;
use super::run_tool;
fn parse_url(s: &str) -> Result<crate::url::Url> {
s.parse::<crate::url::Url>()
.map_err(|e| anyhow::anyhow!("invalid url {s:?}: {e}"))
}
fn params(mode: WebMode, url: crate::url::Url) -> WebParams {
WebParams {
mode,
url,
index: None,
scope: None,
max_pages: None,
max_depth: None,
limit: None,
}
}
let p = match cmd {
WebCmd::Scrape { url, no_index, scope } => WebParams {
index: no_index.then_some(false),
scope,
..params(WebMode::Scrape, parse_url(&url)?)
},
WebCmd::Crawl {
url,
max_pages,
max_depth,
scope,
} => WebParams {
max_pages,
max_depth,
scope,
..params(WebMode::Crawl, parse_url(&url)?)
},
WebCmd::Map { url, limit } => WebParams {
limit,
..params(WebMode::Map, parse_url(&url)?)
},
};
let key = p.mode.telemetry_key();
let r = run_tool(key, server.web(Parameters(Lenient(p))).await)?;
emit(key, &r, opts, out)
}
#[cfg(not(feature = "crawl"))]
pub async fn run(_server: &BasemindServer, _cmd: WebCmd, _opts: &Emit, _out: &mut impl Write) -> Result<()> {
anyhow::bail!("this `basemind` was built without the `crawl` feature; rebuild with --features crawl")
}