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
/simon/simon_command_center.php
<?php declare(strict_types=1); /** * SIMON Command Center * Suggested path: /htdocs/simon/index.php * * Requires: * /api/auth/session_bootstrap.php * /private/config.php loaded by session_bootstrap.php * * Uses existing DB_DSN, DB_USER, DB_PASS constants. */ error_reporting(E_ALL); ini_set('display_errors', '0'); ini_set('log_errors', '1'); require_once dirname(__DIR__) . '/api/auth/session_bootstrap.php'; /* * Optional protection: * If /_guardian/admin_guard.php exists, load it and require authentication. */ $adminGuard = dirname(__DIR__) . '/_guardian/admin_guard.php'; if (is_file($adminGuard)) { require_once $adminGuard; if (function_exists('guardian_require_auth')) { guardian_require_auth(); } } header('Content-Type: text/html; charset=UTF-8'); header('X-Content-Type-Options: nosniff'); header('X-Frame-Options: SAMEORIGIN'); header('Referrer-Policy: strict-origin-when-cross-origin'); if (!isset($_SESSION['csrf_token']) || !is_string($_SESSION['csrf_token'])) { $_SESSION['csrf_token'] = bin2hex(random_bytes(32)); } function simon_h(string $value): string { return htmlspecialchars($value, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8'); } function simon_json(mixed $value): string { $json = json_encode($value, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); return $json === false ? '{}' : $json; } function simon_db(): PDO { static $pdo = null; if ($pdo instanceof PDO) { return $pdo; } if (!defined('DB_DSN') || !defined('DB_USER') || !defined('DB_PASS')) { throw new RuntimeException('Database constants DB_DSN, DB_USER, or DB_PASS are missing.'); } $pdo = new PDO( DB_DSN, DB_USER, DB_PASS, [ PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, PDO::ATTR_STRINGIFY_FETCHES => false, PDO::ATTR_TIMEOUT => 8, ] ); $pdo->exec("SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"); return $pdo; } function simon_table_exists(PDO $pdo, string $table): bool { $stmt = $pdo->prepare( 'SELECT COUNT(*) FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name = ?' ); $stmt->execute([$table]); return (int)$stmt->fetchColumn() > 0; } function simon_column_exists(PDO $pdo, string $table, string $column): bool { $stmt = $pdo->prepare( 'SELECT COUNT(*) FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = ? AND column_name = ?' ); $stmt->execute([$table, $column]); return (int)$stmt->fetchColumn() > 0; } function simon_install_schema(PDO $pdo): void { $queries = []; $queries[] = " CREATE TABLE IF NOT EXISTS simon_projects ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, project_key VARCHAR(100) NOT NULL, name VARCHAR(190) NOT NULL, description TEXT NULL, status ENUM('planned','active','paused','completed','archived','error') NOT NULL DEFAULT 'planned', phase VARCHAR(100) NULL, progress TINYINT UNSIGNED NOT NULL DEFAULT 0, environment ENUM('development','staging','production') NOT NULL DEFAULT 'development', root_path VARCHAR(500) NULL, repository_url VARCHAR(500) NULL, owner_email VARCHAR(190) NULL, metadata_json LONGTEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, UNIQUE KEY uq_simon_projects_project_key (project_key), KEY idx_simon_projects_status (status), KEY idx_simon_projects_environment (environment), KEY idx_simon_projects_updated (updated_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; $queries[] = " CREATE TABLE IF NOT EXISTS simon_tasks ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, project_id BIGINT UNSIGNED NULL, title VARCHAR(255) NOT NULL, description TEXT NULL, status ENUM('queued','active','blocked','review','completed','failed','cancelled') NOT NULL DEFAULT 'queued', priority ENUM('low','medium','high','critical') NOT NULL DEFAULT 'medium', assigned_agent VARCHAR(100) NULL, due_at DATETIME NULL, completed_at DATETIME NULL, metadata_json LONGTEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, KEY idx_simon_tasks_project (project_id), KEY idx_simon_tasks_status (status), KEY idx_simon_tasks_priority (priority), CONSTRAINT fk_simon_tasks_project FOREIGN KEY (project_id) REFERENCES simon_projects(id) ON DELETE SET NULL ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; $queries[] = " CREATE TABLE IF NOT EXISTS simon_events ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, event_uuid CHAR(36) NOT NULL, event_type VARCHAR(100) NOT NULL, who_value VARCHAR(190) NOT NULL DEFAULT 'system', what_value TEXT NULL, when_value DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, where_value VARCHAR(500) NULL, why_value TEXT NULL, how_value VARCHAR(190) NULL, trigger_value VARCHAR(190) NULL, truth_value TINYINT(1) NOT NULL DEFAULT 0, confidence DECIMAL(5,4) NOT NULL DEFAULT 0.0000, ambiguity DECIMAL(5,4) NOT NULL DEFAULT 1.0000, completeness DECIMAL(5,4) NOT NULL DEFAULT 0.0000, risk DECIMAL(5,4) NOT NULL DEFAULT 0.0000, make_false_json LONGTEXT NULL, make_true_json LONGTEXT NULL, meta_json LONGTEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE KEY uq_simon_events_uuid (event_uuid), KEY idx_simon_events_type (event_type), KEY idx_simon_events_when (when_value) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; $queries[] = " CREATE TABLE IF NOT EXISTS simon_system_log ( id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, level ENUM('debug','info','notice','warning','error','critical') NOT NULL DEFAULT 'info', source VARCHAR(150) NOT NULL DEFAULT 'command_center', message TEXT NOT NULL, context_json LONGTEXT NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, KEY idx_simon_log_level (level), KEY idx_simon_log_source (source), KEY idx_simon_log_created (created_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci"; foreach ($queries as $query) { $pdo->exec($query); } } function simon_log(PDO $pdo, string $level, string $message, array $context = []): void { $allowed = ['debug', 'info', 'notice', 'warning', 'error', 'critical']; if (!in_array($level, $allowed, true)) { $level = 'info'; } $stmt = $pdo->prepare( 'INSERT INTO simon_system_log (level, source, message, context_json) VALUES (?, ?, ?, ?)' ); $stmt->execute([ $level, 'command_center', $message, simon_json($context), ]); } function simon_uuid_v4(): string { $data = random_bytes(16); $data[6] = chr((ord($data[6]) & 0x0f) | 0x40); $data[8] = chr((ord($data[8]) & 0x3f) | 0x80); return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4)); } function simon_post_string(string $key, int $max = 5000): string { $value = trim((string)($_POST[$key] ?? '')); return mb_substr($value, 0, $max); } function simon_redirect_with_message(string $message, string $type = 'success'): never { $_SESSION['simon_flash'] = [ 'message' => $message, 'type' => $type, ]; header('Location: ' . strtok((string)($_SERVER['REQUEST_URI'] ?? '/simon/index.php'), '?')); exit; } $dbConnected = false; $dbError = ''; $pdo = null; try { $pdo = simon_db(); $dbConnected = true; simon_install_schema($pdo); } catch (Throwable $e) { $dbError = $e->getMessage(); error_log('[SIMON Command Center] ' . $e->getMessage()); } if ($_SERVER['REQUEST_METHOD'] === 'POST') { if (!$dbConnected || !$pdo instanceof PDO) { simon_redirect_with_message('Database connection is unavailable.', 'error'); } $csrf = (string)($_POST['csrf_token'] ?? ''); if (!hash_equals((string)$_SESSION['csrf_token'], $csrf)) { simon_redirect_with_message('Security token validation failed.', 'error'); } $action = simon_post_string('action', 50); try { if ($action === 'create_project') { $name = simon_post_string('name', 190); $key = simon_post_string('project_key', 100); $description = simon_post_string('description', 5000); $environment = simon_post_string('environment', 20); if ($name === '' || $key === '') { throw new RuntimeException('Project name and project key are required.'); } if (!preg_match('/^[a-z0-9][a-z0-9_-]{1,99}$/', $key)) { throw new RuntimeException('Project key must use lowercase letters, numbers, hyphens, or underscores.'); } if (!in_array($environment, ['development', 'staging', 'production'], true)) { $environment = 'development'; } $stmt = $pdo->prepare( 'INSERT INTO simon_projects (project_key, name, description, status, environment, owner_email) VALUES (?, ?, ?, ?, ?, ?)' ); $stmt->execute([ $key, $name, $description !== '' ? $description : null, 'planned', $environment, (string)($_SESSION['guardian_email'] ?? $_SESSION['email'] ?? ''), ]); $projectId = (int)$pdo->lastInsertId(); $eventStmt = $pdo->prepare( 'INSERT INTO simon_events (event_uuid, event_type, who_value, what_value, where_value, why_value, how_value, truth_value, confidence, ambiguity, completeness, risk, meta_json) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)' ); $eventStmt->execute([ simon_uuid_v4(), 'project_created', (string)($_SESSION['guardian_email'] ?? 'user'), 'Created project ' . $name, '/simon/index.php', 'Initialize project in command center', 'direct', 1, 1.0, 0.0, 1.0, 0.1, simon_json(['project_id' => $projectId, 'project_key' => $key]), ]); simon_log($pdo, 'notice', 'Project created', [ 'project_id' => $projectId, 'project_key' => $key, ]); simon_redirect_with_message('Project created successfully.'); } if ($action === 'create_task') { $title = simon_post_string('title', 255); $description = simon_post_string('task_description', 5000); $priority = simon_post_string('priority', 20); $projectId = (int)($_POST['project_id'] ?? 0); if ($title === '') { throw new RuntimeException('Task title is required.'); } if (!in_array($priority, ['low', 'medium', 'high', 'critical'], true)) { $priority = 'medium'; } $stmt = $pdo->prepare( 'INSERT INTO simon_tasks (project_id, title, description, status, priority) VALUES (?, ?, ?, ?, ?)' ); $stmt->execute([ $projectId > 0 ? $projectId : null, $title, $description !== '' ? $description : null, 'queued', $priority, ]); simon_log($pdo, 'info', 'Task created', [ 'task_id' => (int)$pdo->lastInsertId(), 'project_id' => $projectId ?: null, ]); simon_redirect_with_message('Task added to the queue.'); } if ($action === 'update_task_status') { $taskId = (int)($_POST['task_id'] ?? 0); $status = simon_post_string('status', 20); $allowedStatuses = ['queued', 'active', 'blocked', 'review', 'completed', 'failed', 'cancelled']; if ($taskId < 1 || !in_array($status, $allowedStatuses, true)) { throw new RuntimeException('Invalid task update.'); } $completedAt = $status === 'completed' ? date('Y-m-d H:i:s') : null; $stmt = $pdo->prepare( 'UPDATE simon_tasks SET status = ?, completed_at = ? WHERE id = ?' ); $stmt->execute([$status, $completedAt, $taskId]); simon_log($pdo, 'info', 'Task status changed', [ 'task_id' => $taskId, 'status' => $status, ]); simon_redirect_with_message('Task status updated.'); } if ($action === 'test_database') { $result = $pdo->query('SELECT DATABASE() AS db_name, VERSION() AS db_version, NOW() AS server_time')->fetch(); simon_log($pdo, 'info', 'Database connection test completed', $result ?: []); simon_redirect_with_message('Database connection test passed.'); } throw new RuntimeException('Unknown command.'); } catch (Throwable $e) { error_log('[SIMON Action] ' . $e->getMessage()); simon_redirect_with_message($e->getMessage(), 'error'); } } $flash = $_SESSION['simon_flash'] ?? null; unset($_SESSION['simon_flash']); $stats = [ 'projects' => 0, 'active_projects' => 0, 'tasks' => 0, 'open_tasks' => 0, 'events' => 0, 'errors' => 0, ]; $projects = []; $tasks = []; $events = []; $logs = []; $dbInfo = []; if ($dbConnected && $pdo instanceof PDO) { try { $dbInfo = $pdo->query( 'SELECT DATABASE() AS database_name, VERSION() AS database_version, NOW() AS database_time' )->fetch() ?: []; $stats['projects'] = (int)$pdo->query('SELECT COUNT(*) FROM simon_projects')->fetchColumn(); $stats['active_projects'] = (int)$pdo->query( "SELECT COUNT(*) FROM simon_projects WHERE status = 'active'" )->fetchColumn(); $stats['tasks'] = (int)$pdo->query('SELECT COUNT(*) FROM simon_tasks')->fetchColumn(); $stats['open_tasks'] = (int)$pdo->query( "SELECT COUNT(*) FROM simon_tasks WHERE status NOT IN ('completed','cancelled')" )->fetchColumn(); $stats['events'] = (int)$pdo->query('SELECT COUNT(*) FROM simon_events')->fetchColumn(); $stats['errors'] = (int)$pdo->query( "SELECT COUNT(*) FROM simon_system_log WHERE level IN ('error','critical') AND created_at >= (NOW() - INTERVAL 24 HOUR)" )->fetchColumn(); $projects = $pdo->query( 'SELECT id, project_key, name, description, status, phase, progress, environment, updated_at FROM simon_projects ORDER BY updated_at DESC LIMIT 20' )->fetchAll(); $tasks = $pdo->query( 'SELECT t.id, t.project_id, t.title, t.status, t.priority, t.updated_at, p.name AS project_name FROM simon_tasks t LEFT JOIN simon_projects p ON p.id = t.project_id ORDER BY FIELD(t.priority, "critical", "high", "medium", "low"), FIELD(t.status, "active", "blocked", "review", "queued", "failed", "completed", "cancelled"), t.updated_at DESC LIMIT 30' )->fetchAll(); $events = $pdo->query( 'SELECT event_type, who_value, what_value, when_value, risk FROM simon_events ORDER BY when_value DESC LIMIT 15' )->fetchAll(); $logs = $pdo->query( 'SELECT level, source, message, created_at FROM simon_system_log ORDER BY created_at DESC LIMIT 15' )->fetchAll(); } catch (Throwable $e) { $dbError = $e->getMessage(); error_log('[SIMON Dashboard Load] ' . $e->getMessage()); } } $currentUser = (string)($_SESSION['guardian_email'] ?? $_SESSION['email'] ?? 'Operator'); $currentRole = (string)($_SESSION['guardian_role'] ?? $_SESSION['role'] ?? 'user'); ?> <!doctype html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width,initial-scale=1,viewport-fit=cover"> <meta name="theme-color" content="#05070d"> <title>SIMON Command Center</title> <style> :root{ --bg:#05070d; --panel:#0c111d; --panel2:#111827; --line:#263246; --text:#edf4ff; --muted:#91a0b8; --accent:#73d7ff; --good:#61d69c; --warn:#ffd166; --bad:#ff6b7d; --purple:#b49cff; --radius:18px; } *{box-sizing:border-box} html{background:var(--bg);color:var(--text);font-family:Inter,ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif} body{margin:0;min-height:100vh;background: radial-gradient(circle at 20% 0%,rgba(115,215,255,.10),transparent 32rem), radial-gradient(circle at 90% 10%,rgba(180,156,255,.08),transparent 28rem), var(--bg)} button,input,select,textarea{font:inherit} a{color:inherit} .shell{width:min(1500px,100%);margin:0 auto;padding:18px} .topbar{display:flex;gap:16px;align-items:center;justify-content:space-between;margin-bottom:18px} .brand{display:flex;align-items:center;gap:12px} .orb{width:42px;height:42px;border-radius:50%;background: radial-gradient(circle at 35% 30%,#fff 0 4%,#7ee8ff 9%,#2760ff 36%,#4d167c 64%,#05070d 80%); box-shadow:0 0 30px rgba(115,215,255,.35)} .brand h1{font-size:20px;margin:0;letter-spacing:.03em} .brand p{margin:2px 0 0;color:var(--muted);font-size:12px} .user{display:flex;align-items:center;gap:10px;color:var(--muted);font-size:13px} .badge{display:inline-flex;align-items:center;gap:6px;padding:6px 10px;border-radius:999px;border:1px solid var(--line);background:rgba(255,255,255,.03)} .dot{width:8px;height:8px;border-radius:50%;background:var(--bad);box-shadow:0 0 12px currentColor} .dot.good{background:var(--good)} .flash{padding:12px 14px;border-radius:12px;margin-bottom:16px;border:1px solid var(--line);background:var(--panel)} .flash.success{border-color:rgba(97,214,156,.45)} .flash.error{border-color:rgba(255,107,125,.5)} .grid{display:grid;gap:14px} .stats{grid-template-columns:repeat(6,minmax(0,1fr));margin-bottom:14px} .card{background:linear-gradient(180deg,rgba(17,24,39,.96),rgba(9,14,24,.96));border:1px solid var(--line);border-radius:var(--radius);box-shadow:0 18px 50px rgba(0,0,0,.22)} .stat{padding:16px} .stat span{display:block;color:var(--muted);font-size:12px;margin-bottom:8px} .stat strong{font-size:26px;font-weight:700} .main{grid-template-columns:minmax(0,1.7fr) minmax(320px,.8fr)} .section{padding:17px} .section h2{font-size:15px;margin:0} .section-head{display:flex;justify-content:space-between;align-items:center;gap:12px;margin-bottom:14px} .subtle{color:var(--muted);font-size:12px} .toolbar{display:flex;gap:8px;flex-wrap:wrap} button,.button{border:1px solid var(--line);background:#131c2c;color:var(--text);border-radius:11px;padding:9px 12px;cursor:pointer;text-decoration:none} button:hover,.button:hover{border-color:#486180;background:#17243a} button.primary{background:linear-gradient(135deg,#1b6fff,#6055ff);border-color:#617cff} button.danger{border-color:rgba(255,107,125,.45)} table{width:100%;border-collapse:collapse} th,td{text-align:left;padding:11px 9px;border-top:1px solid rgba(38,50,70,.72);font-size:13px;vertical-align:middle} th{color:var(--muted);font-weight:600;font-size:11px;text-transform:uppercase;letter-spacing:.06em} .status,.priority,.env{display:inline-block;padding:5px 8px;border-radius:999px;border:1px solid var(--line);font-size:11px} .status.active,.status.completed{color:var(--good)} .status.blocked,.status.failed,.status.error{color:var(--bad)} .status.review,.status.paused{color:var(--warn)} .priority.critical{color:var(--bad)} .priority.high{color:var(--warn)} .env.production{color:var(--good)} .env.staging{color:var(--purple)} progress{width:110px;height:8px;accent-color:var(--accent)} .forms{display:grid;gap:14px} .form-card{padding:16px} .form-card h3{margin:0 0 12px;font-size:14px} label{display:block;color:var(--muted);font-size:12px;margin:10px 0 6px} input,select,textarea{width:100%;border:1px solid var(--line);background:#080d16;color:var(--text);padding:10px 11px;border-radius:10px;outline:none} input:focus,select:focus,textarea:focus{border-color:var(--accent);box-shadow:0 0 0 3px rgba(115,215,255,.1)} textarea{min-height:82px;resize:vertical} .row{display:grid;grid-template-columns:1fr 1fr;gap:10px} .list{display:grid;gap:8px} .item{padding:11px;border:1px solid rgba(38,50,70,.75);border-radius:12px;background:rgba(5,7,13,.45)} .item .meta{display:flex;justify-content:space-between;gap:8px;color:var(--muted);font-size:11px;margin-bottom:5px} .item p{margin:0;font-size:13px;line-height:1.45} .db-box{padding:14px;border-radius:13px;background:#080d16;border:1px solid var(--line);font-size:12px;line-height:1.65;color:var(--muted)} .db-box strong{color:var(--text)} .error-box{border-color:rgba(255,107,125,.5);color:#ffc0c9} .task-status{width:auto;min-width:110px;padding:7px 9px} .footer{padding:20px 2px;color:var(--muted);font-size:11px;text-align:center} .empty{color:var(--muted);text-align:center;padding:26px} @media(max-width:1100px){ .stats{grid-template-columns:repeat(3,1fr)} .main{grid-template-columns:1fr} } @media(max-width:680px){ .shell{padding:12px} .topbar{align-items:flex-start} .user{display:none} .stats{grid-template-columns:repeat(2,1fr)} .row{grid-template-columns:1fr} .table-wrap{overflow:auto} table{min-width:720px} } </style> </head> <body> <div class="shell"> <header class="topbar"> <div class="brand"> <div class="orb" aria-hidden="true"></div> <div> <h1>SIMON Command Center</h1> <p>Database-backed operations, projects, tasks, events, and system health</p> </div> </div> <div class="user"> <span class="badge"><?= simon_h($currentUser) ?></span> <span class="badge"><?= simon_h($currentRole) ?></span> <span class="badge"><span class="dot <?= $dbConnected ? 'good' : '' ?>"></span><?= $dbConnected ? 'Database online' : 'Database offline' ?></span> </div> </header> <?php if (is_array($flash)): ?> <div class="flash <?= simon_h((string)($flash['type'] ?? 'success')) ?>"> <?= simon_h((string)($flash['message'] ?? '')) ?> </div> <?php endif; ?> <section class="grid stats"> <div class="card stat"><span>Total projects</span><strong><?= $stats['projects'] ?></strong></div> <div class="card stat"><span>Active projects</span><strong><?= $stats['active_projects'] ?></strong></div> <div class="card stat"><span>Total tasks</span><strong><?= $stats['tasks'] ?></strong></div> <div class="card stat"><span>Open tasks</span><strong><?= $stats['open_tasks'] ?></strong></div> <div class="card stat"><span>Recorded events</span><strong><?= $stats['events'] ?></strong></div> <div class="card stat"><span>Errors, 24 hours</span><strong><?= $stats['errors'] ?></strong></div> </section> <main class="grid main"> <div class="grid"> <section class="card section"> <div class="section-head"> <div> <h2>Projects</h2> <div class="subtle">Persistent project registry from MariaDB</div> </div> </div> <div class="table-wrap"> <table> <thead> <tr> <th>Project</th> <th>Status</th> <th>Environment</th> <th>Phase</th> <th>Progress</th> <th>Updated</th> </tr> </thead> <tbody> <?php if ($projects === []): ?> <tr><td colspan="6" class="empty">No projects yet. Create the first project from the right panel.</td></tr> <?php else: ?> <?php foreach ($projects as $project): ?> <tr> <td> <strong><?= simon_h((string)$project['name']) ?></strong><br> <span class="subtle"><?= simon_h((string)$project['project_key']) ?></span> </td> <td><span class="status <?= simon_h((string)$project['status']) ?>"><?= simon_h((string)$project['status']) ?></span></td> <td><span class="env <?= simon_h((string)$project['environment']) ?>"><?= simon_h((string)$project['environment']) ?></span></td> <td><?= simon_h((string)($project['phase'] ?: 'Not set')) ?></td> <td> <progress max="100" value="<?= (int)$project['progress'] ?>"></progress> <span class="subtle"><?= (int)$project['progress'] ?>%</span> </td> <td><?= simon_h((string)$project['updated_at']) ?></td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </section> <section class="card section"> <div class="section-head"> <div> <h2>Task Queue</h2> <div class="subtle">Prioritized work and agent assignments</div> </div> </div> <div class="table-wrap"> <table> <thead> <tr> <th>Task</th> <th>Project</th> <th>Priority</th> <th>Status</th> <th>Updated</th> </tr> </thead> <tbody> <?php if ($tasks === []): ?> <tr><td colspan="5" class="empty">No tasks are queued.</td></tr> <?php else: ?> <?php foreach ($tasks as $task): ?> <tr> <td><strong><?= simon_h((string)$task['title']) ?></strong></td> <td><?= simon_h((string)($task['project_name'] ?: 'General')) ?></td> <td><span class="priority <?= simon_h((string)$task['priority']) ?>"><?= simon_h((string)$task['priority']) ?></span></td> <td> <form method="post"> <input type="hidden" name="csrf_token" value="<?= simon_h((string)$_SESSION['csrf_token']) ?>"> <input type="hidden" name="action" value="update_task_status"> <input type="hidden" name="task_id" value="<?= (int)$task['id'] ?>"> <select class="task-status" name="status" onchange="this.form.submit()"> <?php foreach (['queued','active','blocked','review','completed','failed','cancelled'] as $status): ?> <option value="<?= $status ?>" <?= $task['status'] === $status ? 'selected' : '' ?>><?= ucfirst($status) ?></option> <?php endforeach; ?> </select> </form> </td> <td><?= simon_h((string)$task['updated_at']) ?></td> </tr> <?php endforeach; ?> <?php endif; ?> </tbody> </table> </div> </section> <section class="card section"> <div class="section-head"> <div> <h2>Recent Intelligence Events</h2> <div class="subtle">5W1H-compatible event stream</div> </div> </div> <div class="list"> <?php if ($events === []): ?> <div class="empty">No events recorded yet.</div> <?php else: ?> <?php foreach ($events as $event): ?> <div class="item"> <div class="meta"> <span><?= simon_h((string)$event['event_type']) ?> · <?= simon_h((string)$event['who_value']) ?></span> <span><?= simon_h((string)$event['when_value']) ?> · risk <?= simon_h((string)$event['risk']) ?></span> </div> <p><?= simon_h((string)$event['what_value']) ?></p> </div> <?php endforeach; ?> <?php endif; ?> </div> </section> </div> <aside class="grid"> <section class="card form-card"> <h3>Database Connection</h3> <?php if ($dbConnected): ?> <div class="db-box"> <strong>Status:</strong> Connected<br> <strong>Database:</strong> <?= simon_h((string)($dbInfo['database_name'] ?? 'Unknown')) ?><br> <strong>Version:</strong> <?= simon_h((string)($dbInfo['database_version'] ?? 'Unknown')) ?><br> <strong>Server time:</strong> <?= simon_h((string)($dbInfo['database_time'] ?? 'Unknown')) ?> </div> <form method="post" style="margin-top:10px"> <input type="hidden" name="csrf_token" value="<?= simon_h((string)$_SESSION['csrf_token']) ?>"> <input type="hidden" name="action" value="test_database"> <button type="submit">Test connection</button> </form> <?php else: ?> <div class="db-box error-box"> <strong>Connection failed</strong><br> <?= simon_h($dbError !== '' ? $dbError : 'Unknown database error.') ?> </div> <?php endif; ?> </section> <section class="card form-card"> <h3>Create Project</h3> <form method="post"> <input type="hidden" name="csrf_token" value="<?= simon_h((string)$_SESSION['csrf_token']) ?>"> <input type="hidden" name="action" value="create_project"> <label for="project-name">Project name</label> <input id="project-name" name="name" maxlength="190" required placeholder="SIMON Intelligence"> <label for="project-key">Project key</label> <input id="project-key" name="project_key" maxlength="100" required pattern="[a-z0-9][a-z0-9_-]{1,99}" placeholder="simon_intelligence"> <label for="project-description">Description</label> <textarea id="project-description" name="description" placeholder="Purpose, scope, and expected result"></textarea> <label for="environment">Environment</label> <select id="environment" name="environment"> <option value="development">Development</option> <option value="staging">Staging</option> <option value="production">Production</option> </select> <button class="primary" type="submit" style="margin-top:12px">Create project</button> </form> </section> <section class="card form-card"> <h3>Create Task</h3> <form method="post"> <input type="hidden" name="csrf_token" value="<?= simon_h((string)$_SESSION['csrf_token']) ?>"> <input type="hidden" name="action" value="create_task"> <label for="task-title">Task title</label> <input id="task-title" name="title" maxlength="255" required placeholder="Build file scanner"> <label for="task-project">Project</label> <select id="task-project" name="project_id"> <option value="0">General / no project</option> <?php foreach ($projects as $project): ?> <option value="<?= (int)$project['id'] ?>"><?= simon_h((string)$project['name']) ?></option> <?php endforeach; ?> </select> <div class="row"> <div> <label for="priority">Priority</label> <select id="priority" name="priority"> <option value="low">Low</option> <option value="medium" selected>Medium</option> <option value="high">High</option> <option value="critical">Critical</option> </select> </div> <div> <label>Status</label> <input value="Queued" disabled> </div> </div> <label for="task-description">Description</label> <textarea id="task-description" name="task_description" placeholder="Requirements, dependencies, and completion criteria"></textarea> <button class="primary" type="submit" style="margin-top:12px">Add task</button> </form> </section> <section class="card section"> <div class="section-head"> <div> <h2>System Log</h2> <div class="subtle">Latest command-center events</div> </div> </div> <div class="list"> <?php if ($logs === []): ?> <div class="empty">No log entries.</div> <?php else: ?> <?php foreach ($logs as $log): ?> <div class="item"> <div class="meta"> <span><?= simon_h((string)$log['level']) ?> · <?= simon_h((string)$log['source']) ?></span> <span><?= simon_h((string)$log['created_at']) ?></span> </div> <p><?= simon_h((string)$log['message']) ?></p> </div> <?php endforeach; ?> <?php endif; ?> </div> </section> </aside> </main> <footer class="footer"> SIMON Intelligence · Database-backed command center · <?= date('Y') ?> </footer> </div> </body> </html>
Save file
Quick jump
open a path
Open