// website/src/pages/Projects.jsx // R&D history from rd_loop.py + project timeline // API: GET /api/rd/history/:userId?limit=20 import { useState, useEffect, useCallback } from 'react'; import { api } from '../lib/api'; import { relativeTime } from '../lib/utils'; import Card from '../components/Card'; import Badge from '../components/Badge'; const GHOST_USER_ID = '1356180323058057326'; const STATE_COLOR = { proposed: 'yellow', ranked: 'blue', debating: 'blue', implementing: 'green', done: 'green', failed: 'red', }; function RDEntry({ item }) { const [open, setOpen] = useState(false); return (
{open && (
{item.council_verdict && (

Council Verdict

{item.council_verdict}

)} {item.implementation_notes && (

Implementation

{item.implementation_notes}

)} {item.completed_at && (

Completed {relativeTime(item.completed_at)}

)}
)}
); } function RDState({ state }) { if (!state) return null; return (
{[ { label: 'Current Phase', value: state.phase ?? '—' }, { label: 'Proposals Seen', value: state.proposals_count ?? 0 }, { label: 'Implemented', value: state.implemented_count ?? 0 }, ].map(({ label, value }) => (

{label}

{value}

))}
); } export default function Projects() { const [data, setData] = useState(null); const [loading, setLoading] = useState(true); const [error, setError] = useState(null); const [userId, setUserId] = useState(GHOST_USER_ID); const [inputId, setInputId] = useState(GHOST_USER_ID); const fetchHistory = useCallback(async (uid) => { setLoading(true); setError(null); try { const d = await api.rd.history(uid); setData(d); } catch (e) { setError(e.message); } finally { setLoading(false); } }, []); useEffect(() => { fetchHistory(userId); }, [userId, fetchHistory]); const improvements = data?.improvements ?? []; const rdState = data?.rd_state ?? null; return (

Projects

Tasks, deadlines, and autonomous R&D sessions logged here.

setInputId(e.target.value)} />
{error && (
✗ {error} — Brain may be offline or Redis unavailable.
)} {!loading && rdState && } {loading ? (
Loading...
) : improvements.length === 0 ? (

No R&D sessions yet.

Post-deadline improvement sessions appear here. Powered by rd_loop.py.

) : ( improvements.map((item, i) => ) )}
{[ { phase: 'Phase 1–3', what: 'LLM router, key pool, ReAct loop, task dispatcher', done: true }, { phase: 'Phase 4', what: 'Discord bot, per-channel Redis context window', done: true }, { phase: 'Phase 5', what: 'Memory: RAPTOR, Zilliz, lifecycle, MAGMA graph, R&D loop', done: true }, { phase: 'Phase 5b', what: 'Sentinel, Council MoA, voice STT/TTS, SpacePromoter', done: true }, { phase: 'Phase 6', what: 'Multi-space active-active, key expansion, credential injection', done: false }, { phase: 'Phase 7', what: 'Production deploy: HF Spaces + CF Worker + Discord live', done: false }, ].map(({ phase, what, done }) => (
{phase} {what} {done ? 'done' : 'pending'}
))}
); }