import { useEffect, useMemo, useState } from 'react'; import { api, RefTrackingItem, fmtAge } from '../lib/api'; export function RefTrackingPage() { const [rows, setRows] = useState([]); const [repoFilter, setRepoFilter] = useState(''); const [err, setErr] = useState(null); useEffect(() => { api .refTracking(repoFilter) .then(setRows) .catch((e) => setErr(String(e))); }, [repoFilter]); // Group by repo for a cleaner display. const grouped = useMemo(() => { const g = new Map(); for (const r of rows) { const arr = g.get(r.repo) ?? []; arr.push(r); g.set(r.repo, arr); } return [...g.entries()].sort((a, b) => a[0].localeCompare(b[0])); }, [rows]); return (

Ref-tracking

Every cached fingerprint's producing (repo, git-ref). Feeds the nightly cluster-ref-sweep that reaps fingerprints whose refs are gone from Gitea.

setRepoFilter(e.target.value)} placeholder="filter repo — e.g. clawverse/clawstor" className="w-full sm:w-96 rounded bg-slate-900 border border-slate-800 px-3 py-2 text-sm font-mono" /> {err && (
{err}
)} {grouped.length === 0 && (
no ref-tracking entries yet
)} {grouped.map(([repo, items]) => (
{repo} {items.length} fingerprint{items.length === 1 ? '' : 's'}
{items.map((it) => ( ))}
node fingerprint refs first seen last seen
{it.node} {it.fingerprint_hex.slice(0, 24)}… {it.refs.join(', ')} {fmtAge(it.first_seen_unix)} {fmtAge(it.last_seen_unix)}
))}
); }