- Fix resolveBaseBranch to use stored branch name and consistent fusion/ prefix for both explicit deps and blockedBy paths (was using kb/ for blockedBy) - Add main branch checkout verification in merger before squash merge to prevent feature code from landing on wrong branch lineage - Align all branch prefix references from stale kb/ to fusion/ across executor, merger, store, and routes - Fix executor test OOM by mocking merger fully, adding fake timers to retry tests, and switching vitest pool to vmThreads - Update all test assertions to use fusion/ branch prefix Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
61 lines
1.8 KiB
TypeScript
61 lines
1.8 KiB
TypeScript
import { useState, useEffect, useCallback } from "react";
|
|
import type { Agent, AgentState, AgentCapability, AgentStats } from "../api";
|
|
import { fetchAgents, fetchAgentStats } from "../api";
|
|
|
|
export function useAgents(projectId?: string) {
|
|
const [agents, setAgents] = useState<Agent[]>([]);
|
|
const [stats, setStats] = useState<AgentStats | null>(null);
|
|
const [isLoading, setIsLoading] = useState(false);
|
|
|
|
const loadAgents = useCallback(async (filter?: { state?: AgentState; role?: AgentCapability }) => {
|
|
setIsLoading(true);
|
|
try {
|
|
const data = await fetchAgents(filter, projectId);
|
|
setAgents(data);
|
|
} catch (err) {
|
|
console.error("Failed to load agents:", err);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
}, [projectId]);
|
|
|
|
const loadStats = useCallback(async () => {
|
|
try {
|
|
const data = await fetchAgentStats(projectId);
|
|
setStats(data);
|
|
} catch (err) {
|
|
console.error("Failed to load agent stats:", err);
|
|
}
|
|
}, [projectId]);
|
|
|
|
useEffect(() => {
|
|
void loadAgents();
|
|
void loadStats();
|
|
}, [loadAgents, loadStats]);
|
|
|
|
// SSE subscription for agent events
|
|
useEffect(() => {
|
|
if (!projectId) return;
|
|
const query = `?projectId=${encodeURIComponent(projectId)}`;
|
|
const es = new EventSource(`/api/events${query}`);
|
|
|
|
const refresh = () => {
|
|
void loadAgents();
|
|
void loadStats();
|
|
};
|
|
|
|
es.addEventListener("agent:created", refresh);
|
|
es.addEventListener("agent:updated", refresh);
|
|
es.addEventListener("agent:deleted", refresh);
|
|
es.addEventListener("agent:stateChanged", refresh);
|
|
|
|
return () => {
|
|
es.close();
|
|
};
|
|
}, [projectId, loadAgents, loadStats]);
|
|
|
|
const activeAgents = agents.filter(a => a.state === "active" || a.state === "running");
|
|
|
|
return { agents, activeAgents, stats, isLoading, loadAgents, loadStats };
|
|
}
|