Coverage for src/alprina_cli/acp_server.py: 5%
77 statements
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
« prev ^ index » next coverage.py v7.11.3, created at 2025-11-14 11:27 +0100
1"""
2ACP (Agent Client Protocol) server for IDE integration.
3Allows Alprina to be used as an IDE agent.
4"""
6from typing import Any, Dict
7from rich.console import Console
9console = Console()
12def run_acp():
13 """
14 Start Alprina in ACP mode for IDE integration.
15 """
16 console.print("[cyan]Starting ACP server...[/cyan]")
18 try:
19 from agent_client_protocol import ACPServer, models
21 class AlprinaACPServer(ACPServer):
22 """Alprina ACP Server implementation."""
24 async def handle_request(self, req: models.Request) -> models.Response:
25 """Handle incoming ACP requests from IDE."""
26 method = req.method
27 params = req.params or {}
29 console.print(f"[dim]ACP Request: {method}[/dim]")
31 try:
32 if method == "scan":
33 result = await self._handle_scan(params)
34 return models.Response.ok(req.id, result)
36 elif method == "recon":
37 result = await self._handle_recon(params)
38 return models.Response.ok(req.id, result)
40 elif method == "mitigate":
41 result = await self._handle_mitigate(params)
42 return models.Response.ok(req.id, result)
44 elif method == "analyze_file":
45 result = await self._handle_analyze_file(params)
46 return models.Response.ok(req.id, result)
48 else:
49 return models.Response.error(
50 req.id,
51 -32601,
52 f"Method not found: {method}"
53 )
55 except Exception as e:
56 console.print(f"[red]Error handling request: {e}[/red]")
57 return models.Response.error(
58 req.id,
59 -32603,
60 f"Internal error: {str(e)}"
61 )
63 async def _handle_scan(self, params: Dict[str, Any]) -> Dict[str, Any]:
64 """Handle scan request."""
65 target = params.get("target")
66 profile = params.get("profile", "default")
67 safe_only = params.get("safe_only", True)
69 if not target:
70 raise ValueError("Target parameter is required")
72 from .security_engine import run_local_scan, run_remote_scan
73 from pathlib import Path
75 # Determine if local or remote
76 target_path = Path(target)
77 if target_path.exists():
78 result = run_local_scan(target, profile, safe_only)
79 else:
80 result = run_remote_scan(target, profile, safe_only)
82 return result
84 async def _handle_recon(self, params: Dict[str, Any]) -> Dict[str, Any]:
85 """Handle recon request."""
86 target = params.get("target")
87 passive = params.get("passive", True)
89 if not target:
90 raise ValueError("Target parameter is required")
92 from .security_engine import run_agent
94 result = run_agent(
95 task="web-recon",
96 input_data=target,
97 metadata={"passive": passive}
98 )
100 return result
102 async def _handle_mitigate(self, params: Dict[str, Any]) -> Dict[str, Any]:
103 """Handle mitigation request."""
104 finding = params.get("finding")
106 if not finding:
107 raise ValueError("Finding parameter is required")
109 from .security_engine import run_agent
111 mitigation_prompt = f"""
112 Security Finding: {finding.get('description')}
113 Type: {finding.get('type')}
114 Severity: {finding.get('severity')}
116 Provide step-by-step mitigation guidance.
117 """
119 result = run_agent(
120 task="mitigation",
121 input_data=mitigation_prompt,
122 metadata=finding
123 )
125 return result
127 async def _handle_analyze_file(self, params: Dict[str, Any]) -> Dict[str, Any]:
128 """Handle file analysis request."""
129 file_path = params.get("file_path")
130 content = params.get("content")
132 if not file_path and not content:
133 raise ValueError("Either file_path or content is required")
135 from pathlib import Path
136 from .security_engine import run_agent
138 if file_path:
139 content = Path(file_path).read_text()
141 result = run_agent(
142 task="code-audit",
143 input_data=content,
144 metadata={"file": file_path}
145 )
147 return result
149 # Start the ACP server with stdio transport
150 server = AlprinaACPServer(transport="stdio")
151 console.print("[green]ACP server started on stdio[/green]")
152 server.serve()
154 except ImportError:
155 console.print("[red]agent-client-protocol not installed[/red]")
156 console.print("[yellow]Install with: pip install agent-client-protocol[/yellow]")
157 except Exception as e:
158 console.print(f"[red]Failed to start ACP server: {e}[/red]")