use anyhow::{Context, Result};
use serde::Deserialize;
use serde_json::Value;
use std::path::PathBuf;
mod args;
pub(crate) mod policy;
mod workspace;
pub(crate) use policy::{Approval, ToolPolicy};
pub(crate) fn has_external_sloc_counter() -> bool {
workspace::has_tokei()
}
pub(crate) fn has_external_outline_tool() -> bool {
workspace::has_universal_ctags()
}
#[derive(Debug, Clone)]
pub struct ToolContext {
root: PathBuf,
}
impl ToolContext {
pub fn new(root: PathBuf) -> Self {
Self { root }
}
pub fn root(&self) -> &std::path::Path {
&self.root
}
}
fn parse_tool_args<T: for<'de> Deserialize<'de>>(args: Value) -> Result<T> {
serde_json::from_value(args).context("invalid tool arguments")
}
pub(crate) async fn invoke_read_only_deterministic(
root: PathBuf,
name: &str,
args: Value,
) -> Result<Value> {
let ctx = ToolContext::new(root);
match name {
"outline" => parse_tool_args(args).and_then(|args| workspace::tool_outline(&ctx, args)),
"sloc" => parse_tool_args(args).and_then(|args| workspace::tool_sloc(&ctx, args)),
other => anyhow::bail!("unknown deterministic tool: {other}"),
}
}