2026-10-04 16:32:52 +00:00
/**
* 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 ;
// -------------------------------------------------------------------------
// 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 ( '#' , '' ) ;
2026-10-05 20:18:47 +00:00
if ( [ 'dashboard' , 'dms' , 'jobs' , 'loops' , 'lookup' ] . includes ( hash ) ) {
2026-10-04 16:32:52 +00:00
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" }
] ;
}
// -------------------------------------------------------------------------
// 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 ( ) ;
}
lastUpdated = new Date ( ) ;
renderAll ( ) ;
} finally {
if ( pulseEl ) pulseEl . style . opacity = '1' ;
}
}
// -------------------------------------------------------------------------
// 5. Rendering Functions
// -------------------------------------------------------------------------
function renderAll ( ) {
renderFleet ( ) ;
renderDMs ( ) ;
renderJobs ( ) ;
renderLoopHealth ( ) ;
renderLoops ( ) ;
renderStrats ( ) ;
renderVars ( ) ;
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' ;
card . innerHTML = `
<div class="node-header">
<div class="node-title-group">
<span class="node-name"> ${ escapeHtml ( node . node ) } </span>
<span class="node-netns"> ${ escapeHtml ( node . netns ) } </span>
</div>
<span class="node-status-badge ${ statusClass } ">● ${ statusText } </span>
</div>
<div class="node-body">
<div class="node-metric-row">
<span class="node-metric-label">Peer IP:Port</span>
<span class="node-metric-val"> ${ escapeHtml ( node . peer _ip ) } : ${ node . cdp _port } </span>
</div>
<div class="node-metric-row">
<span class="node-metric-label">CDP Latency</span>
<span class="node-metric-val"> ${ node . latency _ms !== null ? node . latency _ms + 'ms' : '-' } </span>
</div>
<div class="node-metric-row">
<span class="node-metric-label">Queue Depth</span>
<span class="node-metric-val"> ${ node . queue _depth > 0 ? node . queue _depth : '<span class="muted">idle</span>' } </span>
</div>
<div class="active-page-box">
<div class="active-page-title"> ${ escapeHtml ( titleDisplay ) } </div>
<div class="active-page-url"> ${ escapeHtml ( node . url || '-' ) } </div>
</div>
</div>
` ;
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 = ` <tr><td colspan="5" style="text-align: center; color: var(--muted); padding: 24px;">No messages match criteria</td></tr> ` ;
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
? ` <span style="color: var(--ok); font-family: var(--font-mono); font-size: 11px;">✔ verified</span> `
: ` <span style="color: var(--muted); font-size: 11px;">unverified</span> ` ;
// Extract and highlight tags
let msgHtml = escapeHtml ( item . msg || item . reason || item . error || '-' ) ;
msgHtml = msgHtml . replace ( /\[WO:([a-f0-9]+)\]/g , '<span class="tag-badge tag-wo">[WO:$1]</span>' ) ;
msgHtml = msgHtml . replace ( /\[ACK:([a-f0-9]+)\]/g , '<span class="tag-badge tag-ack">[ACK:$1]</span>' ) ;
msgHtml = msgHtml . replace ( /\[JOB ([^\]]+)\]/g , '<span class="tag-badge tag-job">[JOB $1]</span>' ) ;
msgHtml = msgHtml . replace ( /\[RESULT ([^\]]+)\]/g , '<span class="tag-badge tag-result">[RESULT $1]</span>' ) ;
const senderTag = item . agent === 'super'
? ` <span class="tag-badge tag-super">super</span> `
: ` <strong> ${ escapeHtml ( item . agent ) } </strong> ` ;
tr . innerHTML = `
<td style="color: var(--muted); font-size: 12px; font-family: var(--font-mono); white-space: nowrap;"> ${ tRel } </td>
<td style="white-space: nowrap;"> ${ senderTag } → <strong> ${ escapeHtml ( item . to || '-' ) } </strong></td>
<td style="font-family: var(--font-mono); font-size: 11px; color: var(--muted);"> ${ escapeHtml ( item . target || 'main' ) } </td>
<td>
<div style="display: flex; align-items: center; justify-content: space-between;">
<div style="overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 600px;"> ${ msgHtml } </div>
<button class="btn-copy" onclick="event.stopPropagation(); copyText(' ${ escapeAttr ( item . msg || '' ) } ', this)">Copy</button>
</div>
</td>
<td style="white-space: nowrap; text-align: right;"> ${ verifiedBadge } </td>
` ;
// 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 = `
<td colspan="5">
<div style="margin-bottom: 6px; font-size: 11px; color: var(--muted);">Full Record ( ${ escapeHtml ( item . id || 'raw' ) } ):</div>
<div class="detail-content"> ${ escapeHtml ( item . msg || JSON . stringify ( item , null , 2 ) ) } </div>
</td>
` ;
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'
? ` <code style="color: var(--ok); font-weight: 700;"> ${ escapeHtml ( job . schedule ) } </code> `
: ` <span style="color: var(--muted);">manual</span> ` ;
tr . innerHTML = `
<td><strong style="font-family: var(--font-mono);"> ${ escapeHtml ( job . name ) } </strong></td>
<td><span class="tag-badge tag-wo"> ${ escapeHtml ( job . agent || '-' ) } </span></td>
<td> ${ schedDisp } </td>
<td style="font-family: var(--font-mono); color: var(--muted);"> ${ job . timeout || '-' } s</td>
<td style="color: var(--text);"> ${ escapeHtml ( job . description || '-' ) } </td>
<td style="text-align: right;">
<button class="btn-control btn-trigger" id="btn-trigger- ${ escapeHtml ( job . name ) } " onclick="triggerJob(' ${ escapeHtml ( job . name ) } ')">▶ Run</button>
</td>
` ;
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 = `
<div class="stat-card-header">
<span>Fleet Overall Health</span>
<span style="color: ${ isHealthy ? 'var(--ok)' : 'var(--bad)' } "> ${ isHealthy ? 'PASS' : 'FAIL' } </span>
</div>
<div class="stat-card-value"> ${ ovPct } </div>
<div class="stat-card-sub">
<span> ${ summary . total _answered || 0 } / ${ summary . total _landed || 0 } closed</span>
<span>Target: ≥ ${ Math . round ( ( summary . threshold || 0.5 ) * 100 ) } %</span>
</div>
<div class="progress-bar-container">
<div class="progress-bar-fill" style="width: ${ Math . min ( 100 , Math . round ( ovRatio * 100 ) ) } %; background: ${ isHealthy ? 'var(--ok)' : 'var(--bad)' } ;"></div>
</div>
` ;
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 = `
<div class="stat-card-header">
<span>Agent ${ escapeHtml ( ag ) } </span>
<span style="color: ${ aColor } ; font-weight: 700;"> ${ st } </span>
</div>
<div class="stat-card-value"> ${ aData . health _pct } </div>
<div class="stat-card-sub">
<span> ${ aData . answered } / ${ aData . landed } answered</span>
<span> ${ st === 'IDLE' ? 'No traffic' : ` ${ Math . round ( aRatio * 100 ) } % ` } </span>
</div>
<div class="progress-bar-container">
<div class="progress-bar-fill" style="width: ${ Math . min ( 100 , Math . round ( aRatio * 100 ) ) } %; background: ${ aColor } ;"></div>
</div>
` ;
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 = ` <tr><td colspan="8" style="text-align: center; color: var(--muted); padding: 24px;">No active or tracked loops found</td></tr> ` ;
return ;
}
loopsData . forEach ( ( loop , idx ) => {
const tr = document . createElement ( 'tr' ) ;
tr . className = 'table-row' ;
const st = loop . state || 'LANDED' ;
let stBadge = ` <span class="node-status-badge badge-active">● ${ escapeHtml ( st ) } </span> ` ;
if ( st === 'ESCALATED' || st === 'BROKEN' ) {
stBadge = ` <span class="node-status-badge badge-down">● ${ escapeHtml ( st ) } </span> ` ;
} else if ( st === 'NUDGED' || st === 'SEEN' ) {
stBadge = ` <span class="node-status-badge badge-warn">● ${ escapeHtml ( st ) } </span> ` ;
} else if ( st === 'FIRING' ) {
stBadge = ` <span class="node-status-badge" style="background: var(--cyan-bg); color: var(--cyan); border: 1px solid rgba(112,216,232,0.3);">○ FIRING</span> ` ;
}
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 = ` <span style="color: var(--ok);">in ${ Math . floor ( diff / 60 ) } m</span> ` ;
} else {
dlDisp = ` <span style="color: var(--bad);"> ${ Math . floor ( Math . abs ( diff ) / 60 ) } m ago</span> ` ;
}
} 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 = `
<td><strong style="font-family: var(--font-mono);"> ${ escapeHtml ( ( loop . loop _id || '-' ) . slice ( 0 , 8 ) ) } </strong></td>
<td><span class="tag-badge tag-wo"> ${ escapeHtml ( loop . agent || '-' ) } </span></td>
<td style="font-family: var(--font-mono); font-size: 11px; color: var(--muted);"> ${ escapeHtml ( loop . purpose || 'dm' ) } </td>
<td style="color: var(--muted); font-size: 12px; font-family: var(--font-mono);"> ${ tRel } </td>
<td> ${ stBadge } </td>
<td style="font-family: var(--font-mono); font-size: 11px;"> ${ dlDisp } </td>
<td style="font-family: var(--font-mono); font-size: 11px; color: var(--muted);"> ${ nudgesDisp } </td>
<td style="text-align: right; white-space: nowrap;">
${ isPending ? ` <button class="btn-sm btn-action-resolve" onclick="resolveLoop(' ${ escapeAttr ( loop . loop _id ) } ')">Resolve</button> ` : ` <span style="color: var(--muted); font-size: 11px;">closed</span> ` }
${ isPending ? ` <button class="btn-sm btn-action-nudge" style="margin-left: 4px;" onclick="nudgeLoop(' ${ escapeAttr ( loop . loop _id ) } ')">Nudge</button> ` : '' }
</td>
` ;
tbody . appendChild ( tr ) ;
} ) ;
}
function renderStrats ( ) {
const tbody = document . getElementById ( 'strats-tbody' ) ;
if ( ! tbody ) return ;
tbody . innerHTML = '' ;
if ( stratsData . length === 0 ) {
tbody . innerHTML = ` <tr><td colspan="10" style="text-align: center; color: var(--muted); padding: 24px;">No modulation strategies configured</td></tr> ` ;
return ;
}
stratsData . forEach ( s => {
const tr = document . createElement ( 'tr' ) ;
tr . className = 'table-row' ;
const prio = s . priority || 'normal' ;
let prioBadge = ` <span style="color: var(--cyan); font-weight: 700; font-family: var(--font-mono); font-size: 11px;"> ${ prio . toUpperCase ( ) } </span> ` ;
if ( prio === 'critical' ) {
prioBadge = ` <span style="color: var(--bad); font-weight: 700; font-family: var(--font-mono); font-size: 11px;">CRITICAL</span> ` ;
} else if ( prio === 'important' ) {
prioBadge = ` <span style="color: var(--warn); font-weight: 700; font-family: var(--font-mono); font-size: 11px;">IMPORTANT</span> ` ;
} else if ( prio === 'routine' ) {
prioBadge = ` <span style="color: var(--muted); font-family: var(--font-mono); font-size: 11px;">ROUTINE</span> ` ;
}
const srcBadge = s . is _override
? ` <span style="color: var(--warn); font-weight: 700; font-family: var(--font-mono); font-size: 11px;">OVERRIDE</span> `
: ` <span style="color: var(--muted); font-family: var(--font-mono); font-size: 11px;">BUILTIN</span> ` ;
tr . innerHTML = `
<td><strong style="font-family: var(--font-mono);"> ${ escapeHtml ( s . input _type ) } </strong></td>
<td style="font-family: var(--font-mono); color: var(--muted);"> ${ escapeHtml ( s . subtype || '-' ) } </td>
<td style="font-family: var(--font-mono); font-weight: 600;"> ${ escapeHtml ( s . agent || '-' ) } </td>
<td style="font-family: var(--font-mono); font-size: 11px;"> ${ escapeHtml ( String ( s . track ) ) } </td>
<td> ${ prioBadge } </td>
<td style="font-family: var(--font-mono);"> ${ s . timeout _s } s</td>
<td style="font-family: var(--font-mono);"> ${ s . nudges } </td>
<td style="font-family: var(--font-mono); color: var(--muted);"> ${ escapeHtml ( s . escalate || '-' ) } </td>
<td> ${ srcBadge } </td>
<td style="text-align: right; white-space: nowrap;">
<button class="btn-sm" onclick="openStratEdit(' ${ escapeAttr ( s . input _type ) } ', ' ${ escapeAttr ( s . subtype || '' ) } ', ' ${ escapeAttr ( s . agent || '' ) } ')">Override</button>
${ s . is _override ? ` <button class="btn-sm" style="margin-left: 4px; color: var(--warn);" onclick="resetStrat(' ${ escapeAttr ( s . input _type ) } ', ' ${ escapeAttr ( s . subtype || '' ) } ', ' ${ escapeAttr ( s . agent || '' ) } ')">Reset</button> ` : '' }
</td>
` ;
tbody . appendChild ( tr ) ;
} ) ;
}
function renderVars ( ) {
const tbody = document . getElementById ( 'vars-tbody' ) ;
if ( ! tbody ) return ;
tbody . innerHTML = '' ;
if ( varsData . length === 0 ) {
tbody . innerHTML = ` <tr><td colspan="7" style="text-align: center; color: var(--muted); padding: 24px;">No runtime control variables loaded</td></tr> ` ;
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
? ` <strong style="color: var(--cyan);"> ${ escapeHtml ( v . value ) } *</strong> `
: ` <span> ${ escapeHtml ( v . value ) } </span> ` ;
const rng = ( v . min !== undefined && v . max !== undefined ) ? ` ${ v . min } .. ${ v . max } ` : '-' ;
tr . innerHTML = `
<td><strong style="font-family: var(--font-mono);"> ${ escapeHtml ( v . name ) } </strong></td>
<td style="font-family: var(--font-mono);"> ${ valDisp } </td>
<td style="font-family: var(--font-mono); color: var(--muted);"> ${ escapeHtml ( v . default !== undefined ? v . default : '-' ) } </td>
<td style="font-family: var(--font-mono); font-size: 11px; color: var(--muted);"> ${ escapeHtml ( v . unit || '-' ) } </td>
<td style="font-family: var(--font-mono); font-size: 11px; color: var(--muted);"> ${ escapeHtml ( rng ) } </td>
<td style="color: var(--muted); font-size: 12px;"> ${ escapeHtml ( v . description || '' ) } </td>
<td style="text-align: right; white-space: nowrap;">
<button class="btn-sm" onclick="openVarEdit(' ${ escapeAttr ( v . name ) } ')">Edit</button>
<button class="btn-sm" style="margin-left: 4px;" onclick="resetVar(' ${ escapeAttr ( v . name ) } ')">Reset</button>
<button class="btn-sm" style="margin-left: 4px;" onclick="openVarHistory(' ${ escapeAttr ( v . name ) } ')">History</button>
</td>
` ;
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 = '<tr><td colspan="5" style="text-align: center; color: var(--muted);">Loading history...</td></tr>' ;
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 = `
<td style="font-family: var(--font-mono); font-size: 11px;"> ${ h . ts ? h . ts . replace ( 'T' , ' ' ) . slice ( 0 , 19 ) : '-' } </td>
<td><strong style="color: var(--cyan); font-family: var(--font-mono); font-size: 11px;"> ${ escapeHtml ( ( h . action || '' ) . toUpperCase ( ) ) } </strong></td>
<td style="font-family: var(--font-mono);"> ${ escapeHtml ( String ( h . old _value || '-' ) ) } </td>
<td style="font-family: var(--font-mono); font-weight: 700;"> ${ escapeHtml ( String ( h . new _value || '-' ) ) } </td>
<td style="color: var(--muted);"> ${ escapeHtml ( h . by || 'super' ) } </td>
` ;
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 = {
2026-10-04 16:48:38 +00:00
type : itype ,
2026-10-04 16:32:52 +00:00
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 = ` <span style="color: ${ dotColor } ;">●</span> ${ 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 ` ;
}
}
// -------------------------------------------------------------------------
// 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 <token>" \\ \n https://box.muse-dev.online/api/box/fleet ` ;
} else if ( currentTab === 'dms' ) {
codeEl . textContent = ` curl -s -H "Authorization: Bearer <token>" \\ \n "https://box.muse-dev.online/api/box/dm/log?limit=50" ` ;
} else if ( currentTab === 'jobs' ) {
codeEl . textContent = ` curl -s -H "Authorization: Bearer <token>" \\ \n https://box.muse-dev.online/api/box/timers ` ;
} else if ( currentTab === 'loops' ) {
codeEl . textContent = ` curl -s -H "Authorization: Bearer <token>" \\ \n https://box.muse-dev.online/api/box/loop/status \n \n curl -s -H "Authorization: Bearer <token>" \\ \n https://box.muse-dev.online/api/box/loop/health ` ;
2026-10-05 20:18:47 +00:00
} else if ( currentTab === 'lookup' ) {
codeEl . textContent = ` curl -s -H "Authorization: Bearer <token>" \\ \n https://box.muse-dev.online/api/box/lookup \n \n # Or CLI lookup on bl: \n box lookup surfaces \n box lookup parse "[RESULT 7fce46e0] OK Done" ` ;
2026-10-04 16:32:52 +00:00
}
}
// -------------------------------------------------------------------------
// 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 , '>' )
. 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 ( ) ;
} ) ;
}
}
2026-10-05 20:18:47 +00:00
// -------------------------------------------------------------------------
// 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 : / ^ \ [ W O : ( [ a - f 0 - 9 - ] + ) \ ] \ s + \ [ f r o m \ s + ( [ a - z A - Z 0 - 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 : / \ [ R E S U L T \ s + ( [ A - Z a - z 0 - 9 _ / - ] + ) \ ] \ s * ( O K | F A I L | D E C L I N E | S U C C E S S | E R R O R ) ? \ s * ( . * ? ) ( ? = \ [ R E S U L T \ s | $ ) / s ,
fields : [ 'job_id' , 'status' , 'summary' ]
} ,
{
key : 'tool_call' ,
name : 'In-Band Tool Call' ,
regex : / \ [ ( T O O L | E X E C ) \ s + ( [ a - z A - Z 0 - 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 = `
<div style="color: var(--warn); display: flex; align-items: center; gap: 8px;">
<span>⚠</span>
<span>No canonical sentence pattern matched this input. Check required tags: [WO:id] [from sender], [ACK:id], [RESULT id] OK, or [CLAIM id].</span>
</div>
` ;
} else {
let html = ` <div style="color: var(--ok); font-weight: 700; margin-bottom: 8px;">✔ Valid Syntax — Matched ${ matches . length } Pattern(s):</div> ` ;
matches . forEach ( m => {
html += `
<div style="border-top: 1px solid var(--border); padding-top: 8px; margin-top: 8px;">
<div style="font-weight: 600; color: var(--accent); margin-bottom: 4px;">Pattern: ${ m . name } (<code> ${ m . key } </code>)</div>
<div style="color: var(--muted); font-size: 11px; margin-bottom: 6px;">Matched Chunk: <span style="color: var(--fg);"> ${ m . matchedText } </span></div>
<div style="display: flex; flex-wrap: wrap; gap: 8px;">
` ;
Object . entries ( m . tokens ) . forEach ( ( [ k , v ] ) => {
html += `
<div style="background: var(--bg); border: 1px solid var(--border); padding: 4px 8px; border-radius: 4px; font-size: 12px;">
<span style="color: var(--muted);"> ${ k } :</span> <strong style="color: var(--ok);"> ${ v || '-' } </strong>
</div>
` ;
} ) ;
html += ` </div></div> ` ;
} ) ;
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 : '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).' }
] ;
tbody . innerHTML = surfaces . map ( s => `
<tr>
<td style="font-weight: 600; color: var(--fg);"> ${ s . name } </td>
<td><code>#tab- ${ s . id } </code></td>
<td><code style="color: var(--accent);"> ${ s . selector } </code></td>
<td><code style="color: var(--ok);"> ${ s . route } </code></td>
<td style="color: var(--muted); font-size: 12px;"> ${ s . hint } </td>
</tr>
` ) . join ( '' ) ;
}
function renderLookupSentences ( ) {
const grid = document . getElementById ( 'lookup-sentence-grid' ) ;
if ( ! grid ) return ;
const cards = [
{ name : 'Work Order' , tag : '[WO:<id>]' , 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:<id>]' , template : '[ACK:{id}] [from {sender}]' , lifecycle : 'open -> acknowledged' , desc : 'Confirms receipt of task without closing the tracked loop.' } ,
{ name : 'Task Claim' , tag : '[CLAIM <id>]' , 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 <id>]' , template : '[RESULT {job_id}] {status} {summary}' , lifecycle : 'claimed -> resolved' , desc : 'Submits completion evidence and resolves the active loop.' } ,
{ name : 'Task Decline' , tag : '[DECLINE <id>]' , 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 <op> <args>]' , 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 => `
<div class="node-card" style="padding: 16px;">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px;">
<span style="font-weight: 700; color: var(--fg);"> ${ c . name } </span>
<span class="node-status-badge badge-active"> ${ c . tag } </span>
</div>
<div style="font-family: var(--font-mono); font-size: 12px; color: var(--accent); background: var(--bg); padding: 6px 8px; border-radius: 4px; margin-bottom: 8px; word-break: break-all;"> ${ c . template } </div>
<div style="font-size: 12px; color: var(--muted); margin-bottom: 8px;"> ${ c . desc } </div>
<div style="font-size: 11px; color: var(--muted); text-transform: uppercase;">Lifecycle: <span style="color: var(--ok);"> ${ c . lifecycle } </span></div>
</div>
` ) . 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 ( ) ;
}
2026-10-04 16:32:52 +00:00
// -------------------------------------------------------------------------
// 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 ( ) ;
2026-10-05 20:18:47 +00:00
setupLookupTab ( ) ;
2026-10-04 16:32:52 +00:00
// 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 ( ) ;
}
} ) ( ) ;