SIMON Master Console Rebuild
True command center for SIMON + WEB360
This rebuild gives you a cleaner production spine: interactive tree, live viewer, guarded editor, dynamic graphics, architecture map, and note storage. It is designed to sit beside your existing
console.php
and become the stronger replacement path.
Dashboard
Tree
Viewer
System Map
File Registry
Notes
Files
15,026
Folders
377
Scanned Size
3.79 GB
PHP Files
791
Editable Text Files
12,310
File viewer
guarded to /htdocs
/admin/SIMON INTELL.html
<?php declare(strict_types=1); /** * SIMON Intelligence - Master Control Panel * File: /htdocs/simon/master_control_panel.php */ error_reporting(E_ALL); ini_set('display_errors', '0'); date_default_timezone_set('America/Chicago'); $baseDir = __DIR__; $dataDir = $baseDir . '/data'; $configDir = $baseDir . '/config'; $apiDir = $baseDir . '/api'; $memoryFile = $dataDir . '/memory.json'; $logsFile = $dataDir . '/logs.json'; $settingsFile = $configDir . '/settings.php'; $secretsFile = $configDir . '/secrets.php'; $statusEndpoint = $apiDir . '/simon_status.php'; function h(?string $value): string { return htmlspecialchars((string)$value, ENT_QUOTES, 'UTF-8'); } function formatBytes(int $bytes): string { if ($bytes < 1024) return $bytes . ' B'; $units = ['KB', 'MB', 'GB', 'TB']; $i = -1; do { $bytes /= 1024; $i++; } while ($bytes >= 1024 && $i < count($units) - 1); return round($bytes, 2) . ' ' . $units[$i]; } function readJsonFile(string $file): array { if (!is_file($file) || !is_readable($file)) { return []; } $raw = @file_get_contents($file); if ($raw === false || trim($raw) === '') { return []; } $decoded = json_decode($raw, true); return is_array($decoded) ? $decoded : []; } function fileHealth(string $file): array { return [ 'exists' => is_file($file), 'readable' => is_readable($file), 'writable' => is_writable($file), 'size' => is_file($file) ? filesize($file) : 0, 'modified_at' => is_file($file) ? filemtime($file) : null, 'path' => $file, ]; } function endpointHealth(string $file): array { if (!is_file($file)) { return [ 'exists' => false, 'status' => 'missing', 'message' => 'Endpoint file not found', ]; } return [ 'exists' => true, 'status' => 'present', 'message' => 'Endpoint file exists', ]; } function detectProviders(string $settingsFile, string $secretsFile): array { $providers = [ 'OpenAI' => ['enabled' => false, 'reason' => 'No key detected'], 'Claude' => ['enabled' => false, 'reason' => 'No key detected'], 'Grok' => ['enabled' => false, 'reason' => 'No key detected'], 'Gemini' => ['enabled' => false, 'reason' => 'No key detected'], ]; $combined = ''; foreach ([$settingsFile, $secretsFile] as $file) { if (is_file($file) && is_readable($file)) { $combined .= "\n" . (string)@file_get_contents($file); } } $checks = [ 'OpenAI' => ['OPENAI', 'openai', 'sk-'], 'Claude' => ['ANTHROPIC', 'anthropic', 'claude'], 'Grok' => ['XAI', 'xai', 'grok'], 'Gemini' => ['GEMINI', 'google', 'generativeai'], ]; foreach ($checks as $name => $needles) { foreach ($needles as $needle) { if (stripos($combined, $needle) !== false) { $providers[$name]['enabled'] = true; $providers[$name]['reason'] = 'Configuration markers detected'; break; } } } return $providers; } function latestEntries(array $data, int $limit = 10): array { if (!is_array($data)) return []; return array_slice(array_reverse($data), 0, $limit); } function normalizeLogEntries(array $logs): array { $normalized = []; foreach ($logs as $entry) { if (is_string($entry)) { $normalized[] = [ 'time' => '', 'type' => 'log', 'message' => $entry, ]; continue; } if (is_array($entry)) { $normalized[] = [ 'time' => (string)($entry['time'] ?? $entry['timestamp'] ?? $entry['created_at'] ?? ''), 'type' => (string)($entry['type'] ?? $entry['level'] ?? 'log'), 'message' => (string)($entry['message'] ?? $entry['event'] ?? json_encode($entry)), ]; } } return $normalized; } function normalizeMemoryEntries(array $memory): array { $normalized = []; foreach ($memory as $entry) { if (is_string($entry)) { $normalized[] = [ 'title' => 'Memory', 'content' => $entry, 'time' => '', ]; continue; } if (is_array($entry)) { $normalized[] = [ 'title' => (string)($entry['title'] ?? $entry['key'] ?? $entry['topic'] ?? 'Memory'), 'content' => (string)($entry['content'] ?? $entry['value'] ?? $entry['memory'] ?? json_encode($entry)), 'time' => (string)($entry['time'] ?? $entry['timestamp'] ?? $entry['created_at'] ?? ''), ]; } } return $normalized; } $memoryHealth = fileHealth($memoryFile); $logsHealth = fileHealth($logsFile); $settingsHealth = fileHealth($settingsFile); $secretsHealth = fileHealth($secretsFile); $statusHealth = endpointHealth($statusEndpoint); $memoryData = readJsonFile($memoryFile); $logsData = readJsonFile($logsFile); $memoryEntries = latestEntries(normalizeMemoryEntries($memoryData), 12); $logEntries = latestEntries(normalizeLogEntries($logsData), 20); $providers = detectProviders($settingsFile, $secretsFile); $coreFiles = [ 'simon_core.php', 'simon_brain.php', 'simon_router.php', 'simon_memory.php', 'simon_security.php', 'simon_5w1h.php', 'simon_helpers.php', 'index.php', 'console.php', ]; $coreHealth = []; foreach ($coreFiles as $file) { $coreHealth[$file] = fileHealth($baseDir . '/' . $file); } $totalCoreFiles = count($coreHealth); $healthyCoreFiles = count(array_filter($coreHealth, fn($f) => $f['exists'] && $f['readable'])); $memoryCount = count($memoryData); $logsCount = count($logsData); $overallScore = 0; $checks = [ $memoryHealth['exists'] && $memoryHealth['readable'], $logsHealth['exists'] && $logsHealth['readable'], $settingsHealth['exists'] && $settingsHealth['readable'], $secretsHealth['exists'] && $secretsHealth['readable'], $statusHealth['exists'], $healthyCoreFiles >= max(1, $totalCoreFiles - 1), ]; foreach ($checks as $check) { if ($check) $overallScore++; } $overallPercent = (int)round(($overallScore / count($checks)) * 100); $systemState = 'DEGRADED'; if ($overallPercent >= 90) { $systemState = 'OPTIMAL'; } elseif ($overallPercent >= 70) { $systemState = 'STABLE'; } $action = $_GET['action'] ?? ''; $actionMessage = ''; if ($action === 'ping') { $actionMessage = 'SIMON control panel ping completed successfully.'; } if ($action === 'refresh') { $actionMessage = 'System refresh requested. Reloaded live file state.'; } ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"> <title>SIMON Intelligence — Master Control Panel</title> <meta name="description" content="SIMON Intelligence master control panel for monitoring memory, logs, providers, endpoints, and system health."> <style> :root{ --bg:#050816; --bg2:#081225; --panel:rgba(10,18,38,.72); --panel-solid:#0d1630; --line:rgba(123,173,255,.18); --text:#edf4ff; --muted:#98a8c7; --cyan:#72e6ff; --blue:#61a8ff; --violet:#8d77ff; --green:#51f0a8; --amber:#ffca6a; --red:#ff7676; --shadow:0 20px 60px rgba(0,0,0,.45); --radius:22px; } *{box-sizing:border-box} html,body{margin:0;padding:0;background: radial-gradient(circle at top, rgba(86,140,255,.16), transparent 30%), radial-gradient(circle at 80% 20%, rgba(141,119,255,.14), transparent 25%), linear-gradient(180deg,var(--bg),var(--bg2)); color:var(--text); font-family:Inter,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Arial,sans-serif; min-height:100%; } body{ overflow-x:hidden; } body::before{ content:""; position:fixed; inset:0; pointer-events:none; background-image: linear-gradient(rgba(255,255,255,.03) 1px, transparent 1px), linear-gradient(90deg, rgba(255,255,255,.03) 1px, transparent 1px); background-size:40px 40px; mask-image:linear-gradient(to bottom, rgba(255,255,255,.55), rgba(255,255,255,.08)); } .wrap{ width:min(1500px, calc(100% - 32px)); margin:28px auto 80px; } .topbar{ display:flex; gap:18px; align-items:center; justify-content:space-between; flex-wrap:wrap; margin-bottom:22px; } .brand{ display:flex; align-items:center; gap:18px; } .orb{ width:74px;height:74px;border-radius:50%; position:relative; background: radial-gradient(circle at 35% 30%, rgba(255,255,255,.95), rgba(114,230,255,.55) 18%, rgba(97,168,255,.28) 38%, rgba(141,119,255,.14) 55%, rgba(0,0,0,0) 70%), radial-gradient(circle at 50% 50%, rgba(114,230,255,.25), rgba(0,0,0,0) 70%); box-shadow: 0 0 20px rgba(114,230,255,.35), 0 0 60px rgba(97,168,255,.25), inset 0 0 30px rgba(255,255,255,.12); animation:pulse 5s ease-in-out infinite; } .orb::before,.orb::after{ content:""; position:absolute; inset:-10px; border-radius:50%; border:1px solid rgba(114,230,255,.22); animation:spin 9s linear infinite; } .orb::after{ inset:-18px; border-color:rgba(141,119,255,.18); animation-direction:reverse; animation-duration:13s; } @keyframes spin { to { transform:rotate(360deg);} } @keyframes pulse { 0%,100%{ transform:scale(1); filter:brightness(1); } 50%{ transform:scale(1.05); filter:brightness(1.18); } } .title h1{ margin:0; font-size:clamp(1.5rem,2vw,2.4rem); letter-spacing:.03em; } .title p{ margin:6px 0 0; color:var(--muted); font-size:.96rem; } .status-pill{ display:inline-flex; align-items:center; gap:10px; padding:12px 16px; border:1px solid var(--line); background:rgba(255,255,255,.04); border-radius:999px; box-shadow:var(--shadow); font-weight:700; } .dot{ width:10px;height:10px;border-radius:50%; background:var(--green); box-shadow:0 0 18px currentColor; } .dot.warn{ background:var(--amber); } .dot.bad{ background:var(--red); } .actions{ display:flex; gap:10px; flex-wrap:wrap; } .btn{ display:inline-flex; align-items:center; justify-content:center; gap:8px; text-decoration:none; color:var(--text); padding:12px 16px; border-radius:14px; border:1px solid var(--line); background:linear-gradient(180deg, rgba(255,255,255,.08), rgba(255,255,255,.03)); transition:.2s ease; box-shadow:var(--shadow); } .btn:hover{ transform:translateY(-1px); border-color:rgba(114,230,255,.35); } .notice{ margin:18px 0 0; padding:14px 16px; border:1px solid rgba(114,230,255,.2); background:rgba(114,230,255,.07); border-radius:16px; color:#dff8ff; } .grid{ display:grid; grid-template-columns:repeat(12,1fr); gap:18px; margin-top:22px; } .card{ background:linear-gradient(180deg, rgba(12,23,46,.78), rgba(8,15,29,.82)); border:1px solid var(--line); border-radius:var(--radius); box-shadow:var(--shadow); overflow:hidden; position:relative; } .card::before{ content:""; position:absolute; inset:0 auto auto 0; width:100%; height:1px; background:linear-gradient(90deg, rgba(114,230,255,.0), rgba(114,230,255,.55), rgba(114,230,255,.0)); } .card-head{ padding:18px 20px 10px; display:flex; align-items:center; justify-content:space-between; gap:12px; } .card-head h2{ margin:0; font-size:1rem; letter-spacing:.04em; } .card-head span{ color:var(--muted); font-size:.86rem; } .card-body{ padding:0 20px 20px; } .span-12{grid-column:span 12} .span-8{grid-column:span 8} .span-6{grid-column:span 6} .span-4{grid-column:span 4} .span-3{grid-column:span 3} @media (max-width:1100px){ .span-8,.span-6,.span-4,.span-3{grid-column:span 12} } .stats{ display:grid; grid-template-columns:repeat(4,1fr); gap:14px; } @media (max-width:900px){ .stats{grid-template-columns:repeat(2,1fr);} } @media (max-width:560px){ .stats{grid-template-columns:1fr;} } .stat{ padding:18px; border-radius:18px; background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.06); } .stat .k{ color:var(--muted); font-size:.84rem; margin-bottom:10px; } .stat .v{ font-size:1.7rem; font-weight:800; } .progress{ height:12px; border-radius:999px; background:rgba(255,255,255,.08); overflow:hidden; margin-top:12px; } .progress > i{ display:block; height:100%; width:<?= (int)$overallPercent ?>%; background:linear-gradient(90deg, var(--cyan), var(--blue), var(--violet)); border-radius:999px; } .table{ width:100%; border-collapse:collapse; } .table th,.table td{ text-align:left; padding:12px 10px; border-bottom:1px solid rgba(255,255,255,.07); vertical-align:top; font-size:.93rem; } .table th{ color:#d9e7ff; font-weight:700; } .table td{ color:var(--muted); } .badge{ display:inline-flex; align-items:center; gap:8px; padding:7px 10px; border-radius:999px; font-size:.78rem; font-weight:700; border:1px solid rgba(255,255,255,.08); } .badge.good{ color:#dfffee; background:rgba(81,240,168,.1); } .badge.warn{ color:#fff2d6; background:rgba(255,202,106,.12); } .badge.bad{ color:#ffe2e2; background:rgba(255,118,118,.12); } .list{ display:grid; gap:12px; } .item{ padding:14px; border-radius:16px; background:rgba(255,255,255,.03); border:1px solid rgba(255,255,255,.06); } .item h3{ margin:0 0 8px; font-size:.96rem; } .item p{ margin:0; color:var(--muted); line-height:1.45; word-break:break-word; } .item .meta{ margin-top:8px; color:#bad0f5; font-size:.8rem; } .switches{ display:grid; gap:12px; } .switch{ display:flex; align-items:center; justify-content:space-between; gap:14px; padding:16px; border-radius:16px; background:rgba(255,255,255,.04); border:1px solid rgba(255,255,255,.06); } .switch .left strong{ display:block; margin-bottom:6px; } .switch .left small{ color:var(--muted); } .toggle{ width:62px; height:34px; border-radius:999px; position:relative; background:rgba(255,255,255,.12); border:1px solid rgba(255,255,255,.08); } .toggle::after{ content:""; position:absolute; top:4px; left:4px; width:24px; height:24px; border-radius:50%; background:#fff; transition:.25s ease; } .toggle.on{ background:linear-gradient(90deg, rgba(81,240,168,.45), rgba(114,230,255,.45)); } .toggle.on::after{ left:32px; } .foot{ margin-top:26px; text-align:center; color:var(--muted); font-size:.85rem; } .path{ font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace; color:#d5e7ff; font-size:.85rem; } </style> </head> <body> <div class="wrap"> <div class="topbar"> <div class="brand"> <div class="orb"></div> <div class="title"> <h1>SIMON Intelligence — Master Control Panel</h1> <p>Live system oversight for core engine health, memory, logs, providers, and API readiness.</p> </div> </div> <div class="status-pill"> <?php $dotClass = 'dot bad'; if ($systemState === 'OPTIMAL') $dotClass = 'dot'; elseif ($systemState === 'STABLE') $dotClass = 'dot warn'; ?> <span class="<?= $dotClass ?>"></span> <span><?= h($systemState) ?> · <?= (int)$overallPercent ?>% integrity</span> </div> </div> <div class="actions"> <a class="btn" href="?action=refresh">↻ Refresh State</a> <a class="btn" href="?action=ping">⟡ Ping SIMON</a> <a class="btn" href="console.php">📊 Open Console</a> <a class="btn" href="index.php">🧠 Open Orb UI</a> <a class="btn" href="api/simon_status.php" target="_blank" rel="noopener">🔌 Status Endpoint</a> </div> <?php if ($actionMessage !== ''): ?> <div class="notice"><?= h($actionMessage) ?></div> <?php endif; ?> <div class="grid"> <section class="card span-12"> <div class="card-head"> <h2>System Snapshot</h2> <span><?= h(date('F j, Y g:i A')) ?> CT</span> </div> <div class="card-body"> <div class="stats"> <div class="stat"> <div class="k">Overall Health</div> <div class="v"><?= (int)$overallPercent ?>%</div> <div class="progress"><i></i></div> </div> <div class="stat"> <div class="k">Core Files Healthy</div> <div class="v"><?= (int)$healthyCoreFiles ?>/<?= (int)$totalCoreFiles ?></div> </div> <div class="stat"> <div class="k">Memory Records</div> <div class="v"><?= (int)$memoryCount ?></div> </div> <div class="stat"> <div class="k">Log Records</div> <div class="v"><?= (int)$logsCount ?></div> </div> </div> </div> </section> <section class="card span-8"> <div class="card-head"> <h2>Core Engine File Health</h2> <span>/htdocs/simon/</span> </div> <div class="card-body"> <table class="table"> <thead> <tr> <th>File</th> <th>Status</th> <th>Size</th> <th>Modified</th> </tr> </thead> <tbody> <?php foreach ($coreHealth as $file => $meta): ?> <tr> <td><span class="path"><?= h($file) ?></span></td> <td> <?php if ($meta['exists'] && $meta['readable']): ?> <span class="badge good">ONLINE</span> <?php elseif ($meta['exists']): ?> <span class="badge warn">LIMITED</span> <?php else: ?> <span class="badge bad">MISSING</span> <?php endif; ?> </td> <td><?= $meta['exists'] ? h(formatBytes((int)$meta['size'])) : '—' ?></td> <td><?= $meta['modified_at'] ? h(date('Y-m-d H:i:s', (int)$meta['modified_at'])) : '—' ?></td> </tr> <?php endforeach; ?> </tbody> </table> </div> </section> <section class="card span-4"> <div class="card-head"> <h2>Provider Switchboard</h2> <span>Detected from config</span> </div> <div class="card-body"> <div class="switches"> <?php foreach ($providers as $name => $provider): ?> <div class="switch"> <div class="left"> <strong><?= h($name) ?></strong> <small><?= h($provider['reason']) ?></small> </div> <div class="toggle <?= $provider['enabled'] ? 'on' : '' ?>"></div> </div> <?php endforeach; ?> </div> </div> </section> <section class="card span-6"> <div class="card-head"> <h2>Data Layer Health</h2> <span>Memory + logs + config</span> </div> <div class="card-body"> <table class="table"> <thead> <tr> <th>Resource</th> <th>Status</th> <th>Path</th> </tr> </thead> <tbody> <?php $resources = [ 'memory.json' => $memoryHealth, 'logs.json' => $logsHealth, 'settings.php' => $settingsHealth, 'secrets.php' => $secretsHealth, ]; foreach ($resources as $label => $meta): ?> <tr> <td><?= h($label) ?></td> <td> <?php if ($meta['exists'] && $meta['readable']): ?> <span class="badge good">READY</span> <?php elseif ($meta['exists']): ?> <span class="badge warn">PARTIAL</span> <?php else: ?> <span class="badge bad">MISSING</span> <?php endif; ?> </td> <td><span class="path"><?= h(str_replace($baseDir . '/', '', $meta['path'])) ?></span></td> </tr> <?php endforeach; ?> </tbody> </table> </div> </section> <section class="card span-6"> <div class="card-head"> <h2>API Endpoint Readiness</h2> <span>Execution layer</span> </div> <div class="card-body"> <table class="table"> <thead> <tr> <th>Endpoint</th> <th>Status</th> <th>Message</th> </tr> </thead> <tbody> <tr> <td><span class="path">api/simon_status.php</span></td> <td> <?php if ($statusHealth['exists']): ?> <span class="badge good">AVAILABLE</span> <?php else: ?> <span class="badge bad">MISSING</span> <?php endif; ?> </td> <td><?= h($statusHealth['message']) ?></td> </tr> <tr> <td><span class="path">api/simon_request.php</span></td> <td> <?php if (is_file($apiDir . '/simon_request.php')): ?> <span class="badge good">AVAILABLE</span> <?php else: ?> <span class="badge bad">MISSING</span> <?php endif; ?> </td> <td>Main AI request channel</td> </tr> <tr> <td><span class="path">api/openai.php</span></td> <td> <?php if (is_file($apiDir . '/openai.php')): ?> <span class="badge good">AVAILABLE</span> <?php else: ?> <span class="badge warn">NOT FOUND</span> <?php endif; ?> </td> <td>Primary provider adapter</td> </tr> </tbody> </table> </div> </section> <section class="card span-6"> <div class="card-head"> <h2>Recent Memory</h2> <span>Latest <?= (int)count($memoryEntries) ?> entries</span> </div> <div class="card-body"> <div class="list"> <?php if (!$memoryEntries): ?> <div class="item"> <h3>No memory entries found</h3> <p>Check whether <span class="path">data/memory.json</span> exists and contains a valid JSON array.</p> </div> <?php else: ?> <?php foreach ($memoryEntries as $entry): ?> <div class="item"> <h3><?= h($entry['title']) ?></h3> <p><?= nl2br(h(mb_strimwidth($entry['content'], 0, 420, '…'))) ?></p> <?php if (!empty($entry['time'])): ?> <div class="meta"><?= h($entry['time']) ?></div> <?php endif; ?> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> </section> <section class="card span-6"> <div class="card-head"> <h2>Recent Logs</h2> <span>Latest <?= (int)count($logEntries) ?> entries</span> </div> <div class="card-body"> <div class="list"> <?php if (!$logEntries): ?> <div class="item"> <h3>No log entries found</h3> <p>Check whether <span class="path">data/logs.json</span> exists and contains a valid JSON array.</p> </div> <?php else: ?> <?php foreach ($logEntries as $entry): ?> <div class="item"> <h3><?= h(strtoupper($entry['type'])) ?></h3> <p><?= nl2br(h(mb_strimwidth($entry['message'], 0, 420, '…'))) ?></p> <?php if (!empty($entry['time'])): ?> <div class="meta"><?= h($entry['time']) ?></div> <?php endif; ?> </div> <?php endforeach; ?> <?php endif; ?> </div> </div> </section> <section class="card span-12"> <div class="card-head"> <h2>Next Recommended Upgrades</h2> <span>Best value path</span> </div> <div class="card-body"> <div class="list"> <div class="item"> <h3>1. Replace JSON with MySQL persistence</h3> <p>Move memory, logs, projects, prompts, provider results, and user actions into database tables for reliability, filtering, analytics, and future scaling.</p> </div> <div class="item"> <h3>2. Add secure admin authentication</h3> <p>Protect this panel with session login, IP filtering, and optional Basic Auth so only you or approved admins can access the control surface.</p> </div> <div class="item"> <h3>3. Wire live provider switching</h3> <p>Turn the visual provider toggles into real controls backed by <span class="path">config/settings.php</span> so SIMON can route between OpenAI, Grok, Claude, and Gemini dynamically.</p> </div> <div class="item"> <h3>4. Add task macros + automation</h3> <p>Create reusable project macros like “build page,” “scan logs,” “publish asset,” and “review security” from a single action panel.</p> </div> </div> </div> </section> </div> <div class="foot"> SIMON Intelligence Master Control Panel · Cosmic admin layer for your living PHP AI system </div> </div> </body> </html>
Save file
Quick jump
open a path
Open