true,CURLOPT_POSTFIELDS=>json_encode(["model"=>"qwen-3-235b-a22b-instruct-2507","messages"=>[["role"=>"system","content"=>"WEVIA DevOps Pipeline. French. Concise."],["role"=>"user","content"=>$prompt]],"max_tokens"=>500,"temperature"=>0.2]),CURLOPT_HTTPHEADER=>["Content-Type: application/json","Authorization: Bearer ".($secrets["CEREBRAS_API_KEY"]??"")],CURLOPT_RETURNTRANSFER=>true,CURLOPT_TIMEOUT=>12]); $r=curl_exec($ch);curl_close($ch); return json_decode($r,true)["choices"][0]["message"]["content"]??""; } $trace = []; // STEP 1: ANALYZE REQUEST + WIKI + L99 if ($step === "full" || $step === "analyze") { // Read wiki $wikiFiles = glob("/opt/weval-l99/wiki/*.json"); $wikiCount = count($wikiFiles); $recentWiki = []; foreach (array_slice($wikiFiles, -5) as $wf) { $d = json_decode(@file_get_contents($wf), true); $recentWiki[] = $d["title"] ?? basename($wf); } // Read L99 $l99 = json_decode(@file_get_contents("/var/www/html/api/l99-results.json") ?: "{}", true); // Scan servers $ram = trim(shell_exec("free -h | grep Mem | awk '{print $3\"/\"$2}'")); $disk = trim(shell_exec("df -h / | tail -1 | awk '{print $5}'")); $docker = trim(shell_exec("docker ps -q 2>/dev/null | wc -l")); $git = trim(shell_exec("cd /var/www/html && git status --short 2>/dev/null | wc -l")); $gitBranch = trim(shell_exec("cd /var/www/html && git branch --show-current 2>/dev/null")); // Scan architecture $fastLines = count(file("/var/www/html/api/weval-ia-fast.php")); $autoLines = count(file("/var/www/html/api/wevia-autonomous.php")); $analysis = [ "task" => $task, "wiki" => ["count" => $wikiCount, "recent" => $recentWiki], "l99" => ["passed" => $l99["passed"] ?? "?", "total" => $l99["total"] ?? "?"], "infra" => ["ram" => $ram, "disk" => $disk, "docker" => $docker, "dirty_files" => $git, "branch" => $gitBranch], "codebase" => ["fast_lines" => $fastLines, "auto_lines" => $autoLines], ]; // LLM analysis if ($task) { $analysis["llm_analysis"] = llm("Dev request: $task\nInfra: RAM=$ram Disk=$disk Docker=$docker\nL99: {$l99['passed']}/{$l99['total']}\nFast.php: $fastLines lines\nAnalyze: what files to modify, risks, approach.", $secrets); } $trace[] = ["step" => "analyze", "data" => $analysis]; if ($step === "analyze") { echo json_encode($analysis, JSON_UNESCAPED_UNICODE); exit; } } // STEP 2: GOLD BACKUP if ($step === "full" || $step === "backup") { $timestamp = date("Ymd-His"); $backupDir = "/opt/wevads/vault/gold-$timestamp/"; @mkdir($backupDir, 0777, true); shell_exec("cp /var/www/html/api/weval-ia-fast.php $backupDir 2>/dev/null"); shell_exec("cp /var/www/html/api/wevia-autonomous.php $backupDir 2>/dev/null"); shell_exec("cp /var/www/html/wevia-master.html $backupDir 2>/dev/null"); shell_exec("cd $backupDir && md5sum * > checksums.md5 2>/dev/null"); $trace[] = ["step" => "backup", "dir" => $backupDir, "files" => count(glob("$backupDir*"))]; if ($step === "backup") { echo json_encode(["backup" => $backupDir, "files" => count(glob("$backupDir*"))]); exit; } } // STEP 3: GIT SNAPSHOT if ($step === "full" || $step === "snapshot") { $gitStatus = shell_exec("cd /var/www/html && git add -A && git status --short 2>&1"); $dirty = substr_count($gitStatus, "\n"); if ($dirty > 0) { shell_exec("cd /var/www/html && git commit -m 'PIPELINE: pre-dev snapshot' 2>&1"); } $hash = trim(shell_exec("cd /var/www/html && git rev-parse --short HEAD 2>/dev/null")); $trace[] = ["step" => "snapshot", "hash" => $hash, "dirty" => $dirty]; } // STEP 4: L99 PRE-TEST if ($step === "full" || $step === "pretest") { $py = 'import asyncio from playwright.async_api import async_playwright async def t(): async with async_playwright() as p: b=await p.chromium.launch(headless=True,args=["--no-sandbox"]) results=[] pages={"master":"https://weval-consulting.com/wevia-master.html","cortex":"https://weval-consulting.com/wevia-cortex.html","site":"https://weval-consulting.com/"} for name,url in pages.items(): pg=await b.new_page() try: await pg.goto(url,timeout=10000) await pg.wait_for_timeout(2000) title=await pg.title() errors=[] pg.on("pageerror",lambda e:errors.append(1)) await pg.wait_for_timeout(500) await pg.screenshot(path=f"/tmp/l99-pre-{name}.png") results.append({"page":name,"title":title,"errors":len(errors),"ok":True}) except Exception as e: results.append({"page":name,"error":str(e)[:80],"ok":False}) await pg.close() await b.close() import json;print(json.dumps(results)) asyncio.run(t())'; $out = shell_exec("timeout 30 python3 -c " . escapeshellarg($py) . " 2>&1"); $preTests = json_decode($out, true) ?: []; $prePassed = count(array_filter($preTests, function($t){return $t["ok"];})); $trace[] = ["step" => "pretest", "passed" => $prePassed, "total" => count($preTests), "results" => $preTests]; } // STEP 5: DEV (placeholder — actual dev done by caller) if ($step === "full") { $trace[] = ["step" => "dev", "status" => "ready", "note" => "Development phase — modify files now"]; } // STEP 6: POST-TEST (L99 + NonReg) if ($step === "full" || $step === "posttest") { // PHP lint all modified files $phpFiles = glob("/var/www/html/api/*.php"); $lintErrors = 0; foreach ($phpFiles as $pf) { $lint = shell_exec("php -l $pf 2>&1"); if (strpos($lint, "Errors") !== false) $lintErrors++; } // Playwright visual test $postPy = 'import asyncio,json from playwright.async_api import async_playwright async def t(): async with async_playwright() as p: b=await p.chromium.launch(headless=True,args=["--no-sandbox"]) pg=await b.new_page(viewport={"width":1400,"height":900}) await pg.goto("https://weval-consulting.com/wevia-master.html",timeout=10000) await pg.wait_for_timeout(3000) items=await pg.eval_on_selector_all(".sb-item","e=>e.length") await pg.screenshot(path="/tmp/l99-post-master.png") await b.close() print(json.dumps({"sidebar":items,"ok":True})) asyncio.run(t())'; $postOut = shell_exec("timeout 20 python3 -c " . escapeshellarg($postPy) . " 2>&1"); $postResult = json_decode($postOut, true) ?: ["ok" => false]; $trace[] = ["step" => "posttest", "lint_errors" => $lintErrors, "visual" => $postResult]; } // STEP 7: COMMIT + PUSH TO ALL REPOS if ($step === "full" || $step === "push") { $msg = $input["commit_msg"] ?? "PIPELINE: auto-commit " . date("Y-m-d H:i"); // Local git $gitResult = shell_exec("cd /var/www/html && git add -A && git commit -m " . escapeshellarg($msg) . " 2>&1"); // GitHub $ghPush = shell_exec("cd /var/www/html && git push github main 2>&1 | tail -1"); // Get commit hash $hash = trim(shell_exec("cd /var/www/html && git rev-parse --short HEAD 2>/dev/null")); $trace[] = ["step" => "push", "hash" => $hash, "github" => strpos($ghPush, "->") !== false ? "OK" : $ghPush]; } // STEP 8: WIKI UPDATE if ($step === "full" || $step === "wiki") { $wiki = [ "title" => "PIPELINE-" . date("Ymd-His"), "date" => date("c"), "task" => $task, "steps" => count($trace), "results" => array_map(function($t){return ["step"=>$t["step"],"ok"=>true];}, $trace), ]; file_put_contents("/opt/weval-l99/wiki/PIPELINE-" . date("Ymd-His") . ".json", json_encode($wiki)); $trace[] = ["step" => "wiki", "entries" => count(glob("/opt/weval-l99/wiki/*.json"))]; } // STEP 9: FINAL STATUS $pipeline = [ "task" => $task, "steps" => count($trace), "trace" => $trace, "status" => "COMPLETE", "timestamp" => date("c"), ]; echo json_encode($pipeline, JSON_UNESCAPED_UNICODE);