import { useState, useEffect, useCallback } from "react"; import { type DirectiveSummary, type DirectiveWithSteps, type CreateDirectiveRequest, type UpdateDirectiveRequest, type CreateDirectiveStepRequest, listDirectives, createDirective, getDirective, updateDirective, deleteDirective, createDirectiveStep, deleteDirectiveStep, startDirective, pauseDirective, advanceDirective, completeDirectiveStep, failDirectiveStep, skipDirectiveStep, updateDirectiveGoal, } from "../lib/api"; export function useDirectives() { const [directives, setDirectives] = useState([]); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const refresh = useCallback(async () => { try { setLoading(true); setError(null); const res = await listDirectives(); setDirectives(res.directives); } catch (e) { setError(e instanceof Error ? e.message : "Failed to load directives"); } finally { setLoading(false); } }, []); useEffect(() => { refresh(); }, [refresh]); const create = useCallback(async (req: CreateDirectiveRequest) => { const d = await createDirective(req); await refresh(); return d; }, [refresh]); const remove = useCallback(async (id: string) => { await deleteDirective(id); await refresh(); }, [refresh]); return { directives, loading, error, refresh, create, remove }; } export function useDirective(id: string | undefined) { const [directive, setDirective] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const refresh = useCallback(async () => { if (!id) return; try { setLoading(true); setError(null); const d = await getDirective(id); setDirective(d); } catch (e) { setError(e instanceof Error ? e.message : "Failed to load directive"); } finally { setLoading(false); } }, [id]); useEffect(() => { refresh(); }, [refresh]); // Auto-poll while directive is active or has an orchestrator task useEffect(() => { if (!directive) return; const needsPolling = directive.status === "active" || directive.orchestratorTaskId != null; if (!needsPolling) return; const interval = setInterval(refresh, 5000); return () => clearInterval(interval); }, [directive?.status, directive?.orchestratorTaskId, refresh]); const update = useCallback(async (req: UpdateDirectiveRequest) => { if (!id) return; await updateDirective(id, req); await refresh(); }, [id, refresh]); const addStep = useCallback(async (req: CreateDirectiveStepRequest) => { if (!id) return; await createDirectiveStep(id, req); await refresh(); }, [id, refresh]); const removeStep = useCallback(async (stepId: string) => { if (!id) return; await deleteDirectiveStep(id, stepId); await refresh(); }, [id, refresh]); const start = useCallback(async () => { if (!id) return; await startDirective(id); await refresh(); }, [id, refresh]); const pause = useCallback(async () => { if (!id) return; await pauseDirective(id); await refresh(); }, [id, refresh]); const advance = useCallback(async () => { if (!id) return; await advanceDirective(id); await refresh(); }, [id, refresh]); const completeStep = useCallback(async (stepId: string) => { if (!id) return; await completeDirectiveStep(id, stepId); await refresh(); }, [id, refresh]); const failStep = useCallback(async (stepId: string) => { if (!id) return; await failDirectiveStep(id, stepId); await refresh(); }, [id, refresh]); const skipStep = useCallback(async (stepId: string) => { if (!id) return; await skipDirectiveStep(id, stepId); await refresh(); }, [id, refresh]); const updateGoal = useCallback(async (goal: string) => { if (!id) return; await updateDirectiveGoal(id, goal); await refresh(); }, [id, refresh]); return { directive, loading, error, refresh, update, addStep, removeStep, start, pause, advance, completeStep, failStep, skipStep, updateGoal, }; }