// App shell — scene switcher + top bar + command palette + console + toaster. import { useEffect } from "react"; import { useApp, scenarioById } from "./state/store"; import Landing from "./scenes/Landing"; import MissionControl from "./scenes/MissionControl"; import RunHistory from "./scenes/RunHistory"; import Wizard from "./scenes/Wizard"; import Settings from "./scenes/Settings"; import Login from "./scenes/Login"; import SsoCallback from "./scenes/SsoCallback"; import Chat from "./scenes/Chat"; import Agent from "./scenes/Agent"; import Hub from "./scenes/Hub"; import GeoAttendance from "./scenes/GeoAttendance"; import Explainer from "./scenes/Explainer"; import CommandBar from "./components/CommandBar"; import Toaster from "./components/Toaster"; import Console from "./components/Console"; import { Cmd, Home, Layers, HistoryIcon, Pulse, Refresh, Branch, Cog, User, Sun, Moon, Bot } from "./components/icons"; import { liveMeta } from "./data/scenarios"; export default function App() { const scene = useApp((s) => s.scene); const setScene = useApp((s) => s.setScene); const setCmdOpen = useApp((s) => s.setCmdOpen); const scenarioId = useApp((s) => s.scenarioId); const sc = scenarioById(scenarioId); const mode = useApp((s) => s.mode); const setMode = useApp((s) => s.setMode); const refreshLive = useApp((s) => s.refreshLive); const liveLoading = useApp((s) => s.liveLoading); const liveFetchedAt = useApp((s) => s.liveFetchedAt); const consoleOpen = useApp((s) => s.consoleOpen); const setConsoleOpen = useApp((s) => s.setConsoleOpen); const apiLogCount = useApp((s) => s.apiLog.length); const actor = useApp((s) => s.actor); const userEmail = useApp((s) => s.userEmail); const startPolling = useApp((s) => s.startPolling); const stopPolling = useApp((s) => s.stopPolling); const isAuthed = useApp((s) => s.isAuthed); // Auth guard and SSO callback detector useEffect(() => { if (typeof window !== "undefined" && window.location.hash.includes("access_token")) { setScene("sso-callback"); } else if (!isAuthed && scene !== "login" && scene !== "sso-callback") { setScene("login"); } }, [isAuthed, scene, setScene]); useEffect(() => { if (mode === "live") startPolling(); return () => stopPolling(); }, [mode, startPolling, stopPolling]); const liveAge = liveFetchedAt ? `${Math.max(0, Math.floor((Date.now() - liveFetchedAt) / 1000))}s ago` : null; return (