All checks were successful
G12 Leak-Guard / leak-guard (pull_request) Successful in 8s
מגיש את scripts/SCRIPTS.md כדף ב-/scripts: שם · סוג · תפקיד · תזמון לכל סקריפט בתיקיית scripts/. מקור-האמת היחיד נשאר SCRIPTS.md (G2 — אין מסלול-תוכן מקביל); עריכה דרך git, לא מה-UI. - web/app.py: GET /api/scripts/catalog קורא את הקובץ בזמן-ריצה (מחקה את דפוס get_curator_prompt; HTTPException על כשל — אין בליעה שקטה §6) - Dockerfile: COPY scripts/SCRIPTS.md (לא הועתק לקונטיינר עד כה) - web-ui: דף /scripts (AppShell + רכיב Markdown הקיים) + מודול api + קישור ניווט - SCRIPTS.md: תיעוד ingest_bulletins.py — היה הקובץ היחיד מ-73 שלא תועד Invariants: G2 (מקור-אמת יחיד), G12 (אין מגע-Paperclip), X6 (UI↔API). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87 lines
3.0 KiB
TypeScript
87 lines
3.0 KiB
TypeScript
"use client";
|
||
|
||
import { useQuery } from "@tanstack/react-query";
|
||
|
||
import { AppShell } from "@/components/app-shell";
|
||
import { Card, CardContent } from "@/components/ui/card";
|
||
import { Markdown } from "@/components/ui/markdown";
|
||
import { fetchScriptsCatalog } from "@/lib/api/scripts";
|
||
|
||
/*
|
||
* /scripts — read-only catalog of everything under scripts/.
|
||
*
|
||
* The content is `scripts/SCRIPTS.md` verbatim (active · archived · deleted
|
||
* tables), served by GET /api/scripts/catalog. SCRIPTS.md is the single
|
||
* source of truth — CLAUDE.md mandates updating it on every script change —
|
||
* so we render it directly rather than re-describing the scripts here.
|
||
*/
|
||
export default function ScriptsPage() {
|
||
const { data, isLoading, isError, error } = useQuery({
|
||
queryKey: ["scripts-catalog"],
|
||
queryFn: ({ signal }) => fetchScriptsCatalog(signal),
|
||
});
|
||
|
||
const lastModified =
|
||
data?.last_modified != null
|
||
? new Date(data.last_modified * 1000).toLocaleDateString("he-IL", {
|
||
year: "numeric",
|
||
month: "long",
|
||
day: "numeric",
|
||
})
|
||
: null;
|
||
|
||
return (
|
||
<AppShell>
|
||
<section className="space-y-6">
|
||
<div className="flex items-end justify-between gap-4">
|
||
<div>
|
||
<h1 className="text-xl font-bold text-navy">סקריפטים</h1>
|
||
<p className="text-sm text-ink-muted mt-1">
|
||
קטלוג כל הסקריפטים בתיקיית{" "}
|
||
<code className="rounded bg-rule-soft px-1 py-0.5 font-mono text-[0.78rem]">
|
||
scripts/
|
||
</code>{" "}
|
||
— שם, סוג, תפקיד ותזמון. מקור-האמת הוא{" "}
|
||
<code className="rounded bg-rule-soft px-1 py-0.5 font-mono text-[0.78rem]">
|
||
scripts/SCRIPTS.md
|
||
</code>
|
||
; עריכה דרך git, לא מכאן.
|
||
</p>
|
||
</div>
|
||
{data?.gitea_url ? (
|
||
<a
|
||
href={data.gitea_url}
|
||
target="_blank"
|
||
rel="noreferrer"
|
||
className="shrink-0 text-sm text-gold-deep hover:text-gold underline underline-offset-2"
|
||
>
|
||
מקור ב-Gitea ↗
|
||
</a>
|
||
) : null}
|
||
</div>
|
||
|
||
<Card className="bg-surface border-rule shadow-sm">
|
||
<CardContent className="px-6 py-5">
|
||
{isLoading ? (
|
||
<p className="text-sm text-ink-muted">טוען קטלוג…</p>
|
||
) : isError ? (
|
||
<p className="text-sm text-danger">
|
||
שגיאה בטעינת הקטלוג: {(error as Error)?.message ?? "לא ידוע"}
|
||
</p>
|
||
) : data ? (
|
||
<>
|
||
<Markdown content={data.content} />
|
||
{lastModified ? (
|
||
<p className="mt-6 pt-3 border-t border-rule text-xs text-ink-muted">
|
||
עודכן לאחרונה: {lastModified}
|
||
</p>
|
||
) : null}
|
||
</>
|
||
) : null}
|
||
</CardContent>
|
||
</Card>
|
||
</section>
|
||
</AppShell>
|
||
);
|
||
}
|