259 lines
12 KiB
PHP
259 lines
12 KiB
PHP
<?php
|
|
/**
|
|
* WEVIA DEV PIPELINE v1.0 — Full Autonomous Development Cycle
|
|
*
|
|
* PIPELINE (10 étapes):
|
|
* 1. RECEIVE → demande via chat/API
|
|
* 2. ANALYZE → parse intent, scope, impacted files
|
|
* 3. SCAN → wiki + L99 + architecture + 4 servers
|
|
* 4. DEVELOP → write code / fix bugs
|
|
* 5. TEST → L99 video long + Playwright + Selenium
|
|
* 6. FIX → corriger les bugs trouvés
|
|
* 7. RETEST → NonReg complet
|
|
* 8. COMMIT → git commit + checksums
|
|
* 9. WIKI → update wiki + L99 visual
|
|
* 10. PUSH → GitHub + Mattermost + Blade
|
|
*/
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
|
|
$input = json_decode(file_get_contents("php://input"), true);
|
|
$action = $_GET['action'] ?? $input['action'] ?? 'status';
|
|
|
|
switch ($action) {
|
|
|
|
case 'status':
|
|
// Pipeline health check
|
|
$checks = [];
|
|
// Playwright
|
|
exec("python3 -c 'from playwright.sync_api import sync_playwright;print(\"OK\")' 2>&1", $pw);
|
|
$checks['playwright'] = (trim($pw[0] ?? '') === 'OK');
|
|
// Selenium
|
|
exec("python3 -c 'from selenium import webdriver;print(\"OK\")' 2>&1", $se);
|
|
$checks['selenium'] = (trim($se[0] ?? '') === 'OK');
|
|
// Chrome
|
|
$checks['chrome'] = file_exists('/usr/bin/google-chrome');
|
|
$checks['chromedriver'] = file_exists('/usr/local/bin/chromedriver');
|
|
// Git
|
|
$checks['git'] = trim(shell_exec('cd /var/www/html && git status --porcelain 2>/dev/null | wc -l') ?? '0');
|
|
// L99
|
|
$checks['l99_scripts'] = intval(trim(shell_exec('ls /opt/weval-l99/l99-*.py 2>/dev/null | wc -l') ?? '0'));
|
|
// NonReg
|
|
$nr = json_decode(@file_get_contents('https://weval-consulting.com/api/nonreg-api.php?cat=all') ?: '{}', true);
|
|
$checks['nonreg'] = ($nr['pass'] ?? 0) . '/' . ($nr['total'] ?? 0);
|
|
// Wiki
|
|
$checks['wiki'] = intval(trim(shell_exec('ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l') ?? '0'));
|
|
// Gap Detector
|
|
$gap = json_decode(@file_get_contents('/var/www/html/api/gap-detector.json') ?: '{}', true);
|
|
$checks['gap_score'] = ($gap['score'] ?? '?') . '%';
|
|
|
|
echo json_encode(['pipeline' => 'WEVIA DEV v1.0', 'status' => 'ready', 'checks' => $checks], JSON_PRETTY_PRINT);
|
|
break;
|
|
|
|
case 'analyze':
|
|
// Step 1+2: Receive + Analyze demand
|
|
$demand = $input['demand'] ?? '';
|
|
if (!$demand) { echo json_encode(['error' => 'demand required']); exit; }
|
|
|
|
$analysis = [
|
|
'demand' => $demand,
|
|
'timestamp' => date('Y-m-d H:i'),
|
|
'steps' => []
|
|
];
|
|
|
|
// Scan wiki for related entries
|
|
$wiki_hits = [];
|
|
exec("grep -rl " . escapeshellarg(strtolower(substr($demand, 0, 30))) . " /opt/weval-l99/wiki/ 2>/dev/null | head -5", $wiki_hits);
|
|
$analysis['wiki_related'] = count($wiki_hits);
|
|
|
|
// Scan fast.php for impacted routes
|
|
$fast = file_get_contents('/var/www/html/api/weval-ia-fast.php') ?: '';
|
|
$keywords = preg_split('/\s+/', strtolower($demand));
|
|
$impacted_routes = 0;
|
|
foreach ($keywords as $kw) {
|
|
if (strlen($kw) > 4 && stripos($fast, $kw) !== false) $impacted_routes++;
|
|
}
|
|
$analysis['impacted_routes'] = $impacted_routes;
|
|
|
|
// Scan architecture
|
|
$archi = json_decode(@file_get_contents('/var/www/html/api/architecture-scan.json') ?: '{}', true);
|
|
$analysis['archi_sections'] = count($archi);
|
|
|
|
// NonReg baseline
|
|
$nr = json_decode(@file_get_contents('https://weval-consulting.com/api/nonreg-api.php?cat=all') ?: '{}', true);
|
|
$analysis['nonreg_baseline'] = ($nr['pass'] ?? 0) . '/' . ($nr['total'] ?? 0);
|
|
|
|
$analysis['steps'] = [
|
|
'1_receive' => 'OK — demand parsed',
|
|
'2_analyze' => 'OK — ' . count($wiki_hits) . ' wiki hits, ' . $impacted_routes . ' route keywords',
|
|
'3_scan' => 'PENDING — server scan needed',
|
|
'4_develop' => 'PENDING',
|
|
'5_test_l99' => 'PENDING — Playwright + Selenium ready',
|
|
'6_fix' => 'PENDING',
|
|
'7_retest_nonreg' => 'PENDING — baseline ' . $analysis['nonreg_baseline'],
|
|
'8_commit' => 'PENDING',
|
|
'9_wiki_update' => 'PENDING',
|
|
'10_push' => 'PENDING — GitHub configured',
|
|
];
|
|
|
|
echo json_encode($analysis, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
break;
|
|
|
|
case 'scan':
|
|
// Step 3: Real scan of all 4 servers
|
|
$scan = ['timestamp' => date('Y-m-d H:i'), 'servers' => []];
|
|
|
|
// S204 (primary)
|
|
$s204 = [
|
|
'docker' => intval(trim(shell_exec('docker ps | tail -n+2 | wc -l') ?? '0')),
|
|
'disk' => trim(shell_exec("df -h / | tail -1 | awk '{print $5}'") ?? '?'),
|
|
'ram' => trim(shell_exec("free -h | grep Mem | awk '{print $3\"/\"$2}'") ?? '?'),
|
|
'load' => trim(shell_exec('cat /proc/loadavg | head -c 5') ?? '?'),
|
|
'crons' => intval(trim(shell_exec('ls /etc/cron.d/weval-* 2>/dev/null | wc -l') ?? '0')),
|
|
'routes' => intval(trim(shell_exec('grep -c "// Route" /var/www/html/api/weval-ia-fast.php 2>/dev/null') ?? '0')),
|
|
'git_dirty' => intval(trim(shell_exec('cd /var/www/html && git status --porcelain 2>/dev/null | wc -l') ?? '0')),
|
|
];
|
|
$scan['servers']['S204'] = $s204;
|
|
|
|
// S95 (sentinel)
|
|
$s95 = trim(shell_exec('curl -s --max-time 3 http://10.1.0.3:5890/api/sentinel-brain.php?action=ping 2>/dev/null') ?? '');
|
|
$scan['servers']['S95'] = ['status' => $s95 ? 'UP' : 'DOWN', 'port' => 5890];
|
|
|
|
// S151 (tracking)
|
|
$s151 = trim(shell_exec('curl -s --max-time 3 -o /dev/null -w "%{http_code}" http://151.80.235.110/ 2>/dev/null') ?? '');
|
|
$scan['servers']['S151'] = ['status' => $s151 == '200' ? 'UP' : $s151, 'ip' => '151.80.235.110'];
|
|
|
|
// Qdrant
|
|
$qdrant = json_decode(@file_get_contents('http://127.0.0.1:6333/collections') ?: '{}', true);
|
|
$total_v = 0;
|
|
foreach ($qdrant['result']['collections'] ?? [] as $c) $total_v += $c['points_count'] ?? 0;
|
|
$scan['qdrant'] = $total_v;
|
|
|
|
// Ollama
|
|
$ollama = json_decode(@file_get_contents('http://127.0.0.1:11434/api/tags') ?: '{}', true);
|
|
$scan['ollama_models'] = count($ollama['models'] ?? []);
|
|
|
|
echo json_encode($scan, JSON_PRETTY_PRINT);
|
|
break;
|
|
|
|
case 'test':
|
|
// Step 5: Run L99 tests
|
|
$test_type = $input['type'] ?? 'functional';
|
|
$results = ['timestamp' => date('Y-m-d H:i'), 'type' => $test_type];
|
|
|
|
switch ($test_type) {
|
|
case 'functional':
|
|
exec('timeout 120 python3 /opt/weval-l99/l99-functional-test.py 2>&1 | tail -5', $out);
|
|
$results['output'] = implode("\n", $out);
|
|
break;
|
|
case 'visual':
|
|
exec('timeout 60 python3 /opt/weval-l99/l99-visual-test.py 2>&1 | tail -5', $out);
|
|
$results['output'] = implode("\n", $out);
|
|
break;
|
|
case 'video':
|
|
exec('timeout 120 python3 /opt/weval-l99/l99-videotest.py 2>&1 | tail -5', $out);
|
|
$results['output'] = implode("\n", $out);
|
|
break;
|
|
case 'security':
|
|
exec('timeout 60 python3 /opt/weval-l99/l99-security-scan.py 2>&1 | tail -5', $out);
|
|
$results['output'] = implode("\n", $out);
|
|
break;
|
|
case 'nonreg':
|
|
$nr = json_decode(@file_get_contents('https://weval-consulting.com/api/nonreg-api.php?cat=all') ?: '{}', true);
|
|
$results['pass'] = $nr['pass'] ?? 0;
|
|
$results['total'] = $nr['total'] ?? 0;
|
|
$results['score'] = $nr['score'] ?? 0;
|
|
break;
|
|
}
|
|
|
|
echo json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
break;
|
|
|
|
case 'commit':
|
|
// Step 8: Git commit + push
|
|
$msg = $input['message'] ?? 'WEVIA Pipeline auto-commit';
|
|
$results = ['timestamp' => date('Y-m-d H:i')];
|
|
|
|
// GOLD backup first
|
|
exec('cp /var/www/html/api/weval-ia-fast.php /opt/wevads/vault/gold-4avr-brain/pipeline-auto-' . date('His') . '.GOLD 2>&1');
|
|
$results['gold'] = true;
|
|
|
|
// Git commit
|
|
exec('cd /var/www/html && git add -A && git commit -m ' . escapeshellarg($msg) . ' 2>&1', $git_out);
|
|
$results['commit'] = implode("\n", array_slice($git_out, -2));
|
|
|
|
// Git push
|
|
exec('cd /var/www/html && git push github main 2>&1', $push_out);
|
|
$results['push'] = implode("\n", array_slice($push_out, -2));
|
|
|
|
echo json_encode($results, JSON_PRETTY_PRINT);
|
|
break;
|
|
|
|
case 'wiki_update':
|
|
// Step 9: Update wiki
|
|
exec('timeout 30 python3 /opt/weval-l99/wiki-mega-scan.py 2>&1 | tail -1', $wiki_out);
|
|
echo json_encode(['wiki' => trim($wiki_out[0] ?? ''), 'timestamp' => date('Y-m-d H:i')]);
|
|
break;
|
|
|
|
case 'push_all':
|
|
// Step 10: Push to all repositories
|
|
$results = ['timestamp' => date('Y-m-d H:i'), 'targets' => []];
|
|
|
|
// GitHub
|
|
exec('cd /var/www/html && git push github main 2>&1', $gh);
|
|
$results['targets']['github'] = trim(implode("\n", array_slice($gh, -1)));
|
|
|
|
// Mattermost notification
|
|
$mm_text = "🚀 **WEVIA Pipeline** — " . ($input['message'] ?? 'auto-push') . "\nRoutes: " . trim(shell_exec('grep -c "// Route" /var/www/html/api/weval-ia-fast.php 2>/dev/null') ?? '?');
|
|
$ch = curl_init('http://localhost:8065/hooks/pt54hzthf3b6pe6rgp1ionipnh');
|
|
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => json_encode(['text' => $mm_text]),
|
|
CURLOPT_HTTPHEADER => ['Content-Type: application/json'], CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 5]);
|
|
curl_exec($ch); curl_close($ch);
|
|
$results['targets']['mattermost'] = 'notified';
|
|
|
|
echo json_encode($results, JSON_PRETTY_PRINT);
|
|
break;
|
|
|
|
case 'full_cycle':
|
|
// Run complete pipeline
|
|
$demand = $input['demand'] ?? 'Auto maintenance cycle';
|
|
$results = ['pipeline' => 'FULL CYCLE', 'demand' => $demand, 'timestamp' => date('Y-m-d H:i'), 'steps' => []];
|
|
|
|
// Step 1-2: Analyze
|
|
$results['steps']['1_analyze'] = 'Demand: ' . substr($demand, 0, 100);
|
|
|
|
// Step 3: Scan
|
|
$docker = intval(trim(shell_exec('docker ps | tail -n+2 | wc -l') ?? '0'));
|
|
$disk = trim(shell_exec("df -h / | tail -1 | awk '{print \$5}'") ?? '?');
|
|
$results['steps']['3_scan'] = "S204: Docker=$docker Disk=$disk";
|
|
|
|
// Step 5: NonReg test
|
|
$nr = json_decode(@file_get_contents('https://weval-consulting.com/api/nonreg-api.php?cat=all') ?: '{}', true);
|
|
$results['steps']['5_nonreg'] = ($nr['pass'] ?? 0) . '/' . ($nr['total'] ?? 0) . ' (' . ($nr['score'] ?? 0) . '%)';
|
|
|
|
// Step 7: L99
|
|
exec('timeout 60 python3 /opt/weval-l99/l99-functional-test.py 2>&1 | grep "DONE" | tail -1', $l99);
|
|
$results['steps']['7_l99'] = trim($l99[0] ?? 'running');
|
|
|
|
// Step 8: Commit
|
|
exec('cd /var/www/html && git add -A && git status --porcelain 2>/dev/null | wc -l', $dirty);
|
|
$results['steps']['8_git'] = trim($dirty[0] ?? '0') . ' files dirty';
|
|
|
|
// Step 9: Wiki
|
|
$wiki = intval(trim(shell_exec('ls /opt/weval-l99/wiki/*.json 2>/dev/null | wc -l') ?? '0'));
|
|
$results['steps']['9_wiki'] = "$wiki entries";
|
|
|
|
// Step 10: Gap
|
|
$gap = json_decode(@file_get_contents('/var/www/html/api/gap-detector.json') ?: '{}', true);
|
|
$results['steps']['10_gap'] = ($gap['score'] ?? '?') . '% wired';
|
|
|
|
echo json_encode($results, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE);
|
|
break;
|
|
|
|
default:
|
|
echo json_encode([
|
|
'pipeline' => 'WEVIA DEV v1.0',
|
|
'actions' => ['status', 'analyze', 'scan', 'test', 'commit', 'wiki_update', 'push_all', 'full_cycle'],
|
|
'test_types' => ['functional', 'visual', 'video', 'security', 'nonreg'],
|
|
]);
|
|
}
|