feat(#986): dedicated logs page with build/agent/system sub-tabs

Add /logs.html as a standalone page (same back-link pattern as flow.html):
- BUILD tab: all-agents build log history via new GET /api/build-logs endpoint
- AGENT tab: per-container journald viewer with agent selector + unit filter
- SYSTEM tab: host-side hive-c0re.service logs via new GET /api/journal-host endpoint

Remove inline log drill-ins from SW4RM container rows (buildJournalTrigger
and buildBuildLogsTrigger) — log viewing now lives on the dedicated page.

flow.html: strip the full dashboard tabbar, replace with a simple back link
matching the new logs page chrome.

index.html: add L0GS tab link to /logs.html in the tab strip.

Backend additions:
- build_logs::list_recent_all — cross-agent query (newest first, cap 100)
- GET /api/build-logs — all-agents variant backed by list_recent_all
- GET /api/journal-host — host journald (no -M container flag), restricted
  to allow-listed units (hive-c0re.service)
This commit is contained in:
iris 2026-06-01 19:11:47 +02:00
commit 0b15cad93f
9 changed files with 534 additions and 299 deletions

View file

@ -8,46 +8,13 @@
</head>
<body class="flow-shell">
<!-- Fixed-overlay chrome — just the tab strip. The full-viewport
terminal has no normal-flow footer position so the dashboard's
slug doesn't appear here. The operator can still switch tabs
from the flow page without navigating back; FL0W is the current
page, SW4RM / Y3R C4LL / SYST3M / SCH3DUL3S cross-link to the
dashboard with the matching hash. -->
<header class="dashboard-chrome flow-chrome" id="flow-header">
<nav class="tabbar" id="tabbar" role="tablist">
<a class="tab" href="/#swarm" role="tab" data-tab="swarm">
<span class="tab-label">◆ SW4RM ◆</span>
<span class="tab-count" id="tab-count-swarm" hidden></span>
</a>
<a class="tab" href="/#call" role="tab" data-tab="call">
<span class="tab-label">◆ Y3R C4LL ◆</span>
<span class="tab-count tab-count-attn" id="tab-count-call" hidden></span>
</a>
<a class="tab" href="/#system" role="tab" data-tab="system">
<span class="tab-label">◆ SYST3M ◆</span>
<span class="tab-count" id="tab-count-system" hidden></span>
</a>
<a class="tab" href="/#schedules" role="tab" data-tab="schedules">
<span class="tab-label">◆ SCH3DUL3S ◆</span>
<span class="tab-count" id="tab-count-schedules" hidden></span>
</a>
<a class="tab tab-link active" id="tab-flow" href="/flow.html"
aria-current="page"
title="all-agents chat — you are here">
<span class="tab-label">◆ FL0W ◆</span>
<span class="tab-count" id="tab-count-flow" hidden></span>
</a>
<!-- S3TT1NGS cross-links to the dashboard tab — notification
toggle + future preferences live there now. `NOTIF.show()`
in common.js doesn't depend on the buttons existing here,
so notifications still fire on this page when they're
enabled (or muted) in dashboard settings. -->
<a class="tab tab-link" href="/#settings"
title="open S3TT1NGS on the dashboard">
<span class="tab-label">◆ S3TT1NGS ◆ →</span>
</a>
</nav>
<!-- Minimal chrome: just a back link. No full tabbar — the main
dashboard already has the tab strip. The flow page is a
dedicated full-viewport terminal surface; navigating back
is the only chrome needed. -->
<header class="logs-header">
<a class="logs-back" href="/">← dashboard</a>
<span class="logs-title">FL0W</span>
</header>
<!-- Operator inbox flyout trigger — count + click → side panel
@ -63,7 +30,7 @@
<!-- Main content: the full-viewport terminal. Padded for the
overlay header + composer so the first/last rows stay
reachable. -->
<main class="flow-main">
<main class="flow-main flow-main-slim">
<div class="terminal-wrap">
<div id="msgflow" class="live terminal"><div class="meta">connecting…</div></div>
</div>