/** * Root component: header with connection/session status and the workspace * toggle, the chat column (thread, plan, permissions, composer) and the * workspace panel. The WebSocket is injected so tests (and future * embeddings) can supply a fake. * * @example * */ import { ChatThread } from "./components/ChatThread"; import { PermissionPrompt } from "./components/PermissionPrompt"; import { PlanView } from "./components/PlanView"; import { PromptInput } from "./components/PromptInput"; import { Workspace } from "./components/Workspace"; import { useChatState } from "./store"; import { toggleTheme, useTheme } from "./theme"; import { toggleWorkspace, useWorkspace } from "./workspace"; import type { OriSocket } from "./ws"; export function App({ socket }: { socket: OriSocket }) { const state = useChatState(); const workspaceOpen = useWorkspace((workspace) => workspace.open); const theme = useTheme((state) => state.theme); const nextTheme = theme === "dark" ? "light" : "dark"; return (

Ori

{state.connection} {state.sessionId ? ` · ${state.sessionId}` : ""}
{state.permissions.map((request) => ( socket.send({ type: "permission_response", requestId, optionId, }) } /> ))} socket.send( attachments.length > 0 ? { type: "prompt", text, attachments } : { type: "prompt", text }, ) } onCancel={() => socket.send({ type: "cancel" })} />
); }