[],'crons'=>[],'docker'=>[],'pipelines'=>[],'ports'=>[],'n8n'=>[],'blade'=>[]]; // Paperclip agents $pc=@file_get_contents('http://127.0.0.1:3100/api/companies/dd12987b-c774-45e7-95fd-d34003f91650/agents'); if($pc){$d=json_decode($pc,true);if(is_array($d))foreach($d as $a)$r['agents'][]=['name'=>$a['name']??'?','role'=>$a['role']??'general','status'=>$a['status']??'idle','source'=>'paperclip'];} // Crons www-data $cw=shell_exec('crontab -l 2>/dev/null|grep -v "^#"|grep -v "^$"|head -40'); foreach(explode("\n",trim($cw??''))as$l){if(!trim($l))continue;$p=preg_split('/\s+/',trim($l),6);$r['crons'][]=['sched'=>implode(' ',array_slice($p,0,5)),'cmd'=>substr($p[5]??trim($l),0,80),'srv'=>'S204','type'=>'www-data'];} // Crons cron.d $cd=shell_exec('ls /etc/cron.d/ 2>/dev/null|grep -v certbot|grep -v e2scrub|grep -v php$|grep -v sysstat'); foreach(explode("\n",trim($cd??''))as$f){if(!trim($f))continue;$r['crons'][]=['sched'=>'cron.d','cmd'=>trim($f),'srv'=>'S204','type'=>'cron.d'];} // Docker $dk=shell_exec('docker ps --format "{{.Names}}|{{.Status}}|{{.Ports}}" 2>/dev/null'); foreach(explode("\n",trim($dk??''))as$l){if(!trim($l))continue;$p=explode('|',$l);$r['docker'][]=['name'=>$p[0]??'','status'=>$p[1]??'','ports'=>$p[2]??''];} // Systemd services $sv=shell_exec('systemctl list-units --type=service --state=running --no-pager 2>/dev/null|grep -E "deerflow|sovereign|paperclip|search-proxy|crowdsec|fail2ban|ollama|flowise"|awk "{print \$1}"'); foreach(explode("\n",trim($sv??''))as$s){if(!trim($s))continue;$r['pipelines'][]=['name'=>str_replace('.service','',trim($s)),'type'=>'systemd','status'=>'running'];} // n8n workflows $n8=shell_exec('docker exec n8n n8n list:workflow 2>/dev/null'); foreach(explode("\n",trim($n8??''))as$l){$p=explode('|',$l);if(count($p)>=2)$r['n8n'][]=['id'=>trim($p[0]),'name'=>trim($p[1])];} // n8n active check $na=shell_exec('docker exec n8n n8n list:workflow --active=true 2>/dev/null'); $activeIds=[]; foreach(explode("\n",trim($na??''))as$l){$p=explode('|',$l);if(count($p)>=2)$activeIds[]=trim($p[0]);} foreach($r['n8n'] as &$w)$w['active']=in_array($w['id'],$activeIds); // Flowise chatflows $fl=@file_get_contents('http://127.0.0.1:3033/api/v1/chatflows'); $r['flowise']=[]; if($fl){$fd=json_decode($fl,true);if(is_array($fd))foreach($fd as $c)$r['flowise'][]=['name'=>$c['name']??'?','id'=>$c['id']??''];} // DeerFlow $r['deerflow']=['status'=>trim(shell_exec('systemctl is-active deerflow 2>/dev/null')?:'unknown'),'skills'=>intval(shell_exec('ls /opt/deer-flow/skills/ 2>/dev/null|wc -l')),'web'=>trim(shell_exec('systemctl is-active deerflow-web 2>/dev/null')?:'unknown')]; // Sovereign $sv2=@file_get_contents('http://127.0.0.1:4000/health'); $r['sovereign']=json_decode($sv2,true)?:['status'=>'unknown']; // Ollama $ol=@file_get_contents('http://127.0.0.1:11434/api/tags'); $od=json_decode($ol,true); $r['ollama']=['models'=>count($od['models']??[]),'names'=>array_map(function($m){return $m['name'];},$od['models']??[])]; // Ports $r['ports']=['S204'=>[25,80,443,2024,2026,3000,3001,3002,3003,3033,3050,3100,4000,5001,5432,5433,5434,5678,6060,6333,6334,6379,6380,8000,8001,8065,8080,8123,8222,8280,8281,8443,8888,9000,9004,9005,9009,9300,9443,11434,18821],'S95'=>[25,587,2525,2526,5432,5433,5821,5822,5823,5824,5825,5826,5850,5880,5888,5890,5899,6060,8010,8080,8443,9000,11434,18821,49222]]; // Blade heartbeat $hb=json_decode(@file_get_contents('/var/www/html/api/blade-tasks/heartbeat.json'),true); $r['blade']=$hb?:['ts'=>'unknown']; echo json_encode(['ok'=>true]+$r+['totals'=>[ 'agents'=>count($r['agents']), 'crons'=>count($r['crons']), 'docker'=>count($r['docker']), 'pipelines'=>count($r['pipelines']), 'n8n'=>count($r['n8n']), 'flowise'=>count($r['flowise']), 'ports_total'=>count($r['ports']['S204'])+count($r['ports']['S95']), 'ollama_models'=>$r['ollama']['models'] ],'synced_at'=>date('Y-m-d H:i:s')],JSON_PRETTY_PRINT);