mirror of
https://github.com/proffesor-for-testing/agentic-qe.git
synced 2026-09-19 08:45:47 +08:00
7363bb1278
## @ruvector/edge Integration - Phases 0-3 Complete ### Phase 0: Browser Runtime - WASM shims and browser compatibility - BrowserAgent, BrowserHNSWAdapter, IndexedDBStorage - Chrome DevTools panel ### Phase 1: VS Code Extension MVP - Full extension with real-time analysis - Inline test suggestions, coverage visualization - Offline-first storage with sync ### Phase 2: P2P Foundation - Ed25519 crypto, WebRTC connections - SignalingServer, AgentSpawnAPI, EdgeServer - Pattern sharing via data channels - CRDT conflict resolution ### Phase 3: Web Dashboard - React dashboard with dark theme - P2P connection management UI - QE Agent Launcher from browser - React hooks (useP2P, usePatternSync, etc.) ### Documentation - Edge Server Guide - P2P Pattern Sharing Guide - Updated CLI agent-commands ### Also includes - Dead code cleanup (~22k lines) - 143 new P2P integration tests - Version updates across all files 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
12 KiB
12 KiB
Edge Server Guide
Complete guide for deploying and using the AQE Edge Server for REST API access and P2P pattern sharing.
Overview
The Edge Server provides two deployment options beyond the standard Claude Code integration:
- REST API - Spawn and manage agents from external applications, CI/CD pipelines, or custom tools
- P2P Pattern Sharing - Real-time test pattern synchronization between team members via WebRTC
Quick Start
Starting the Edge Server
# Build the project (if not already built)
npm run build
# Start with default ports (HTTP: 3001, WebSocket: 3002)
node dist/edge/server/index.js
# Or with custom configuration
HTTP_PORT=8080 WS_PORT=8081 HOST=0.0.0.0 node dist/edge/server/index.js
Verify Server is Running
# Health check
curl http://localhost:3001/health
# Response:
# {"status":"ok","uptime":1234,"version":"1.0.0"}
# Full API health with agent/peer counts
curl http://localhost:3001/api/health
# Response:
# {"status":"ok","uptime":1234,"version":"1.0.0","agents":0,"signalingPeers":0}
REST API Reference
Agent Management
Spawn Agent
POST /api/agents/spawn
Content-Type: application/json
{
"agentType": "test-generator",
"task": "Create unit tests for UserService",
"model": "claude-sonnet-4-20250514", // optional
"maxTokens": 8192 // optional
}
Response (201 Created):
{
"success": true,
"agentId": "agent-550e8400-e29b-41d4-a716-446655440000",
"agentType": "test-generator",
"status": "running",
"startedAt": "2025-01-03T10:30:00.000Z"
}
List Agents
GET /api/agents
GET /api/agents?status=running
GET /api/agents?type=test-generator
Response:
{
"agents": [
{
"id": "agent-550e8400...",
"agentType": "test-generator",
"status": "running",
"startedAt": "2025-01-03T10:30:00.000Z"
}
]
}
Get Agent Status
GET /api/agents/:id
Response:
{
"id": "agent-550e8400...",
"agentType": "test-generator",
"status": "completed",
"startedAt": "2025-01-03T10:30:00.000Z",
"completedAt": "2025-01-03T10:32:15.000Z",
"exitCode": 0
}
Get Agent Output
GET /api/agents/:id/output
GET /api/agents/:id/output?last=100 # Last 100 lines
Response:
{
"output": "Generated 15 test cases for UserService...\n..."
}
Cancel Agent
DELETE /api/agents/:id
Response:
{
"success": true,
"message": "Agent cancelled"
}
List Available Agent Types
GET /api/agents/types
Response:
{
"types": [
"test-generator",
"coverage-analyzer",
"quality-gate",
"performance-tester",
"security-scanner",
"flaky-test-hunter",
"chaos-engineer",
"visual-tester",
"code-reviewer",
"integration-tester"
]
}
Signaling Server Stats
GET /api/signaling/stats
Response:
{
"totalPeers": 5,
"totalRooms": 2,
"messagesProcessed": 1247,
"uptime": 3600000
}
Room Peers
GET /api/signaling/rooms/:roomId/peers
Response:
{
"roomId": "team-alpha",
"peers": ["peer-1", "peer-2", "peer-3"]
}
P2P Pattern Sharing
Architecture
┌─────────────────┐ WebSocket ┌──────────────────┐
│ Browser A │◄──────────────────►│ Signaling │
│ (P2PService) │ │ Server │
└────────┬────────┘ │ (WS: 3002) │
│ └──────────────────┘
│ WebRTC Data Channel ▲
│ (Direct P2P) │ WebSocket
▼ │
┌─────────────────┐ ┌────────┴─────────┐
│ Browser B │◄───────────────────│ Browser C │
│ (P2PService) │ WebRTC │ (P2PService) │
└─────────────────┘ └──────────────────┘
React Integration
Setup Provider
// App.tsx
import { P2PProvider } from '@agentic-qe/edge/webapp';
function App() {
return (
<P2PProvider config={{
signalingUrl: 'ws://localhost:3002',
roomId: 'team-alpha',
autoConnect: true
}}>
<PatternDashboard />
</P2PProvider>
);
}
Using P2P Hooks
import { useP2P, usePatternSync, usePeerConnection } from '@agentic-qe/edge/webapp';
function PatternDashboard() {
// Core P2P functionality
const {
isInitialized,
peers,
connectToPeer,
disconnectFromPeer,
sharePattern
} = useP2P();
// Pattern synchronization
const {
status,
isSyncing,
pendingCount,
syncedCount,
sync,
syncAll,
onPatternReceived,
onConflict
} = usePatternSync({
autoSync: true,
syncInterval: 30000 // 30 seconds
});
// Subscribe to received patterns
useEffect(() => {
const unsubscribe = onPatternReceived((pattern) => {
console.log('Received pattern:', pattern.id, pattern.name);
});
return unsubscribe;
}, [onPatternReceived]);
return (
<div>
<h2>P2P Status</h2>
<p>Connected: {isInitialized ? 'Yes' : 'No'}</p>
<p>Peers: {peers.size}</p>
<p>Sync Status: {status.status}</p>
<p>Pending: {pendingCount} | Synced: {syncedCount}</p>
<button onClick={syncAll} disabled={isSyncing}>
{isSyncing ? 'Syncing...' : 'Sync All Patterns'}
</button>
</div>
);
}
Monitor Peer Connections
import { usePeerConnection } from '@agentic-qe/edge/webapp';
function PeerMonitor({ peerId }: { peerId: string }) {
const {
connectionState,
dataChannelState,
stats,
connect,
disconnect
} = usePeerConnection(peerId);
return (
<div>
<p>Peer: {peerId}</p>
<p>Connection: {connectionState}</p>
<p>Data Channel: {dataChannelState}</p>
<p>Latency: {stats?.latency}ms</p>
{connectionState === 'disconnected' && (
<button onClick={connect}>Connect</button>
)}
{connectionState === 'connected' && (
<button onClick={disconnect}>Disconnect</button>
)}
</div>
);
}
Pattern Data Format
interface SharedPattern {
id: string;
name: string;
category: PatternCategory;
framework: string;
pattern: string;
description: string;
confidence: number;
usageCount: number;
version: number;
createdAt: Date;
updatedAt: Date;
sharedBy: string; // Peer ID
}
enum PatternCategory {
UNIT_TEST = 'unit-test',
INTEGRATION_TEST = 'integration-test',
E2E_TEST = 'e2e-test',
PERFORMANCE_TEST = 'performance-test',
SECURITY_TEST = 'security-test',
DEFECT_FIX = 'defect-fix'
}
CI/CD Integration
GitHub Actions Example
name: AQE Test Generation
on: [push]
jobs:
generate-tests:
runs-on: ubuntu-latest
services:
edge-server:
image: node:20
ports:
- 3001:3001
- 3002:3002
steps:
- uses: actions/checkout@v4
- name: Start Edge Server
run: |
npm ci
npm run build
node dist/edge/server/index.js &
sleep 5 # Wait for server startup
- name: Generate Tests
run: |
RESPONSE=$(curl -X POST http://localhost:3001/api/agents/spawn \
-H "Content-Type: application/json" \
-d '{
"agentType": "test-generator",
"task": "Create unit tests for src/services/"
}')
AGENT_ID=$(echo $RESPONSE | jq -r '.agentId')
echo "Agent ID: $AGENT_ID"
# Wait for completion
while true; do
STATUS=$(curl -s http://localhost:3001/api/agents/$AGENT_ID | jq -r '.status')
if [ "$STATUS" = "completed" ]; then
break
fi
sleep 5
done
# Get output
curl http://localhost:3001/api/agents/$AGENT_ID/output
Jenkins Pipeline Example
pipeline {
agent any
stages {
stage('Start Edge Server') {
steps {
sh '''
npm ci
npm run build
nohup node dist/edge/server/index.js &
sleep 5
'''
}
}
stage('Generate Tests') {
steps {
script {
def response = sh(
script: '''
curl -X POST http://localhost:3001/api/agents/spawn \
-H "Content-Type: application/json" \
-d '{"agentType": "test-generator", "task": "Generate tests"}'
''',
returnStdout: true
)
def agentId = readJSON(text: response).agentId
// Poll for completion
timeout(time: 10, unit: 'MINUTES') {
waitUntil {
def status = sh(
script: "curl -s http://localhost:3001/api/agents/${agentId} | jq -r '.status'",
returnStdout: true
).trim()
return status == 'completed'
}
}
}
}
}
}
}
Configuration
Environment Variables
| Variable | Default | Description |
|---|---|---|
HTTP_PORT |
3001 |
HTTP API port |
WS_PORT |
3002 |
WebSocket signaling port |
HOST |
0.0.0.0 |
Bind address |
CORS_ORIGINS |
localhost:3000,3001,5173 |
Allowed CORS origins |
MAX_AGENTS |
10 |
Maximum concurrent agents |
Programmatic Configuration
import { EdgeServer } from '@agentic-qe/edge/server';
const server = new EdgeServer({
httpPort: 3001,
wsPort: 3002,
host: '0.0.0.0',
projectPath: process.cwd(),
maxAgents: 20,
corsOrigins: [
'http://localhost:3000',
'https://my-app.example.com'
],
signalingConfig: {
maxPeersPerRoom: 50,
heartbeatInterval: 30000
}
});
await server.start();
console.log('Edge Server running');
// Graceful shutdown
process.on('SIGTERM', async () => {
await server.stop();
process.exit(0);
});
Comparison: CLI vs REST API vs Task Tool
| Feature | CLI (aqe agent spawn) |
REST API | Task Tool |
|---|---|---|---|
| Use Case | Terminal, scripts | CI/CD, web apps | Claude Code |
| Async Support | --wait flag |
Polling | Built-in |
| Output Streaming | Yes (attach) | Polling | Yes |
| External Access | Local only | Network | Local only |
| Authentication | N/A | Custom (CORS) | N/A |
| Best For | Developers | Automation | AI workflows |
Troubleshooting
Port Already in Use
# Find process using port
lsof -i :3001
# Kill process
kill -9 <PID>
# Or use different port
HTTP_PORT=4001 node dist/edge/server/index.js
CORS Errors
Add your origin to the CORS configuration:
const server = new EdgeServer({
corsOrigins: [
'http://localhost:3000',
'https://your-domain.com' // Add your domain
]
});
WebRTC Connection Failed
- Ensure both peers are connected to the signaling server
- Check firewall settings for WebRTC ports
- Verify STUN/TURN server configuration for NAT traversal
// Configure ICE servers for NAT traversal
const config: P2PServiceConfig = {
signalingUrl: 'ws://localhost:3002',
iceServers: [
{ urls: 'stun:stun.l.google.com:19302' },
{ urls: 'turn:your-turn-server.com', username: 'user', credential: 'pass' }
]
};