weavatrix-rust 2.16.4

Protocol-independent Rust repository intelligence: typed evidence graphs for impact, architecture, APIs, Git, n8n, Dify, Agent catalogs, Mermaid, and Web3 ABI
Documentation
use super::facts::{locator, push_meta, symbol};
use super::model::a2a_kind;
use super::paths::{package_root, span_of};
use crate::language::FileFacts;
use blazingly_json::Value;

#[must_use]
pub(super) fn decode(path: &str, raw: &str, value: &Value) -> Option<FileFacts> {
    let object = value.as_object()?;
    let schema = object.get("$schema").and_then(Value::as_str).unwrap_or("");
    let looks = schema.contains("a2a")
        || (object.get("preferredTransport").is_some() && object.get("url").is_some())
        || (object.get("capabilities").is_some()
            && object.get("skills").and_then(Value::as_array).is_some()
            && object.get("url").and_then(Value::as_str).is_some());
    if !looks {
        return None;
    }
    let name = object
        .get("name")
        .and_then(Value::as_str)
        .unwrap_or("a2a-card");
    let mut facts = FileFacts::default();
    let card = symbol(name, a2a_kind(), span_of(path, raw, name));
    let owner = locator(&card);
    facts.symbols.push(card);
    let mut meta = vec![
        format!("package:{}", package_root(path)),
        "plane:declared".to_owned(),
        "kind:a2a_card".to_owned(),
        "not:agent.skill".to_owned(),
    ];
    if let Some(url) = object.get("url").and_then(Value::as_str) {
        meta.push(format!("url:{url}"));
    }
    push_meta(&mut facts, &owner, &owner.span, &meta);
    Some(facts)
}

#[cfg(test)]
mod tests {
    use super::decode;
    use blazingly_json::json;

    #[test]
    fn a2a_cards_are_recognized_by_schema_or_transport_shape() {
        assert!(decode("card.json", "{}", &json!({"name": "x"})).is_none());
        let schema = decode(
            "card.json",
            r#"{"$schema":"https://a2a.dev/card"}"#,
            &json!({"$schema": "https://a2a.dev/card", "name": "desk", "url": "https://x"}),
        )
        .unwrap();
        assert!(schema.symbols.iter().any(|symbol| symbol.name == "desk"));
        let transport = decode(
            "card.json",
            "{}",
            &json!({"preferredTransport": "jsonrpc", "url": "https://x"}),
        );
        assert!(transport.is_some());
        let skills = decode(
            "card.json",
            "{}",
            &json!({"capabilities": {}, "skills": [], "url": "https://x"}),
        );
        assert!(skills.is_some());
    }
}