import React, { useState } from "react"; import { ShieldAlert } from "lucide-react"; import { C, FD, FB, FM, fmt } from "../theme.js"; // Small presentational atoms lifted verbatim-in-spirit from the validated mock. // Do NOT restyle these; they carry the Tactical Grey look. export function Chip({ dot, text }) { return (
{text}
); } export function Stat({ label, v, grad }) { return (
{v}
{label}
); } export function Hero({ v, label, grad }) { return (
{v}
{label}
); } export function PanelTitle({ icon: Icon, text, mt }) { return (
{text}
); } export function SecHead({ icon: Icon, c, text }) { return (
{text}
); } export function Bar({ label, v, max, c, note }) { return (
{label} {fmt(v)}
{note &&
{note}
}
); } // A line-style legend row used inside the turn graph (proven vs hypothesis). export function EdgeLegend({ c, text, dashed }) { return (
{text}
); } export function ChainNode({ icon: Icon, c, title, sub }) { return (
{title}
{sub}
); } // --------------------------------------------------------------------------- // BINARIES — the real tools run via Bash (npx remotion -> remotion, railway, …), // a SEPARATE entity dimension from tool calls. Logo served LOCALLY from // /binary-logos/.svg (pulled by the background enricher); colored-monogram // fallback when the file isn't there yet. No network on render (NN #2). // --------------------------------------------------------------------------- const _MONO = [C.orange, C.cyan, C.amber, C.blue, "#a78bfa", "#f472b6", "#34d399", "#fb923c", "#60a5fa"]; function monoColor(name) { let h = 0; for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0; return _MONO[h % _MONO.length]; } export function BinaryLogo({ b, size = 18 }) { const [err, setErr] = useState(false); const name = (b.binary || b.name || "?"); const src = b.logo || `/binary-logos/${encodeURIComponent(name)}.svg`; const col = monoColor(name); if (err) { return ( {name[0] ? name[0].toUpperCase() : "?"} ); } return ( setErr(true)} style={{ borderRadius: 4, objectFit: "contain", flexShrink: 0, background: "transparent" }} /> ); } // Compact chip (logo + product) for session cards / inline lists. export function BinaryBadge({ b, onClick }) { const name = b.binary || b.name; const label = b.product || name; return ( {label} {b.security && } ); } // A traceable row for the left rails: logo + product, blurb, count, security note, // and the turns it fired in. `onOpen(turnIndex)` jumps to the first turn. export function BinaryRow({ b, onOpen, color = C.orange }) { const name = b.binary || b.name; const label = b.product || name; const turns = b.turns || []; return (
turns.length && onOpen && onOpen(turns[0])} title={`${b.identified ? label : name + " (not yet identified)"}${b.blurb ? " — " + b.blurb : ""}` + `${b.via && b.via !== "direct" ? " · via " + b.via : ""}` + `${turns.length ? " · turn(s) " + turns.join(", ") : ""}` + `${b.security ? " ⚠ " + b.security : ""}`} style={{ display: "flex", alignItems: "center", gap: 7, padding: "5px 8px", borderRadius: 6, cursor: turns.length ? "pointer" : "default", borderLeft: `2px solid ${color}` }}> {label}{!b.identified && · {name}} {b.blurb && ( {b.blurb} )} {b.security && } ×{b.count ?? b.total}
); } // "Generated" provenance badge — every piece of narrator prose must be labelled // generated (NON-NEGOTIABLE #7). Deterministic numbers are NOT badged. export function GeneratedTag({ cites }) { return ( GENERATED{cites ? ` · reads ${cites}` : ""} ); }