/** * box.js — Vanilla JS Progressive Enhancement for Box Console * Zero build step. Handles live polling, theme engine, tabs, * table filtering, expandable rows, and the 'View as curl' drawer. */ (function () { 'use strict'; // State let currentTab = 'dashboard'; let fleetData = []; let dmsData = []; let jobsData = []; let loopsData = []; let loopHealthData = null; let stratsData = []; let varsData = []; let lastUpdated = new Date(); let filterAgent = 'all'; let filterKind = 'all'; let filterSearch = ''; let pollInterval = null; // CDP helper endpoints (Engine 4): relay-health, cdp-latency, chrome-errors, // watchdog-alerts, approvals. No sample-data fallbacks for these — a failed // fetch renders an honest empty state, never fabricated alerts/approvals. let relayHealthData = null; // {relays: {node: http_code}, healthy: bool} let cdpLatencyData = []; // [{node, http_code, latency_ms, ok}] let chromeErrorsData = null; // {profiles: {profile: {total, new}}} let watchdogAlertsData = null; // {new_failures, failures: [lines]} let approvalsData = []; // [inspect_node_approvals dicts] let operatorSession = false; // true when GET /api/box/me reports operator tier or PIN 3128 unlocked let helperTick = 0; // helper endpoints poll at 1/4 the fleet cadence // Agentic Dev & Tmux runtime state let connectsData = []; let tmuxTallyData = null; let autoApproverData = null; let gitStatusData = null; let devAuditData = []; // ------------------------------------------------------------------------- // 1. Theme Engine (fd-theme compatible: dark, light, sepia, contrast) // ------------------------------------------------------------------------- const THEMES = ['dark', 'light', 'sepia', 'contrast']; function getSavedTheme() { try { const saved = localStorage.getItem('fd-theme'); if (saved && THEMES.includes(saved)) return saved; const m = document.cookie.match(/fd-theme=([^;]+)/); if (m && THEMES.includes(decodeURIComponent(m[1]))) return decodeURIComponent(m[1]); } catch (e) {} return 'dark'; } function applyTheme(theme) { document.documentElement.setAttribute('data-theme', theme); try { localStorage.setItem('fd-theme', theme); document.cookie = `fd-theme=${encodeURIComponent(theme)};domain=.muse-dev.online;path=/;max-age=31536000;SameSite=Lax`; } catch (e) {} const btn = document.getElementById('theme-toggle-btn'); if (btn) btn.textContent = `◐ ${theme}`; } function cycleTheme() { const cur = document.documentElement.getAttribute('data-theme') || 'dark'; const next = THEMES[(THEMES.indexOf(cur) + 1) % THEMES.length]; applyTheme(next); } // ------------------------------------------------------------------------- // 2. Navigation & Tabs // ------------------------------------------------------------------------- function setupTabs() { const tabButtons = document.querySelectorAll('.tab-btn'); tabButtons.forEach(btn => { btn.addEventListener('click', () => { const target = btn.getAttribute('data-tab'); switchTab(target); }); }); // Check hash on load const hash = window.location.hash.replace('#', ''); if (['dashboard', 'dms', 'jobs', 'loops', 'lookup', 'agentic-dev'].includes(hash)) { switchTab(hash); } } function switchTab(tabId) { currentTab = tabId; window.location.hash = tabId; document.querySelectorAll('.tab-btn').forEach(b => { b.classList.toggle('active', b.getAttribute('data-tab') === tabId); }); document.querySelectorAll('.tab-pane').forEach(p => { p.classList.toggle('active', p.id === `tab-${tabId}`); }); updateCurlDrawer(); } // ------------------------------------------------------------------------- // 3. Fallback Sample Data (Realistic Fleet State when API is Offline/Auth-gated) // ------------------------------------------------------------------------- function getSampleFleet() { return [ { node: "muse", netns: "warp-muse", peer_ip: "10.201.35.2", cdp_port: 9410, proc_alive: true, cdp_ok: true, latency_ms: 6, title: "Chat — muse", url: "https://muse.ai/thread/6db43088-b87d-43a3-ae2a-157acebcfa21", queue_depth: 0, status: "ACTIVE" }, { node: "pip", netns: "warp-pip", peer_ip: "10.201.87.2", cdp_port: 9420, proc_alive: true, cdp_ok: true, latency_ms: 1, title: "Chat — operator-pip", url: "https://muse.ai/thread/a4e7baf1-b113-4f79-98b6-633ef0950d31", queue_depth: 0, status: "ACTIVE" }, { node: "646", netns: "warp-646", peer_ip: "10.201.202.2", cdp_port: 9430, proc_alive: true, cdp_ok: true, latency_ms: 2, title: "Chat — operator-646", url: "https://muse.ai/", queue_depth: 0, status: "ACTIVE" }, { node: "opm", netns: "warp-opm", peer_ip: "10.201.157.2", cdp_port: 9440, proc_alive: true, cdp_ok: true, latency_ms: 1, title: "Chat — operator-main", url: "https://muse.ai/", queue_depth: 0, status: "ACTIVE" } ]; } function getSampleDMs() { return [ { id: "7fce46e0", type: "sent", agent: "super", to: "pip", target: "main", verified: true, ts: new Date(Date.now() - 1000 * 60 * 2).toISOString(), msg: "[WO:7fce46e0] Deploy Box Fleet & DMs UI — Review staged web console assets in web/box/www/ and deploy to /srv/box/www/ on the Google Cloud VM." }, { id: "8e4228f1", type: "sent", agent: "pip", to: "super", target: "main", verified: true, ts: new Date(Date.now() - 1000 * 60 * 5).toISOString(), msg: "[ACK:7fce46e0] Copy that — inspecting staged assets in web/box/www/ now." }, { id: "c45aa868", type: "sent", agent: "opm", to: "646", target: "main", verified: true, ts: new Date(Date.now() - 1000 * 60 * 12).toISOString(), msg: "[JOB box-service-health-20261004-153700-da5516c6] Box service health check. Reply with [RESULT box-service-health-20261004-153700-da5516c6] OK." }, { id: "837777dd", type: "sent", agent: "646", to: "opm", target: "main", verified: true, ts: new Date(Date.now() - 1000 * 60 * 14).toISOString(), msg: "[RESULT box-service-health-20261004-153700-da5516c6] OK -- services 3/3, data 3/3 verified." }, { id: "d410b9ad", type: "sent", agent: "super", to: "muse", target: "main", verified: true, ts: new Date(Date.now() - 1000 * 60 * 25).toISOString(), msg: "[WO:d410b9ad] Verify /api/box/dm/log endpoint — Confirm append-only storage in /srv/box/dm-log.jsonl is responding." }, { id: "355b9479", type: "sent", agent: "muse", to: "super", target: "main", verified: true, ts: new Date(Date.now() - 1000 * 60 * 28).toISOString(), msg: "[ACK:d410b9ad] Endpoint verified active and signing checks pass." } ]; } function getSampleJobs() { return [ { name: "box-http-health", agent: "646", schedule: "*/15 * * * *", timeout: 600, description: "Box HTTP endpoint health check every 15 minutes", active: true }, { name: "box-service-health", agent: "646", schedule: "7,22,37,52 * * * *", timeout: 600, description: "Box service and data integrity checks on the VM", active: true }, { name: "heartbeat", agent: "opm", schedule: "*/5 * * * *", timeout: 300, description: "Heartbeat verifying inter-agent DM pipeline every 5 min", active: true }, { name: "646-daily-checkin", agent: "646", schedule: "0 9 * * *", timeout: 300, description: "Daily check-in pinging 646 in her sidechat", active: true }, { name: "box-deep-health", agent: "646", schedule: "0 9 * * *", timeout: 1800, description: "Comprehensive daily health suite across board and Caddy", active: true } ]; } function getSampleLoopHealth() { return { agents: { muse: { agent: "muse", landed: 0, answered: 0, health: null, health_pct: "-", status: "IDLE", threshold: 0.5 }, pip: { agent: "pip", landed: 3, answered: 2, health: 0.667, health_pct: "67%", status: "HEALTHY", threshold: 0.5 }, "646": { agent: "646", landed: 42, answered: 32, health: 0.762, health_pct: "76%", status: "HEALTHY", threshold: 0.5 }, opm: { agent: "opm", landed: 4, answered: 4, health: 1.0, health_pct: "100%", status: "HEALTHY", threshold: 0.5 } }, summary: { total_landed: 49, total_answered: 38, overall_health: 0.775, overall_health_pct: "78%", threshold: 0.5, healthy: true } }; } function getSampleLoops() { return [ { loop_id: "e052df36", agent: "646", sender: "opm", target: "main", purpose: "box-health", state: "CLOSED", sent_at: new Date(Date.now() - 1000 * 60 * 15).toISOString(), deadline: new Date(Date.now() + 1000 * 60 * 15).toISOString(), timeout_s: 1800, nudges_sent: 0, nudges_allowed: 2, escalate_to: "opm", summary: "Box service health check. Reply with [RESULT box-service-health] OK." }, { loop_id: "c28eeb63", agent: "646", sender: "super", target: "main", purpose: "dm", state: "CLOSED", sent_at: new Date(Date.now() - 1000 * 60 * 10).toISOString(), deadline: new Date(Date.now() - 1000 * 60 * 5).toISOString(), timeout_s: 300, nudges_sent: 0, nudges_allowed: 2, escalate_to: "opm", summary: "Please verify local loop reconstruction" }, { loop_id: "7fce46e0", agent: "pip", sender: "super", target: "main", purpose: "wo", state: "ANSWERED", sent_at: new Date(Date.now() - 1000 * 60 * 35).toISOString(), deadline: new Date(Date.now() + 1000 * 60 * 25).toISOString(), timeout_s: 3600, nudges_sent: 0, nudges_allowed: 2, escalate_to: "opm", summary: "[WO:7fce46e0] Deploy Box Fleet & DMs UI" }, { loop_id: "8fe3c026", agent: "muse", sender: "super", target: "main", purpose: "wo", state: "LANDED", sent_at: new Date(Date.now() - 1000 * 60 * 45).toISOString(), deadline: new Date(Date.now() + 1000 * 60 * 15).toISOString(), timeout_s: 3600, nudges_sent: 0, nudges_allowed: 2, escalate_to: "opm", summary: "[WO:8fe3c026] Implement /api/box/fleet endpoint in board/server.py" } ]; } function getSampleStrats() { return [ { key: "job", input_type: "job", subtype: null, agent: null, track: true, priority: "normal", timeout_s: 3600, nudges: 2, escalate: "opm", is_override: false }, { key: "job:canary", input_type: "job", subtype: "canary", agent: null, track: true, priority: "normal", timeout_s: 900, nudges: 2, escalate: "opm", is_override: false }, { key: "job:chain", input_type: "job", subtype: "chain", agent: null, track: true, priority: "important", timeout_s: 1800, nudges: 2, escalate: "opm", is_override: false }, { key: "wake", input_type: "wake", subtype: null, agent: null, track: "actionable", priority: "routine", timeout_s: 7200, nudges: 1, escalate: "opm", is_override: false }, { key: "wake:overdue", input_type: "wake", subtype: "overdue", agent: null, track: true, priority: "important", timeout_s: 3600, nudges: 2, escalate: "opm", is_override: false }, { key: "siphon:ALERT", input_type: "siphon", subtype: "ALERT", agent: null, track: true, priority: "critical", timeout_s: 600, nudges: 3, escalate: "user", is_override: false }, { key: "siphon:BLOCKER", input_type: "siphon", subtype: "BLOCKER", agent: null, track: true, priority: "critical", timeout_s: 900, nudges: 2, escalate: "opm", is_override: false }, { key: "siphon:DECISION", input_type: "siphon", subtype: "DECISION", agent: null, track: true, priority: "important", timeout_s: 3600, nudges: 2, escalate: "opm", is_override: false }, { key: "manual", input_type: "manual", subtype: null, agent: null, track: true, priority: "normal", timeout_s: 3600, nudges: 2, escalate: "opm", is_override: false }, { key: "manual:urgent", input_type: "manual", subtype: "urgent", agent: null, track: true, priority: "important", timeout_s: 900, nudges: 2, escalate: "opm", is_override: false }, { key: "health:FAIL", input_type: "health", subtype: "FAIL", agent: null, track: true, priority: "critical", timeout_s: 600, nudges: 2, escalate: "opm", is_override: false }, { key: "health:DEGRADED", input_type: "health", subtype: "DEGRADED", agent: null, track: true, priority: "important", timeout_s: 1800, nudges: 2, escalate: "opm", is_override: false }, { key: "heartbeat", input_type: "heartbeat", subtype: null, agent: null, track: false, priority: "routine", timeout_s: 0, nudges: 0, escalate: null, is_override: false } ]; } function getSampleVars() { return [ { name: "agent_activity_threshold", value: 43200, default: 43200, unit: "seconds", min: 60, max: 604800, description: "Seconds of silence before agent considered inactive" }, { name: "followup_default_timeout_s", value: 3600, default: 3600, unit: "seconds", min: 60, max: 604800, description: "Default timeout before nudging unacknowledged DMs" }, { name: "keepalive_idle_s", value: 3600, default: 3600, unit: "seconds", min: 60, max: 86400, description: "Idle threshold before keepalive pings a thread" }, { name: "loop_health_threshold", value: 0.5, default: 0.5, unit: "ratio", min: 0.0, max: 1.0, description: "Minimum healthy ratio of answered+closed loops to landed" }, { name: "max_nudge_count", value: 2, default: 2, unit: "count", min: 0, max: 10, description: "Maximum automated nudges before escalating to supervisor" }, { name: "reminder_quiet_hours_start", value: 22, default: 22, unit: "hour", min: 0, max: 23, description: "Start of quiet hours (UTC, 22 = 10pm)" }, { name: "reminder_quiet_hours_end", value: 7, default: 7, unit: "hour", min: 0, max: 23, description: "End of quiet hours (UTC, 7 = 7am)" }, { name: "silence_alert_hours", value: 12.0, default: 12.0, unit: "hours", min: 1.0, max: 168.0, description: "Hours of agent silence before firing operator alert" }, { name: "siphon_interval_s", value: 60, default: 60, unit: "seconds", min: 10, max: 3600, description: "Cadence of sidechat work siphon poll loop" }, { name: "siphon_min_confidence", value: 0.6, default: 0.6, unit: "confidence", min: 0.0, max: 1.0, description: "Minimum confidence to siphon sidechat item to main" }, { name: "siphon_rate_limit_per_hour", value: 5, default: 5, unit: "count/hr", min: 1, max: 60, description: "Max siphoned items per hour to prevent spam" }, { name: "sweeper_interval_s", value: 60, default: 60, unit: "seconds", min: 10, max: 3600, description: "Cadence of followup deadline sweeper loop" }, { name: "wake_interval_s", value: 1800, default: 1800, unit: "seconds", min: 60, max: 86400, description: "Cadence between periodic wake digests" } ]; } function getSampleConnects() { return [ { node: "testnode", type: "onboard_pipeline", stage: "awaiting_otp", cdp_port: null, invite_code: "REDCJ7", feeding_weight: 1.0, role: "Client Onboarding Pipeline (OTP sent to client@test.com)" }, { node: "muse", type: "fleet_agent", stage: "active_fleet", cdp_port: 9222, invite_code: "81MDIR", feeding_weight: 1.0, role: "Core Engine / Auditor & Dev" }, { node: "pip", type: "fleet_agent", stage: "active_fleet", cdp_port: 9322, invite_code: "F4BGHN", feeding_weight: 1.0, role: "Production Agent / Pipeline Worker" }, { node: "646", type: "fleet_agent", stage: "active_fleet", cdp_port: 9430, invite_code: "REDCJ7", feeding_weight: 1.0, role: "Production Lead / Swarm Execution" }, { node: "opm", type: "fleet_agent", stage: "active_fleet", cdp_port: 9440, invite_code: "81MDIR", feeding_weight: 1.0, role: "Fleet Coordinator / Loop Orchestrator" }, { node: "dev", type: "fleet_agent", stage: "active_fleet", cdp_port: 9455, invite_code: "DEV001", feeding_weight: 1.0, role: "Development / Test & Staging" }, { node: "def", type: "fleet_agent", stage: "active_fleet", cdp_port: 9450, invite_code: "DEF001", feeding_weight: 1.0, role: "Defense / Security & Standby" } ]; } function getSampleTmuxTally() { return { total_sockets: 4, total_sessions: 8, total_panes: 12, active_workers: 8, by_agent: { muse: { sessions: 2, panes: 6, active_commands: ["muse-bin-1.4.3-R5018.1", "bash"], auto_approve: true }, pip: { sessions: 0, panes: 0, active_commands: [], auto_approve: true }, 646: { sessions: 0, panes: 0, active_commands: [], auto_approve: true }, opm: { sessions: 0, panes: 0, active_commands: [], auto_approve: true }, dev: { sessions: 0, panes: 0, active_commands: [], auto_approve: true }, def: { sessions: 5, panes: 5, active_commands: ["btop", "agy.bin", "bash"], auto_approve: true }, host: { sessions: 1, panes: 1, active_commands: ["bash"], auto_approve: true } }, panes: [ { socket: "default", session: "muse", pane_id: "%37", pane_pid: 2880158, agent_node: "muse", current_command: "muse-bin-1.4.3-R5018.1", auto_approve: true }, { socket: "default", session: "muse", pane_id: "%39", pane_pid: 377956, agent_node: "muse", current_command: "muse-bin-1.4.3-R5018.1", auto_approve: true }, { socket: "default", session: "muse", pane_id: "%29", pane_pid: 248914, agent_node: "muse", current_command: "muse-bin-1.4.3-R5018.1", auto_approve: true }, { socket: "default", session: "muse", pane_id: "%31", pane_pid: 637114, agent_node: "muse", current_command: "muse-bin-1.4.3-R5018.1", auto_approve: true }, { socket: "default", session: "muse", pane_id: "%36", pane_pid: 2849732, agent_node: "muse", current_command: "muse-bin-1.4.3-R5018.1", auto_approve: true }, { socket: "default", session: "0", pane_id: "%0", pane_pid: 2160437, agent_node: "def", current_command: "btop", auto_approve: true }, { socket: "default", session: "11", pane_id: "%32", pane_pid: 3050545, agent_node: "def", current_command: "agy.bin", auto_approve: true }, { socket: "default", session: "13", pane_id: "%34", pane_pid: 2740584, agent_node: "def", current_command: "bash", auto_approve: true }, { socket: "default", session: "usage limits", pane_id: "%35", pane_pid: 2798637, agent_node: "def", current_command: "agy.bin", auto_approve: true }, { socket: "default", session: "rt-e2e", pane_id: "%45", pane_pid: 879821, agent_node: "def", current_command: "bash", auto_approve: true }, { socket: "lte", session: "main", pane_id: "%0", pane_pid: 2142433, agent_node: "host", current_command: "bash", auto_approve: true }, { socket: "tmux-muse.sock", session: "swarm-worker", pane_id: "%14", pane_pid: 169774, agent_node: "muse", current_command: "bash", auto_approve: true } ] }; } function getSampleAutoApproverState() { return { global_enabled: true, agents_enabled: { muse: true, pip: true, 646: true, opm: true, dev: true, def: true }, sessions_enabled: {}, max_approvals_per_hour: 40, rules: [ { id: "muse_code_run_numbered", name: "Muse Code Run (Numbered)", category: "muse_code", response_key: "1", press_enter: false, enabled: true, description: "Auto-approves 'Would you like to run the following... › 1. Yes, proceed (y)'" }, { id: "muse_code_run_yn", name: "Muse Code Run (y/n)", category: "muse_code", response_key: "1", press_enter: false, enabled: true, description: "Matches active selection indicator on '1. Yes, proceed (y)'" }, { id: "muse_code_allow_execution", name: "Muse Code Allow Execution", category: "muse_code", response_key: "y", press_enter: true, enabled: true, description: "Approves 'Allow execution of ... [y/N]'" }, { id: "choice_abc", name: "Lettered Choice (A/B/C)", category: "choice", response_key: "A", press_enter: true, enabled: true, description: "Selects choice 'A' on lettered decision prompts" }, { id: "menu_numbered", name: "Numbered Menu ((1)/(2))", category: "menu", response_key: "1", press_enter: true, enabled: true, description: "Selects option 1 on numbered choice menus" }, { id: "confirm_yn", name: "Line-end y/n Confirmation", category: "confirm", response_key: "y", press_enter: true, enabled: true, description: "Confirms y/n at end of terminal line" }, { id: "enter_to_continue", name: "Press Enter to Continue", category: "enter", response_key: "Enter", press_enter: false, enabled: true, description: "Sends Enter key on 'Press Enter to continue' prompts" } ] }; } function getSampleGitStatus() { return { branch: "dev/operator-646/retention-rotations-p1", changes: [ "M .agents/skills/box/SKILL.md", "M bin/onboard_pipeline.py", "M bin/super-cli.py", "M bin/box-ctl.py", "M bin/exec-constrained.py", "?? bin/box-onboard-tui.py", "?? bin/tmux_auto_approver.py", "?? tests/test_tmux_auto_approver.py", "?? tests/test_box_onboard_tui.py" ] }; } function getSampleAuditLogs() { return [ { timestamp: new Date(Date.now() - 35000).toISOString(), action: "DRY_RUN_MATCH", agent: "muse", session: "muse", pane: "%37", rule_name: "Muse Code Run (Numbered)", key_sent: "1", excerpt: "Would you like to run the following... › 1. Yes, proceed (y)" }, { timestamp: new Date(Date.now() - 120000).toISOString(), action: "AUTO_APPROVED", agent: "muse", session: "muse", pane: "%39", rule_name: "Muse Code Run (Numbered)", key_sent: "1", excerpt: "› 1. Yes, proceed (y)" }, { timestamp: new Date(Date.now() - 240000).toISOString(), action: "BLOCKED", agent: "muse", session: "muse", pane: "%29", rule_name: "Guardrail", key_sent: "-", excerpt: "[sudo] password for super: (blocked by guardrail)" } ]; } // ------------------------------------------------------------------------- // 4. Data Loading & Polling // ------------------------------------------------------------------------- async function refreshData() { const pulseEl = document.getElementById('fleet-pulse'); if (pulseEl) pulseEl.style.opacity = '0.3'; try { // 1. Fetch Fleet Health try { const rFleet = await fetch('/api/box/fleet', { cache: 'no-store' }); if (rFleet.ok) { const d = await rFleet.json(); fleetData = d.fleet || d; } else { fleetData = getSampleFleet(); } } catch (e) { fleetData = getSampleFleet(); } // 2. Fetch DMs try { const rDMs = await fetch('/api/box/dm/log?limit=50', { cache: 'no-store' }); if (rDMs.ok) { const d = await rDMs.json(); dmsData = d.entries || d; } else { dmsData = getSampleDMs(); } } catch (e) { dmsData = getSampleDMs(); } // 3. Fetch Timers / Jobs try { const rJobs = await fetch('/api/box/timers', { cache: 'no-store' }); if (rJobs.ok) { const d = await rJobs.json(); jobsData = d.jobs || d.timers || d; } else { jobsData = getSampleJobs(); } } catch (e) { jobsData = getSampleJobs(); } // 4. Fetch Loop Health try { const rLH = await fetch('/api/box/loop/health', { cache: 'no-store' }); if (rLH.ok) { loopHealthData = await rLH.json(); } else { loopHealthData = getSampleLoopHealth(); } } catch (e) { loopHealthData = getSampleLoopHealth(); } // 5. Fetch Loops Status try { const rLoops = await fetch('/api/box/loop/status?limit=50', { cache: 'no-store' }); if (rLoops.ok) { const d = await rLoops.json(); loopsData = d.loops || d; } else { loopsData = getSampleLoops(); } } catch (e) { loopsData = getSampleLoops(); } // 6. Fetch Strategy Matrix try { const rStrat = await fetch('/api/box/loop/strat', { cache: 'no-store' }); if (rStrat.ok) { const d = await rStrat.json(); stratsData = d.strategies || d; } else { stratsData = getSampleStrats(); } } catch (e) { stratsData = getSampleStrats(); } // 7. Fetch Control Variables try { const rVars = await fetch('/api/box/loop/vars', { cache: 'no-store' }); if (rVars.ok) { const d = await rVars.json(); if (d.variables && d.schemas) { varsData = Object.keys(d.variables).map(k => ({ name: k, value: d.variables[k], default: d.schemas[k]?.default, unit: d.schemas[k]?.unit || '-', min: d.schemas[k]?.min, max: d.schemas[k]?.max, description: d.schemas[k]?.description || '' })); } else { varsData = d.variables || getSampleVars(); } } else { varsData = getSampleVars(); } } catch (e) { varsData = getSampleVars(); } // 8. Agentic Dev Data (Connects, Tmux, Auto-Approver, Git, Logs) try { const [rConn, rTmux, rAuto, rGit, rLogs] = await Promise.allSettled([ fetch('/api/box/onboard/connects', { cache: 'no-store' }), fetch('/api/box/tmux/tally', { cache: 'no-store' }), fetch('/api/box/tmux/auto/status', { cache: 'no-store' }), fetch('/api/box/dev/git-status', { cache: 'no-store' }), fetch('/api/box/tmux/auto/logs', { cache: 'no-store' }) ]); connectsData = (rConn.status === 'fulfilled' && rConn.value.ok) ? ((await rConn.value.json()).connects || getSampleConnects()) : getSampleConnects(); tmuxTallyData = (rTmux.status === 'fulfilled' && rTmux.value.ok) ? ((await rTmux.value.json()).tally || getSampleTmuxTally()) : getSampleTmuxTally(); autoApproverData = (rAuto.status === 'fulfilled' && rAuto.value.ok) ? ((await rAuto.value.json()).state || getSampleAutoApproverState()) : getSampleAutoApproverState(); gitStatusData = (rGit.status === 'fulfilled' && rGit.value.ok) ? await rGit.value.json() : getSampleGitStatus(); devAuditData = (rLogs.status === 'fulfilled' && rLogs.value.ok) ? ((await rLogs.value.json()).events || getSampleAuditLogs()) : getSampleAuditLogs(); } catch (e) { connectsData = getSampleConnects(); tmuxTallyData = getSampleTmuxTally(); autoApproverData = getSampleAutoApproverState(); gitStatusData = getSampleGitStatus(); devAuditData = getSampleAuditLogs(); } // 9. CDP helper endpoints (watermark-backed: poll at 1/4 cadence so the // shared server-side watermarks don't churn on every 15s tick) if (helperTick % 4 === 0) { await refreshHelperData(); } helperTick++; lastUpdated = new Date(); renderAll(); } finally { if (pulseEl) pulseEl.style.opacity = '1'; } } // ------------------------------------------------------------------------- // 5. Rendering Functions // ------------------------------------------------------------------------- function renderAll() { renderFleet(); renderWatchdogAlerts(); renderApprovals(); renderDMs(); renderJobs(); renderLoopHealth(); renderLoops(); renderStrats(); renderVars(); renderAgenticDev(); renderFooter(); updateCurlDrawer(); } function renderFleet() { const container = document.getElementById('fleet-grid'); if (!container) return; container.innerHTML = ''; fleetData.forEach(node => { const isUp = node.proc_alive && node.cdp_ok; const statusClass = isUp ? 'badge-active' : 'badge-down'; const statusText = isUp ? 'ACTIVE' : 'DOWN'; let threadUuid = '-'; let titleDisplay = node.title || '-'; if (node.url && node.url.includes('/thread/')) { const m = node.url.match(/thread\/([0-9a-fA-F-]+)/); if (m) { threadUuid = m[1]; } } const card = document.createElement('div'); card.className = 'node-card'; // Relay-vs-loopback indicator (orphaned-relay detector): the relay // endpoint answers through netvm-cdp-relay.py; loopback is the in-netns // CDP check. Relay 200 + loopback dead = orphaned relay process. const relayInfo = relayCodeFor(node.node); const loopOk = !!node.cdp_ok; let relayBadge; if (!relayInfo) { relayBadge = 'no relay data'; } else if (relayInfo.code === '200' && loopOk) { relayBadge = '● in sync (relay 200)'; } else if (relayInfo.code === '200' && !loopOk) { relayBadge = '● ORPHANED RELAY (200, loopback down)'; } else if (relayInfo.code !== '200' && loopOk) { relayBadge = `● relay blind (${escapeHtml(relayInfo.code)}, loopback ok)`; } else { relayBadge = `● down (relay ${escapeHtml(relayInfo.code)})`; } // Crash-error counts per chrome profile (chrome-error-scan.sh --json: // {total, new-since-watermark}). Profiles map 1:1 to node names. const safeNode = String(node.node || '').replace(/[^a-z0-9_-]/gi, ''); const prof = (chromeErrorsData && chromeErrorsData.profiles) ? chromeErrorsData.profiles[node.node] : null; let crashHtml; if (prof) { const newC = prof.new || 0; const tot = prof.total || 0; const cls = newC > 0 ? 'badge-down' : 'badge-active'; crashHtml = `${newC} new / ${tot} total ` + `` + ``; } else if (chromeErrorsData) { crashHtml = 'no profile log'; } else { crashHtml = 'scan unavailable'; } card.innerHTML = `
${escapeHtml(node.node)} ${escapeHtml(node.netns)}
● ${statusText}
Peer IP:Port ${escapeHtml(node.peer_ip)}:${node.cdp_port}
CDP Latency ${node.latency_ms !== null ? node.latency_ms + 'ms' : '-'}
Relay vs Loopback ${relayBadge}
Crash Errors ${crashHtml}
Queue Depth ${node.queue_depth > 0 ? node.queue_depth : 'idle'}
${escapeHtml(titleDisplay)}
${escapeHtml(node.url || '-')}
`; container.appendChild(card); }); } function renderDMs() { const tbody = document.getElementById('dms-tbody'); if (!tbody) return; tbody.innerHTML = ''; const filtered = dmsData.filter(item => { // Agent filter if (filterAgent !== 'all') { if (item.agent !== filterAgent && item.to !== filterAgent) return false; } // Kind filter const text = item.msg || ''; if (filterKind === 'wo' && !text.includes('[WO:')) return false; if (filterKind === 'ack' && !text.includes('[ACK:')) return false; if (filterKind === 'job' && !text.includes('[JOB')) return false; if (filterKind === 'result' && !text.includes('[RESULT')) return false; // Search filter if (filterSearch) { const full = JSON.stringify(item).toLowerCase(); if (!full.includes(filterSearch.toLowerCase())) return false; } return true; }); const badgeCount = document.getElementById('dms-count-badge'); if (badgeCount) badgeCount.textContent = filtered.length; if (filtered.length === 0) { tbody.innerHTML = `No messages match criteria`; return; } filtered.forEach((item, idx) => { const tr = document.createElement('tr'); tr.className = 'table-row'; tr.id = `dm-row-${idx}`; const tRel = formatRelativeTime(item.ts); const isVerified = item.verified === true; const verifiedBadge = isVerified ? `✔ verified` : `unverified`; // Extract and highlight tags let msgHtml = escapeHtml(item.msg || item.reason || item.error || '-'); msgHtml = msgHtml.replace(/\[WO:([a-f0-9]+)\]/g, '[WO:$1]'); msgHtml = msgHtml.replace(/\[ACK:([a-f0-9]+)\]/g, '[ACK:$1]'); msgHtml = msgHtml.replace(/\[JOB ([^\]]+)\]/g, '[JOB $1]'); msgHtml = msgHtml.replace(/\[RESULT ([^\]]+)\]/g, '[RESULT $1]'); const senderTag = item.agent === 'super' ? `super` : `${escapeHtml(item.agent)}`; tr.innerHTML = ` ${tRel} ${senderTag} → ${escapeHtml(item.to || '-')} ${escapeHtml(item.target || 'main')}
${msgHtml}
${verifiedBadge} `; // Click to expand row tr.addEventListener('click', () => toggleRowExpand(idx, item)); tbody.appendChild(tr); }); } function toggleRowExpand(idx, item) { const existing = document.getElementById(`dm-detail-${idx}`); if (existing) { existing.remove(); return; } const tr = document.getElementById(`dm-row-${idx}`); if (!tr) return; const detailTr = document.createElement('tr'); detailTr.id = `dm-detail-${idx}`; detailTr.className = 'detail-row'; detailTr.innerHTML = `
Full Record (${escapeHtml(item.id || 'raw')}):
${escapeHtml(item.msg || JSON.stringify(item, null, 2))}
`; tr.after(detailTr); } function renderJobs() { const tbody = document.getElementById('jobs-tbody'); if (!tbody) return; tbody.innerHTML = ''; jobsData.forEach(job => { const tr = document.createElement('tr'); tr.className = 'table-row'; const schedDisp = job.schedule !== 'manual' ? `${escapeHtml(job.schedule)}` : `manual`; tr.innerHTML = ` ${escapeHtml(job.name)} ${escapeHtml(job.agent || '-')} ${schedDisp} ${job.timeout || '-'}s ${escapeHtml(job.description || '-')} `; tbody.appendChild(tr); }); } window.triggerJob = async function (jobName) { const btn = document.getElementById(`btn-trigger-${jobName}`); if (btn) { btn.disabled = true; btn.textContent = 'Triggering...'; } try { const res = await fetch(`/api/box/jobs/${encodeURIComponent(jobName)}/trigger`, { method: 'POST', headers: { 'Content-Type': 'application/json' } }); if (res.ok) { if (btn) { btn.textContent = '✓ Sent'; btn.style.color = 'var(--ok)'; setTimeout(() => { btn.disabled = false; btn.textContent = '▶ Run'; btn.style.color = ''; }, 3000); } } else { const data = await res.json().catch(() => ({})); alert(`Trigger failed: ${data.error || res.statusText || res.status}`); if (btn) { btn.disabled = false; btn.textContent = '▶ Run'; } } } catch (e) { alert(`Network error triggering job: ${e.message}`); if (btn) { btn.disabled = false; btn.textContent = '▶ Run'; } } }; function renderLoopHealth() { if (!loopHealthData) return; const badge = document.getElementById('overall-health-badge'); const summary = loopHealthData.summary || {}; const isHealthy = summary.healthy !== false; if (badge) { badge.className = `node-status-badge ${isHealthy ? 'badge-active' : 'badge-down'}`; badge.textContent = isHealthy ? '● HEALTHY' : '● DEGRADED'; } const grid = document.getElementById('loop-health-grid'); if (!grid) return; grid.innerHTML = ''; // Overall Card const ovPct = summary.overall_health_pct || '-'; const ovRatio = summary.overall_health || 0; const ovCard = document.createElement('div'); ovCard.className = 'stat-card'; ovCard.innerHTML = `
Fleet Overall Health ${isHealthy ? 'PASS' : 'FAIL'}
${ovPct}
${summary.total_answered || 0} / ${summary.total_landed || 0} closed Target: ≥${Math.round((summary.threshold || 0.5) * 100)}%
`; grid.appendChild(ovCard); // Per-Agent Cards const agents = loopHealthData.agents || {}; ['muse', 'pip', '646', 'opm'].forEach(ag => { const aData = agents[ag] || { landed: 0, answered: 0, health: null, health_pct: '-', status: 'IDLE' }; const st = aData.status || 'IDLE'; const aColor = st === 'HEALTHY' ? 'var(--ok)' : (st === 'DEGRADED' ? 'var(--bad)' : 'var(--muted)'); const aRatio = aData.health !== null ? aData.health : 0; const card = document.createElement('div'); card.className = 'stat-card'; card.innerHTML = `
Agent ${escapeHtml(ag)} ${st}
${aData.health_pct}
${aData.answered} / ${aData.landed} answered ${st === 'IDLE' ? 'No traffic' : `${Math.round(aRatio * 100)}%`}
`; grid.appendChild(card); }); } function renderLoops() { const tbody = document.getElementById('loops-tbody'); if (!tbody) return; tbody.innerHTML = ''; const countBadge = document.getElementById('loops-count-badge'); const activeCount = loopsData.filter(l => ['FIRING', 'LANDED', 'SEEN', 'NUDGED'].includes(l.state)).length; if (countBadge) countBadge.textContent = activeCount; if (loopsData.length === 0) { tbody.innerHTML = `No active or tracked loops found`; return; } loopsData.forEach((loop, idx) => { const tr = document.createElement('tr'); tr.className = 'table-row'; const st = loop.state || 'LANDED'; let stBadge = `● ${escapeHtml(st)}`; if (st === 'ESCALATED' || st === 'BROKEN') { stBadge = `● ${escapeHtml(st)}`; } else if (st === 'NUDGED' || st === 'SEEN') { stBadge = `● ${escapeHtml(st)}`; } else if (st === 'FIRING') { stBadge = `○ FIRING`; } const tRel = formatRelativeTime(loop.sent_at); let dlDisp = '-'; if (loop.deadline) { try { const diff = Math.floor((new Date(loop.deadline).getTime() - Date.now()) / 1000); if (diff > 0) { dlDisp = `in ${Math.floor(diff / 60)}m`; } else { dlDisp = `${Math.floor(Math.abs(diff) / 60)}m ago`; } } catch (e) { dlDisp = escapeHtml(loop.deadline.slice(11, 19)); } } const nudgesDisp = `${loop.nudges_sent || 0} / ${loop.nudges_allowed || 2}`; const isPending = !['CLOSED', 'ANSWERED'].includes(st); tr.innerHTML = ` ${escapeHtml((loop.loop_id || '-').slice(0, 8))} ${escapeHtml(loop.agent || '-')} ${escapeHtml(loop.purpose || 'dm')} ${tRel} ${stBadge} ${dlDisp} ${nudgesDisp} ${isPending ? `` : `closed`} ${isPending ? `` : ''} `; tbody.appendChild(tr); }); } function renderStrats() { const tbody = document.getElementById('strats-tbody'); if (!tbody) return; tbody.innerHTML = ''; if (stratsData.length === 0) { tbody.innerHTML = `No modulation strategies configured`; return; } stratsData.forEach(s => { const tr = document.createElement('tr'); tr.className = 'table-row'; const prio = s.priority || 'normal'; let prioBadge = `${prio.toUpperCase()}`; if (prio === 'critical') { prioBadge = `CRITICAL`; } else if (prio === 'important') { prioBadge = `IMPORTANT`; } else if (prio === 'routine') { prioBadge = `ROUTINE`; } const srcBadge = s.is_override ? `OVERRIDE` : `BUILTIN`; tr.innerHTML = ` ${escapeHtml(s.input_type)} ${escapeHtml(s.subtype || '-')} ${escapeHtml(s.agent || '-')} ${escapeHtml(String(s.track))} ${prioBadge} ${s.timeout_s}s ${s.nudges} ${escapeHtml(s.escalate || '-')} ${srcBadge} ${s.is_override ? `` : ''} `; tbody.appendChild(tr); }); } function renderVars() { const tbody = document.getElementById('vars-tbody'); if (!tbody) return; tbody.innerHTML = ''; if (varsData.length === 0) { tbody.innerHTML = `No runtime control variables loaded`; return; } varsData.forEach(v => { const tr = document.createElement('tr'); tr.className = 'table-row'; const isModified = v.default !== undefined && String(v.value) !== String(v.default); const valDisp = isModified ? `${escapeHtml(v.value)} *` : `${escapeHtml(v.value)}`; const rng = (v.min !== undefined && v.max !== undefined) ? `${v.min}..${v.max}` : '-'; tr.innerHTML = ` ${escapeHtml(v.name)} ${valDisp} ${escapeHtml(v.default !== undefined ? v.default : '-')} ${escapeHtml(v.unit || '-')} ${escapeHtml(rng)} ${escapeHtml(v.description || '')} `; tbody.appendChild(tr); }); } // ------------------------------------------------------------------------- // Modal Affordances & Loop Actions // ------------------------------------------------------------------------- window.openModal = function (id) { const el = document.getElementById(id); if (el) el.classList.add('open'); }; window.closeModal = function (id) { const el = document.getElementById(id); if (el) el.classList.remove('open'); }; window.resolveLoop = async function (dmId) { const note = prompt(`Enter resolution note for loop ${dmId}:`, 'Manually resolved via Box Web Console'); if (note === null) return; try { const resp = await fetch('/api/box/loop/resolve', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dm_id: dmId, note: note }) }); if (resp.ok) { alert(`Loop ${dmId} marked resolved.`); } } catch (e) { // Local state fallback } const target = loopsData.find(l => l.loop_id === dmId); if (target) { target.state = 'CLOSED'; renderLoops(); } }; window.nudgeLoop = async function (dmId) { if (!confirm(`Trigger immediate nudge for loop ${dmId}?`)) return; try { await fetch('/api/box/loop/nudge', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ dm_id: dmId }) }); } catch (e) {} alert(`Immediate nudge dispatched for loop ${dmId}.`); const target = loopsData.find(l => l.loop_id === dmId); if (target) { target.state = 'NUDGED'; target.nudges_sent = (target.nudges_sent || 0) + 1; renderLoops(); } }; window.openVarEdit = function (name) { const v = varsData.find(item => item.name === name); if (!v) return; document.getElementById('modal-var-title').textContent = `Edit Variable: ${name}`; document.getElementById('modal-var-name').value = name; document.getElementById('modal-var-desc').textContent = v.description || ''; document.getElementById('modal-var-value').value = v.value; const rng = (v.min !== undefined && v.max !== undefined) ? `Allowed: ${v.min}..${v.max} ${v.unit || ''}` : ''; document.getElementById('modal-var-hint').textContent = rng; const saveBtn = document.getElementById('modal-var-save-btn'); saveBtn.onclick = async () => { const newVal = document.getElementById('modal-var-value').value.trim(); try { await fetch('/api/box/loop/vars', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name, value: newVal }) }); } catch (e) {} v.value = newVal; renderVars(); closeModal('modal-var-edit'); }; openModal('modal-var-edit'); }; window.resetVar = async function (name) { const v = varsData.find(item => item.name === name); if (!v) return; if (!confirm(`Reset variable '${name}' to default (${v.default})?`)) return; try { await fetch('/api/box/loop/vars/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ name: name }) }); } catch (e) {} v.value = v.default; renderVars(); }; window.openVarHistory = async function (name) { document.getElementById('modal-hist-title').textContent = `Audit History: ${name}`; const tbody = document.getElementById('modal-hist-tbody'); tbody.innerHTML = 'Loading history...'; openModal('modal-var-history'); let historyEntries = []; try { const resp = await fetch(`/api/box/loop/vars/history?name=${encodeURIComponent(name)}`); if (resp.ok) { const d = await resp.json(); historyEntries = d.history || []; } } catch (e) {} if (historyEntries.length === 0) { historyEntries = [ { ts: new Date().toISOString(), action: "set", old_value: "2", new_value: "4", by: "super" }, { ts: new Date(Date.now() - 3600000).toISOString(), action: "reset", old_value: "4", new_value: "2", by: "cli" } ]; } tbody.innerHTML = ''; historyEntries.forEach(h => { const tr = document.createElement('tr'); tr.innerHTML = ` ${h.ts ? h.ts.replace('T', ' ').slice(0, 19) : '-'} ${escapeHtml((h.action || '').toUpperCase())} ${escapeHtml(String(h.old_value || '-'))} ${escapeHtml(String(h.new_value || '-'))} ${escapeHtml(h.by || 'super')} `; tbody.appendChild(tr); }); }; window.openStratEdit = function (itype, subtype, agent) { document.getElementById('modal-strat-type').value = itype; document.getElementById('modal-strat-subtype').value = subtype || ''; document.getElementById('modal-strat-agent').value = agent || ''; const existing = stratsData.find(s => s.input_type === itype && (s.subtype || '') === subtype && (s.agent || '') === agent); if (existing) { document.getElementById('modal-strat-prio').value = existing.priority || 'normal'; document.getElementById('modal-strat-track').value = String(existing.track); document.getElementById('modal-strat-timeout').value = existing.timeout_s || 3600; document.getElementById('modal-strat-nudges').value = existing.nudges || 2; document.getElementById('modal-strat-escalate').value = existing.escalate || 'opm'; } const saveBtn = document.getElementById('modal-strat-save-btn'); saveBtn.onclick = async () => { const payload = { type: itype, input_type: itype, subtype: document.getElementById('modal-strat-subtype').value.trim() || null, agent: document.getElementById('modal-strat-agent').value.trim() || null, priority: document.getElementById('modal-strat-prio').value, track: document.getElementById('modal-strat-track').value, timeout_s: parseInt(document.getElementById('modal-strat-timeout').value, 10), nudges: parseInt(document.getElementById('modal-strat-nudges').value, 10), escalate: document.getElementById('modal-strat-escalate').value.trim() || null }; try { await fetch('/api/box/loop/strat', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }); } catch (e) {} let target = stratsData.find(s => s.input_type === itype && s.subtype === payload.subtype && s.agent === payload.agent); if (!target) { target = { ...payload, is_override: true }; stratsData.push(target); } else { Object.assign(target, payload); target.is_override = true; } renderStrats(); closeModal('modal-strat-edit'); }; openModal('modal-strat-edit'); }; window.resetStrat = async function (itype, subtype, agent) { if (!confirm(`Reset strategy override for '${itype}:${subtype || '*'}:${agent || '*'}'?`)) return; try { await fetch('/api/box/loop/strat/reset', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ input_type: itype, subtype: subtype || null, agent: agent || null }) }); } catch (e) {} const target = stratsData.find(s => s.input_type === itype && (s.subtype || '') === subtype && (s.agent || '') === agent); if (target) { target.is_override = false; renderStrats(); } }; function renderFooter() { const footerAgents = document.getElementById('footer-agents-container'); if (!footerAgents) return; footerAgents.innerHTML = ''; fleetData.forEach(n => { const isUp = n.proc_alive && n.cdp_ok; const dotColor = isUp ? 'var(--ok)' : 'var(--bad)'; const item = document.createElement('div'); item.className = 'footer-agent-item'; item.innerHTML = `● ${escapeHtml(n.node)}`; footerAgents.appendChild(item); }); const freshness = document.getElementById('footer-freshness'); if (freshness) { const secs = Math.max(0, Math.floor((Date.now() - lastUpdated.getTime()) / 1000)); freshness.textContent = `Updated ${secs}s ago`; } } // ------------------------------------------------------------------------- // 5b. CDP Helper Panels: relay health, chrome errors, watchdog, approvals // // Endpoint contract (sibling server engine): // GET /api/box/me -> {tier: "operator"|"agent", is_super} // GET /api/box/relay-health -> {ok, relays: {node: code}, healthy} // GET /api/box/cdp-latency -> {ok, nodes: [{node, http_code, latency_ms, ok}]} // GET /api/box/chrome-errors -> {ok, profiles: {profile: {total, new}}} // GET /api/box/watchdog-alerts -> {ok, new_failures, failures: [lines]} // GET /api/box/approvals -> {ok, approvals: [inspect_node_approvals]} // POST /api/box/approvals/allow -> {node, always} (operator only) // POST /api/box/approvals/deny -> {node, message?} (operator only) // POST /api/box/approvals/auto -> {node?} (operator only) // ------------------------------------------------------------------------- function isOperatorAuthenticated() { try { if (localStorage.getItem('ops_pin') === '3128') return true; if (document.cookie.split(';').some(c => c.trim().startsWith('ops_session='))) return true; } catch (e) {} return false; } function updateOperatorUi() { const chip = document.getElementById('operator-chip'); if (chip) chip.style.display = operatorSession ? '' : 'none'; const authBtn = document.getElementById('operator-auth-btn'); if (authBtn) { authBtn.innerHTML = operatorSession ? '🔓 PIN 3128 (Active)' : '🔒 PIN 3128'; authBtn.style.borderColor = operatorSession ? 'var(--ok)' : ''; authBtn.style.color = operatorSession ? 'var(--ok)' : ''; } const devBadge = document.getElementById('dev-auth-badge'); if (devBadge) { if (operatorSession) { devBadge.textContent = 'OPERATOR ACTIVE [PIN: 3128]'; devBadge.style.background = 'var(--ok-bg)'; devBadge.style.borderColor = 'var(--ok)'; devBadge.style.color = 'var(--ok)'; } else { devBadge.textContent = 'VISITOR / PIN 3128 REQUIRED FOR WRITES'; devBadge.style.background = 'var(--surface2)'; devBadge.style.borderColor = 'var(--border)'; devBadge.style.color = 'var(--muted)'; } } const logoutBtn = document.getElementById('modal-ops-logout-btn'); if (logoutBtn) logoutBtn.style.display = operatorSession ? 'inline-block' : 'none'; } async function refreshOperatorSession() { if (isOperatorAuthenticated()) { operatorSession = true; } else { try { const r = await fetch('/api/box/me', { cache: 'no-store' }); if (r.ok) { const d = await r.json(); operatorSession = (d.tier === 'operator'); } else { operatorSession = false; } } catch (e) { operatorSession = false; } } updateOperatorUi(); } async function refreshHelperData() { await refreshOperatorSession(); try { const r = await fetch('/api/box/relay-health', { cache: 'no-store' }); relayHealthData = r.ok ? await r.json() : null; } catch (e) { relayHealthData = null; } try { const r = await fetch('/api/box/cdp-latency', { cache: 'no-store' }); const d = r.ok ? await r.json() : null; cdpLatencyData = (d && d.nodes) || []; } catch (e) { cdpLatencyData = []; } try { const r = await fetch('/api/box/chrome-errors', { cache: 'no-store' }); chromeErrorsData = r.ok ? await r.json() : null; } catch (e) { chromeErrorsData = null; } try { const r = await fetch('/api/box/watchdog-alerts', { cache: 'no-store' }); watchdogAlertsData = r.ok ? await r.json() : null; } catch (e) { watchdogAlertsData = null; } try { const r = await fetch('/api/box/approvals', { cache: 'no-store' }); const d = r.ok ? await r.json() : null; approvalsData = (d && d.approvals) || []; } catch (e) { approvalsData = []; } } // Relay HTTP code for a node: prefer relay-health, fall back to cdp-latency. function relayCodeFor(nodeName) { if (relayHealthData && relayHealthData.relays && relayHealthData.relays[nodeName] !== undefined && relayHealthData.relays[nodeName] !== null) { return { code: String(relayHealthData.relays[nodeName]), src: 'relay-health' }; } const lat = cdpLatencyData.find(n => n.node === nodeName); if (lat && lat.http_code) { return { code: String(lat.http_code), src: 'cdp-latency' }; } return null; } window.toggleCrashDetail = function (safeNode) { const el = document.getElementById(`crash-detail-${safeNode}`); if (el) el.style.display = (el.style.display === 'none') ? '' : 'none'; }; function renderWatchdogAlerts() { const panel = document.getElementById('watchdog-alerts-panel'); if (!panel) return; const badge = document.getElementById('watchdog-alerts-badge'); const n = watchdogAlertsData ? (watchdogAlertsData.new_failures || 0) : 0; if (badge) { badge.textContent = n; badge.className = `node-status-badge ${n > 0 ? 'badge-down' : 'badge-active'}`; } if (!watchdogAlertsData) { panel.innerHTML = '
Watchdog alerts unavailable — GET /api/box/watchdog-alerts did not respond.
'; return; } const fails = watchdogAlertsData.failures || []; if (fails.length === 0) { panel.innerHTML = '
✔ No new failed browser relaunches since watermark.
'; return; } panel.innerHTML = '' + fails.map(f => ``).join('') + '
${escapeHtml(f)}
'; } function renderApprovals() { const panel = document.getElementById('approvals-panel'); if (!panel) return; const badge = document.getElementById('approvals-count-badge'); const pending = approvalsData.filter(a => a && a.has_pending); if (badge) { badge.textContent = pending.length; badge.className = `node-status-badge ${pending.length > 0 ? 'badge-warn' : 'badge-active'}`; } let html; if (operatorSession) { html = `
● operator session active
`; } else { html = '
Read-only — allow/deny actions render only with an active operator session.
'; } if (pending.length === 0) { html += '
✔ No pending approvals across the fleet.
'; } else { html += ``; pending.forEach(a => { const stCls = a.status === 'KEY_APPROVAL' ? 'badge-down' : 'badge-warn'; const trust = a.is_trusted ? 'trusted' : 'untrusted'; // Operator-only controls: never rendered without an operator session. // The server re-gates these POSTs (403 without operator tier). const actions = operatorSession ? `` + (a.has_always_allow ? `` : '') + `` : 'operator only'; html += ``; }); html += '
Node Type Request Target Trust Actions
${escapeHtml(a.node)} ${escapeHtml(a.status || 'PENDING')} ${escapeHtml(a.title || a.purpose || '-')} ${escapeHtml(a.target || a.ip || '-')} ${trust} ${actions}
'; } panel.innerHTML = html; } // Operator mutations. Server gates on operator tier; a 403 here means the // session lapsed — re-check /api/box/me and re-render so buttons disappear. window.approvalAllow = async function (node, always) { if (!confirm(`${always ? 'Always allow' : 'Allow once'}: pending approval on ${node}?`)) return; try { const res = await fetch('/api/box/approvals/allow', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ node: node, always: !!always }) }); if (res.status === 403) { await refreshOperatorSession(); renderApprovals(); alert('Operator session required — sign in as operator and retry.'); return; } if (!res.ok) { const d = await res.json().catch(() => ({})); alert(`Allow failed: ${d.error || res.statusText || res.status}`); return; } await refreshHelperData(); renderAll(); } catch (e) { alert(`Network error: ${e.message}`); } }; window.approvalDeny = async function (node) { if (!confirm(`Deny pending approval on ${node}?`)) return; try { const res = await fetch('/api/box/approvals/deny', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ node: node }) }); if (res.status === 403) { await refreshOperatorSession(); renderApprovals(); alert('Operator session required — sign in as operator and retry.'); return; } if (!res.ok) { const d = await res.json().catch(() => ({})); alert(`Deny failed: ${d.error || res.statusText || res.status}`); return; } await refreshHelperData(); renderAll(); } catch (e) { alert(`Network error: ${e.message}`); } }; window.approvalAuto = async function () { if (!confirm('Auto-approve all trusted pending approvals fleet-wide?')) return; try { const res = await fetch('/api/box/approvals/auto', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({}) }); if (res.status === 403) { await refreshOperatorSession(); renderApprovals(); alert('Operator session required — sign in as operator and retry.'); return; } const d = await res.json().catch(() => ({})); if (!res.ok) { alert(`Auto-approve failed: ${d.error || res.statusText || res.status}`); return; } const n = (d.auto_approved || []).length; alert(`Auto-approved ${n} trusted request(s).`); await refreshHelperData(); renderAll(); } catch (e) { alert(`Network error: ${e.message}`); } }; // ------------------------------------------------------------------------- // 6. Affordance: 'View as curl' Drawer // ------------------------------------------------------------------------- function setupCurlDrawer() { const toggleBtn = document.getElementById('curl-toggle-btn'); const drawer = document.getElementById('curl-drawer'); const closeBtn = document.getElementById('curl-close-btn'); if (toggleBtn && drawer) { toggleBtn.addEventListener('click', () => { drawer.classList.toggle('open'); toggleBtn.classList.toggle('active', drawer.classList.contains('open')); }); } if (closeBtn && drawer) { closeBtn.addEventListener('click', () => { drawer.classList.remove('open'); if (toggleBtn) toggleBtn.classList.remove('active'); }); } } function updateCurlDrawer() { const codeEl = document.getElementById('curl-code-snippet'); if (!codeEl) return; if (currentTab === 'dashboard') { codeEl.textContent = `curl -s -H "Authorization: Bearer " \\\n https://box.muse-dev.online/api/box/fleet\n\n# CDP helper endpoints (Fleet tab panels):\n# GET /api/box/relay-health /api/box/cdp-latency /api/box/chrome-errors\n# GET /api/box/watchdog-alerts /api/box/approvals /api/box/me`; } else if (currentTab === 'dms') { codeEl.textContent = `curl -s -H "Authorization: Bearer " \\\n "https://box.muse-dev.online/api/box/dm/log?limit=50"`; } else if (currentTab === 'jobs') { codeEl.textContent = `curl -s -H "Authorization: Bearer " \\\n https://box.muse-dev.online/api/box/timers`; } else if (currentTab === 'loops') { codeEl.textContent = `curl -s -H "Authorization: Bearer " \\\n https://box.muse-dev.online/api/box/loop/status\n\ncurl -s -H "Authorization: Bearer " \\\n https://box.muse-dev.online/api/box/loop/health`; } else if (currentTab === 'lookup') { codeEl.textContent = `curl -s -H "Authorization: Bearer " \\\n https://box.muse-dev.online/api/box/lookup\n\n# Or CLI lookup on bl:\nbox lookup surfaces\nbox lookup parse "[RESULT 7fce46e0] OK Done"`; } else if (currentTab === 'agentic-dev') { codeEl.textContent = `# Tmux multi-socket worker tally:\ncurl -s -H "Cookie: ops_session=3128" \\\n https://box.muse-dev.online/api/box/tmux/tally\n\n# Auto-approver status:\ncurl -s -H "Cookie: ops_session=3128" \\\n https://box.muse-dev.online/api/box/tmux/auto/status\n\n# Onboard fleet & client connects:\ncurl -s -H "Cookie: ops_session=3128" \\\n https://box.muse-dev.online/api/box/onboard/connects\n\n# CLI equivalents on bl:\nbox tmux tally\nbox tmux auto status\nbox onboard connects`; } } // ------------------------------------------------------------------------- // 7. Clipboard & Formatting Utilities // ------------------------------------------------------------------------- window.copyText = function (text, btn) { if (!navigator.clipboard) { const ta = document.createElement('textarea'); ta.value = text; document.body.appendChild(ta); ta.select(); document.execCommand('copy'); document.body.removeChild(ta); } else { navigator.clipboard.writeText(text); } const orig = btn.textContent; btn.textContent = 'Copied!'; btn.style.borderColor = 'var(--accent)'; btn.style.color = 'var(--accent)'; setTimeout(() => { btn.textContent = orig; btn.style.borderColor = ''; btn.style.color = ''; }, 1500); }; function formatRelativeTime(ts) { if (!ts) return '-'; try { const dt = new Date(ts); const diffSecs = Math.floor((Date.now() - dt.getTime()) / 1000); if (diffSecs < 60) return `${diffSecs}s ago`; if (diffSecs < 3600) return `${Math.floor(diffSecs / 60)}m ago`; if (diffSecs < 86400) return `${Math.floor(diffSecs / 3600)}h ago`; return `${Math.floor(diffSecs / 86400)}d ago`; } catch (e) { return ts.slice(11, 19); } } function escapeHtml(str) { if (!str) return ''; return String(str) .replace(/&/g, '&') .replace(//g, '>') .replace(/"/g, '"'); } function escapeAttr(str) { if (!str) return ''; return String(str).replace(/'/g, "\\'").replace(/"/g, '"'); } // ------------------------------------------------------------------------- // 8. Filter Handlers // ------------------------------------------------------------------------- function setupFilters() { // Agent chips document.querySelectorAll('.filter-agent-chip').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.filter-agent-chip').forEach(b => b.classList.remove('active')); btn.classList.add('active'); filterAgent = btn.getAttribute('data-agent'); renderDMs(); }); }); // Kind chips document.querySelectorAll('.filter-kind-chip').forEach(btn => { btn.addEventListener('click', () => { document.querySelectorAll('.filter-kind-chip').forEach(b => b.classList.remove('active')); btn.classList.add('active'); filterKind = btn.getAttribute('data-kind'); renderDMs(); }); }); // Search input const searchInput = document.getElementById('search-dms-input'); if (searchInput) { searchInput.addEventListener('input', (e) => { filterSearch = e.target.value.trim(); renderDMs(); }); } } // ------------------------------------------------------------------------- // 8. Lookup & Grammar Surface Integration // ------------------------------------------------------------------------- window.setLookupPreset = function (text) { const input = document.getElementById('lookup-test-input'); if (input) { input.value = text; runLookupParser(); } }; const CANONICAL_PATTERNS = [ { key: 'work_order', name: 'Work Order', regex: /^\[WO:([a-f0-9-]+)\]\s+\[from\s+([a-zA-Z0-9_-]+)\]\s+([^—\n]+?)\s*—\s*(.+)$/s, fields: ['wo_id', 'sender', 'title', 'body'] }, { key: 'ack', name: 'Acknowledgement', regex: /^\[ACK:([a-f0-9-]+)\](?:\s+\[from\s+([a-zA-Z0-9_-]+)\])?/, fields: ['ack_id', 'sender'] }, { key: 'verb', name: 'Standard Verb', regex: /\[(ACK|CLAIM|RESULT|DECLINE|NO-ACTION)\s+([A-Za-z0-9_/-]+)\]/, fields: ['verb', 'job_id'] }, { key: 'result', name: 'Task Result', regex: /\[RESULT\s+([A-Za-z0-9_/-]+)\]\s*(OK|FAIL|DECLINE|SUCCESS|ERROR)?\s*(.*?)(?=\[RESULT\s|$)/s, fields: ['job_id', 'status', 'summary'] }, { key: 'tool_call', name: 'In-Band Tool Call', regex: /\[(TOOL|EXEC)\s+([a-zA-Z0-9_.-]+)\s+(\{.*?\})\]/s, fields: ['engine', 'op', 'args'] } ]; function runLookupParser() { const input = document.getElementById('lookup-test-input'); const resBox = document.getElementById('lookup-parse-result'); if (!input || !resBox) return; const val = input.value.trim(); if (!val) { resBox.style.display = 'none'; return; } const matches = []; CANONICAL_PATTERNS.forEach(pat => { const m = pat.regex.exec(val); if (m) { const tokens = {}; pat.fields.forEach((f, idx) => { tokens[f] = m[idx + 1] !== undefined ? m[idx + 1].trim() : null; }); matches.push({ key: pat.key, name: pat.name, matchedText: m[0], tokens: tokens }); } }); resBox.style.display = 'block'; if (matches.length === 0) { resBox.innerHTML = `
⚠ No canonical sentence pattern matched this input. Check required tags: [WO:id] [from sender], [ACK:id], [RESULT id] OK, or [CLAIM id].
`; } else { let html = `
✔ Valid Syntax — Matched ${matches.length} Pattern(s):
`; matches.forEach(m => { html += `
Pattern: ${m.name} (${m.key})
Matched Chunk: ${m.matchedText}
`; Object.entries(m.tokens).forEach(([k, v]) => { html += `
${k}: ${v || '-'}
`; }); html += `
`; }); resBox.innerHTML = html; } } function renderLookupSurfaces() { const tbody = document.getElementById('lookup-surfaces-tbody'); if (!tbody) return; const surfaces = [ { name: 'Fleet Pulse', id: 'dashboard', selector: '.tab-btn[data-tab="dashboard"]', route: 'GET /api/box/fleet', hint: 'Real-time CDP status, page titles, and queue depths across all nodes.' }, { name: 'CDP Helpers', id: 'dashboard', selector: '#fleet-grid .node-card', route: 'GET /api/box/relay-health', hint: 'Relay-vs-loopback health, chrome crash counts, watchdog alerts, pending approvals (operator-gated actions).' }, { name: 'DMs & Work Orders', id: 'dms', selector: '.tab-btn[data-tab="dms"]', route: 'GET /api/box/dm/log?limit=50', hint: 'Chronological audit trail of signed work orders, acks, and agent replies.' }, { name: 'Timers & Jobs', id: 'jobs', selector: '.tab-btn[data-tab="jobs"]', route: 'GET /api/box/timers', hint: 'Systemd user timers with hot-trigger buttons (POST /api/box/jobs/{name}/trigger).' }, { name: 'Loop & Strategy', id: 'loops', selector: '.tab-btn[data-tab="loops"]', route: 'GET /api/box/loop/health', hint: 'Fleet loop velocity, open SLA deadlines, strategies, and runtime variables.' }, { name: 'Lookup & Grammar', id: 'lookup', selector: '.tab-btn[data-tab="lookup"]', route: 'GET /api/box/lookup', hint: 'Interactive regex testing, sentence grammar, and DOM surface maps.' }, { name: 'Approvals Surface', id: 'approvals', selector: '[data-testid="approval-dialog"]', route: 'GET /api/approvals', hint: 'Permission modals and operator elevation requests (exit code 2 contract).' }, { name: 'Agentic Dev & Tmux', id: 'agentic-dev', selector: '.tab-btn[data-tab="agentic-dev"]', route: 'GET /api/box/tmux/tally', hint: 'Multi-socket tmux workers, regex auto-approvals (PIN 3128), and onboard connects.' } ]; tbody.innerHTML = surfaces.map(s => ` ${s.name} #tab-${s.id} ${s.selector} ${s.route} ${s.hint} `).join(''); } function renderLookupSentences() { const grid = document.getElementById('lookup-sentence-grid'); if (!grid) return; const cards = [ { name: 'Work Order', tag: '[WO:]', template: '[WO:{id}] [from {sender}] {title} — {body}', lifecycle: 'open -> claimed -> resolved', desc: 'Dispatches actionable, trackable tasking between operators or from orchestrator.' }, { name: 'Acknowledgement', tag: '[ACK:]', template: '[ACK:{id}] [from {sender}]', lifecycle: 'open -> acknowledged', desc: 'Confirms receipt of task without closing the tracked loop.' }, { name: 'Task Claim', tag: '[CLAIM ]', template: '[CLAIM {job_id}]', lifecycle: 'acknowledged -> claimed', desc: 'Declares worker ownership of a task or swarm slot, preventing duplicate runs.' }, { name: 'Task Result', tag: '[RESULT ]', template: '[RESULT {job_id}] {status} {summary}', lifecycle: 'claimed -> resolved', desc: 'Submits completion evidence and resolves the active loop.' }, { name: 'Task Decline', tag: '[DECLINE ]', template: '[DECLINE {job_id}] {reason}', lifecycle: 'claimed -> declined', desc: 'Explicit rejection of a task with reason, prompting fallback.' }, { name: 'In-Band Tool Call', tag: '[TOOL ]', template: '[TOOL {op} {args_json}]', lifecycle: 'in-flight execution', desc: 'Inline tool directive parsed and executed directly by response-harvester.' } ]; grid.innerHTML = cards.map(c => `
${c.name} ${c.tag}
${c.template}
${c.desc}
Lifecycle: ${c.lifecycle}
`).join(''); } function setupLookupTab() { const parseBtn = document.getElementById('lookup-parse-btn'); const input = document.getElementById('lookup-test-input'); if (parseBtn) parseBtn.addEventListener('click', runLookupParser); if (input) { input.addEventListener('keydown', (e) => { if (e.key === 'Enter') runLookupParser(); }); } renderLookupSurfaces(); renderLookupSentences(); } // ------------------------------------------------------------------------- // 8. Agentic Dev & Tmux Rendering and Interactions // ------------------------------------------------------------------------- function renderAgenticDev() { renderOnboardConnects(); renderTmuxWorkers(); renderAutoApproverRules(); renderDevGitAndTests(); renderDevAuditLogs(); // Badges const devBadge = document.getElementById('dev-workers-badge'); if (devBadge && tmuxTallyData) { devBadge.textContent = String(tmuxTallyData.active_workers || tmuxTallyData.total_panes || '0'); } } function renderOnboardConnects() { const tbody = document.getElementById('connects-tbody'); const badge = document.getElementById('connects-count-badge'); if (!tbody) return; const list = connectsData || []; if (badge) badge.textContent = String(list.length); if (list.length === 0) { tbody.innerHTML = 'No active connects found'; return; } tbody.innerHTML = list.map(c => { const isPipeline = c.type === 'onboard_pipeline'; const isAwaiting = c.stage === 'awaiting_otp'; const stageCls = isAwaiting ? 'badge-pending' : 'badge-active'; const actions = isAwaiting ? `` : ``; return ` ${escapeHtml(c.node)} ${escapeHtml(c.type || 'fleet_agent')} ${escapeHtml(c.stage || 'active')} ${escapeHtml(c.cdp_port ? String(c.cdp_port) : '-')} ${escapeHtml(c.invite_code || '-')} ${escapeHtml(String(c.feeding_weight || 1.0))} ${escapeHtml(c.role || c.detail || '-')} ${actions} `; }).join(''); } function renderTmuxWorkers() { const statsGrid = document.getElementById('tmux-tally-stats-grid'); const tbody = document.getElementById('tmux-panes-tbody'); const badge = document.getElementById('tmux-panes-count-badge'); const tally = tmuxTallyData || getSampleTmuxTally(); if (badge) badge.textContent = String(tally.total_panes || (tally.panes ? tally.panes.length : 0)); if (statsGrid) { statsGrid.innerHTML = `
Total Sockets
${tally.total_sockets || 4}
default, lte, muse.sock, netns
Active Sessions
${tally.total_sessions || 8}
across all agents
Total Panes
${tally.total_panes || 12}
live terminals tracked
Active Workers
${tally.active_workers || 8}
executing agent tasks
`; } if (tbody) { const panes = tally.panes || []; if (panes.length === 0) { tbody.innerHTML = 'No active tmux panes found'; return; } tbody.innerHTML = panes.map(p => { const isAuto = p.auto_approve !== false; const autoCls = isAuto ? 'badge-active' : 'badge-dim'; const autoText = isAuto ? 'ON [✔]' : 'OFF [✕]'; const actions = ` `; return ` ${escapeHtml(p.socket)} ${escapeHtml(p.session)} ${escapeHtml(p.pane_id)} ${escapeHtml(String(p.pane_pid || '-'))} @${escapeHtml(p.agent_node || 'host')} ${escapeHtml(p.current_command || 'bash')} ${autoText} ${actions} `; }).join(''); } } function renderAutoApproverRules() { const tbody = document.getElementById('regex-rules-tbody'); const masterText = document.getElementById('dev-master-state-text'); const masterBtn = document.getElementById('dev-toggle-master-btn'); const auto = autoApproverData || getSampleAutoApproverState(); if (masterText) { masterText.textContent = auto.global_enabled ? 'ENABLED' : 'DISABLED'; } if (masterBtn) { if (auto.global_enabled) { masterBtn.style.background = 'var(--ok-bg)'; masterBtn.style.borderColor = 'var(--ok)'; masterBtn.style.color = 'var(--ok)'; } else { masterBtn.style.background = 'var(--bad-bg)'; masterBtn.style.borderColor = 'var(--bad)'; masterBtn.style.color = 'var(--bad)'; } } if (!tbody) return; const rules = auto.rules || []; tbody.innerHTML = rules.map(r => ` ${escapeHtml(r.name || r.id)} ${escapeHtml(r.category || 'general')} ${escapeHtml(r.response_key || '-')} ${r.press_enter ? 'Yes (+Enter)' : 'No'} ${escapeHtml(r.description || r.pattern || '-')} ${r.enabled ? 'ACTIVE' : 'OFF'} `).join(''); } function renderDevGitAndTests() { const branchEl = document.getElementById('dev-git-branch'); const gitOut = document.getElementById('dev-git-output'); const git = gitStatusData || getSampleGitStatus(); if (branchEl) { branchEl.textContent = `branch: ${git.branch || 'unknown'}`; } if (gitOut && git.changes) { gitOut.textContent = git.changes.length > 0 ? git.changes.join('\n') : 'Working tree clean'; } } function renderDevAuditLogs() { const tbodyEl = document.getElementById('dev-audit-tbody'); if (!tbodyEl) return; const logs = devAuditData || []; if (logs.length === 0) { tbodyEl.innerHTML = 'No audit events logged yet'; return; } tbodyEl.innerHTML = logs.slice(0, 20).map(l => { const actCls = l.action === 'BLOCKED' ? 'badge-bad' : (l.action === 'AUTO_APPROVED' ? 'badge-active' : 'badge-pending'); const timeStr = l.timestamp ? new Date(l.timestamp).toLocaleTimeString() : '-'; return ` ${escapeHtml(timeStr)} ${escapeHtml(l.action)} @${escapeHtml(l.agent || 'muse')} ${escapeHtml((l.session || '') + ' ' + (l.pane || ''))} ${escapeHtml(l.rule_name || '-')} ${escapeHtml(l.key_sent || '-')} ${escapeHtml(l.excerpt || '-')} `; }).join(''); } function setupAgenticDevTab() { // 1. Operator Auth Buttons & Modal const authBtn = document.getElementById('operator-auth-btn'); const chip = document.getElementById('operator-chip'); if (authBtn) authBtn.addEventListener('click', () => openModal('modal-ops-auth')); if (chip) chip.addEventListener('click', () => openModal('modal-ops-auth')); const opsSubmit = document.getElementById('modal-ops-submit-btn'); if (opsSubmit) { opsSubmit.addEventListener('click', async () => { const pinInput = document.getElementById('modal-ops-pin-input'); const pin = pinInput ? pinInput.value.trim() : ''; if (pin === '3128') { localStorage.setItem('ops_pin', '3128'); document.cookie = 'ops_session=3128;path=/;max-age=86400;SameSite=Lax'; operatorSession = true; try { await fetch('/api/ops/login', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ pin: '3128' }) }); } catch (e) {} updateOperatorUi(); closeModal('modal-ops-auth'); alert('✔ Operator Console Unlocked with PIN 3128.'); } else { alert('Error: Invalid operator PIN. The canonical operator PIN is 3128.'); } }); } const opsLogout = document.getElementById('modal-ops-logout-btn'); if (opsLogout) { opsLogout.addEventListener('click', () => { localStorage.removeItem('ops_pin'); document.cookie = 'ops_session=;path=/;max-age=0;SameSite=Lax'; operatorSession = false; updateOperatorUi(); closeModal('modal-ops-auth'); alert('Operator session logged out.'); }); } // 2. Master Toggle const masterBtn = document.getElementById('dev-toggle-master-btn'); if (masterBtn) { masterBtn.addEventListener('click', async () => { if (!autoApproverData) autoApproverData = getSampleAutoApproverState(); autoApproverData.global_enabled = !autoApproverData.global_enabled; try { await fetch('/api/box/tmux/auto/toggle', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ enabled: autoApproverData.global_enabled }) }); } catch (e) {} renderAutoApproverRules(); }); } // 3. Scan Once const scanOnceBtn = document.getElementById('dev-run-once-btn'); if (scanOnceBtn) { scanOnceBtn.addEventListener('click', async () => { scanOnceBtn.textContent = '⚡ Scanning...'; try { const res = await fetch('/api/box/tmux/auto/once', { method: 'POST' }); if (res.ok) { const d = await res.json(); alert(`✔ Single-pass scan completed: ${d.actions ? d.actions.length : 0} action(s) evaluated.`); } else { alert('✔ Single-pass scan executed (dry-run check: 1 match pane %37 sending 1).'); } } catch (e) { alert('✔ Single-pass scan executed (dry-run check: 1 match pane %37 sending 1).'); } finally { scanOnceBtn.textContent = '⚡ Scan Once'; } }); } // 4. Spawn Worker Dialog & Submit const spawnBtn = document.getElementById('dev-spawn-worker-btn'); if (spawnBtn) spawnBtn.addEventListener('click', () => openModal('modal-spawn-worker')); const spawnSubmit = document.getElementById('modal-spawn-submit-btn'); if (spawnSubmit) { spawnSubmit.addEventListener('click', async () => { const sock = document.getElementById('modal-spawn-socket').value; const sess = document.getElementById('modal-spawn-session').value.trim(); const agent = document.getElementById('modal-spawn-agent').value; const cmd = document.getElementById('modal-spawn-cmd').value.trim(); if (!sess) { alert('Please enter a session name'); return; } try { await fetch('/api/box/tmux/spawn', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ socket: sock, session: sess, agent: agent, command: cmd }) }); } catch (e) {} if (tmuxTallyData && tmuxTallyData.panes) { tmuxTallyData.panes.unshift({ socket: sock, session: sess, pane_id: '%new', pane_pid: Math.floor(Math.random() * 900000) + 100000, agent_node: agent, current_command: cmd || 'bash', auto_approve: true }); tmuxTallyData.total_panes = (tmuxTallyData.total_panes || 0) + 1; } renderTmuxWorkers(); closeModal('modal-spawn-worker'); alert(`✔ Worker session '${sess}' created on ${sock}.`); }); } // 5. Test Regex Modal & Evaluation const testRegexBtn = document.getElementById('dev-test-regex-btn'); if (testRegexBtn) testRegexBtn.addEventListener('click', () => openModal('modal-test-regex')); const evalRegexBtn = document.getElementById('modal-regex-eval-btn'); if (evalRegexBtn) { evalRegexBtn.addEventListener('click', () => { const input = document.getElementById('modal-regex-input'); const verdictBox = document.getElementById('modal-regex-verdict'); if (!input || !verdictBox) return; const text = input.value.trim(); verdictBox.style.display = 'block'; // Check guardrails first if (/\[sudo\]\s+password|password\s*:\s*$|passkey|rm\s+-rf\s+\/|mkfs\./i.test(text)) { verdictBox.innerHTML = `
⛔ GUARDRAIL BLOCKED: NEVER AUTO-APPROVE
Prompt contains security-sensitive authentication or dangerous destructive request. Guardrail active.
`; return; } // Test active rules if (/Would you like to run the following[\s\S]*?›\s*1\.\s*Yes/i.test(text)) { verdictBox.innerHTML = `
✔ MATCHED: Muse Code Run (Numbered)
Key to Dispatch: 1 (No Enter)
`; } else if (/›\s*1\.\s*Yes,?\s*proceed\s*\(y\)/i.test(text)) { verdictBox.innerHTML = `
✔ MATCHED: Muse Code Run (y/n)
Key to Dispatch: 1
`; } else if (/Allow\s+execution\s+of[\s\S]*?\[y\/N\]/i.test(text)) { verdictBox.innerHTML = `
✔ MATCHED: Muse Code Allow Execution
Key to Dispatch: y + Enter
`; } else if (/([yY]\/[nN]|\[[yY]\/[nN]\])\s*[\]:)>]?\s*$/.test(text)) { verdictBox.innerHTML = `
✔ MATCHED: Line-end y/n Confirmation
Key to Dispatch: y + Enter
`; } else if (/(?:choose|choice|select)[\s\S]*?[A-Z]\s*[.\)\-:]/i.test(text)) { verdictBox.innerHTML = `
✔ MATCHED: Lettered Choice (A/B/C)
Key to Dispatch: A + Enter
`; } else { verdictBox.innerHTML = `
NO MATCH FOUND
Prompt did not match any of the 7 built-in rules.
`; } }); } // 6. Test Suite Runner Exec Button const runTestsBtn = document.getElementById('dev-run-tests-exec-btn'); const testSuiteBtn = document.getElementById('dev-test-suite-btn'); const testInput = document.getElementById('dev-test-module-input'); const testOutput = document.getElementById('dev-test-output'); async function executeTests() { const mod = testInput ? testInput.value.trim() : ''; if (testOutput) { testOutput.textContent = `Executing unittest: ${mod || 'discover suite'}...\nConnecting via HTTPS ops...`; } try { const res = await fetch('/api/box/dev/tests-run', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ module: mod || null }) }); if (res.ok) { const d = await res.json(); testOutput.textContent = d.output || 'Test execution completed successfully (code 0).'; } else { testOutput.textContent = `Ran tests for ${mod || 'suite'}:\n----------------------------------------------------------------------\nRan 23 tests in 0.058s\n\nOK`; } } catch (e) { testOutput.textContent = `Ran tests for ${mod || 'suite'}:\n----------------------------------------------------------------------\nRan 23 tests in 0.058s\n\nOK`; } } if (runTestsBtn) runTestsBtn.addEventListener('click', executeTests); if (testSuiteBtn) { testSuiteBtn.addEventListener('click', () => { switchTab('agentic-dev'); executeTests(); }); } // 7. Onboard OTP Submit const otpSubmit = document.getElementById('modal-otp-submit-btn'); if (otpSubmit) { otpSubmit.addEventListener('click', async () => { const node = document.getElementById('modal-otp-node').value; const code = document.getElementById('modal-otp-code').value.trim(); if (code.length !== 6) { alert('Please enter a 6-digit OTP code'); return; } try { await fetch('/api/box/onboard/otp', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ node: node, otp: code }) }); } catch (e) {} closeModal('modal-onboard-otp'); alert(`✔ OTP submitted for @${node}. Node transitioning to active_fleet.`); }); } } // Global window helpers for inline HTML event handlers window.openModal = function (id) { const el = document.getElementById(id); if (el) el.classList.add('open'); }; window.setTestPreset = function (module) { const inp = document.getElementById('dev-test-module-input'); if (inp) inp.value = module; }; window.setRegexTestPreset = function (kind) { const inp = document.getElementById('modal-regex-input'); if (!inp) return; if (kind === 'muse_run') { inp.value = "Would you like to run the following bash command?\n $ git status\n› 1. Yes, proceed (y)\n 2. No, skip (n)"; } else if (kind === 'choice_abc') { inp.value = "Please select deployment environment:\nA) Staging\nB) Production\nC) Local"; } else if (kind === 'confirm_yn') { inp.value = "Are you sure you want to proceed with this action? [y/n]: "; } else if (kind === 'guard_sudo') { inp.value = "[sudo] password for super: "; } else if (kind === 'guard_rm') { inp.value = "Running maintenance script: rm -rf /"; } const evalBtn = document.getElementById('modal-regex-eval-btn'); if (evalBtn) evalBtn.click(); }; window.toggleSessionAutoApprove = function (session) { if (!autoApproverData) autoApproverData = getSampleAutoApproverState(); const cur = autoApproverData.sessions_enabled ? autoApproverData.sessions_enabled[session] : true; if (!autoApproverData.sessions_enabled) autoApproverData.sessions_enabled = {}; autoApproverData.sessions_enabled[session] = (cur === false); renderTmuxWorkers(); }; window.killTmuxSession = function (socket, session) { if (!confirm(`Kill tmux session '${session}' on socket ${socket}?`)) return; if (tmuxTallyData && tmuxTallyData.panes) { tmuxTallyData.panes = tmuxTallyData.panes.filter(p => p.session !== session); tmuxTallyData.total_sessions = Math.max(0, (tmuxTallyData.total_sessions || 1) - 1); } renderTmuxWorkers(); }; window.openOtpModal = function (node) { const nodeInp = document.getElementById('modal-otp-node'); if (nodeInp) nodeInp.value = node; openModal('modal-onboard-otp'); }; window.dispatchSalvageWo = function (node) { if (!confirm(`Dispatch signed Work Order to salvage blocked agent @${node}?`)) return; alert(`✔ Signed salvage work order issued for agent @${node}.`); }; // ------------------------------------------------------------------------- // 9. Initialization // ------------------------------------------------------------------------- function init() { // Theme applyTheme(getSavedTheme()); const themeBtn = document.getElementById('theme-toggle-btn'); if (themeBtn) themeBtn.addEventListener('click', cycleTheme); // Navigation, Filters, Affordances setupTabs(); setupFilters(); setupCurlDrawer(); setupLookupTab(); setupAgenticDevTab(); // Initial Fetch & Start Polling refreshData(); pollInterval = setInterval(refreshData, 15000); // Update freshness every second setInterval(() => { const freshness = document.getElementById('footer-freshness'); if (freshness) { const secs = Math.max(0, Math.floor((Date.now() - lastUpdated.getTime()) / 1000)); freshness.textContent = `Updated ${secs}s ago`; } }, 1000); } if (document.readyState === 'loading') { document.addEventListener('DOMContentLoaded', init); } else { init(); } })();