diff --git a/api/endpoints/arc.php b/api/endpoints/arc.php new file mode 100644 index 0000000..9afe6fc --- /dev/null +++ b/api/endpoints/arc.php @@ -0,0 +1,108 @@ + true, + CURLOPT_TIMEOUT => ARC_TIMEOUT, + CURLOPT_CONNECTTIMEOUT => 3, + CURLOPT_HTTPHEADER => ['Content-Type: application/json'], + ]); + if ($method === 'POST') { + curl_setopt($ch, CURLOPT_POST, true); + curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); + } elseif ($method === 'DELETE') { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); + } + $raw = curl_exec($ch); + $code = curl_getinfo($ch, CURLINFO_HTTP_CODE); + $err = curl_error($ch); + curl_close($ch); + + if ($err || $raw === false) { + return ['error' => 'Arc Reactor unreachable: ' . $err, 'online' => false]; + } + $decoded = json_decode($raw, true); + return $decoded ?? ['error' => 'Invalid response from Arc Reactor', 'raw' => substr($raw, 0, 200)]; +} + +// ── ROUTING ─────────────────────────────────────────────────────────────────── +// arc action comes from query string or POST body (not the URL path segment) +global $data; +$action = $_GET['action'] ?? $data['action'] ?? ''; + +switch ($action) { + + // GET /api/arc?action=status + case 'status': + $result = arc_request('GET', '/status'); + if (!isset($result['online'])) $result['online'] = false; + echo json_encode($result); + break; + + // POST /api/arc — create a job + // body: { action: "job_create", type: "ping", payload: {}, priority: 5 } + case 'job_create': + $type = $data['type'] ?? ''; + $payload = $data['payload'] ?? []; + $priority = (int)($data['priority'] ?? 5); + if (!$type) { http_response_code(400); echo json_encode(['error' => 'Missing job type']); break; } + $result = arc_request('POST', '/job', [ + 'type' => $type, + 'payload' => $payload, + 'priority' => $priority, + 'created_by' => 'jarvis_ui', + ]); + echo json_encode($result); + break; + + // GET /api/arc?action=job_get&id=123 + case 'job_get': + $id = (int)($data['id'] ?? $_GET['id'] ?? 0); + if (!$id) { http_response_code(400); echo json_encode(['error' => 'Missing job id']); break; } + echo json_encode(arc_request('GET', "/job/{$id}")); + break; + + // GET /api/arc?action=jobs&status=done&limit=20 + case 'jobs': + $status = $_GET['status'] ?? $data['status'] ?? ''; + $limit = (int)($_GET['limit'] ?? $data['limit'] ?? 50); + $qs = http_build_query(array_filter(['status' => $status, 'limit' => $limit])); + echo json_encode(arc_request('GET', '/jobs' . ($qs ? "?{$qs}" : ''))); + break; + + // DELETE /api/arc?action=job_cancel&id=123 + case 'job_cancel': + $id = (int)($data['id'] ?? $_GET['id'] ?? 0); + if (!$id) { http_response_code(400); echo json_encode(['error' => 'Missing job id']); break; } + echo json_encode(arc_request('DELETE', "/job/{$id}")); + break; + + // DELETE /api/arc?action=purge + case 'purge': + echo json_encode(arc_request('DELETE', '/jobs/purge')); + break; + + // Quick ping test + case 'ping': + $result = arc_request('POST', '/job', [ + 'type' => 'ping', + 'payload' => [], + 'priority' => 9, + 'created_by' => 'jarvis_ping', + ]); + echo json_encode($result); + break; + + default: + http_response_code(404); + echo json_encode(['error' => "Unknown arc action: {$action}"]); +} diff --git a/public_html/admin/index.php b/public_html/admin/index.php index 3b13a0d..c44b353 100644 --- a/public_html/admin/index.php +++ b/public_html/admin/index.php @@ -459,6 +459,45 @@ if ($action) { $r = runSync(); j(['ok'=>true,'results'=>$r]); + + // ── ARC REACTOR ────────────────────────────────────────────────────── + case 'arc_status': + $ch = curl_init('http://127.0.0.1:7474/status'); + curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5, CURLOPT_CONNECTTIMEOUT=>3]); + $raw = curl_exec($ch); $err = curl_error($ch); curl_close($ch); + if ($err || !$raw) j(['online'=>false, 'error'=>$err ?: 'unreachable']); + j(json_decode($raw, true) ?: ['online'=>false, 'error'=>'bad response']); + + case 'arc_jobs': + $status = $_GET['status'] ?? ''; + $limit = (int)($_GET['limit'] ?? 100); + $url = 'http://127.0.0.1:7474/jobs?' . http_build_query(array_filter(['status'=>$status,'limit'=>$limit])); + $ch = curl_init($url); + curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5]); + $raw = curl_exec($ch); curl_close($ch); + j(json_decode($raw, true) ?: []); + + case 'arc_job_get': + $id = (int)($_GET['id'] ?? 0); if (!$id) bad('Missing id'); + $ch = curl_init('http://127.0.0.1:7474/job/' . $id); + curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5]); + $raw = curl_exec($ch); curl_close($ch); + j(json_decode($raw, true) ?: ['error'=>'not found']); + + case 'arc_ping': + $ch = curl_init('http://127.0.0.1:7474/job'); + curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5, CURLOPT_POST=>true, + CURLOPT_POSTFIELDS=>json_encode(['type'=>'ping','payload'=>[],'priority'=>9,'created_by'=>'admin']), + CURLOPT_HTTPHEADER=>['Content-Type: application/json']]); + $raw = curl_exec($ch); curl_close($ch); + j(json_decode($raw, true) ?: ['error'=>'failed']); + + case 'arc_purge': + $ch = curl_init('http://127.0.0.1:7474/jobs/purge'); + curl_setopt_array($ch, [CURLOPT_RETURNTRANSFER=>true, CURLOPT_TIMEOUT=>5, CURLOPT_CUSTOMREQUEST=>'DELETE']); + $raw = curl_exec($ch); curl_close($ch); + j(json_decode($raw, true) ?: ['ok'=>true]); + case 'users_list': j(JarvisDB::query('SELECT id,username,display_name,last_seen,created_at FROM users ORDER BY username')); @@ -695,6 +734,8 @@ select.filter-sel:focus{border-color:var(--cyan)}
+ + @@ -943,6 +984,54 @@ select.filter-sel:focus{border-color:var(--cyan)}