From d1fdfb140cc440664f77a24886172f9976a05a31 Mon Sep 17 00:00:00 2001 From: soryu Date: Tue, 28 Apr 2026 19:12:52 +0100 Subject: feat: revert broken directive PRs, re-implement Lexical document orchestrator (#98) * feat: soryu-co/soryu - makima: Revert broken directive PRs and verify clean build * feat: soryu-co/soryu - makima: Re-implement frontend: Lexical document editor with feature flag and base components * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: Add contract blocks, expandable log rows, and interaction controls * WIP: heartbeat checkpoint * feat: soryu-co/soryu - makima: End-to-end build verification and integration polish --- .../src/components/document/DocumentLayout.tsx | 316 --------------------- 1 file changed, 316 deletions(-) delete mode 100644 frontend/src/components/document/DocumentLayout.tsx (limited to 'frontend/src/components/document/DocumentLayout.tsx') diff --git a/frontend/src/components/document/DocumentLayout.tsx b/frontend/src/components/document/DocumentLayout.tsx deleted file mode 100644 index 05f4190..0000000 --- a/frontend/src/components/document/DocumentLayout.tsx +++ /dev/null @@ -1,316 +0,0 @@ -import { useEffect, useState, useCallback, useRef, useMemo } from 'react' -import { useParams, useNavigate, Link } from 'react-router-dom' -import { DirectiveFileTree } from './DirectiveFileTree' -import DocumentEditor from './DocumentEditor' -import { ToastProvider, useToast } from './Toast' -import { - type DirectiveWithSteps, - type DirectiveStep, - getDirective, - getDirectiveSteps, - updateGoal, - updateDirective, - cleanupDirective, - createPr, - pickUpOrders, - pauseDirective, - startDirective, -} from '../../services/directiveApi' -import './DocumentLayout.css' - -function StatusBadge({ status }: { status: string }) { - const colors: Record = { - active: '#4caf50', - running: '#4caf50', - idle: '#ffc107', - paused: '#ffc107', - draft: '#9e9e9e', - pending: '#9e9e9e', - archived: '#f44336', - failed: '#f44336', - } - const color = colors[status.toLowerCase()] || '#9e9e9e' - - return ( - - {status} - - ) -} - -function DocumentLayoutInner() { - const { id: urlDirectiveId } = useParams<{ id: string }>() - const navigate = useNavigate() - const { addToast } = useToast() - - const [selectedId, setSelectedId] = useState(urlDirectiveId || null) - const [directive, setDirective] = useState(null) - const [loading, setLoading] = useState(false) - const [error, setError] = useState(null) - const [sidebarWidth, setSidebarWidth] = useState(250) - const resizingRef = useRef(false) - const startXRef = useRef(0) - const startWidthRef = useRef(250) - const pollRef = useRef | null>(null) - - // Sync URL param on mount - useEffect(() => { - if (urlDirectiveId && urlDirectiveId !== selectedId) { - setSelectedId(urlDirectiveId) - } - }, [urlDirectiveId]) - - // Handle directive selection - update URL - const handleSelectDirective = useCallback((id: string) => { - setSelectedId(id) - navigate(`/directives/${id}`, { replace: true }) - }, [navigate]) - - // Load directive when selected - useEffect(() => { - if (!selectedId) { - setDirective(null) - return - } - - let cancelled = false - async function load() { - try { - setLoading(true) - setError(null) - const data = await getDirective(selectedId!) - if (!cancelled) setDirective(data) - } catch (err) { - if (!cancelled) { - const msg = err instanceof Error ? err.message : 'Failed to load directive' - setError(msg) - addToast(msg, 'error') - } - } finally { - if (!cancelled) setLoading(false) - } - } - load() - - return () => { cancelled = true } - }, [selectedId, addToast]) - - // Step polling (after goal update triggers supervisor) - const startStepPolling = useCallback(() => { - if (pollRef.current) clearInterval(pollRef.current) - pollRef.current = setInterval(async () => { - if (!selectedId) return - try { - const data = await getDirective(selectedId) - setDirective(data) - } catch { - // Silently fail for polling - } - }, 3000) - // Stop after 60 seconds - setTimeout(() => { - if (pollRef.current) { - clearInterval(pollRef.current) - pollRef.current = null - } - }, 60000) - }, [selectedId]) - - useEffect(() => { - return () => { - if (pollRef.current) clearInterval(pollRef.current) - } - }, []) - - // Auto-save goal changes - const handleGoalChange = useCallback(async (newGoal: string) => { - if (!selectedId) return - try { - const updated = await updateGoal(selectedId, newGoal) - setDirective(updated) - addToast('Goal saved', 'success') - startStepPolling() - } catch (err) { - addToast(`Failed to save goal: ${(err as Error).message}`, 'error') - } - }, [selectedId, addToast, startStepPolling]) - - const handleTitleChange = useCallback(async (newTitle: string) => { - if (!selectedId || !directive) return - try { - const updated = await updateDirective(selectedId, { - title: newTitle, - version: directive.version, - }) - setDirective(updated) - } catch (err) { - addToast(`Failed to update title: ${(err as Error).message}`, 'error') - } - }, [selectedId, directive, addToast]) - - const handleCleanup = useCallback(async () => { - if (!selectedId) return - try { - await cleanupDirective(selectedId) - addToast('Cleanup contract spawned', 'success') - startStepPolling() - } catch (err) { - addToast(`Cleanup failed: ${(err as Error).message}`, 'error') - } - }, [selectedId, addToast, startStepPolling]) - - const handleCreatePr = useCallback(async () => { - if (!selectedId) return - try { - await createPr(selectedId) - addToast('PR update triggered', 'success') - } catch (err) { - addToast(`PR update failed: ${(err as Error).message}`, 'error') - } - }, [selectedId, addToast]) - - const handlePlanOrders = useCallback(async () => { - if (!selectedId) return - try { - await pickUpOrders(selectedId) - addToast('Planning orders...', 'info') - startStepPolling() - } catch (err) { - addToast(`Plan orders failed: ${(err as Error).message}`, 'error') - } - }, [selectedId, addToast, startStepPolling]) - - const handleTogglePause = useCallback(async () => { - if (!selectedId || !directive) return - try { - if (directive.status === 'paused') { - const result = await startDirective(selectedId) - setDirective(result) - addToast('Directive resumed', 'success') - } else { - const updated = await pauseDirective(selectedId) - setDirective(updated) - addToast('Directive paused', 'info') - } - } catch (err) { - addToast(`Failed to toggle pause: ${(err as Error).message}`, 'error') - } - }, [selectedId, directive, addToast]) - - // Sidebar resize handlers - const handleMouseDown = useCallback((e: React.MouseEvent) => { - resizingRef.current = true - startXRef.current = e.clientX - startWidthRef.current = sidebarWidth - document.body.style.cursor = 'col-resize' - document.body.style.userSelect = 'none' - - const handleMouseMove = (e: MouseEvent) => { - if (!resizingRef.current) return - const diff = e.clientX - startXRef.current - const newWidth = Math.max(180, Math.min(500, startWidthRef.current + diff)) - setSidebarWidth(newWidth) - } - - const handleMouseUp = () => { - resizingRef.current = false - document.body.style.cursor = '' - document.body.style.userSelect = '' - document.removeEventListener('mousemove', handleMouseMove) - document.removeEventListener('mouseup', handleMouseUp) - } - - document.addEventListener('mousemove', handleMouseMove) - document.addEventListener('mouseup', handleMouseUp) - }, [sidebarWidth]) - - const handleNewDirective = useCallback(() => { - // Placeholder - will be implemented with full directive creation flow - console.log('New directive requested') - }, []) - - return ( -
- {/* Sidebar */} -
-
- - {'\u2190'} Back to Main - -
- -
- - {/* Resize handle */} -
- - {/* Main content */} -
- {directive && ( -
-
-

{directive.title || 'Untitled'}

- -
-
- -
-
- )} - -
- {loading && ( -
-

Loading directive...

-
- )} - - {error && ( -
-

Error: {error}

-
- )} - - {!loading && !error && !directive && ( -
-
{'\u{1F4DD}'}
-

No directive selected

-

Select a directive from the sidebar or create a new one to get started.

-
- )} - - {!loading && !error && directive && ( - - )} -
-
-
- ) -} - -// Wrapper that provides toast context -export default function DocumentLayout() { - return ( - - - - ) -} -- cgit v1.2.3