import { useCallback, useEffect, useState } from "react"; import { listTerminalSessions, createTerminalSession, closeTerminalSession, resetTerminalSession, renameTerminalSession, type TerminalSession, } from "../api/terminal"; export interface UseTerminalSessionsResult { sessions: TerminalSession[]; activeSessionId: string | null; setActiveSessionId: (id: string) => void; createSession: (name?: string) => Promise; closeSession: (sessionId: string) => Promise; renameSession: (sessionId: string, name: string) => Promise; resetSession: (sessionId: string) => Promise; loading: boolean; error: string | null; } export function useTerminalSessions( instanceId: string, ): UseTerminalSessionsResult { const [sessions, setSessions] = useState([]); const [activeSessionId, setActiveSessionId] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const loadSessions = useCallback(async () => { setLoading(true); setError(null); try { const sess = await listTerminalSessions(instanceId); setSessions(sess); if (sess.length > 0 && !activeSessionId) { setActiveSessionId(sess[0].id); } } catch (err) { setError(err instanceof Error ? err.message : "Failed to load sessions"); } finally { setLoading(false); } }, [instanceId, activeSessionId]); const createSession = useCallback( async (name?: string) => { setError(null); try { const newSession = await createTerminalSession(instanceId, name); const session: TerminalSession = { id: newSession.id, name: newSession.name, status: newSession.status, has_websockets: false, created_at: newSession.created_at, last_activity_at: null, }; setSessions((prev) => [...prev, session]); setActiveSessionId(session.id); return session; } catch (err) { const msg = err instanceof Error ? err.message : "Failed to create session"; setError(msg); return null; } }, [instanceId], ); const closeSession = useCallback( async (sessionId: string) => { setError(null); try { await closeTerminalSession(instanceId, sessionId); setSessions((prev) => { const filtered = prev.filter((s) => s.id !== sessionId); if (activeSessionId === sessionId && filtered.length > 0) { setActiveSessionId(filtered[0].id); } else if (filtered.length === 0) { setActiveSessionId(null); } return filtered; }); } catch (err) { setError( err instanceof Error ? err.message : "Failed to close session", ); } }, [instanceId, activeSessionId], ); const renameSession = useCallback( async (sessionId: string, name: string) => { setError(null); try { await renameTerminalSession(instanceId, sessionId, name); setSessions((prev) => prev.map((s) => (s.id === sessionId ? { ...s, name } : s)), ); } catch (err) { setError( err instanceof Error ? err.message : "Failed to rename session", ); } }, [instanceId], ); const resetSession = useCallback( async (sessionId: string) => { setError(null); try { await resetTerminalSession(instanceId, sessionId); // Refetch to get updated session info await loadSessions(); } catch (err) { setError( err instanceof Error ? err.message : "Failed to reset session", ); } }, [instanceId, loadSessions], ); // Initial load useEffect(() => { void loadSessions(); }, [loadSessions]); return { sessions, activeSessionId, setActiveSessionId, createSession, closeSession, renameSession, resetSession, loading, error, }; }