← back to kavekonAI__OCLANetwork

Function bodies 47 total

All specs Real LLM only Function bodies
k8sToken function · javascript · L30-L32 (3 LOC)
dashboard/server.js
function k8sToken() {
  try { return fs.readFileSync(K8S_TOKEN_FILE, 'utf8').trim(); } catch { return ''; }
}
k8sCa function · javascript · L33-L35 (3 LOC)
dashboard/server.js
function k8sCa() {
  try { return fs.readFileSync(K8S_CA_FILE); } catch { return undefined; }
}
k8sGet function · javascript · L37-L56 (20 LOC)
dashboard/server.js
async function k8sGet(path) {
  const https = require('https');
  return new Promise((resolve, reject) => {
    const req = https.request(`${K8S_API}${path}`, {
      method: 'GET',
      headers: { Authorization: `Bearer ${k8sToken()}`, Accept: 'application/json' },
      ca: k8sCa(),
    }, (res) => {
      let body = '';
      res.on('data', (d) => body += d);
      res.on('end', () => {
        try { resolve({ status: res.statusCode, body: JSON.parse(body) }); }
        catch { resolve({ status: res.statusCode, body }); }
      });
    });
    req.on('error', reject);
    req.setTimeout(5000, () => { req.destroy(new Error('k8s request timeout')); });
    req.end();
  });
}
k8sPatch function · javascript · L58-L84 (27 LOC)
dashboard/server.js
async function k8sPatch(path, body) {
  const https = require('https');
  const data = JSON.stringify(body);
  return new Promise((resolve, reject) => {
    const req = https.request(`${K8S_API}${path}`, {
      method: 'PATCH',
      headers: {
        Authorization: `Bearer ${k8sToken()}`,
        'Content-Type': 'application/strategic-merge-patch+json',
        'Content-Length': Buffer.byteLength(data),
        Accept: 'application/json',
      },
      ca: k8sCa(),
    }, (res) => {
      let body = '';
      res.on('data', (d) => body += d);
      res.on('end', () => {
        try { resolve({ status: res.statusCode, body: JSON.parse(body) }); }
        catch { resolve({ status: res.statusCode, body }); }
      });
    });
    req.on('error', reject);
    req.setTimeout(10000, () => { req.destroy(new Error('k8s patch timeout')); });
    req.write(data);
    req.end();
  });
}
isGatewayReady function · javascript · L90-L101 (12 LOC)
dashboard/server.js
async function isGatewayReady() {
  if (gatewayReadyCache !== null && Date.now() < gatewayReadyExpiry) return gatewayReadyCache;
  try {
    const res = await k8sGet('/apis/apps/v1/namespaces/ocl-agents/deployments/gateway-home');
    const avail = res.body?.status?.availableReplicas || 0;
    gatewayReadyCache = avail >= 1;
  } catch {
    gatewayReadyCache = false;
  }
  gatewayReadyExpiry = Date.now() + 10000; // 10s cache
  return gatewayReadyCache;
}
getAgentList function · javascript · L107-L134 (28 LOC)
dashboard/server.js
async function getAgentList() {
  if (agentListCache && Date.now() < agentListExpiry) return agentListCache;
  try {
    const res = await k8sGet('/api/v1/namespaces/ocl-agents/configmaps/openclaw-home-config');
    if (res.status === 200 && res.body.data) {
      const configStr = res.body.data['config.json'] || res.body.data['openclaw.json'] || '';
      if (configStr) {
        const cfg = JSON.parse(configStr);
        const list = cfg.agents?.list || cfg.agents || [];
        agentListCache = Array.isArray(list)
          ? list.map((a) => (typeof a === 'string' ? { id: a, name: a } : a))
          : [];
      }
    }
  } catch (e) {
    console.error('[agents] ConfigMap read failed:', e.message);
  }
  // Fallback: scan redis heartbeat keys
  if (!agentListCache || agentListCache.length === 0) {
    const keys = await redisScan('ocl:heartbeat:*');
    agentListCache = keys.map((k) => {
      const id = k.replace('ocl:heartbeat:', '');
      return { id, name: id };
    });
  }
  
redisScan function · javascript · L137-L146 (10 LOC)
dashboard/server.js
async function redisScan(pattern) {
  const keys = [];
  let cursor = '0';
  do {
    const [nextCursor, batch] = await redis.scan(cursor, 'MATCH', pattern, 'COUNT', 200);
    cursor = nextCursor;
    keys.push(...batch);
  } while (cursor !== '0');
  return keys;
}
Powered by Repobility — scan your code at https://repobility.com
broadcast function · javascript · L152-L157 (6 LOC)
dashboard/server.js
function broadcast(type, data) {
  const msg = JSON.stringify({ type, data, ts: Date.now() });
  for (const ws of wsClients) {
    if (ws.readyState === 1) ws.send(msg);
  }
}
readSecurityStream function · javascript · L170-L194 (25 LOC)
dashboard/server.js
async function readSecurityStream() {
  // eslint-disable-next-line no-constant-condition
  while (true) {
    try {
      const results = await streamSecurity.xread(
        'BLOCK', 5000, 'STREAMS', 'ocl:security:audit', lastSecurityId
      );
      if (results) {
        for (const [, entries] of results) {
          for (const [id, fields] of entries) {
            lastSecurityId = id;
            const obj = { id };
            for (let i = 0; i < fields.length; i += 2) obj[fields[i]] = fields[i + 1];
            broadcast('security', obj);
          }
        }
      }
    } catch (e) {
      if (!e.message?.includes('Connection is closed')) {
        console.error('[stream:security]', e.message);
      }
      await new Promise((r) => setTimeout(r, 2000));
    }
  }
}
readDLPStream function · javascript · L196-L220 (25 LOC)
dashboard/server.js
async function readDLPStream() {
  // eslint-disable-next-line no-constant-condition
  while (true) {
    try {
      const results = await streamDLP.xread(
        'BLOCK', 5000, 'STREAMS', 'ocl:dlp:log', lastDLPId
      );
      if (results) {
        for (const [, entries] of results) {
          for (const [id, fields] of entries) {
            lastDLPId = id;
            const obj = { id };
            for (let i = 0; i < fields.length; i += 2) obj[fields[i]] = fields[i + 1];
            broadcast('dlp', obj);
          }
        }
      }
    } catch (e) {
      if (!e.message?.includes('Connection is closed')) {
        console.error('[stream:dlp]', e.message);
      }
      await new Promise((r) => setTimeout(r, 2000));
    }
  }
}
auth function · javascript · L223-L245 (23 LOC)
dashboard/server.js
function auth(req, res, next) {
  // Path 1: Tailscale identity headers (injected by tailscale serve)
  const tsLogin = req.headers['tailscale-user-login'];
  if (tsLogin && DASHBOARD_TAILSCALE_USERS.length > 0) {
    if (DASHBOARD_TAILSCALE_USERS.includes(tsLogin.toLowerCase())) {
      req.authMethod = 'tailscale';
      req.authUser = {
        login: tsLogin,
        name: req.headers['tailscale-user-name'] || '',
        pic: req.headers['tailscale-user-profile-pic'] || '',
      };
      return next();
    }
  }
  // Path 2: Bearer token
  if (!DASHBOARD_TOKEN) return next(); // no token configured — open (dev)
  const h = req.headers['authorization'] || '';
  if (h === `Bearer ${DASHBOARD_TOKEN}`) {
    req.authMethod = 'token';
    return next();
  }
  res.status(401).json({ error: 'Unauthorized' });
}
serveIndex function · javascript · L258-L265 (8 LOC)
dashboard/server.js
function serveIndex(res) {
  const indexPath = path.join(DIST, 'index.html');
  if (!fs.existsSync(indexPath)) {
    return res.status(503).send('Dashboard not built. Run: npm run build');
  }
  res.setHeader('Content-Type', 'text/html');
  res.sendFile(indexPath);
}
getToken function · javascript · L5-L7 (3 LOC)
dashboard/src/api.js
function getToken() {
  return sessionStorage.getItem(TOKEN_KEY) || '';
}
setToken function · javascript · L9-L15 (7 LOC)
dashboard/src/api.js
export function setToken(token) {
  if (token) {
    sessionStorage.setItem(TOKEN_KEY, token);
  } else {
    sessionStorage.removeItem(TOKEN_KEY);
  }
}
hasToken function · javascript · L17-L19 (3 LOC)
dashboard/src/api.js
export function hasToken() {
  return !!sessionStorage.getItem(TOKEN_KEY);
}
Repobility — same analyzer, your code, free for public repos · /scan/
verifyToken function · javascript · L21-L28 (8 LOC)
dashboard/src/api.js
export async function verifyToken(token) {
  const r = await fetch('/api/auth/verify', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ token }),
  });
  return r.ok;
}
whoami function · javascript · L30-L34 (5 LOC)
dashboard/src/api.js
export async function whoami() {
  const r = await fetch('/api/auth/whoami', { headers: headers() });
  if (!r.ok) return null;
  return r.json();
}
headers function · javascript · L36-L39 (4 LOC)
dashboard/src/api.js
function headers() {
  const t = getToken();
  return t ? { Authorization: `Bearer ${t}` } : {};
}
get function · javascript · L41-L50 (10 LOC)
dashboard/src/api.js
async function get(path) {
  const r = await fetch(path, { headers: headers() });
  if (r.status === 401) {
    setToken(null);
    window.dispatchEvent(new Event('oclan-auth-expired'));
    throw new Error('Session expired');
  }
  if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
  return r.json();
}
post function · javascript · L52-L65 (14 LOC)
dashboard/src/api.js
async function post(path, body) {
  const r = await fetch(path, {
    method: 'POST',
    headers: { ...headers(), 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  if (r.status === 401) {
    setToken(null);
    window.dispatchEvent(new Event('oclan-auth-expired'));
    throw new Error('Session expired');
  }
  if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
  return r.json();
}
del function · javascript · L67-L80 (14 LOC)
dashboard/src/api.js
async function del(path, body) {
  const r = await fetch(path, {
    method: 'DELETE',
    headers: { ...headers(), 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  });
  if (r.status === 401) {
    setToken(null);
    window.dispatchEvent(new Event('oclan-auth-expired'));
    throw new Error('Session expired');
  }
  if (!r.ok) throw new Error(`${r.status} ${r.statusText}`);
  return r.json();
}
useWebSocket function · javascript · L105-L132 (28 LOC)
dashboard/src/api.js
export function useWebSocket(onMessage) {
  const wsRef = useRef(null);
  const [connected, setConnected] = useState(false);

  useEffect(() => {
    function connect() {
      const token = getToken();
      const proto = location.protocol === 'https:' ? 'wss' : 'ws';
      const url = `${proto}://${location.host}/ws${token ? `?token=${token}` : ''}`;
      const ws = new WebSocket(url);
      wsRef.current = ws;

      ws.onopen = () => setConnected(true);
      ws.onclose = () => {
        setConnected(false);
        setTimeout(connect, 3000);
      };
      ws.onerror = () => ws.close();
      ws.onmessage = (e) => {
        try { onMessage(JSON.parse(e.data)); } catch {}
      };
    }
    connect();
    return () => { wsRef.current?.close(); };
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  return connected;
}
connect function · javascript · L110-L126 (17 LOC)
dashboard/src/api.js
    function connect() {
      const token = getToken();
      const proto = location.protocol === 'https:' ? 'wss' : 'ws';
      const url = `${proto}://${location.host}/ws${token ? `?token=${token}` : ''}`;
      const ws = new WebSocket(url);
      wsRef.current = ws;

      ws.onopen = () => setConnected(true);
      ws.onclose = () => {
        setConnected(false);
        setTimeout(connect, 3000);
      };
      ws.onerror = () => ws.close();
      ws.onmessage = (e) => {
        try { onMessage(JSON.parse(e.data)); } catch {}
      };
    }
Repobility (the analyzer behind this table) · https://repobility.com
Login function · javascript · L34-L87 (54 LOC)
dashboard/src/App.jsx
function Login({ onLogin }) {
  const [token, setInputToken] = useState('')
  const [error, setError] = useState('')
  const [loading, setLoading] = useState(false)

  const handleSubmit = async (e) => {
    e.preventDefault()
    setError('')
    setLoading(true)
    try {
      const valid = await verifyToken(token.trim())
      if (valid) {
        setToken(token.trim())
        onLogin()
      } else {
        setError('Invalid token')
      }
    } catch {
      setError('Connection failed')
    }
    setLoading(false)
  }

  return (
    <div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100vh' }}>
      <form onSubmit={handleSubmit} style={{
        background: '#161b22', border: '1px solid #30363d', borderRadius: 8,
        padding: 32, width: 380, display: 'flex', flexDirection: 'column', gap: 16,
      }}>
        <div style={{ fontWeight: 700, fontSize: 18, color: '#58a6ff', textAlign: 'center' }}>OCLAN Dashboard</div>
        <div sty
App function · javascript · L89-L228 (140 LOC)
dashboard/src/App.jsx
export default function App() {
  const [authed, setAuthed] = useState(false)
  const [authChecking, setAuthChecking] = useState(true)
  const [authUser, setAuthUser] = useState(null)
  const [tab, setTab] = useState('overview')
  const [wsEvents, setWsEvents] = useState([])

  // Auto-login: try whoami on mount (handles Tailscale SSO + stored token)
  useEffect(() => {
    let cancelled = false
    async function tryAutoLogin() {
      try {
        const info = await whoami()
        if (!cancelled && info) {
          setAuthUser(info)
          setAuthed(true)
        }
      } catch {}
      if (!cancelled) setAuthChecking(false)
    }
    tryAutoLogin()
    return () => { cancelled = true }
  }, [])

  // Listen for auth expiry from api.js (401 responses)
  useEffect(() => {
    const handler = () => { setAuthed(false); setAuthUser(null) }
    window.addEventListener('oclan-auth-expired', handler)
    return () => window.removeEventListener('oclan-auth-expired', handler)
  }, [])
tryAutoLogin function · javascript · L99-L108 (10 LOC)
dashboard/src/App.jsx
    async function tryAutoLogin() {
      try {
        const info = await whoami()
        if (!cancelled && info) {
          setAuthUser(info)
          setAuthed(true)
        }
      } catch {}
      if (!cancelled) setAuthChecking(false)
    }
ALKBTab function · javascript · L4-L172 (169 LOC)
dashboard/src/components/ALKBTab.jsx
export default function ALKBTab() {
  const [failures, setFailures] = useState([])
  const [fixed, setFixed] = useState([])
  const [pendingCount, setPendingCount] = useState(0)
  const [loading, setLoading] = useState(true)
  const [subTab, setSubTab] = useState('failures')
  const [filter, setFilter] = useState('')
  const [promoting, setPromoting] = useState(null)
  const [error, setError] = useState(null)
  const [msg, setMsg] = useState(null)

  async function load() {
    try {
      const [f, fx, pc] = await Promise.all([
        api.alkbFailures(),
        api.alkbFixed(),
        api.alkbPendingCount(),
      ])
      setFailures(f)
      setFixed(fx)
      setPendingCount(pc.count || 0)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => { load() }, [])

  async function promote(id) {
    setPromoting(id)
    setMsg(null)
    try {
      await api.promoteAlkb(id)
      setMsg({ ok: true, text: `
load function · javascript · L15-L31 (17 LOC)
dashboard/src/components/ALKBTab.jsx
  async function load() {
    try {
      const [f, fx, pc] = await Promise.all([
        api.alkbFailures(),
        api.alkbFixed(),
        api.alkbPendingCount(),
      ])
      setFailures(f)
      setFixed(fx)
      setPendingCount(pc.count || 0)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }
promote function · javascript · L35-L47 (13 LOC)
dashboard/src/components/ALKBTab.jsx
  async function promote(id) {
    setPromoting(id)
    setMsg(null)
    try {
      await api.promoteAlkb(id)
      setMsg({ ok: true, text: `Promoted ${id} to Fixed` })
      await load()
    } catch (e) {
      setMsg({ ok: false, text: `Promote failed: ${e.message}` })
    } finally {
      setPromoting(null)
    }
  }
streamIdToDate function · javascript · L4-L7 (4 LOC)
dashboard/src/components/DLPLog.jsx
function streamIdToDate(id) {
  const ts = parseInt(id?.split('-')[0], 10)
  return isNaN(ts) ? '—' : new Date(ts).toLocaleString()
}
DLPLog function · javascript · L9-L88 (80 LOC)
dashboard/src/components/DLPLog.jsx
export default function DLPLog({ liveEvents = [] }) {
  const [historical, setHistorical] = useState([])
  const [filter, setFilter] = useState('')
  const [agentFilter, setAgentFilter] = useState('')
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    api.dlp(100).then(setHistorical).finally(() => setLoading(false))
  }, [])

  const liveIds = new Set(liveEvents.map((e) => e.id))
  const merged = [...liveEvents, ...historical.filter((e) => !liveIds.has(e.id))]
  const filtered = merged.filter((e) => {
    if (agentFilter && e.agent !== agentFilter) return false
    if (filter && !JSON.stringify(e).toLowerCase().includes(filter.toLowerCase())) return false
    return true
  })

  const agents = [...new Set(merged.map((e) => e.agent).filter(Boolean))]

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12, flexWrap: 'wrap' }}>
        <h3 style={{ fontSize: 14 }}>Egress DLP Log</h3>
        {liveEvents.length > 0 &&
About: code-quality intelligence by Repobility · https://repobility.com
CountdownTimer function · javascript · L4-L20 (17 LOC)
dashboard/src/components/EfficiencyTab.jsx
function CountdownTimer({ resetAt }) {
  const [label, setLabel] = useState('')
  useEffect(() => {
    function tick() {
      const diff = parseInt(resetAt, 10) - Date.now()
      if (diff <= 0) { setLabel('Resetting…'); return }
      const h = Math.floor(diff / 3600000)
      const m = Math.floor((diff % 3600000) / 60000)
      const s = Math.floor((diff % 60000) / 1000)
      setLabel(`${h}h ${m}m ${s}s`)
    }
    tick()
    const t = setInterval(tick, 1000)
    return () => clearInterval(t)
  }, [resetAt])
  return <span style={{ color: '#58a6ff', fontWeight: 600 }}>{label}</span>
}
tick function · javascript · L7-L14 (8 LOC)
dashboard/src/components/EfficiencyTab.jsx
    function tick() {
      const diff = parseInt(resetAt, 10) - Date.now()
      if (diff <= 0) { setLabel('Resetting…'); return }
      const h = Math.floor(diff / 3600000)
      const m = Math.floor((diff % 3600000) / 60000)
      const s = Math.floor((diff % 60000) / 1000)
      setLabel(`${h}h ${m}m ${s}s`)
    }
EfficiencyTab function · javascript · L22-L144 (123 LOC)
dashboard/src/components/EfficiencyTab.jsx
export default function EfficiencyTab() {
  const [rows, setRows] = useState([])
  const [sub, setSub] = useState({})
  const [litellm, setLitellm] = useState(null)
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  async function load() {
    try {
      const [eff, s, ll] = await Promise.all([
        api.efficiency(),
        api.subscription(),
        api.litellmStatus(),
      ])
      setRows(eff)
      setSub(s)
      setLitellm(ll)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
    const t = setInterval(load, 30000)
    return () => clearInterval(t)
  }, [])

  // High-Burn leaderboard: sort by cost desc
  const leaderboard = [...rows].sort((a, b) =>
    parseFloat(b.cost || '0') - parseFloat(a.cost || '0')
  ).slice(0, 10)

  if (loading) return <div style={{ color: '#8b949e' }}>Loading efficiency data…</div>
  if (error) return <div st
load function · javascript · L29-L45 (17 LOC)
dashboard/src/components/EfficiencyTab.jsx
  async function load() {
    try {
      const [eff, s, ll] = await Promise.all([
        api.efficiency(),
        api.subscription(),
        api.litellmStatus(),
      ])
      setRows(eff)
      setSub(s)
      setLitellm(ll)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }
ConfirmDialog function · javascript · L4-L62 (59 LOC)
dashboard/src/components/ManagementTab.jsx
function ConfirmDialog({ agentId, pendingCount, onConfirm, onCancel }) {
  const [text, setText] = useState('')
  const expected = `NUKE ${agentId}`
  return (
    <div style={{
      position: 'fixed', top: 0, left: 0, right: 0, bottom: 0,
      background: '#0d111799', display: 'flex', alignItems: 'center', justifyContent: 'center',
      zIndex: 1000,
    }}>
      <div style={{
        background: '#161b22', border: '1px solid #f85149', borderRadius: 8,
        padding: '24px 28px', maxWidth: 420, width: '90%',
      }}>
        <div style={{ fontSize: 16, fontWeight: 700, color: '#f85149', marginBottom: 12 }}>
          Nuke Agent: {agentId}
        </div>
        <div style={{ fontSize: 13, color: '#8b949e', marginBottom: 16, lineHeight: 1.6 }}>
          This will archive agent state to ALKB, clear all task state, and remove status keys from Redis.
          The gateway pod will NOT be deleted (agents share a pod).
        </div>
        <div style={{
          background: '#0d1
ManagementTab function · javascript · L64-L243 (180 LOC)
dashboard/src/components/ManagementTab.jsx
export default function ManagementTab() {
  const [agents, setAgents] = useState([])
  const [pendingCount, setPendingCount] = useState(0)
  const [loading, setLoading] = useState(true)
  const [nukeTarget, setNukeTarget] = useState(null)
  const [busy, setBusy] = useState({})
  const [msgs, setMsgs] = useState({})
  const [error, setError] = useState(null)

  async function load() {
    try {
      const [a, pc] = await Promise.all([api.agents(), api.alkbPendingCount()])
      setAgents(a)
      setPendingCount(pc.count || 0)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
    const t = setInterval(load, 15000)
    return () => clearInterval(t)
  }, [])

  async function action(fn, id, label) {
    setBusy((b) => ({ ...b, [id]: label }))
    setMsgs((m) => ({ ...m, [id]: null }))
    try {
      await fn()
      setMsgs((m) => ({ ...m, [id]: { ok: true, text: `${label} OK` } }))
      aw
load function · javascript · L73-L84 (12 LOC)
dashboard/src/components/ManagementTab.jsx
  async function load() {
    try {
      const [a, pc] = await Promise.all([api.agents(), api.alkbPendingCount()])
      setAgents(a)
      setPendingCount(pc.count || 0)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }
action function · javascript · L92-L104 (13 LOC)
dashboard/src/components/ManagementTab.jsx
  async function action(fn, id, label) {
    setBusy((b) => ({ ...b, [id]: label }))
    setMsgs((m) => ({ ...m, [id]: null }))
    try {
      await fn()
      setMsgs((m) => ({ ...m, [id]: { ok: true, text: `${label} OK` } }))
      await load()
    } catch (e) {
      setMsgs((m) => ({ ...m, [id]: { ok: false, text: e.message } }))
    } finally {
      setBusy((b) => { const n = { ...b }; delete n[id]; return n })
    }
  }
Powered by Repobility — scan your code at https://repobility.com
confirmNuke function · javascript · L106-L109 (4 LOC)
dashboard/src/components/ManagementTab.jsx
  async function confirmNuke(id, confirmText) {
    setNukeTarget(null)
    await action(() => api.nukeAgent(id, confirmText), id, 'Nuke')
  }
restartGateway function · javascript · L111-L122 (12 LOC)
dashboard/src/components/ManagementTab.jsx
  async function restartGateway() {
    setBusy((b) => ({ ...b, _gateway: 'Restarting' }))
    setMsgs((m) => ({ ...m, _gateway: null }))
    try {
      await api.restartGateway()
      setMsgs((m) => ({ ...m, _gateway: { ok: true, text: 'Gateway restart triggered' } }))
    } catch (e) {
      setMsgs((m) => ({ ...m, _gateway: { ok: false, text: e.message } }))
    } finally {
      setBusy((b) => { const n = { ...b }; delete n._gateway; return n })
    }
  }
Overview function · javascript · L17-L118 (102 LOC)
dashboard/src/components/Overview.jsx
export default function Overview() {
  const [agents, setAgents] = useState([])
  const [sub, setSub] = useState({})
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState(null)

  async function load() {
    try {
      const [a, s] = await Promise.all([api.agents(), api.subscription()])
      setAgents(a)
      setSub(s)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
    const t = setInterval(load, 15000)
    return () => clearInterval(t)
  }, [])

  // Reset countdown
  let resetIn = null
  if (sub.reset_at) {
    const diff = parseInt(sub.reset_at, 10) - Date.now()
    if (diff > 0) {
      const h = Math.floor(diff / 3600000)
      const m = Math.floor((diff % 3600000) / 60000)
      resetIn = `${h}h ${m}m`
    }
  }

  if (loading) return <div style={{ color: '#8b949e' }}>Loading agents…</div>
  if (error) return <div style={{ color: '#f85149' }}>Error:
load function · javascript · L23-L34 (12 LOC)
dashboard/src/components/Overview.jsx
  async function load() {
    try {
      const [a, s] = await Promise.all([api.agents(), api.subscription()])
      setAgents(a)
      setSub(s)
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }
streamIdToDate function · javascript · L4-L7 (4 LOC)
dashboard/src/components/SecurityLog.jsx
function streamIdToDate(id) {
  const ts = parseInt(id?.split('-')[0], 10)
  return isNaN(ts) ? '—' : new Date(ts).toLocaleString()
}
SecurityLog function · javascript · L9-L86 (78 LOC)
dashboard/src/components/SecurityLog.jsx
export default function SecurityLog({ liveEvents = [] }) {
  const [historical, setHistorical] = useState([])
  const [filter, setFilter] = useState('')
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    api.security(100).then(setHistorical).finally(() => setLoading(false))
  }, [])

  // Merge: live events at top, historical below (deduplicate by id)
  const liveIds = new Set(liveEvents.map((e) => e.id))
  const merged = [...liveEvents, ...historical.filter((e) => !liveIds.has(e.id))]
  const filtered = merged.filter((e) =>
    !filter || JSON.stringify(e).toLowerCase().includes(filter.toLowerCase())
  )

  return (
    <div>
      <div style={{ display: 'flex', alignItems: 'center', gap: 12, marginBottom: 12 }}>
        <h3 style={{ fontSize: 14 }}>Security Audit Log</h3>
        {liveEvents.length > 0 && (
          <span style={{ fontSize: 11, color: '#f85149', fontWeight: 600 }}>
            ● {liveEvents.length} live
          </span>
        )}
        <inpu
TaskBoard function · javascript · L12-L122 (111 LOC)
dashboard/src/components/TaskBoard.jsx
export default function TaskBoard() {
  const [tasks, setTasks] = useState([])
  const [loading, setLoading] = useState(true)
  const [filter, setFilter] = useState('')
  const [error, setError] = useState(null)

  async function load() {
    try {
      setTasks(await api.tasks())
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }

  useEffect(() => {
    load()
    const t = setInterval(load, 15000)
    return () => clearInterval(t)
  }, [])

  const filtered = tasks.filter((t) =>
    !filter || JSON.stringify(t).toLowerCase().includes(filter.toLowerCase())
  )

  // Queue depth by agent
  const queueDepth = {}
  for (const t of tasks) {
    if (t.agent && t.status !== 'completed') {
      queueDepth[t.agent] = (queueDepth[t.agent] || 0) + 1
    }
  }

  if (loading) return <div style={{ color: '#8b949e' }}>Loading tasks…</div>
  if (error) return <div style={{ color: '#f85149' }}>Error: {error}</div>

  return (
    <di
load function · javascript · L18-L27 (10 LOC)
dashboard/src/components/TaskBoard.jsx
  async function load() {
    try {
      setTasks(await api.tasks())
      setError(null)
    } catch (e) {
      setError(e.message)
    } finally {
      setLoading(false)
    }
  }