import { useEffect, useState, useCallback } from 'react' import { api } from './lib/api' import type { Plan, Agent, QueueItem, PendingQuestion } from './lib/api' import { useWebSocket } from './hooks/useWebSocket' import { AgentStatus } from './components/AgentStatus' import { PlanBoard } from './components/PlanBoard' import { DirectorQueue } from './components/DirectorQueue' import { PendingQuestions } from './components/PendingQuestions' import { PlanDetail } from './components/PlanDetail' import { NewPlanModal } from './components/NewPlanModal' import { ClaudeModeToggle } from './components/ClaudeModeToggle' type RightTab = 'queue' | 'questions' function App() { const [plans, setPlans] = useState([]) const [agents, setAgents] = useState([]) const [queue, setQueue] = useState([]) const [questions, setQuestions] = useState([]) const [rightTab, setRightTab] = useState('queue') const [selectedPlan, setSelectedPlan] = useState(null) const [reviewItem, setReviewItem] = useState(null) const [showNewPlan, setShowNewPlan] = useState(false) const [connected, setConnected] = useState(false) const loadData = useCallback(() => { api.plans.list().then(setPlans).catch(() => {}) api.agents.list().then(setAgents).catch(() => {}) api.queue.list().then(setQueue).catch(() => {}) api.questions.list().then(setQuestions).catch(() => {}) }, []) useEffect(() => { loadData() }, [loadData]) useWebSocket(useCallback((event: string, _data: unknown) => { if (event.startsWith('plan:')) loadData() if (event.startsWith('task:')) loadData() if (event.startsWith('agent:')) api.agents.list().then(setAgents) if (event.startsWith('queue:')) api.queue.list().then(setQueue) if (event.startsWith('question:')) api.questions.list().then(setQuestions) if (event.startsWith('message:')) loadData() setConnected(true) }, [loadData])) const handleReview = useCallback(async (item: QueueItem) => { if (!item.plan_id) return try { const plan = await api.plans.get(item.plan_id) setReviewItem(item) setSelectedPlan(plan) } catch (err) { console.error('failed to load plan for review', err) } }, []) const closeDetail = useCallback(() => { setSelectedPlan(null) setReviewItem(null) }, []) return (

Director

{connected ? 'Connected' : 'Disconnected'}
{/* Tab toggle for queue vs questions */}
{rightTab === 'queue' && } {rightTab === 'questions' && }
{selectedPlan && ( )} {showNewPlan && ( setShowNewPlan(false)} onCreated={loadData} /> )}
) } export default App