[], 'ok'=>false]; $SRC = '/var/www/weval/wevia-ia/weval-chatbot-api.php'; $MARKER = 'OPUS4-AUTOWIRE-CHATBOT-v1'; $TS = date('Ymd-Hi'); $content = file_get_contents($SRC); $R['steps'][] = ['read' => strlen($content).'B']; if (strpos($content, $MARKER) !== false) { $R['ok'] = true; $R['steps'][] = ['already_applied' => true]; die(json_encode($R, JSON_PRETTY_PRINT)); } // GOLD $GOLD = "/opt/wevads/vault/weval-chatbot-api-CHATBOT-{$TS}.gold.php"; copy($SRC, $GOLD); $R['steps'][] = ['gold' => $GOLD, 'size' => filesize($GOLD)]; // Anchor : juste avant "if(($_SERVER[\"REQUEST_METHOD\"]" (ligne 54) $anchor = 'if(($_SERVER["REQUEST_METHOD"] ?? "") === "GET"'; $pos = strpos($content, $anchor); if ($pos === false) { $R['steps'][] = ['err' => 'anchor not found']; die(json_encode($R)); } // Injection via heredoc-like — double quote safe $INJECT = ' // === OPUS4-AUTOWIRE-CHATBOT-v1 (17avr 02h35) === // Cause racine: /api/weval-ia proxie vers ce fichier, qui bypass wevia-master-api. // Ce handler capture master add/list intent en priorite absolue AVANT tout LLM call. // Zero regression: return silencieux si syntaxe pas matchee. if ($_SERVER["REQUEST_METHOD"] === "POST") { $__opus4_raw = $GLOBALS["_wevia_raw"] ?? file_get_contents("php://input"); $__opus4_in = @json_decode($__opus4_raw, true) ?: []; $__opus4_msg = mb_strtolower(trim($__opus4_in["message"] ?? ($_POST["message"] ?? ""))); if ($__opus4_msg) { if (preg_match("/^\s*master\s+add\s+intent\s+([a-z0-9_]+)\s*::\s*(.+?)\s*::\s*(.+)$/i", $__opus4_msg, $__m4)) { $__n = trim($__m4[1]); $__t = trim($__m4[2]); $__c = trim($__m4[3]); $__pd = "/var/www/html/api/wired-pending"; @mkdir($__pd, 0755, true); $__stub = "$__pd/intent-opus4-$__n.php"; $__ok4 = false; foreach (["/var/www/html/","/var/www/weval/","/opt/wevia-brain/","/opt/wevads/vault/","echo ","curl ","php8.4 ","git "] as $__p4) { if (strpos($__c, $__p4) !== false) { $__ok4 = true; break; } } $__pl = ["name"=>$__n, "triggers"=>array_map("trim", explode("|", $__t)), "cmd"=>$__c, "status"=>$__ok4?"PENDING_APPROVAL":"PENDING_SECURITY_REVIEW", "created_at"=>date("c"), "source"=>"opus4-chatbot-v1"]; @file_put_contents($__stub, ""Intent \'$__n\' wired (status={$__pl["status"]}). Triggers: " . implode(", ", $__pl["triggers"]) . ". Cmd: " . substr($__c, 0, 80), "executed"=>true, "provider"=>"opus4-autowire-chatbot", "intent"=>$__n, "status"=>$__pl["status"]]); exit; } if (preg_match("/^\s*master\s+(list|show)\s+intents?\s*$/i", $__opus4_msg)) { $__stubs4 = @glob("/var/www/html/api/wired-pending/intent-opus4-*.php") ?: []; $__sum4 = []; foreach ($__stubs4 as $__s4) { $__info4 = @include $__s4; if (is_array($__info4)) $__sum4[] = ["name"=>$__info4["name"] ?? "?", "status"=>$__info4["status"] ?? "?", "triggers"=>$__info4["triggers"] ?? []]; } header("Content-Type: application/json"); echo json_encode(["response"=>"Wired opus4 intents: " . count($__stubs4) . "\n" . json_encode($__sum4, JSON_PRETTY_PRINT), "executed"=>true, "provider"=>"opus4-autowire-chatbot-list", "count"=>count($__stubs4)]); exit; } } } // === OPUS4-AUTOWIRE-CHATBOT-v1 END === '; $newContent = substr($content, 0, $pos) . $INJECT . substr($content, $pos); $R['steps'][] = ['inject_at' => $pos, 'before' => strlen($content), 'after' => strlen($newContent)]; // Lint temp $TMP = "/tmp/wc-test-{$TS}.php"; file_put_contents($TMP, $newContent); exec("php8.4 -l $TMP 2>&1", $lo, $lr); $R['steps'][] = ['lint_rc' => $lr, 'lint' => $lo]; if ($lr !== 0) { unlink($TMP); $R['steps'][] = ['err' => 'LINT FAIL']; die(json_encode($R, JSON_PRETTY_PRINT)); } // Test regex locale exec('php8.4 -r "if(preg_match(\"/^\\s*master\\s+add\\s+intent/i\", \"master add intent x :: a :: echo b\")) echo \"RX_OK\";"', $rt); $R['steps'][] = ['regex_local_test' => $rt]; // Write exec('sudo chattr -i '.escapeshellarg($SRC).' 2>&1', $c1, $rc1); if ($rc1 !== 0) exec('chattr -i '.escapeshellarg($SRC).' 2>&1', $c1, $rc1); $R['steps'][] = ['chattr_minus' => $rc1]; $w = file_put_contents($SRC, $newContent); $R['steps'][] = ['written' => $w]; exec('sudo chattr +i '.escapeshellarg($SRC).' 2>&1', $c2, $rc2); if ($rc2 !== 0) exec('chattr +i '.escapeshellarg($SRC).' 2>&1', $c2, $rc2); $R['steps'][] = ['chattr_plus' => $rc2]; // Final lint exec("php8.4 -l $SRC 2>&1", $flo, $flr); $R['steps'][] = ['final_lint_rc' => $flr, 'final_lint' => $flo]; $final = file_get_contents($SRC); $R['steps'][] = ['marker_present' => (strpos($final, $MARKER) !== false)]; // Opcache flush ciblé @opcache_invalidate($SRC, true); @opcache_invalidate('/var/www/html/api/weval-ia.php', true); @opcache_reset(); unlink($TMP); $R['ok'] = ($flr === 0 && strpos($final, $MARKER) !== false && $w > 300000); echo json_encode($R, JSON_PRETTY_PRINT);