import fs from "node:fs"; import { SWARM_TASKS_FILE } from "@/lib/fleet-config"; import { appendTaskEvent, applyTaskCallback, findTask } from "@/lib/tasks"; type SwarmRegistryTask = { id: string; taskboardTaskId?: number | null; status?: string; tmuxSession?: string; worktree?: string; pr?: number | null; note?: string | null; failedAt?: number | null; completedAt?: number | null; startedAt?: number | null; agent?: string | null; }; function readRegistry() { if (!fs.existsSync(SWARM_TASKS_FILE)) { return [] as SwarmRegistryTask[]; } const parsed = JSON.parse(fs.readFileSync(SWARM_TASKS_FILE, "utf8")) as { tasks?: SwarmRegistryTask[] }; return Array.isArray(parsed.tasks) ? parsed.tasks : []; } function statusToDispatchState(status: string | undefined) { switch (status) { case "running": return "acknowledged" as const; case "done": return "completed" as const; case "failed": return "failed" as const; case "queued": case "retrying": return "dispatched" as const; default: return null; } } function statusToTaskStatus(status: string | undefined) { switch (status) { case "running": return "In Progress" as const; case "done": return "Done" as const; case "failed": return "Backlog" as const; case "queued": case "retrying": return "Todo" as const; default: return undefined; } } export async function syncOpenClawTasks() { const registryTasks = readRegistry(); const results: Array<{ taskId: number; registryStatus: string; synced: boolean }> = []; for (const registryTask of registryTasks) { if (!registryTask.taskboardTaskId) { continue; } const task = await findTask(registryTask.taskboardTaskId); if (!task) { continue; } const dispatchState = statusToDispatchState(registryTask.status); const taskStatus = statusToTaskStatus(registryTask.status); if (!dispatchState) { continue; } await applyTaskCallback(task.id, { status: taskStatus, dispatch_state: dispatchState, summary: registryTask.status === "done" ? `OpenClaw task ${registryTask.id} completed` : registryTask.status === "failed" ? `OpenClaw task ${registryTask.id} failed` : `OpenClaw task ${registryTask.id} ${registryTask.status}`, detail: registryTask.pr ? `PR #${registryTask.pr} from ${registryTask.id}` : registryTask.note || registryTask.worktree || "", completed_by: registryTask.agent || "openclaw-swarm", last_error: registryTask.status === "failed" ? registryTask.note || "Swarm task failed" : null, }); await appendTaskEvent({ taskId: task.id, assignee: task.assignee, family: task.family, host: task.target_host, eventType: "updated", state: dispatchState, summary: `OpenClaw sync: ${registryTask.status}`, detail: registryTask.worktree || "", }); results.push({ taskId: task.id, registryStatus: registryTask.status || "unknown", synced: true, }); } return results; }