import { useState, type FormEvent } from "react"; import { Link } from "react-router"; import { api, ApiError, type Debt, type Endpoint, type Evidence } from "../api"; import { fmtDate } from "../hooks"; import { Badge, ErrorBox, JsonTree, Td } from "./ui"; export function EvidenceList({ evidence }: { evidence: Evidence[] }) { if (!evidence.length) return
No machine evidence recorded yet.
; return (
{[...evidence].reverse().map((e) => (
{e.kind} {fmtDate(e.created_at)} · {e.created_by ?? "system"}
{e.command &&
command: {e.command}
} {e.output_excerpt &&
{e.output_excerpt}
} {e.output_hash &&
output sha256 {e.output_hash}
} {Object.keys(e.details ?? {}).length > 0 && }
))}
); } export function DebtTable({ debt, onChange }: { debt: Debt[]; onChange?: () => void }) { const [err, setErr] = useState(null); if (!debt.length) return
No knowledge debt.
; const patch = async (id: string, status: string) => { setErr(null); try { await api(`debt/${id}`, { method: "PATCH", body: { status } }); onChange?.(); } catch (e) { setErr(e as ApiError); } }; return (
{debt.map((d) => ())}
SeverityKindSubjectDescriptionRemediationStatusCreated
{d.kind} {d.description}{d.remediation ?? "—"} {onChange ? : } {fmtDate(d.created_at)}
); } export function SubjectLink({ type, id, label }: { type: string; id: string; label?: string }) { const to = type === "akp" ? `/akps/${id}` : type === "api" ? `/apis/${id}` : type === "execution" ? `/executions/${id}` : type === "version" ? `/versions/${id}` : type === "dataset" ? `/datasets/${id}` : null; const text = label ?? `${type} ${id.slice(0, 8)}`; return to ? {text} : {text}; } export function LifecycleButtons({ allowed, onTransition }: { allowed: string[]; onTransition: (to: string, reason: string) => Promise }) { const [err, setErr] = useState(null); const [busy, setBusy] = useState(null); const [reason, setReason] = useState(""); if (!allowed.length) return no transitions available; return (
setReason(e.target.value)} /> {allowed.map((t) => )}
); } /** Execute form for one endpoint: query + path params → POST /execute. */ export function ExecuteForm({ endpoint, apiId, packageId, projects }: { endpoint: Endpoint; apiId?: string; packageId?: string; projects: { slug: string; name: string }[] }) { const [vals, setVals] = useState>(() => Object.fromEntries(endpoint.parameters.filter((p) => p.example !== undefined && p.example !== null).map((p) => [p.name, String(p.example)]))); const [project, setProject] = useState("default"); const [purpose, setPurpose] = useState(""); const [res, setRes] = useState | null>(null); const [err, setErr] = useState(null); const [busy, setBusy] = useState(false); const submit = async (e: FormEvent) => { e.preventDefault(); setBusy(true); setErr(null); setRes(null); const path_params: Record = {}, query: Record = {}; for (const p of endpoint.parameters) { const v = vals[p.name]; if (v === undefined || v === "") continue; (p.in === "path" ? path_params : query)[p.name] = v; } try { setRes(await api("execute", { body: { project_id: project, api_id: packageId ? undefined : apiId, package_id: packageId, endpoint_id: endpoint.id, operation_id: endpoint.operation_id, method: endpoint.method === "MCP" ? "GET" : endpoint.method, path_params, query, purpose, caller: "ui" } })); } catch (ex) { const e = ex as ApiError; setErr(e); const p = e.payload as { execution?: Record } | undefined; if (p?.execution) setRes(p.execution); } finally { setBusy(false); } }; const ex = res as { id?: string; state?: string; status_code?: number; duration_ms?: number; response_hash?: string; policy_decision?: { decision: string; reasons: string[] } } | null; return (
{endpoint.parameters.map((p) =>
setVals({ ...vals, [p.name]: e.target.value })} placeholder={p.description?.slice(0, 60)} />
)}
setPurpose(e.target.value)} />
{ex &&
execution {String(ex.id).slice(0, 8)} status {ex.status_code ?? "—"} · {ex.duration_ms ?? "—"} ms · hash {ex.response_hash?.slice(0, 16) ?? "—"}{ex.policy_decision &&
policy {ex.policy_decision.decision}: {ex.policy_decision.reasons.join("; ")}
}
} ); } export function EndpointRow({ e, apiId, packageId, projects }: { e: Endpoint; apiId?: string; packageId?: string; projects: { slug: string; name: string }[] }) { return (
{e.method} {e.path} {e.operation_id} {e.inferred && } {e.summary && — {e.summary}}

Parameters

{e.parameters.length ? {e.parameters.map((p) => )}
NameInReqSchemaDescription
{p.name}{p.in}{p.required ? "yes" : ""}{p.schema?.type ? String(p.schema.type) : "—"}{p.description}
: none} {Object.keys(e.pagination ?? {}).length > 0 && <>

Pagination

}

Execute

Response schema

{e.response_schema ? : not documented} {e.request_schema ? <>

Request schema

: null}

endpoint page →

); }