// Agents tab - agent cards grid with intervention controls import { escapeHtml, formatDuration } from "../core/helpers"; import { icon } from "../design/icons"; import { openInterventionModal, confirmAbort } from "../components/modal"; import * as api from "../core/api"; import type { FleetState, View, PipelineInfo } from "../types/api"; function renderAgentsTab(data: FleetState): void { const container = document.getElementById("agents-grid"); if (!container) return; const pipelines = data.pipelines || []; if (pipelines.length === 0) { container.innerHTML = `
${icon("users", 32)}

No active agents

`; return; } let html = ""; for (const p of pipelines) { const statusClass = p.status === "failed" ? "agent-failed" : "agent-active"; html += `
` + `
` + `#${p.issue}` + `${escapeHtml(p.title)}
` + `
` + `
${icon("activity", 14)} Stage` + `${escapeHtml(p.stage)}
` + `
${icon("timer", 14)} Elapsed` + `${formatDuration(p.elapsed_s)}
` + `
${icon("refresh-cw", 14)} Iteration` + `${p.iteration || 0}/${p.maxIterations || 20}
` + `
` + `
` + `` + `` + `` + `
`; } container.innerHTML = html; // Wire up action buttons container.querySelectorAll(".agent-action-btn").forEach((btn) => { btn.addEventListener("click", (e) => { e.stopPropagation(); const action = btn.getAttribute("data-action"); const issue = parseInt(btn.getAttribute("data-issue") || "0", 10); if (!issue) return; switch (action) { case "message": openInterventionModal(issue); break; case "pause": api.sendIntervention(issue, "pause"); break; case "abort": confirmAbort(issue); break; } }); }); } export const agentsView: View = { init() {}, render(data: FleetState) { renderAgentsTab(data); }, destroy() {}, };