const refreshButton = document.getElementById("refresh-button"); const refreshStatus = document.getElementById("refresh-status"); const tailSelect = document.getElementById("tail-select"); const fields = { activeRun: document.getElementById("metric-active-run"), phase: document.getElementById("metric-phase"), branch: document.getElementById("metric-branch"), blockers: document.getElementById("metric-blockers"), runCount: document.getElementById("run-count"), runsList: document.getElementById("runs-list"), generatedAt: document.getElementById("generated-at"), nextAction: document.getElementById("next-action"), workspace: document.getElementById("workspace"), blockersList: document.getElementById("blockers"), progressPath: document.getElementById("progress-path"), progressTail: document.getElementById("progress-tail"), }; let refreshTimer = null; refreshButton.addEventListener("click", () => loadStatus()); tailSelect.addEventListener("change", () => loadStatus()); loadStatus(); refreshTimer = setInterval(loadStatus, 5000); window.addEventListener("beforeunload", () => clearInterval(refreshTimer)); async function loadStatus() { setRefreshState("Loading", ""); try { const response = await fetch(`/api/status?tail=${encodeURIComponent(tailSelect.value)}`); if (!response.ok) throw new Error(`HTTP ${response.status}`); const data = await response.json(); render(data); setRefreshState("Live", "status-ok"); } catch (error) { setRefreshState("Error", "status-dead"); fields.progressTail.textContent = `Failed to load status: ${error.message}`; } } function render(data) { const summary = data.summary || {}; const checkpoint = data.checkpoint || {}; const blockers = Array.isArray(checkpoint.blockers) ? checkpoint.blockers : []; fields.activeRun.textContent = summary.active_run_id || "none"; fields.phase.textContent = summary.current_phase || "unknown"; fields.branch.textContent = summary.active_branch || "none"; fields.blockers.textContent = String(blockers.length); fields.runCount.textContent = `${data.runs.length} total`; fields.generatedAt.textContent = formatTime(data.generated_at); fields.nextAction.textContent = summary.next_action || "No next action recorded."; fields.workspace.textContent = data.workspace || "-"; renderBlockers(blockers); renderRuns(data.runs, summary.active_run_id); renderProgress(data.active_progress); } function renderBlockers(blockers) { fields.blockersList.innerHTML = ""; if (blockers.length === 0) { fields.blockersList.innerHTML = '
No blockers recorded.
'; return; } for (const blocker of blockers) { const item = document.createElement("div"); item.className = "blocker"; item.textContent = blocker; fields.blockersList.appendChild(item); } } function renderRuns(runs, activeRunId) { fields.runsList.innerHTML = ""; if (runs.length === 0) { fields.runsList.innerHTML = '