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,340
Folders
408
Scanned Size
3.84 GB
PHP Files
891
Editable Text Files
12,601
File viewer
guarded to /htdocs
/simon/old/ind.php
<?php declare(strict_types=1); /** * /htdocs/simon/api/simon_voice.php * * SIMON Voice Router — streamlined + emotion/tone ready * * Purpose: * - Accept transcribed voice text * - Classify voice intent * - Route into SIMON jobs * - Return OpenAI-friendly voice instructions * - Support tone / attitude / emotion / style fields * - Keep server-side execution clean and safe */ date_default_timezone_set('America/Chicago'); header('Content-Type: application/json; charset=utf-8'); const SIMON_DATA_DIR = __DIR__ . '/../data'; const SIMON_LOG_DIR = __DIR__ . '/../logs'; const JOB_QUEUE_FILE = SIMON_DATA_DIR . '/job_queue.json'; const JOB_LOG_FILE = SIMON_DATA_DIR . '/job_log.json'; const MEMORY_FILE = SIMON_DATA_DIR . '/memory.json'; const EVENT_LOG_FILE = SIMON_DATA_DIR . '/voice_events.ndjson'; const CHANGE_LOG_FILE = SIMON_DATA_DIR . '/change_log.json'; ensureDirectories(); ensureJsonFile(JOB_QUEUE_FILE, []); ensureJsonFile(JOB_LOG_FILE, []); ensureJsonFile(MEMORY_FILE, []); ensureJsonFile(CHANGE_LOG_FILE, []); if ($_SERVER['REQUEST_METHOD'] !== 'POST') { respond(405, [ 'status' => 'error', 'message' => 'POST requests only' ]); } $raw = file_get_contents('php://input'); $data = json_decode($raw ?: '', true); if (!is_array($data)) { respond(400, [ 'status' => 'error', 'message' => 'Invalid JSON payload' ]); } $voiceText = trim((string)($data['text'] ?? '')); $userId = trim((string)($data['user_id'] ?? 'default')); $source = trim((string)($data['source'] ?? 'voice')); $context = is_array($data['context'] ?? null) ? $data['context'] : []; /** * Voice controls sent from UI/client */ $requestedVoice = trim((string)($data['voice'] ?? 'cedar')); $tone = normalizeTone((string)($data['tone'] ?? 'calm')); $attitude = normalizeAttitude((string)($data['attitude'] ?? 'helpful')); $emotion = normalizeEmotion((string)($data['emotion'] ?? 'warm')); $responseStyle = normalizeResponseStyle((string)($data['response_style'] ?? 'concise')); $speakingSpeed = normalizeSpeakingSpeed((string)($data['speaking_speed'] ?? 'normal')); $verbosity = normalizeVerbosity((string)($data['verbosity'] ?? 'short')); if ($voiceText === '') { respond(422, [ 'status' => 'error', 'message' => 'Missing voice text' ]); } $voiceProfile = buildVoiceProfile( $requestedVoice, $tone, $attitude, $emotion, $responseStyle, $speakingSpeed, $verbosity ); /** * Step 1: classify intent */ $intent = classifyIntent($voiceText); /** * Step 2: block unsafe actions */ if (!$intent['allowed']) { $payload = [ 'status' => 'blocked', 'spoken_reply' => $intent['spoken_reply'], 'intent' => $intent, 'voice_profile' => $voiceProfile, 'openai_voice_enabled' => true, 'disable_system_tts' => true, 'openai_voice_instructions' => buildOpenAIVoiceInstructions($voiceProfile, $intent['spoken_reply']), ]; logVoiceEvent([ 'event_type' => 'voice.blocked', 'what' => $voiceText, 'why' => 'Intent blocked by policy', 'where' => 'simon_voice.php', 'who' => $userId, 'how' => $source, 'result' => $intent['reason'] ?? 'blocked', 'meta' => [ 'intent' => $intent, 'voice_profile' => $voiceProfile ] ]); respond(403, $payload); } /** * Step 3: execute action */ $result = dispatchIntent($intent, $voiceText, $userId, $source, $context); /** * Step 4: choose final spoken reply */ $spokenReply = trim((string)($result['spoken_reply'] ?? 'Done.')); $openAIInstructions = buildOpenAIVoiceInstructions($voiceProfile, $spokenReply); /** * Step 5: log */ logVoiceEvent([ 'event_type' => 'voice.command', 'what' => $voiceText, 'why' => $intent['label'], 'where' => 'simon_voice.php', 'who' => $userId, 'how' => $source, 'result' => $result['message'] ?? 'completed', 'meta' => [ 'intent' => $intent, 'result' => $result, 'voice_profile' => $voiceProfile, 'openai_voice_instructions' => $openAIInstructions ] ]); /** * Step 6: memory */ appendMemory([ 'type' => 'voice_command', 'summary' => $voiceText, 'intent' => $intent['key'], 'timestamp' => date('c'), 'user_id' => $userId, 'voice_profile' => $voiceProfile ]); respond(200, [ 'status' => 'ok', 'spoken_reply' => $spokenReply, 'intent' => $intent, 'result' => $result, 'voice_profile' => $voiceProfile, 'openai_voice_enabled' => true, 'disable_system_tts' => true, 'openai_voice_instructions' => $openAIInstructions ]); /* -------------------------------------------------------- * Intent * ------------------------------------------------------*/ function classifyIntent(string $text): array { $t = mb_strtolower($text); $rules = [ [ 'key' => 'scan_files', 'label' => 'Scan files', 'patterns' => [ 'scan files', 'scan all files', 'run file scan', 'audit files', 'check files', 'review files' ], 'action' => 'queue_scan_job', 'allowed' => true, 'spoken_reply' => 'Starting a file scan.' ], [ 'key' => 'show_risky_files', 'label' => 'Show risky files', 'patterns' => [ 'show risky files', 'show dangerous files', 'show flagged files', 'show broken files' ], 'action' => 'read_registry_summary', 'allowed' => true, 'spoken_reply' => 'Showing risky files.' ], [ 'key' => 'open_file_registry', 'label' => 'Open file registry', 'patterns' => [ 'open file registry', 'show file registry', 'open registry', 'show registry' ], 'action' => 'open_console_target', 'target' => '/simon/file_registry.php', 'allowed' => true, 'spoken_reply' => 'Opening file registry.' ], [ 'key' => 'open_dashboard', 'label' => 'Open dashboard', 'patterns' => [ 'open dashboard', 'show dashboard', 'open simon dashboard' ], 'action' => 'open_console_target', 'target' => '/simon/dashboard.php', 'allowed' => true, 'spoken_reply' => 'Opening dashboard.' ], [ 'key' => 'run_security_scan', 'label' => 'Run security scan', 'patterns' => [ 'run security scan', 'scan security', 'check security', 'security audit' ], 'action' => 'queue_security_job', 'allowed' => true, 'spoken_reply' => 'Starting a security scan.' ], [ 'key' => 'show_logs', 'label' => 'Show logs', 'patterns' => [ 'show logs', 'open logs', 'view logs', 'show system log' ], 'action' => 'open_console_target', 'target' => '/simon/logs.php', 'allowed' => true, 'spoken_reply' => 'Opening logs.' ], [ 'key' => 'show_memory', 'label' => 'Show memory', 'patterns' => [ 'show memory', 'open memory', 'view memory' ], 'action' => 'open_console_target', 'target' => '/simon/memory_view.php', 'allowed' => true, 'spoken_reply' => 'Opening memory.' ], [ 'key' => 'generate_project', 'label' => 'Generate project', 'patterns' => [ 'create project', 'generate project', 'new project', 'build project' ], 'action' => 'queue_generate_project', 'allowed' => true, 'spoken_reply' => 'Preparing a new project job.' ], [ 'key' => 'deploy_staging', 'label' => 'Deploy staging', 'patterns' => [ 'deploy staging', 'push to staging', 'release to staging' ], 'action' => 'queue_deploy_job', 'environment' => 'staging', 'allowed' => true, 'spoken_reply' => 'Queuing a staging deployment.' ], [ 'key' => 'deploy_production', 'label' => 'Deploy production', 'patterns' => [ 'deploy production', 'push live', 'release to production', 'go live' ], 'action' => 'queue_deploy_job', 'environment' => 'production', 'allowed' => false, 'reason' => 'Production deploy requires approval workflow', 'spoken_reply' => 'Production deployment is blocked until approval is granted.' ], ]; foreach ($rules as $rule) { foreach ($rule['patterns'] as $pattern) { if (str_contains($t, $pattern)) { return array_merge([ 'matched_pattern' => $pattern, 'reason' => null ], $rule); } } } return [ 'key' => 'unknown', 'label' => 'Unknown', 'matched_pattern' => null, 'action' => 'none', 'allowed' => false, 'reason' => 'No matching voice command', 'spoken_reply' => 'I understood your voice input, but I do not have a safe mapped action for it yet.' ]; } /* -------------------------------------------------------- * Dispatch * ------------------------------------------------------*/ function dispatchIntent(array $intent, string $voiceText, string $userId, string $source, array $context): array { switch ($intent['action']) { case 'queue_scan_job': $job = createJob('scan', [ 'scope' => 'full_project', 'requested_by' => $userId, 'source' => $source, 'voice_text' => $voiceText ], 'high'); return [ 'message' => 'File scan queued', 'spoken_reply' => 'File scan queued successfully.', 'job' => $job ]; case 'queue_security_job': $job = createJob('security_scan', [ 'scope' => 'full_project', 'requested_by' => $userId, 'source' => $source, 'voice_text' => $voiceText ], 'high'); return [ 'message' => 'Security scan queued', 'spoken_reply' => 'Security scan queued successfully.', 'job' => $job ]; case 'queue_generate_project': $projectName = extractProjectName($voiceText) ?: 'New SIMON Project'; $job = createJob('generate_project', [ 'project_name' => $projectName, 'requested_by' => $userId, 'source' => $source, 'context' => $context, 'voice_text' => $voiceText ], 'medium'); return [ 'message' => 'Project generation queued', 'spoken_reply' => "Project job queued for {$projectName}.", 'job' => $job ]; case 'queue_deploy_job': $environment = (string)($intent['environment'] ?? 'staging'); $job = createJob('deploy', [ 'environment' => $environment, 'requested_by' => $userId, 'source' => $source, 'voice_text' => $voiceText ], 'high'); return [ 'message' => "Deployment queued for {$environment}", 'spoken_reply' => ucfirst($environment) . ' deployment queued.', 'job' => $job ]; case 'open_console_target': return [ 'message' => 'Console target ready', 'spoken_reply' => $intent['spoken_reply'] ?? 'Opening target.', 'target' => $intent['target'] ?? '/simon/' ]; case 'read_registry_summary': $summary = readRegistrySummary(); return [ 'message' => 'Registry summary loaded', 'spoken_reply' => $summary['spoken_reply'], 'summary' => $summary ]; default: return [ 'message' => 'No dispatch action performed', 'spoken_reply' => 'No action was performed.' ]; } } /* -------------------------------------------------------- * Voice profile * ------------------------------------------------------*/ function buildVoiceProfile( string $voice, string $tone, string $attitude, string $emotion, string $responseStyle, string $speakingSpeed, string $verbosity ): array { return [ 'provider' => 'openai', 'voice' => normalizeVoice($voice), 'tone' => $tone, 'attitude' => $attitude, 'emotion' => $emotion, 'response_style' => $responseStyle, 'speaking_speed' => $speakingSpeed, 'verbosity' => $verbosity ]; } function buildOpenAIVoiceInstructions(array $voiceProfile, string $replyText): string { $tone = $voiceProfile['tone'] ?? 'calm'; $attitude = $voiceProfile['attitude'] ?? 'helpful'; $emotion = $voiceProfile['emotion'] ?? 'warm'; $responseStyle = $voiceProfile['response_style'] ?? 'concise'; $speed = $voiceProfile['speaking_speed'] ?? 'normal'; $verbosity = $voiceProfile['verbosity'] ?? 'short'; return trim( "Speak in a {$tone}, {$emotion} tone with a {$attitude} attitude. " . "Use {$responseStyle} response style, {$speed} speaking pace, and {$verbosity} verbal length. " . "Do not use system or browser speech synthesis. " . "Use OpenAI voice output only. " . "Deliver this reply naturally: {$replyText}" ); } /* -------------------------------------------------------- * Jobs * ------------------------------------------------------*/ function createJob(string $type, array $input, string $priority = 'medium'): array { $queue = readJson(JOB_QUEUE_FILE, []); $jobLog = readJson(JOB_LOG_FILE, []); $job = [ 'job_id' => 'job_' . bin2hex(random_bytes(6)), 'type' => $type, 'priority' => $priority, 'status' => 'queued', 'assigned_agent' => suggestAgent($type), 'input' => $input, 'output' => null, 'created_at' => date('c'), 'updated_at' => date('c') ]; $queue[] = $job; $jobLog[] = [ 'job_id' => $job['job_id'], 'type' => $type, 'status' => 'queued', 'timestamp' => date('c') ]; writeJson(JOB_QUEUE_FILE, $queue); writeJson(JOB_LOG_FILE, $jobLog); return $job; } function suggestAgent(string $jobType): string { return match ($jobType) { 'scan' => 'file_scanner_agent', 'security_scan' => 'security_agent', 'generate_project' => 'builder_agent', 'deploy' => 'deploy_agent', default => 'general_agent', }; } /* -------------------------------------------------------- * Registry / Memory * ------------------------------------------------------*/ function readRegistrySummary(): array { $file = __DIR__ . '/../data/file_registry.json'; $registry = readJson($file, []); $riskCounts = [ 'error' => 0, 'warning' => 0, 'orphan' => 0, 'valid' => 0 ]; foreach ($registry as $row) { $status = strtolower((string)($row['status'] ?? 'valid')); if (!isset($riskCounts[$status])) { $riskCounts[$status] = 0; } $riskCounts[$status]++; } $spoken = sprintf( 'Registry summary loaded. Errors: %d. Warnings: %d. Orphans: %d.', (int)($riskCounts['error'] ?? 0), (int)($riskCounts['warning'] ?? 0), (int)($riskCounts['orphan'] ?? 0) ); return [ 'counts' => $riskCounts, 'spoken_reply' => $spoken ]; } function appendMemory(array $entry): void { $memory = readJson(MEMORY_FILE, []); $memory[] = $entry; writeJson(MEMORY_FILE, $memory); } function extractProjectName(string $text): ?string { if (preg_match('/(?:called|named)\s+["\']?([^"\']{2,80})["\']?/i', $text, $m)) { return trim($m[1]); } return null; } /* -------------------------------------------------------- * Normalizers * ------------------------------------------------------*/ function normalizeVoice(string $voice): string { $allowed = ['alloy', 'ash', 'ballad', 'cedar', 'coral', 'echo', 'marin', 'sage', 'shimmer', 'verse']; $voice = strtolower(trim($voice)); return in_array($voice, $allowed, true) ? $voice : 'cedar'; } function normalizeTone(string $tone): string { $allowed = ['calm', 'warm', 'serious', 'playful', 'confident', 'dramatic']; $tone = strtolower(trim($tone)); return in_array($tone, $allowed, true) ? $tone : 'calm'; } function normalizeAttitude(string $attitude): string { $allowed = ['helpful', 'supportive', 'direct', 'assertive', 'gentle', 'professional']; $attitude = strtolower(trim($attitude)); return in_array($attitude, $allowed, true) ? $attitude : 'helpful'; } function normalizeEmotion(string $emotion): string { $allowed = ['warm', 'empathetic', 'excited', 'focused', 'neutral', 'reassuring']; $emotion = strtolower(trim($emotion)); return in_array($emotion, $allowed, true) ? $emotion : 'warm'; } function normalizeResponseStyle(string $style): string { $allowed = ['concise', 'balanced', 'detailed']; $style = strtolower(trim($style)); return in_array($style, $allowed, true) ? $style : 'concise'; } function normalizeSpeakingSpeed(string $speed): string { $allowed = ['slow', 'normal', 'fast']; $speed = strtolower(trim($speed)); return in_array($speed, $allowed, true) ? $speed : 'normal'; } function normalizeVerbosity(string $verbosity): string { $allowed = ['short', 'medium', 'long']; $verbosity = strtolower(trim($verbosity)); return in_array($verbosity, $allowed, true) ? $verbosity : 'short'; } /* -------------------------------------------------------- * Logging * ------------------------------------------------------*/ function logVoiceEvent(array $event): void { $payload = [ 'event_id' => 'evt_' . bin2hex(random_bytes(6)), 'event_type' => (string)($event['event_type'] ?? 'voice.event'), 'what' => (string)($event['what'] ?? ''), 'why' => (string)($event['why'] ?? ''), 'where' => (string)($event['where'] ?? ''), 'when' => date('c'), 'who' => (string)($event['who'] ?? 'unknown'), 'how' => (string)($event['how'] ?? 'voice'), 'result' => (string)($event['result'] ?? ''), 'meta' => $event['meta'] ?? new stdClass() ]; file_put_contents( EVENT_LOG_FILE, json_encode($payload, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE) . PHP_EOL, FILE_APPEND | LOCK_EX ); } /* -------------------------------------------------------- * Files / JSON * ------------------------------------------------------*/ function ensureDirectories(): void { foreach ([SIMON_DATA_DIR, SIMON_LOG_DIR] as $dir) { if (!is_dir($dir)) { mkdir($dir, 0775, true); } } } function ensureJsonFile(string $path, array $default): void { if (!is_file($path)) { writeJson($path, $default); } } function readJson(string $path, array $fallback): array { if (!is_file($path)) { return $fallback; } $raw = file_get_contents($path); $data = json_decode((string)$raw, true); return is_array($data) ? $data : $fallback; } function writeJson(string $path, array $data): void { file_put_contents( $path, json_encode($data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE), LOCK_EX ); } function respond(int $statusCode, array $payload): void { http_response_code($statusCode); echo json_encode($payload, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); exit; }
Save file
Quick jump
open a path
Open