diff --git a/dashboard/src/index.md b/dashboard/src/index.md index be14899..e616994 100644 --- a/dashboard/src/index.md +++ b/dashboard/src/index.md @@ -46,6 +46,24 @@ const refreshDecisions = async () => { refreshDecisions(); ``` +```js +// SBOM snapshots — repo coverage and total package count +const sbomSnapState = (async function*() { + while (true) { + let snapshots = [], totalPkgs = 0; + try { + const r = await fetch(`${API}/sbom/snapshots/`); + if (r.ok) { + snapshots = await r.json(); + totalPkgs = snapshots.reduce((s, sn) => s + (sn.entry_count ?? 0), 0); + } + } catch {} + yield {snapshots, totalPkgs}; + await new Promise(res => setTimeout(res, POLL)); + } +})(); +``` + ```js // Registered projects — milestone events tagged with registration const regsState = (async function*() { @@ -316,6 +334,8 @@ const contribCounts = summary.contribution_counts ?? {}; const licenceRisk = summary.licence_risk_count ?? 0; const totalContribs = ["br","fr","ep","upr"].reduce((s, t) => s + (contribCounts[t] ?? 0), 0); const needsFollowUp = (contribCounts["submitted"] ?? 0) + (contribCounts["acknowledged"] ?? 0); +const sbomSnaps = sbomSnapState.snapshots ?? []; +const totalPkgs = sbomSnapState.totalPkgs ?? 0; display(html`
By type: ${["br","fr","ep","upr"].filter(t => contribCounts[t]).map(t => html`${t.toUpperCase()} ${contribCounts[t]}`).join("") || "—"}
+${totalPkgs.toLocaleString()}
+ ${sbomSnaps.length} repo${sbomSnaps.length !== 1 ? "s" : ""} tracked · ${licenceRisk > 0 ? html`${licenceRisk} copyleft risks` : html`✓ no copyleft`}