import { useEffect, useReducer, useState } from "react"; import { useSessionStore } from "../store/sessionStore"; import { WorkingSpinner } from "./WorkingSpinner"; /** Last few non-blank lines of a string — a compact "what the model is doing now" * tail (mirrors ModelActivityPanel's tail-line logic, at a smaller size). Returned * as an array so each line renders as its own formatted log row. */ function tailLines(s: string, n = 5): string[] { return s .split("\n") .map((l) => l.trimEnd()) .filter((l) => l.trim() !== "") .slice(-n); } /** The minimal central view: the user's last input/choice, a live "working" indicator * (elapsed time + a short tail of the model stream) while the model is busy, and the * gate's curated messages for the current step. The full verbose stream lives in the * left Model-activity panel. */ export function CentralStatus({ working }: { working: boolean }) { const lastUserEntry = useSessionStore((s) => s.lastUserEntry); const stepMessages = useSessionStore((s) => s.stepMessages); const transcript = useSessionStore((s) => s.transcript); const [startedAt, setStartedAt] = useState(null); const [, tick] = useReducer((x: number) => x + 1, 0); // Start the per-step timer when work begins; tick once a second so the elapsed // display updates; clear it when work stops. useEffect(() => { if (!working) { setStartedAt(null); return; } setStartedAt((prev) => prev ?? Date.now()); const id = setInterval(tick, 1000); return () => clearInterval(id); }, [working]); if (!working && !lastUserEntry && stepMessages.length === 0) return null; const elapsed = startedAt ? Math.max(0, Math.floor((Date.now() - startedAt) / 1000)) : 0; const tailRows = tailLines(transcript.at(-1)?.text ?? ""); return (
{lastUserEntry && (
{lastUserEntry.kind === "input" ? "You asked" : "You chose"}

{lastUserEntry.text}

)} {working && (
{/* Pure status indicator — opening the activity panel now lives on the dedicated arrow toggle in the header, not on this spinner. */} {elapsed}s ThothII is working
{tailRows.length > 0 && (
    {tailRows.map((line, i) => { const isLast = i === tailRows.length - 1; return (
  1. › {line}
  2. ); })}
)}
)} {stepMessages.map((m, i) => (

{m.text}

))}
); }