weavatrix-rust 1.0.2

Native repository intelligence for coding agents: 39 read-only MCP tools, evidence graph, cross-repository analysis, and lossless parsing
Documentation
use blazingly_json::{Map, Value, json};
use serde::Serialize;

#[derive(Debug, Clone, Serialize)]
#[serde(rename_all = "camelCase")]
pub struct ToolDefinition {
    pub name: &'static str,
    pub description: &'static str,
    pub input_schema: Value,
}

#[must_use]
#[allow(clippy::too_many_lines)]
pub fn catalog() -> Vec<ToolDefinition> {
    let mut tools = vec![
        tool(
            "graph_stats",
            "Graph size, evidence and build freshness.",
            &[],
        ),
        tool("get_node", "Resolve one exact graph node.", &["label"]),
        tool(
            "get_neighbors",
            "Direct typed incoming and outgoing relationships.",
            &["label"],
        ),
        tool(
            "query_graph",
            "Bounded BFS or DFS around exact or textual seeds.",
            &[],
        ),
        tool("god_nodes", "Rank high-connectivity production nodes.", &[]),
        tool(
            "shortest_path",
            "Shortest typed dependency path between two nodes.",
            &["source", "target"],
        ),
        tool(
            "get_dependents",
            "Bounded transitive reverse blast radius.",
            &["label"],
        ),
        tool(
            "change_impact",
            "Read-only Git change impact with graph evidence.",
            &[],
        ),
        tool(
            "git_history",
            "Bounded direct Git history without launching git.",
            &[],
        ),
        tool(
            "cross_repo_git",
            "Parallel histories, shared commits, or diffs across local repositories.",
            &["repositories"],
        ),
        tool(
            "verified_change",
            "Composite pre-commit evidence and conservative verdict.",
            &["task"],
        ),
        tool(
            "trace_api_contract",
            "Cross-repository HTTP, GraphQL, gRPC and event-transport contract evidence.",
            &["backend", "clients"],
        ),
        tool(
            "get_community",
            "Return one weak graph component.",
            &["community_id"],
        ),
        tool(
            "search_code",
            "Literal or Rust-regex repository search without ripgrep.",
            &["query"],
        ),
        tool(
            "read_source",
            "Bounded source context by node or repository path.",
            &[],
        ),
        tool(
            "inspect_symbol",
            "Definition, direct relationships and source evidence.",
            &["label"],
        ),
        tool(
            "context_bundle",
            "Compact graph and source bundle for one symbol.",
            &["label"],
        ),
        tool(
            "find_duplicates",
            "Deterministic Type-1/2/3 clone families.",
            &[],
        ),
        tool(
            "find_dead_code",
            "Conservative unreferenced-symbol review queue.",
            &[],
        ),
        tool(
            "run_audit",
            "Repository structure and evidence completeness audit.",
            &[],
        ),
        tool(
            "coverage_map",
            "Measured coverage discovery or explicit static reachability.",
            &[],
        ),
        tool(
            "hot_path_review",
            "Rank high-connectivity and large source symbols.",
            &[],
        ),
        tool(
            "list_communities",
            "List deterministic weak graph components.",
            &[],
        ),
        tool("module_map", "Production folder and dependency map.", &[]),
        tool(
            "list_endpoints",
            "Inventory statically extracted HTTP endpoints.",
            &[],
        ),
        tool(
            "trace_endpoint",
            "Resolve an endpoint and its bounded call neighborhood.",
            &["path"],
        ),
        tool(
            "rebuild_graph",
            "Rebuild the derived in-memory graph without source writes.",
            &[],
        ),
        tool(
            "graph_diff",
            "Compare the current snapshot with an immutable Git revision.",
            &["base_ref"],
        ),
        tool(
            "get_architecture_contract",
            "Read or preview the local target-architecture contract.",
            &[],
        ),
        tool(
            "prepare_change",
            "Select architecture rules for intended changed files.",
            &["files"],
        ),
        tool(
            "verify_architecture",
            "Verify graph dependencies against the active contract.",
            &[],
        ),
        tool(
            "explain_architecture_violation",
            "Explain one active contract violation.",
            &["fingerprint"],
        ),
        tool(
            "propose_architecture_exception",
            "Return a reviewable exception proposal without writing it.",
            &["fingerprint", "reason"],
        ),
        tool(
            "open_repo",
            "Retarget to another local repository.",
            &["path"],
        ),
        tool(
            "list_known_repos",
            "List repositories opened by this server process.",
            &[],
        ),
        tool(
            "semantic_link",
            "Build inferred semantic graph evidence from supplied vectors.",
            &["vectors"],
        ),
        tool(
            "vector_search",
            "Exact or bounded approximate nearest-neighbor search.",
            &["vectors", "query"],
        ),
        tool(
            "seo_link_suggestions",
            "Directional SEO internal-link evidence from supplied page profiles.",
            &["vectors", "pages"],
        ),
        tool(
            "memory_context",
            "Compile bounded temporal memory context from supplied events.",
            &["events", "request"],
        ),
    ];
    tools.retain(|tool| capability_is_compiled(tool.name));
    tools
}

#[must_use]
pub fn catalog_for_profile(profile: crate::mcp::McpProfile) -> Vec<ToolDefinition> {
    catalog()
        .into_iter()
        .filter(|tool| profile.allows(tool.name))
        .collect()
}

#[allow(clippy::needless_bool)]
fn capability_is_compiled(tool: &str) -> bool {
    if tool == "find_duplicates" {
        cfg!(feature = "clone")
    } else if matches!(
        tool,
        "change_impact" | "git_history" | "cross_repo_git" | "verified_change" | "graph_diff"
    ) {
        cfg!(feature = "git")
    } else if tool == "search_code" {
        cfg!(feature = "search")
    } else if matches!(tool, "semantic_link" | "seo_link_suggestions") {
        cfg!(feature = "semantic")
    } else if tool == "vector_search" {
        cfg!(feature = "vector")
    } else if tool == "memory_context" {
        cfg!(feature = "memory")
    } else {
        true
    }
}

fn tool(
    tool_name: &'static str,
    description: &'static str,
    required: &[&'static str],
) -> ToolDefinition {
    let mut properties = Map::from_iter([(
        "output_format".to_owned(),
        json!({
            "type": "string",
            "enum": ["text", "json"],
            "default": "json"
        }),
    )]);
    for name in super::catalog_schema::optional_fields(tool_name) {
        properties.insert(
            (*name).to_owned(),
            super::catalog_schema::field_schema(tool_name, name),
        );
    }
    for name in required {
        let schema = super::catalog_schema::field_schema(tool_name, name);
        properties.insert((*name).to_owned(), schema);
    }
    let required = required
        .iter()
        .map(|value| json!(value))
        .collect::<Vec<_>>();
    ToolDefinition {
        name: tool_name,
        description,
        input_schema: json!({
            "type": "object",
            "additionalProperties": true,
            "properties": properties,
            "required": required
        }),
    }
}