import { useMemo } from "react";
import { useHive } from "../store";
import { hhmmss } from "../lib/agents";
// The live wall clock. Reads the store's 1s `now` tick — no second timer.
function Clock() {
const now = useHive((s) => s.now);
return (
{hhmmss(now || Date.now())}
);
}
// Recent provider back-pressure (Phase 4.11): `provider_response` is emitted only
// for non-2xx responses (429/529 rate-limit/overload). Surface a count of those
// seen in the last few minutes so a stalled fleet has a visible cause. Silent
// when there's no recent pressure.
//
// R3-2.5: read `scopedEvents` (already filtered to the selected scope) rather than
// the fleet-wide `allEvents`, so the indicator reflects the pressure on what the
// user is actually looking at. The window filter is memoized so it doesn't re-scan
// on every unrelated render (the 1s `now` tick advances the window boundary, so it
// recomputes ~once a second by design, not per keystroke).
const PRESSURE_WINDOW_MS = 5 * 60_000;
function ProviderPressure() {
const events = useHive((s) => s.scopedEvents);
const now = useHive((s) => s.now);
const recent = useMemo(
() => events.filter(
(e) => e.type === "provider_response" && (now || Date.now()) - new Date(e.ts).getTime() < PRESSURE_WINDOW_MS,
),
[events, now],
);
if (!recent.length) return null;
// scopedEvents is newest-first (recomputeScoped reverses it), so recent[0] is the
// latest pressure response.
const last = recent[0];
const status = last?.payload?.status;
return (
{recent.length}× {status ?? "429/529"}
);
}
export default function Topbar() {
const liveCount = useHive((s) => s.scopedStats.live);
const isLive = liveCount > 0;
return (
);
}