import { useEffect } from "react"; import { useShallow } from "zustand/react/shallow"; import Sidebar from "./components/layout/Sidebar"; import TopBar from "./components/layout/TopBar"; import StatusBar from "./components/layout/StatusBar"; import TerminalView from "./components/terminal/TerminalView"; import { useDocker } from "./hooks/useDocker"; import { useSettings } from "./hooks/useSettings"; import { useProjects } from "./hooks/useProjects"; import { useMcpServers } from "./hooks/useMcpServers"; import { useUpdates } from "./hooks/useUpdates"; import { useAppState } from "./store/appState"; export default function App() { const { checkDocker, checkImage, startDockerPolling } = useDocker(); const { loadSettings } = useSettings(); const { refresh } = useProjects(); const { refresh: refreshMcp } = useMcpServers(); const { loadVersion, checkForUpdates, startPeriodicCheck } = useUpdates(); const { sessions, activeSessionId } = useAppState( useShallow(s => ({ sessions: s.sessions, activeSessionId: s.activeSessionId })) ); // Initialize on mount useEffect(() => { loadSettings(); let stopPolling: (() => void) | undefined; checkDocker().then((available) => { if (available) { checkImage(); } else { stopPolling = startDockerPolling(); } }); refresh(); refreshMcp(); // Update detection loadVersion(); const updateTimer = setTimeout(() => checkForUpdates(), 3000); const cleanup = startPeriodicCheck(); return () => { clearTimeout(updateTimer); cleanup?.(); stopPolling?.(); }; }, []); // eslint-disable-line react-hooks/exhaustive-deps return (
Claude Code Container
Add a project from the sidebar, start its container, then open a terminal to begin using Claude Code in a sandboxed environment.