import React, { useEffect, useMemo, useRef, useState } from 'react'; import api from '../../utils/api'; import { useEscapeKey } from '../../hooks/useEscapeKey'; import { useFocusTrap } from '../../hooks/useFocusTrap'; import { X } from '../../icons'; import { contentClassLabel, isCanaryClass } from '../../realism/labels'; // Reuse the DeckyFleet shell + the persona-page tweaks so this page reads // the same as the rest of the realism nav group. import '../DeckyFleet.css'; import '../PersonaGeneration.css'; import './SyntheticFiles.css'; // ─── Types ─────────────────────────────────────────────────────────────────── interface SyntheticFileRow { uuid: string; decky_uuid: string; path: string; persona: string; content_class: string; created_at: string; last_modified: string; edit_count: number; content_hash: string; } interface SyntheticFileDetail extends SyntheticFileRow { last_body: string; truncated: boolean; } interface PaginatedResponse { total: number; limit: number; offset: number; data: SyntheticFileRow[]; } interface DeckyOption { uuid: string; name: string; } const PAGE_SIZE = 50; // Fixed list of content_class values mirroring decnet/realism/taxonomy.py. // A static dropdown beats free-text — the operator sees what's actually // available without a typo path failing silently. const CONTENT_CLASSES = [ 'note', 'todo', 'draft', 'script', 'log_cron', 'log_daemon', 'cache_tmp', 'canary_aws_creds', 'canary_env_file', 'canary_git_config', 'canary_ssh_key', 'canary_honeydoc', 'canary_honeydoc_docx', 'canary_honeydoc_pdf', 'canary_mysql_dump', 'canary_fingerprint_html', 'canary_fingerprint_svg', ] as const; // ─── Helpers ───────────────────────────────────────────────────────────────── function fmt(iso: string): string { const d = new Date(iso); if (Number.isNaN(d.getTime())) return iso; const pad = (n: number) => String(n).padStart(2, '0'); return `${d.getFullYear()}-${pad(d.getMonth() + 1)}-${pad(d.getDate())} ${pad(d.getHours())}:${pad(d.getMinutes())}`; } function deckyLabel(uuid: string, deckies: DeckyOption[]): string { const d = deckies.find((d) => d.uuid === uuid); return d ? d.name : `${uuid.slice(0, 8)}…`; } // ─── Drawer ────────────────────────────────────────────────────────────────── interface DrawerProps { uuid: string; deckies: DeckyOption[]; onClose: () => void; } const SyntheticFileDrawer: React.FC = ({ uuid, deckies, onClose }) => { const panelRef = useRef(null); useEscapeKey(onClose, true); useFocusTrap(panelRef, true); useEffect(() => { const prev = document.body.style.overflow; document.body.style.overflow = 'hidden'; return () => { document.body.style.overflow = prev; }; }, []); const [row, setRow] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); useEffect(() => { let cancelled = false; setLoading(true); setError(null); api.get(`/realism/synthetic-files/${encodeURIComponent(uuid)}`) .then((res) => { if (!cancelled) setRow(res.data); }) .catch((err: any) => { if (cancelled) return; setError(err?.response?.status === 404 ? 'File no longer exists.' : 'Load failed.'); }) .finally(() => { if (!cancelled) setLoading(false); }); return () => { cancelled = true; }; }, [uuid]); const canary = row ? isCanaryClass(row.content_class) : false; return (
{ if (e.target === e.currentTarget) onClose(); }} >
SYNTHETIC FILE{row ? ` · ${deckyLabel(row.decky_uuid, deckies)}` : ''}
{row?.path ?? uuid}
{loading &&
Loading…
} {error &&
{error}
} {row && ( <>
Persona
{row.persona}
Content Class
{contentClassLabel(row.content_class)} {row.content_class}
Edit Count
{row.edit_count}
Created
{fmt(row.created_at)}
Last Modified
{fmt(row.last_modified)}
Content Hash
{row.content_hash}
BODY PREVIEW · {(row.last_body?.length ?? 0).toLocaleString()} BYTES {row.truncated && ( TRUNCATED )}
              {row.last_body || }
            
)}
); }; // ─── Page ──────────────────────────────────────────────────────────────────── const SyntheticFiles: React.FC = () => { const [rows, setRows] = useState([]); const [total, setTotal] = useState(0); const [page, setPage] = useState(0); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [deckies, setDeckies] = useState([]); const [deckyFilter, setDeckyFilter] = useState(''); // '' = all const [personaFilter, setPersonaFilter] = useState(''); const [classFilter, setClassFilter] = useState(''); const [selectedUuid, setSelectedUuid] = useState(null); useEffect(() => { api.get('/deckies') .then((res) => setDeckies(Array.isArray(res.data) ? res.data : [])) .catch(() => setDeckies([])); }, []); const personaOptions = useMemo(() => { const set = new Set(); rows.forEach((r) => set.add(r.persona)); return Array.from(set).sort(); }, [rows]); const fetchRows = async () => { setLoading(true); setError(null); try { const params = new URLSearchParams(); params.set('limit', String(PAGE_SIZE)); params.set('offset', String(page * PAGE_SIZE)); if (deckyFilter) params.set('decky_uuid', deckyFilter); if (personaFilter) params.set('persona', personaFilter); if (classFilter) params.set('content_class', classFilter); const res = await api.get( `/realism/synthetic-files?${params.toString()}`, ); setRows(res.data.data); setTotal(res.data.total); } catch (err: any) { setError(err?.response?.status === 401 ? 'Authentication required.' : 'Load failed.'); } finally { setLoading(false); } }; useEffect(() => { fetchRows(); /* eslint-disable-next-line react-hooks/exhaustive-deps */ }, [ page, deckyFilter, personaFilter, classFilter, ]); const totalPages = Math.max(1, Math.ceil(total / PAGE_SIZE)); const filtersActive = !!(deckyFilter || personaFilter || classFilter); return (

SYNTHETIC FILES

{total} TOTAL · PAGE {page + 1} / {totalPages} {filtersActive ? ' · FILTERED' : ''}
Scope: read-only inventory of files the realism worker has grown across the fleet. The orchestrator is the sole writer; rows persist in the{' '} synthetic_files table. Click any row for the body preview and lineage detail.
{error && (
{error}
)}
{loading && ( )} {!loading && rows.length === 0 && ( )} {!loading && rows.map((r) => { const canary = isCanaryClass(r.content_class); return ( setSelectedUuid(r.uuid)}> ); })}
Decky Path Persona Class Last Modified Edits Hash
Loading…
No files match the current filters.
{deckyLabel(r.decky_uuid, deckies)} {r.path} {r.persona} {contentClassLabel(r.content_class)} {fmt(r.last_modified)} {r.edit_count} {r.content_hash.slice(0, 12)}…
PAGE {page + 1} / {totalPages}
{selectedUuid && ( setSelectedUuid(null)} /> )}
); }; export default SyntheticFiles;