// Logs — streaming monospace surface. Filter pills + a fake live tail. const LOG_LINES = [ { ts: '09:42:18.124', level: 'info', source: 'gateway', msg: 'POST /v1/messages → 200 (1.2s, 482 tokens out)' }, { ts: '09:42:18.066', level: 'debug', source: 'tool', msg: 'tool_call read_file path=src/App.jsx (8.2KB)' }, { ts: '09:42:17.880', level: 'info', source: 'agent', msg: 'turn 14 started — personality=Forge model=claude-sonnet-4.5' }, { ts: '09:42:15.341', level: 'warn', source: 'mcp', msg: 'github: rate-limit warning 4500/5000 used this hour' }, { ts: '09:42:11.012', level: 'info', source: 'tool', msg: 'tool_call execute cmd="npm test -- --watch=false" status=ok 14.2s' }, { ts: '09:42:01.508', level: 'error', source: 'tool', msg: 'tool_call execute denied: command "rm -rf node_modules" matches deny rule "rm -rf"' }, { ts: '09:41:58.211', level: 'info', source: 'agent', msg: 'user message received (1.4KB)' }, { ts: '09:41:42.004', level: 'debug', source: 'memory', msg: 'AGENTS.md hash unchanged (4f02…ab19), skipping reload' }, { ts: '09:41:30.882', level: 'info', source: 'cron', msg: 'incident-triage finished ok (4.2s)' }, { ts: '09:41:26.108', level: 'info', source: 'cron', msg: 'incident-triage started' }, { ts: '09:41:18.443', level: 'info', source: 'mcp', msg: 'linear: tools/list 9 tools (142ms)' }, { ts: '09:40:54.221', level: 'warn', source: 'gateway', msg: 'approval pending: tool_call execute cmd="git push origin main" (12s)' }, { ts: '09:40:42.001', level: 'info', source: 'agent', msg: 'turn 13 ended — 2.1s, 7 tool calls, $0.0042' }, { ts: '09:40:21.778', level: 'debug', source: 'tool', msg: 'tool_call list_files path=ui_kits/scarf-mac (24 entries)' }, { ts: '09:40:18.422', level: 'error', source: 'mcp', msg: 'notion: TLS handshake failed (timeout 5s) — backing off 30s' }, { ts: '09:40:02.114', level: 'info', source: 'agent', msg: 'session resumed (idle 14m)' }, ]; const LEVEL_TONES = { debug: '#7C7263', info: 'var(--blue-500)', warn: 'var(--amber-500)', error: 'var(--red-500)', }; function Logs() { const [level, setLevel] = React.useState(['info', 'warn', 'error']); const [source, setSource] = React.useState('all'); const [search, setSearch] = React.useState(''); const [follow, setFollow] = React.useState(true); React.useEffect(() => { requestAnimationFrame(() => window.lucide && window.lucide.createIcons()); }); const sources = ['all', 'agent', 'tool', 'gateway', 'mcp', 'cron', 'memory']; const filtered = LOG_LINES.filter(l => { if (!level.includes(l.level)) return false; if (source !== 'all' && l.source !== source) return false; if (search && !l.msg.toLowerCase().includes(search.toLowerCase())) return false; return true; }); return (