@nbt-dev/devtools 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/config.tsx", "../src/components/devtools/devtools-context.tsx", "../src/components/devtools/dev-tools.tsx", "../src/lib/utils.ts", "../src/components/devtools/console-tab.tsx", "../src/components/devtools/network-tab.tsx", "../src/components/devtools/data-tab.tsx", "../src/hooks/use-cartridge-info.ts", "../src/hooks/use-bulk-stream.ts", "../src/generated/bulk-protocol.ts", "../src/components/devtools/data-browser/data-store.ts", "../src/components/devtools/data-browser/bulk-decoder.ts", "../src/components/devtools/data-browser/data-table.tsx", "../src/components/devtools/entity-graph/diagram-tab.tsx", "../src/components/devtools/entity-graph/entity-node.tsx", "../src/components/devtools/entity-graph/entity-graph-utils.ts", "../src/components/ui/sheet.tsx", "../src/components/ui/button.tsx", "../src/components/devtools/settings-tab.tsx", "../src/index.tsx"],
4
- "sourcesContent": ["import React from \"react\";\n\n// Runtime config for the devtools, replacing the inspector's compile-time\n// `NIMBIT_API_ENDPOINT` define. Hosts pass the console's base URL once via\n// <NimbitDevTools apiBaseUrl=\"\u2026\" /> and every fetch/WebSocket derives from it.\n// Empty string => same-origin (the inspector default when served by the console).\nexport type DevToolsConfig = {\n apiBaseUrl: string;\n};\n\nconst DevToolsConfigContext = React.createContext<DevToolsConfig>({\n apiBaseUrl: \"\",\n});\n\nexport const DevToolsConfigProvider: React.FC<{\n apiBaseUrl?: string;\n children: React.ReactNode;\n}> = ({ apiBaseUrl = \"\", children }) => {\n const value = React.useMemo(() => ({ apiBaseUrl }), [apiBaseUrl]);\n return (\n <DevToolsConfigContext.Provider value={value}>\n {children}\n </DevToolsConfigContext.Provider>\n );\n};\n\nexport function useDevToolsConfig(): DevToolsConfig {\n return React.useContext(DevToolsConfigContext);\n}\n\n// Turn an http(s) base into a ws(s) base. Empty => derive from window.location.\nexport function wsBaseFrom(apiBaseUrl: string): string {\n if (!apiBaseUrl) {\n const loc = window.location;\n const proto = loc.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${proto}//${loc.host}`;\n }\n return apiBaseUrl.replace(/^http(s?):/, \"ws$1:\");\n}\n", "import React, { useEffect } from \"react\";\n\nexport type DevToolsDock = \"bottom\" | \"right\";\n\nexport type DevToolsTab = {\n id: string;\n title: string;\n icon?: React.ReactNode;\n render: () => React.ReactNode;\n};\n\nexport type DevToolsSize = { h: number; w: number };\n\ntype DevToolsCtx = {\n open: boolean;\n setOpen: (v: boolean) => void;\n toggle: () => void;\n dock: DevToolsDock;\n setDock: (d: DevToolsDock) => void;\n activeTab: string | null;\n setActiveTab: (id: string) => void;\n size: DevToolsSize;\n setSize: (s: DevToolsSize | ((prev: DevToolsSize) => DevToolsSize)) => void;\n maximized: boolean;\n setMaximized: (v: boolean) => void;\n dataCart: string | null;\n setDataCart: (v: string | null) => void;\n dataEntity: string | null;\n setDataEntity: (v: string | null) => void;\n};\n\nconst Ctx = React.createContext<DevToolsCtx | null>(null);\n\nexport const DevToolsProvider: React.FC<{\n children: React.ReactNode;\n defaultActiveTab?: string;\n}> = ({ children, defaultActiveTab }) => {\n const [open, setOpen] = React.useState(false);\n const [dock, setDock] = React.useState<DevToolsDock>(\"bottom\");\n const [activeTab, setActiveTab] = React.useState<string | null>(\n defaultActiveTab ?? null,\n );\n const [size, setSize] = React.useState<DevToolsSize>({ h: 320, w: 480 });\n const [maximized, setMaximized] = React.useState(false);\n const [dataCart, setDataCart] = React.useState<string | null>(null);\n const [dataEntity, setDataEntity] = React.useState<string | null>(null);\n\n const toggle = React.useCallback(() => setOpen((o) => !o), []);\n\n const value = React.useMemo(\n () => ({\n open,\n setOpen,\n toggle,\n dock,\n setDock,\n activeTab,\n setActiveTab,\n size,\n setSize,\n maximized,\n setMaximized,\n dataCart,\n setDataCart,\n dataEntity,\n setDataEntity,\n }),\n [open, toggle, dock, activeTab, size, maximized, dataCart, dataEntity],\n );\n\n // Toggle from anywhere via `window.dispatchEvent(new Event(\"devtools-toggle\"))`.\n useEffect(() => {\n const listen = () => toggle();\n window.addEventListener(\"devtools-toggle\", listen);\n return () => window.removeEventListener(\"devtools-toggle\", listen);\n }, [open, toggle]);\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>;\n};\n\nexport function useDevTools(): DevToolsCtx {\n const v = React.useContext(Ctx);\n if (!v) throw new Error(\"useDevTools must be used inside <DevToolsProvider>\");\n return v;\n}\n", "import React from \"react\";\nimport { Maximize2, Minimize2, PanelBottom, PanelRight, X } from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\nimport { useDevTools, type DevToolsTab } from \"./devtools-context\";\nimport ConsoleTab from \"./console-tab\";\nimport NetworkTab from \"./network-tab\";\nimport DataTab from \"./data-tab\";\nimport SettingsTab from \"./settings-tab\";\n\nconst MIN_H = 120;\nconst MIN_W = 240;\n\nconst DEV_TOOLS_TABS: DevToolsTab[] = [\n { id: \"console\", title: \"Console\", render: () => <ConsoleTab /> },\n { id: \"network\", title: \"Network\", render: () => <NetworkTab /> },\n { id: \"data\", title: \"Data\", render: () => <DataTab /> },\n { id: \"settings\", title: \"Settings\", render: () => <SettingsTab /> },\n];\n\nconst DevTools: React.FC = () => {\n const {\n open,\n setOpen,\n dock,\n setDock,\n activeTab,\n setActiveTab,\n size,\n setSize,\n maximized,\n setMaximized,\n } = useDevTools();\n\n const panelRef = React.useRef<HTMLDivElement | null>(null);\n\n React.useEffect(() => {\n if (activeTab) return;\n if (DEV_TOOLS_TABS.length > 0) setActiveTab(DEV_TOOLS_TABS[0].id);\n }, [activeTab, setActiveTab]);\n\n const startResize = React.useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n const panel = panelRef.current;\n if (!panel) return;\n const parent = panel.parentElement;\n if (!parent) return;\n\n const handle = e.currentTarget as HTMLElement;\n handle.setPointerCapture(e.pointerId);\n\n const parentRect = parent.getBoundingClientRect();\n const startX = e.clientX;\n const startY = e.clientY;\n const startH = panel.offsetHeight;\n const startW = panel.offsetWidth;\n const isBottom = dock === \"bottom\";\n\n // Resize by mutating the panel's DOM size directly each frame \u2014 no React\n // state churn, so the active tab (e.g. the ReactFlow Diagram) doesn't\n // re-render on every pointermove. State is committed once on pointerup.\n let pendingNext: number | null = null;\n let lastApplied = isBottom ? startH : startW;\n let rafId = 0;\n const flush = () => {\n rafId = 0;\n if (pendingNext == null) return;\n const v = pendingNext;\n pendingNext = null;\n lastApplied = v;\n if (isBottom) panel.style.height = `${v}px`;\n else panel.style.width = `${v}px`;\n };\n\n const onMove = (ev: PointerEvent) => {\n ev.preventDefault();\n if (isBottom) {\n const dy = startY - ev.clientY;\n pendingNext = Math.max(\n MIN_H,\n Math.min(parentRect.height - 24, startH + dy),\n );\n } else {\n const dx = startX - ev.clientX;\n pendingNext = Math.max(\n MIN_W,\n Math.min(parentRect.width - 24, startW + dx),\n );\n }\n if (!rafId) rafId = requestAnimationFrame(flush);\n };\n\n const onUp = () => {\n if (rafId) cancelAnimationFrame(rafId);\n flush();\n setSize((prev) =>\n isBottom\n ? prev.h === lastApplied\n ? prev\n : { ...prev, h: lastApplied }\n : prev.w === lastApplied\n ? prev\n : { ...prev, w: lastApplied },\n );\n handle.removeEventListener(\"pointermove\", onMove);\n handle.removeEventListener(\"pointerup\", onUp);\n handle.removeEventListener(\"pointercancel\", onUp);\n try {\n handle.releasePointerCapture(e.pointerId);\n } catch {\n /* already released */\n }\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n };\n\n document.body.style.userSelect = \"none\";\n document.body.style.cursor =\n dock === \"bottom\" ? \"ns-resize\" : \"ew-resize\";\n handle.addEventListener(\"pointermove\", onMove);\n handle.addEventListener(\"pointerup\", onUp);\n handle.addEventListener(\"pointercancel\", onUp);\n },\n [dock, setSize],\n );\n\n if (!open) return null;\n\n const active =\n DEV_TOOLS_TABS.find((t) => t.id === activeTab) ?? DEV_TOOLS_TABS[0];\n\n const positionClass = maximized\n ? \"inset-0\"\n : dock === \"bottom\"\n ? \"inset-x-0 bottom-0\"\n : \"inset-y-0 right-0\";\n\n const sizeStyle: React.CSSProperties = maximized\n ? {}\n : dock === \"bottom\"\n ? { height: size.h }\n : { width: size.w };\n\n return (\n <div\n ref={panelRef}\n style={sizeStyle}\n className={cn(\n \"nimbit-devtools dark absolute z-40 flex flex-col border-border bg-background text-foreground text-[12px] shadow-lg\",\n positionClass,\n dock === \"bottom\" ? \"border-t\" : \"border-l\",\n )}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {!maximized && (\n <div\n onPointerDown={startResize}\n style={{ touchAction: \"none\" }}\n className={cn(\n \"absolute z-10 bg-transparent hover:bg-accent/40\",\n dock === \"bottom\"\n ? \"left-0 right-0 -top-px h-1.5 cursor-ns-resize\"\n : \"top-0 bottom-0 -left-px w-1.5 cursor-ew-resize\",\n )}\n />\n )}\n\n <div className=\"flex h-7 shrink-0 items-center border-b border-border bg-background pl-1 pr-1 select-none\">\n <div className=\"flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto\">\n {DEV_TOOLS_TABS.map((tab) => {\n const isActive = tab.id === active?.id;\n return (\n <button\n key={tab.id}\n type=\"button\"\n data-active={isActive}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n \"h-5 shrink-0 rounded-md px-2 text-[12px] leading-none outline-none transition-colors\",\n \"text-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n <span className=\"inline-flex items-center gap-1\">\n {tab.icon}\n {tab.title}\n </span>\n </button>\n );\n })}\n </div>\n\n <div className=\"flex shrink-0 items-center gap-0.5 pl-2\">\n <IconBtn\n label={dock === \"bottom\" ? \"Dock right\" : \"Dock bottom\"}\n onClick={() => setDock(dock === \"bottom\" ? \"right\" : \"bottom\")}\n >\n {dock === \"bottom\" ? (\n <PanelRight className=\"size-3.5\" />\n ) : (\n <PanelBottom className=\"size-3.5\" />\n )}\n </IconBtn>\n <IconBtn\n label={maximized ? \"Restore\" : \"Maximize\"}\n onClick={() => setMaximized(!maximized)}\n >\n {maximized ? (\n <Minimize2 className=\"size-3.5\" />\n ) : (\n <Maximize2 className=\"size-3.5\" />\n )}\n </IconBtn>\n <IconBtn label=\"Close\" onClick={() => setOpen(false)}>\n <X className=\"size-3.5\" />\n </IconBtn>\n </div>\n </div>\n\n <div className=\"min-h-0 flex-1 overflow-auto\">\n {active ? active.render() : null}\n </div>\n </div>\n );\n};\n\nconst IconBtn: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { label: string }\n> = ({ label, className, children, ...rest }) => (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n className={cn(\n \"grid size-5 place-items-center rounded-md text-foreground outline-none hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n);\n\nexport default DevTools;\n", "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n", "import React from \"react\";\nimport {\n ChevronRight,\n Pause,\n Play,\n Trash2,\n} from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\nimport { useDevToolsConfig, wsBaseFrom } from \"../../config\";\n\nconst MAX_ENTRIES = 5000;\nconst RECONNECT_MIN_MS = 500;\nconst RECONNECT_MAX_MS = 5000;\n\ntype StackFrame = { proc: string; file: string; line: number };\ntype Parsed = {\n ts?: string;\n level?: \"info\" | \"warn\" | \"error\" | string;\n msg?: string;\n stack?: StackFrame[];\n};\n\ntype WireLine = { raw: string; parsed?: boolean };\ntype WireFrame = { cursor: number; lines: WireLine[] };\n\ntype LogEntry = {\n id: number;\n raw: string;\n level: \"info\" | \"warn\" | \"error\" | \"plain\";\n parsed: Parsed | null;\n};\n\ntype LevelKey = \"info\" | \"warn\" | \"error\" | \"plain\";\n\nfunction resolveWsUrl(apiBaseUrl: string, path: string): string {\n return `${wsBaseFrom(apiBaseUrl)}${path}`;\n}\n\nfunction classifyLine(line: WireLine): LogEntry {\n if (line.parsed) {\n try {\n const p = JSON.parse(line.raw) as Parsed;\n const lvl =\n p.level === \"info\" || p.level === \"warn\" || p.level === \"error\"\n ? p.level\n : \"plain\";\n return {\n id: _nextId(),\n raw: line.raw,\n level: lvl,\n parsed: p,\n };\n } catch {\n // Fall through to plain.\n }\n }\n return { id: _nextId(), raw: line.raw, level: \"plain\", parsed: null };\n}\n\nlet _idCounter = 0;\nfunction _nextId(): number {\n _idCounter += 1;\n return _idCounter;\n}\n\nconst LEVEL_BADGE: Record<LevelKey, string> = {\n info: \"bg-blue-500/20 text-blue-300 border-blue-400/30\",\n warn: \"bg-yellow-500/20 text-yellow-300 border-yellow-400/30\",\n error: \"bg-red-500/20 text-red-300 border-red-400/30\",\n plain: \"bg-zinc-700/40 text-zinc-300 border-zinc-500/30\",\n};\n\nconst ConsoleTab: React.FC = () => {\n const { apiBaseUrl } = useDevToolsConfig();\n const [entries, setEntries] = React.useState<LogEntry[]>([]);\n const [paused, setPaused] = React.useState(false);\n const [filter, setFilter] = React.useState<Record<LevelKey, boolean>>({\n info: true,\n warn: true,\n error: true,\n plain: true,\n });\n const [expanded, setExpanded] = React.useState<Record<number, boolean>>({});\n\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const stickToBottomRef = React.useRef(true);\n const pausedRef = React.useRef(paused);\n pausedRef.current = paused;\n\n React.useEffect(() => {\n let alive = true;\n let socket: WebSocket | null = null;\n let backoff = RECONNECT_MIN_MS;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n const connect = () => {\n if (!alive) return;\n try {\n socket = new WebSocket(resolveWsUrl(apiBaseUrl, \"/_console/logs/ws\"));\n } catch {\n scheduleReconnect();\n return;\n }\n\n socket.onopen = () => {\n backoff = RECONNECT_MIN_MS;\n };\n socket.onmessage = (ev) => {\n if (pausedRef.current) return;\n if (typeof ev.data !== \"string\") return;\n let frame: WireFrame;\n try {\n frame = JSON.parse(ev.data) as WireFrame;\n } catch {\n return;\n }\n if (!frame.lines || frame.lines.length === 0) return;\n const batch = frame.lines.map(classifyLine);\n setEntries((prev) => {\n const next = prev.concat(batch);\n if (next.length > MAX_ENTRIES) {\n return next.slice(next.length - MAX_ENTRIES);\n }\n return next;\n });\n };\n socket.onerror = () => {\n // Let onclose handle reconnect.\n };\n socket.onclose = () => {\n socket = null;\n scheduleReconnect();\n };\n };\n\n const scheduleReconnect = () => {\n if (!alive) return;\n reconnectTimer = setTimeout(() => {\n backoff = Math.min(backoff * 2, RECONNECT_MAX_MS);\n connect();\n }, backoff);\n };\n\n connect();\n\n return () => {\n alive = false;\n if (reconnectTimer) clearTimeout(reconnectTimer);\n if (socket) socket.close();\n };\n }, []);\n\n // Auto-scroll: stick to bottom unless user scrolled up. We track intent\n // via a ref and apply a single trailing scrollTop per frame so a burst of\n // batches doesn't cause repeated DOM thrash.\n const handleScroll = React.useCallback(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const atBottom =\n el.scrollHeight - (el.scrollTop + el.clientHeight) < 8;\n stickToBottomRef.current = atBottom;\n }, []);\n\n const scrollRafRef = React.useRef(0);\n React.useEffect(() => {\n if (!stickToBottomRef.current) return;\n if (scrollRafRef.current) return;\n scrollRafRef.current = requestAnimationFrame(() => {\n scrollRafRef.current = 0;\n const el = scrollerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n });\n }, [entries]);\n React.useEffect(\n () => () => {\n if (scrollRafRef.current) cancelAnimationFrame(scrollRafRef.current);\n },\n [],\n );\n\n const visible = React.useMemo(\n () => entries.filter((e) => filter[e.level]),\n [entries, filter],\n );\n\n const toggleFilter = React.useCallback(\n (k: LevelKey) => setFilter((f) => ({ ...f, [k]: !f[k] })),\n [],\n );\n\n // One stable handler shared by every row. Each row tags itself via\n // `data-row-id`; click events bubble up to the <ul> where we read the id.\n // Avoids per-row closures that would break React.memo on LogRow.\n const onRowClick = React.useCallback((e: React.MouseEvent) => {\n let el: HTMLElement | null = e.target as HTMLElement;\n while (el && el !== e.currentTarget) {\n const id = el.dataset.rowId;\n if (id) {\n const n = Number(id);\n if (Number.isFinite(n)) {\n setExpanded((prev) => ({ ...prev, [n]: !prev[n] }));\n }\n return;\n }\n el = el.parentElement;\n }\n }, []);\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex h-7 shrink-0 items-center gap-1 border-b border-border bg-background px-1.5 select-none\">\n <ToolbarButton\n aria-label={paused ? \"Resume\" : \"Pause\"}\n onClick={() => setPaused((p) => !p)}\n >\n {paused ? (\n <Play className=\"size-3.5\" />\n ) : (\n <Pause className=\"size-3.5\" />\n )}\n </ToolbarButton>\n <ToolbarButton\n aria-label=\"Clear\"\n onClick={() => {\n setEntries([]);\n setExpanded({});\n }}\n >\n <Trash2 className=\"size-3.5\" />\n </ToolbarButton>\n <div className=\"mx-1 h-3 w-px bg-border/60\" />\n {([\"info\", \"warn\", \"error\", \"plain\"] as LevelKey[]).map((k) => (\n <FilterChip\n key={k}\n label={k}\n active={filter[k]}\n level={k}\n onClick={() => toggleFilter(k)}\n />\n ))}\n <div className=\"flex-1\" />\n <span className=\"text-[11px] text-muted-foreground tabular-nums\">\n {visible.length} / {entries.length}\n </span>\n </div>\n\n <div\n ref={scrollerRef}\n onScroll={handleScroll}\n style={{ overflowAnchor: \"none\" }}\n className=\"min-h-0 flex-1 overflow-auto font-mono text-[11px] leading-[1.45]\"\n >\n {visible.length === 0 ? (\n <div className=\"p-3 text-muted-foreground\">\n Waiting for console output\u2026\n </div>\n ) : (\n <ul onClick={onRowClick}>\n {visible.map((e) => (\n <LogRow\n key={e.id}\n entry={e}\n expanded={!!expanded[e.id]}\n />\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n};\n\nconst ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n> = ({ className, children, ...rest }) => (\n <button\n type=\"button\"\n className={cn(\n \"grid size-5 place-items-center rounded-md text-foreground outline-none hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n);\n\nconst FilterChip: React.FC<{\n label: string;\n level: LevelKey;\n active: boolean;\n onClick: () => void;\n}> = ({ label, level, active, onClick }) => (\n <button\n type=\"button\"\n onClick={onClick}\n data-active={active}\n className={cn(\n \"h-5 rounded-md border px-1.5 text-[11px] leading-none transition-colors\",\n \"data-[active=false]:opacity-40 data-[active=false]:hover:opacity-70\",\n LEVEL_BADGE[level],\n )}\n >\n {label}\n </button>\n);\n\ntype LogRowProps = {\n entry: LogEntry;\n expanded: boolean;\n};\n\nconst _LogRow: React.FC<LogRowProps> = ({ entry, expanded }) => {\n if (entry.level === \"plain\" || !entry.parsed) {\n return (\n <li\n className=\"border-b border-border/30 px-2 py-0.5 text-zinc-400 whitespace-pre-wrap break-words\"\n style={{ contain: \"content\" }}\n >\n {entry.raw}\n </li>\n );\n }\n\n const p = entry.parsed;\n const hasStack = Array.isArray(p.stack) && p.stack.length > 0;\n\n return (\n <li\n className=\"border-b border-border/30\"\n style={{ contain: \"content\" }}\n data-row-id={hasStack ? entry.id : undefined}\n >\n <div\n className={cn(\n \"flex items-start gap-1.5 px-2 py-0.5\",\n hasStack && \"cursor-pointer hover:bg-accent/30\",\n )}\n >\n {hasStack ? (\n <ChevronRight\n className={cn(\n \"mt-0.5 size-3 shrink-0 transition-transform\",\n expanded && \"rotate-90\",\n )}\n />\n ) : (\n <span className=\"inline-block size-3 shrink-0\" />\n )}\n <span\n className={cn(\n \"shrink-0 rounded border px-1 text-[10px] font-medium uppercase tracking-wide\",\n LEVEL_BADGE[entry.level],\n )}\n >\n {entry.level}\n </span>\n {p.ts && (\n <span className=\"shrink-0 text-zinc-500 tabular-nums\">\n {p.ts}\n </span>\n )}\n <span className=\"break-words text-zinc-200\">{p.msg ?? entry.raw}</span>\n </div>\n {hasStack && expanded && (\n <ul className=\"border-t border-border/20 bg-accent/10 px-7 py-1\">\n {p.stack!.map((f, i) => (\n <li\n key={i}\n className=\"text-zinc-400 whitespace-pre-wrap break-words\"\n >\n <span className=\"text-zinc-300\">{f.proc || \"<anon>\"}</span>\n <span className=\"text-zinc-500\"> @ </span>\n <span>{f.file}</span>\n <span className=\"text-zinc-500\">:</span>\n <span className=\"tabular-nums text-zinc-300\">{f.line}</span>\n </li>\n ))}\n </ul>\n )}\n </li>\n );\n};\n\n// Memoize per-row so a streaming batch (which replaces `entries` with a new\n// array reference) doesn't force every visible row to reconcile. Entry\n// objects are stable across batches once added, so reference-equality on\n// `entry` plus a primitive `expanded` is sufficient.\nconst LogRow = React.memo(\n _LogRow,\n (prev, next) =>\n prev.entry === next.entry && prev.expanded === next.expanded,\n);\n\nexport default ConsoleTab;\n", "import React from \"react\";\n\n// explicit goals:\n// * Detailed tracking of all requests coming in and out of the console.\n// * We need some sort of event listening on the api client / server side routes?\n\nconst NetworkTab: React.FC = () => {\n return (\n <div className=\"p-3 text-muted-foreground\">Network placeholder</div>\n );\n};\n\nexport default NetworkTab;\n", "import React from \"react\";\nimport { Network, Table2 } from \"lucide-react\";\nimport { useLiveBulkRegistry, type BulkEntity } from \"../../hooks/use-cartridge-info\";\nimport { BulkStreamProvider } from \"../../hooks/use-bulk-stream\";\nimport { useDevTools } from \"./devtools-context\";\nimport DataTable from \"./data-browser/data-table\";\nimport { DiagramView } from \"./entity-graph/diagram-tab\";\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n} from \"../ui/sheet\";\nimport { cn } from \"../../lib/utils\";\n\nconst DataTab: React.FC = () => {\n const { dataCart, setDataCart, dataEntity, setDataEntity } = useDevTools();\n const [detail, setDetail] = React.useState<Record<string, string> | null>(null);\n const [view, setView] = React.useState<\"table\" | \"diagram\">(\"table\");\n const { registry, carts, loading, error } = useLiveBulkRegistry();\n\n const activeCart = dataCart && registry[dataCart] ? dataCart : carts[0] ?? null;\n const entities: readonly BulkEntity[] = activeCart ? registry[activeCart] ?? [] : [];\n const activeEntity =\n entities.find((e) => e.name === dataEntity) ?? entities[0] ?? null;\n\n // First-time defaults / fixup when the persisted cart vanished.\n React.useEffect(() => {\n if (activeCart && activeCart !== dataCart) setDataCart(activeCart);\n if (activeEntity && activeEntity.name !== dataEntity) setDataEntity(activeEntity.name);\n }, [activeCart, activeEntity, dataCart, dataEntity, setDataCart, setDataEntity]);\n\n if (carts.length === 0) {\n let msg = \"No installed cartridges with entities.\";\n if (loading) msg = \"Loading cartridges\u2026\";\n else if (error) msg = `Failed to load cartridges: ${error}`;\n return <div className=\"p-3 text-[12px] text-muted-foreground\">{msg}</div>;\n }\n\n return (\n <BulkStreamProvider registry={registry}>\n <div className=\"flex h-full flex-col\">\n <div className=\"flex h-7 shrink-0 items-center gap-1 overflow-x-auto border-b border-border bg-background px-1 select-none\">\n <div className=\"flex shrink-0 items-center gap-0.5 pr-1\">\n <ViewBtn active={view === \"table\"} onClick={() => setView(\"table\")} label=\"Table\">\n <Table2 className=\"size-3\" />\n </ViewBtn>\n <ViewBtn active={view === \"diagram\"} onClick={() => setView(\"diagram\")} label=\"Graph\">\n <Network className=\"size-3\" />\n </ViewBtn>\n </div>\n {view === \"table\" ? (\n <>\n <div className=\"h-4 w-px shrink-0 bg-border\" />\n {carts.map((cart) => {\n const isActive = cart === activeCart;\n return (\n <button\n key={cart}\n type=\"button\"\n data-active={isActive}\n onClick={() => {\n setDataCart(cart);\n const first = registry[cart]?.[0];\n setDataEntity(first ? first.name : null);\n }}\n className={cn(\n \"h-5 shrink-0 rounded-full px-2.5 text-[11px] leading-none outline-none transition-colors\",\n \"border border-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:border-border data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n {cart}\n </button>\n );\n })}\n </>\n ) : null}\n </div>\n\n {view === \"diagram\" ? (\n <div className=\"min-h-0 flex-1\">\n <DiagramView />\n </div>\n ) : (\n <div className=\"flex min-h-0 flex-1\">\n <div className=\"flex w-44 shrink-0 flex-col overflow-y-auto border-r border-border bg-muted/10 py-1\">\n {entities.length === 0 ? (\n <div className=\"px-2 py-1 text-[11px] text-muted-foreground\">\n No entities\n </div>\n ) : (\n entities.map((e) => {\n const isActive = e.name === activeEntity?.name;\n return (\n <button\n key={e.name}\n type=\"button\"\n data-active={isActive}\n onClick={() => setDataEntity(e.name)}\n className={cn(\n \"h-6 shrink-0 text-left px-2 text-[12px] leading-none outline-none transition-colors\",\n \"text-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n {e.name}\n </button>\n );\n })\n )}\n </div>\n\n <div className=\"min-h-0 flex-1\">\n {activeEntity ? (\n <DataTable\n key={`${activeCart}:${activeEntity.name}`}\n cart={activeCart!}\n entity={activeEntity.name}\n searchFields={activeEntity.searchFields}\n onSelectRow={(row) => setDetail(row)}\n />\n ) : (\n <div className=\"p-3 text-[12px] text-muted-foreground\">\n Pick an entity.\n </div>\n )}\n </div>\n </div>\n )}\n\n <Sheet open={!!detail} onOpenChange={(o) => !o && setDetail(null)}>\n <SheetContent side=\"right\" className=\"w-[480px] sm:max-w-[480px]\">\n <SheetHeader>\n <SheetTitle className=\"text-[13px]\">\n {activeCart}.{activeEntity?.name}\n {detail?.id ? (\n <span className=\"ml-2 font-mono text-[11px] text-muted-foreground\">\n {detail.id}\n </span>\n ) : null}\n </SheetTitle>\n <SheetDescription className=\"text-[11px]\">\n Row detail\n </SheetDescription>\n </SheetHeader>\n <div className=\"min-h-0 flex-1 overflow-auto px-4 pb-4\">\n {detail ? (\n <table className=\"w-full text-[12px]\">\n <tbody>\n {Object.entries(detail).map(([k, v]) => (\n <tr key={k} className=\"border-b border-border/40 align-top\">\n <td className=\"w-32 py-1 pr-2 font-mono text-[11px] text-muted-foreground\">\n {k}\n </td>\n <td className=\"break-all py-1 font-mono\">{v || <span className=\"text-muted-foreground/60\">\u2205</span>}</td>\n </tr>\n ))}\n </tbody>\n </table>\n ) : null}\n </div>\n </SheetContent>\n </Sheet>\n </div>\n </BulkStreamProvider>\n );\n};\n\nconst ViewBtn: React.FC<{\n active: boolean;\n onClick: () => void;\n label: string;\n children: React.ReactNode;\n}> = ({ active, onClick, label, children }) => (\n <button\n type=\"button\"\n data-active={active}\n onClick={onClick}\n title={label}\n className={cn(\n \"inline-flex h-5 shrink-0 items-center gap-1 rounded-md px-1.5 text-[11px] leading-none outline-none transition-colors\",\n \"text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n {children}\n {label}\n </button>\n);\n\nexport default DataTab;\n", "import { useEffect, useState } from \"react\";\nimport { useDevToolsConfig } from \"../config\";\n\n// Live cartridge/entity registry for the Data tab. Instead of the build-time\n// `BULK_REGISTRY` (every cart in the repo, generated by `nbt generate`), we\n// read the daemon's `/_console/contracts` \u2014 which only lists *running*\n// cartridges and carries each entity's `searchFields`. Bulk WS routes are\n// derived live (`/_ws/bulk/<cart>/<entity-lower>`) and fed straight into\n// useBulkStream. So the tab reflects what is actually installed right now.\n\nexport type BulkEntity = {\n name: string;\n route: string;\n searchFields: readonly string[];\n};\nexport type BulkRegistry = Record<string, BulkEntity[]>;\n\ntype Contract = {\n cartridge?: string;\n owns?: Record<string, { searchFields?: string[] }>;\n};\n\nfunction buildRegistry(contracts: Contract[]): BulkRegistry {\n const reg: BulkRegistry = {};\n for (const c of contracts) {\n const cart = c.cartridge;\n if (!cart || !c.owns) continue;\n const entities: BulkEntity[] = [];\n for (const [name, ent] of Object.entries(c.owns)) {\n const sf = Array.isArray(ent?.searchFields) ? ent.searchFields : [];\n entities.push({\n name,\n route: `/_ws/bulk/${cart}/${name.toLowerCase()}`,\n searchFields: sf,\n });\n }\n if (entities.length > 0) reg[cart] = entities;\n }\n return reg;\n}\n\nexport type LiveRegistryState = {\n registry: BulkRegistry;\n carts: string[];\n loading: boolean;\n error: string | null;\n};\n\nexport function useLiveBulkRegistry(): LiveRegistryState {\n const { apiBaseUrl } = useDevToolsConfig();\n const [registry, setRegistry] = useState<BulkRegistry>({});\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n (async () => {\n try {\n const r = await fetch(`${apiBaseUrl}/_console/contracts`, {\n signal: ac.signal,\n credentials: \"include\",\n });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const data = (await r.json()) as Contract[];\n if (!Array.isArray(data)) throw new Error(\"malformed contracts response\");\n if (cancelled) return;\n setRegistry(buildRegistry(data));\n } catch (e) {\n if (cancelled || (e as { name?: string }).name === \"AbortError\") return;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n ac.abort();\n };\n }, []);\n\n const carts = Object.keys(registry).sort();\n return { registry, carts, loading, error };\n}\n", "import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BulkDataStore } from \"../components/devtools/data-browser/data-store\";\nimport {\n getFrameType,\n getFrameSid,\n parseSchema,\n parseDataChunk,\n parseDelta,\n parseError,\n encodeSchemaCmd,\n encodeStreamCmd,\n encodeSearchCmd,\n encodeClearSearchCmd,\n} from \"../components/devtools/data-browser/bulk-decoder\";\nimport {\n FRAME_SCHEMA,\n FRAME_DATA,\n FRAME_DATA_END,\n FRAME_DELTA_INS,\n FRAME_DELTA_UPD,\n FRAME_DELTA_DEL,\n FRAME_SEARCH_RESULT,\n FRAME_SEARCH_END,\n FRAME_ERROR,\n type ColumnDef,\n} from \"../generated/bulk-protocol\";\nimport type { BulkRegistry } from \"./use-cartridge-info\";\nimport { useDevToolsConfig, wsBaseFrom } from \"../config\";\n\n// One per-entity table view, demultiplexed off the shared socket by sid. The\n// object is stable across renders and mutated in place; consumers re-render via\n// the listener set (and the cheap per-chunk onRender for virtualization).\ntype View = {\n sid: number;\n cart: string;\n entity: string;\n store: BulkDataStore;\n columns: ColumnDef[];\n totalRows: number;\n loadedRows: number;\n streaming: boolean;\n error: string | null;\n streamRequested: boolean; // sent a `sub` (full stream) at least once\n searchStreaming: boolean;\n onRender: (() => void) | null;\n listeners: Set<() => void>;\n};\n\nexport type BulkSubscription = {\n store: BulkDataStore;\n connected: boolean;\n streaming: boolean;\n error: string | null;\n columns: ColumnDef[];\n totalRows: number;\n loadedRows: number;\n search: (q: string) => void;\n clearSearch: () => void;\n setOnRender: (fn: (() => void) | null) => void;\n};\n\ntype Ctx = {\n getView: (cart: string, entity: string) => View;\n ensureStreamed: (view: View) => void;\n search: (view: View, query: string) => void;\n clearSearch: (view: View) => void;\n subscribe: (view: View, cb: () => void) => () => void;\n connected: boolean;\n error: string | null;\n};\n\nconst BulkStreamContext = createContext<Ctx | null>(null);\n\nfunction base64UrlEncode(value: string): string {\n if (typeof btoa === \"function\") {\n return btoa(value).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n }\n throw new Error(\"No base64 encoder available for bulk WS auth\");\n}\n\nfunction bulkAuthProtocols(token: string): string[] {\n return [\"nimbit-bulk\", `auth-${base64UrlEncode(token)}`];\n}\n\nlet _wsTokenCache: { token: string; at: number } | null = null;\nconst WS_TOKEN_TTL_MS = 60_000;\n\n// The console doesn't mint /auth/ws-token (that's the portal BFF); the inspector\n// talks to the daemon directly, so we read the session bearer from\n// auth.Session.current and forward it in the WS subprotocol.\nasync function fetchWsToken(\n signal: AbortSignal,\n apiBaseUrl: string,\n): Promise<string | null> {\n const now = Date.now();\n if (_wsTokenCache && now - _wsTokenCache.at < WS_TOKEN_TTL_MS) {\n return _wsTokenCache.token;\n }\n const r = await fetch(`${apiBaseUrl}/api/auth/session/current`, {\n method: \"POST\",\n signal,\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n });\n if (!r.ok) return null;\n const j = (await r.json()) as { session?: { token?: string } };\n const token = j.session?.token;\n if (!token) return null;\n _wsTokenCache = { token, at: now };\n return token;\n}\n\nfunction invalidateWsToken() {\n _wsTokenCache = null;\n}\n\nfunction notify(view: View) {\n view.listeners.forEach((cb) => cb());\n}\n\ntype Props = { registry: BulkRegistry; children: React.ReactNode };\n\nexport function BulkStreamProvider({ registry, children }: Props): React.ReactElement {\n const { apiBaseUrl } = useDevToolsConfig();\n const wsRef = useRef<WebSocket | null>(null);\n const sendQueueRef = useRef<string[]>([]);\n const sidCounterRef = useRef(1);\n const viewsBySidRef = useRef<Map<number, View>>(new Map());\n const viewsByKeyRef = useRef<Map<string, View>>(new Map());\n const preloadedRef = useRef(false);\n\n const [connected, setConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const sendCmd = (cmd: string) => {\n const ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN) ws.send(cmd);\n else sendQueueRef.current.push(cmd);\n };\n\n const flushQueue = () => {\n const ws = wsRef.current;\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n const q = sendQueueRef.current;\n sendQueueRef.current = [];\n for (const cmd of q) ws.send(cmd);\n };\n\n const getView = (cart: string, entity: string): View => {\n // The server registers entity ops under \"<cart>/<entity-lower>\" (route\n // path casing), so normalize here \u2014 preload and subscription then share one\n // view per entity regardless of the caller's casing.\n const entLower = entity.toLowerCase();\n const key = `${cart}/${entLower}`;\n const existing = viewsByKeyRef.current.get(key);\n if (existing) return existing;\n const sid = sidCounterRef.current++;\n const view: View = {\n sid,\n cart,\n entity: entLower,\n store: new BulkDataStore(),\n columns: [],\n totalRows: 0,\n loadedRows: 0,\n streaming: false,\n error: null,\n streamRequested: false,\n searchStreaming: false,\n onRender: null,\n listeners: new Set(),\n };\n viewsByKeyRef.current.set(key, view);\n viewsBySidRef.current.set(sid, view);\n return view;\n };\n\n const ensureStreamed = (view: View) => {\n if (view.streamRequested) return;\n view.streamRequested = true;\n sendCmd(encodeStreamCmd(view.sid, view.cart, view.entity));\n };\n\n const handleMessage = (ev: MessageEvent) => {\n const buf = ev.data as ArrayBuffer;\n const sid = getFrameSid(buf);\n const view = viewsBySidRef.current.get(sid);\n if (!view) return;\n const ft = getFrameType(buf);\n const store = view.store;\n switch (ft) {\n case FRAME_SCHEMA: {\n const schema = parseSchema(buf);\n if (view.searchStreaming) store.enterSearch(schema);\n else store.applySchema(schema);\n view.columns = schema.columns;\n view.totalRows = schema.totalRows;\n view.loadedRows = 0;\n view.streaming = true;\n notify(view);\n break;\n }\n case FRAME_DATA:\n case FRAME_SEARCH_RESULT: {\n const rows = parseDataChunk(buf, store.columns);\n store.appendChunk(rows);\n view.loadedRows = store.getRowCount();\n view.onRender?.();\n break;\n }\n case FRAME_DATA_END:\n view.streaming = false;\n notify(view);\n break;\n case FRAME_SEARCH_END:\n view.searchStreaming = false;\n view.streaming = false;\n notify(view);\n break;\n case FRAME_DELTA_INS:\n case FRAME_DELTA_UPD:\n case FRAME_DELTA_DEL: {\n const delta = parseDelta(buf, store.columns);\n store.applyDelta(delta);\n view.totalRows = store.totalRows;\n view.loadedRows = store.getRowCount();\n view.onRender?.();\n notify(view);\n break;\n }\n case FRAME_ERROR:\n view.error = parseError(buf);\n view.streaming = false;\n notify(view);\n break;\n }\n };\n\n // Open one shared socket for the provider's lifetime.\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n let opened = false;\n let ws: WebSocket | null = null;\n setError(null);\n\n (async () => {\n let token: string | null = null;\n try {\n token = await fetchWsToken(ac.signal, apiBaseUrl);\n } catch {\n if (!cancelled) setError(\"Failed to obtain WS session token\");\n return;\n }\n if (cancelled) return;\n if (!token) {\n setError(\"No session \u2014 sign in to view data\");\n return;\n }\n ws = new WebSocket(`${wsBaseFrom(apiBaseUrl)}/_ws/bulk`, bulkAuthProtocols(token));\n ws.binaryType = \"arraybuffer\";\n wsRef.current = ws;\n ws.onopen = () => {\n if (cancelled || wsRef.current !== ws) return;\n opened = true;\n setConnected(true);\n setError(null);\n flushQueue();\n };\n ws.onmessage = handleMessage;\n ws.onerror = () => {};\n ws.onclose = () => {\n if (cancelled || wsRef.current !== ws) return;\n setConnected(false);\n wsRef.current = null;\n if (!opened) {\n invalidateWsToken();\n setError(\"WebSocket connection closed\");\n }\n };\n })();\n\n return () => {\n cancelled = true;\n ac.abort();\n if (ws) {\n ws.onopen = ws.onmessage = ws.onerror = ws.onclose = null;\n try {\n ws.close();\n } catch {}\n if (wsRef.current === ws) wsRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n // Preload every entity's SCHEMA once connected + registry known, so columns\n // are ready before a tab is opened (no \"Waiting for schema\u2026\" flicker). Rows\n // stream lazily on first open via ensureStreamed.\n useEffect(() => {\n if (!connected) return;\n if (preloadedRef.current) return;\n const keys = Object.keys(registry);\n if (keys.length === 0) return;\n preloadedRef.current = true;\n for (const cart of keys) {\n for (const ent of registry[cart] ?? []) {\n const view = getView(cart, ent.name);\n sendCmd(encodeSchemaCmd(view.sid, view.cart, view.entity));\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [connected, registry]);\n\n const search = (view: View, query: string) => {\n if (!query) {\n view.store.exitSearch();\n view.totalRows = view.store.totalRows;\n view.loadedRows = view.store.getRowCount();\n sendCmd(encodeClearSearchCmd(view.sid));\n notify(view);\n view.onRender?.();\n return;\n }\n view.searchStreaming = true;\n sendCmd(encodeSearchCmd(view.sid, query));\n };\n\n const clearSearch = (view: View) => {\n view.store.exitSearch();\n view.totalRows = view.store.totalRows;\n view.loadedRows = view.store.getRowCount();\n sendCmd(encodeClearSearchCmd(view.sid));\n notify(view);\n view.onRender?.();\n };\n\n const subscribe = (view: View, cb: () => void) => {\n view.listeners.add(cb);\n return () => {\n view.listeners.delete(cb);\n };\n };\n\n const ctx: Ctx = {\n getView,\n ensureStreamed,\n search,\n clearSearch,\n subscribe,\n connected,\n error,\n };\n\n return React.createElement(BulkStreamContext.Provider, { value: ctx }, children);\n}\n\n// Row counts for every entity in the registry, sourced from the SCHEMA preload\n// the provider already runs on connect (FRAME_SCHEMA carries totalRows). No row\n// streaming is triggered \u2014 we subscribe to each view but never ensureStreamed.\n// Keyed by the graph id `cart:Entity` (original casing) for the Diagram tab.\nexport function useBulkRowCounts(registry: BulkRegistry): Record<string, number> {\n const ctx = useContext(BulkStreamContext);\n if (!ctx) throw new Error(\"useBulkRowCounts must be used within BulkStreamProvider\");\n const [, force] = useState(0);\n\n const pairs: Array<{ id: string; view: View }> = [];\n for (const cart of Object.keys(registry)) {\n for (const ent of registry[cart] ?? []) {\n pairs.push({ id: `${cart}:${ent.name}`, view: ctx.getView(cart, ent.name) });\n }\n }\n\n const key = pairs.map((p) => p.id).join(\"|\");\n useEffect(() => {\n const unsubs = pairs.map((p) => ctx.subscribe(p.view, () => force((n) => n + 1)));\n return () => unsubs.forEach((u) => u());\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key]);\n\n const counts: Record<string, number> = {};\n for (const p of pairs) counts[p.id] = p.view.totalRows;\n return counts;\n}\n\n// Keyed to a single entity. The view (schema + rows + deltas) is shared and\n// cached in the provider, so switching tabs is instant once visited.\nexport function useBulkSubscription(cart: string, entity: string): BulkSubscription {\n const ctx = useContext(BulkStreamContext);\n if (!ctx) throw new Error(\"useBulkSubscription must be used within BulkStreamProvider\");\n\n const view = ctx.getView(cart, entity);\n const [, force] = useState(0);\n\n useEffect(() => {\n const unsub = ctx.subscribe(view, () => force((n) => n + 1));\n ctx.ensureStreamed(view);\n return unsub;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [view]);\n\n return {\n store: view.store,\n connected: ctx.connected,\n streaming: view.streaming,\n error: view.error ?? ctx.error,\n columns: view.columns,\n totalRows: view.totalRows,\n loadedRows: view.loadedRows,\n search: (q: string) => ctx.search(view, q),\n clearSearch: () => ctx.clearSearch(view),\n setOnRender: (fn) => {\n view.onRender = fn;\n },\n };\n}\n", "// AUTO-GENERATED by inspector/scripts/gen-contracts.mjs \u2014 do not edit by hand.\n// Source: modules/nbt/codegen_ws_bulk.jai (WS_FRAME_* + ws_type_byte_for).\n\n// Frame types (first byte of each WS binary message).\nexport const FRAME_SCHEMA = 0x01;\nexport const FRAME_DATA = 0x02;\nexport const FRAME_DATA_END = 0x03;\nexport const FRAME_DELTA_INS = 0x04;\nexport const FRAME_DELTA_UPD = 0x05;\nexport const FRAME_DELTA_DEL = 0x06;\nexport const FRAME_SEARCH_RESULT = 0x07;\nexport const FRAME_SEARCH_END = 0x08;\nexport const FRAME_ERROR = 0xff;\n\n// Column type bytes (schema frame, per column).\nexport const TYPE_U8 = 0x01;\nexport const TYPE_U16 = 0x02;\nexport const TYPE_U32 = 0x03;\nexport const TYPE_U64 = 0x04;\nexport const TYPE_S8 = 0x05;\nexport const TYPE_S16 = 0x06;\nexport const TYPE_S32 = 0x07;\nexport const TYPE_S64 = 0x08;\nexport const TYPE_BOOL = 0x09;\nexport const TYPE_FLOAT32 = 0x0a;\nexport const TYPE_FLOAT64 = 0x0b;\nexport const TYPE_STRING = 0x0c;\nexport const TYPE_DATETIME = 0x0d;\nexport const TYPE_DOCUMENT = 0x0e;\n\nexport type ColumnDef = {\n name: string;\n type: number;\n fixedSize: number; // 0 for variable-width (string, document)\n};\n\nexport type SchemaFrame = {\n totalRows: number;\n columns: ColumnDef[];\n};\n\nexport type DeltaFrame = {\n op: number;\n rowData?: string[];\n id?: string; // DELETE carries the row id as a len-prefixed string\n};\n\nexport function fixedSizeForType(type: number): number {\n switch (type) {\n case TYPE_U8: return 1;\n case TYPE_U16: return 2;\n case TYPE_U32: return 4;\n case TYPE_U64: return 8;\n case TYPE_S8: return 1;\n case TYPE_S16: return 2;\n case TYPE_S32: return 4;\n case TYPE_S64: return 8;\n case TYPE_BOOL: return 1;\n case TYPE_FLOAT32: return 4;\n case TYPE_FLOAT64: return 8;\n case TYPE_STRING: return 0;\n case TYPE_DATETIME: return 8;\n case TYPE_DOCUMENT: return 0;\n default: return 0;\n }\n}\n", "import {\n FRAME_DELTA_INS,\n FRAME_DELTA_UPD,\n FRAME_DELTA_DEL,\n type ColumnDef,\n type SchemaFrame,\n type DeltaFrame,\n} from \"../../../generated/bulk-protocol\";\n\nexport class BulkDataStore {\n columns: ColumnDef[] = [];\n rows: string[][] = [];\n totalRows = 0;\n searchActive = false;\n\n private _fullRows: string[][] = [];\n private _fullTotalRows = 0;\n private _idColIndex = -1;\n\n applySchema(schema: SchemaFrame): void {\n this.columns = schema.columns;\n this.totalRows = schema.totalRows;\n this.rows = [];\n this._idColIndex = schema.columns.findIndex((c) => c.name === \"id\");\n }\n\n appendChunk(chunk: string[][]): void {\n for (let i = 0; i < chunk.length; i++) this.rows.push(chunk[i]!);\n }\n\n applyDelta(delta: DeltaFrame): void {\n const target = this.searchActive ? this._fullRows : this.rows;\n if (delta.op === FRAME_DELTA_INS && delta.rowData) {\n target.push(delta.rowData);\n if (this.searchActive) this._fullTotalRows++;\n else this.totalRows++;\n return;\n }\n if (delta.op === FRAME_DELTA_UPD && delta.rowData) {\n const idx = this._findRowById(target, delta.rowData);\n if (idx >= 0) target[idx] = delta.rowData;\n return;\n }\n if (delta.op === FRAME_DELTA_DEL && delta.id !== undefined) {\n const idStr = String(delta.id);\n const idx = this._findRowByIdStr(target, idStr);\n if (idx >= 0) {\n target.splice(idx, 1);\n if (this.searchActive) this._fullTotalRows--;\n else this.totalRows--;\n }\n return;\n }\n }\n\n enterSearch(schema: SchemaFrame): void {\n if (!this.searchActive) {\n this._fullRows = this.rows;\n this._fullTotalRows = this.totalRows;\n }\n this.searchActive = true;\n this.columns = schema.columns;\n this.totalRows = schema.totalRows;\n this.rows = [];\n }\n\n exitSearch(): void {\n if (!this.searchActive) return;\n this.rows = this._fullRows;\n this.totalRows = this._fullTotalRows;\n this._fullRows = [];\n this._fullTotalRows = 0;\n this.searchActive = false;\n }\n\n getRowCount(): number {\n return this.rows.length;\n }\n\n private _findRowById(rows: string[][], rowData: string[]): number {\n if (this._idColIndex < 0) return -1;\n const id = rowData[this._idColIndex];\n for (let i = 0; i < rows.length; i++) {\n if (rows[i]![this._idColIndex] === id) return i;\n }\n return -1;\n }\n\n private _findRowByIdStr(rows: string[][], idStr: string): number {\n if (this._idColIndex < 0) return -1;\n for (let i = 0; i < rows.length; i++) {\n if (rows[i]![this._idColIndex] === idStr) return i;\n }\n return -1;\n }\n}\n", "// Wire-format decoders + client\u2192server command encoders for the multiplexed\n// bulk WS protocol. Frame opcodes and column-type bytes live in\n// @/generated/bulk-protocol (autogen'd from modules/nbt/codegen_ws_bulk.jai).\n//\n// Every server\u2192client binary frame is [op:u8][sid:u16 LE][payload]. The sid is\n// the client-chosen subscription id; one socket multiplexes many entities, and\n// the provider routes each frame to the matching view by sid (getFrameSid).\n// Only the parse/encode bodies are hand-maintained here.\n\nimport {\n FRAME_SCHEMA,\n FRAME_DATA,\n FRAME_SEARCH_RESULT,\n FRAME_DELTA_DEL,\n FRAME_DELTA_INS,\n FRAME_DELTA_UPD,\n TYPE_U8,\n TYPE_S8,\n TYPE_BOOL,\n TYPE_U16,\n TYPE_S16,\n TYPE_U32,\n TYPE_S32,\n TYPE_FLOAT32,\n TYPE_U64,\n TYPE_S64,\n TYPE_FLOAT64,\n TYPE_DATETIME,\n TYPE_STRING,\n TYPE_DOCUMENT,\n fixedSizeForType,\n type ColumnDef,\n type SchemaFrame,\n type DeltaFrame,\n} from \"../../../generated/bulk-protocol\";\n\nconst textDecoder = new TextDecoder();\n\n// Bytes between the op byte and the frame payload: the u16 LE subscription id.\nconst SID_BYTES = 2;\n// Offset of the payload in every server\u2192client frame (op + sid).\nconst HEAD = 1 + SID_BYTES;\n\nfunction epochToDate(epoch: number): Date {\n const abs = Math.abs(epoch);\n if (abs < 10_000_000_000) return new Date(epoch * 1000);\n if (abs < 10_000_000_000_000) return new Date(epoch);\n if (abs < 10_000_000_000_000_000) return new Date(epoch / 1000);\n return new Date(epoch / 1_000_000);\n}\n\nfunction formatCellValue(view: DataView, offset: number, col: ColumnDef): [string, number] {\n switch (col.type) {\n case TYPE_U8: return [String(view.getUint8(offset)), 1];\n case TYPE_S8: return [String(view.getInt8(offset)), 1];\n case TYPE_BOOL: return [view.getUint8(offset) ? \"true\" : \"false\", 1];\n case TYPE_U16: return [String(view.getUint16(offset, true)), 2];\n case TYPE_S16: return [String(view.getInt16(offset, true)), 2];\n case TYPE_U32: return [String(view.getUint32(offset, true)), 4];\n case TYPE_S32: return [String(view.getInt32(offset, true)), 4];\n case TYPE_FLOAT32: return [String(view.getFloat32(offset, true)), 4];\n case TYPE_U64: return [String(view.getBigUint64(offset, true)), 8];\n case TYPE_S64: return [String(view.getBigInt64(offset, true)), 8];\n case TYPE_FLOAT64: return [String(view.getFloat64(offset, true)), 8];\n case TYPE_DATETIME: {\n const epoch = Number(view.getBigInt64(offset, true));\n if (epoch === 0) return [\"\", 8];\n return [epochToDate(epoch).toISOString(), 8];\n }\n case TYPE_STRING:\n case TYPE_DOCUMENT: {\n const len = view.getUint32(offset, true);\n const bytes = new Uint8Array(view.buffer, view.byteOffset + offset + 4, len);\n return [textDecoder.decode(bytes), 4 + len];\n }\n default:\n return [\"\", 0];\n }\n}\n\nexport function getFrameType(buf: ArrayBuffer): number {\n return new DataView(buf).getUint8(0);\n}\n\n// The subscription id this frame belongs to (u16 LE right after the op byte).\nexport function getFrameSid(buf: ArrayBuffer): number {\n return new DataView(buf).getUint16(1, true);\n}\n\nexport function parseSchema(buf: ArrayBuffer): SchemaFrame {\n const view = new DataView(buf);\n let offset = 0;\n const frameType = view.getUint8(offset); offset += 1;\n if (frameType !== FRAME_SCHEMA) {\n throw new Error(`Expected SCHEMA frame (0x01), got 0x${frameType.toString(16)}`);\n }\n offset += SID_BYTES;\n const totalRows = view.getUint32(offset, true); offset += 4;\n const columnCount = view.getUint16(offset, true); offset += 2;\n const columns: ColumnDef[] = [];\n for (let i = 0; i < columnCount; i++) {\n const type = view.getUint8(offset); offset += 1;\n const nameLen = view.getUint16(offset, true); offset += 2;\n const nameBytes = new Uint8Array(buf, offset, nameLen);\n const name = textDecoder.decode(nameBytes);\n offset += nameLen;\n columns.push({ name, type, fixedSize: fixedSizeForType(type) });\n }\n return { totalRows, columns };\n}\n\nexport function parseDataChunk(buf: ArrayBuffer, columns: ColumnDef[]): string[][] {\n const view = new DataView(buf);\n let offset = 0;\n const frameType = view.getUint8(offset); offset += 1;\n if (frameType !== FRAME_DATA && frameType !== FRAME_SEARCH_RESULT) {\n throw new Error(`Expected DATA/SEARCH_RESULT frame, got 0x${frameType.toString(16)}`);\n }\n offset += SID_BYTES;\n const rowCount = view.getUint16(offset, true); offset += 2;\n const rows: string[][] = [];\n for (let r = 0; r < rowCount; r++) {\n const row: string[] = [];\n for (let c = 0; c < columns.length; c++) {\n const [value, bytesRead] = formatCellValue(view, offset, columns[c]!);\n row.push(value);\n offset += bytesRead;\n }\n rows.push(row);\n }\n return rows;\n}\n\nexport function parseDelta(buf: ArrayBuffer, columns: ColumnDef[]): DeltaFrame {\n const view = new DataView(buf);\n let offset = 0;\n const op = view.getUint8(offset); offset += 1;\n offset += SID_BYTES;\n if (op === FRAME_DELTA_DEL) {\n // [id_len:u16 LE][id_bytes] \u2014 the row id is a string (ULID), not an int.\n const len = view.getUint16(offset, true); offset += 2;\n const bytes = new Uint8Array(buf, offset, len);\n return { op, id: textDecoder.decode(bytes) };\n }\n if (op === FRAME_DELTA_INS || op === FRAME_DELTA_UPD) {\n const rowData: string[] = [];\n for (let c = 0; c < columns.length; c++) {\n const [value, bytesRead] = formatCellValue(view, offset, columns[c]!);\n rowData.push(value);\n offset += bytesRead;\n }\n return { op, rowData };\n }\n throw new Error(`Unknown delta op 0x${op.toString(16)}`);\n}\n\nexport function parseError(buf: ArrayBuffer): string {\n const view = new DataView(buf);\n // [0xFF][sid:u16][msg_len:u16 LE][msg_bytes]\n const len = view.getUint16(HEAD, true);\n const bytes = new Uint8Array(buf, HEAD + 2, len);\n return textDecoder.decode(bytes);\n}\n\n// --- client \u2192 server command encoders ---\n// Each command carries the subscription id; sub/schema also name the target.\n\nexport function encodeSchemaCmd(sid: number, cart: string, entity: string): string {\n return JSON.stringify({ cmd: \"schema\", sid, cart, entity });\n}\n\nexport function encodeStreamCmd(\n sid: number,\n cart: string,\n entity: string,\n opts?: { sort?: string; sort_desc?: boolean; filters?: Record<string, string> },\n): string {\n return JSON.stringify({ cmd: \"sub\", sid, cart, entity, ...opts });\n}\n\nexport function encodeSearchCmd(sid: number, query: string): string {\n return JSON.stringify({ cmd: \"search\", sid, q: query });\n}\n\nexport function encodeUnsubCmd(sid: number): string {\n return JSON.stringify({ cmd: \"unsub\", sid });\n}\n\nexport function encodeClearSearchCmd(sid: number): string {\n // Server-side no-op (the client restores the cached full set); sent for symmetry.\n return JSON.stringify({ cmd: \"clear_search\", sid });\n}\n", "import React from \"react\";\nimport { useBulkSubscription } from \"../../../hooks/use-bulk-stream\";\nimport { cn } from \"../../../lib/utils\";\n\nconst ROW_H = 22;\nconst OVERSCAN = 6;\nconst MIN_COL_W = 80;\n\ntype DataTableProps = {\n cart: string;\n entity: string;\n searchFields: readonly string[];\n onSelectRow: (rowJson: Record<string, string>) => void;\n};\n\nfunction colWidth(name: string): number {\n if (name === \"id\") return 220;\n if (name === \"createdAt\" || name === \"updatedAt\") return 180;\n if (name === \"email\" || name === \"phone\") return 180;\n if (name.endsWith(\"At\")) return 180;\n return Math.max(MIN_COL_W, Math.min(240, name.length * 9 + 24));\n}\n\nconst DataTable: React.FC<DataTableProps> = ({ cart, entity, searchFields, onSelectRow }) => {\n const stream = useBulkSubscription(cart, entity);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const [viewportH, setViewportH] = React.useState(0);\n const [query, setQuery] = React.useState(\"\");\n // Bump on every chunk arrival without re-rendering each FRAME_DATA.\n const [tick, setTick] = React.useState(0);\n\n React.useEffect(() => {\n stream.setOnRender(() => setTick((n) => n + 1));\n return () => stream.setOnRender(null);\n }, [stream]);\n\n React.useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => setViewportH(el.clientHeight));\n ro.observe(el);\n setViewportH(el.clientHeight);\n return () => ro.disconnect();\n }, []);\n\n const rows = stream.store.rows;\n const columns = stream.columns;\n\n const totalH = rows.length * ROW_H;\n const start = Math.max(0, Math.floor(scrollTop / ROW_H) - OVERSCAN);\n const visibleCount = Math.max(0, Math.ceil(viewportH / ROW_H) + OVERSCAN * 2);\n const end = Math.min(rows.length, start + visibleCount);\n\n const onSearchKey = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n stream.search(query.trim());\n } else if (e.key === \"Escape\") {\n setQuery(\"\");\n stream.clearSearch();\n }\n };\n\n const handleRowClick = (rowIdx: number) => {\n const r = rows[rowIdx];\n if (!r) return;\n const out: Record<string, string> = {};\n for (let i = 0; i < columns.length; i++) out[columns[i]!.name] = r[i] ?? \"\";\n onSelectRow(out);\n };\n\n const searchDisabled = searchFields.length === 0;\n const totalColW = columns.reduce((s, c) => s + colWidth(c.name), 0);\n\n return (\n <div className=\"flex h-full flex-col bg-background\">\n <div className=\"flex h-7 shrink-0 items-center gap-2 border-b border-border px-2\">\n <input\n type=\"text\"\n value={query}\n disabled={searchDisabled}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onSearchKey}\n placeholder={\n searchDisabled\n ? \"Search disabled (no @@search declared)\"\n : `Search ${searchFields.join(\", \")} \u23CE`\n }\n className={cn(\n \"h-5 flex-1 rounded-sm border border-border bg-background px-2 text-[12px] outline-none\",\n \"placeholder:text-muted-foreground/70 focus:border-accent-foreground/30\",\n searchDisabled && \"opacity-50 cursor-not-allowed\",\n )}\n />\n <div className=\"shrink-0 text-[11px] text-muted-foreground tabular-nums\">\n {stream.error ? (\n <span className=\"text-red-400\">{stream.error}</span>\n ) : !stream.connected ? (\n <span>connecting\u2026</span>\n ) : (\n <span>\n {stream.loadedRows.toLocaleString()} / {stream.totalRows.toLocaleString()} rows\n {stream.streaming ? \" \u00B7 streaming\" : \"\"}\n </span>\n )}\n </div>\n </div>\n\n {columns.length === 0 ? (\n <div className=\"flex flex-1 items-center justify-center text-[12px] text-muted-foreground\">\n {stream.error ? stream.error : \"Waiting for schema\u2026\"}\n </div>\n ) : (\n <div className=\"flex min-h-0 flex-1 flex-col\">\n <div className=\"overflow-hidden border-b border-border bg-muted/30\">\n <div\n className=\"flex h-6 select-none text-[11px] uppercase tracking-wider text-muted-foreground\"\n style={{\n width: totalColW,\n transform: `translateX(${-(scrollerRef.current?.scrollLeft ?? 0)}px)`,\n }}\n >\n {columns.map((c) => (\n <div\n key={c.name}\n style={{ width: colWidth(c.name) }}\n className=\"flex items-center overflow-hidden border-r border-border px-2\"\n >\n <span className=\"truncate\">{c.name}</span>\n </div>\n ))}\n </div>\n </div>\n\n <div\n ref={scrollerRef}\n onScroll={(e) => {\n setScrollTop((e.target as HTMLDivElement).scrollTop);\n // header translate uses scrollLeft \u2192 re-render\n setTick((n) => n + 1);\n }}\n className=\"relative min-h-0 flex-1 overflow-auto font-mono\"\n >\n <div style={{ height: totalH, width: totalColW, position: \"relative\" }}>\n {rows.slice(start, end).map((row, i) => {\n const rowIdx = start + i;\n return (\n <div\n key={rowIdx}\n onClick={() => handleRowClick(rowIdx)}\n style={{\n top: rowIdx * ROW_H,\n height: ROW_H,\n width: totalColW,\n }}\n className={cn(\n \"absolute left-0 flex cursor-pointer text-[12px] leading-none\",\n rowIdx % 2 === 0 ? \"bg-background\" : \"bg-muted/20\",\n \"hover:bg-accent hover:text-accent-foreground\",\n )}\n >\n {columns.map((c, ci) => (\n <div\n key={c.name}\n style={{ width: colWidth(c.name) }}\n className=\"flex items-center overflow-hidden border-r border-border/60 px-2\"\n title={row[ci]}\n >\n <span className=\"truncate\">{row[ci]}</span>\n </div>\n ))}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n )}\n {/* Force re-read of refs on tick; tick is intentional dep of layout reads above. */}\n {tick < 0 && <span />}\n </div>\n );\n};\n\nexport default DataTable;\n", "import React from \"react\";\nimport {\n Background,\n BackgroundVariant,\n Controls,\n MarkerType,\n ReactFlow,\n ReactFlowProvider,\n useNodesInitialized,\n useReactFlow,\n type Edge,\n type Node,\n} from \"@xyflow/react\";\n// ReactFlow's stylesheet ships inlined in @nbt-dev/devtools/styles.css.\nimport { Database, Eye, EyeOff, GitBranch, Rows3 } from \"lucide-react\";\nimport { cn } from \"../../../lib/utils\";\nimport { useBulkRowCounts } from \"../../../hooks/use-bulk-stream\";\nimport type { BulkRegistry } from \"../../../hooks/use-cartridge-info\";\nimport { EntityNode } from \"./entity-node\";\nimport {\n buildEntityGraphModel,\n cartsFromContracts,\n entityGraphId,\n filterEntityGraphModel,\n type Contract,\n type EntityGraphModel,\n type EntityGraphNodeData,\n} from \"./entity-graph-utils\";\n\ndeclare const NIMBIT_API_ENDPOINT: string | undefined;\nconst API_BASE: string =\n (typeof NIMBIT_API_ENDPOINT !== \"undefined\" && NIMBIT_API_ENDPOINT) || \"\";\n\nconst STORAGE_KEY = \"nimbit:inspector:entity-graph:hidden-carts\";\n\nconst nodeTypes = { entity: EntityNode };\n\n// Custom nodes are measured asynchronously after mount, so the `fitView` prop\n// fits to zero-size bounds on first paint (boxes end up off-screen). Refit once\n// nodes report measured dimensions, and again whenever the visible set changes.\nconst FitOnReady: React.FC<{ fitKey: string }> = ({ fitKey }) => {\n const initialized = useNodesInitialized();\n const { fitView } = useReactFlow();\n React.useEffect(() => {\n if (initialized) fitView({ padding: 0.25, duration: 200 });\n }, [initialized, fitKey, fitView]);\n return null;\n};\n\ntype EntityFlowEdge = Edge<Record<string, unknown>, \"smoothstep\"> & {\n pathOptions: { borderRadius: number; offset: number };\n};\n\nfunction useContracts() {\n const [contracts, setContracts] = React.useState<Contract[]>([]);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n (async () => {\n try {\n const r = await fetch(`${API_BASE}/_console/contracts`, {\n signal: ac.signal,\n credentials: \"include\",\n });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const data = (await r.json()) as Contract[];\n if (!Array.isArray(data)) throw new Error(\"malformed contracts response\");\n if (!cancelled) setContracts(data);\n } catch (e) {\n if (cancelled || (e as { name?: string }).name === \"AbortError\") return;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n ac.abort();\n };\n }, []);\n\n return { contracts, loading, error };\n}\n\n// Derive the bulk WS registry off the same contracts so live row counts work\n// through the shared socket (the provider preloads each entity's SCHEMA, which\n// carries totalRows). Mirrors buildRegistry in use-cartridge-info.\nfunction registryFromContracts(contracts: Contract[]): BulkRegistry {\n const reg: BulkRegistry = {};\n for (const c of contracts) {\n if (!c.cartridge || !c.owns) continue;\n const entities = Object.keys(c.owns).map((name) => ({\n name,\n route: `/_ws/bulk/${c.cartridge}/${name.toLowerCase()}`,\n searchFields: [] as string[],\n }));\n if (entities.length > 0) reg[c.cartridge] = entities;\n }\n return reg;\n}\n\n// Renders the entity graph. Must be mounted inside a <BulkStreamProvider> \u2014 it\n// reads live row counts off that shared socket's SCHEMA preload rather than\n// opening its own connection (the Data tab already provides one).\nexport const DiagramView: React.FC = () => {\n const { contracts, loading, error } = useContracts();\n\n const graph = React.useMemo(\n () => buildEntityGraphModel(cartsFromContracts(contracts)),\n [contracts],\n );\n const registry = React.useMemo(() => registryFromContracts(contracts), [contracts]);\n\n if (graph.nodes.length === 0) {\n let msg = \"No installed cartridges with entities.\";\n if (loading) msg = \"Loading entity graph\u2026\";\n else if (error) msg = `Failed to load contracts: ${error}`;\n return <div className=\"p-3 text-[12px] text-muted-foreground\">{msg}</div>;\n }\n\n return <DiagramInner graph={graph} registry={registry} />;\n};\n\nconst DiagramInner: React.FC<{ graph: EntityGraphModel; registry: BulkRegistry }> = ({\n graph,\n registry,\n}) => {\n const rowCounts = useBulkRowCounts(registry);\n const [hiddenCarts, setHiddenCarts] = React.useState<Set<string>>(() => {\n if (typeof window === \"undefined\") return new Set();\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n const saved = raw ? JSON.parse(raw) : [];\n return new Set<string>(Array.isArray(saved) ? saved.filter((n) => typeof n === \"string\") : []);\n } catch {\n return new Set();\n }\n });\n const [focusedNodeId, setFocusedNodeId] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify([...hiddenCarts]));\n }, [hiddenCarts]);\n\n const cartGroups = React.useMemo(() => {\n const counts = new Map<string, number>();\n for (const node of graph.nodes) counts.set(node.cartridge, (counts.get(node.cartridge) ?? 0) + 1);\n return [...counts.entries()]\n .map(([name, total]) => ({ name, total }))\n .sort((a, b) => a.name.localeCompare(b.name));\n }, [graph.nodes]);\n\n const visibleIds = React.useMemo(\n () => new Set(graph.nodes.filter((n) => !hiddenCarts.has(n.cartridge)).map((n) => n.id)),\n [graph.nodes, hiddenCarts],\n );\n\n const visibleGraph = React.useMemo(\n () => filterEntityGraphModel(graph, visibleIds),\n [graph, visibleIds],\n );\n\n React.useEffect(() => {\n if (focusedNodeId && !visibleIds.has(focusedNodeId)) setFocusedNodeId(null);\n }, [focusedNodeId, visibleIds]);\n\n const focusedConnections = React.useMemo(() => {\n if (!focusedNodeId) {\n return {\n connectedIds: new Set<string>(),\n edgeIds: new Set<string>(),\n fieldsByNode: new Map<string, Set<string>>(),\n };\n }\n const connectedIds = new Set<string>([focusedNodeId]);\n const edgeIds = new Set<string>();\n const fieldsByNode = new Map<string, Set<string>>();\n const addField = (nodeId: string, fieldName: string) => {\n const fields = fieldsByNode.get(nodeId) ?? new Set<string>();\n fields.add(fieldName);\n fieldsByNode.set(nodeId, fields);\n };\n for (const edge of visibleGraph.edges) {\n if (edge.source !== focusedNodeId && edge.target !== focusedNodeId) continue;\n edgeIds.add(edge.id);\n connectedIds.add(edge.source);\n connectedIds.add(edge.target);\n addField(edge.source, edge.sourceField);\n addField(edge.target, edge.targetField);\n }\n return { connectedIds, edgeIds, fieldsByNode };\n }, [focusedNodeId, visibleGraph.edges]);\n\n const liveRows = React.useMemo(\n () => visibleGraph.nodes.reduce((sum, n) => sum + (rowCounts[n.id] ?? 0), 0),\n [visibleGraph.nodes, rowCounts],\n );\n\n const nodes: Node[] = React.useMemo(\n () =>\n visibleGraph.nodes.map((node) => ({\n id: node.id,\n type: \"entity\",\n position: node.position,\n data: {\n ...node,\n rowCount: rowCounts[node.id] ?? node.rowCount,\n highlight: focusedNodeId\n ? {\n focused: node.id === focusedNodeId,\n connected: focusedConnections.connectedIds.has(node.id) && node.id !== focusedNodeId,\n dimmed: !focusedConnections.connectedIds.has(node.id),\n fields: [...(focusedConnections.fieldsByNode.get(node.id) ?? [])],\n }\n : undefined,\n },\n })),\n [focusedConnections, focusedNodeId, visibleGraph.nodes, rowCounts],\n );\n\n const edges: EntityFlowEdge[] = React.useMemo(() => {\n const nodeById = new Map(visibleGraph.nodes.map((node) => [node.id, node]));\n const laneCounts = new Map<string, number>();\n return visibleGraph.edges.map((edge) => {\n const source = nodeById.get(edge.source);\n const target = nodeById.get(edge.target);\n const sourceSide = source && target && source.position.x > target.position.x ? \"left\" : \"right\";\n const targetSide = sourceSide === \"left\" ? \"right\" : \"left\";\n const laneKey = `${edge.target}:${edge.targetField}:${targetSide}`;\n const lane = laneCounts.get(laneKey) ?? 0;\n laneCounts.set(laneKey, lane + 1);\n const highlighted = !focusedNodeId || focusedConnections.edgeIds.has(edge.id);\n return {\n id: edge.id,\n source: edge.source,\n target: edge.target,\n sourceHandle: `source-${edge.sourceField}-${sourceSide}`,\n targetHandle: `target-${edge.targetField}-${targetSide}`,\n type: \"smoothstep\",\n pathOptions: { borderRadius: 8, offset: 22 + (lane % 5) * 12 },\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: highlighted ? \"#2563eb\" : \"#64748b\",\n },\n style: {\n strokeWidth: focusedNodeId && highlighted ? 2.5 : 1.5,\n stroke: highlighted ? \"#2563eb\" : \"#64748b\",\n opacity: highlighted ? 1 : 0.16,\n },\n };\n });\n }, [focusedConnections.edgeIds, focusedNodeId, visibleGraph.edges, visibleGraph.nodes]);\n\n const toggleCart = React.useCallback((name: string) => {\n setHiddenCarts((prev) => {\n const next = new Set(prev);\n if (next.has(name)) next.delete(name);\n else next.add(name);\n return next;\n });\n }, []);\n\n const onNodeClick = React.useCallback((_: unknown, node: Node) => {\n const data = node.data as EntityGraphNodeData;\n const nodeId = entityGraphId(data.cartridge, data.entity);\n setFocusedNodeId((prev) => (prev === nodeId ? null : nodeId));\n }, []);\n\n const clearFocusedNode = React.useCallback(() => setFocusedNodeId(null), []);\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col\">\n <div className=\"flex h-7 shrink-0 items-center gap-3 border-b border-border bg-background px-2 text-[11px] text-muted-foreground select-none\">\n <span className=\"inline-flex items-center gap-1 text-foreground\">\n <GitBranch className=\"h-3.5 w-3.5\" />\n Entity Graph\n </span>\n <span className=\"ml-auto inline-flex items-center gap-1\">\n <Database className=\"h-3 w-3\" />\n {visibleGraph.totals.entities} entities\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <GitBranch className=\"h-3 w-3\" />\n {visibleGraph.totals.relationships} relationships\n </span>\n <span className=\"inline-flex items-center gap-1\">\n <Rows3 className=\"h-3 w-3\" />\n {liveRows.toLocaleString()} rows\n </span>\n </div>\n\n <div className=\"relative min-h-0 flex-1 bg-zinc-950\">\n {cartGroups.length > 0 ? (\n <div className=\"pointer-events-none absolute left-2 top-2 z-10 max-h-[calc(100%-1rem)]\">\n <div className=\"pointer-events-auto flex max-h-full flex-col gap-0.5 overflow-y-auto rounded-md border border-zinc-700 bg-zinc-900/95 p-1 shadow-sm backdrop-blur\">\n {cartGroups.map((g) => {\n const hidden = hiddenCarts.has(g.name);\n return (\n <button\n key={g.name}\n type=\"button\"\n onClick={() => toggleCart(g.name)}\n className={cn(\n \"flex items-center gap-2 rounded px-2 py-1 text-left font-mono text-[11px] hover:bg-zinc-800\",\n hidden ? \"text-zinc-500\" : \"text-zinc-100\",\n )}\n title={hidden ? `Show ${g.name}` : `Hide ${g.name}`}\n >\n {hidden ? (\n <EyeOff className=\"h-3.5 w-3.5 shrink-0\" />\n ) : (\n <Eye className=\"h-3.5 w-3.5 shrink-0 text-orange-400\" />\n )}\n <span className=\"min-w-0 flex-1 truncate\">{g.name}</span>\n <span className=\"shrink-0 text-[10px] tabular-nums text-zinc-500\">{g.total}</span>\n </button>\n );\n })}\n </div>\n </div>\n ) : null}\n\n {nodes.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-[12px] text-zinc-500\">\n No entities are visible.\n </div>\n ) : (\n <ReactFlowProvider>\n <ReactFlow\n colorMode=\"dark\"\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n fitView\n fitViewOptions={{ padding: 0.2 }}\n minZoom={0.1}\n maxZoom={1.6}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n panOnDrag\n panOnScroll\n zoomOnScroll={false}\n zoomOnPinch\n selectionOnDrag={false}\n onNodeClick={onNodeClick}\n onPaneClick={clearFocusedNode}\n proOptions={{ hideAttribution: true }}\n >\n <FitOnReady fitKey={[...visibleIds].sort().join(\"|\")} />\n <Background variant={BackgroundVariant.Dots} gap={16} size={1} color=\"#3f3f46\" />\n <Controls showInteractive={false} />\n </ReactFlow>\n </ReactFlowProvider>\n )}\n </div>\n </div>\n );\n};\n", "import React from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport { Database, FileText, KeyRound, Link2 } from \"lucide-react\";\nimport type { EntityGraphNodeData } from \"./entity-graph-utils\";\n\nexport type EntityNodeHighlight = {\n focused: boolean;\n connected: boolean;\n dimmed: boolean;\n fields: string[];\n};\n\ntype EntityNodeViewData = EntityGraphNodeData & {\n highlight?: EntityNodeHighlight;\n};\n\n// Dark entity card. Colors are pinned (not theme tokens) so the card looks the\n// same regardless of where it mounts; it sits inside the dark devtools panel.\nexport function EntityNode({ data, selected }: NodeProps) {\n const node = data as EntityNodeViewData;\n const highlight = node.highlight;\n const highlightedFields = new Set(highlight?.fields ?? []);\n const hiddenHandleClass = \"!h-1 !w-1 !border-0 !bg-transparent !opacity-0\";\n return (\n <div\n className={[\n \"relative w-[260px] overflow-visible rounded-xl border bg-zinc-900 font-mono text-[11px] text-zinc-100 shadow-lg shadow-black/40 transition-opacity\",\n highlight?.focused\n ? \"border-blue-500 ring-2 ring-blue-500/30\"\n : highlight?.connected\n ? \"border-blue-400/60 ring-2 ring-blue-500/10\"\n : \"border-zinc-700\",\n highlight?.dimmed ? \"opacity-35\" : \"\",\n selected && !highlight?.focused ? \"ring-2 ring-zinc-100/10\" : \"\",\n ].join(\" \")}\n >\n <div className=\"rounded-t-xl border-b border-zinc-700 bg-zinc-800 px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Database className=\"h-3.5 w-3.5 shrink-0 text-zinc-400\" />\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-semibold leading-none text-zinc-50\">\n {node.entity}\n </span>\n <span className=\"shrink-0 rounded bg-zinc-700 px-1.5 py-0.5 text-[10px] font-medium tabular-nums text-zinc-200\">\n {node.fieldCount}\n </span>\n </div>\n <div className=\"mt-1 truncate text-[10px] text-zinc-500\">{node.cartridge}</div>\n </div>\n <div className=\"bg-zinc-900 py-1\">\n {node.fields.length === 0 ? (\n <div className=\"px-3 py-2 text-[10px] text-zinc-500\">No fields</div>\n ) : (\n node.fields.map((field) => {\n const type = `${field.type}${field.array ? \"[]\" : \"\"}${field.optional ? \"?\" : \"\"}`;\n const isId = field.displayName.toLowerCase() === \"id\";\n const isRelation = field.kind === \"relation\";\n const isDocument = field.kind === \"document\";\n const fieldHighlighted = highlightedFields.has(field.displayName);\n return (\n <div\n key={`${field.name}:${field.displayName}`}\n className={[\n \"relative grid min-h-[26px] grid-cols-[minmax(0,1fr)_auto] items-center gap-3 px-3 py-1 text-zinc-300\",\n fieldHighlighted ? \"bg-blue-500/15 text-blue-200\" : \"\",\n ].join(\" \")}\n >\n {isId ? (\n <>\n <Handle\n id={`target-${field.displayName}-left`}\n type=\"target\"\n position={Position.Left}\n className={`!left-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n <Handle\n id={`target-${field.displayName}-right`}\n type=\"target\"\n position={Position.Right}\n className={`!right-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n </>\n ) : null}\n {isRelation ? (\n <>\n <Handle\n id={`source-${field.displayName}-left`}\n type=\"source\"\n position={Position.Left}\n className={`!left-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n <Handle\n id={`source-${field.displayName}-right`}\n type=\"source\"\n position={Position.Right}\n className={`!right-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n </>\n ) : null}\n <span className=\"flex min-w-0 items-center gap-1.5\">\n {isId ? <KeyRound className=\"h-3 w-3 shrink-0 text-zinc-500\" /> : null}\n {isRelation ? (\n <Link2 className={[\"h-3 w-3 shrink-0\", fieldHighlighted ? \"text-blue-300\" : \"text-blue-400\"].join(\" \")} />\n ) : null}\n {isDocument ? <FileText className=\"h-3 w-3 shrink-0 text-zinc-500\" /> : null}\n <span className=\"truncate\">{field.displayName}</span>\n </span>\n <span className=\"max-w-[96px] truncate text-right text-zinc-500\">{type}</span>\n </div>\n );\n })\n )}\n </div>\n <div className=\"flex items-center justify-between gap-2 rounded-b-xl border-t border-zinc-700 bg-zinc-800 px-3 py-1.5 text-[10px] text-zinc-500\">\n <span className=\"tabular-nums\">{node.rowCount.toLocaleString()} rows</span>\n <span className=\"tabular-nums\">\n {node.relationCount} rel \u00B7 {node.scalarCount} scalar\n </span>\n </div>\n </div>\n );\n}\n", "// Entity-relationship graph model for the devtools Diagram tab. Ported from the\n// portal-ui entity-graph (apps/portal/.../systems/entity-graph) but fed off the\n// daemon's `/_console/contracts` directly instead of the portal BFF's\n// cartridges-in-use + resources endpoints. Contract fields use snake_case\n// relation keys (`target_cart`, `fk_field`, `relation_kind`); we normalize to\n// the camelCase model below in `cartsFromContracts`. Row counts are overlaid\n// live from the bulk-stream schema preload, not baked into the model here.\n//\n// Placement uses dagre (layered LR) \u2014 the portal's hand-rolled column stacker\n// sprawled here because the devtools shows every installed cart at once rather\n// than a project-scoped subset.\n\nimport dagre from \"@dagrejs/dagre\";\n\nexport type GraphInputField = {\n name: string;\n type: string;\n optional?: boolean;\n array?: boolean;\n kind?: string;\n target?: string;\n targetCart?: string;\n relationKind?: string;\n fkField?: string;\n};\n\nexport type GraphInputEntity = {\n name: string;\n fields: GraphInputField[];\n};\n\nexport type GraphInputCart = {\n name: string;\n entities: GraphInputEntity[];\n};\n\nexport type EntityGraphField = {\n name: string;\n displayName: string;\n type: string;\n kind: string;\n optional: boolean;\n array: boolean;\n target?: string;\n targetCart?: string;\n relationKind?: string;\n fkField?: string;\n implicit?: boolean;\n};\n\nexport type EntityGraphNodeData = {\n id: string;\n cartridge: string;\n entity: string;\n fields: EntityGraphField[];\n fieldCount: number;\n scalarCount: number;\n relationCount: number;\n documentCount: number;\n rowCount: number;\n};\n\nexport type EntityGraphNode = EntityGraphNodeData & {\n position: { x: number; y: number };\n};\n\nexport type EntityGraphEdge = {\n id: string;\n source: string;\n target: string;\n sourceField: string;\n targetField: string;\n label: string;\n relationKind?: string;\n fkField?: string;\n};\n\nexport type EntityGraphTotals = {\n entities: number;\n relationships: number;\n rows: number;\n};\n\nexport type EntityGraphModel = {\n nodes: EntityGraphNode[];\n edges: EntityGraphEdge[];\n totals: EntityGraphTotals;\n};\n\nconst NODE_WIDTH = 260;\nconst MIN_NODE_HEIGHT = 150;\nconst FIELD_ROW_HEIGHT = 26;\nconst COLUMN_WIDTH = 390; // initial pre-layout spread; dagre overrides positions\n\n// Raw contract shapes (subset). `/_console/contracts` returns one object per\n// running cart with an `owns` map of entity -> { fields, ... }.\ntype ContractField = {\n name: string;\n type: string;\n optional?: boolean;\n array?: boolean;\n kind?: string;\n target?: string;\n target_cart?: string;\n relation_kind?: string;\n fk_field?: string;\n};\ntype ContractEntity = { fields?: ContractField[] };\nexport type Contract = {\n cartridge?: string;\n owns?: Record<string, ContractEntity>;\n};\n\nexport function cartsFromContracts(contracts: Contract[]): GraphInputCart[] {\n const carts: GraphInputCart[] = [];\n for (const c of contracts) {\n if (!c.cartridge || !c.owns) continue;\n const entities: GraphInputEntity[] = [];\n for (const [name, ent] of Object.entries(c.owns)) {\n const fields: GraphInputField[] = (ent.fields ?? []).map((f) => ({\n name: f.name,\n type: f.type,\n optional: f.optional,\n array: f.array,\n kind: f.kind,\n target: f.target,\n targetCart: f.target_cart,\n relationKind: f.relation_kind,\n fkField: f.fk_field,\n }));\n entities.push({ name, fields });\n }\n if (entities.length > 0) carts.push({ name: c.cartridge, entities });\n }\n return carts;\n}\n\nexport function entityGraphId(cartridge: string, entity: string): string {\n return `${cartridge}:${entity}`;\n}\n\nfunction fieldKind(field: GraphInputField): string {\n return field.kind ?? (field.target ? \"relation\" : \"scalar\");\n}\n\nfunction graphField(field: GraphInputField): EntityGraphField {\n const kind = fieldKind(field);\n return {\n name: field.name,\n displayName: kind === \"relation\" ? (field.fkField ?? field.name) : field.name,\n type: kind === \"relation\" && field.target ? field.target : field.type,\n kind,\n optional: field.optional === true,\n array: field.array === true,\n target: field.target,\n targetCart: field.targetCart,\n relationKind: field.relationKind,\n fkField: field.fkField,\n };\n}\n\nfunction makeGraphFields(fields: GraphInputField[]): EntityGraphField[] {\n const out = fields.map(graphField);\n if (!out.some((field) => field.displayName.toLowerCase() === \"id\")) {\n out.unshift({\n name: \"id\",\n displayName: \"id\",\n type: \"id\",\n kind: \"scalar\",\n optional: false,\n array: false,\n implicit: true,\n });\n }\n return out;\n}\n\nfunction normalizeName(value: string): string {\n return value.replace(/[^a-zA-Z0-9]/g, \"\").toLowerCase();\n}\n\nfunction words(value: string): string[] {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^a-zA-Z0-9]+/)\n .map((part) => part.toLowerCase())\n .filter(Boolean);\n}\n\nfunction entityAliases(entity: string): string[] {\n const parts = words(entity);\n const aliases = new Set<string>([normalizeName(entity)]);\n const last = parts.length > 0 ? parts[parts.length - 1] : undefined;\n if (last) aliases.add(last);\n if (parts.length > 1 && last) {\n aliases.add(`${parts.slice(0, -1).map((part) => part[0]).join(\"\")}${last}`);\n aliases.add(parts.map((part) => part[0]).join(\"\"));\n }\n return [...aliases].filter((alias) => alias.length >= 2);\n}\n\nfunction inferTargetNode(fieldName: string, nodes: EntityGraphNode[]): EntityGraphNode | null {\n if (!/id$/i.test(fieldName) || /^id$/i.test(fieldName)) return null;\n const base = normalizeName(fieldName.replace(/id$/i, \"\"));\n if (base.length < 3) return null;\n\n const candidates = nodes\n .flatMap((node) =>\n entityAliases(node.entity).map((alias) => {\n const exact = base === alias;\n const suffix = !exact && alias.length >= 4 && base.endsWith(alias);\n if (!exact && !suffix) return null;\n return {\n node,\n score: (exact ? 1000 : 500) + alias.length,\n };\n }),\n )\n .filter((candidate): candidate is { node: EntityGraphNode; score: number } => candidate !== null)\n .sort((a, b) => b.score - a.score || a.node.entity.localeCompare(b.node.entity));\n\n const first = candidates[0];\n if (!first) return null;\n const second = candidates[1];\n if (second && first.score === second.score) return null;\n return first.node;\n}\n\nfunction markRelationField(node: EntityGraphNode | undefined, fieldName: string, target: EntityGraphNode) {\n const field = node?.fields.find(\n (candidate) => candidate.displayName === fieldName || candidate.name === fieldName,\n );\n if (!field || field.displayName.toLowerCase() === \"id\") return;\n field.kind = \"relation\";\n field.target = target.entity;\n field.targetCart = target.cartridge;\n field.relationKind ??= \"inferred\";\n field.fkField ??= fieldName;\n}\n\nfunction recomputeNodeCounts(nodes: EntityGraphNode[]) {\n for (const node of nodes) {\n node.scalarCount = node.fields.filter((field) => field.kind === \"scalar\").length;\n node.relationCount = node.fields.filter((field) => field.kind === \"relation\").length;\n node.documentCount = node.fields.filter((field) => field.kind === \"document\").length;\n }\n}\n\nfunction nodeHeight(node: EntityGraphNode): number {\n return Math.max(MIN_NODE_HEIGHT, 74 + node.fields.length * FIELD_ROW_HEIGHT);\n}\n\n// Layered left-to-right placement via dagre. Connected components get clean\n// ranks with minimized crossings; isolated nodes (no edges) are gathered into a\n// trailing grid so they don't inflate dagre's ranks.\nfunction layoutNodes(nodes: EntityGraphNode[], edges: EntityGraphEdge[]) {\n const degree = new Map(nodes.map((n) => [n.id, 0]));\n for (const edge of edges) {\n degree.set(edge.source, (degree.get(edge.source) ?? 0) + 1);\n degree.set(edge.target, (degree.get(edge.target) ?? 0) + 1);\n }\n\n const connected = nodes.filter((n) => (degree.get(n.id) ?? 0) > 0);\n const isolated = nodes.filter((n) => (degree.get(n.id) ?? 0) === 0);\n const connectedIds = new Set(connected.map((n) => n.id));\n\n let maxX = 0;\n let maxY = 0;\n\n if (connected.length > 0) {\n const g = new dagre.graphlib.Graph();\n g.setGraph({ rankdir: \"LR\", ranksep: 130, nodesep: 36, marginx: 40, marginy: 40 });\n g.setDefaultEdgeLabel(() => ({}));\n for (const node of connected) {\n g.setNode(node.id, { width: NODE_WIDTH, height: nodeHeight(node) });\n }\n for (const edge of edges) {\n // dagre can't rank self-loops; the edge still renders (handle picks the\n // same node's left+right). Cross-component edges are all kept.\n if (edge.source === edge.target) continue;\n if (!connectedIds.has(edge.source) || !connectedIds.has(edge.target)) continue;\n g.setEdge(edge.source, edge.target);\n }\n dagre.layout(g);\n for (const node of connected) {\n const p = g.node(node.id);\n const h = nodeHeight(node);\n node.position = { x: p.x - NODE_WIDTH / 2, y: p.y - h / 2 };\n maxX = Math.max(maxX, node.position.x + NODE_WIDTH);\n maxY = Math.max(maxY, node.position.y + h);\n }\n }\n\n // Isolated nodes: a tidy grid to the right of the laid-out graph.\n if (isolated.length > 0) {\n isolated.sort((a, b) => a.entity.localeCompare(b.entity));\n const startX = connected.length > 0 ? maxX + COLUMN_WIDTH : 0;\n const perColumn = Math.max(1, Math.ceil(isolated.length / Math.ceil(isolated.length / 6)));\n let x = startX;\n let y = 0;\n let inColumn = 0;\n for (const node of isolated) {\n node.position = { x, y };\n y += nodeHeight(node) + 48;\n inColumn += 1;\n if (inColumn >= perColumn) {\n inColumn = 0;\n y = 0;\n x += COLUMN_WIDTH;\n }\n }\n }\n}\n\nfunction makeTotals(nodes: EntityGraphNode[], edges: EntityGraphEdge[]): EntityGraphTotals {\n return {\n entities: nodes.length,\n relationships: edges.length,\n rows: nodes.reduce((sum, node) => sum + node.rowCount, 0),\n };\n}\n\nexport function buildEntityGraphModel(cartridges: GraphInputCart[]): EntityGraphModel {\n const sortedCarts = [...cartridges].sort((a, b) => a.name.localeCompare(b.name));\n const nodes: EntityGraphNode[] = [];\n\n sortedCarts.forEach((cart, cartIndex) => {\n const entities = [...cart.entities].sort((a, b) => a.name.localeCompare(b.name));\n let y = 0;\n entities.forEach((entity) => {\n const id = entityGraphId(cart.name, entity.name);\n const fields = entity.fields ?? [];\n const graphFields = makeGraphFields(fields);\n nodes.push({\n id,\n cartridge: cart.name,\n entity: entity.name,\n fields: graphFields,\n fieldCount: graphFields.length,\n scalarCount: graphFields.filter((field) => field.kind === \"scalar\").length,\n relationCount: graphFields.filter((field) => field.kind === \"relation\").length,\n documentCount: graphFields.filter((field) => field.kind === \"document\").length,\n rowCount: 0,\n position: { x: cartIndex * COLUMN_WIDTH, y },\n });\n y += Math.max(MIN_NODE_HEIGHT, 74 + graphFields.length * FIELD_ROW_HEIGHT) + 56;\n });\n });\n\n const nodeIds = new Set(nodes.map((node) => node.id));\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const edges: EntityGraphEdge[] = [];\n const edgeKeys = new Set<string>();\n for (const cart of sortedCarts) {\n for (const entity of cart.entities) {\n const source = entityGraphId(cart.name, entity.name);\n const sourceNode = nodeById.get(source);\n for (const field of entity.fields ?? []) {\n const explicitRelation = fieldKind(field) === \"relation\" && !!field.target;\n const inferredTargetNode = explicitRelation ? null : inferTargetNode(field.name, nodes);\n if (!explicitRelation && !inferredTargetNode) continue;\n\n const targetCart = explicitRelation\n ? field.targetCart ?? cart.name\n : inferredTargetNode?.cartridge;\n const targetEntity = explicitRelation ? field.target : inferredTargetNode?.entity;\n if (!targetCart || !targetEntity) continue;\n const target = entityGraphId(targetCart, targetEntity);\n if (!nodeIds.has(source) || !nodeIds.has(target)) continue;\n const targetNode = nodeById.get(target);\n const idField = targetNode?.fields.find((candidate) => candidate.displayName.toLowerCase() === \"id\");\n const targetField = idField?.displayName ?? \"__entity\";\n const sourceGraphField = sourceNode?.fields.find(\n (candidate) => candidate.name === field.name || candidate.displayName === field.name,\n );\n const sourceField = sourceGraphField?.displayName ?? field.fkField ?? field.name;\n const edgeKey = `${source}:${sourceField}->${target}:${targetField}`;\n if (edgeKeys.has(edgeKey)) continue;\n edgeKeys.add(edgeKey);\n if (!explicitRelation && targetNode) markRelationField(sourceNode, sourceField, targetNode);\n edges.push({\n id: `${source}:${field.name}->${target}`,\n source,\n target,\n sourceField,\n targetField,\n label: field.name,\n relationKind: field.relationKind ?? (!explicitRelation ? \"inferred\" : undefined),\n fkField: field.fkField ?? (!explicitRelation ? field.name : undefined),\n });\n }\n }\n }\n\n recomputeNodeCounts(nodes);\n layoutNodes(nodes, edges);\n\n return {\n nodes,\n edges,\n totals: makeTotals(nodes, edges),\n };\n}\n\nexport function filterEntityGraphModel(\n model: EntityGraphModel,\n visibleIds: Set<string>,\n): EntityGraphModel {\n const nodes = model.nodes.filter((node) => visibleIds.has(node.id));\n const ids = new Set(nodes.map((node) => node.id));\n const edges = model.edges.filter((edge) => ids.has(edge.source) && ids.has(edge.target));\n return {\n nodes,\n edges,\n totals: makeTotals(nodes, edges),\n };\n}\n", "import * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { XIcon } from \"lucide-react\"\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"nimbit-devtools dark fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n \"nimbit-devtools dark fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close data-slot=\"sheet-close\" asChild>\n <Button\n variant=\"ghost\"\n className=\"absolute top-3 right-3\"\n size=\"icon-sm\"\n >\n <XIcon\n />\n <span className=\"sr-only\">Close</span>\n </Button>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-0.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\n \"text-base font-medium text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n", "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n outline:\n \"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-8\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n", "import React from \"react\";\n\nconst SettingsTab: React.FC = () => {\n return <></>;\n};\n\nexport default SettingsTab;\n", "import React from \"react\";\nimport { DevToolsConfigProvider } from \"./config\";\nimport { DevToolsProvider } from \"./components/devtools/devtools-context\";\nimport DevTools from \"./components/devtools/dev-tools\";\n\nexport type NimbitDevToolsProps = {\n // Base URL of the nimbit console (e.g. \"https://console.example.com\").\n // Omit / empty string => same-origin (the panel is served by the console).\n apiBaseUrl?: string;\n defaultActiveTab?: string;\n};\n\n// Drop-in devtools panel. Mount once near your app root; it renders nothing\n// until toggled open via `toggleDevTools()` (or a `devtools-toggle` window event).\nexport const NimbitDevTools: React.FC<NimbitDevToolsProps> = ({\n apiBaseUrl = \"\",\n defaultActiveTab,\n}) => (\n <DevToolsConfigProvider apiBaseUrl={apiBaseUrl}>\n <DevToolsProvider defaultActiveTab={defaultActiveTab}>\n <DevTools />\n </DevToolsProvider>\n </DevToolsConfigProvider>\n);\n\nexport default NimbitDevTools;\n\n// Open/close the panel from anywhere (keybinding, button, command palette).\nexport function toggleDevTools(): void {\n window.dispatchEvent(new CustomEvent(\"devtools-toggle\"));\n}\n\nexport {\n DevToolsProvider,\n useDevTools,\n} from \"./components/devtools/devtools-context\";\nexport { DevToolsConfigProvider, useDevToolsConfig } from \"./config\";\nexport type { DevToolsConfig } from \"./config\";\nexport { default as DevTools } from \"./components/devtools/dev-tools\";\nexport type {\n DevToolsDock,\n DevToolsTab,\n DevToolsSize,\n} from \"./components/devtools/devtools-context\";\n"],
5
- "mappings": "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",
6
- "names": ["React", "jsx", "React", "React", "jsx", "React", "jsx", "React", "useEffect", "useEffect", "React", "useEffect", "useState", "useState", "useEffect", "React", "React", "jsx", "jsxs", "React", "React", "Database", "jsx", "jsxs", "jsx", "jsxs", "React", "Database", "jsx", "jsx", "jsxs", "jsx", "jsxs", "jsx", "Fragment", "jsx", "jsxs", "React", "Fragment", "jsx", "jsx", "jsxs", "React", "jsx"]
3
+ "sources": ["../src/config.tsx", "../src/components/devtools/devtools-context.tsx", "../src/components/devtools/dev-tools.tsx", "../src/lib/utils.ts", "../src/components/devtools/console-tab.tsx", "../src/components/devtools/network-tab.tsx", "../src/components/devtools/data-tab.tsx", "../src/hooks/use-cartridge-info.ts", "../src/hooks/use-bulk-stream.ts", "../src/generated/bulk-protocol.ts", "../src/components/devtools/data-browser/data-store.ts", "../src/components/devtools/data-browser/bulk-decoder.ts", "../src/components/devtools/data-browser/data-table.tsx", "../src/components/devtools/data-browser/value-popover.tsx", "../src/components/devtools/entity-graph/diagram-tab.tsx", "../src/components/devtools/entity-graph/entity-node.tsx", "../src/components/devtools/entity-graph/entity-graph-utils.ts", "../src/components/ui/sheet.tsx", "../src/components/ui/button.tsx", "../src/components/devtools/settings-tab.tsx", "../src/components/devtools/sources/sources-tab.tsx", "../src/components/devtools/sources/use-dev-files.ts", "../src/components/devtools/sources/file-tree.tsx", "../src/components/devtools/sources/nbt-editor.tsx", "../src/components/devtools/sources/nbt-language.ts", "../src/components/devtools/sources/lsp-extensions.ts", "../src/components/devtools/sources/lsp-client.ts", "../src/index.tsx"],
4
+ "sourcesContent": ["import React from \"react\";\n\n// Runtime config for the devtools, replacing the inspector's compile-time\n// `NIMBIT_API_ENDPOINT` define. Hosts pass the console's base URL once via\n// <NimbitDevTools apiBaseUrl=\"\u2026\" /> and every fetch/WebSocket derives from it.\n// Empty string => same-origin (the inspector default when served by the console).\nexport type DevToolsConfig = {\n apiBaseUrl: string;\n};\n\nconst DevToolsConfigContext = React.createContext<DevToolsConfig>({\n apiBaseUrl: \"\",\n});\n\nexport const DevToolsConfigProvider: React.FC<{\n apiBaseUrl?: string;\n children: React.ReactNode;\n}> = ({ apiBaseUrl = \"\", children }) => {\n const value = React.useMemo(() => ({ apiBaseUrl }), [apiBaseUrl]);\n return (\n <DevToolsConfigContext.Provider value={value}>\n {children}\n </DevToolsConfigContext.Provider>\n );\n};\n\nexport function useDevToolsConfig(): DevToolsConfig {\n return React.useContext(DevToolsConfigContext);\n}\n\n// Turn an http(s) base into a ws(s) base. Empty => derive from window.location.\nexport function wsBaseFrom(apiBaseUrl: string): string {\n if (!apiBaseUrl) {\n const loc = window.location;\n const proto = loc.protocol === \"https:\" ? \"wss:\" : \"ws:\";\n return `${proto}//${loc.host}`;\n }\n return apiBaseUrl.replace(/^http(s?):/, \"ws$1:\");\n}\n", "import React, { useEffect } from \"react\";\n\nexport type DevToolsDock = \"bottom\" | \"right\";\nexport type DevToolsView = \"table\" | \"diagram\";\nexport type ConsoleLevel = \"info\" | \"warn\" | \"error\" | \"plain\";\nexport type ConsoleFilter = Record<ConsoleLevel, boolean>;\n\nexport type DevToolsTab = {\n id: string;\n title: string;\n icon?: React.ReactNode;\n render: () => React.ReactNode;\n};\n\nexport type DevToolsSize = { h: number; w: number };\n\ntype DevToolsCtx = {\n open: boolean;\n setOpen: (v: boolean) => void;\n toggle: () => void;\n dock: DevToolsDock;\n setDock: (d: DevToolsDock) => void;\n activeTab: string | null;\n setActiveTab: (id: string) => void;\n size: DevToolsSize;\n setSize: React.Dispatch<React.SetStateAction<DevToolsSize>>;\n maximized: boolean;\n setMaximized: (v: boolean) => void;\n dataCart: string | null;\n setDataCart: (v: string | null) => void;\n dataEntity: string | null;\n setDataEntity: (v: string | null) => void;\n // Data tab view config (persisted so the graph filters survive refresh).\n view: DevToolsView;\n setView: React.Dispatch<React.SetStateAction<DevToolsView>>;\n graphCarts: Set<string> | null; // null = all carts selected\n setGraphCarts: React.Dispatch<React.SetStateAction<Set<string> | null>>;\n hiddenEntities: Set<string>;\n setHiddenEntities: React.Dispatch<React.SetStateAction<Set<string>>>;\n // Resizable data-tab side panels (px). Left = entity list, right = graph rail.\n graphLeftW: number;\n setGraphLeftW: React.Dispatch<React.SetStateAction<number>>;\n graphRightW: number;\n setGraphRightW: React.Dispatch<React.SetStateAction<number>>;\n // Console tab view config.\n consoleFilter: ConsoleFilter;\n setConsoleFilter: React.Dispatch<React.SetStateAction<ConsoleFilter>>;\n consolePaused: boolean;\n setConsolePaused: React.Dispatch<React.SetStateAction<boolean>>;\n // Sources tab (dev-mode schema editor). Unsaved buffer contents stay\n // component-local; only the selection + layout persist.\n sourcesCart: string | null;\n setSourcesCart: (v: string | null) => void;\n sourcesFile: string | null;\n setSourcesFile: (v: string | null) => void;\n sourcesTreeW: number;\n setSourcesTreeW: React.Dispatch<React.SetStateAction<number>>;\n};\n\nconst Ctx = React.createContext<DevToolsCtx | null>(null);\n\nconst STORAGE_KEY = \"nimbit-devtools:v1\";\n\n// Everything that should survive a page refresh. Sets are stored as arrays\n// (JSON can't serialize a Set); `graphCarts: null` means \"all carts\".\ntype PersistedState = {\n open: boolean;\n dock: DevToolsDock;\n activeTab: string | null;\n size: DevToolsSize;\n maximized: boolean;\n dataCart: string | null;\n dataEntity: string | null;\n view: DevToolsView;\n graphCarts: string[] | null;\n hiddenEntities: string[];\n graphLeftW: number;\n graphRightW: number;\n consoleFilter: ConsoleFilter;\n consolePaused: boolean;\n sourcesCart: string | null;\n sourcesFile: string | null;\n sourcesTreeW: number;\n};\n\nconst DEFAULT_FILTER: ConsoleFilter = {\n info: true,\n warn: true,\n error: true,\n plain: true,\n};\n\nfunction loadPersisted(): Partial<PersistedState> {\n if (typeof window === \"undefined\") return {};\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (!raw) return {};\n const parsed = JSON.parse(raw);\n return typeof parsed === \"object\" && parsed ? parsed : {};\n } catch {\n return {};\n }\n}\n\nexport const DevToolsProvider: React.FC<{\n children: React.ReactNode;\n defaultActiveTab?: string;\n}> = ({ children, defaultActiveTab }) => {\n // Start from defaults so the first client render matches the server (which\n // can't read localStorage). Persisted state is loaded after mount in the\n // hydration effect below \u2014 reading it during render causes a hydration\n // mismatch when e.g. the panel was left open.\n const [open, setOpen] = React.useState(false);\n const [dock, setDock] = React.useState<DevToolsDock>(\"bottom\");\n const [activeTab, setActiveTab] = React.useState<string | null>(\n defaultActiveTab ?? null,\n );\n const [size, setSize] = React.useState<DevToolsSize>({ h: 320, w: 480 });\n const [maximized, setMaximized] = React.useState(false);\n const [dataCart, setDataCart] = React.useState<string | null>(null);\n const [dataEntity, setDataEntity] = React.useState<string | null>(null);\n const [view, setView] = React.useState<DevToolsView>(\"table\");\n const [graphCarts, setGraphCarts] = React.useState<Set<string> | null>(null);\n const [hiddenEntities, setHiddenEntities] = React.useState<Set<string>>(\n () => new Set(),\n );\n const [graphLeftW, setGraphLeftW] = React.useState(176);\n const [graphRightW, setGraphRightW] = React.useState(440);\n const [consoleFilter, setConsoleFilter] =\n React.useState<ConsoleFilter>(DEFAULT_FILTER);\n const [consolePaused, setConsolePaused] = React.useState(false);\n const [sourcesCart, setSourcesCart] = React.useState<string | null>(null);\n const [sourcesFile, setSourcesFile] = React.useState<string | null>(null);\n const [sourcesTreeW, setSourcesTreeW] = React.useState(200);\n\n // Gate persistence until we've loaded the saved snapshot, so the save effect\n // doesn't clobber localStorage with defaults before hydration runs.\n const [hydrated, setHydrated] = React.useState(false);\n\n const toggle = React.useCallback(() => setOpen((o) => !o), []);\n\n // Hydrate from localStorage once, after mount. Runs on the client only, so it\n // never affects the server-rendered HTML.\n useEffect(() => {\n const saved = loadPersisted();\n if (saved.open != null) setOpen(saved.open);\n if (saved.dock != null) setDock(saved.dock);\n if (saved.activeTab != null) setActiveTab(saved.activeTab);\n if (saved.size != null) setSize(saved.size);\n if (saved.maximized != null) setMaximized(saved.maximized);\n if (saved.dataCart != null) setDataCart(saved.dataCart);\n if (saved.dataEntity != null) setDataEntity(saved.dataEntity);\n if (saved.view != null) setView(saved.view);\n if (saved.graphCarts != null) setGraphCarts(new Set(saved.graphCarts));\n if (saved.hiddenEntities != null)\n setHiddenEntities(new Set(saved.hiddenEntities));\n if (saved.graphLeftW != null) setGraphLeftW(saved.graphLeftW);\n if (saved.graphRightW != null) setGraphRightW(saved.graphRightW);\n if (saved.consoleFilter != null) setConsoleFilter(saved.consoleFilter);\n if (saved.consolePaused != null) setConsolePaused(saved.consolePaused);\n if (saved.sourcesCart != null) setSourcesCart(saved.sourcesCart);\n if (saved.sourcesFile != null) setSourcesFile(saved.sourcesFile);\n if (saved.sourcesTreeW != null) setSourcesTreeW(saved.sourcesTreeW);\n setHydrated(true);\n }, []);\n\n // Persist the durable view config on every change. Transient state (live log\n // entries, scroll, open drawers, focused graph node) stays component-local.\n useEffect(() => {\n if (typeof window === \"undefined\" || !hydrated) return;\n const snapshot: PersistedState = {\n open,\n dock,\n activeTab,\n size,\n maximized,\n dataCart,\n dataEntity,\n view,\n graphCarts: graphCarts ? [...graphCarts] : null,\n hiddenEntities: [...hiddenEntities],\n graphLeftW,\n graphRightW,\n consoleFilter,\n consolePaused,\n sourcesCart,\n sourcesFile,\n sourcesTreeW,\n };\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(snapshot));\n } catch {\n /* storage full or unavailable \u2014 non-fatal */\n }\n }, [\n hydrated,\n open,\n dock,\n activeTab,\n size,\n maximized,\n dataCart,\n dataEntity,\n view,\n graphCarts,\n hiddenEntities,\n graphLeftW,\n graphRightW,\n consoleFilter,\n consolePaused,\n sourcesCart,\n sourcesFile,\n sourcesTreeW,\n ]);\n\n const value = React.useMemo(\n () => ({\n open,\n setOpen,\n toggle,\n dock,\n setDock,\n activeTab,\n setActiveTab,\n size,\n setSize,\n maximized,\n setMaximized,\n dataCart,\n setDataCart,\n dataEntity,\n setDataEntity,\n view,\n setView,\n graphCarts,\n setGraphCarts,\n hiddenEntities,\n setHiddenEntities,\n graphLeftW,\n setGraphLeftW,\n graphRightW,\n setGraphRightW,\n consoleFilter,\n setConsoleFilter,\n consolePaused,\n setConsolePaused,\n sourcesCart,\n setSourcesCart,\n sourcesFile,\n setSourcesFile,\n sourcesTreeW,\n setSourcesTreeW,\n }),\n [\n open,\n toggle,\n dock,\n activeTab,\n size,\n maximized,\n dataCart,\n dataEntity,\n view,\n graphCarts,\n hiddenEntities,\n graphLeftW,\n graphRightW,\n consoleFilter,\n consolePaused,\n sourcesCart,\n sourcesFile,\n sourcesTreeW,\n ],\n );\n\n // Own the toggle keybinding (Ctrl+F12) instead of relying on the host app.\n // Still honor a programmatic `devtools-toggle` window event.\n useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.ctrlKey && (e.key === \"F12\" || e.code === \"F12\")) {\n e.preventDefault();\n toggle();\n }\n };\n const onEvent = () => toggle();\n window.addEventListener(\"keydown\", onKey);\n window.addEventListener(\"devtools-toggle\", onEvent);\n return () => {\n window.removeEventListener(\"keydown\", onKey);\n window.removeEventListener(\"devtools-toggle\", onEvent);\n };\n }, [toggle]);\n\n return <Ctx.Provider value={value}>{children}</Ctx.Provider>;\n};\n\nexport function useDevTools(): DevToolsCtx {\n const v = React.useContext(Ctx);\n if (!v) throw new Error(\"useDevTools must be used inside <DevToolsProvider>\");\n return v;\n}\n", "import React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { Maximize2, Minimize2, PanelBottom, PanelRight, X } from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\nimport { useDevTools, type DevToolsTab } from \"./devtools-context\";\nimport ConsoleTab from \"./console-tab\";\nimport NetworkTab from \"./network-tab\";\nimport DataTab from \"./data-tab\";\nimport SettingsTab from \"./settings-tab\";\nimport SourcesTab from \"./sources/sources-tab\";\nimport { useDevMode } from \"./sources/use-dev-files\";\n\nconst MIN_H = 120;\nconst MIN_W = 240;\n// Keep the panel inset from the viewport edge so the header/close button can't\n// bleed off-screen (e.g. when the real Chrome devtools shrink the viewport).\nconst EDGE = 8;\n\nconst BASE_TABS: DevToolsTab[] = [\n { id: \"console\", title: \"Console\", render: () => <ConsoleTab /> },\n { id: \"network\", title: \"Network\", render: () => <NetworkTab /> },\n { id: \"data\", title: \"Data\", render: () => <DataTab /> },\n];\n\nconst SOURCES_TAB: DevToolsTab = {\n id: \"sources\",\n title: \"Sources\",\n render: () => <SourcesTab />,\n};\n\nconst SETTINGS_TAB: DevToolsTab = {\n id: \"settings\",\n title: \"Settings\",\n render: () => <SettingsTab />,\n};\n\nconst DevTools: React.FC = () => {\n const {\n open,\n setOpen,\n dock,\n setDock,\n activeTab,\n setActiveTab,\n size,\n setSize,\n maximized,\n setMaximized,\n } = useDevTools();\n\n const panelRef = React.useRef<HTMLDivElement | null>(null);\n const hasOpenedRef = React.useRef(false);\n\n // Sources only exists when the console runs in dev mode (the status probe\n // 404s otherwise).\n const devMode = useDevMode();\n const tabs = React.useMemo(\n () => (devMode?.dev ? [...BASE_TABS, SOURCES_TAB, SETTINGS_TAB] : [...BASE_TABS, SETTINGS_TAB]),\n [devMode?.dev],\n );\n\n // Track the live viewport so the rendered size can be clamped to it. Catches\n // the case where the real Chrome devtools open and shrink window.inner*.\n // Initialize to 0 on the server (no `window`); the effect below syncs the\n // real values after mount.\n const [vp, setVp] = React.useState(() =>\n typeof window === \"undefined\"\n ? { w: 0, h: 0 }\n : { w: window.innerWidth, h: window.innerHeight },\n );\n React.useEffect(() => {\n const onResize = () =>\n setVp({ w: window.innerWidth, h: window.innerHeight });\n window.addEventListener(\"resize\", onResize);\n window.visualViewport?.addEventListener(\"resize\", onResize);\n return () => {\n window.removeEventListener(\"resize\", onResize);\n window.visualViewport?.removeEventListener(\"resize\", onResize);\n };\n }, []);\n\n React.useEffect(() => {\n if (activeTab) return;\n if (tabs.length > 0) setActiveTab(tabs[0].id);\n }, [activeTab, setActiveTab, tabs]);\n\n // Keep the wheel inside the panel: let an internal scroller consume it, but\n // never let it chain to the host page (so the site behind doesn't scroll when\n // the cursor is over devtools). Non-passive listener so we can preventDefault.\n React.useEffect(() => {\n const panel = panelRef.current;\n if (!panel) return;\n const onWheel = (e: WheelEvent) => {\n let node = e.target as HTMLElement | null;\n while (node && node !== panel) {\n const s = getComputedStyle(node);\n const vertical = Math.abs(e.deltaY) >= Math.abs(e.deltaX);\n if (vertical) {\n const scrollable =\n (s.overflowY === \"auto\" || s.overflowY === \"scroll\") &&\n node.scrollHeight > node.clientHeight;\n if (scrollable) {\n const atTop = node.scrollTop <= 0;\n const atBottom =\n node.scrollTop + node.clientHeight >= node.scrollHeight - 1;\n // Only block if this scroller can't move further in that direction.\n if (!((e.deltaY < 0 && atTop) || (e.deltaY > 0 && atBottom))) return;\n }\n } else {\n const scrollable =\n (s.overflowX === \"auto\" || s.overflowX === \"scroll\") &&\n node.scrollWidth > node.clientWidth;\n if (scrollable) {\n const atLeft = node.scrollLeft <= 0;\n const atRight =\n node.scrollLeft + node.clientWidth >= node.scrollWidth - 1;\n if (!((e.deltaX < 0 && atLeft) || (e.deltaX > 0 && atRight))) return;\n }\n }\n node = node.parentElement;\n }\n // No internal scroller will consume it \u2014 stop it reaching the host page.\n e.preventDefault();\n };\n panel.addEventListener(\"wheel\", onWheel, { passive: false });\n return () => panel.removeEventListener(\"wheel\", onWheel);\n }, [open]);\n\n const startResize = React.useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n const panel = panelRef.current;\n if (!panel) return;\n\n const handle = e.currentTarget as HTMLElement;\n handle.setPointerCapture(e.pointerId);\n\n const startX = e.clientX;\n const startY = e.clientY;\n const startH = panel.offsetHeight;\n const startW = panel.offsetWidth;\n const isBottom = dock === \"bottom\";\n\n // Resize by mutating the panel's DOM size directly each frame \u2014 no React\n // state churn, so the active tab (e.g. the ReactFlow Diagram) doesn't\n // re-render on every pointermove. State is committed once on pointerup.\n let pendingNext: number | null = null;\n let lastApplied = isBottom ? startH : startW;\n let rafId = 0;\n const flush = () => {\n rafId = 0;\n if (pendingNext == null) return;\n const v = pendingNext;\n pendingNext = null;\n lastApplied = v;\n if (isBottom) panel.style.height = `${v}px`;\n else panel.style.width = `${v}px`;\n };\n\n const onMove = (ev: PointerEvent) => {\n ev.preventDefault();\n if (isBottom) {\n const dy = startY - ev.clientY;\n pendingNext = Math.max(\n MIN_H,\n Math.min(window.innerHeight - 24, startH + dy),\n );\n } else {\n const dx = startX - ev.clientX;\n pendingNext = Math.max(\n MIN_W,\n Math.min(window.innerWidth - 24, startW + dx),\n );\n }\n if (!rafId) rafId = requestAnimationFrame(flush);\n };\n\n const onUp = () => {\n if (rafId) cancelAnimationFrame(rafId);\n flush();\n setSize((prev) =>\n isBottom\n ? prev.h === lastApplied\n ? prev\n : { ...prev, h: lastApplied }\n : prev.w === lastApplied\n ? prev\n : { ...prev, w: lastApplied },\n );\n handle.removeEventListener(\"pointermove\", onMove);\n handle.removeEventListener(\"pointerup\", onUp);\n handle.removeEventListener(\"pointercancel\", onUp);\n try {\n handle.releasePointerCapture(e.pointerId);\n } catch {\n /* already released */\n }\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n };\n\n document.body.style.userSelect = \"none\";\n document.body.style.cursor =\n dock === \"bottom\" ? \"ns-resize\" : \"ew-resize\";\n handle.addEventListener(\"pointermove\", onMove);\n handle.addEventListener(\"pointerup\", onUp);\n handle.addEventListener(\"pointercancel\", onUp);\n },\n [dock, setSize],\n );\n\n // Once opened, stay mounted (hidden when closed) so each tab's UX state \u2014\n // scroll, selection, search text, graph pan/zoom, captured console \u2014 survives\n // closing and reopening. Before the first open we render nothing (no cost,\n // and SSR-safe since `open` defaults false so there's no portal on the server).\n if (open) hasOpenedRef.current = true;\n if (!hasOpenedRef.current) return null;\n\n const active = tabs.find((t) => t.id === activeTab) ?? tabs[0];\n\n const positionClass = maximized\n ? \"inset-0\"\n : dock === \"bottom\"\n ? \"inset-x-0 bottom-0\"\n : \"inset-y-0 right-0\";\n\n // Clamp the rendered size to the live viewport (minus a small edge margin) so\n // the header/close button never bleed off-screen. The persisted preference in\n // `size` is left untouched \u2014 only the displayed value is clamped.\n const sizeStyle: React.CSSProperties = maximized\n ? {}\n : dock === \"bottom\"\n ? { height: Math.max(MIN_H, Math.min(size.h, vp.h - EDGE)) }\n : { width: Math.max(MIN_W, Math.min(size.w, vp.w - EDGE)) };\n\n return createPortal(\n <div\n ref={panelRef}\n style={sizeStyle}\n className={cn(\n \"nimbit-devtools dark fixed z-50 flex flex-col border-border bg-background text-foreground text-[12px] shadow-lg\",\n positionClass,\n dock === \"bottom\" ? \"border-t\" : \"border-l\",\n !open && \"hidden\",\n )}\n onMouseDown={(e) => e.stopPropagation()}\n >\n {!maximized && (\n <div\n onPointerDown={startResize}\n style={{ touchAction: \"none\" }}\n className={cn(\n \"absolute z-10 bg-transparent hover:bg-accent/40\",\n dock === \"bottom\"\n ? \"left-0 right-0 -top-px h-1.5 cursor-ns-resize\"\n : \"top-0 bottom-0 -left-px w-1.5 cursor-ew-resize\",\n )}\n />\n )}\n\n <div className=\"flex h-7 shrink-0 items-center border-b border-border bg-background pl-1 pr-1 select-none\">\n <div className=\"flex min-w-0 flex-1 items-center gap-0.5 overflow-x-auto\">\n {tabs.map((tab) => {\n const isActive = tab.id === active?.id;\n return (\n <button\n key={tab.id}\n type=\"button\"\n data-active={isActive}\n onClick={() => setActiveTab(tab.id)}\n className={cn(\n \"h-5 shrink-0 rounded-md px-2 text-[12px] leading-none outline-none transition-colors\",\n \"text-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n <span className=\"inline-flex items-center gap-1\">\n {tab.icon}\n {tab.title}\n </span>\n </button>\n );\n })}\n </div>\n\n <div className=\"flex shrink-0 items-center gap-0.5 pl-2\">\n <IconBtn\n label={dock === \"bottom\" ? \"Dock right\" : \"Dock bottom\"}\n onClick={() => setDock(dock === \"bottom\" ? \"right\" : \"bottom\")}\n >\n {dock === \"bottom\" ? (\n <PanelRight className=\"size-3.5\" />\n ) : (\n <PanelBottom className=\"size-3.5\" />\n )}\n </IconBtn>\n <IconBtn\n label={maximized ? \"Restore\" : \"Maximize\"}\n onClick={() => setMaximized(!maximized)}\n >\n {maximized ? (\n <Minimize2 className=\"size-3.5\" />\n ) : (\n <Maximize2 className=\"size-3.5\" />\n )}\n </IconBtn>\n <IconBtn label=\"Close\" onClick={() => setOpen(false)}>\n <X className=\"size-3.5\" />\n </IconBtn>\n </div>\n </div>\n\n {/* Keep every tab mounted and just hide the inactive ones, so each tab's\n UX state (scroll position, selected cell, search text, graph pan/zoom,\n live console capture) survives switching between tabs. */}\n <div className=\"min-h-0 min-w-0 flex-1 overflow-hidden\">\n {tabs.map((tab) => (\n <div\n key={tab.id}\n className={cn(\"h-full w-full\", tab.id !== active?.id && \"hidden\")}\n >\n {tab.render()}\n </div>\n ))}\n </div>\n </div>,\n document.body,\n );\n};\n\nconst IconBtn: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement> & { label: string }\n> = ({ label, className, children, ...rest }) => (\n <button\n type=\"button\"\n aria-label={label}\n title={label}\n className={cn(\n \"grid size-5 place-items-center rounded-md text-foreground outline-none hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n);\n\nexport default DevTools;\n", "import { clsx, type ClassValue } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n", "import React from \"react\";\nimport {\n ChevronRight,\n Pause,\n Play,\n Trash2,\n} from \"lucide-react\";\nimport { cn } from \"../../lib/utils\";\nimport { useDevToolsConfig, wsBaseFrom } from \"../../config\";\nimport { useDevTools } from \"./devtools-context\";\n\nconst MAX_ENTRIES = 5000;\nconst RECONNECT_MIN_MS = 500;\nconst RECONNECT_MAX_MS = 5000;\n\ntype StackFrame = { proc: string; file: string; line: number };\ntype Parsed = {\n ts?: string;\n level?: \"info\" | \"warn\" | \"error\" | string;\n msg?: string;\n stack?: StackFrame[];\n};\n\ntype WireLine = { raw: string; parsed?: boolean };\ntype WireFrame = { cursor: number; lines: WireLine[] };\n\ntype LogEntry = {\n id: number;\n raw: string;\n level: \"info\" | \"warn\" | \"error\" | \"plain\";\n parsed: Parsed | null;\n};\n\ntype LevelKey = \"info\" | \"warn\" | \"error\" | \"plain\";\n\nfunction resolveWsUrl(apiBaseUrl: string, path: string): string {\n return `${wsBaseFrom(apiBaseUrl)}${path}`;\n}\n\nfunction classifyLine(line: WireLine): LogEntry {\n if (line.parsed) {\n try {\n const p = JSON.parse(line.raw) as Parsed;\n const lvl =\n p.level === \"info\" || p.level === \"warn\" || p.level === \"error\"\n ? p.level\n : \"plain\";\n return {\n id: _nextId(),\n raw: line.raw,\n level: lvl,\n parsed: p,\n };\n } catch {\n // Fall through to plain.\n }\n }\n return { id: _nextId(), raw: line.raw, level: \"plain\", parsed: null };\n}\n\nlet _idCounter = 0;\nfunction _nextId(): number {\n _idCounter += 1;\n return _idCounter;\n}\n\nconst LEVEL_BADGE: Record<LevelKey, string> = {\n info: \"bg-blue-500/20 text-blue-300 border-blue-400/30\",\n warn: \"bg-yellow-500/20 text-yellow-300 border-yellow-400/30\",\n error: \"bg-red-500/20 text-red-300 border-red-400/30\",\n plain: \"bg-zinc-700/40 text-zinc-300 border-zinc-500/30\",\n};\n\nconst ConsoleTab: React.FC = () => {\n const { apiBaseUrl } = useDevToolsConfig();\n const {\n consoleFilter: filter,\n setConsoleFilter: setFilter,\n consolePaused: paused,\n setConsolePaused: setPaused,\n } = useDevTools();\n const [entries, setEntries] = React.useState<LogEntry[]>([]);\n const [expanded, setExpanded] = React.useState<Record<number, boolean>>({});\n\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const stickToBottomRef = React.useRef(true);\n const pausedRef = React.useRef(paused);\n pausedRef.current = paused;\n\n React.useEffect(() => {\n let alive = true;\n let socket: WebSocket | null = null;\n let backoff = RECONNECT_MIN_MS;\n let reconnectTimer: ReturnType<typeof setTimeout> | null = null;\n\n const connect = () => {\n if (!alive) return;\n try {\n socket = new WebSocket(resolveWsUrl(apiBaseUrl, \"/_console/logs/ws\"));\n } catch {\n scheduleReconnect();\n return;\n }\n\n socket.onopen = () => {\n backoff = RECONNECT_MIN_MS;\n };\n socket.onmessage = (ev) => {\n if (pausedRef.current) return;\n if (typeof ev.data !== \"string\") return;\n let frame: WireFrame;\n try {\n frame = JSON.parse(ev.data) as WireFrame;\n } catch {\n return;\n }\n if (!frame.lines || frame.lines.length === 0) return;\n const batch = frame.lines.map(classifyLine);\n setEntries((prev) => {\n const next = prev.concat(batch);\n if (next.length > MAX_ENTRIES) {\n return next.slice(next.length - MAX_ENTRIES);\n }\n return next;\n });\n };\n socket.onerror = () => {\n // Let onclose handle reconnect.\n };\n socket.onclose = () => {\n socket = null;\n scheduleReconnect();\n };\n };\n\n const scheduleReconnect = () => {\n if (!alive) return;\n reconnectTimer = setTimeout(() => {\n backoff = Math.min(backoff * 2, RECONNECT_MAX_MS);\n connect();\n }, backoff);\n };\n\n connect();\n\n return () => {\n alive = false;\n if (reconnectTimer) clearTimeout(reconnectTimer);\n if (socket) socket.close();\n };\n }, [apiBaseUrl]);\n\n // Auto-scroll: stick to bottom unless user scrolled up. We track intent\n // via a ref and apply a single trailing scrollTop per frame so a burst of\n // batches doesn't cause repeated DOM thrash.\n const handleScroll = React.useCallback(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const atBottom =\n el.scrollHeight - (el.scrollTop + el.clientHeight) < 8;\n stickToBottomRef.current = atBottom;\n }, []);\n\n const scrollRafRef = React.useRef(0);\n React.useEffect(() => {\n if (!stickToBottomRef.current) return;\n if (scrollRafRef.current) return;\n scrollRafRef.current = requestAnimationFrame(() => {\n scrollRafRef.current = 0;\n const el = scrollerRef.current;\n if (!el) return;\n el.scrollTop = el.scrollHeight;\n });\n }, [entries]);\n React.useEffect(\n () => () => {\n if (scrollRafRef.current) cancelAnimationFrame(scrollRafRef.current);\n },\n [],\n );\n\n const visible = React.useMemo(\n () => entries.filter((e) => filter[e.level]),\n [entries, filter],\n );\n\n const toggleFilter = React.useCallback(\n (k: LevelKey) => setFilter((f) => ({ ...f, [k]: !f[k] })),\n [],\n );\n\n // One stable handler shared by every row. Each row tags itself via\n // `data-row-id`; click events bubble up to the <ul> where we read the id.\n // Avoids per-row closures that would break React.memo on LogRow.\n const onRowClick = React.useCallback((e: React.MouseEvent) => {\n let el: HTMLElement | null = e.target as HTMLElement;\n while (el && el !== e.currentTarget) {\n const id = el.dataset.rowId;\n if (id) {\n const n = Number(id);\n if (Number.isFinite(n)) {\n setExpanded((prev) => ({ ...prev, [n]: !prev[n] }));\n }\n return;\n }\n el = el.parentElement;\n }\n }, []);\n\n return (\n <div className=\"flex h-full flex-col\">\n <div className=\"flex h-7 shrink-0 items-center gap-1 border-b border-border bg-background px-1.5 select-none\">\n <ToolbarButton\n aria-label={paused ? \"Resume\" : \"Pause\"}\n onClick={() => setPaused((p) => !p)}\n >\n {paused ? (\n <Play className=\"size-3.5\" />\n ) : (\n <Pause className=\"size-3.5\" />\n )}\n </ToolbarButton>\n <ToolbarButton\n aria-label=\"Clear\"\n onClick={() => {\n setEntries([]);\n setExpanded({});\n }}\n >\n <Trash2 className=\"size-3.5\" />\n </ToolbarButton>\n <div className=\"mx-1 h-3 w-px bg-border/60\" />\n {([\"info\", \"warn\", \"error\", \"plain\"] as LevelKey[]).map((k) => (\n <FilterChip\n key={k}\n label={k}\n active={filter[k]}\n level={k}\n onClick={() => toggleFilter(k)}\n />\n ))}\n <div className=\"flex-1\" />\n <span className=\"text-[11px] text-muted-foreground tabular-nums\">\n {visible.length} / {entries.length}\n </span>\n </div>\n\n <div\n ref={scrollerRef}\n onScroll={handleScroll}\n style={{ overflowAnchor: \"none\" }}\n className=\"min-h-0 flex-1 overflow-auto font-mono text-[11px] leading-[1.45]\"\n >\n {visible.length === 0 ? (\n <div className=\"p-3 text-muted-foreground\">\n Waiting for console output\u2026\n </div>\n ) : (\n <ul onClick={onRowClick}>\n {visible.map((e) => (\n <LogRow\n key={e.id}\n entry={e}\n expanded={!!expanded[e.id]}\n />\n ))}\n </ul>\n )}\n </div>\n </div>\n );\n};\n\nconst ToolbarButton: React.FC<\n React.ButtonHTMLAttributes<HTMLButtonElement>\n> = ({ className, children, ...rest }) => (\n <button\n type=\"button\"\n className={cn(\n \"grid size-5 place-items-center rounded-md text-foreground outline-none hover:bg-accent hover:text-accent-foreground\",\n className,\n )}\n {...rest}\n >\n {children}\n </button>\n);\n\nconst FilterChip: React.FC<{\n label: string;\n level: LevelKey;\n active: boolean;\n onClick: () => void;\n}> = ({ label, level, active, onClick }) => (\n <button\n type=\"button\"\n onClick={onClick}\n data-active={active}\n className={cn(\n \"h-5 rounded-md border px-1.5 text-[11px] leading-none transition-colors\",\n \"data-[active=false]:opacity-40 data-[active=false]:hover:opacity-70\",\n LEVEL_BADGE[level],\n )}\n >\n {label}\n </button>\n);\n\ntype LogRowProps = {\n entry: LogEntry;\n expanded: boolean;\n};\n\nconst _LogRow: React.FC<LogRowProps> = ({ entry, expanded }) => {\n if (entry.level === \"plain\" || !entry.parsed) {\n return (\n <li\n className=\"border-b border-border/30 px-2 py-0.5 text-zinc-400 whitespace-pre-wrap break-words\"\n style={{ contain: \"content\" }}\n >\n {entry.raw}\n </li>\n );\n }\n\n const p = entry.parsed;\n const hasStack = Array.isArray(p.stack) && p.stack.length > 0;\n\n return (\n <li\n className=\"border-b border-border/30\"\n style={{ contain: \"content\" }}\n data-row-id={hasStack ? entry.id : undefined}\n >\n <div\n className={cn(\n \"flex items-start gap-1.5 px-2 py-0.5\",\n hasStack && \"cursor-pointer hover:bg-accent/30\",\n )}\n >\n {hasStack ? (\n <ChevronRight\n className={cn(\n \"mt-0.5 size-3 shrink-0 transition-transform\",\n expanded && \"rotate-90\",\n )}\n />\n ) : (\n <span className=\"inline-block size-3 shrink-0\" />\n )}\n <span\n className={cn(\n \"shrink-0 rounded border px-1 text-[10px] font-medium uppercase tracking-wide\",\n LEVEL_BADGE[entry.level],\n )}\n >\n {entry.level}\n </span>\n {p.ts && (\n <span className=\"shrink-0 text-zinc-500 tabular-nums\">\n {p.ts}\n </span>\n )}\n <span className=\"break-words text-zinc-200\">{p.msg ?? entry.raw}</span>\n </div>\n {hasStack && expanded && (\n <ul className=\"border-t border-border/20 bg-accent/10 px-7 py-1\">\n {p.stack!.map((f, i) => (\n <li\n key={i}\n className=\"text-zinc-400 whitespace-pre-wrap break-words\"\n >\n <span className=\"text-zinc-300\">{f.proc || \"<anon>\"}</span>\n <span className=\"text-zinc-500\"> @ </span>\n <span>{f.file}</span>\n <span className=\"text-zinc-500\">:</span>\n <span className=\"tabular-nums text-zinc-300\">{f.line}</span>\n </li>\n ))}\n </ul>\n )}\n </li>\n );\n};\n\n// Memoize per-row so a streaming batch (which replaces `entries` with a new\n// array reference) doesn't force every visible row to reconcile. Entry\n// objects are stable across batches once added, so reference-equality on\n// `entry` plus a primitive `expanded` is sufficient.\nconst LogRow = React.memo(\n _LogRow,\n (prev, next) =>\n prev.entry === next.entry && prev.expanded === next.expanded,\n);\n\nexport default ConsoleTab;\n", "import React from \"react\";\n\n// explicit goals:\n// * Detailed tracking of all requests coming in and out of the console.\n// * We need some sort of event listening on the api client / server side routes?\n\nconst NetworkTab: React.FC = () => {\n return (\n <div className=\"p-3 text-muted-foreground\">Network placeholder</div>\n );\n};\n\nexport default NetworkTab;\n", "import React from \"react\";\nimport { Network, Table2, X } from \"lucide-react\";\nimport { useLiveBulkRegistry, type BulkEntity } from \"../../hooks/use-cartridge-info\";\nimport { BulkStreamProvider } from \"../../hooks/use-bulk-stream\";\nimport { useDevTools } from \"./devtools-context\";\nimport DataTable from \"./data-browser/data-table\";\nimport { DiagramView } from \"./entity-graph/diagram-tab\";\nimport {\n Sheet,\n SheetContent,\n SheetHeader,\n SheetTitle,\n SheetDescription,\n} from \"../ui/sheet\";\nimport { cn } from \"../../lib/utils\";\n\nconst DataTab: React.FC = () => {\n const {\n dataCart,\n setDataCart,\n dataEntity,\n setDataEntity,\n view,\n setView,\n graphCarts,\n setGraphCarts,\n hiddenEntities,\n setHiddenEntities,\n graphLeftW,\n setGraphLeftW,\n graphRightW,\n setGraphRightW,\n } = useDevTools();\n const leftRef = React.useRef<HTMLDivElement | null>(null);\n const rightRef = React.useRef<HTMLDivElement | null>(null);\n const [detail, setDetail] = React.useState<Record<string, string> | null>(null);\n // Graph-node selection \u2192 entity table in a right drawer.\n const [graphSel, setGraphSel] = React.useState<{ cart: string; entity: string } | null>(null);\n const { registry, carts, loading, error } = useLiveBulkRegistry();\n\n // Graph-mode selection (independent of table's single-select dataCart/dataEntity).\n // graphCarts === null means \"all carts selected\" (default); hiddenEntities holds\n // `cart:entity` ids explicitly toggled off (default empty = all visible).\n const selectedCarts = graphCarts ?? new Set(carts);\n\n const toggleGraphCart = (cart: string) => {\n setGraphCarts((prev) => {\n const next = new Set(prev ?? carts);\n if (next.has(cart)) next.delete(cart);\n else next.add(cart);\n return next;\n });\n };\n const toggleEntity = (id: string) => {\n setHiddenEntities((prev) => {\n const next = new Set(prev);\n if (next.has(id)) next.delete(id);\n else next.add(id);\n return next;\n });\n };\n\n const visibleIds = React.useMemo(() => {\n const ids = new Set<string>();\n for (const cart of carts) {\n if (!selectedCarts.has(cart)) continue;\n for (const e of registry[cart] ?? [])\n if (!hiddenEntities.has(`${cart}:${e.name}`)) ids.add(`${cart}:${e.name}`);\n }\n return ids;\n }, [carts, registry, graphCarts, hiddenEntities]);\n\n // Close the graph data rail when its entity is toggled out of the visible set.\n React.useEffect(() => {\n if (graphSel && !visibleIds.has(`${graphSel.cart}:${graphSel.entity}`))\n setGraphSel(null);\n }, [graphSel, visibleIds]);\n\n const activeCart = dataCart && registry[dataCart] ? dataCart : carts[0] ?? null;\n const entities: readonly BulkEntity[] = activeCart ? registry[activeCart] ?? [] : [];\n const activeEntity =\n entities.find((e) => e.name === dataEntity) ?? entities[0] ?? null;\n\n // First-time defaults / fixup when the persisted cart vanished.\n React.useEffect(() => {\n if (activeCart && activeCart !== dataCart) setDataCart(activeCart);\n if (activeEntity && activeEntity.name !== dataEntity) setDataEntity(activeEntity.name);\n }, [activeCart, activeEntity, dataCart, dataEntity, setDataCart, setDataEntity]);\n\n if (carts.length === 0) {\n let msg = \"No installed cartridges with entities.\";\n if (loading) msg = \"Loading cartridges\u2026\";\n else if (error) msg = `Failed to load cartridges: ${error}`;\n return <div className=\"p-3 text-[12px] text-muted-foreground\">{msg}</div>;\n }\n\n return (\n <BulkStreamProvider registry={registry}>\n <div className=\"flex h-full flex-col\">\n <div className=\"flex h-7 shrink-0 items-center gap-1 overflow-x-auto border-b border-border bg-background px-1 select-none\">\n <div className=\"flex shrink-0 items-center gap-0.5 pr-1\">\n <ViewBtn active={view === \"table\"} onClick={() => setView(\"table\")} label=\"Table\">\n <Table2 className=\"size-3\" />\n </ViewBtn>\n <ViewBtn active={view === \"diagram\"} onClick={() => setView(\"diagram\")} label=\"Graph\">\n <Network className=\"size-3\" />\n </ViewBtn>\n </div>\n <div className=\"h-4 w-px shrink-0 bg-border\" />\n {carts.map((cart) => {\n const isActive = view === \"table\" ? cart === activeCart : selectedCarts.has(cart);\n return (\n <button\n key={cart}\n type=\"button\"\n data-active={isActive}\n onClick={() => {\n if (view === \"table\") {\n setDataCart(cart);\n const first = registry[cart]?.[0];\n setDataEntity(first ? first.name : null);\n } else {\n toggleGraphCart(cart);\n }\n }}\n className={cn(\n \"h-5 shrink-0 rounded-full px-2.5 text-[11px] leading-none outline-none transition-colors\",\n \"border border-transparent text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:border-border data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n {cart}\n </button>\n );\n })}\n </div>\n\n <div className=\"flex min-h-0 min-w-0 flex-1\">\n <div\n ref={leftRef}\n style={{ width: graphLeftW }}\n className=\"relative shrink-0 border-r border-border bg-muted/10\"\n >\n <ResizeHandle edge=\"right\" targetRef={leftRef} min={120} max={480} onCommit={setGraphLeftW} />\n <div className=\"flex h-full flex-col overflow-y-auto py-1\">\n {view === \"table\" ? (\n entities.length === 0 ? (\n <div className=\"px-2 py-1 text-[11px] text-muted-foreground\">\n No entities\n </div>\n ) : (\n entities.map((e) => {\n const isActive = e.name === activeEntity?.name;\n return (\n <button\n key={e.name}\n type=\"button\"\n data-active={isActive}\n onClick={() => setDataEntity(e.name)}\n className={cn(\n \"h-6 shrink-0 text-left px-2 text-[12px] leading-none outline-none transition-colors\",\n \"text-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n {e.name}\n </button>\n );\n })\n )\n ) : carts.filter((c) => selectedCarts.has(c)).length === 0 ? (\n <div className=\"px-2 py-1 text-[11px] text-muted-foreground\">\n No cartridges selected\n </div>\n ) : (\n carts\n .filter((c) => selectedCarts.has(c))\n .map((cart) => (\n <div key={cart} className=\"mb-1\">\n <div className=\"px-2 py-0.5 text-[10px] uppercase tracking-wider text-muted-foreground/60\">\n {cart}\n </div>\n {(registry[cart] ?? []).map((e) => {\n const id = `${cart}:${e.name}`;\n const on = !hiddenEntities.has(id);\n return (\n <button\n key={id}\n type=\"button\"\n data-active={on}\n onClick={() => toggleEntity(id)}\n title={on ? `Hide ${e.name}` : `Show ${e.name}`}\n className={cn(\n \"h-6 w-full shrink-0 text-left px-2 text-[12px] leading-none outline-none transition-colors hover:bg-accent hover:text-accent-foreground\",\n on ? \"text-foreground\" : \"text-muted-foreground/40 line-through\",\n )}\n >\n {e.name}\n </button>\n );\n })}\n </div>\n ))\n )}\n </div>\n </div>\n\n <div className=\"min-h-0 min-w-0 flex-1\">\n {view === \"diagram\" ? (\n <DiagramView\n visibleIds={visibleIds}\n onSelectNode={(cart, entity) => setGraphSel({ cart, entity })}\n />\n ) : activeEntity ? (\n <DataTable\n key={`${activeCart}:${activeEntity.name}`}\n cart={activeCart!}\n entity={activeEntity.name}\n searchFields={activeEntity.searchFields}\n onSelectRow={(row) => setDetail(row)}\n />\n ) : (\n <div className=\"p-3 text-[12px] text-muted-foreground\">\n Pick an entity.\n </div>\n )}\n </div>\n\n {view === \"diagram\" && graphSel ? (\n <div\n ref={rightRef}\n style={{ width: graphRightW }}\n className=\"relative flex shrink-0 flex-col border-l border-border bg-background\"\n >\n <ResizeHandle edge=\"left\" targetRef={rightRef} min={280} max={900} onCommit={setGraphRightW} />\n <div className=\"flex h-7 shrink-0 items-center gap-1 border-b border-border bg-muted/10 px-2 select-none\">\n <span className=\"min-w-0 flex-1 truncate text-[12px]\">\n <span className=\"text-muted-foreground\">{graphSel.cart}.</span>\n {graphSel.entity}\n </span>\n <button\n type=\"button\"\n aria-label=\"Close\"\n title=\"Close\"\n onClick={() => setGraphSel(null)}\n className=\"grid size-5 shrink-0 place-items-center rounded-md text-foreground outline-none hover:bg-accent hover:text-accent-foreground\"\n >\n <X className=\"size-3.5\" />\n </button>\n </div>\n <div className=\"min-h-0 flex-1\">\n <DataTable\n key={`${graphSel.cart}:${graphSel.entity}`}\n cart={graphSel.cart}\n entity={graphSel.entity}\n searchFields={\n (registry[graphSel.cart] ?? []).find((e) => e.name === graphSel.entity)\n ?.searchFields ?? []\n }\n onSelectRow={(row) => setDetail(row)}\n />\n </div>\n </div>\n ) : null}\n </div>\n\n <Sheet open={!!detail} onOpenChange={(o) => !o && setDetail(null)}>\n <SheetContent side=\"right\" className=\"w-[480px] sm:max-w-[480px]\">\n <SheetHeader>\n <SheetTitle className=\"text-[13px]\">\n {activeCart}.{activeEntity?.name}\n {detail?.id ? (\n <span className=\"ml-2 font-mono text-[11px] text-muted-foreground\">\n {detail.id}\n </span>\n ) : null}\n </SheetTitle>\n <SheetDescription className=\"text-[11px]\">\n Row detail\n </SheetDescription>\n </SheetHeader>\n <div className=\"min-h-0 flex-1 overflow-auto px-4 pb-4\">\n {detail ? (\n <table className=\"w-full text-[12px]\">\n <tbody>\n {Object.entries(detail).map(([k, v]) => (\n <tr key={k} className=\"border-b border-border/40 align-top\">\n <td className=\"w-32 py-1 pr-2 font-mono text-[11px] text-muted-foreground\">\n {k}\n </td>\n <td className=\"break-all py-1 font-mono\">{v || <span className=\"text-muted-foreground/60\">\u2205</span>}</td>\n </tr>\n ))}\n </tbody>\n </table>\n ) : null}\n </div>\n </SheetContent>\n </Sheet>\n </div>\n </BulkStreamProvider>\n );\n};\n\n// Drag handle pinned to one edge of a side panel. Resizes by mutating the\n// target's width directly each frame (no React churn \u2014 the ReactFlow diagram\n// doesn't re-render mid-drag), committing the final width to state on release.\nconst ResizeHandle: React.FC<{\n edge: \"left\" | \"right\";\n targetRef: React.RefObject<HTMLDivElement | null>;\n min: number;\n max: number;\n onCommit: (w: number) => void;\n}> = ({ edge, targetRef, min, max, onCommit }) => {\n const onPointerDown = (e: React.PointerEvent) => {\n e.preventDefault();\n const el = targetRef.current;\n if (!el) return;\n const handle = e.currentTarget as HTMLElement;\n handle.setPointerCapture(e.pointerId);\n const startX = e.clientX;\n const startW = el.offsetWidth;\n let last = startW;\n let raf = 0;\n let pending: number | null = null;\n const flush = () => {\n raf = 0;\n if (pending == null) return;\n last = pending;\n el.style.width = `${pending}px`;\n pending = null;\n };\n const onMove = (ev: PointerEvent) => {\n ev.preventDefault();\n const dx = ev.clientX - startX;\n const delta = edge === \"left\" ? -dx : dx;\n pending = Math.max(min, Math.min(max, startW + delta));\n if (!raf) raf = requestAnimationFrame(flush);\n };\n const onUp = () => {\n if (raf) cancelAnimationFrame(raf);\n flush();\n onCommit(last);\n handle.removeEventListener(\"pointermove\", onMove);\n handle.removeEventListener(\"pointerup\", onUp);\n handle.removeEventListener(\"pointercancel\", onUp);\n try {\n handle.releasePointerCapture(e.pointerId);\n } catch {\n /* already released */\n }\n document.body.style.userSelect = \"\";\n document.body.style.cursor = \"\";\n };\n document.body.style.userSelect = \"none\";\n document.body.style.cursor = \"ew-resize\";\n handle.addEventListener(\"pointermove\", onMove);\n handle.addEventListener(\"pointerup\", onUp);\n handle.addEventListener(\"pointercancel\", onUp);\n };\n return (\n <div\n onPointerDown={onPointerDown}\n style={{ touchAction: \"none\" }}\n className={cn(\n \"absolute top-0 bottom-0 z-20 w-1.5 cursor-ew-resize bg-transparent hover:bg-accent/40\",\n edge === \"left\" ? \"-left-px\" : \"-right-px\",\n )}\n />\n );\n};\n\nconst ViewBtn: React.FC<{\n active: boolean;\n onClick: () => void;\n label: string;\n children: React.ReactNode;\n}> = ({ active, onClick, label, children }) => (\n <button\n type=\"button\"\n data-active={active}\n onClick={onClick}\n title={label}\n className={cn(\n \"inline-flex h-5 shrink-0 items-center gap-1 rounded-md px-1.5 text-[11px] leading-none outline-none transition-colors\",\n \"text-muted-foreground hover:bg-accent hover:text-accent-foreground\",\n \"data-[active=true]:bg-accent data-[active=true]:text-accent-foreground\",\n )}\n >\n {children}\n {label}\n </button>\n);\n\nexport default DataTab;\n", "import { useEffect, useState } from \"react\";\nimport { useDevToolsConfig } from \"../config\";\n\n// Live cartridge/entity registry for the Data tab. Instead of the build-time\n// `BULK_REGISTRY` (every cart in the repo, generated by `nbt generate`), we\n// read the daemon's `/_console/contracts` \u2014 which only lists *running*\n// cartridges and carries each entity's `searchFields`. Bulk WS routes are\n// derived live (`/_ws/bulk/<cart>/<entity-lower>`) and fed straight into\n// useBulkStream. So the tab reflects what is actually installed right now.\n\nexport type BulkEntity = {\n name: string;\n route: string;\n searchFields: readonly string[];\n};\nexport type BulkRegistry = Record<string, BulkEntity[]>;\n\ntype Contract = {\n cartridge?: string;\n owns?: Record<string, { searchFields?: string[] }>;\n};\n\nfunction buildRegistry(contracts: Contract[]): BulkRegistry {\n const reg: BulkRegistry = {};\n for (const c of contracts) {\n const cart = c.cartridge;\n if (!cart || !c.owns) continue;\n const entities: BulkEntity[] = [];\n for (const [name, ent] of Object.entries(c.owns)) {\n const sf = Array.isArray(ent?.searchFields) ? ent.searchFields : [];\n entities.push({\n name,\n route: `/_ws/bulk/${cart}/${name.toLowerCase()}`,\n searchFields: sf,\n });\n }\n if (entities.length > 0) reg[cart] = entities;\n }\n return reg;\n}\n\nexport type LiveRegistryState = {\n registry: BulkRegistry;\n carts: string[];\n loading: boolean;\n error: string | null;\n};\n\nexport function useLiveBulkRegistry(): LiveRegistryState {\n const { apiBaseUrl } = useDevToolsConfig();\n const [registry, setRegistry] = useState<BulkRegistry>({});\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n setLoading(true);\n setError(null);\n (async () => {\n try {\n const r = await fetch(`${apiBaseUrl}/_console/contracts`, {\n signal: ac.signal,\n credentials: \"include\",\n });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const data = (await r.json()) as Contract[];\n if (!Array.isArray(data)) throw new Error(\"malformed contracts response\");\n if (cancelled) return;\n setRegistry(buildRegistry(data));\n } catch (e) {\n if (cancelled || (e as { name?: string }).name === \"AbortError\") return;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n ac.abort();\n };\n }, [apiBaseUrl]);\n\n const carts = Object.keys(registry).sort();\n return { registry, carts, loading, error };\n}\n", "import React, {\n createContext,\n useContext,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { BulkDataStore } from \"../components/devtools/data-browser/data-store\";\nimport {\n getFrameType,\n getFrameSid,\n parseSchema,\n parseDataChunk,\n parseDelta,\n parseError,\n encodeStreamCmd,\n} from \"../components/devtools/data-browser/bulk-decoder\";\nimport {\n FRAME_SCHEMA,\n FRAME_DATA,\n FRAME_DATA_END,\n FRAME_DELTA_INS,\n FRAME_DELTA_UPD,\n FRAME_DELTA_DEL,\n FRAME_ERROR,\n type ColumnDef,\n} from \"../generated/bulk-protocol\";\nimport type { BulkRegistry } from \"./use-cartridge-info\";\nimport { useDevToolsConfig, wsBaseFrom } from \"../config\";\n\n// One per-entity table view, demultiplexed off the shared socket by sid. The\n// object is stable across renders and mutated in place; consumers re-render via\n// the listener set (and the cheap per-chunk onRender for virtualization).\ntype View = {\n sid: number;\n cart: string;\n entity: string;\n store: BulkDataStore;\n columns: ColumnDef[];\n totalRows: number;\n loadedRows: number;\n streaming: boolean;\n error: string | null;\n streamRequested: boolean; // sent a `sub` (full stream) at least once\n onRender: (() => void) | null;\n listeners: Set<() => void>;\n};\n\nexport type BulkSubscription = {\n store: BulkDataStore;\n connected: boolean;\n streaming: boolean;\n error: string | null;\n columns: ColumnDef[];\n totalRows: number;\n loadedRows: number;\n search: (q: string) => void;\n clearSearch: () => void;\n setOnRender: (fn: (() => void) | null) => void;\n};\n\ntype Ctx = {\n getView: (cart: string, entity: string) => View;\n ensureStreamed: (view: View) => void;\n search: (view: View, query: string) => void;\n clearSearch: (view: View) => void;\n subscribe: (view: View, cb: () => void) => () => void;\n connected: boolean;\n error: string | null;\n};\n\nconst BulkStreamContext = createContext<Ctx | null>(null);\n\nfunction base64UrlEncode(value: string): string {\n if (typeof btoa === \"function\") {\n return btoa(value).replace(/\\+/g, \"-\").replace(/\\//g, \"_\").replace(/=+$/g, \"\");\n }\n throw new Error(\"No base64 encoder available for bulk WS auth\");\n}\n\nfunction bulkAuthProtocols(token: string): string[] {\n return [\"nimbit-bulk\", `auth-${base64UrlEncode(token)}`];\n}\n\nlet _wsTokenCache: { apiBaseUrl: string; token: string; at: number } | null = null;\nconst WS_TOKEN_TTL_MS = 60_000;\n\n// The console doesn't mint /auth/ws-token (that's the portal BFF); the inspector\n// talks to the daemon directly, so we read the session bearer from\n// auth.Session.current and forward it in the WS subprotocol.\nasync function fetchWsToken(\n signal: AbortSignal,\n apiBaseUrl: string,\n): Promise<string | null> {\n const now = Date.now();\n if (_wsTokenCache?.apiBaseUrl === apiBaseUrl && now - _wsTokenCache.at < WS_TOKEN_TTL_MS) {\n return _wsTokenCache.token;\n }\n const r = await fetch(`${apiBaseUrl}/api/auth/session/current`, {\n method: \"POST\",\n signal,\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n });\n if (!r.ok) return null;\n const j = (await r.json()) as { session?: { token?: string } };\n const token = j.session?.token;\n if (!token) return null;\n _wsTokenCache = { apiBaseUrl, token, at: now };\n return token;\n}\n\nfunction invalidateWsToken() {\n _wsTokenCache = null;\n}\n\nfunction notify(view: View) {\n view.listeners.forEach((cb) => cb());\n}\n\ntype Props = { registry: BulkRegistry; children: React.ReactNode };\n\nexport function BulkStreamProvider({ registry, children }: Props): React.ReactElement {\n const { apiBaseUrl } = useDevToolsConfig();\n const wsRef = useRef<WebSocket | null>(null);\n const sendQueueRef = useRef<string[]>([]);\n const sidCounterRef = useRef(1);\n const viewsBySidRef = useRef<Map<number, View>>(new Map());\n const viewsByKeyRef = useRef<Map<string, View>>(new Map());\n const preloadedRef = useRef(false);\n\n const [connected, setConnected] = useState(false);\n const [error, setError] = useState<string | null>(null);\n\n const sendCmd = (cmd: string) => {\n const ws = wsRef.current;\n if (ws && ws.readyState === WebSocket.OPEN) ws.send(cmd);\n else sendQueueRef.current.push(cmd);\n };\n\n const flushQueue = () => {\n const ws = wsRef.current;\n if (!ws || ws.readyState !== WebSocket.OPEN) return;\n const q = sendQueueRef.current;\n sendQueueRef.current = [];\n for (const cmd of q) ws.send(cmd);\n };\n\n const getView = (cart: string, entity: string): View => {\n // The server registers entity ops under \"<cart>/<entity-lower>\" (route\n // path casing), so normalize here \u2014 preload and subscription then share one\n // view per entity regardless of the caller's casing.\n const entLower = entity.toLowerCase();\n const key = `${cart}/${entLower}`;\n const existing = viewsByKeyRef.current.get(key);\n if (existing) return existing;\n const sid = sidCounterRef.current++;\n const view: View = {\n sid,\n cart,\n entity: entLower,\n store: new BulkDataStore(),\n columns: [],\n totalRows: 0,\n loadedRows: 0,\n streaming: false,\n error: null,\n streamRequested: false,\n onRender: null,\n listeners: new Set(),\n };\n viewsByKeyRef.current.set(key, view);\n viewsBySidRef.current.set(sid, view);\n return view;\n };\n\n const ensureStreamed = (view: View) => {\n if (view.streamRequested) return;\n view.streamRequested = true;\n sendCmd(encodeStreamCmd(view.sid, view.cart, view.entity));\n };\n\n const handleMessage = (ev: MessageEvent) => {\n const buf = ev.data as ArrayBuffer;\n const sid = getFrameSid(buf);\n const view = viewsBySidRef.current.get(sid);\n if (!view) return;\n const ft = getFrameType(buf);\n const store = view.store;\n switch (ft) {\n case FRAME_SCHEMA: {\n const schema = parseSchema(buf);\n store.applySchema(schema);\n view.columns = schema.columns;\n view.totalRows = schema.totalRows;\n view.loadedRows = 0;\n view.streaming = true;\n notify(view);\n break;\n }\n case FRAME_DATA:\n {\n const rows = parseDataChunk(buf, store.columns);\n store.appendChunk(rows);\n view.loadedRows = store.getRowCount();\n view.onRender?.();\n break;\n }\n case FRAME_DATA_END:\n view.streaming = false;\n notify(view);\n break;\n case FRAME_DELTA_INS:\n case FRAME_DELTA_UPD:\n case FRAME_DELTA_DEL: {\n const delta = parseDelta(buf, store.columns);\n store.applyDelta(delta);\n view.totalRows = store.totalRows;\n view.loadedRows = store.getRowCount();\n view.onRender?.();\n notify(view);\n break;\n }\n case FRAME_ERROR:\n view.error = parseError(buf);\n view.streaming = false;\n notify(view);\n break;\n }\n };\n\n // Open one shared socket for the provider's lifetime.\n useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n let opened = false;\n let ws: WebSocket | null = null;\n sendQueueRef.current = [];\n sidCounterRef.current = 1;\n viewsBySidRef.current.clear();\n viewsByKeyRef.current.clear();\n preloadedRef.current = false;\n setConnected(false);\n setError(null);\n\n (async () => {\n let token: string | null = null;\n try {\n token = await fetchWsToken(ac.signal, apiBaseUrl);\n } catch {\n if (!cancelled) setError(\"Failed to obtain WS session token\");\n return;\n }\n if (cancelled) return;\n if (!token) {\n setError(\"No session \u2014 sign in to view data\");\n return;\n }\n ws = new WebSocket(`${wsBaseFrom(apiBaseUrl)}/_ws/bulk`, bulkAuthProtocols(token));\n ws.binaryType = \"arraybuffer\";\n wsRef.current = ws;\n ws.onopen = () => {\n if (cancelled || wsRef.current !== ws) return;\n opened = true;\n setConnected(true);\n setError(null);\n flushQueue();\n };\n ws.onmessage = handleMessage;\n ws.onerror = () => {};\n ws.onclose = () => {\n if (cancelled || wsRef.current !== ws) return;\n setConnected(false);\n wsRef.current = null;\n if (!opened) {\n invalidateWsToken();\n setError(\"WebSocket connection closed\");\n }\n };\n })();\n\n return () => {\n cancelled = true;\n ac.abort();\n if (ws) {\n ws.onopen = ws.onmessage = ws.onerror = ws.onclose = null;\n try {\n ws.close();\n } catch {}\n if (wsRef.current === ws) wsRef.current = null;\n }\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [apiBaseUrl]);\n\n // The live protocol exposes only sub/unsub. Subscribe every known entity once\n // so schema, row counts, snapshots, and deltas stay available to all tabs.\n useEffect(() => {\n if (!connected) return;\n if (preloadedRef.current) return;\n const keys = Object.keys(registry);\n if (keys.length === 0) return;\n preloadedRef.current = true;\n for (const cart of keys) {\n for (const ent of registry[cart] ?? []) {\n const view = getView(cart, ent.name);\n ensureStreamed(view);\n }\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [connected, registry]);\n\n const search = (view: View, query: string) => {\n view.store.search(query);\n view.totalRows = view.store.totalRows;\n view.loadedRows = view.store.getRowCount();\n notify(view);\n view.onRender?.();\n };\n\n const clearSearch = (view: View) => {\n view.store.exitSearch();\n view.totalRows = view.store.totalRows;\n view.loadedRows = view.store.getRowCount();\n notify(view);\n view.onRender?.();\n };\n\n const subscribe = (view: View, cb: () => void) => {\n view.listeners.add(cb);\n return () => {\n view.listeners.delete(cb);\n };\n };\n\n const ctx: Ctx = {\n getView,\n ensureStreamed,\n search,\n clearSearch,\n subscribe,\n connected,\n error,\n };\n\n return React.createElement(BulkStreamContext.Provider, { value: ctx }, children);\n}\n\n// Row counts for every entity in the registry, sourced from the SCHEMA preload\n// the provider already runs on connect (FRAME_SCHEMA carries totalRows). No row\n// streaming is triggered \u2014 we subscribe to each view but never ensureStreamed.\n// Keyed by the graph id `cart:Entity` (original casing) for the Diagram tab.\nexport function useBulkRowCounts(registry: BulkRegistry): Record<string, number> {\n const ctx = useContext(BulkStreamContext);\n if (!ctx) throw new Error(\"useBulkRowCounts must be used within BulkStreamProvider\");\n const [, force] = useState(0);\n\n const pairs: Array<{ id: string; view: View }> = [];\n for (const cart of Object.keys(registry)) {\n for (const ent of registry[cart] ?? []) {\n pairs.push({ id: `${cart}:${ent.name}`, view: ctx.getView(cart, ent.name) });\n }\n }\n\n const key = pairs.map((p) => p.id).join(\"|\");\n useEffect(() => {\n const unsubs = pairs.map((p) => ctx.subscribe(p.view, () => force((n) => n + 1)));\n return () => unsubs.forEach((u) => u());\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [key]);\n\n const counts: Record<string, number> = {};\n for (const p of pairs) counts[p.id] = p.view.totalRows;\n return counts;\n}\n\n// Keyed to a single entity. The view (schema + rows + deltas) is shared and\n// cached in the provider, so switching tabs is instant once visited.\nexport function useBulkSubscription(cart: string, entity: string): BulkSubscription {\n const ctx = useContext(BulkStreamContext);\n if (!ctx) throw new Error(\"useBulkSubscription must be used within BulkStreamProvider\");\n\n const view = ctx.getView(cart, entity);\n const [, force] = useState(0);\n\n useEffect(() => {\n const unsub = ctx.subscribe(view, () => force((n) => n + 1));\n ctx.ensureStreamed(view);\n return unsub;\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [view]);\n\n return {\n store: view.store,\n connected: ctx.connected,\n streaming: view.streaming,\n error: view.error ?? ctx.error,\n columns: view.columns,\n totalRows: view.totalRows,\n loadedRows: view.loadedRows,\n search: (q: string) => ctx.search(view, q),\n clearSearch: () => ctx.clearSearch(view),\n setOnRender: (fn) => {\n view.onRender = fn;\n },\n };\n}\n", "// Wire constants mirrored from modules/cart/ws.jai (CART_WS_* + cart_ws_type_byte).\n\n// Frame types (first byte of each WS binary message).\nexport const FRAME_SCHEMA = 0x01;\nexport const FRAME_DATA = 0x02;\nexport const FRAME_DATA_END = 0x03;\nexport const FRAME_DELTA_INS = 0x04;\nexport const FRAME_DELTA_UPD = 0x05;\nexport const FRAME_DELTA_DEL = 0x06;\nexport const FRAME_ERROR = 0xff;\n\n// Column type bytes (schema frame, per column).\nexport const TYPE_U8 = 0x01;\nexport const TYPE_U16 = 0x02;\nexport const TYPE_U32 = 0x03;\nexport const TYPE_U64 = 0x04;\nexport const TYPE_S8 = 0x05;\nexport const TYPE_S16 = 0x06;\nexport const TYPE_S32 = 0x07;\nexport const TYPE_S64 = 0x08;\nexport const TYPE_BOOL = 0x09;\nexport const TYPE_FLOAT32 = 0x0a;\nexport const TYPE_FLOAT64 = 0x0b;\nexport const TYPE_STRING = 0x0c;\nexport const TYPE_DATETIME = 0x0d;\nexport const TYPE_DOCUMENT = 0x0e;\n\nexport type ColumnDef = {\n name: string;\n type: number;\n fixedSize: number; // 0 for variable-width (string, document)\n};\n\nexport type SchemaFrame = {\n totalRows: number;\n columns: ColumnDef[];\n};\n\nexport type DeltaFrame = {\n op: number;\n rowData?: string[];\n id?: string; // DELETE carries the row id as a len-prefixed string\n};\n\nexport function fixedSizeForType(type: number): number {\n switch (type) {\n case TYPE_U8: return 1;\n case TYPE_U16: return 2;\n case TYPE_U32: return 4;\n case TYPE_U64: return 8;\n case TYPE_S8: return 1;\n case TYPE_S16: return 2;\n case TYPE_S32: return 4;\n case TYPE_S64: return 8;\n case TYPE_BOOL: return 1;\n case TYPE_FLOAT32: return 4;\n case TYPE_FLOAT64: return 8;\n case TYPE_STRING: return 0;\n case TYPE_DATETIME: return 8;\n case TYPE_DOCUMENT: return 0;\n default: return 0;\n }\n}\n", "import {\n FRAME_DELTA_INS,\n FRAME_DELTA_UPD,\n FRAME_DELTA_DEL,\n type ColumnDef,\n type SchemaFrame,\n type DeltaFrame,\n} from \"../../../generated/bulk-protocol\";\n\nexport class BulkDataStore {\n columns: ColumnDef[] = [];\n rows: string[][] = [];\n totalRows = 0;\n searchActive = false;\n\n private _fullRows: string[][] = [];\n private _fullTotalRows = 0;\n private _idColIndex = -1;\n private _query = \"\";\n\n applySchema(schema: SchemaFrame): void {\n this.columns = schema.columns;\n this.totalRows = schema.totalRows;\n this.rows = [];\n this._fullRows = [];\n this._fullTotalRows = schema.totalRows;\n this.searchActive = false;\n this._query = \"\";\n this._idColIndex = schema.columns.findIndex((c) => c.name === \"id\");\n }\n\n appendChunk(chunk: string[][]): void {\n for (let i = 0; i < chunk.length; i++) {\n const row = chunk[i]!;\n this._fullRows.push(row);\n if (!this.searchActive) this.rows.push(row);\n }\n }\n\n applyDelta(delta: DeltaFrame): void {\n const target = this._fullRows;\n if (delta.op === FRAME_DELTA_INS && delta.rowData) {\n target.push(delta.rowData);\n this._fullTotalRows++;\n this.totalRows++;\n if (!this.searchActive) this.rows = this._fullRows;\n else this._applySearch();\n return;\n }\n if (delta.op === FRAME_DELTA_UPD && delta.rowData) {\n const idx = this._findRowById(target, delta.rowData);\n if (idx >= 0) target[idx] = delta.rowData;\n if (this.searchActive) this._applySearch();\n return;\n }\n if (delta.op === FRAME_DELTA_DEL && delta.id !== undefined) {\n const idStr = String(delta.id);\n const idx = this._findRowByIdStr(target, idStr);\n if (idx >= 0) {\n target.splice(idx, 1);\n this._fullTotalRows--;\n this.totalRows--;\n if (!this.searchActive) this.rows = this._fullRows;\n else this._applySearch();\n }\n return;\n }\n }\n\n search(query: string): void {\n const q = query.trim().toLowerCase();\n if (!q) { this.exitSearch(); return; }\n this.searchActive = true;\n this._query = q;\n this._applySearch();\n }\n\n exitSearch(): void {\n if (!this.searchActive) return;\n this.rows = this._fullRows;\n this.totalRows = this._fullTotalRows;\n this.searchActive = false;\n this._query = \"\";\n }\n\n getRowCount(): number {\n return this.rows.length;\n }\n\n private _findRowById(rows: string[][], rowData: string[]): number {\n if (this._idColIndex < 0) return -1;\n const id = rowData[this._idColIndex];\n for (let i = 0; i < rows.length; i++) {\n if (rows[i]![this._idColIndex] === id) return i;\n }\n return -1;\n }\n\n private _findRowByIdStr(rows: string[][], idStr: string): number {\n if (this._idColIndex < 0) return -1;\n for (let i = 0; i < rows.length; i++) {\n if (rows[i]![this._idColIndex] === idStr) return i;\n }\n return -1;\n }\n\n private _applySearch(): void {\n this.rows = this._fullRows.filter((row) =>\n row.some((value) => value.toLowerCase().includes(this._query)),\n );\n this.totalRows = this.rows.length;\n }\n}\n", "// Wire-format decoders + client\u2192server command encoders for the multiplexed\n// bulk WS protocol. Frame opcodes and column-type bytes live in\n// @/generated/bulk-protocol (kept in sync with modules/cart/ws.jai).\n//\n// Every server\u2192client binary frame is [op:u8][sid:u16 LE][payload]. The sid is\n// the client-chosen subscription id; one socket multiplexes many entities, and\n// the provider routes each frame to the matching view by sid (getFrameSid).\n// Only the parse/encode bodies are hand-maintained here.\n\nimport {\n FRAME_SCHEMA,\n FRAME_DATA,\n FRAME_DELTA_DEL,\n FRAME_DELTA_INS,\n FRAME_DELTA_UPD,\n TYPE_U8,\n TYPE_S8,\n TYPE_BOOL,\n TYPE_U16,\n TYPE_S16,\n TYPE_U32,\n TYPE_S32,\n TYPE_FLOAT32,\n TYPE_U64,\n TYPE_S64,\n TYPE_FLOAT64,\n TYPE_DATETIME,\n TYPE_STRING,\n TYPE_DOCUMENT,\n fixedSizeForType,\n type ColumnDef,\n type SchemaFrame,\n type DeltaFrame,\n} from \"../../../generated/bulk-protocol\";\n\nconst textDecoder = new TextDecoder();\n\n// Bytes between the op byte and the frame payload: the u16 LE subscription id.\nconst SID_BYTES = 2;\n// Offset of the payload in every server\u2192client frame (op + sid).\nconst HEAD = 1 + SID_BYTES;\n\nfunction epochToDate(epoch: number): Date {\n const abs = Math.abs(epoch);\n if (abs < 10_000_000_000) return new Date(epoch * 1000);\n if (abs < 10_000_000_000_000) return new Date(epoch);\n if (abs < 10_000_000_000_000_000) return new Date(epoch / 1000);\n return new Date(epoch / 1_000_000);\n}\n\nfunction formatCellValue(view: DataView, offset: number, col: ColumnDef): [string, number] {\n switch (col.type) {\n case TYPE_U8: return [String(view.getUint8(offset)), 1];\n case TYPE_S8: return [String(view.getInt8(offset)), 1];\n case TYPE_BOOL: return [view.getUint8(offset) ? \"true\" : \"false\", 1];\n case TYPE_U16: return [String(view.getUint16(offset, true)), 2];\n case TYPE_S16: return [String(view.getInt16(offset, true)), 2];\n case TYPE_U32: return [String(view.getUint32(offset, true)), 4];\n case TYPE_S32: return [String(view.getInt32(offset, true)), 4];\n case TYPE_FLOAT32: return [String(view.getFloat32(offset, true)), 4];\n case TYPE_U64: return [String(view.getBigUint64(offset, true)), 8];\n case TYPE_S64: return [String(view.getBigInt64(offset, true)), 8];\n case TYPE_FLOAT64: return [String(view.getFloat64(offset, true)), 8];\n case TYPE_DATETIME: {\n const epoch = Number(view.getBigInt64(offset, true));\n if (epoch === 0) return [\"\", 8];\n return [epochToDate(epoch).toISOString(), 8];\n }\n case TYPE_STRING:\n case TYPE_DOCUMENT: {\n const len = view.getUint32(offset, true);\n const bytes = new Uint8Array(view.buffer, view.byteOffset + offset + 4, len);\n return [textDecoder.decode(bytes), 4 + len];\n }\n default:\n return [\"\", 0];\n }\n}\n\nexport function getFrameType(buf: ArrayBuffer): number {\n return new DataView(buf).getUint8(0);\n}\n\n// The subscription id this frame belongs to (u16 LE right after the op byte).\nexport function getFrameSid(buf: ArrayBuffer): number {\n return new DataView(buf).getUint16(1, true);\n}\n\nexport function parseSchema(buf: ArrayBuffer): SchemaFrame {\n const view = new DataView(buf);\n let offset = 0;\n const frameType = view.getUint8(offset); offset += 1;\n if (frameType !== FRAME_SCHEMA) {\n throw new Error(`Expected SCHEMA frame (0x01), got 0x${frameType.toString(16)}`);\n }\n offset += SID_BYTES;\n const totalRows = view.getUint32(offset, true); offset += 4;\n const columnCount = view.getUint16(offset, true); offset += 2;\n const columns: ColumnDef[] = [];\n for (let i = 0; i < columnCount; i++) {\n const type = view.getUint8(offset); offset += 1;\n const nameLen = view.getUint16(offset, true); offset += 2;\n const nameBytes = new Uint8Array(buf, offset, nameLen);\n const name = textDecoder.decode(nameBytes);\n offset += nameLen;\n columns.push({ name, type, fixedSize: fixedSizeForType(type) });\n }\n return { totalRows, columns };\n}\n\nexport function parseDataChunk(buf: ArrayBuffer, columns: ColumnDef[]): string[][] {\n const view = new DataView(buf);\n let offset = 0;\n const frameType = view.getUint8(offset); offset += 1;\n if (frameType !== FRAME_DATA) {\n throw new Error(`Expected DATA frame, got 0x${frameType.toString(16)}`);\n }\n offset += SID_BYTES;\n const rowCount = view.getUint16(offset, true); offset += 2;\n const rows: string[][] = [];\n for (let r = 0; r < rowCount; r++) {\n const row: string[] = [];\n for (let c = 0; c < columns.length; c++) {\n const [value, bytesRead] = formatCellValue(view, offset, columns[c]!);\n row.push(value);\n offset += bytesRead;\n }\n rows.push(row);\n }\n return rows;\n}\n\nexport function parseDelta(buf: ArrayBuffer, columns: ColumnDef[]): DeltaFrame {\n const view = new DataView(buf);\n let offset = 0;\n const op = view.getUint8(offset); offset += 1;\n offset += SID_BYTES;\n if (op === FRAME_DELTA_DEL) {\n // [id_len:u16 LE][id_bytes] \u2014 the row id is a string (ULID), not an int.\n const len = view.getUint16(offset, true); offset += 2;\n const bytes = new Uint8Array(buf, offset, len);\n return { op, id: textDecoder.decode(bytes) };\n }\n if (op === FRAME_DELTA_INS || op === FRAME_DELTA_UPD) {\n const rowData: string[] = [];\n for (let c = 0; c < columns.length; c++) {\n const [value, bytesRead] = formatCellValue(view, offset, columns[c]!);\n rowData.push(value);\n offset += bytesRead;\n }\n return { op, rowData };\n }\n throw new Error(`Unknown delta op 0x${op.toString(16)}`);\n}\n\nexport function parseError(buf: ArrayBuffer): string {\n const view = new DataView(buf);\n // [0xFF][sid:u16][msg_len:u16 LE][msg_bytes]\n const len = view.getUint16(HEAD, true);\n const bytes = new Uint8Array(buf, HEAD + 2, len);\n return textDecoder.decode(bytes);\n}\n\n// --- client \u2192 server command encoders ---\n// Each command carries the subscription id; sub/schema also name the target.\n\nexport function encodeStreamCmd(\n sid: number,\n cart: string,\n entity: string,\n opts?: { sort?: string; sort_desc?: boolean; filters?: Record<string, string> },\n): string {\n return JSON.stringify({ cmd: \"sub\", sid, cart, entity, ...opts });\n}\n\nexport function encodeUnsubCmd(sid: number): string {\n return JSON.stringify({ cmd: \"unsub\", sid });\n}\n", "import React from \"react\";\nimport { useBulkSubscription } from \"../../../hooks/use-bulk-stream\";\nimport { cn } from \"../../../lib/utils\";\nimport { TYPE_DATETIME, TYPE_DOCUMENT } from \"../../../generated/bulk-protocol\";\nimport ValuePopover, { type ValuePopoverData } from \"./value-popover\";\n\nconst ROW_H = 22;\nconst OVERSCAN = 6;\nconst MIN_COL_W = 80;\nconst GUTTER_W = 32;\n\nconst READONLY_FIELDS = new Set([\"id\", \"createdAt\", \"updatedAt\"]);\nconst READONLY_TYPES = new Set([TYPE_DATETIME, TYPE_DOCUMENT]);\n\ntype DataTableProps = {\n cart: string;\n entity: string;\n searchFields: readonly string[];\n onSelectRow: (rowJson: Record<string, string>) => void;\n};\n\nfunction colWidth(name: string): number {\n if (name === \"id\") return 220;\n if (name === \"createdAt\" || name === \"updatedAt\") return 180;\n if (name === \"email\" || name === \"phone\") return 180;\n if (name.endsWith(\"At\")) return 180;\n return Math.max(MIN_COL_W, Math.min(240, name.length * 9 + 24));\n}\n\nconst DataTable: React.FC<DataTableProps> = ({ cart, entity, searchFields, onSelectRow }) => {\n const stream = useBulkSubscription(cart, entity);\n const scrollerRef = React.useRef<HTMLDivElement | null>(null);\n const [scrollTop, setScrollTop] = React.useState(0);\n const [viewportH, setViewportH] = React.useState(0);\n const [query, setQuery] = React.useState(\"\");\n const [selected, setSelected] = React.useState<{ r: number; c: number } | null>(null);\n const [popover, setPopover] = React.useState<ValuePopoverData | null>(null);\n // Bump on every chunk arrival without re-rendering each FRAME_DATA.\n const [tick, setTick] = React.useState(0);\n\n React.useEffect(() => {\n stream.setOnRender(() => setTick((n) => n + 1));\n return () => stream.setOnRender(null);\n }, [stream]);\n\n React.useEffect(() => {\n const el = scrollerRef.current;\n if (!el) return;\n const ro = new ResizeObserver(() => setViewportH(el.clientHeight));\n ro.observe(el);\n setViewportH(el.clientHeight);\n return () => ro.disconnect();\n }, []);\n\n const rows = stream.store.rows;\n const columns = stream.columns;\n\n const totalH = rows.length * ROW_H;\n const start = Math.max(0, Math.floor(scrollTop / ROW_H) - OVERSCAN);\n const visibleCount = Math.max(0, Math.ceil(viewportH / ROW_H) + OVERSCAN * 2);\n const end = Math.min(rows.length, start + visibleCount);\n\n const onSearchKey = (e: React.KeyboardEvent<HTMLInputElement>) => {\n if (e.key === \"Enter\") {\n stream.search(query.trim());\n } else if (e.key === \"Escape\") {\n setQuery(\"\");\n stream.clearSearch();\n }\n };\n\n const handleRowClick = (rowIdx: number) => {\n const r = rows[rowIdx];\n if (!r) return;\n const out: Record<string, string> = {};\n for (let i = 0; i < columns.length; i++) out[columns[i]!.name] = r[i] ?? \"\";\n onSelectRow(out);\n };\n\n const searchDisabled = searchFields.length === 0;\n const totalColW = GUTTER_W + columns.reduce((s, c) => s + colWidth(c.name), 0);\n const idColIndex = columns.findIndex((c) => c.name === \"id\");\n\n const scrollRowIntoView = (r: number) => {\n const el = scrollerRef.current;\n if (!el) return;\n const top = r * ROW_H;\n if (top < el.scrollTop) el.scrollTop = top;\n else if (top + ROW_H > el.scrollTop + el.clientHeight)\n el.scrollTop = top + ROW_H - el.clientHeight;\n };\n\n const onKeyDown = (e: React.KeyboardEvent<HTMLDivElement>) => {\n if (rows.length === 0 || columns.length === 0) return;\n if ((e.metaKey || e.ctrlKey) && (e.key === \"c\" || e.key === \"C\")) {\n if (!selected) return;\n const v = rows[selected.r]?.[selected.c] ?? \"\";\n void navigator.clipboard?.writeText(v);\n e.preventDefault();\n return;\n }\n const cur = selected ?? { r: start, c: 0 };\n let { r, c } = cur;\n if (e.key === \"ArrowUp\") r--;\n else if (e.key === \"ArrowDown\") r++;\n else if (e.key === \"ArrowLeft\") c--;\n else if (e.key === \"ArrowRight\") c++;\n else return;\n e.preventDefault();\n r = Math.max(0, Math.min(rows.length - 1, r));\n c = Math.max(0, Math.min(columns.length - 1, c));\n setSelected({ r, c });\n setPopover(null);\n scrollRowIntoView(r);\n };\n\n return (\n <div className=\"flex h-full flex-col bg-background\">\n <div className=\"flex h-7 shrink-0 items-center gap-2 border-b border-border px-2\">\n <input\n type=\"text\"\n value={query}\n disabled={searchDisabled}\n onChange={(e) => setQuery(e.target.value)}\n onKeyDown={onSearchKey}\n placeholder={\n searchDisabled\n ? \"Search disabled (no @@search declared)\"\n : `Search ${searchFields.join(\", \")} \u23CE`\n }\n className={cn(\n \"h-5 flex-1 rounded-sm border border-border bg-background px-2 text-[12px] outline-none\",\n \"placeholder:text-muted-foreground/70 focus:border-accent-foreground/30\",\n searchDisabled && \"opacity-50 cursor-not-allowed\",\n )}\n />\n <div className=\"shrink-0 text-[11px] text-muted-foreground tabular-nums\">\n {stream.error ? (\n <span className=\"text-red-400\">{stream.error}</span>\n ) : !stream.connected ? (\n <span>connecting\u2026</span>\n ) : (\n <span>\n {stream.loadedRows.toLocaleString()} / {stream.totalRows.toLocaleString()} rows\n {stream.streaming ? \" \u00B7 streaming\" : \"\"}\n </span>\n )}\n </div>\n </div>\n\n {columns.length === 0 ? (\n <div className=\"flex flex-1 items-center justify-center text-[12px] text-muted-foreground\">\n {stream.error ? stream.error : \"Waiting for schema\u2026\"}\n </div>\n ) : (\n <div\n ref={scrollerRef}\n tabIndex={0}\n onKeyDown={onKeyDown}\n onScroll={(e) => {\n setScrollTop((e.target as HTMLDivElement).scrollTop);\n if (popover) setPopover(null);\n }}\n className=\"group/table relative min-h-0 flex-1 overflow-auto font-mono outline-none\"\n >\n <div style={{ width: totalColW }}>\n {/* Sticky header lives inside the scroller so it shares the native\n horizontal scroll with the rows \u2014 no JS transform sync, no jitter. */}\n <div\n className=\"sticky top-0 z-10 flex h-6 select-none border-b border-border bg-background text-[11px] uppercase tracking-wider text-muted-foreground\"\n style={{ width: totalColW }}\n >\n <div\n style={{ width: GUTTER_W }}\n className=\"shrink-0 border-r border-border\"\n />\n {columns.map((c) => (\n <div\n key={c.name}\n style={{ width: colWidth(c.name) }}\n className=\"flex items-center overflow-hidden border-r border-border px-2\"\n >\n <span className=\"truncate\">{c.name}</span>\n </div>\n ))}\n </div>\n\n <div style={{ height: totalH, width: totalColW, position: \"relative\" }}>\n {rows.slice(start, end).map((row, i) => {\n const rowIdx = start + i;\n return (\n <div\n key={rowIdx}\n style={{\n top: rowIdx * ROW_H,\n height: ROW_H,\n width: totalColW,\n }}\n className={cn(\n \"absolute left-0 flex text-[12px] leading-none\",\n rowIdx % 2 === 0 ? \"bg-background\" : \"bg-muted/20\",\n )}\n >\n <button\n type=\"button\"\n title=\"Open row detail\"\n onClick={() => handleRowClick(rowIdx)}\n style={{ width: GUTTER_W }}\n className={cn(\n \"flex shrink-0 items-center justify-center border-r border-border/60\",\n \"cursor-pointer text-[10px] tabular-nums text-muted-foreground/60\",\n \"hover:bg-accent hover:text-accent-foreground\",\n )}\n >\n {rowIdx + 1}\n </button>\n {columns.map((c, ci) => {\n const isSel = selected?.r === rowIdx && selected?.c === ci;\n return (\n <div\n key={c.name}\n data-selected={isSel}\n onClick={(e) => {\n e.stopPropagation();\n setSelected({ r: rowIdx, c: ci });\n setPopover(null);\n }}\n onDoubleClick={(e) => {\n e.stopPropagation();\n setSelected({ r: rowIdx, c: ci });\n const editable =\n idColIndex >= 0 &&\n !READONLY_FIELDS.has(c.name) &&\n !READONLY_TYPES.has(c.type);\n setPopover({\n r: rowIdx,\n c: ci,\n colName: c.name,\n value: row[ci] ?? \"\",\n rect: (e.currentTarget as HTMLElement).getBoundingClientRect(),\n cart,\n entity,\n rowId: idColIndex >= 0 ? row[idColIndex] ?? \"\" : \"\",\n colType: c.type,\n editable,\n });\n }}\n style={{ width: colWidth(c.name) }}\n className={cn(\n \"flex cursor-pointer items-center overflow-hidden border-r border-border/60 px-2\",\n \"data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground\",\n \"data-[selected=true]:[box-shadow:inset_0_0_0_1px_#60a5fa]\",\n )}\n title={row[ci]}\n >\n <span className=\"truncate\">{row[ci]}</span>\n </div>\n );\n })}\n </div>\n );\n })}\n </div>\n </div>\n </div>\n )}\n {popover ? <ValuePopover data={popover} onClose={() => setPopover(null)} /> : null}\n {/* tick is bumped on each data chunk to force a re-render of the rows. */}\n {tick < 0 && <span />}\n </div>\n );\n};\n\nexport default DataTable;\n", "import React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { cn } from \"../../../lib/utils\";\nimport { useDevToolsConfig } from \"../../../config\";\nimport {\n TYPE_U8,\n TYPE_U16,\n TYPE_U32,\n TYPE_U64,\n TYPE_S8,\n TYPE_S16,\n TYPE_S32,\n TYPE_S64,\n TYPE_BOOL,\n TYPE_FLOAT32,\n TYPE_FLOAT64,\n} from \"../../../generated/bulk-protocol\";\n\nconst WIDTH = 420;\n\nexport type ValuePopoverData = {\n r: number;\n c: number;\n colName: string;\n value: string;\n rect: DOMRect;\n cart: string;\n entity: string;\n rowId: string;\n colType: number;\n editable: boolean;\n};\n\nconst INT_TYPES = new Set([\n TYPE_U8, TYPE_U16, TYPE_U32, TYPE_U64,\n TYPE_S8, TYPE_S16, TYPE_S32, TYPE_S64,\n]);\nconst FLOAT_TYPES = new Set([TYPE_FLOAT32, TYPE_FLOAT64]);\n\nfunction position(rect: DOMRect): React.CSSProperties {\n const margin = 12;\n const left = Math.max(\n margin,\n Math.min(rect.left, window.innerWidth - WIDTH - margin),\n );\n const roomBelow = window.innerHeight - rect.bottom;\n const top = roomBelow >= 180 ? rect.bottom + 6 : Math.max(margin, rect.top - 188);\n return { left, top, width: WIDTH };\n}\n\n// Coerce the edited string to the JSON value the update handler expects for the\n// column's wire type. Returns the value or an error string.\nfunction coerce(draft: string, colType: number): { value: unknown } | { error: string } {\n if (colType === TYPE_BOOL) return { value: draft === \"true\" };\n if (INT_TYPES.has(colType)) {\n const n = Number(draft);\n if (!Number.isInteger(n)) return { error: \"Expected an integer\" };\n return { value: n };\n }\n if (FLOAT_TYPES.has(colType)) {\n const n = Number(draft);\n if (!Number.isFinite(n)) return { error: \"Expected a number\" };\n return { value: n };\n }\n return { value: draft };\n}\n\nconst ValuePopover: React.FC<{ data: ValuePopoverData; onClose: () => void }> = ({\n data,\n onClose,\n}) => {\n const { apiBaseUrl } = useDevToolsConfig();\n const [copied, setCopied] = React.useState(false);\n const [draft, setDraft] = React.useState(data.value);\n const [saving, setSaving] = React.useState(false);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n setDraft(data.value);\n setError(null);\n }, [data.value, data.r, data.c]);\n\n React.useEffect(() => {\n const onKey = (e: KeyboardEvent) => {\n if (e.key === \"Escape\") onClose();\n };\n document.addEventListener(\"keydown\", onKey);\n return () => document.removeEventListener(\"keydown\", onKey);\n }, [onClose]);\n\n const copy = async () => {\n try {\n await navigator.clipboard.writeText(data.value);\n setCopied(true);\n } catch {\n /* clipboard unavailable */\n }\n };\n\n const save = async () => {\n const result = coerce(draft, data.colType);\n if (\"error\" in result) {\n setError(result.error);\n return;\n }\n setSaving(true);\n setError(null);\n try {\n const r = await fetch(\n `${apiBaseUrl}/api/${data.cart}/${data.entity.toLowerCase()}/${encodeURIComponent(data.rowId)}`,\n {\n method: \"PUT\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ [data.colName]: result.value }),\n },\n );\n if (!r.ok) {\n setError((await r.text()) || `HTTP ${r.status}`);\n setSaving(false);\n return;\n }\n // Success: the update handler broadcasts FRAME_DELTA_UPD, which refreshes\n // the row in place \u2014 just close.\n onClose();\n } catch (e) {\n setError(e instanceof Error ? e.message : String(e));\n setSaving(false);\n }\n };\n\n const isBool = data.colType === TYPE_BOOL;\n const isNumeric = INT_TYPES.has(data.colType) || FLOAT_TYPES.has(data.colType);\n\n return createPortal(\n <>\n <div className=\"fixed inset-0 z-[60]\" onClick={onClose} />\n <div\n className={cn(\n \"nimbit-devtools dark fixed z-[61] rounded-md border border-border bg-popover p-3\",\n \"text-[12px] text-popover-foreground shadow-lg\",\n )}\n style={position(data.rect)}\n onClick={(e) => e.stopPropagation()}\n >\n <div className=\"mb-2 flex items-center justify-between gap-3\">\n <div className=\"min-w-0\">\n <div className=\"truncate font-medium text-foreground\">{data.colName}</div>\n <div className=\"text-[11px] text-muted-foreground\">Row {data.r + 1}</div>\n </div>\n <div className=\"flex shrink-0 items-center gap-1.5\">\n <button\n type=\"button\"\n onClick={copy}\n className={cn(\n \"rounded border border-border px-2 py-1 text-[11px] leading-none\",\n \"hover:bg-accent hover:text-accent-foreground\",\n )}\n >\n {copied ? \"Copied\" : \"Copy\"}\n </button>\n {data.editable ? (\n <button\n type=\"button\"\n onClick={save}\n disabled={saving}\n className={cn(\n \"rounded border border-border bg-primary/90 px-2 py-1 text-[11px] leading-none text-primary-foreground\",\n \"hover:bg-primary disabled:opacity-50\",\n )}\n >\n {saving ? \"Saving\u2026\" : \"Save\"}\n </button>\n ) : null}\n </div>\n </div>\n\n {data.editable ? (\n <>\n {isBool ? (\n <select\n value={draft}\n disabled={saving}\n onChange={(e) => setDraft(e.target.value)}\n className=\"w-full rounded-sm border border-border bg-background px-2 py-1 text-[12px] outline-none focus:border-accent-foreground/30\"\n >\n <option value=\"true\">true</option>\n <option value=\"false\">false</option>\n </select>\n ) : isNumeric ? (\n <input\n type=\"number\"\n value={draft}\n disabled={saving}\n autoFocus\n onChange={(e) => setDraft(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") void save();\n }}\n className=\"w-full rounded-sm border border-border bg-background px-2 py-1 font-mono text-[12px] outline-none focus:border-accent-foreground/30\"\n />\n ) : (\n <textarea\n value={draft}\n disabled={saving}\n autoFocus\n onChange={(e) => setDraft(e.target.value)}\n className=\"max-h-48 min-h-[3rem] w-full resize-y overflow-auto rounded-sm border border-border bg-background p-2 font-mono text-[11px] leading-5 outline-none focus:border-accent-foreground/30\"\n />\n )}\n {error ? (\n <div className=\"mt-2 break-words text-[11px] text-red-400\">{error}</div>\n ) : null}\n </>\n ) : (\n <div className=\"max-h-48 overflow-auto rounded-sm bg-muted/40 p-2 font-mono text-[11px] leading-5 whitespace-pre-wrap break-words\">\n {data.value.length > 0 ? (\n data.value\n ) : (\n <span className=\"font-sans italic text-muted-foreground\">(empty)</span>\n )}\n </div>\n )}\n </div>\n </>,\n document.body,\n );\n};\n\nexport default ValuePopover;\n", "import React from \"react\";\nimport {\n Background,\n BackgroundVariant,\n Controls,\n MarkerType,\n ReactFlow,\n ReactFlowProvider,\n useNodesInitialized,\n useReactFlow,\n type Edge,\n type Node,\n} from \"@xyflow/react\";\n// ReactFlow's stylesheet ships inlined in @nbt-dev/devtools/styles.css.\nimport { useDevToolsConfig } from \"../../../config\";\nimport { useBulkRowCounts } from \"../../../hooks/use-bulk-stream\";\nimport type { BulkRegistry } from \"../../../hooks/use-cartridge-info\";\nimport { EntityNode } from \"./entity-node\";\nimport {\n buildEntityGraphModel,\n cartsFromContracts,\n entityGraphId,\n filterEntityGraphModel,\n type Contract,\n type EntityGraphModel,\n type EntityGraphNodeData,\n} from \"./entity-graph-utils\";\n\nconst nodeTypes = { entity: EntityNode };\n\n// Custom nodes are measured asynchronously after mount, so the `fitView` prop\n// fits to zero-size bounds on first paint (boxes end up off-screen). Refit once\n// nodes report measured dimensions, and again whenever the visible set changes.\nconst FitOnReady: React.FC<{ fitKey: string }> = ({ fitKey }) => {\n const initialized = useNodesInitialized();\n const { fitView } = useReactFlow();\n React.useEffect(() => {\n if (initialized) fitView({ padding: 0.25, duration: 200 });\n }, [initialized, fitKey, fitView]);\n return null;\n};\n\ntype EntityFlowEdge = Edge<Record<string, unknown>, \"smoothstep\"> & {\n pathOptions: { borderRadius: number; offset: number };\n};\n\nfunction useContracts() {\n const { apiBaseUrl } = useDevToolsConfig();\n const [contracts, setContracts] = React.useState<Contract[]>([]);\n const [loading, setLoading] = React.useState(true);\n const [error, setError] = React.useState<string | null>(null);\n\n React.useEffect(() => {\n const ac = new AbortController();\n let cancelled = false;\n (async () => {\n try {\n const r = await fetch(`${apiBaseUrl}/_console/contracts`, {\n signal: ac.signal,\n credentials: \"include\",\n });\n if (!r.ok) throw new Error(`HTTP ${r.status}`);\n const data = (await r.json()) as Contract[];\n if (!Array.isArray(data)) throw new Error(\"malformed contracts response\");\n if (!cancelled) setContracts(data);\n } catch (e) {\n if (cancelled || (e as { name?: string }).name === \"AbortError\") return;\n setError(e instanceof Error ? e.message : String(e));\n } finally {\n if (!cancelled) setLoading(false);\n }\n })();\n return () => {\n cancelled = true;\n ac.abort();\n };\n }, [apiBaseUrl]);\n\n return { contracts, loading, error };\n}\n\n// Derive the bulk WS registry off the same contracts so live row counts work\n// through the shared socket (the provider preloads each entity's SCHEMA, which\n// carries totalRows). Mirrors buildRegistry in use-cartridge-info.\nfunction registryFromContracts(contracts: Contract[]): BulkRegistry {\n const reg: BulkRegistry = {};\n for (const c of contracts) {\n if (!c.cartridge || !c.owns) continue;\n const entities = Object.keys(c.owns).map((name) => ({\n name,\n route: `/_ws/bulk/${c.cartridge}/${name.toLowerCase()}`,\n searchFields: [] as string[],\n }));\n if (entities.length > 0) reg[c.cartridge] = entities;\n }\n return reg;\n}\n\n// Renders the entity graph. Must be mounted inside a <BulkStreamProvider> \u2014 it\n// reads live row counts off that shared socket's SCHEMA preload rather than\n// opening its own connection (the Data tab already provides one).\nexport const DiagramView: React.FC<{\n visibleIds: Set<string>;\n onSelectNode?: (cart: string, entity: string) => void;\n}> = ({ visibleIds, onSelectNode }) => {\n const { contracts, loading, error } = useContracts();\n\n const graph = React.useMemo(\n () => buildEntityGraphModel(cartsFromContracts(contracts)),\n [contracts],\n );\n const registry = React.useMemo(() => registryFromContracts(contracts), [contracts]);\n\n if (graph.nodes.length === 0) {\n let msg = \"No installed cartridges with entities.\";\n if (loading) msg = \"Loading entity graph\u2026\";\n else if (error) msg = `Failed to load contracts: ${error}`;\n return <div className=\"p-3 text-[12px] text-muted-foreground\">{msg}</div>;\n }\n\n return (\n <DiagramInner\n graph={graph}\n registry={registry}\n visibleIds={visibleIds}\n onSelectNode={onSelectNode}\n />\n );\n};\n\nconst DiagramInner: React.FC<{\n graph: EntityGraphModel;\n registry: BulkRegistry;\n visibleIds: Set<string>;\n onSelectNode?: (cart: string, entity: string) => void;\n}> = ({ graph, registry, visibleIds, onSelectNode }) => {\n const rowCounts = useBulkRowCounts(registry);\n const [focusedNodeId, setFocusedNodeId] = React.useState<string | null>(null);\n\n const visibleGraph = React.useMemo(\n () => filterEntityGraphModel(graph, visibleIds),\n [graph, visibleIds],\n );\n\n React.useEffect(() => {\n if (focusedNodeId && !visibleIds.has(focusedNodeId)) setFocusedNodeId(null);\n }, [focusedNodeId, visibleIds]);\n\n const focusedConnections = React.useMemo(() => {\n if (!focusedNodeId) {\n return {\n connectedIds: new Set<string>(),\n edgeIds: new Set<string>(),\n fieldsByNode: new Map<string, Set<string>>(),\n };\n }\n const connectedIds = new Set<string>([focusedNodeId]);\n const edgeIds = new Set<string>();\n const fieldsByNode = new Map<string, Set<string>>();\n const addField = (nodeId: string, fieldName: string) => {\n const fields = fieldsByNode.get(nodeId) ?? new Set<string>();\n fields.add(fieldName);\n fieldsByNode.set(nodeId, fields);\n };\n for (const edge of visibleGraph.edges) {\n if (edge.source !== focusedNodeId && edge.target !== focusedNodeId) continue;\n edgeIds.add(edge.id);\n connectedIds.add(edge.source);\n connectedIds.add(edge.target);\n addField(edge.source, edge.sourceField);\n addField(edge.target, edge.targetField);\n }\n return { connectedIds, edgeIds, fieldsByNode };\n }, [focusedNodeId, visibleGraph.edges]);\n\n const nodes: Node[] = React.useMemo(\n () =>\n visibleGraph.nodes.map((node) => ({\n id: node.id,\n type: \"entity\",\n position: node.position,\n data: {\n ...node,\n rowCount: rowCounts[node.id] ?? node.rowCount,\n highlight: focusedNodeId\n ? {\n focused: node.id === focusedNodeId,\n connected: focusedConnections.connectedIds.has(node.id) && node.id !== focusedNodeId,\n dimmed: !focusedConnections.connectedIds.has(node.id),\n fields: [...(focusedConnections.fieldsByNode.get(node.id) ?? [])],\n }\n : undefined,\n },\n })),\n [focusedConnections, focusedNodeId, visibleGraph.nodes, rowCounts],\n );\n\n const edges: EntityFlowEdge[] = React.useMemo(() => {\n const nodeById = new Map(visibleGraph.nodes.map((node) => [node.id, node]));\n const laneCounts = new Map<string, number>();\n return visibleGraph.edges.map((edge) => {\n const source = nodeById.get(edge.source);\n const target = nodeById.get(edge.target);\n const sourceSide = source && target && source.position.x > target.position.x ? \"left\" : \"right\";\n const targetSide = sourceSide === \"left\" ? \"right\" : \"left\";\n const laneKey = `${edge.target}:${edge.targetField}:${targetSide}`;\n const lane = laneCounts.get(laneKey) ?? 0;\n laneCounts.set(laneKey, lane + 1);\n const highlighted = !focusedNodeId || focusedConnections.edgeIds.has(edge.id);\n return {\n id: edge.id,\n source: edge.source,\n target: edge.target,\n sourceHandle: `source-${edge.sourceField}-${sourceSide}`,\n targetHandle: `target-${edge.targetField}-${targetSide}`,\n type: \"smoothstep\",\n pathOptions: { borderRadius: 8, offset: 22 + (lane % 5) * 12 },\n markerEnd: {\n type: MarkerType.ArrowClosed,\n color: highlighted ? \"#2563eb\" : \"#64748b\",\n },\n style: {\n strokeWidth: focusedNodeId && highlighted ? 2.5 : 1.5,\n stroke: highlighted ? \"#2563eb\" : \"#64748b\",\n opacity: highlighted ? 1 : 0.16,\n },\n };\n });\n }, [focusedConnections.edgeIds, focusedNodeId, visibleGraph.edges, visibleGraph.nodes]);\n\n const onNodeClick = React.useCallback(\n (_: unknown, node: Node) => {\n const data = node.data as EntityGraphNodeData;\n const nodeId = entityGraphId(data.cartridge, data.entity);\n setFocusedNodeId((prev) => (prev === nodeId ? null : nodeId));\n onSelectNode?.(data.cartridge, data.entity);\n },\n [onSelectNode],\n );\n\n // Right-click surfaces the same data panel (and suppresses the browser menu)\n // rather than toggling focus off; selecting also focuses the node.\n const onNodeContextMenu = React.useCallback(\n (e: React.MouseEvent, node: Node) => {\n e.preventDefault();\n const data = node.data as EntityGraphNodeData;\n setFocusedNodeId(entityGraphId(data.cartridge, data.entity));\n onSelectNode?.(data.cartridge, data.entity);\n },\n [onSelectNode],\n );\n\n const clearFocusedNode = React.useCallback(() => setFocusedNodeId(null), []);\n\n return (\n <div className=\"flex h-full min-h-0 w-full flex-col\">\n <div className=\"relative min-h-0 flex-1 bg-zinc-950\">\n {nodes.length === 0 ? (\n <div className=\"flex h-full items-center justify-center text-[12px] text-zinc-500\">\n No entities are visible.\n </div>\n ) : (\n <ReactFlowProvider>\n <ReactFlow\n colorMode=\"dark\"\n nodes={nodes}\n edges={edges}\n nodeTypes={nodeTypes}\n fitView\n fitViewOptions={{ padding: 0.2 }}\n minZoom={0.1}\n maxZoom={1.6}\n nodesDraggable={false}\n nodesConnectable={false}\n elementsSelectable\n panOnDrag\n zoomOnScroll\n zoomOnPinch\n selectionOnDrag={false}\n onNodeClick={onNodeClick}\n onNodeContextMenu={onNodeContextMenu}\n onPaneClick={clearFocusedNode}\n proOptions={{ hideAttribution: true }}\n >\n <FitOnReady fitKey={[...visibleIds].sort().join(\"|\")} />\n <Background variant={BackgroundVariant.Dots} gap={16} size={1} color=\"#3f3f46\" />\n <Controls showInteractive={false} />\n </ReactFlow>\n </ReactFlowProvider>\n )}\n </div>\n </div>\n );\n};\n", "import React from \"react\";\nimport { Handle, Position, type NodeProps } from \"@xyflow/react\";\nimport { Database, FileText, KeyRound, Link2 } from \"lucide-react\";\nimport type { EntityGraphNodeData } from \"./entity-graph-utils\";\n\nexport type EntityNodeHighlight = {\n focused: boolean;\n connected: boolean;\n dimmed: boolean;\n fields: string[];\n};\n\ntype EntityNodeViewData = EntityGraphNodeData & {\n highlight?: EntityNodeHighlight;\n};\n\n// Dark entity card. Colors are pinned (not theme tokens) so the card looks the\n// same regardless of where it mounts; it sits inside the dark devtools panel.\nexport function EntityNode({ data, selected }: NodeProps) {\n const node = data as EntityNodeViewData;\n const highlight = node.highlight;\n const highlightedFields = new Set(highlight?.fields ?? []);\n const hiddenHandleClass = \"!h-1 !w-1 !border-0 !bg-transparent !opacity-0\";\n return (\n <div\n className={[\n \"relative w-[260px] overflow-visible rounded-xl border bg-zinc-900 font-mono text-[11px] text-zinc-100 shadow-lg shadow-black/40 transition-opacity\",\n highlight?.focused\n ? \"border-blue-500 ring-2 ring-blue-500/30\"\n : highlight?.connected\n ? \"border-blue-400/60 ring-2 ring-blue-500/10\"\n : \"border-zinc-700\",\n highlight?.dimmed ? \"opacity-35\" : \"\",\n selected && !highlight?.focused ? \"ring-2 ring-zinc-100/10\" : \"\",\n ].join(\" \")}\n >\n <div className=\"rounded-t-xl border-b border-zinc-700 bg-zinc-800 px-3 py-2\">\n <div className=\"flex min-w-0 items-center gap-2\">\n <Database className=\"h-3.5 w-3.5 shrink-0 text-zinc-400\" />\n <span className=\"min-w-0 flex-1 truncate text-[13px] font-semibold leading-none text-zinc-50\">\n {node.entity}\n </span>\n </div>\n <div className=\"mt-1 truncate text-[10px] text-zinc-500\">{node.cartridge}</div>\n </div>\n <div className=\"bg-zinc-900 py-1\">\n {node.fields.length === 0 ? (\n <div className=\"px-3 py-2 text-[10px] text-zinc-500\">No fields</div>\n ) : (\n node.fields.map((field) => {\n const type = `${field.type}${field.array ? \"[]\" : \"\"}${field.optional ? \"?\" : \"\"}`;\n const isId = field.displayName.toLowerCase() === \"id\";\n const isRelation = field.kind === \"relation\";\n const isDocument = field.kind === \"document\";\n const fieldHighlighted = highlightedFields.has(field.displayName);\n return (\n <div\n key={`${field.name}:${field.displayName}`}\n className={[\n \"relative grid min-h-[26px] grid-cols-[minmax(0,1fr)_auto] items-center gap-3 px-3 py-1 text-zinc-300\",\n fieldHighlighted ? \"bg-blue-500/15 text-blue-200\" : \"\",\n ].join(\" \")}\n >\n {isId ? (\n <>\n <Handle\n id={`target-${field.displayName}-left`}\n type=\"target\"\n position={Position.Left}\n className={`!left-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n <Handle\n id={`target-${field.displayName}-right`}\n type=\"target\"\n position={Position.Right}\n className={`!right-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n </>\n ) : null}\n {isRelation ? (\n <>\n <Handle\n id={`source-${field.displayName}-left`}\n type=\"source\"\n position={Position.Left}\n className={`!left-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n <Handle\n id={`source-${field.displayName}-right`}\n type=\"source\"\n position={Position.Right}\n className={`!right-0 ${hiddenHandleClass}`}\n style={{ top: \"50%\" }}\n />\n </>\n ) : null}\n <span className=\"flex min-w-0 items-center gap-1.5\">\n {isId ? <KeyRound className=\"h-3 w-3 shrink-0 text-zinc-500\" /> : null}\n {isRelation ? (\n <Link2 className={[\"h-3 w-3 shrink-0\", fieldHighlighted ? \"text-blue-300\" : \"text-blue-400\"].join(\" \")} />\n ) : null}\n {isDocument ? <FileText className=\"h-3 w-3 shrink-0 text-zinc-500\" /> : null}\n <span className=\"truncate\">{field.displayName}</span>\n </span>\n <span className=\"max-w-[96px] truncate text-right text-zinc-500\">{type}</span>\n </div>\n );\n })\n )}\n </div>\n <div className=\"flex items-center justify-between gap-2 rounded-b-xl border-t border-zinc-700 bg-zinc-800 px-3 py-1.5 text-[10px] text-zinc-500\">\n <span className=\"tabular-nums\">{node.rowCount.toLocaleString()} rows</span>\n <span className=\"tabular-nums\">\n {node.relationCount} rel \u00B7 {node.scalarCount} scalar\n </span>\n </div>\n </div>\n );\n}\n", "// Entity-relationship graph model for the devtools Diagram tab. Ported from the\n// portal-ui entity-graph (apps/portal/.../systems/entity-graph) but fed off the\n// daemon's `/_console/contracts` directly instead of the portal BFF's\n// cartridges-in-use + resources endpoints. Contract fields use snake_case\n// relation keys (`target_cart`, `fk_field`, `relation_kind`); we normalize to\n// the camelCase model below in `cartsFromContracts`. Row counts are overlaid\n// live from the bulk-stream schema preload, not baked into the model here.\n//\n// Placement uses dagre (layered LR) \u2014 the portal's hand-rolled column stacker\n// sprawled here because the devtools shows every installed cart at once rather\n// than a project-scoped subset.\n\nimport dagre from \"@dagrejs/dagre\";\n\nexport type GraphInputField = {\n name: string;\n type: string;\n optional?: boolean;\n array?: boolean;\n kind?: string;\n target?: string;\n targetCart?: string;\n relationKind?: string;\n fkField?: string;\n};\n\nexport type GraphInputEntity = {\n name: string;\n fields: GraphInputField[];\n};\n\nexport type GraphInputCart = {\n name: string;\n entities: GraphInputEntity[];\n};\n\nexport type EntityGraphField = {\n name: string;\n displayName: string;\n type: string;\n kind: string;\n optional: boolean;\n array: boolean;\n target?: string;\n targetCart?: string;\n relationKind?: string;\n fkField?: string;\n implicit?: boolean;\n};\n\nexport type EntityGraphNodeData = {\n id: string;\n cartridge: string;\n entity: string;\n fields: EntityGraphField[];\n fieldCount: number;\n scalarCount: number;\n relationCount: number;\n documentCount: number;\n rowCount: number;\n};\n\nexport type EntityGraphNode = EntityGraphNodeData & {\n position: { x: number; y: number };\n};\n\nexport type EntityGraphEdge = {\n id: string;\n source: string;\n target: string;\n sourceField: string;\n targetField: string;\n label: string;\n relationKind?: string;\n fkField?: string;\n};\n\nexport type EntityGraphTotals = {\n entities: number;\n relationships: number;\n rows: number;\n};\n\nexport type EntityGraphModel = {\n nodes: EntityGraphNode[];\n edges: EntityGraphEdge[];\n totals: EntityGraphTotals;\n};\n\nconst NODE_WIDTH = 260;\nconst MIN_NODE_HEIGHT = 150;\nconst FIELD_ROW_HEIGHT = 26;\nconst COLUMN_WIDTH = 390; // initial pre-layout spread; dagre overrides positions\n\n// Raw contract shapes (subset). `/_console/contracts` returns one object per\n// running cart with an `owns` map of entity -> { fields, ... }.\ntype ContractField = {\n name: string;\n type: string;\n optional?: boolean;\n array?: boolean;\n kind?: string;\n target?: string;\n target_cart?: string;\n relation_kind?: string;\n fk_field?: string;\n};\ntype ContractEntity = { fields?: ContractField[] };\nexport type Contract = {\n cartridge?: string;\n owns?: Record<string, ContractEntity>;\n};\n\nexport function cartsFromContracts(contracts: Contract[]): GraphInputCart[] {\n const carts: GraphInputCart[] = [];\n for (const c of contracts) {\n if (!c.cartridge || !c.owns) continue;\n const entities: GraphInputEntity[] = [];\n for (const [name, ent] of Object.entries(c.owns)) {\n const fields: GraphInputField[] = (ent.fields ?? []).map((f) => ({\n name: f.name,\n type: f.type,\n optional: f.optional,\n array: f.array,\n kind: f.kind,\n target: f.target,\n targetCart: f.target_cart,\n relationKind: f.relation_kind,\n fkField: f.fk_field,\n }));\n entities.push({ name, fields });\n }\n if (entities.length > 0) carts.push({ name: c.cartridge, entities });\n }\n return carts;\n}\n\nexport function entityGraphId(cartridge: string, entity: string): string {\n return `${cartridge}:${entity}`;\n}\n\nfunction fieldKind(field: GraphInputField): string {\n return field.kind ?? (field.target ? \"relation\" : \"scalar\");\n}\n\nfunction graphField(field: GraphInputField): EntityGraphField {\n const kind = fieldKind(field);\n return {\n name: field.name,\n displayName: kind === \"relation\" ? (field.fkField ?? field.name) : field.name,\n type: kind === \"relation\" && field.target ? field.target : field.type,\n kind,\n optional: field.optional === true,\n array: field.array === true,\n target: field.target,\n targetCart: field.targetCart,\n relationKind: field.relationKind,\n fkField: field.fkField,\n };\n}\n\nfunction makeGraphFields(fields: GraphInputField[]): EntityGraphField[] {\n const out = fields.map(graphField);\n if (!out.some((field) => field.displayName.toLowerCase() === \"id\")) {\n out.unshift({\n name: \"id\",\n displayName: \"id\",\n type: \"id\",\n kind: \"scalar\",\n optional: false,\n array: false,\n implicit: true,\n });\n }\n return out;\n}\n\nfunction normalizeName(value: string): string {\n return value.replace(/[^a-zA-Z0-9]/g, \"\").toLowerCase();\n}\n\nfunction words(value: string): string[] {\n return value\n .replace(/([a-z0-9])([A-Z])/g, \"$1 $2\")\n .split(/[^a-zA-Z0-9]+/)\n .map((part) => part.toLowerCase())\n .filter(Boolean);\n}\n\nfunction entityAliases(entity: string): string[] {\n const parts = words(entity);\n const aliases = new Set<string>([normalizeName(entity)]);\n const last = parts.length > 0 ? parts[parts.length - 1] : undefined;\n if (last) aliases.add(last);\n if (parts.length > 1 && last) {\n aliases.add(`${parts.slice(0, -1).map((part) => part[0]).join(\"\")}${last}`);\n aliases.add(parts.map((part) => part[0]).join(\"\"));\n }\n return [...aliases].filter((alias) => alias.length >= 2);\n}\n\nfunction inferTargetNode(fieldName: string, nodes: EntityGraphNode[]): EntityGraphNode | null {\n if (!/id$/i.test(fieldName) || /^id$/i.test(fieldName)) return null;\n const base = normalizeName(fieldName.replace(/id$/i, \"\"));\n if (base.length < 3) return null;\n\n const candidates = nodes\n .flatMap((node) =>\n entityAliases(node.entity).map((alias) => {\n const exact = base === alias;\n const suffix = !exact && alias.length >= 4 && base.endsWith(alias);\n if (!exact && !suffix) return null;\n return {\n node,\n score: (exact ? 1000 : 500) + alias.length,\n };\n }),\n )\n .filter((candidate): candidate is { node: EntityGraphNode; score: number } => candidate !== null)\n .sort((a, b) => b.score - a.score || a.node.entity.localeCompare(b.node.entity));\n\n const first = candidates[0];\n if (!first) return null;\n const second = candidates[1];\n if (second && first.score === second.score) return null;\n return first.node;\n}\n\nfunction markRelationField(node: EntityGraphNode | undefined, fieldName: string, target: EntityGraphNode) {\n const field = node?.fields.find(\n (candidate) => candidate.displayName === fieldName || candidate.name === fieldName,\n );\n if (!field || field.displayName.toLowerCase() === \"id\") return;\n field.kind = \"relation\";\n field.target = target.entity;\n field.targetCart = target.cartridge;\n field.relationKind ??= \"inferred\";\n field.fkField ??= fieldName;\n}\n\nfunction recomputeNodeCounts(nodes: EntityGraphNode[]) {\n for (const node of nodes) {\n node.scalarCount = node.fields.filter((field) => field.kind === \"scalar\").length;\n node.relationCount = node.fields.filter((field) => field.kind === \"relation\").length;\n node.documentCount = node.fields.filter((field) => field.kind === \"document\").length;\n }\n}\n\nfunction nodeHeight(node: EntityGraphNode): number {\n return Math.max(MIN_NODE_HEIGHT, 74 + node.fields.length * FIELD_ROW_HEIGHT);\n}\n\n// Layered left-to-right placement via dagre. Connected components get clean\n// ranks with minimized crossings; isolated nodes (no edges) are gathered into a\n// trailing grid so they don't inflate dagre's ranks.\nfunction layoutNodes(nodes: EntityGraphNode[], edges: EntityGraphEdge[]) {\n const degree = new Map(nodes.map((n) => [n.id, 0]));\n for (const edge of edges) {\n degree.set(edge.source, (degree.get(edge.source) ?? 0) + 1);\n degree.set(edge.target, (degree.get(edge.target) ?? 0) + 1);\n }\n\n const connected = nodes.filter((n) => (degree.get(n.id) ?? 0) > 0);\n const isolated = nodes.filter((n) => (degree.get(n.id) ?? 0) === 0);\n const connectedIds = new Set(connected.map((n) => n.id));\n\n let maxX = 0;\n let maxY = 0;\n\n if (connected.length > 0) {\n const g = new dagre.graphlib.Graph();\n g.setGraph({ rankdir: \"LR\", ranksep: 160, nodesep: 48, marginx: 40, marginy: 40 });\n g.setDefaultEdgeLabel(() => ({}));\n for (const node of connected) {\n g.setNode(node.id, { width: NODE_WIDTH, height: nodeHeight(node) });\n }\n for (const edge of edges) {\n // dagre can't rank self-loops; the edge still renders (handle picks the\n // same node's left+right). Cross-component edges are all kept.\n if (edge.source === edge.target) continue;\n if (!connectedIds.has(edge.source) || !connectedIds.has(edge.target)) continue;\n g.setEdge(edge.source, edge.target);\n }\n dagre.layout(g);\n for (const node of connected) {\n const p = g.node(node.id);\n const h = nodeHeight(node);\n node.position = { x: p.x - NODE_WIDTH / 2, y: p.y - h / 2 };\n maxX = Math.max(maxX, node.position.x + NODE_WIDTH);\n maxY = Math.max(maxY, node.position.y + h);\n }\n }\n\n // Isolated nodes: a tidy grid to the right of the laid-out graph.\n if (isolated.length > 0) {\n isolated.sort((a, b) => a.entity.localeCompare(b.entity));\n const startX = connected.length > 0 ? maxX + COLUMN_WIDTH : 0;\n const perColumn = Math.max(1, Math.ceil(isolated.length / Math.ceil(isolated.length / 6)));\n let x = startX;\n let y = 0;\n let inColumn = 0;\n for (const node of isolated) {\n node.position = { x, y };\n y += nodeHeight(node) + 48;\n inColumn += 1;\n if (inColumn >= perColumn) {\n inColumn = 0;\n y = 0;\n x += COLUMN_WIDTH;\n }\n }\n }\n}\n\nfunction makeTotals(nodes: EntityGraphNode[], edges: EntityGraphEdge[]): EntityGraphTotals {\n return {\n entities: nodes.length,\n relationships: edges.length,\n rows: nodes.reduce((sum, node) => sum + node.rowCount, 0),\n };\n}\n\nexport function buildEntityGraphModel(cartridges: GraphInputCart[]): EntityGraphModel {\n const sortedCarts = [...cartridges].sort((a, b) => a.name.localeCompare(b.name));\n const nodes: EntityGraphNode[] = [];\n\n sortedCarts.forEach((cart, cartIndex) => {\n const entities = [...cart.entities].sort((a, b) => a.name.localeCompare(b.name));\n let y = 0;\n entities.forEach((entity) => {\n const id = entityGraphId(cart.name, entity.name);\n const fields = entity.fields ?? [];\n const graphFields = makeGraphFields(fields);\n nodes.push({\n id,\n cartridge: cart.name,\n entity: entity.name,\n fields: graphFields,\n fieldCount: graphFields.length,\n scalarCount: graphFields.filter((field) => field.kind === \"scalar\").length,\n relationCount: graphFields.filter((field) => field.kind === \"relation\").length,\n documentCount: graphFields.filter((field) => field.kind === \"document\").length,\n rowCount: 0,\n position: { x: cartIndex * COLUMN_WIDTH, y },\n });\n y += Math.max(MIN_NODE_HEIGHT, 74 + graphFields.length * FIELD_ROW_HEIGHT) + 56;\n });\n });\n\n const nodeIds = new Set(nodes.map((node) => node.id));\n const nodeById = new Map(nodes.map((node) => [node.id, node]));\n const edges: EntityGraphEdge[] = [];\n const edgeKeys = new Set<string>();\n for (const cart of sortedCarts) {\n for (const entity of cart.entities) {\n const source = entityGraphId(cart.name, entity.name);\n const sourceNode = nodeById.get(source);\n for (const field of entity.fields ?? []) {\n const explicitRelation = fieldKind(field) === \"relation\" && !!field.target;\n const inferredTargetNode = explicitRelation ? null : inferTargetNode(field.name, nodes);\n if (!explicitRelation && !inferredTargetNode) continue;\n\n const targetCart = explicitRelation\n ? field.targetCart ?? cart.name\n : inferredTargetNode?.cartridge;\n const targetEntity = explicitRelation ? field.target : inferredTargetNode?.entity;\n if (!targetCart || !targetEntity) continue;\n const target = entityGraphId(targetCart, targetEntity);\n if (!nodeIds.has(source) || !nodeIds.has(target)) continue;\n const targetNode = nodeById.get(target);\n const idField = targetNode?.fields.find((candidate) => candidate.displayName.toLowerCase() === \"id\");\n const targetField = idField?.displayName ?? \"__entity\";\n const sourceGraphField = sourceNode?.fields.find(\n (candidate) => candidate.name === field.name || candidate.displayName === field.name,\n );\n const sourceField = sourceGraphField?.displayName ?? field.fkField ?? field.name;\n const edgeKey = `${source}:${sourceField}->${target}:${targetField}`;\n if (edgeKeys.has(edgeKey)) continue;\n edgeKeys.add(edgeKey);\n if (!explicitRelation && targetNode) markRelationField(sourceNode, sourceField, targetNode);\n edges.push({\n id: `${source}:${field.name}->${target}`,\n source,\n target,\n sourceField,\n targetField,\n label: field.name,\n relationKind: field.relationKind ?? (!explicitRelation ? \"inferred\" : undefined),\n fkField: field.fkField ?? (!explicitRelation ? field.name : undefined),\n });\n }\n }\n }\n\n recomputeNodeCounts(nodes);\n\n return {\n nodes,\n edges,\n totals: makeTotals(nodes, edges),\n };\n}\n\n// Filter to the visible set and re-run layout over exactly those nodes/edges, so\n// toggling entities re-fits the graph rather than leaving stale full-graph gaps.\n// Nodes are cloned before layout mutates their `position`, keeping the cached base\n// model untouched.\nexport function filterEntityGraphModel(\n model: EntityGraphModel,\n visibleIds: Set<string>,\n): EntityGraphModel {\n const nodes = model.nodes\n .filter((node) => visibleIds.has(node.id))\n .map((node) => ({ ...node, position: { ...node.position } }));\n const ids = new Set(nodes.map((node) => node.id));\n const edges = model.edges.filter((edge) => ids.has(edge.source) && ids.has(edge.target));\n layoutNodes(nodes, edges);\n return {\n nodes,\n edges,\n totals: makeTotals(nodes, edges),\n };\n}\n", "import * as React from \"react\"\nimport { Dialog as SheetPrimitive } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\nimport { Button } from \"./button\"\nimport { XIcon } from \"lucide-react\"\n\nfunction Sheet({ ...props }: React.ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />\n}\n\nfunction SheetTrigger({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />\n}\n\nfunction SheetClose({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />\n}\n\nfunction SheetPortal({\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Portal>) {\n return <SheetPrimitive.Portal data-slot=\"sheet-portal\" {...props} />\n}\n\nfunction SheetOverlay({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn(\n \"nimbit-devtools dark fixed inset-0 z-50 bg-black/10 duration-100 supports-backdrop-filter:backdrop-blur-xs data-open:animate-in data-open:fade-in-0 data-closed:animate-out data-closed:fade-out-0\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetContent({\n className,\n children,\n side = \"right\",\n showCloseButton = true,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Content> & {\n side?: \"top\" | \"right\" | \"bottom\" | \"left\"\n showCloseButton?: boolean\n}) {\n return (\n <SheetPortal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n \"nimbit-devtools dark fixed z-50 flex flex-col gap-4 bg-popover bg-clip-padding text-sm text-popover-foreground shadow-lg transition duration-200 ease-in-out data-[side=bottom]:inset-x-0 data-[side=bottom]:bottom-0 data-[side=bottom]:h-auto data-[side=bottom]:border-t data-[side=left]:inset-y-0 data-[side=left]:left-0 data-[side=left]:h-full data-[side=left]:w-3/4 data-[side=left]:border-r data-[side=right]:inset-y-0 data-[side=right]:right-0 data-[side=right]:h-full data-[side=right]:w-3/4 data-[side=right]:border-l data-[side=top]:inset-x-0 data-[side=top]:top-0 data-[side=top]:h-auto data-[side=top]:border-b data-[side=left]:sm:max-w-sm data-[side=right]:sm:max-w-sm data-open:animate-in data-open:fade-in-0 data-[side=bottom]:data-open:slide-in-from-bottom-10 data-[side=left]:data-open:slide-in-from-left-10 data-[side=right]:data-open:slide-in-from-right-10 data-[side=top]:data-open:slide-in-from-top-10 data-closed:animate-out data-closed:fade-out-0 data-[side=bottom]:data-closed:slide-out-to-bottom-10 data-[side=left]:data-closed:slide-out-to-left-10 data-[side=right]:data-closed:slide-out-to-right-10 data-[side=top]:data-closed:slide-out-to-top-10\",\n className\n )}\n {...props}\n >\n {children}\n {showCloseButton && (\n <SheetPrimitive.Close data-slot=\"sheet-close\" asChild>\n <Button\n variant=\"ghost\"\n className=\"absolute top-3 right-3\"\n size=\"icon-sm\"\n >\n <XIcon\n />\n <span className=\"sr-only\">Close</span>\n </Button>\n </SheetPrimitive.Close>\n )}\n </SheetPrimitive.Content>\n </SheetPortal>\n )\n}\n\nfunction SheetHeader({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn(\"flex flex-col gap-0.5 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetFooter({ className, ...props }: React.ComponentProps<\"div\">) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\"mt-auto flex flex-col gap-2 p-4\", className)}\n {...props}\n />\n )\n}\n\nfunction SheetTitle({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn(\n \"text-base font-medium text-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\nfunction SheetDescription({\n className,\n ...props\n}: React.ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\nexport {\n Sheet,\n SheetTrigger,\n SheetClose,\n SheetContent,\n SheetHeader,\n SheetFooter,\n SheetTitle,\n SheetDescription,\n}\n", "import * as React from \"react\"\nimport { cva, type VariantProps } from \"class-variance-authority\"\nimport { Slot } from \"radix-ui\"\n\nimport { cn } from \"../../lib/utils\"\n\nconst buttonVariants = cva(\n \"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all outline-none select-none focus-visible:border-ring focus-visible:ring-3 focus-visible:ring-ring/50 active:not-aria-[haspopup]:translate-y-px disabled:pointer-events-none disabled:opacity-50 aria-invalid:border-destructive aria-invalid:ring-3 aria-invalid:ring-destructive/20 dark:aria-invalid:border-destructive/50 dark:aria-invalid:ring-destructive/40 [&_svg]:pointer-events-none [&_svg]:shrink-0 [&_svg:not([class*='size-'])]:size-4\",\n {\n variants: {\n variant: {\n default: \"bg-primary text-primary-foreground [a]:hover:bg-primary/80\",\n outline:\n \"border-border bg-background hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:border-input dark:bg-input/30 dark:hover:bg-input/50\",\n secondary:\n \"bg-secondary text-secondary-foreground hover:bg-secondary/80 aria-expanded:bg-secondary aria-expanded:text-secondary-foreground\",\n ghost:\n \"hover:bg-muted hover:text-foreground aria-expanded:bg-muted aria-expanded:text-foreground dark:hover:bg-muted/50\",\n destructive:\n \"bg-destructive/10 text-destructive hover:bg-destructive/20 focus-visible:border-destructive/40 focus-visible:ring-destructive/20 dark:bg-destructive/20 dark:hover:bg-destructive/30 dark:focus-visible:ring-destructive/40\",\n link: \"text-primary underline-offset-4 hover:underline\",\n },\n size: {\n default:\n \"h-8 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n xs: \"h-6 gap-1 rounded-[min(var(--radius-md),10px)] px-2 text-xs in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3\",\n sm: \"h-7 gap-1 rounded-[min(var(--radius-md),12px)] px-2.5 text-[0.8rem] in-data-[slot=button-group]:rounded-lg has-data-[icon=inline-end]:pr-1.5 has-data-[icon=inline-start]:pl-1.5 [&_svg:not([class*='size-'])]:size-3.5\",\n lg: \"h-9 gap-1.5 px-2.5 has-data-[icon=inline-end]:pr-2 has-data-[icon=inline-start]:pl-2\",\n icon: \"size-8\",\n \"icon-xs\":\n \"size-6 rounded-[min(var(--radius-md),10px)] in-data-[slot=button-group]:rounded-lg [&_svg:not([class*='size-'])]:size-3\",\n \"icon-sm\":\n \"size-7 rounded-[min(var(--radius-md),12px)] in-data-[slot=button-group]:rounded-lg\",\n \"icon-lg\": \"size-9\",\n },\n },\n defaultVariants: {\n variant: \"default\",\n size: \"default\",\n },\n }\n)\n\nfunction Button({\n className,\n variant = \"default\",\n size = \"default\",\n asChild = false,\n ...props\n}: React.ComponentProps<\"button\"> &\n VariantProps<typeof buttonVariants> & {\n asChild?: boolean\n }) {\n const Comp = asChild ? Slot.Root : \"button\"\n\n return (\n <Comp\n data-slot=\"button\"\n data-variant={variant}\n data-size={size}\n className={cn(buttonVariants({ variant, size, className }))}\n {...props}\n />\n )\n}\n\nexport { Button, buttonVariants }\n", "import React from \"react\";\n\nconst SettingsTab: React.FC = () => {\n return <></>;\n};\n\nexport default SettingsTab;\n", "// Sources tab \u2014 Chrome-DevTools-Sources-style schema editor. File tree on the\n// left, CodeMirror buffer on the right, status bar below. Saves mirror the\n// file into the user's local project folder via POST /_console/dev/file (the\n// console runs with --dev); Apply re-installs the cart from disk, running the\n// user's hand-written pending migrations. Language smarts ride the LSP-over-WS\n// bridge at /_console/dev/lsp.\n\nimport React from \"react\";\nimport { Play, Save } from \"lucide-react\";\nimport { cn } from \"../../../lib/utils\";\nimport { useDevToolsConfig, wsBaseFrom } from \"../../../config\";\nimport { useDevTools } from \"../devtools-context\";\nimport {\n useDevMode,\n useDevFilesApi,\n type DevCart,\n type DevDiagnostic,\n} from \"./use-dev-files\";\nimport { FileTree, type FileSel } from \"./file-tree\";\nimport { NbtEditor } from \"./nbt-editor\";\nimport { NbtLspClient } from \"./lsp-client\";\n\ntype Buffer = { saved: string; current: string; writable: boolean };\n\nconst bufKey = (s: FileSel) => `${s.cart}:${s.path}`;\n\nfunction migrationStamp(): string {\n const d = new Date();\n const p = (n: number) => String(n).padStart(2, \"0\");\n return `${d.getFullYear()}${p(d.getMonth() + 1)}${p(d.getDate())}${p(d.getHours())}${p(d.getMinutes())}${p(d.getSeconds())}`;\n}\n\nconst SourcesTab: React.FC = () => {\n const { apiBaseUrl } = useDevToolsConfig();\n const status = useDevMode();\n const api = useDevFilesApi();\n const { sourcesCart, setSourcesCart, sourcesFile, setSourcesFile, sourcesTreeW, setSourcesTreeW } =\n useDevTools();\n\n const [carts, setCarts] = React.useState<DevCart[]>([]);\n const [buffers, setBuffers] = React.useState<Map<string, Buffer>>(new Map());\n const [statusMsg, setStatusMsg] = React.useState<string>(\"\");\n const [diags, setDiags] = React.useState<DevDiagnostic[]>([]);\n const [applying, setApplying] = React.useState(false);\n\n const selected: FileSel | null =\n sourcesCart && sourcesFile ? { cart: sourcesCart, path: sourcesFile } : null;\n\n // One LSP client for the whole tab, dev-mode only.\n const lspRef = React.useRef<NbtLspClient | null>(null);\n React.useEffect(() => {\n if (!status?.dev) return;\n const client = new NbtLspClient(`${wsBaseFrom(apiBaseUrl)}/_console/dev/lsp`);\n client.initialize(`file://${status.projectRoot}`);\n lspRef.current = client;\n return () => {\n client.dispose();\n lspRef.current = null;\n };\n }, [status?.dev, status?.projectRoot, apiBaseUrl]);\n\n const refreshCarts = React.useCallback(() => {\n api.listCarts().then(setCarts).catch((e) => setStatusMsg(String(e.message ?? e)));\n }, [api]);\n React.useEffect(() => {\n if (status?.dev) refreshCarts();\n }, [status?.dev, refreshCarts]);\n\n const cartOf = React.useCallback(\n (name: string) => carts.find((c) => c.name === name),\n [carts],\n );\n\n const openFile = React.useCallback(\n (sel: FileSel) => {\n setSourcesCart(sel.cart);\n setSourcesFile(sel.path);\n setDiags([]);\n setStatusMsg(\"\");\n const key = bufKey(sel);\n if (buffers.has(key)) return;\n api\n .readFile(sel.cart, sel.path)\n .then(({ content, writable }) => {\n setBuffers((prev) => {\n if (prev.has(key)) return prev;\n const next = new Map(prev);\n next.set(key, { saved: content, current: content, writable });\n return next;\n });\n })\n .catch((e) => setStatusMsg(String(e.message ?? e)));\n },\n [api, buffers, setSourcesCart, setSourcesFile],\n );\n\n // Re-open the persisted selection on mount once carts are known.\n React.useEffect(() => {\n if (selected && carts.length > 0 && !buffers.has(bufKey(selected))) openFile(selected);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [carts]);\n\n const buf = selected ? buffers.get(bufKey(selected)) : undefined;\n const dirtyKeys = React.useMemo(() => {\n const s = new Set<string>();\n for (const [k, b] of buffers) if (b.current !== b.saved) s.add(k);\n return s;\n }, [buffers]);\n\n // Warn before unload with unsaved buffers.\n React.useEffect(() => {\n if (dirtyKeys.size === 0) return;\n const onBeforeUnload = (e: BeforeUnloadEvent) => e.preventDefault();\n window.addEventListener(\"beforeunload\", onBeforeUnload);\n return () => window.removeEventListener(\"beforeunload\", onBeforeUnload);\n }, [dirtyKeys.size]);\n\n const onChange = React.useCallback(\n (text: string) => {\n if (!selected) return;\n const key = bufKey(selected);\n setBuffers((prev) => {\n const b = prev.get(key);\n if (!b || b.current === text) return prev;\n const next = new Map(prev);\n next.set(key, { ...b, current: text });\n return next;\n });\n },\n [selected],\n );\n\n const onSave = React.useCallback(\n (text: string) => {\n if (!selected) return;\n const key = bufKey(selected);\n api\n .writeFile(selected.cart, selected.path, text)\n .then((r) => {\n setDiags(r.diagnostics);\n setStatusMsg(\n r.ok ? `saved ${selected.path}` : `saved ${selected.path} \u2014 ${r.diagnostics.length} problem(s)`,\n );\n setBuffers((prev) => {\n const b = prev.get(key);\n if (!b) return prev;\n const next = new Map(prev);\n next.set(key, { ...b, saved: text, current: text });\n return next;\n });\n refreshCarts(); // a save may add files (new migration dirs)\n })\n .catch((e) => setStatusMsg(`save failed: ${e.message ?? e}`));\n },\n [api, selected, refreshCarts],\n );\n\n const onApply = React.useCallback(() => {\n if (!selected) return;\n setApplying(true);\n setStatusMsg(`applying ${selected.cart}\u2026`);\n api\n .applyCart(selected.cart)\n .then(() => setStatusMsg(`applied ${selected.cart} \u2014 pending migrations ran, cart re-registered`))\n .catch((e) => setStatusMsg(`apply failed: ${e.message ?? e}`))\n .finally(() => setApplying(false));\n }, [api, selected]);\n\n const onNewCart = React.useCallback(\n (name: string) => {\n setStatusMsg(`creating ${name}\u2026`);\n api\n .scaffoldCart(name)\n .then(() => {\n setStatusMsg(`created ${name}`);\n refreshCarts();\n openFile({ cart: name, path: \"schema.nbt\" });\n })\n .catch((e) => setStatusMsg(`scaffold failed: ${e.message ?? e}`));\n },\n [api, refreshCarts, openFile],\n );\n\n const onNewMigration = React.useCallback(\n (cart: string) => {\n const path = `migrations/${migrationStamp()}_change/migration.nbt`;\n const key = `${cart}:${path}`;\n setBuffers((prev) => {\n const next = new Map(prev);\n next.set(key, {\n saved: \"\",\n current: \"migration change {\\n \\n}\\n\",\n writable: true,\n });\n return next;\n });\n setSourcesCart(cart);\n setSourcesFile(path);\n },\n [setSourcesCart, setSourcesFile],\n );\n\n // Goto-definition into another file: map file://<sourceDir>/<rel> back to a\n // cart by longest sourceDir prefix.\n const onGotoDefinition = React.useCallback(\n (uri: string, _line: number) => {\n const path = uri.replace(/^file:\\/\\//, \"\");\n let best: { cart: string; rel: string } | null = null;\n for (const c of carts) {\n if (!c.sourceDir) continue;\n const prefix = `${c.sourceDir}/`;\n if (path.startsWith(prefix) && (!best || prefix.length > best.cart.length)) {\n best = { cart: c.name, rel: path.slice(prefix.length) };\n }\n }\n if (best) openFile({ cart: best.cart, path: best.rel });\n },\n [carts, openFile],\n );\n\n // Tree resize (pattern from data-tab: commit on pointerup-free simple drag).\n const startTreeResize = React.useCallback(\n (e: React.PointerEvent) => {\n e.preventDefault();\n const startX = e.clientX;\n const startW = sourcesTreeW;\n const handle = e.currentTarget as HTMLElement;\n handle.setPointerCapture(e.pointerId);\n const onMove = (ev: PointerEvent) =>\n setSourcesTreeW(Math.max(120, Math.min(480, startW + (ev.clientX - startX))));\n const onUp = () => {\n handle.removeEventListener(\"pointermove\", onMove);\n handle.removeEventListener(\"pointerup\", onUp);\n };\n handle.addEventListener(\"pointermove\", onMove);\n handle.addEventListener(\"pointerup\", onUp);\n },\n [sourcesTreeW, setSourcesTreeW],\n );\n\n if (!status?.dev) {\n return (\n <div className=\"flex h-full items-center justify-center text-[12px] text-muted-foreground\">\n Sources requires the console to run in dev mode (`console up --dev`).\n </div>\n );\n }\n\n const cart = selected ? cartOf(selected.cart) : undefined;\n const editorUri =\n selected && cart?.sourceDir\n ? `file://${cart.sourceDir}/${selected.path}`\n : selected\n ? `file://${status.projectRoot}/.readonly/${selected.cart}/${selected.path}`\n : \"\";\n const isDirty = selected ? dirtyKeys.has(bufKey(selected)) : false;\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"flex min-h-0 flex-1\">\n <div style={{ width: sourcesTreeW }} className=\"shrink-0 border-r border-border\">\n <FileTree\n carts={carts}\n selected={selected}\n dirtyKeys={dirtyKeys}\n onSelect={openFile}\n onNewCart={onNewCart}\n onNewMigration={onNewMigration}\n />\n </div>\n <div\n onPointerDown={startTreeResize}\n style={{ touchAction: \"none\" }}\n className=\"w-1 shrink-0 cursor-ew-resize bg-transparent hover:bg-accent/40\"\n />\n <div className=\"min-h-0 min-w-0 flex-1\">\n {selected && buf ? (\n <NbtEditor\n key={bufKey(selected)}\n uri={editorUri}\n value={buf.current}\n readOnly={!buf.writable}\n lsp={lspRef.current}\n onChange={onChange}\n onSave={onSave}\n onGotoDefinition={onGotoDefinition}\n />\n ) : (\n <div className=\"flex h-full items-center justify-center text-[12px] text-muted-foreground\">\n Select a file \u2014 or create a cartridge with the + button.\n </div>\n )}\n </div>\n </div>\n\n <div className=\"flex h-6 shrink-0 items-center gap-2 border-t border-border px-2 text-[11px]\">\n {selected && buf?.writable && (\n <>\n <button\n type=\"button\"\n onClick={() => buf && onSave(buf.current)}\n className={cn(\n \"flex items-center gap-1 rounded px-1.5 py-0.5 hover:bg-accent\",\n isDirty && \"text-amber-400\",\n )}\n title=\"Save (Ctrl+S) \u2014 mirrors to your local project folder\"\n >\n <Save className=\"size-3\" /> Save\n </button>\n <button\n type=\"button\"\n onClick={onApply}\n disabled={applying || isDirty}\n className=\"flex items-center gap-1 rounded px-1.5 py-0.5 hover:bg-accent disabled:opacity-40\"\n title={\n isDirty\n ? \"Save first\"\n : \"Re-install this cart from disk (runs your pending migrations)\"\n }\n >\n <Play className=\"size-3\" /> Apply\n </button>\n </>\n )}\n {selected && !buf?.writable && (\n <span className=\"text-muted-foreground\">read-only ({cart?.reason ?? \"no source mapping\"})</span>\n )}\n <span className=\"min-w-0 flex-1 truncate text-muted-foreground\">{statusMsg}</span>\n {diags.length > 0 && (\n <span className=\"shrink-0 text-red-400\" title={diags.map((d) => `${d.line}:${d.col} ${d.message}`).join(\"\\n\")}>\n {diags.length} problem{diags.length > 1 ? \"s\" : \"\"}\n </span>\n )}\n </div>\n </div>\n );\n};\n\nexport default SourcesTab;\n", "// Fetchers + hooks for the console's dev-mode editor endpoints\n// (/_console/dev/*). All gated server-side on `console up --dev` \u2014 the status\n// probe 404s otherwise and the Sources tab stays hidden.\n\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useDevToolsConfig } from \"../../../config\";\n\nexport type DevStatus = { dev: boolean; projectRoot: string };\nexport type DevCart = {\n name: string;\n writable: boolean;\n reason?: string;\n sourceDir?: string;\n files: string[];\n};\nexport type DevDiagnostic = {\n message: string;\n severity: number;\n line: number;\n col: number;\n endLine: number;\n endCol: number;\n};\nexport type WriteResult = { ok: boolean; diagnostics: DevDiagnostic[] };\n\nexport function useDevMode(): DevStatus | null {\n const { apiBaseUrl } = useDevToolsConfig();\n const [status, setStatus] = useState<DevStatus | null>(null);\n useEffect(() => {\n let cancelled = false;\n fetch(`${apiBaseUrl}/_console/dev/status`, { credentials: \"include\" })\n .then((r) => (r.ok ? r.json() : null))\n .then((s) => {\n if (!cancelled) setStatus(s && s.dev ? s : null);\n })\n .catch(() => {\n if (!cancelled) setStatus(null);\n });\n return () => {\n cancelled = true;\n };\n }, [apiBaseUrl]);\n return status;\n}\n\nasync function jsonOrThrow(r: Response) {\n const body = await r.json().catch(() => ({}));\n if (!r.ok) throw new Error(body?.error ?? `HTTP ${r.status}`);\n return body;\n}\n\nexport function useDevFilesApi() {\n const { apiBaseUrl } = useDevToolsConfig();\n\n const listCarts = useCallback(\n async (): Promise<DevCart[]> =>\n (await jsonOrThrow(await fetch(`${apiBaseUrl}/_console/dev/carts`, { credentials: \"include\" }))).carts ?? [],\n [apiBaseUrl],\n );\n\n const readFile = useCallback(\n async (cart: string, path: string): Promise<{ content: string; writable: boolean }> =>\n jsonOrThrow(\n await fetch(\n `${apiBaseUrl}/_console/dev/file?cart=${encodeURIComponent(cart)}&path=${encodeURIComponent(path)}`,\n { credentials: \"include\" },\n ),\n ),\n [apiBaseUrl],\n );\n\n const writeFile = useCallback(\n async (cart: string, path: string, content: string): Promise<WriteResult> =>\n jsonOrThrow(\n await fetch(`${apiBaseUrl}/_console/dev/file`, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ cart, path, content }),\n }),\n ),\n [apiBaseUrl],\n );\n\n const applyCart = useCallback(\n async (cart: string): Promise<{ ok: boolean; cart: string }> =>\n jsonOrThrow(\n await fetch(`${apiBaseUrl}/_console/dev/apply`, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ cart }),\n }),\n ),\n [apiBaseUrl],\n );\n\n const scaffoldCart = useCallback(\n async (name: string): Promise<{ ok: boolean; cart: string; sourceDir: string }> =>\n jsonOrThrow(\n await fetch(`${apiBaseUrl}/_console/dev/scaffold`, {\n method: \"POST\",\n credentials: \"include\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify({ name }),\n }),\n ),\n [apiBaseUrl],\n );\n\n return { listCarts, readFile, writeFile, applyCart, scaffoldCart };\n}\n", "// Left rail of the Sources tab: carts and their .nbt files. Writable carts\n// (dev source mapping) are editable; bundled/unmapped carts show a lock.\n\nimport React from \"react\";\nimport { Lock, Plus, FilePlus2 } from \"lucide-react\";\nimport { cn } from \"../../../lib/utils\";\nimport type { DevCart } from \"./use-dev-files\";\n\nexport type FileSel = { cart: string; path: string };\n\ntype Props = {\n carts: DevCart[];\n selected: FileSel | null;\n dirtyKeys: Set<string>;\n onSelect: (sel: FileSel) => void;\n onNewCart: (name: string) => void;\n onNewMigration: (cart: string) => void;\n};\n\nexport const FileTree: React.FC<Props> = ({\n carts,\n selected,\n dirtyKeys,\n onSelect,\n onNewCart,\n onNewMigration,\n}) => {\n const [creating, setCreating] = React.useState(false);\n const [newName, setNewName] = React.useState(\"\");\n\n const submitNew = () => {\n const name = newName.trim();\n if (/^[a-z][a-z0-9_]*$/.test(name)) {\n onNewCart(name);\n setNewName(\"\");\n setCreating(false);\n }\n };\n\n return (\n <div className=\"flex h-full min-h-0 flex-col\">\n <div className=\"flex h-6 shrink-0 items-center justify-between border-b border-border px-2\">\n <span className=\"text-[11px] font-medium text-muted-foreground\">Cartridges</span>\n <button\n type=\"button\"\n title=\"New cartridge\"\n onClick={() => setCreating((v) => !v)}\n className=\"rounded p-0.5 hover:bg-accent\"\n >\n <Plus className=\"size-3.5\" />\n </button>\n </div>\n {creating && (\n <div className=\"flex items-center gap-1 border-b border-border p-1\">\n <input\n autoFocus\n value={newName}\n onChange={(e) => setNewName(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\") submitNew();\n if (e.key === \"Escape\") setCreating(false);\n }}\n placeholder=\"cart_name\"\n className=\"h-5 w-full rounded border border-border bg-background px-1 text-[11px] outline-none\"\n />\n <button\n type=\"button\"\n onClick={submitNew}\n disabled={!/^[a-z][a-z0-9_]*$/.test(newName.trim())}\n className=\"rounded px-1 text-[11px] hover:bg-accent disabled:opacity-40\"\n >\n Create\n </button>\n </div>\n )}\n <div className=\"min-h-0 flex-1 overflow-y-auto py-1\">\n {carts.map((cart) => (\n <div key={cart.name} className=\"mb-1\">\n <div className=\"flex items-center justify-between px-2 py-0.5\">\n <span className=\"flex items-center gap-1 text-[11px] font-medium\">\n {cart.name}\n {!cart.writable && (\n <Lock\n className=\"size-3 text-muted-foreground\"\n aria-label={cart.reason ?? \"read-only\"}\n />\n )}\n </span>\n {cart.writable && (\n <button\n type=\"button\"\n title=\"New migration\"\n onClick={() => onNewMigration(cart.name)}\n className=\"rounded p-0.5 text-muted-foreground hover:bg-accent\"\n >\n <FilePlus2 className=\"size-3\" />\n </button>\n )}\n </div>\n {cart.files.map((path) => {\n const key = `${cart.name}:${path}`;\n const isSel = selected?.cart === cart.name && selected?.path === path;\n return (\n <button\n key={path}\n type=\"button\"\n onClick={() => onSelect({ cart: cart.name, path })}\n data-active={isSel}\n className={cn(\n \"flex w-full items-center gap-1 truncate py-0.5 pl-4 pr-2 text-left text-[11px]\",\n \"hover:bg-accent data-[active=true]:bg-accent\",\n )}\n >\n <span className=\"truncate\">{path}</span>\n {dirtyKeys.has(key) && (\n <span className=\"size-1.5 shrink-0 rounded-full bg-amber-400\" title=\"unsaved\" />\n )}\n </button>\n );\n })}\n </div>\n ))}\n </div>\n </div>\n );\n};\n", "// CodeMirror 6 React wrapper for one NBT buffer. Recreated per uri (keyed by\n// the host); owns the EditorView lifecycle, Ctrl+S save, and the LSP wiring.\n\nimport React from \"react\";\nimport { EditorState } from \"@codemirror/state\";\nimport {\n EditorView,\n keymap,\n lineNumbers,\n drawSelection,\n highlightActiveLine,\n} from \"@codemirror/view\";\nimport {\n defaultKeymap,\n history,\n historyKeymap,\n indentWithTab,\n} from \"@codemirror/commands\";\nimport {\n syntaxHighlighting,\n defaultHighlightStyle,\n bracketMatching,\n} from \"@codemirror/language\";\nimport { lintGutter } from \"@codemirror/lint\";\nimport { searchKeymap } from \"@codemirror/search\";\nimport { completionKeymap, closeBrackets } from \"@codemirror/autocomplete\";\nimport { nbtLanguageSupport } from \"./nbt-language\";\nimport { lspExtensions, type GotoDefHandler } from \"./lsp-extensions\";\nimport { NbtLspClient } from \"./lsp-client\";\n\n// Match the devtools panel chrome via its CSS variables (we render inside the\n// .nimbit-devtools subtree, so these resolve to the scoped theme).\nconst nbtTheme = EditorView.theme(\n {\n \"&\": {\n height: \"100%\",\n fontSize: \"12px\",\n backgroundColor: \"var(--background)\",\n color: \"var(--foreground)\",\n },\n \".cm-content\": { fontFamily: \"ui-monospace, monospace\" },\n \".cm-gutters\": {\n backgroundColor: \"var(--background)\",\n color: \"var(--muted-foreground)\",\n borderRight: \"1px solid var(--border)\",\n },\n \".cm-activeLine\": { backgroundColor: \"color-mix(in srgb, var(--accent) 35%, transparent)\" },\n \"&.cm-focused\": { outline: \"none\" },\n \".cm-tooltip\": {\n backgroundColor: \"var(--popover)\",\n color: \"var(--popover-foreground)\",\n border: \"1px solid var(--border)\",\n },\n },\n { dark: true },\n);\n\nexport type NbtEditorProps = {\n uri: string;\n value: string;\n readOnly?: boolean;\n lsp?: NbtLspClient | null;\n onChange?: (text: string) => void;\n onSave?: (text: string) => void;\n onGotoDefinition?: GotoDefHandler;\n};\n\nexport const NbtEditor: React.FC<NbtEditorProps> = ({\n uri,\n value,\n readOnly = false,\n lsp,\n onChange,\n onSave,\n onGotoDefinition,\n}) => {\n const hostRef = React.useRef<HTMLDivElement | null>(null);\n const viewRef = React.useRef<EditorView | null>(null);\n\n // Latest callbacks without recreating the view.\n const onChangeRef = React.useRef(onChange);\n onChangeRef.current = onChange;\n const onSaveRef = React.useRef(onSave);\n onSaveRef.current = onSave;\n const onGotoRef = React.useRef(onGotoDefinition);\n onGotoRef.current = onGotoDefinition;\n\n React.useEffect(() => {\n const host = hostRef.current;\n if (!host) return;\n\n const extensions = [\n lineNumbers(),\n history(),\n drawSelection(),\n highlightActiveLine(),\n bracketMatching(),\n closeBrackets(),\n lintGutter(),\n syntaxHighlighting(defaultHighlightStyle, { fallback: true }),\n nbtLanguageSupport(),\n nbtTheme,\n keymap.of([\n {\n key: \"Mod-s\",\n run: (view) => {\n onSaveRef.current?.(view.state.doc.toString());\n return true;\n },\n },\n ...defaultKeymap,\n ...historyKeymap,\n ...searchKeymap,\n ...completionKeymap,\n indentWithTab,\n ]),\n EditorView.updateListener.of((u) => {\n if (u.docChanged) onChangeRef.current?.(u.state.doc.toString());\n }),\n EditorState.readOnly.of(readOnly),\n ];\n if (lsp && !readOnly) {\n extensions.push(\n lspExtensions(lsp, uri, (defUri, line) => onGotoRef.current?.(defUri, line)),\n );\n }\n\n const view = new EditorView({\n state: EditorState.create({ doc: value, extensions }),\n parent: host,\n });\n viewRef.current = view;\n return () => {\n view.destroy();\n viewRef.current = null;\n };\n // Recreate per buffer identity / mode; `value` is only the initial doc.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [uri, readOnly, lsp]);\n\n return <div ref={hostRef} className=\"h-full min-h-0 overflow-hidden\" />;\n};\n", "// NBT syntax highlighting for CodeMirror 6 \u2014 a StreamLanguage tokenizer ported\n// from the console tokenizer (modules/lang_common/scan.jai) and the VSCode\n// grammar (editors/vscode/nbt/syntaxes/nbt.tmLanguage.json). Highlighting is\n// local; everything semantic (diagnostics/completion/hover) comes via the LSP.\n\nimport {\n StreamLanguage,\n LanguageSupport,\n indentUnit,\n type StreamParser,\n} from \"@codemirror/language\";\n\nconst KEYWORDS = new Set([\n \"entity\", \"enum\", \"struct\", \"const\", \"export\", \"extends\",\n \"fn\", \"on\", \"action\", \"activity\", \"task\", \"variant\", \"workflow\", \"command\",\n \"middleware\", \"schedule\", \"every\", \"jai\",\n \"migration\", \"test\", \"mock\", \"assert\",\n \"cartridge\", \"service\", \"component\", \"app\", \"route\", \"layout\",\n \"import\", \"from\",\n \"if\", \"elif\", \"else\", \"while\", \"for\", \"in\", \"return\", \"break\", \"continue\",\n \"delete\", \"defer\", \"print\", \"sleep\", \"fail\",\n]);\n\nconst TYPES = new Set([\n \"string\", \"bool\", \"ulid\", \"document\", \"dict\", \"blob\", \"DateTime\",\n \"u8\", \"u16\", \"u32\", \"u64\", \"s8\", \"s16\", \"s32\", \"s64\",\n \"int\", \"integer\", \"float\", \"float64\", \"f32\", \"f64\", \"double\",\n \"time\", \"bytes\", \"any\", \"name\", \"ref\",\n]);\n\ntype NbtState = {\n tripleString: boolean;\n};\n\n// NBT strings carry NO escapes (scan.jai consumes to the bare closing quote),\n// so a backslash before a quote does not extend the string.\nfunction eatSingleLineString(stream: StringStream, quote: string): string {\n while (!stream.eol()) {\n if (stream.next() === quote) break;\n }\n return \"string\";\n}\n\ntype StringStream = Parameters<StreamParser<NbtState>[\"token\"]>[0];\n\nconst nbtParser: StreamParser<NbtState> = {\n name: \"nbt\",\n startState: () => ({ tripleString: false }),\n token(stream, state) {\n if (state.tripleString) {\n while (!stream.eol()) {\n if (stream.match('\"\"\"')) {\n state.tripleString = false;\n return \"string\";\n }\n stream.next();\n }\n return \"string\";\n }\n\n if (stream.eatSpace()) return null;\n\n const ch = stream.peek();\n if (ch == null) return null;\n\n if (ch === \"#\") {\n stream.skipToEnd();\n return \"comment\";\n }\n\n if (stream.match('\"\"\"')) {\n state.tripleString = true;\n // Rest of line is string body unless it closes on the same line.\n while (!stream.eol()) {\n if (stream.match('\"\"\"')) {\n state.tripleString = false;\n return \"string\";\n }\n stream.next();\n }\n return \"string\";\n }\n\n if (ch === '\"') {\n stream.next();\n return eatSingleLineString(stream, '\"');\n }\n if (ch === \"'\") {\n // Like the scanner: only a string opener when not glued to an identifier\n // (lets contractions inside docs pass).\n const before = stream.string.charAt(stream.pos - 1);\n if (!/[A-Za-z0-9_]/.test(before)) {\n stream.next();\n return eatSingleLineString(stream, \"'\");\n }\n stream.next();\n return null;\n }\n\n // f-strings: f\"...\" \u2014 body highlighted as a string (interpolation holes\n // are cosmetic only).\n if (ch === \"f\" && stream.string.charAt(stream.pos + 1) === '\"') {\n stream.next();\n stream.next();\n return eatSingleLineString(stream, '\"');\n }\n\n // @attr / @@attr\n if (ch === \"@\") {\n stream.next();\n stream.eat(\"@\");\n stream.eatWhile(/[A-Za-z0-9_]/);\n return \"meta\";\n }\n\n // Numbers. The optional fraction backtracks on `0..9` ranges (matches \"0\",\n // not \"0.\").\n if (/\\d/.test(ch)) {\n stream.match(/^\\d+(\\.\\d+)?/);\n return \"number\";\n }\n\n if (/[A-Za-z_]/.test(ch)) {\n stream.eatWhile(/[A-Za-z0-9_]/);\n const word = stream.current();\n if (word === \"true\" || word === \"false\") return \"atom\";\n if (KEYWORDS.has(word)) return \"keyword\";\n if (TYPES.has(word)) return \"typeName\";\n if (/^[A-Z]/.test(word)) return \"typeName\"; // entity/enum references\n return \"variableName\";\n }\n\n if (/[+\\-*/=<>!&|?.,:;]/.test(ch)) {\n stream.next();\n stream.eatWhile(/[+\\-*/=<>!&|.]/);\n return \"operator\";\n }\n\n stream.next();\n return null;\n },\n languageData: {\n commentTokens: { line: \"#\" },\n },\n};\n\nexport const nbtLanguage = StreamLanguage.define(nbtParser);\n\nexport function nbtLanguageSupport(): LanguageSupport {\n return new LanguageSupport(nbtLanguage, [indentUnit.of(\" \")]);\n}\n", "// CodeMirror extensions wiring an editor buffer to the NbtLspClient:\n// full-text didChange sync (debounced), pushed publishDiagnostics \u2192 lint,\n// completion, hover, and F12 go-to-definition.\n\nimport { type Extension, type Text } from \"@codemirror/state\";\nimport {\n EditorView,\n ViewPlugin,\n type ViewUpdate,\n hoverTooltip,\n keymap,\n} from \"@codemirror/view\";\nimport {\n autocompletion,\n type CompletionContext,\n type CompletionResult,\n} from \"@codemirror/autocomplete\";\nimport { setDiagnostics, type Diagnostic } from \"@codemirror/lint\";\nimport {\n NbtLspClient,\n type LspDiagnostic,\n type LspPosition,\n type LspCompletionItem,\n type LspLocation,\n} from \"./lsp-client\";\n\nfunction toLspPos(doc: Text, offset: number): LspPosition {\n const line = doc.lineAt(offset);\n return { line: line.number - 1, character: offset - line.from };\n}\n\nfunction fromLspPos(doc: Text, pos: LspPosition): number {\n const lineNo = Math.min(Math.max(pos.line + 1, 1), doc.lines);\n const line = doc.line(lineNo);\n return Math.min(line.from + Math.max(pos.character, 0), line.to);\n}\n\nfunction toCmDiagnostics(doc: Text, diags: LspDiagnostic[]): Diagnostic[] {\n return diags.map((d) => {\n const from = fromLspPos(doc, d.range.start);\n let to = fromLspPos(doc, d.range.end);\n if (to <= from) to = Math.min(from + 1, doc.length);\n const severity =\n d.severity === 2 ? \"warning\" : d.severity === 3 || d.severity === 4 ? \"info\" : \"error\";\n return { from, to, severity, message: d.message, source: d.source ?? \"nbt\" };\n });\n}\n\n// LSP CompletionItemKind \u2192 CM completion type (drives the icon).\nfunction completionType(kind?: number): string {\n switch (kind) {\n case 3: return \"function\";\n case 5: return \"property\";\n case 13: return \"enum\";\n case 14: return \"keyword\";\n case 22: return \"class\";\n default: return \"variable\";\n }\n}\n\nexport type GotoDefHandler = (uri: string, line: number) => void;\n\nexport function lspExtensions(\n client: NbtLspClient,\n uri: string,\n onGotoDefinition?: GotoDefHandler,\n): Extension[] {\n // Sync + diagnostics plugin. didOpen on create, debounced didChange,\n // diagnostics pushed by the server are dispatched into the lint state.\n const syncPlugin = ViewPlugin.fromClass(\n class {\n private timer: ReturnType<typeof setTimeout> | null = null;\n private unsubscribe: () => void;\n\n constructor(readonly view: EditorView) {\n client.didOpen(uri, view.state.doc.toString());\n this.unsubscribe = client.onDiagnostics(uri, (diags) => {\n const cm = toCmDiagnostics(this.view.state.doc, diags);\n this.view.dispatch(setDiagnostics(this.view.state, cm));\n });\n }\n\n update(u: ViewUpdate) {\n if (!u.docChanged) return;\n if (this.timer) clearTimeout(this.timer);\n this.timer = setTimeout(() => {\n this.timer = null;\n client.didChange(uri, this.view.state.doc.toString());\n }, 200);\n }\n\n destroy() {\n if (this.timer) {\n clearTimeout(this.timer);\n client.didChange(uri, this.view.state.doc.toString());\n }\n this.unsubscribe();\n }\n },\n );\n\n const completionSource = async (\n ctx: CompletionContext,\n ): Promise<CompletionResult | null> => {\n const word = ctx.matchBefore(/\\w*/);\n if (!word) return null;\n if (word.from === word.to && !ctx.explicit) {\n // Only fire automatically right after a trigger character.\n const before = ctx.state.doc.sliceString(Math.max(0, ctx.pos - 1), ctx.pos);\n if (before !== \".\" && before !== \":\" && before !== '\"') return null;\n }\n // Flush any pending edit so the server completes against the live buffer.\n client.didChange(uri, ctx.state.doc.toString());\n let result;\n try {\n result = await client.completion(uri, toLspPos(ctx.state.doc, ctx.pos));\n } catch {\n return null;\n }\n const items: LspCompletionItem[] = Array.isArray(result)\n ? result\n : (result?.items ?? []);\n if (items.length === 0) return null;\n return {\n from: word.from,\n options: items.map((it) => ({\n label: it.label,\n type: completionType(it.kind),\n detail: it.detail,\n })),\n };\n };\n\n const hover = hoverTooltip(async (view, pos) => {\n let result;\n try {\n result = await client.hover(uri, toLspPos(view.state.doc, pos));\n } catch {\n return null;\n }\n const value = result?.contents?.value;\n if (!value) return null;\n return {\n pos,\n create: () => {\n const dom = document.createElement(\"pre\");\n dom.className = \"nbt-hover-tooltip\";\n dom.style.cssText =\n \"margin:0;padding:6px 8px;max-width:480px;white-space:pre-wrap;font-size:11px;\";\n // Server emits fenced markdown code blocks; strip the fences, show text.\n dom.textContent = value.replace(/```\\w*\\n?/g, \"\");\n return { dom };\n },\n };\n });\n\n const gotoDef = keymap.of([\n {\n key: \"F12\",\n run: (view) => {\n const pos = toLspPos(view.state.doc, view.state.selection.main.head);\n client\n .definition(uri, pos)\n .then((result) => {\n const loc: LspLocation | null = Array.isArray(result)\n ? (result[0] ?? null)\n : result;\n if (!loc?.uri) return;\n if (loc.uri === uri) {\n const off = fromLspPos(view.state.doc, loc.range.start);\n view.dispatch({\n selection: { anchor: off },\n scrollIntoView: true,\n });\n } else {\n onGotoDefinition?.(loc.uri, loc.range.start.line);\n }\n })\n .catch(() => {});\n return true;\n },\n },\n ]);\n\n return [\n syncPlugin,\n autocompletion({ override: [completionSource] }),\n hover,\n gotoDef,\n ];\n}\n", "// Minimal LSP client over WebSocket for the console's dev-mode nbt_lsp bridge\n// (/_console/dev/lsp). One JSON-RPC message per WS text frame \u2014 no\n// Content-Length framing (the bridge's write_proc emits bare JSON).\n//\n// Hand-rolled on purpose: the server speaks ~10 methods with full-text sync,\n// and a library client (codemirror-languageserver) would drag transitive\n// runtime deps into every host app.\n\nexport type LspPosition = { line: number; character: number };\nexport type LspRange = { start: LspPosition; end: LspPosition };\nexport type LspDiagnostic = {\n range: LspRange;\n severity?: number; // 1=error 2=warning 3=info 4=hint\n message: string;\n source?: string;\n};\nexport type LspCompletionItem = {\n label: string;\n kind?: number;\n detail?: string;\n};\nexport type LspLocation = { uri: string; range: LspRange };\n\ntype Pending = {\n resolve: (v: unknown) => void;\n reject: (e: Error) => void;\n};\n\nexport class NbtLspClient {\n private url: string;\n private rootUri: string | null = null;\n private ws: WebSocket | null = null;\n private nextId = 1;\n private pending = new Map<number, Pending>();\n private diagHandlers = new Map<string, (d: LspDiagnostic[]) => void>();\n // Open buffers, kept for replay across reconnects.\n private docs = new Map<string, { text: string; version: number }>();\n private ready = false;\n private queue: string[] = [];\n private closed = false;\n private retryMs = 500;\n\n constructor(url: string) {\n this.url = url;\n this.connect();\n }\n\n dispose() {\n this.closed = true;\n this.ws?.close();\n this.pending.forEach((p) => p.reject(new Error(\"lsp client disposed\")));\n this.pending.clear();\n }\n\n private connect() {\n if (this.closed) return;\n const ws = new WebSocket(this.url);\n this.ws = ws;\n ws.onopen = () => {\n this.retryMs = 500;\n if (this.rootUri) this.sendInitialize(this.rootUri);\n };\n ws.onmessage = (ev) => {\n if (typeof ev.data !== \"string\") return;\n this.onMessage(ev.data);\n };\n ws.onclose = () => {\n this.ready = false;\n this.ws = null;\n for (const p of this.pending.values())\n p.reject(new Error(\"lsp connection closed\"));\n this.pending.clear();\n if (!this.closed) {\n setTimeout(() => this.connect(), this.retryMs);\n this.retryMs = Math.min(this.retryMs * 2, 10_000);\n }\n };\n }\n\n // Called once by the host with file://<projectRoot>; also re-sent after every\n // reconnect, followed by didOpen replays for tracked buffers.\n initialize(rootUri: string) {\n this.rootUri = rootUri;\n if (this.ws?.readyState === WebSocket.OPEN) this.sendInitialize(rootUri);\n }\n\n private sendInitialize(rootUri: string) {\n const id = this.nextId++;\n this.pending.set(id, {\n resolve: () => {\n this.sendRaw({ jsonrpc: \"2.0\", method: \"initialized\", params: {} });\n this.ready = true;\n for (const [uri, d] of this.docs) {\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didOpen\",\n params: {\n textDocument: {\n uri,\n languageId: \"nbt\",\n version: d.version,\n text: d.text,\n },\n },\n });\n }\n const q = this.queue;\n this.queue = [];\n for (const m of q) this.ws?.send(m);\n },\n reject: () => {},\n });\n this.ws?.send(\n JSON.stringify({\n jsonrpc: \"2.0\",\n id,\n method: \"initialize\",\n params: { rootUri },\n }),\n );\n }\n\n private sendRaw(msg: object) {\n const s = JSON.stringify(msg);\n if (this.ready && this.ws?.readyState === WebSocket.OPEN) this.ws.send(s);\n else this.queue.push(s);\n }\n\n private onMessage(data: string) {\n let msg: any;\n try {\n msg = JSON.parse(data);\n } catch {\n return;\n }\n if (msg.id != null && (msg.result !== undefined || msg.error)) {\n const p = this.pending.get(msg.id);\n if (!p) return;\n this.pending.delete(msg.id);\n if (msg.error) p.reject(new Error(msg.error.message ?? \"lsp error\"));\n else p.resolve(msg.result);\n return;\n }\n if (msg.method === \"textDocument/publishDiagnostics\") {\n const uri = msg.params?.uri as string;\n const handler = this.diagHandlers.get(uri);\n if (handler) handler((msg.params?.diagnostics ?? []) as LspDiagnostic[]);\n }\n }\n\n request<T>(method: string, params: object): Promise<T> {\n const id = this.nextId++;\n const p = new Promise<T>((resolve, reject) => {\n this.pending.set(id, { resolve: resolve as Pending[\"resolve\"], reject });\n });\n this.sendRaw({ jsonrpc: \"2.0\", id, method, params });\n return p;\n }\n\n onDiagnostics(uri: string, handler: (d: LspDiagnostic[]) => void): () => void {\n this.diagHandlers.set(uri, handler);\n return () => {\n if (this.diagHandlers.get(uri) === handler) this.diagHandlers.delete(uri);\n };\n }\n\n didOpen(uri: string, text: string) {\n const existing = this.docs.get(uri);\n if (existing) {\n // Re-opening an already-tracked buffer (tab switch) \u2014 just resync.\n this.didChange(uri, text);\n return;\n }\n this.docs.set(uri, { text, version: 1 });\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didOpen\",\n params: { textDocument: { uri, languageId: \"nbt\", version: 1, text } },\n });\n }\n\n didChange(uri: string, text: string) {\n const d = this.docs.get(uri);\n if (!d) return this.didOpen(uri, text);\n if (d.text === text) return;\n d.text = text;\n d.version += 1;\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didChange\",\n params: {\n textDocument: { uri, version: d.version },\n contentChanges: [{ text }],\n },\n });\n }\n\n didClose(uri: string) {\n if (!this.docs.delete(uri)) return;\n this.sendRaw({\n jsonrpc: \"2.0\",\n method: \"textDocument/didClose\",\n params: { textDocument: { uri } },\n });\n }\n\n completion(uri: string, pos: LspPosition): Promise<{ items: LspCompletionItem[] } | LspCompletionItem[] | null> {\n return this.request(\"textDocument/completion\", {\n textDocument: { uri },\n position: pos,\n });\n }\n\n hover(uri: string, pos: LspPosition): Promise<{ contents?: { value?: string } } | null> {\n return this.request(\"textDocument/hover\", {\n textDocument: { uri },\n position: pos,\n });\n }\n\n definition(uri: string, pos: LspPosition): Promise<LspLocation | LspLocation[] | null> {\n return this.request(\"textDocument/definition\", {\n textDocument: { uri },\n position: pos,\n });\n }\n}\n", "import React from \"react\";\nimport { DevToolsConfigProvider } from \"./config\";\nimport { DevToolsProvider } from \"./components/devtools/devtools-context\";\nimport DevTools from \"./components/devtools/dev-tools\";\n\nexport type NimbitDevToolsProps = {\n // Base URL of the NBT console (e.g. \"https://console.example.com\").\n // Omit / empty string => same-origin (the panel is served by the console).\n apiBaseUrl?: string;\n defaultActiveTab?: string;\n};\n\n// Drop-in devtools panel. Mount once near your app root; it renders nothing\n// until toggled open via `toggleDevTools()` (or a `devtools-toggle` window event).\nexport const NimbitDevTools: React.FC<NimbitDevToolsProps> = ({\n apiBaseUrl = \"\",\n defaultActiveTab,\n}) => (\n <DevToolsConfigProvider apiBaseUrl={apiBaseUrl}>\n <DevToolsProvider defaultActiveTab={defaultActiveTab}>\n <DevTools />\n </DevToolsProvider>\n </DevToolsConfigProvider>\n);\n\nexport default NimbitDevTools;\n\n// Open/close the panel from anywhere (keybinding, button, command palette).\nexport function toggleDevTools(): void {\n window.dispatchEvent(new CustomEvent(\"devtools-toggle\"));\n}\n\nexport {\n DevToolsProvider,\n useDevTools,\n} from \"./components/devtools/devtools-context\";\nexport { DevToolsConfigProvider, useDevToolsConfig } from \"./config\";\nexport type { DevToolsConfig } from \"./config\";\nexport { default as DevTools } from \"./components/devtools/dev-tools\";\nexport type {\n DevToolsDock,\n DevToolsTab,\n DevToolsSize,\n} from \"./components/devtools/devtools-context\";\n\n// The CM6 NBT editor, exported for host apps that show NBT source (e.g. the\n// nbt.dev builder's generated-schema panel). readOnly + no lsp = viewer.\nexport { NbtEditor } from \"./components/devtools/sources/nbt-editor\";\nexport type { NbtEditorProps } from \"./components/devtools/sources/nbt-editor\";\nexport { nbtLanguageSupport } from \"./components/devtools/sources/nbt-language\";\n"],
5
+ "mappings": "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",
6
+ "names": ["React", "jsx", "React", "createPortal", "X", "React", "jsx", "React", "jsx", "React", "useEffect", "useEffect", "React", "useEffect", "useState", "useState", "useEffect", "React", "React", "React", "jsx", "jsxs", "React", "jsx", "jsxs", "React", "React", "Fragment", "jsx", "jsxs", "jsx", "jsxs", "React", "jsx", "jsx", "jsxs", "jsx", "jsxs", "jsx", "jsx", "jsxs", "React", "Fragment", "jsx", "React", "Play", "useEffect", "useState", "useState", "useEffect", "React", "jsx", "jsxs", "React", "React", "EditorView", "keymap", "jsx", "EditorView", "React", "keymap", "view", "Fragment", "jsx", "jsxs", "React", "cart", "Play", "jsx", "jsxs", "React", "createPortal", "X", "jsx"]
7
7
  }