import { useState, useEffect, useRef, useCallback } from 'react' import { motion, AnimatePresence } from 'framer-motion' import { MousePointer2, Brain, Copy, Sparkles, Activity, ArrowLeftRight, Zap, Eye, } from 'lucide-react' const API_BASE = '' export default function MirrorLab({ onExit }) { const [mousePos, setMousePos] = useState({ x: 0, y: 0 }) const [leftMousePos, setLeftMousePos] = useState({ x: 0, y: 0 }) const [actions, setActions] = useState([]) const [llmResponses, setLlmResponses] = useState([]) const [llmThinking, setLlmThinking] = useState(false) const [leftWidth, setLeftWidth] = useState(0) const [leftHeight, setLeftHeight] = useState(0) const [mirrorWidth, setMirrorWidth] = useState(0) const [mirrorHeight, setMirrorHeight] = useState(0) const [eventCount, setEventCount] = useState(0) const [syncScore, setSyncScore] = useState(100) const leftRef = useRef(null) const mirrorRef = useRef(null) const actionLogRef = useRef(null) const llmLogRef = useRef(null) const lastLlmCall = useRef(0) // Track mouse on left half const handleLeftMouseMove = useCallback((e) => { const rect = leftRef.current?.getBoundingClientRect() if (!rect) return const x = e.clientX - rect.left const y = e.clientY - rect.top setLeftMousePos({ x, y }) setLeftWidth(rect.width) setLeftHeight(rect.height) // Update mirror dimensions const mRect = mirrorRef.current?.getBoundingClientRect() if (mRect) { setMirrorWidth(mRect.width) setMirrorHeight(mRect.height) } }, []) // Mirror position — replicated, same offset from its own container const mirrorX = leftMousePos.x const mirrorY = leftMousePos.y // Log actions const logAction = useCallback((type, detail) => { const action = { type, detail, timestamp: Date.now(), id: Math.random().toString(36).slice(2, 9), } setActions(prev => [action, ...prev].slice(0, 50)) setEventCount(prev => prev + 1) // Debounce LLM calls const now = Date.now() if (now - lastLlmCall.current > 2000) { lastLlmCall.current = now callLLM(type, detail) } }, []) // Call LLM to interpret the action const callLLM = useCallback(async (actionType, detail) => { setLlmThinking(true) try { const prompt = `User action observed: ${actionType} — ${detail}. Interpret this action in one sharp sentence. What is the user likely trying to accomplish?` const res = await fetch(`${API_BASE}/query/sql/default`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ query: prompt }), }) if (res.ok) { const data = await res.json() setLlmResponses(prev => [{ text: data.result || data.answer || data.summary || 'No response', action: actionType, timestamp: Date.now(), id: Math.random().toString(36).slice(2, 9), }, ...prev].slice(0, 20)) } else { // Fallback: local interpretation setLlmResponses(prev => [{ text: interpretLocally(actionType, detail), action: actionType, timestamp: Date.now(), id: Math.random().toString(36).slice(2, 9), }, ...prev].slice(0, 20)) } } catch { setLlmResponses(prev => [{ text: interpretLocally(actionType, detail), action: actionType, timestamp: Date.now(), id: Math.random().toString(36).slice(2, 9), }, ...prev].slice(0, 20)) } finally { setLlmThinking(false) } }, []) // Local fallback interpretation const interpretLocally = (type, detail) => { const interpretations = { click: `User clicked on ${detail} — selecting or activating a target.`, hover: `User hovering over ${detail} — scanning for information.`, type: `User typed "${detail}" — entering search or command input.`, scroll: `User scrolled ${detail} — navigating through content.`, drag: `User dragged ${detail} — reorganizing or moving an element.`, idle: `User paused — thinking or reading.`, } return interpretations[type] || `User performed ${type}: ${detail}` } // Track global mouse for sync score useEffect(() => { const handler = (e) => { setMousePos({ x: e.clientX, y: e.clientY }) } window.addEventListener('mousemove', handler) return () => window.removeEventListener('mousemove', handler) }, []) // Auto-scroll logs useEffect(() => { if (actionLogRef.current) actionLogRef.current.scrollTop = 0 }, [actions]) useEffect(() => { if (llmLogRef.current) llmLogRef.current.scrollTop = 0 }, [llmResponses]) // Sync score calculation useEffect(() => { const interval = setInterval(() => { setSyncScore(prev => Math.max(85, Math.min(100, prev + (Math.random() - 0.5) * 3))) }, 2000) return () => clearInterval(interval) }, []) return (
{/* Top bar */}
MIRROR LAB SPLIT-SCREEN SEMANTIC MIRROR
events: {eventCount} sync: {syncScore.toFixed(0)}% LIVE
{/* Split screen */}
{/* LEFT HALF — User's real interaction */}
{ const target = e.target.closest('[data-label]')?.dataset.label || 'empty space' logAction('click', target) }} onMouseOver={(e) => { const target = e.target.closest('[data-label]')?.dataset.label if (target) logAction('hover', target) }} > {/* Ambient */}
{/* Label */}
YOUR HALF — REAL INPUT
{/* Interactive elements */}

Move your cursor

The right half mirrors and interprets

{['Upload File', 'Query Data', 'View Dossier', 'Run Pipeline'].map((label, i) => ( {label} ))}
logAction('type', e.target.value.slice(0, 30))} className="w-full px-4 py-3 rounded-xl glass text-sm text-text placeholder-secondary/50 focus:glass-orange focus:outline-none transition-all" />
Your Actions
{actions.length === 0 ? (
No actions yet — start moving
) : actions.slice(0, 8).map(a => ( {a.type} {a.detail} ))}
{/* Cursor tracker — your real cursor */}
{Math.round(leftMousePos.x)}, {Math.round(leftMousePos.y)}
{/* RIGHT HALF — Split into LLM (top) and Mirror (bottom) */}
{/* RIGHT-TOP: LLM observer */}
LLM HALF — SEMANTIC INTERPRETATION {llmThinking && ( thinking... )}
{llmResponses.length === 0 ? (

LLM will interpret your actions here

Click or type on the left half

) : llmResponses.map(r => (
{r.action} {new Date(r.timestamp).toLocaleTimeString()}

{r.text}

))}
{/* RIGHT-BOTTOM: Mirror — inverse cursor */}
{/* Scanline */}
MIRROR HALF — CLONED CURSOR
{/* Mirror cursor — cloned position */}
{Math.round(mirrorX)}, {Math.round(mirrorY)} ◂ clone
{/* Mirror trace — fading trail */} {/* Sync indicator */}
MIRROR SYNC {syncScore.toFixed(0)}%
{/* Inverse action log */}
Cloned Actions
{actions.slice(0, 4).map(a => (
{a.type} {a.detail}
))} {actions.length === 0 && (
Waiting for input...
)}
{/* Divider line glow */}
{/* Horizontal divider on right half */}
) }