Spaces:
Running on Zero
Running on Zero
File size: 8,829 Bytes
5f43c7d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 | 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 (
<div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 10.5, color: C.text2, fontFamily: FM, border: `1px solid ${C.borderSoft}`, borderRadius: 999, padding: "4px 10px" }}>
<span style={{ width: 7, height: 7, borderRadius: 999, background: dot, boxShadow: `0 0 6px ${dot}` }} />
{text}
</div>
);
}
export function Stat({ label, v, grad }) {
return (
<div style={{ textAlign: "right" }}>
<div className={grad ? "hb" : ""} style={{ fontFamily: FM, fontSize: 14, fontWeight: 700, color: grad ? undefined : C.text }}>{v}</div>
<div style={{ fontSize: 9, color: C.muted, letterSpacing: 0.5, textTransform: "uppercase" }}>{label}</div>
</div>
);
}
export function Hero({ v, label, grad }) {
return (
<div style={{ flex: 1, background: `linear-gradient(135deg,${C.card},${C.panel})`, border: `1px solid ${C.borderSoft}`, borderRadius: 10, padding: "13px 15px" }}>
<div className={grad ? "hb" : ""} style={{ fontFamily: FD, fontWeight: 700, fontSize: 24, color: grad ? undefined : C.text }}>{v}</div>
<div style={{ fontSize: 10, color: C.muted, letterSpacing: 0.6, textTransform: "uppercase", marginTop: 2 }}>{label}</div>
</div>
);
}
export function PanelTitle({ icon: Icon, text, mt }) {
return (
<div style={{ display: "flex", alignItems: "center", gap: 7, marginTop: mt ? 20 : 0, color: C.muted }}>
<Icon size={13} />
<span style={{ fontFamily: FM, fontSize: 10.5, letterSpacing: 0.6 }}>{text}</span>
</div>
);
}
export function SecHead({ icon: Icon, c, text }) {
return (
<div style={{ display: "flex", alignItems: "center", gap: 8, marginTop: 26 }}>
<Icon size={16} color={c} />
<span style={{ fontFamily: FM, fontSize: 11, letterSpacing: 0.9, color: c, fontWeight: 600 }}>{text}</span>
<div style={{ flex: 1, height: 1, background: `linear-gradient(90deg,${c}44,transparent)` }} />
</div>
);
}
export function Bar({ label, v, max, c, note }) {
return (
<div style={{ marginTop: 9 }}>
<div style={{ display: "flex", justifyContent: "space-between", fontSize: 11.5 }}>
<span style={{ color: C.text2 }}>{label}</span>
<span style={{ fontFamily: FM, color: c, fontWeight: 600 }}>{fmt(v)}</span>
</div>
<div style={{ height: 6, background: C.black, borderRadius: 3, marginTop: 4, overflow: "hidden" }}>
<div style={{ width: `${Math.max(2, (100 * v) / Math.max(1, max))}%`, height: "100%", background: `linear-gradient(90deg,${c},${c}aa)` }} />
</div>
{note && <div style={{ fontSize: 9.5, color: C.muted, marginTop: 3, fontStyle: "italic" }}>{note}</div>}
</div>
);
}
// A line-style legend row used inside the turn graph (proven vs hypothesis).
export function EdgeLegend({ c, text, dashed }) {
return (
<div style={{ display: "flex", alignItems: "center", gap: 6, fontSize: 11, color: C.text2 }}>
<span style={{ width: 16, height: 0, borderTop: `2px ${dashed ? "dotted" : "solid"} ${c}`, display: "inline-block" }} />
{text}
</div>
);
}
export function ChainNode({ icon: Icon, c, title, sub }) {
return (
<div style={{ display: "flex", gap: 10, alignItems: "center", padding: "9px 11px", background: `linear-gradient(135deg,${C.card},${C.panel})`, border: `1px solid ${c}`, borderRadius: 8, marginBottom: 4, boxShadow: "0 1px 3px rgba(0,0,0,.35)" }}>
<div style={{ width: 28, height: 28, borderRadius: 7, background: C.elevated, display: "flex", alignItems: "center", justifyContent: "center", border: `1px solid ${c}` }}>
<Icon size={15} color={c} />
</div>
<div style={{ minWidth: 0 }}>
<div style={{ fontSize: 13, fontWeight: 600, color: c }}>{title}</div>
<div style={{ fontFamily: FM, fontSize: 10.5, color: C.muted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", maxWidth: 520 }}>{sub}</div>
</div>
</div>
);
}
// ---------------------------------------------------------------------------
// BINARIES — the real tools run via Bash (npx remotion -> remotion, railway, …),
// a SEPARATE entity dimension from tool calls. Logo served LOCALLY from
// /binary-logos/<name>.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 (
<span style={{ width: size, height: size, borderRadius: 5, background: col + "22", border: `1px solid ${col}66`, color: col, display: "inline-flex", alignItems: "center", justifyContent: "center", fontFamily: FM, fontSize: Math.round(size * 0.5), fontWeight: 700, flexShrink: 0, lineHeight: 1 }}>
{name[0] ? name[0].toUpperCase() : "?"}
</span>
);
}
return (
<img src={src} alt="" width={size} height={size} onError={() => 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 (
<span onClick={onClick} className={onClick ? "lift" : ""}
title={`${label}${b.blurb ? " — " + b.blurb : ""}${b.via && b.via !== "direct" ? " · via " + b.via : ""}${b.security ? " ⚠ " + b.security : ""}`}
style={{ display: "inline-flex", alignItems: "center", gap: 5, fontFamily: FM, fontSize: 9, color: C.text2, border: `1px solid ${C.borderSoft}`, borderRadius: 5, padding: "2px 6px 2px 4px", cursor: onClick ? "pointer" : "default" }}>
<BinaryLogo b={b} size={12} />{label}
{b.security && <ShieldAlert size={9} color={C.amber} />}
</span>
);
}
// 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 (
<div className="row lift"
onClick={() => 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}` }}>
<BinaryLogo b={b} size={16} />
<span style={{ minWidth: 0, flex: 1 }}>
<span style={{ fontFamily: FM, fontSize: 11.5, color: C.text, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", display: "block" }}>
{label}{!b.identified && <span style={{ color: C.muted }}> · {name}</span>}
</span>
{b.blurb && (
<span style={{ fontFamily: FB, fontSize: 9.5, color: C.muted, overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap", display: "block" }}>{b.blurb}</span>
)}
</span>
{b.security && <ShieldAlert size={11} color={C.amber} title={b.security} style={{ flexShrink: 0 }} />}
<span style={{ fontFamily: FM, fontSize: 9, color: C.muted, flexShrink: 0 }}>×{b.count ?? b.total}</span>
</div>
);
}
// "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 (
<span style={{ display: "inline-flex", alignItems: "center", gap: 5, fontFamily: FM, fontSize: 9, letterSpacing: 0.5, color: C.muted, border: `1px solid ${C.borderSoft}`, borderRadius: 5, padding: "1px 7px" }}>
GENERATED{cites ? ` · reads ${cites}` : ""}
</span>
);
}
|