import { AgentSidebar, focusAgentChat, } from "@agent-native/core/client/agent-chat"; import { useT } from "@agent-native/core/client/i18n"; import { IconMenu2 } from "@tabler/icons-react"; import { useState, useEffect } from "react"; import { useLocation } from "react-router"; import { Button } from "@/components/ui/button"; import { Sheet, SheetContent, SheetDescription, SheetTitle, } from "@/components/ui/sheet"; import { TAB_ID } from "@/lib/tab-id"; import { Header } from "./Header"; import { HeaderActionsProvider } from "./HeaderActions"; import { Sidebar } from "./Sidebar"; interface LayoutProps { children: React.ReactNode; } const SIDEBAR_COLLAPSE_KEY = "tasks.sidebar.collapsed"; /** * Routes whose page renders its own toolbar. Layout still wraps these with the * left Sidebar and agent surfaces but skips the global Header so they don't * double-stack chrome. */ function routeOwnsToolbar(pathname: string): boolean { return pathname === "/tasks" || pathname.startsWith("/extensions"); } export function Layout({ children }: LayoutProps) { const t = useT(); const location = useLocation(); const [mobileSidebarOpen, setMobileSidebarOpen] = useState(false); const [sidebarCollapsed, setSidebarCollapsed] = useState(true); useEffect(() => { setMobileSidebarOpen(false); }, [location.pathname]); useEffect(() => { try { const stored = window.localStorage.getItem(SIDEBAR_COLLAPSE_KEY); if (stored !== null) setSidebarCollapsed(stored === "1"); } catch { // Ignore storage access errors; the default collapsed state still works. } }, []); useEffect(() => { try { window.localStorage.setItem( SIDEBAR_COLLAPSE_KEY, sidebarCollapsed ? "1" : "0", ); } catch { // Ignore storage access errors. } }, [sidebarCollapsed]); const ownsToolbar = routeOwnsToolbar(location.pathname); const contentFrame = (