agentshield/adapter/
mod.rs1pub mod mcp;
2pub mod openclaw;
3
4use std::path::Path;
5
6use crate::error::{Result, ShieldError};
7use crate::ir::{Framework, ScanTarget};
8
9pub trait Adapter: Send + Sync {
12 fn framework(&self) -> Framework;
14
15 fn detect(&self, root: &Path) -> bool;
17
18 fn load(&self, root: &Path) -> Result<Vec<ScanTarget>>;
20}
21
22pub fn all_adapters() -> Vec<Box<dyn Adapter>> {
24 vec![
25 Box::new(mcp::McpAdapter),
26 Box::new(openclaw::OpenClawAdapter),
27 ]
28}
29
30pub fn auto_detect_and_load(root: &Path) -> Result<Vec<ScanTarget>> {
35 let adapters = all_adapters();
36 let mut all_targets = Vec::new();
37
38 for adapter in &adapters {
39 if adapter.detect(root) {
40 match adapter.load(root) {
41 Ok(targets) => all_targets.extend(targets),
42 Err(e) => {
43 tracing::warn!(
44 framework = %adapter.framework(),
45 error = %e,
46 "adapter failed to load, skipping"
47 );
48 }
49 }
50 }
51 }
52
53 if all_targets.is_empty() {
54 return Err(ShieldError::NoAdapter(root.display().to_string()));
55 }
56
57 Ok(all_targets)
58}