import { useEffect, useState } from 'react' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' import type { HoloLakeUiPlugin, UiPluginNode } from '@/lib/uiPluginSystem' import { applyUiPluginTokens, validateUiPlugin } from '@/lib/uiPluginSystem' export type LanguageShellViewState = { status: string confirmationQuestion: string | null receipt: string | null evidence?: string | null } export type LanguageShellBridge = { submitGoal(goal: string): void answerConfirmation(approved: boolean): void } type Props = { plugin: HoloLakeUiPlugin state: LanguageShellViewState bridge: LanguageShellBridge } export function HotPluggableLanguageShell({ plugin, state, bridge }: Props) { const validation = validateUiPlugin(plugin) const [goal, setGoal] = useState('') const [evidenceOpen, setEvidenceOpen] = useState(false) useEffect(() => { if (!validation.ok) return const root = document.documentElement.style const names = applyUiPluginTokens(plugin, root) return () => names.forEach((name) => root.removeProperty(name)) }, [plugin, validation.ok]) if (!validation.ok) throw new Error(`UI_PLUGIN_REJECTED:${validation.errors.join(',')}`) const renderNode = (node: UiPluginNode, path: string): React.ReactNode => { const children = node.children?.map((child, index) => renderNode(child, `${path}.${index}`)) switch (node.kind) { case 'shell': return
{children}
case 'stack': return
{children}
case 'row': return
{children}
case 'text': return

{node.text}

case 'language_input': return (
{ event.preventDefault(); bridge.submitGoal(goal) }}> setGoal(event.target.value)} aria-label="language goal" />
) case 'task_status': return

{state.status}

case 'reality_boundary_confirmation': return state.confirmationQuestion ? (

{state.confirmationQuestion}

) :