date('c'), 'source'=>'opus5-registry']; $refresh = !empty($_GET['refresh']); $detail = !empty($_GET['detail']); // Try Redis cache first $redis = null; $CACHE_KEY = 'wevia:opus5-registry:' . ($detail ? 'detail' : 'lite'); try { $redis = new Redis(); if (!$redis->connect('127.0.0.1', 6379, 0.3)) { $redis = null; } } catch (Throwable $e) { $redis = null; } if (!$refresh && $redis) { $cached = $redis->get($CACHE_KEY); if ($cached) { $R = json_decode($cached, true); $R['cache'] = 'HIT'; $R['served_at'] = date('c'); if ($redis) $redis->close(); echo json_encode($R, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE); exit; } } $R['cache'] = 'MISS'; $files = glob('/var/www/html/api/opus5-*.php') ?: []; $endpoints = []; foreach ($files as $f) { $name = basename($f, '.php'); $ep = [ 'name' => $name, 'url' => "/api/$name.php", 'size_bytes' => @filesize($f), 'mtime' => date('c', @filemtime($f)) ]; if ($detail) { // Only parse first 2KB for speed $handle = @fopen($f, 'r'); if ($handle) { $head = @fread($handle, 2048); @fclose($handle); if (preg_match('/\/\/\s*OPUS5\s*[-\xe2][-\s]*(.+?)(?:\n|\r)/u', $head, $m)) { $ep['description'] = trim($m[1]); } if (preg_match('/doctrine\s*(\d+)/i', $head, $m)) { $ep['doctrine'] = (int)$m[1]; } } } $endpoints[] = $ep; } if ($detail) { usort($endpoints, function($a, $b) { $da = $a['doctrine'] ?? 999; $db = $b['doctrine'] ?? 999; if ($da !== $db) return $da - $db; return strcmp($a['name'], $b['name']); }); } $R['count'] = count($endpoints); $R['endpoints'] = $endpoints; // Wired intents $wired = glob('/var/www/html/api/wired-pending/intent-opus4-*.php') ?: []; $R['wired_intents_count'] = count($wired); $R['wired_intents'] = array_map(function($f){ return str_replace(['intent-opus4-', '.php'], '', basename($f)); }, $wired); $R['doctrine'] = '82 — opus5 registry (factual list, Redis cached 1h)'; // Cache for 1h if ($redis) { try { $redis->setex($CACHE_KEY, 3600, json_encode($R, JSON_UNESCAPED_UNICODE)); } catch (Throwable $e) {} $redis->close(); } echo json_encode($R, JSON_PRETTY_PRINT|JSON_UNESCAPED_UNICODE);