From ed71c3cd4324c370a7d0e5b4f3bd9f810a118387 Mon Sep 17 00:00:00 2001 From: Emil Date: Sat, 18 Jul 2026 23:45:05 +0300 Subject: [PATCH] feat: add MCP control plane and live dashboard --- Dashboard.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Dashboard.html b/Dashboard.html index 5e6b84e..98a5e94 100644 --- a/Dashboard.html +++ b/Dashboard.html @@ -8,7 +8,7 @@ const agents=document.querySelector('#agents'),events=document.querySelector('#e const esc=s=>String(s??'').replace(/[&<>"']/g,c=>({'&':'&','<':'<','>':'>','"':'"',"'":'''}[c])); function drawAgents(items){agents.innerHTML=items.length?items.map(a=>`
${esc(a.name)} ${esc(a.role)}
${esc(a.state)}
${esc(a.workspace)}
${(a.scopes||[]).map(s=>`${esc(s)}`).join('')||'No exclusive scopes'}
`).join(''):'
No agents yet. Create one through the MCP tool or REST API.
'} async function refresh(){try{drawAgents(await (await fetch('/agents')).json())}catch{agents.innerHTML='
Dashboard cannot reach KimiFleet.
'}} -function add(e){const text=pretty(e);if(text===null)return;const time=new Date(e.time).toLocaleTimeString();const row=document.createElement('article');row.className='event';row.innerHTML=`
${esc(time)} · ${esc(e.agent)} · ${esc(e.kind)}
${esc(text)}
`;events.prepend(row);while(events.children.length>140)events.removeChild(events.lastChild)} -function pretty(e){if(e.kind!=='session/update')return e.message;try{const u=JSON.parse(e.message).update;if(u.sessionUpdate==='tool_call_update')return `${u.title||'Tool call'} — ${u.status||'in progress'}`;if(u.sessionUpdate==='agent_thought_chunk'||u.sessionUpdate==='agent_message_chunk')return null;return u.sessionUpdate||'session update'}catch{return e.message}} +function add(e){const text=pretty(e);if(text===null)return;events.querySelector('.empty')?.remove();const time=new Date(e.time).toLocaleTimeString();const row=document.createElement('article');row.className='event';row.innerHTML=`
${esc(time)} · ${esc(e.agent)} · ${esc(e.kind)}
${esc(text)}
`;events.prepend(row);while(events.children.length>140)events.removeChild(events.lastChild)} +function pretty(e){if(e.kind!=='session/update')return e.message;try{const u=JSON.parse(e.message).update;if(u.sessionUpdate==='tool_call_update')return `${u.title||'Tool call'} — ${u.status||'in progress'}`;if(['agent_thought_chunk','agent_message_chunk','available_commands_update','tool_call'].includes(u.sessionUpdate))return null;return u.sessionUpdate||'session update'}catch{return e.message}} new EventSource('/events').onmessage=x=>{add(JSON.parse(x.data));refresh()};refresh();setInterval(refresh,5000);