const state = { summary: null, runs: [], systems: [], advisories: {}, profiles: {}, selectedRunId: null, selectedArtifact: null, filters: { search: "", system: "", status: "", family: "" }, autoRefresh: true, refreshMs: 5000, refreshHandle: null, }; const $ = (id) => document.getElementById(id); const statusClass = (status) => `status-pill ${({ "blocked-artifact": "status-blocked-artifact", "blocked-destructive": "status-blocked-destructive", "triage-manual": "status-triage-manual", "verified-real": "status-verified-real", "verified-synthetic": "status-verified-synthetic", "suspected": "status-suspected", "completed": "status-verified-real", "failed": "status-blocked-artifact", "skipped": "status-triage-manual" })[status] || "status-default"}`; function escapeHtml(value) { return String(value ?? "") .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """); } function timeAgo(value) { if (!value) return "-"; const diff = Date.now() - new Date(value).getTime(); if (Number.isNaN(diff)) return value; const seconds = Math.floor(diff / 1000); if (seconds < 60) return `${seconds}s ago`; const minutes = Math.floor(seconds / 60); if (minutes < 60) return `${minutes}m ago`; const hours = Math.floor(minutes / 60); if (hours < 24) return `${hours}h ago`; const days = Math.floor(hours / 24); return `${days}d ago`; } async function fetchJson(url) { const response = await fetch(`${url}?t=${Date.now()}`, { cache: "no-store" }); if (!response.ok) { throw new Error(`${url} -> ${response.status}`); } return response.json(); } async function loadData(preserveSelection = true) { $("syncState").innerHTML = `Refreshing${new Date().toLocaleTimeString()}`; const previousRun = state.selectedRunId; try { const [summary, runs, systems, advisories, profiles] = await Promise.all([ fetchJson("./summary.json"), fetchJson("./runs.json"), fetchJson("./systems.json"), fetchJson("./advisories.json"), fetchJson("./profiles.json"), ]); state.summary = summary; state.runs = runs; state.systems = systems; state.advisories = advisories; state.profiles = profiles; hydrateFilterOptions(); const hashRun = location.hash.startsWith("#run=") ? location.hash.replace("#run=", "") : null; const selectedCandidate = preserveSelection ? (hashRun || previousRun) : hashRun; if (selectedCandidate && runs.some((item) => item.run_id === selectedCandidate)) { state.selectedRunId = selectedCandidate; } else { state.selectedRunId = runs[0]?.run_id || null; } renderDashboard(); $("syncState").innerHTML = `Live${summary.generated_at || new Date().toISOString()}`; } catch (error) { $("syncState").innerHTML = `Load Failed${escapeHtml(error.message)}`; $("runList").innerHTML = `
Dashboard load failed: ${escapeHtml(error.message)}
`; $("detailRoot").innerHTML = `
Unable to load dashboard data. Check generated JSON and local static server state.
`; } } function filteredRuns() { return state.runs.filter((item) => { if (state.filters.system && item.system_id !== state.filters.system) return false; if (state.filters.status && item.verification_status !== state.filters.status) return false; if (state.filters.family && item.repro_profile_id !== state.filters.family) return false; if (!state.filters.search) return true; const advisoryTitle = item.advisory_meta?.title || ""; const haystack = [item.run_id, item.advisory_id, item.system_id, item.repro_profile_id, advisoryTitle] .join(" ") .toLowerCase(); return haystack.includes(state.filters.search); }); } function renderMetrics() { const metrics = [ { label: "Advisories", value: state.summary?.advisory_count ?? 0 }, { label: "Run Bundles", value: state.summary?.run_count ?? 0 }, ...Object.entries(state.summary?.statuses || {}).map(([label, value]) => ({ label, value })), ]; $("metrics").innerHTML = metrics .map((item) => `
${escapeHtml(item.label)}${escapeHtml(item.value)}
`) .join(""); } function renderSystemCoverage() { $("systemCoverage").innerHTML = state.systems .map((system) => { const total = Math.max(system.total || 0, 1); const verified = (system.verified_real || 0) + (system.verified_synthetic || 0); const fill = Math.round((verified / total) * 100); return `
${escapeHtml(system.display_name || system.system_id)} ${escapeHtml(system.browser_present || 0)}/${escapeHtml(system.browser_required || 0)} browser
${escapeHtml(system.system_id)} · latest ${escapeHtml(system.latest_update || "-")}
real ${escapeHtml(system.verified_real || 0)} synthetic ${escapeHtml(system.verified_synthetic || 0)} blocked ${escapeHtml(system.blocked || 0)} manual ${escapeHtml(system.manual || 0)}
`; }) .join(""); } function renderFailures() { const failures = state.summary?.recent_failures || []; $("failureFeed").innerHTML = failures.length ? failures .map((item) => `
${escapeHtml(item.run_id)} ${escapeHtml(item.status)}
${escapeHtml(item.title || item.advisory_id)}
${escapeHtml(item.blocked_reason || "-")}
`) .join("") : `
No recent blockers.
`; } function renderRunList() { const filtered = filteredRuns(); $("runCount").textContent = `${filtered.length} shown`; $("runList").innerHTML = filtered.length ? filtered .map((item) => { const active = item.run_id === state.selectedRunId ? "is-active" : ""; const title = item.advisory_meta?.title || item.advisory_id; const reasoning = item.reasoning_lines?.[0] || item.blocked_reason || ""; const browserLabel = item.browser_evidence?.present ? "ready" : (item.browser_evidence?.required ? "required" : "n/a"); return ` `; }) .join("") : `
No runs match the current filters.
`; document.querySelectorAll("[data-run-id]").forEach((button) => { button.addEventListener("click", () => { state.selectedRunId = button.dataset.runId; location.hash = `run=${state.selectedRunId}`; renderRunList(); renderDetail(); }); }); } function renderDashboard() { renderMetrics(); renderSystemCoverage(); renderFailures(); renderRunList(); renderDetail(); } function setFilterListeners() { [["searchInput", "search"], ["systemFilter", "system"], ["statusFilter", "status"], ["familyFilter", "family"]].forEach(([id, key]) => { $(id).addEventListener("input", (event) => { state.filters[key] = String(event.target.value || "").trim().toLowerCase(); if (key !== "search") { state.filters[key] = String(event.target.value || ""); } renderRunList(); }); }); } function hydrateFilterOptions() { const distinct = (items) => [...new Set(items.filter(Boolean))].sort(); const patchOptions = (id, values) => { const control = $(id); const current = control.value; control.innerHTML = control.dataset.base; control.innerHTML += distinct(values).map((value) => ``).join(""); control.value = current; }; patchOptions("systemFilter", state.runs.map((item) => item.system_id)); patchOptions("statusFilter", state.runs.map((item) => item.verification_status)); patchOptions("familyFilter", state.runs.map((item) => item.repro_profile_id)); } function defaultArtifact(run) { const preference = ["attack", "requests", "container", "browser", "baseline", "compose", "reports"]; for (const key of preference) { const group = (run.artifact_groups || []).find((item) => item.key === key && item.items?.length); if (!group) continue; const preferredText = group.items.find((item) => item.kind === "text"); return preferredText || group.items[0]; } return null; } function totalProgress(progress) { const values = Object.values(progress || {}).map((value) => Number(value || 0)); return values.reduce((sum, value) => sum + value, 0); } function renderProgressStrip(progress) { const total = totalProgress(progress); if (!total) { return `
No timeline progress recorded.
`; } const order = [ ["completed", "Completed", "progress-completed"], ["blocked", "Blocked", "progress-blocked"], ["failed", "Failed", "progress-failed"], ["skipped", "Skipped", "progress-skipped"], ["planned", "Planned", "progress-planned"], ["other", "Other", "progress-other"], ]; const segments = order .filter(([key]) => Number(progress?.[key] || 0) > 0) .map(([key, _label, klass]) => { const count = Number(progress?.[key] || 0); const pct = Math.max((count / total) * 100, 4); return `
`; }) .join(""); const legend = order .filter(([key]) => Number(progress?.[key] || 0) > 0) .map(([key, label, klass]) => ` ${escapeHtml(label)} ${escapeHtml(progress?.[key] || 0)} `) .join(""); return `
${segments}
${legend}
`; } function renderStageCards(run) { const timeline = run.timeline || []; if (!timeline.length) { return `
No stage records available.
`; } return `
${timeline.map((item) => `
${escapeHtml(item.step || "-")}
${escapeHtml(item.status || "unknown")}
${escapeHtml(item.detail || "-")}
${escapeHtml(item.at || "-")}
`).join("")}
`; } async function openArtifact(href, label, kind) { state.selectedArtifact = { href, label, kind }; document.querySelectorAll(".artifact-button").forEach((button) => { button.classList.toggle("is-active", button.dataset.href === href); }); $("artifactLabel").textContent = label; $("artifactOpen").href = href; $("artifactMeta").textContent = href; try { if (kind === "image") { $("artifactViewer").innerHTML = `${escapeHtml(label)}`; return; } if (href.endsWith(".html")) { $("artifactViewer").innerHTML = ``; return; } const response = await fetch(`${href}?t=${Date.now()}`, { cache: "no-store" }); if (!response.ok) throw new Error(`${href} -> ${response.status}`); const text = await response.text(); let formatted = text; if (href.endsWith(".json")) { try { formatted = JSON.stringify(JSON.parse(text), null, 2); } catch (_error) { } } $("artifactViewer").innerHTML = `
${escapeHtml(formatted)}
`; } catch (error) { $("artifactViewer").innerHTML = `
Artifact load failed: ${escapeHtml(error.message)}
`; } } function renderDetail() { const run = state.runs.find((item) => item.run_id === state.selectedRunId); if (!run) { $("detailRoot").innerHTML = `
Select a run to inspect full timeline, logs, sources, and reasoning.
`; return; } const advisory = run.advisory_meta || {}; const profile = run.profile_meta || {}; const screenshotItems = (run.artifact_groups || []) .find((group) => group.key === "browser") ?.items.filter((item) => item.kind === "image") || []; $("detailRoot").innerHTML = `
Local Verification Workspace
${escapeHtml(run.verification_status)}
${escapeHtml(run.system_id)} ${escapeHtml(run.repro_profile_id)} ${escapeHtml(run.artifact_mode)} ${escapeHtml(run.verification_mode)} ${escapeHtml(run.target_env || "local-docker")}

${escapeHtml(advisory.title || run.advisory_id)}

${escapeHtml(advisory.summary || "No summary available.")}

Timeline Steps${escapeHtml(run.timeline?.length || 0)}
Artifacts${escapeHtml((run.artifact_groups || []).reduce((sum, group) => sum + group.count, 0))}
Browser${run.browser_evidence?.present ? "Ready" : (run.browser_evidence?.required ? "Required" : "Optional")}
Finished${escapeHtml(timeAgo(run.finished_at))}
Progress Timeline${escapeHtml(run.timeline?.length || 0)} steps
${renderProgressStrip(run.progress)} ${renderStageCards(run)}
${(run.timeline || []).map((item) => `
${escapeHtml(item.at || "-")}
${escapeHtml(item.step || "-")}
${escapeHtml(item.status || "unknown")}
${escapeHtml(item.detail || "-")}
`).join("") || `
No timeline items available.
`}
Attack Plan & Reasoning${escapeHtml(profile.vuln_family || "unknown")}
${run.blocked_reason ? `
Failure reason
${escapeHtml(run.blocked_reason)}
` : ""}
destructive risk ${escapeHtml(profile.destructive_risk || "-")} cleanup ${escapeHtml(profile.cleanup_policy || "-")} targets ${(profile.allowed_target_types || []).join(", ") || "-"}
${(run.reasoning_lines || []).map((line) => `
${escapeHtml(line)}
`).join("")}
${(profile.success_criteria || []).map((line) => `${escapeHtml(line)}`).join("")}
Evidence Explorer${escapeHtml((run.artifact_groups || []).length)} groups
${(run.artifact_groups || []).map((group) => `

${escapeHtml(group.label)} · ${escapeHtml(group.count)}

${group.items.map((item) => ` `).join("")}
`).join("") || `
No artifacts linked for this run.
`} ${screenshotItems.length ? ` ` : ""}
Live Log Viewer${state.selectedArtifact ? "active" : "idle"}
${escapeHtml(state.selectedArtifact?.label || "Select an artifact")}
${escapeHtml(state.selectedArtifact?.href || "Artifacts and logs can be previewed here.")}
Open artifact
Select a report, log, JSON, screenshot, or timeline file to preview it here.
Sources & Fix Topics${escapeHtml((advisory.secondary_source_urls || []).length + (advisory.official_source_url ? 1 : 0))} links
${(advisory.aliases || []).map((alias) => `${escapeHtml(alias)}`).join("")}
${advisory.official_source_url ? `${escapeHtml(advisory.official_source_url)}` : `
No official source linked.
`} ${(advisory.secondary_source_urls || []).map((ref) => `${escapeHtml(ref)}`).join("")}
${(advisory.secure_code_topics || []).map((topic) => `${escapeHtml(topic)}`).join("")}
Run JSONraw
${escapeHtml(JSON.stringify(run, null, 2))}
Advisory JSONraw
${escapeHtml(JSON.stringify(advisory, null, 2))}
Profile JSONraw
${escapeHtml(JSON.stringify(profile, null, 2))}
`; document.querySelectorAll(".artifact-button").forEach((button) => { button.addEventListener("click", () => openArtifact(button.dataset.href, button.dataset.label, button.dataset.kind)); }); $("refreshArtifact")?.addEventListener("click", () => { if (state.selectedArtifact) { openArtifact(state.selectedArtifact.href, state.selectedArtifact.label, state.selectedArtifact.kind); } }); if (!state.selectedArtifact || !(run.artifact_groups || []).some((group) => group.items.some((item) => item.href === state.selectedArtifact.href))) { const artifact = defaultArtifact(run); if (artifact) { openArtifact(artifact.href, artifact.label, artifact.kind); } } else { openArtifact(state.selectedArtifact.href, state.selectedArtifact.label, state.selectedArtifact.kind); } } function attachGlobalActions() { $("searchInput").addEventListener("input", (event) => { state.filters.search = String(event.target.value || "").trim().toLowerCase(); renderRunList(); }); [["systemFilter", "system"], ["statusFilter", "status"], ["familyFilter", "family"]].forEach(([id, key]) => { $(id).addEventListener("input", (event) => { state.filters[key] = String(event.target.value || ""); renderRunList(); }); }); $("refreshDashboard").addEventListener("click", () => loadData(false)); $("autoRefresh").addEventListener("change", (event) => { state.autoRefresh = Boolean(event.target.checked); startRefreshLoop(); }); } function startRefreshLoop() { if (state.refreshHandle) { clearInterval(state.refreshHandle); state.refreshHandle = null; } if (!state.autoRefresh) return; state.refreshHandle = setInterval(() => loadData(true), state.refreshMs); } async function init() { ["systemFilter", "statusFilter", "familyFilter"].forEach((id) => { $(id).dataset.base = $(id).innerHTML; }); attachGlobalActions(); await loadData(false); startRefreshLoop(); window.addEventListener("hashchange", () => loadData(false)); } document.addEventListener("DOMContentLoaded", init);