Merge visual review into full shell and preserve bilingual layout

This commit is contained in:
Codex
2026-09-13 14:55:58 +02:00
69 changed files with 1419 additions and 346 deletions
@@ -68,8 +68,8 @@ function WorkspaceEvidence({ workspace, generation }: { workspace: string; gener
return <div className="flex min-h-0 flex-1 flex-col gap-5 p-6">
{list.data && <Instructions data={list.data} />}
<EvidenceSources workspace={workspace} sources={list.data?.source_reviews ?? []} />
<div className="flex flex-wrap items-end gap-3">
<label className="grid flex-1 gap-1 text-sm">{t("Search Evidence")}<input className={control} value={filters.q} onChange={e => filter("q", e.target.value)} placeholder={t("Title, identifier or content")} /></label>
<div className="thot-evidence-filters">
<label className="thot-evidence-search grid gap-1 text-sm">{t("Search Evidence")}<input className={control} value={filters.q} onChange={e => filter("q", e.target.value)} placeholder={t("Title, identifier or content")} /></label>
<Select label={t("Kind")} value={filters.kind} values={kinds} onChange={v => filter("kind", v)} />
<Select label={t("Purpose")} value={filters.purpose} values={["disambiguation", "rewriting", "schema_linking", "sql_generation"]} onChange={v => filter("purpose", v)} />
<Select label={t("Status")} value={filters.status} values={Object.keys(states)} labels={states} onChange={v => filter("status", v)} />
@@ -111,8 +111,8 @@ function Instructions({ data }: { data: EvidencePage }) {
const example = `---\nschema_version: 4\nid: evidence:my-unit\nkind: ${kind}\nlanguage: en\npurposes: [sql_generation]\n---\n\n# My Evidence\n\n${templates[kind]}\n`;
return <div className="border-b pb-5">
<p className="mb-2 text-sm font-medium">{data.pending_revision ? t("Consolidation is incomplete. The previous active content remains available.") : data.active_revision ? t("The core uses the last successfully consolidated version.") : t("Run the first consolidation to convert and activate the local archive.")}</p>
{data.location.workspace ? <><p className="mb-1 text-xs text-muted-foreground">{t("Workspace on the installation host")}</p><CopyText text={data.location.workspace} label={t("workspace path")} /></> : <p role="alert" className="text-sm">{t("A host file path is unavailable for this installation. Configure a persistent workspace-registry bind mount before editing files from the host.")}</p>}
<details className="mt-3"><summary className="cursor-pointer text-sm font-medium">{t("Edit files, consolidate and commit")}</summary>
{data.location.workspace ? <div className="mt-3"><p className="mb-1 text-xs text-muted-foreground">{t("Workspace on the installation host")}</p><CopyText text={data.location.workspace} label={t("workspace path")} /></div> : <p role="alert" className="mt-3 text-sm">{t("A host file path is unavailable for this installation. Configure a persistent workspace-registry bind mount before editing files from the host.")}</p>}
<ol className="mt-3 max-w-[75ch] list-decimal space-y-3 pl-5 text-sm">
<li>{t("Edit the files under")} <code>evidence/curated/&lt;kind&gt;/</code> {t("with your preferred editor. Keep existing IDs. Remove a unit's file to delete it; keep the curated directory.")}</li>
<li>{t("Check Git status and the diff. Saving a file does not update recall.")}{data.location.git_commands.slice(0, 2).map(command => <div className="mt-2" key={command}><CopyText text={command} label={t("Git inspection command")} /></div>)}</li>
@@ -131,7 +131,7 @@ function UnitDetail({ item, location }: { item: EvidenceUnit; location: Evidence
const source = item.provenance.kind === "manual" ? item.provenance.original : item.provenance;
const file = location.workspace ? `${location.workspace.replace(/\\/g, "/")}/evidence/${item.file}` : null;
return <article className="max-w-[75ch] space-y-5 pb-8">
<header><p className="text-xs text-muted-foreground">{t(states[item.status])} · {item.purposes.map(purpose => t(purpose.replaceAll("_", " "))).join(", ")}</p><h2 className="mt-1 font-serif text-xl font-semibold">{item.title}</h2></header>
<header><p className="text-xs text-muted-foreground">{t(states[item.status])} · {item.purposes.map(purpose => t(purpose.replaceAll("_", " "))).join(", ")}</p><h2 className="mt-1 font-sans text-xl font-semibold">{item.title}</h2></header>
{file && <CopyText text={file} label={t("Evidence file path")} />}
{item.status !== "active" && <p className="text-sm text-muted-foreground">{["invalid", "removed"].includes(item.status) ? t("The file is invalid or removed. Its last active content is shown here.") : t("This is the file version awaiting consolidation.")} {t("The core continues to use its last active version.")}</p>}
{Object.entries(item.applies_to).some(([, values]) => values.length > 0) && <section><h3 className="font-medium">{t("Scope")}</h3>{Object.entries(item.applies_to).map(([name, values]) => values.length > 0 && <p className="mt-2 break-words text-sm" key={name}><span className="capitalize">{t(name)}</span>: {values.join(", ")}</p>)}</section>}