mirror of
https://github.com/myronblair/jarvis
synced 2026-06-30 17:50:23 -05:00
feat: Phase 1 — Arc Reactor Core Daemon
- Python asyncio daemon (/opt/jarvis-arc/reactor.py) running on 127.0.0.1:7474 - systemd service (jarvis-arc) auto-starts with MySQL dependency - arc_jobs + arc_status MySQL tables for async job queue - api/endpoints/arc.php: PHP bridge to daemon (status, job_create, job_get, jobs, purge) - api.php: added arc route - index.html: ARC REACTOR status indicator in bottom bar with live polling - admin/index.php: ARC REACTOR nav section + full job management panel - Built-in job handlers: ping, echo, shell (whitelist-gated) - Foundation for Phase 2 (Intel Protocol) and beyond Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -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)}
|
||||
<div class="nav-item" data-tab="tasks" onclick="nav(this)">📋 TASKS</div>
|
||||
<div class="nav-item" data-tab="appointments" onclick="nav(this)">📅 APPOINTMENTS</div>
|
||||
<div class="nav-item" data-tab="calendar" onclick="nav(this)">🗓 CALENDAR SYNC</div>
|
||||
<div class="nav-section">ARC REACTOR</div>
|
||||
<div class="nav-item" data-tab="arc" onclick="nav(this)">⚡ ARC REACTOR</div>
|
||||
<div class="nav-section">INFO</div>
|
||||
<div class="nav-item" data-tab="sites" onclick="nav(this)">SITES</div>
|
||||
<div class="nav-item" data-tab="users" onclick="nav(this)">USERS</div>
|
||||
@@ -943,6 +984,54 @@ select.filter-sel:focus{border-color:var(--cyan)}
|
||||
<div class="tbl-wrap" id="users-tbl"><div class="loading">SCANNING...</div></div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- ARC REACTOR -->
|
||||
<div class="tab" id="tab-arc">
|
||||
<div class="page-title">⚡ ARC REACTOR — CORE DAEMON</div>
|
||||
<div id="arc-status-bar" style="display:flex;gap:12px;margin-bottom:16px;flex-wrap:wrap">
|
||||
<div class="stat-box" style="background:rgba(0,212,255,0.06);border:1px solid var(--border);padding:12px 20px;border-radius:4px;min-width:130px">
|
||||
<div style="font-size:0.55rem;letter-spacing:2px;color:var(--dim);margin-bottom:4px">STATUS</div>
|
||||
<div id="arc-status-val" style="font-size:1.1rem;font-family:var(--mono);color:var(--green)">CHECKING...</div>
|
||||
</div>
|
||||
<div class="stat-box" style="background:rgba(0,212,255,0.06);border:1px solid var(--border);padding:12px 20px;border-radius:4px;min-width:130px">
|
||||
<div style="font-size:0.55rem;letter-spacing:2px;color:var(--dim);margin-bottom:4px">VERSION</div>
|
||||
<div id="arc-version-val" style="font-size:1.1rem;font-family:var(--mono)">—</div>
|
||||
</div>
|
||||
<div class="stat-box" style="background:rgba(0,212,255,0.06);border:1px solid var(--border);padding:12px 20px;border-radius:4px;min-width:130px">
|
||||
<div style="font-size:0.55rem;letter-spacing:2px;color:var(--dim);margin-bottom:4px">JOBS DONE</div>
|
||||
<div id="arc-done-val" style="font-size:1.1rem;font-family:var(--mono)">—</div>
|
||||
</div>
|
||||
<div class="stat-box" style="background:rgba(0,212,255,0.06);border:1px solid var(--border);padding:12px 20px;border-radius:4px;min-width:130px">
|
||||
<div style="font-size:0.55rem;letter-spacing:2px;color:var(--dim);margin-bottom:4px">FAILED</div>
|
||||
<div id="arc-fail-val" style="font-size:1.1rem;font-family:var(--mono)">—</div>
|
||||
</div>
|
||||
<div class="stat-box" style="background:rgba(0,212,255,0.06);border:1px solid var(--border);padding:12px 20px;border-radius:4px;min-width:130px">
|
||||
<div style="font-size:0.55rem;letter-spacing:2px;color:var(--dim);margin-bottom:4px">HEARTBEAT</div>
|
||||
<div id="arc-hb-val" style="font-size:0.75rem;font-family:var(--mono)">—</div>
|
||||
</div>
|
||||
<div class="stat-box" style="background:rgba(0,212,255,0.06);border:1px solid var(--border);padding:12px 20px;border-radius:4px;min-width:130px">
|
||||
<div style="font-size:0.55rem;letter-spacing:2px;color:var(--dim);margin-bottom:4px">CAPABILITIES</div>
|
||||
<div id="arc-caps-val" style="font-size:0.65rem;font-family:var(--mono)">—</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div style="display:flex;gap:10px;margin-bottom:16px;align-items:center;flex-wrap:wrap">
|
||||
<button class="btn btn-sm" onclick="loadArc()">↻ REFRESH</button>
|
||||
<button class="btn btn-sm btn-green" onclick="arcTestPing()">PING TEST</button>
|
||||
<button class="btn btn-sm" onclick="arcPurge()" style="margin-left:auto;opacity:0.7">PURGE OLD JOBS</button>
|
||||
<select id="arc-job-filter" class="inp" style="width:auto;padding:4px 8px;font-size:0.65rem" onchange="loadArc()">
|
||||
<option value="">ALL JOBS</option>
|
||||
<option value="queued">QUEUED</option>
|
||||
<option value="running">RUNNING</option>
|
||||
<option value="done">DONE</option>
|
||||
<option value="failed">FAILED</option>
|
||||
<option value="cancelled">CANCELLED</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div class="tbl-wrap" id="arc-jobs-tbl"><div class="loading">INITIALIZING...</div></div>
|
||||
</div>
|
||||
|
||||
</div><!-- /content -->
|
||||
</div><!-- /main -->
|
||||
</div><!-- /app -->
|
||||
|
||||
Reference in New Issue
Block a user