// HistoryScreen — append-only audit log
(function () {
const KIND_META = {
import: { label: "IMPORT", glyph: "↓", color: "var(--fg-strong)" },
poll: { label: "POLL", glyph: "↻", color: "var(--fg-muted)" },
approve: { label: "APPROVE", glyph: "✓", color: "var(--conf-rules)" },
override: { label: "OVERRIDE", glyph: "✎", color: "var(--conf-high)" },
skip: { label: "SKIP", glyph: "↩", color: "var(--conf-mid)" },
rule: { label: "RULE", glyph: "§", color: "var(--conf-high)" },
commit: { label: "COMMIT", glyph: "●", color: "var(--fg-strong)" },
fx: { label: "FX", glyph: "◇", color: "var(--fg-muted)" },
categorize: { label: "AGENT", glyph: "△", color: "var(--conf-high)" },
error: { label: "ERROR", glyph: "✕", color: "var(--conf-low)" },
};
const ACTOR_LABEL = { you: "you", system: "system", agent: "agent" };
const entityShort = { all: "ALL", personal: "P/", tfox: "9T/", finacode: "FC/" };
const entityClass = { personal: "personal", tfox: "tfox", finacode: "finacode" };
function HistoryFilters({ activeKinds, toggleKind, actor, setActor, range, setRange }) {
const kinds = Object.keys(KIND_META);
return (
KIND
{kinds.map(k => (
))}
ACTOR
{["all", "you", "system", "agent"].map(a => (
))}
RANGE
{[
{ id: "24h", label: "24H" },
{ id: "7d", label: "7D" },
{ id: "30d", label: "30D" },
{ id: "all", label: "ALL" },
].map(r => (
))}
);
}
// Group log entries by date
function groupByDay(rows) {
const groups = new Map();
rows.forEach(r => {
const day = r.at.split(" ")[0];
if (!groups.has(day)) groups.set(day, []);
groups.get(day).push(r);
});
return [...groups.entries()];
}
function dayLabel(iso) {
const d = new Date(iso + "T00:00:00");
const today = new Date("2026-03-08T00:00:00");
const diff = Math.round((today - d) / (24 * 3600 * 1000));
if (diff === 0) return "TODAY";
if (diff === 1) return "YESTERDAY";
const wd = d.toLocaleDateString("en-US", { weekday: "short" }).toUpperCase();
const md = d.toLocaleDateString("en-US", { month: "short", day: "numeric" }).toUpperCase();
return `${wd} · ${md}`;
}
function HistoryRow({ row }) {
const meta = KIND_META[row.kind];
return (
{row.at.split(" ")[1]}
{meta.glyph}
{meta.label}
{ACTOR_LABEL[row.actor]}
{entityShort[row.entity]}
{row.summary}
{row.detail}
{row.ref}
);
}
function HistoryScreen({ entity }) {
const all = window.AKEFIN_DATA.history;
const [activeKinds, setActiveKinds] = React.useState(new Set());
const [actor, setActor] = React.useState("all");
const [range, setRange] = React.useState("7d");
const toggleKind = (k) => {
setActiveKinds(prev => {
const next = new Set(prev);
if (next.has(k)) next.delete(k); else next.add(k);
return next;
});
};
// Range filter (anchored to 2026-03-08 — the demo's "today")
const TODAY = new Date("2026-03-08T23:59:59");
const RANGE_DAYS = { "24h": 1, "7d": 7, "30d": 30, "all": 99999 };
const cutoff = new Date(TODAY.getTime() - RANGE_DAYS[range] * 24 * 3600 * 1000);
const rows = all.filter(r => {
if (entity !== "all" && r.entity !== entity && r.entity !== "all") return false;
if (activeKinds.size > 0 && !activeKinds.has(r.kind)) return false;
if (actor !== "all" && r.actor !== actor) return false;
const d = new Date(r.at.replace(" ", "T"));
if (d < cutoff) return false;
return true;
});
// Aggregates for header strip
const counts = rows.reduce((acc, r) => {
acc.total++;
acc.byActor[r.actor] = (acc.byActor[r.actor] || 0) + 1;
acc.byKind[r.kind] = (acc.byKind[r.kind] || 0) + 1;
return acc;
}, { total: 0, byActor: {}, byKind: {} });
const grouped = groupByDay(rows);
return (
HISTORY · {entity === "all" ? "ALL ENTITIES" : entity.toUpperCase()}
Audit log
{counts.total} events · append-only · backed by git on main
{/* Summary strip */}
BY YOU
{counts.byActor.you || 0}
BY SYSTEM
{counts.byActor.system || 0}
BY AGENT
{counts.byActor.agent || 0}
COMMITS
{counts.byKind.commit || 0}
ERRORS
0 ? "neg" : ""}`}>{counts.byKind.error || 0}
TIME
KIND
ACTOR
ENT
EVENT
REF
{grouped.length === 0 && (
NO EVENTS MATCH
Try widening the range or clearing filters.
)}
{grouped.map(([day, dayRows]) => (
{dayLabel(day)}
{day}
{dayRows.length} events
{dayRows.map(r => )}
))}
);
}
Object.assign(window, { HistoryScreen });
})();