@backbay/glia 0.2.0-alpha.6 → 0.2.0-alpha.8
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/audio/index.js +1145 -5
- package/dist/audio/index.js.map +1 -1
- package/dist/components/index.js +3187 -10
- package/dist/components/index.js.map +1 -1
- package/dist/core.js +19714 -12
- package/dist/core.js.map +1 -1
- package/dist/emotion/index.js +1 -1
- package/dist/emotion/index.js.map +1 -1
- package/dist/hooks/index.js +941 -6
- package/dist/hooks/index.js.map +1 -1
- package/dist/index.js +31841 -183
- package/dist/index.js.map +1 -1
- package/dist/primitives/index.js +21111 -57
- package/dist/primitives/index.js.map +1 -1
- package/dist/protocol/index.js +360 -2
- package/dist/protocol/index.js.map +1 -1
- package/dist/speakeasy/index.js +2786 -38
- package/dist/speakeasy/index.js.map +1 -1
- package/dist/styles.css +1 -1
- package/dist/theme/index.js +1150 -3
- package/dist/theme/index.js.map +1 -1
- package/dist/vision/index.js +370 -2
- package/dist/vision/index.js.map +1 -1
- package/dist/workspace/index.js +16824 -2
- package/dist/workspace/index.js.map +1 -1
- package/package.json +16 -10
- package/dist/AuroraBackground-AP6ZHVFA.js +0 -6
- package/dist/AuroraBackground-AP6ZHVFA.js.map +0 -1
- package/dist/BentoGrid-CDARICNM.js +0 -6
- package/dist/BentoGrid-CDARICNM.js.map +0 -1
- package/dist/CommandPalette-JCWJKRBY.js +0 -6
- package/dist/CommandPalette-JCWJKRBY.js.map +0 -1
- package/dist/Glass-H4X4ZI4P.js +0 -7
- package/dist/Glass-H4X4ZI4P.js.map +0 -1
- package/dist/GlitchText-KLQ57PPY.js +0 -6
- package/dist/GlitchText-KLQ57PPY.js.map +0 -1
- package/dist/GlowButton-VGBPMZO7.js +0 -6
- package/dist/GlowButton-VGBPMZO7.js.map +0 -1
- package/dist/Graph3D-GO7N2EZQ.js +0 -540
- package/dist/Graph3D-GO7N2EZQ.js.map +0 -1
- package/dist/HUDProgressRing-N6C5NAEV.js +0 -6
- package/dist/HUDProgressRing-N6C5NAEV.js.map +0 -1
- package/dist/KPIStat-PBQK27ZB.js +0 -6
- package/dist/KPIStat-PBQK27ZB.js.map +0 -1
- package/dist/NeonToast-W5F7MU3U.js +0 -6
- package/dist/NeonToast-W5F7MU3U.js.map +0 -1
- package/dist/ParticleField-WK6CNHWU.js +0 -51
- package/dist/ParticleField-WK6CNHWU.js.map +0 -1
- package/dist/TextGenerateEffect-EUCEIIUJ.js +0 -6
- package/dist/TextGenerateEffect-EUCEIIUJ.js.map +0 -1
- package/dist/ThreeDCard-VH5I3SSY.js +0 -6
- package/dist/ThreeDCard-VH5I3SSY.js.map +0 -1
- package/dist/TypingAnimation-GIWOHPIX.js +0 -6
- package/dist/TypingAnimation-GIWOHPIX.js.map +0 -1
- package/dist/alert-dialog-QOSYBIIE.js +0 -19
- package/dist/alert-dialog-QOSYBIIE.js.map +0 -1
- package/dist/avatar-N5R37PCU.js +0 -10
- package/dist/avatar-N5R37PCU.js.map +0 -1
- package/dist/badge-GTVIIGPY.js +0 -8
- package/dist/badge-GTVIIGPY.js.map +0 -1
- package/dist/button-D7IMSV2D.js +0 -8
- package/dist/button-D7IMSV2D.js.map +0 -1
- package/dist/chunk-3CMPQOMY.js +0 -69
- package/dist/chunk-3CMPQOMY.js.map +0 -1
- package/dist/chunk-3OQT6IYR.js +0 -41
- package/dist/chunk-3OQT6IYR.js.map +0 -1
- package/dist/chunk-43B2WVLS.js +0 -85
- package/dist/chunk-43B2WVLS.js.map +0 -1
- package/dist/chunk-4SRFO5W3.js +0 -121
- package/dist/chunk-4SRFO5W3.js.map +0 -1
- package/dist/chunk-5IZELOOU.js +0 -362
- package/dist/chunk-5IZELOOU.js.map +0 -1
- package/dist/chunk-6DM4ACSS.js +0 -154
- package/dist/chunk-6DM4ACSS.js.map +0 -1
- package/dist/chunk-6IGT34PC.js +0 -50
- package/dist/chunk-6IGT34PC.js.map +0 -1
- package/dist/chunk-6RKBCJHN.js +0 -194
- package/dist/chunk-6RKBCJHN.js.map +0 -1
- package/dist/chunk-6RX2WGCO.js +0 -108
- package/dist/chunk-6RX2WGCO.js.map +0 -1
- package/dist/chunk-7K4WZM3U.js +0 -189
- package/dist/chunk-7K4WZM3U.js.map +0 -1
- package/dist/chunk-7MDBHJPT.js +0 -407
- package/dist/chunk-7MDBHJPT.js.map +0 -1
- package/dist/chunk-7UQD6ROV.js +0 -9
- package/dist/chunk-7UQD6ROV.js.map +0 -1
- package/dist/chunk-AFNIVLZP.js +0 -1069
- package/dist/chunk-AFNIVLZP.js.map +0 -1
- package/dist/chunk-ANWYRO6A.js +0 -407
- package/dist/chunk-ANWYRO6A.js.map +0 -1
- package/dist/chunk-DIXPOHDO.js +0 -71
- package/dist/chunk-DIXPOHDO.js.map +0 -1
- package/dist/chunk-DWYMKYPI.js +0 -3
- package/dist/chunk-DWYMKYPI.js.map +0 -1
- package/dist/chunk-E3NVDCZG.js +0 -280
- package/dist/chunk-E3NVDCZG.js.map +0 -1
- package/dist/chunk-EBM7YBKL.js +0 -399
- package/dist/chunk-EBM7YBKL.js.map +0 -1
- package/dist/chunk-EPAM7IWW.js +0 -294
- package/dist/chunk-EPAM7IWW.js.map +0 -1
- package/dist/chunk-EXQ7GYRS.js +0 -134
- package/dist/chunk-EXQ7GYRS.js.map +0 -1
- package/dist/chunk-F4QTUZ3C.js +0 -136
- package/dist/chunk-F4QTUZ3C.js.map +0 -1
- package/dist/chunk-FEW533R2.js +0 -105
- package/dist/chunk-FEW533R2.js.map +0 -1
- package/dist/chunk-FFZLJKC7.js +0 -270
- package/dist/chunk-FFZLJKC7.js.map +0 -1
- package/dist/chunk-GEAMOBF7.js +0 -8486
- package/dist/chunk-GEAMOBF7.js.map +0 -1
- package/dist/chunk-GRTRSCTD.js +0 -74
- package/dist/chunk-GRTRSCTD.js.map +0 -1
- package/dist/chunk-IKGYOGLK.js +0 -16
- package/dist/chunk-IKGYOGLK.js.map +0 -1
- package/dist/chunk-IQ7WYWVJ.js +0 -73
- package/dist/chunk-IQ7WYWVJ.js.map +0 -1
- package/dist/chunk-IXIVWQLF.js +0 -543
- package/dist/chunk-IXIVWQLF.js.map +0 -1
- package/dist/chunk-JCJU57RC.js +0 -115
- package/dist/chunk-JCJU57RC.js.map +0 -1
- package/dist/chunk-KORSTBU4.js +0 -117
- package/dist/chunk-KORSTBU4.js.map +0 -1
- package/dist/chunk-KSEZ6UM2.js +0 -235
- package/dist/chunk-KSEZ6UM2.js.map +0 -1
- package/dist/chunk-MHPF7R3O.js +0 -1376
- package/dist/chunk-MHPF7R3O.js.map +0 -1
- package/dist/chunk-MPC5IH7E.js +0 -81
- package/dist/chunk-MPC5IH7E.js.map +0 -1
- package/dist/chunk-MQIU2NYA.js +0 -114
- package/dist/chunk-MQIU2NYA.js.map +0 -1
- package/dist/chunk-NYMBJOGR.js +0 -2192
- package/dist/chunk-NYMBJOGR.js.map +0 -1
- package/dist/chunk-OBZD2M3C.js +0 -169
- package/dist/chunk-OBZD2M3C.js.map +0 -1
- package/dist/chunk-ODM2AG6G.js +0 -176
- package/dist/chunk-ODM2AG6G.js.map +0 -1
- package/dist/chunk-ONDKF5LP.js +0 -53
- package/dist/chunk-ONDKF5LP.js.map +0 -1
- package/dist/chunk-P25YCWQB.js +0 -41
- package/dist/chunk-P25YCWQB.js.map +0 -1
- package/dist/chunk-PFYVNM6H.js +0 -14
- package/dist/chunk-PFYVNM6H.js.map +0 -1
- package/dist/chunk-PWNNSGFL.js +0 -20
- package/dist/chunk-PWNNSGFL.js.map +0 -1
- package/dist/chunk-Q2PGZVOT.js +0 -36
- package/dist/chunk-Q2PGZVOT.js.map +0 -1
- package/dist/chunk-Q2XDMV7U.js +0 -76
- package/dist/chunk-Q2XDMV7U.js.map +0 -1
- package/dist/chunk-QG7FH2FI.js +0 -45
- package/dist/chunk-QG7FH2FI.js.map +0 -1
- package/dist/chunk-R7HUOK2D.js +0 -1914
- package/dist/chunk-R7HUOK2D.js.map +0 -1
- package/dist/chunk-REUYY7G5.js +0 -773
- package/dist/chunk-REUYY7G5.js.map +0 -1
- package/dist/chunk-RHC2Z2HT.js +0 -199
- package/dist/chunk-RHC2Z2HT.js.map +0 -1
- package/dist/chunk-RMCVLIFE.js +0 -23
- package/dist/chunk-RMCVLIFE.js.map +0 -1
- package/dist/chunk-ROZLTXGR.js +0 -234
- package/dist/chunk-ROZLTXGR.js.map +0 -1
- package/dist/chunk-RSS2C2O3.js +0 -17
- package/dist/chunk-RSS2C2O3.js.map +0 -1
- package/dist/chunk-SAGCG5SH.js +0 -355
- package/dist/chunk-SAGCG5SH.js.map +0 -1
- package/dist/chunk-TM6AOUSD.js +0 -40
- package/dist/chunk-TM6AOUSD.js.map +0 -1
- package/dist/chunk-TPK4BYCO.js +0 -970
- package/dist/chunk-TPK4BYCO.js.map +0 -1
- package/dist/chunk-UNQIL4K2.js +0 -34
- package/dist/chunk-UNQIL4K2.js.map +0 -1
- package/dist/chunk-UUG6L75Y.js +0 -47
- package/dist/chunk-UUG6L75Y.js.map +0 -1
- package/dist/chunk-V2SYMV4W.js +0 -114
- package/dist/chunk-V2SYMV4W.js.map +0 -1
- package/dist/chunk-V7EN5CTH.js +0 -130
- package/dist/chunk-V7EN5CTH.js.map +0 -1
- package/dist/chunk-VITKG2HL.js +0 -1125
- package/dist/chunk-VITKG2HL.js.map +0 -1
- package/dist/chunk-VYEWU5LO.js +0 -2631
- package/dist/chunk-VYEWU5LO.js.map +0 -1
- package/dist/chunk-W67QAGSH.js +0 -178
- package/dist/chunk-W67QAGSH.js.map +0 -1
- package/dist/chunk-WWBIN6KV.js +0 -1353
- package/dist/chunk-WWBIN6KV.js.map +0 -1
- package/dist/chunk-X77Z4PFB.js +0 -224
- package/dist/chunk-X77Z4PFB.js.map +0 -1
- package/dist/chunk-X7VG7OTT.js +0 -8
- package/dist/chunk-X7VG7OTT.js.map +0 -1
- package/dist/chunk-XE4K2SGI.js +0 -74
- package/dist/chunk-XE4K2SGI.js.map +0 -1
- package/dist/chunk-YIUG7IJK.js +0 -628
- package/dist/chunk-YIUG7IJK.js.map +0 -1
- package/dist/chunk-YNVN3V4Y.js +0 -13
- package/dist/chunk-YNVN3V4Y.js.map +0 -1
- package/dist/chunk-Z2S54IZX.js +0 -198
- package/dist/chunk-Z2S54IZX.js.map +0 -1
- package/dist/chunk-ZR6AH25Z.js +0 -17
- package/dist/chunk-ZR6AH25Z.js.map +0 -1
- package/dist/dialog-SPM3DTTI.js +0 -17
- package/dist/dialog-SPM3DTTI.js.map +0 -1
- package/dist/dropdown-menu-HMTWKWGK.js +0 -21
- package/dist/dropdown-menu-HMTWKWGK.js.map +0 -1
- package/dist/input-BH4P4S26.js +0 -6
- package/dist/input-BH4P4S26.js.map +0 -1
- package/dist/label-5Z4Q6VER.js +0 -8
- package/dist/label-5Z4Q6VER.js.map +0 -1
- package/dist/popover-IFOUXYLI.js +0 -18
- package/dist/popover-IFOUXYLI.js.map +0 -1
- package/dist/scroll-area-DJXNW6QX.js +0 -14
- package/dist/scroll-area-DJXNW6QX.js.map +0 -1
- package/dist/select-FZ277C3G.js +0 -22
- package/dist/select-FZ277C3G.js.map +0 -1
- package/dist/separator-BTMLN4NB.js +0 -8
- package/dist/separator-BTMLN4NB.js.map +0 -1
- package/dist/skeleton-DXIWBH4W.js +0 -6
- package/dist/skeleton-DXIWBH4W.js.map +0 -1
- package/dist/switch-4MCXIZBY.js +0 -13
- package/dist/switch-4MCXIZBY.js.map +0 -1
- package/dist/tabs-O7AW3APK.js +0 -17
- package/dist/tabs-O7AW3APK.js.map +0 -1
- package/dist/textarea-IB5WAFDO.js +0 -6
- package/dist/textarea-IB5WAFDO.js.map +0 -1
- package/dist/toggle-XVPPG6P4.js +0 -10
- package/dist/toggle-XVPPG6P4.js.map +0 -1
- package/dist/tooltip-JICZTD4F.js +0 -18
- package/dist/tooltip-JICZTD4F.js.map +0 -1
package/dist/hooks/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../../src/hooks/useSync.ts","../../src/components/BBProvider.tsx","../../src/hooks/useAgentRun.ts","../../src/hooks/useRunStream.ts","../../src/hooks/useIntensity.tsx","../../src/hooks/usePlaySession.ts"],"names":["useState","useRef","useCallback","useEffect","useMemo","createContext","jsx","useContext"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * useSync - Offline-first sync hook with conflict resolution\n *\n * Implements the hybrid local+API sync pattern from Backbay.\n */\n\nimport { useState, useCallback, useEffect, useRef } from 'react';\nimport type { SyncStatus, SyncConflict, ConflictResolution } from '../protocol/types.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UseSyncOptions<T> {\n /** Unique key for localStorage */\n key: string;\n\n /** API endpoint for sync */\n endpoint: string;\n\n /** Debounce time in ms (default: 2000) */\n debounce?: number;\n\n /** Initial data */\n initialData?: T;\n\n /** Custom fetch function */\n fetcher?: (endpoint: string) => Promise<T>;\n\n /** Custom save function */\n saver?: (endpoint: string, data: T) => Promise<T>;\n\n /** Called when conflict is detected */\n onConflict?: (conflict: SyncConflict<T>) => void;\n\n /** Called on sync error */\n onError?: (error: Error) => void;\n\n /** Called on successful sync */\n onSync?: (data: T) => void;\n}\n\nexport interface UseSyncReturn<T> {\n /** Current data */\n data: T | null;\n\n /** Update data locally (triggers debounced sync) */\n setData: (data: T | ((prev: T | null) => T)) => void;\n\n /** Current sync status */\n status: SyncStatus;\n\n /** Number of pending changes */\n pendingChanges: number;\n\n /** Timestamp of last successful sync */\n lastSyncedAt: number | null;\n\n /** Current conflict if status === 'conflict' */\n conflict: SyncConflict<T> | null;\n\n /** Resolve a conflict */\n resolveConflict: (resolution: ConflictResolution) => Promise<void>;\n\n /** Force immediate save (bypass debounce) */\n forceSave: () => Promise<void>;\n\n /** Refresh from server */\n refresh: () => Promise<void>;\n\n /** Whether initial load is complete */\n isLoaded: boolean;\n}\n\n// =============================================================================\n// Local Storage Helpers\n// =============================================================================\n\ntype StoredDataV1<T> = {\n data: T;\n timestamp: number;\n version: number;\n};\n\ninterface StoredDataV2<T> {\n data: T;\n /** When the data last changed locally (ms since epoch). */\n lastModifiedAt: number;\n /** When we last successfully synced to server (ms since epoch). 0 means \"unknown/never\". */\n lastSyncedAt: number;\n /** Hash of the server data at the last successful sync (empty string means \"unknown/never\"). */\n lastSyncedHash: string;\n}\n\ntype StoredData<T> = StoredDataV2<T>;\n\nfunction stableStringify(value: unknown): string {\n if (value === null || typeof value !== \"object\") {\n const encoded = JSON.stringify(value);\n return encoded === undefined ? \"null\" : encoded;\n }\n\n if (Array.isArray(value)) {\n return `[${value.map(stableStringify).join(\",\")}]`;\n }\n\n const record = value as Record<string, unknown>;\n const keys = Object.keys(record).sort();\n return `{${keys.map((k) => `${JSON.stringify(k)}:${stableStringify(record[k])}`).join(\",\")}}`;\n}\n\nfunction hashString(input: string): string {\n // FNV-1a 32-bit\n let hash = 0x811c9dc5;\n for (let i = 0; i < input.length; i++) {\n hash ^= input.charCodeAt(i);\n hash = (hash * 0x01000193) >>> 0;\n }\n return hash.toString(36);\n}\n\nfunction hashData(value: unknown): string {\n return hashString(stableStringify(value));\n}\n\nfunction normalizeStoredData<T>(raw: unknown): StoredData<T> | null {\n if (!raw || typeof raw !== \"object\") return null;\n const record = raw as Record<string, unknown>;\n\n // v2\n if (\n \"data\" in record &&\n typeof record.lastModifiedAt === \"number\" &&\n typeof record.lastSyncedAt === \"number\" &&\n typeof record.lastSyncedHash === \"string\"\n ) {\n return record as unknown as StoredData<T>;\n }\n\n // v1 (legacy)\n if (\"data\" in record && typeof record.timestamp === \"number\" && typeof record.version === \"number\") {\n const legacy = record as StoredDataV1<T>;\n const syncedHash = hashData(legacy.data);\n return {\n data: legacy.data,\n lastModifiedAt: legacy.timestamp,\n lastSyncedAt: legacy.timestamp,\n lastSyncedHash: syncedHash,\n };\n }\n\n return null;\n}\n\nfunction getStoredData<T>(key: string): StoredData<T> | null {\n try {\n const raw = localStorage.getItem(key);\n if (!raw) return null;\n const parsed = JSON.parse(raw) as unknown;\n return normalizeStoredData<T>(parsed);\n } catch {\n return null;\n }\n}\n\nfunction setStoredData<T>(key: string, record: StoredData<T>): void {\n localStorage.setItem(key, JSON.stringify(record));\n}\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\nexport function useSync<T>({\n key,\n endpoint,\n debounce = 2000,\n initialData,\n fetcher,\n saver,\n onConflict,\n onError,\n onSync,\n}: UseSyncOptions<T>): UseSyncReturn<T> {\n // State\n const [data, setDataState] = useState<T | null>(initialData ?? null);\n const [status, setStatus] = useState<SyncStatus>('synced');\n const [pendingChanges, setPendingChanges] = useState(0);\n const [lastSyncedAt, setLastSyncedAt] = useState<number | null>(null);\n const [conflict, setConflict] = useState<SyncConflict<T> | null>(null);\n const [isLoaded, setIsLoaded] = useState(false);\n\n // Refs\n const debounceTimerRef = useRef<ReturnType<typeof setTimeout> | null>(null);\n const isSavingRef = useRef(false);\n\n // Fetcher / saver are injectable to support custom backends.\n const doFetch = useCallback(\n async (url: string) => {\n if (fetcher) return fetcher(url);\n const response = await fetch(url);\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return response.json() as Promise<T>;\n },\n [fetcher]\n );\n\n const doSave = useCallback(\n async (url: string, payload: T) => {\n if (saver) return saver(url, payload);\n const response = await fetch(url, {\n method: \"PUT\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify(payload),\n });\n if (!response.ok) throw new Error(`HTTP ${response.status}`);\n return response.json() as Promise<T>;\n },\n [saver]\n );\n\n // Load initial data\n useEffect(() => {\n const loadInitial = async () => {\n // First, check localStorage for cached data\n const stored = getStoredData<T>(key);\n if (stored) {\n setDataState(stored.data);\n const storedSyncedAt = stored.lastSyncedAt > 0 ? stored.lastSyncedAt : null;\n setLastSyncedAt(storedSyncedAt);\n\n const hasLocalChanges = stored.lastModifiedAt > stored.lastSyncedAt;\n if (hasLocalChanges) {\n setStatus(\"pending\");\n setPendingChanges((c) => Math.max(c, 1));\n }\n }\n\n // Then fetch from server\n try {\n const serverData = await doFetch(endpoint);\n const remoteTimestamp = Date.now();\n const remoteHash = hashData(serverData);\n\n if (stored) {\n const hasLocalChanges = stored.lastModifiedAt > stored.lastSyncedAt;\n const baselineHash = stored.lastSyncedHash || hashData(stored.data);\n const remoteChangedSinceSync = remoteHash !== baselineHash;\n\n if (hasLocalChanges && remoteChangedSinceSync) {\n const localConflict: SyncConflict<T> = {\n local: stored.data,\n remote: serverData,\n localTimestamp: stored.lastModifiedAt,\n remoteTimestamp,\n };\n setConflict(localConflict);\n setStatus(\"conflict\");\n onConflict?.(localConflict);\n } else if (!hasLocalChanges) {\n // No local changes, use server data\n setDataState(serverData);\n setStoredData(key, {\n data: serverData,\n lastModifiedAt: remoteTimestamp,\n lastSyncedAt: remoteTimestamp,\n lastSyncedHash: remoteHash,\n });\n setLastSyncedAt(remoteTimestamp);\n setPendingChanges(0);\n setStatus(\"synced\");\n } else {\n // Local has changes, but server hasn't changed since last sync.\n // Keep local data and remain pending until the next save.\n setStatus(\"pending\");\n }\n } else {\n // No local data, use server data\n setDataState(serverData);\n setStoredData(key, {\n data: serverData,\n lastModifiedAt: remoteTimestamp,\n lastSyncedAt: remoteTimestamp,\n lastSyncedHash: remoteHash,\n });\n setLastSyncedAt(remoteTimestamp);\n setPendingChanges(0);\n setStatus(\"synced\");\n }\n } catch (error) {\n // Offline - use cached data\n setStatus(\"offline\");\n if (error instanceof Error) {\n onError?.(error);\n }\n }\n\n setIsLoaded(true);\n };\n\n loadInitial();\n }, [key, endpoint, doFetch, onConflict, onError]);\n\n // Save to server\n const saveToServer = useCallback(async (payload?: T) => {\n const dataToSave = payload ?? data;\n if (isSavingRef.current || dataToSave === null) return;\n isSavingRef.current = true;\n\n try {\n setStatus(\"pending\");\n const serverData = await doSave(endpoint, dataToSave);\n const syncedAt = Date.now();\n const syncedHash = hashData(serverData);\n\n setDataState(serverData);\n setStoredData(key, {\n data: serverData,\n lastModifiedAt: syncedAt,\n lastSyncedAt: syncedAt,\n lastSyncedHash: syncedHash,\n });\n setLastSyncedAt(syncedAt);\n setPendingChanges(0);\n setStatus(\"synced\");\n onSync?.(serverData);\n } catch (error) {\n setStatus(\"offline\");\n if (error instanceof Error) {\n onError?.(error);\n }\n } finally {\n isSavingRef.current = false;\n }\n }, [data, endpoint, key, doSave, onSync, onError]);\n\n // Set data with debounced sync\n const setData = useCallback(\n (updater: T | ((prev: T | null) => T)) => {\n setDataState((prev) => {\n const newData = typeof updater === \"function\" ? (updater as (prev: T | null) => T)(prev) : updater;\n\n const previousStored = getStoredData<T>(key);\n const now = Date.now();\n\n setStoredData(key, {\n data: newData,\n lastModifiedAt: now,\n lastSyncedAt: previousStored?.lastSyncedAt ?? 0,\n lastSyncedHash: previousStored?.lastSyncedHash ?? \"\",\n });\n\n setPendingChanges((c) => c + 1);\n setStatus(\"pending\");\n\n // Clear existing debounce timer\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current);\n }\n\n // Set new debounce timer\n debounceTimerRef.current = setTimeout(() => {\n saveToServer();\n }, debounce);\n\n return newData;\n });\n },\n [key, debounce, saveToServer]\n );\n\n // Force save (bypass debounce)\n const forceSave = useCallback(async () => {\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current);\n debounceTimerRef.current = null;\n }\n await saveToServer();\n }, [saveToServer]);\n\n // Refresh from server\n const refresh = useCallback(async () => {\n try {\n const serverData = await doFetch(endpoint);\n const syncedAt = Date.now();\n const syncedHash = hashData(serverData);\n\n setDataState(serverData);\n setStoredData(key, {\n data: serverData,\n lastModifiedAt: syncedAt,\n lastSyncedAt: syncedAt,\n lastSyncedHash: syncedHash,\n });\n setLastSyncedAt(syncedAt);\n setPendingChanges(0);\n setConflict(null);\n setStatus(\"synced\");\n } catch (error) {\n setStatus(\"offline\");\n if (error instanceof Error) {\n onError?.(error);\n }\n }\n }, [endpoint, key, doFetch, onError]);\n\n // Resolve conflict\n const resolveConflict = useCallback(\n async (resolution: ConflictResolution) => {\n if (!conflict) return;\n\n switch (resolution) {\n case \"keep_local\":\n // Keep local, push to server\n setDataState(conflict.local);\n setConflict(null);\n setStatus(\"pending\");\n setPendingChanges((c) => Math.max(c, 1));\n await saveToServer(conflict.local);\n break;\n\n case \"use_remote\": {\n // Use remote, discard local\n const remoteHash = hashData(conflict.remote);\n setDataState(conflict.remote);\n setStoredData(key, {\n data: conflict.remote,\n lastModifiedAt: conflict.remoteTimestamp,\n lastSyncedAt: conflict.remoteTimestamp,\n lastSyncedHash: remoteHash,\n });\n setLastSyncedAt(conflict.remoteTimestamp);\n setPendingChanges(0);\n setConflict(null);\n setStatus(\"synced\");\n break;\n }\n\n case \"create_copy\":\n // Keep local as copy, also keep remote\n // This would typically save local to a new key/endpoint\n // For now, we just keep local\n setDataState(conflict.local);\n setConflict(null);\n setStatus(\"pending\");\n setPendingChanges((c) => Math.max(c, 1));\n await saveToServer(conflict.local);\n break;\n }\n },\n [conflict, key, saveToServer]\n );\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (debounceTimerRef.current) {\n clearTimeout(debounceTimerRef.current);\n }\n };\n }, []);\n\n return {\n data,\n setData,\n status,\n pendingChanges,\n lastSyncedAt,\n conflict,\n resolveConflict,\n forceSave,\n refresh,\n isLoaded,\n };\n}\n","/**\n * BBProvider - Root context provider for bb-ui\n */\n\nimport {\n createContext,\n useContext,\n useState,\n useCallback,\n useEffect,\n useMemo,\n type ReactNode,\n} from 'react';\nimport type { Agent, AgentRun, BBConfig, SyncStatus } from '../protocol/types.js';\nimport { GliaErrorBoundary } from '../primitives/atoms/GliaErrorBoundary';\n\n// =============================================================================\n// Context Types\n// =============================================================================\n\ninterface BBContextValue {\n /** Configuration */\n config: BBConfig;\n\n /** Available agents */\n agents: Agent[];\n\n /** Currently executing runs */\n activeRuns: AgentRun[];\n\n /** All runs in this session */\n runHistory: AgentRun[];\n\n /** Session cost accumulator */\n totalCost: number;\n\n /** Global sync status */\n syncStatus: SyncStatus;\n\n /** Add a run to tracking */\n addRun: (run: AgentRun) => void;\n\n /** Update a run */\n updateRun: (runId: string, updates: Partial<AgentRun>) => void;\n\n /** Set global sync status */\n setSyncStatus: (status: SyncStatus) => void;\n\n /** Get an agent by ID */\n getAgent: (agentId: string) => Agent | undefined;\n}\n\n// =============================================================================\n// Context\n// =============================================================================\n\nconst BBContext = createContext<BBContextValue | null>(null);\n\n// =============================================================================\n// Provider Props\n// =============================================================================\n\nexport interface BBProviderProps {\n children: ReactNode;\n\n /** Configuration for bb-ui */\n config: BBConfig;\n\n /** Available agents */\n agents?: Agent[];\n\n /** Initial sync status */\n initialSyncStatus?: SyncStatus;\n}\n\n// =============================================================================\n// Provider Component\n// =============================================================================\n\nexport function BBProvider({\n children,\n config,\n agents = [],\n initialSyncStatus = 'synced',\n}: BBProviderProps) {\n const [activeRuns, setActiveRuns] = useState<AgentRun[]>([]);\n const [runHistory, setRunHistory] = useState<AgentRun[]>([]);\n const [syncStatus, setSyncStatus] = useState<SyncStatus>(initialSyncStatus);\n\n // Calculate total cost from run history\n const totalCost = useMemo(() => {\n return runHistory.reduce((sum, run) => sum + (run.cost ?? 0), 0);\n }, [runHistory]);\n\n // Add a new run\n const addRun = useCallback((run: AgentRun) => {\n setActiveRuns((prev) => [...prev, run]);\n setRunHistory((prev) => [...prev, run]);\n }, []);\n\n // Update an existing run\n const updateRun = useCallback((runId: string, updates: Partial<AgentRun>) => {\n const updateInList = (runs: AgentRun[]) =>\n runs.map((run) => (run.id === runId ? { ...run, ...updates } : run));\n\n setActiveRuns((prev) => {\n const updated = updateInList(prev);\n // Remove completed/failed/cancelled runs from active\n return updated.filter(\n (run) => run.status === 'idle' || run.status === 'running'\n );\n });\n\n setRunHistory(updateInList);\n }, []);\n\n // Get agent by ID\n const getAgent = useCallback(\n (agentId: string) => agents.find((a) => a.id === agentId),\n [agents]\n );\n\n const value = useMemo<BBContextValue>(\n () => ({\n config,\n agents,\n activeRuns,\n runHistory,\n totalCost,\n syncStatus,\n addRun,\n updateRun,\n setSyncStatus,\n getAgent,\n }),\n [\n config,\n agents,\n activeRuns,\n runHistory,\n totalCost,\n syncStatus,\n addRun,\n updateRun,\n getAgent,\n ]\n );\n\n return (\n <BBContext.Provider value={value}>\n <GliaErrorBoundary variant=\"fullscreen\">\n {children}\n </GliaErrorBoundary>\n </BBContext.Provider>\n );\n}\n\n// =============================================================================\n// Hook\n// =============================================================================\n\n/**\n * Access the bb-ui context\n */\nexport function useBBContext(): BBContextValue {\n const context = useContext(BBContext);\n if (!context) {\n throw new Error('useBBContext must be used within a BBProvider');\n }\n return context;\n}\n\n/**\n * Check if we're inside a BBProvider\n */\nexport function useBBContextOptional(): BBContextValue | null {\n return useContext(BBContext);\n}\n","/**\n * useAgentRun - Hook for executing agent runs\n */\n\nimport { useState, useCallback, useRef } from 'react';\nimport type { AgentRun, RunStatus } from '../protocol/types.js';\nimport { useBBContext } from '../components/BBProvider.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UseAgentRunOptions {\n /** Called when run starts */\n onStart?: (run: AgentRun) => void;\n\n /** Called when run completes */\n onComplete?: (run: AgentRun) => void;\n\n /** Called when run fails */\n onError?: (run: AgentRun, error: Error) => void;\n\n /** Called when run is cancelled */\n onCancel?: (run: AgentRun) => void;\n}\n\nexport interface UseAgentRunReturn {\n /** Current run object or null */\n run: AgentRun | null;\n\n /** Current status */\n status: RunStatus;\n\n /** Run output when completed */\n output: string | null;\n\n /** Error message if failed */\n error: string | null;\n\n /** Actual cost incurred */\n cost: number | null;\n\n /** Time taken in ms */\n latency: number | null;\n\n /** Start a new run */\n start: (agentId: string, prompt: string, context?: Record<string, unknown>) => Promise<void>;\n\n /** Cancel the current run */\n cancel: () => void;\n\n /** Whether a run is in progress */\n isRunning: boolean;\n}\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\nexport function useAgentRun(options: UseAgentRunOptions = {}): UseAgentRunReturn {\n const { onStart, onComplete, onError, onCancel } = options;\n\n const { config, addRun, updateRun, getAgent } = useBBContext();\n\n const [run, setRun] = useState<AgentRun | null>(null);\n const [status, setStatus] = useState<RunStatus>('idle');\n const [output, setOutput] = useState<string | null>(null);\n const [error, setError] = useState<string | null>(null);\n const [cost, setCost] = useState<number | null>(null);\n const [latency, setLatency] = useState<number | null>(null);\n\n const abortControllerRef = useRef<AbortController | null>(null);\n\n const start = useCallback(\n async (agentId: string, prompt: string, context?: Record<string, unknown>) => {\n // Cancel any existing run\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n }\n\n const controller = new AbortController();\n abortControllerRef.current = controller;\n\n const runId = `run-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;\n const startedAt = Date.now();\n\n const newRun: AgentRun = {\n id: runId,\n agentId,\n prompt,\n context,\n status: 'running',\n startedAt,\n };\n\n // Update state\n setRun(newRun);\n setStatus('running');\n setOutput(null);\n setError(null);\n setCost(null);\n setLatency(null);\n\n // Add to global tracking\n addRun(newRun);\n onStart?.(newRun);\n\n try {\n // Make API call\n const response = await fetch(`${config.apiBaseUrl}/runs`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...config.headers,\n },\n body: JSON.stringify({\n agentId,\n prompt,\n context,\n }),\n signal: controller.signal,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const result = await response.json();\n const completedAt = Date.now();\n const runLatency = completedAt - startedAt;\n\n // Get agent cost estimate\n const agent = getAgent(agentId);\n const runCost = result.cost ?? agent?.costPerRun ?? 0;\n\n const completedRun: AgentRun = {\n ...newRun,\n status: 'completed',\n output: result.output,\n cost: runCost,\n tokenCount: result.tokenCount,\n latencyMs: runLatency,\n completedAt,\n };\n\n // Update state\n setRun(completedRun);\n setStatus('completed');\n setOutput(result.output);\n setCost(runCost);\n setLatency(runLatency);\n\n // Update global tracking\n updateRun(runId, completedRun);\n onComplete?.(completedRun);\n } catch (err) {\n if (err instanceof Error && err.name === 'AbortError') {\n // Cancelled\n const cancelledRun: AgentRun = {\n ...newRun,\n status: 'cancelled',\n completedAt: Date.now(),\n };\n setRun(cancelledRun);\n setStatus('cancelled');\n updateRun(runId, cancelledRun);\n onCancel?.(cancelledRun);\n return;\n }\n\n // Failed\n const errorMessage = err instanceof Error ? err.message : 'Unknown error';\n const failedRun: AgentRun = {\n ...newRun,\n status: 'failed',\n error: errorMessage,\n completedAt: Date.now(),\n };\n\n setRun(failedRun);\n setStatus('failed');\n setError(errorMessage);\n\n updateRun(runId, failedRun);\n onError?.(failedRun, err instanceof Error ? err : new Error(errorMessage));\n } finally {\n if (abortControllerRef.current === controller) {\n abortControllerRef.current = null;\n }\n }\n },\n [config, addRun, updateRun, getAgent, onStart, onComplete, onError, onCancel]\n );\n\n const cancel = useCallback(() => {\n if (abortControllerRef.current) {\n abortControllerRef.current.abort();\n abortControllerRef.current = null;\n }\n }, []);\n\n return {\n run,\n status,\n output,\n error,\n cost,\n latency,\n start,\n cancel,\n isRunning: status === 'running',\n };\n}\n","/**\n * useRunStream - Hook for streaming run events\n *\n * Implements dual EventSource + polling pattern for resilient real-time updates.\n */\n\nimport { useState, useEffect, useCallback, useRef } from 'react';\nimport type { RunEvent, RunStatus, AgentRun } from '../protocol/types.js';\nimport { useBBContext } from '../components/BBProvider.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UseRunStreamOptions {\n /** Polling interval in ms (default: 4000) */\n pollInterval?: number;\n\n /** Whether to use polling as primary (if EventSource unavailable) */\n preferPolling?: boolean;\n\n /** Called on each event */\n onEvent?: (event: RunEvent) => void;\n\n /** Called when run completes */\n onComplete?: (run: AgentRun) => void;\n\n /** Called on error */\n onError?: (error: Error) => void;\n}\n\nexport interface UseRunStreamReturn {\n /** All received events */\n events: RunEvent[];\n\n /** Most recent event */\n latestEvent: RunEvent | null;\n\n /** Derived run status */\n status: RunStatus;\n\n /** Whether EventSource is connected */\n isConnected: boolean;\n\n /** Current run data (if available) */\n run: AgentRun | null;\n\n /** Manually disconnect */\n disconnect: () => void;\n\n /** Manually reconnect */\n reconnect: () => void;\n}\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\nexport function useRunStream(\n runId: string | null,\n options: UseRunStreamOptions = {}\n): UseRunStreamReturn {\n const { pollInterval = 4000, preferPolling = false, onEvent, onComplete, onError } = options;\n\n const { config } = useBBContext();\n\n const [events, setEvents] = useState<RunEvent[]>([]);\n const [latestEvent, setLatestEvent] = useState<RunEvent | null>(null);\n const [status, setStatus] = useState<RunStatus>('idle');\n const [isConnected, setIsConnected] = useState(false);\n const [run, setRun] = useState<AgentRun | null>(null);\n\n const eventSourceRef = useRef<EventSource | null>(null);\n const pollingIntervalRef = useRef<ReturnType<typeof setInterval> | null>(null);\n const isActiveRef = useRef(true);\n\n // Handle incoming event\n const handleEvent = useCallback(\n (event: RunEvent) => {\n if (!isActiveRef.current) return;\n\n setEvents((prev) => [...prev, event]);\n setLatestEvent(event);\n onEvent?.(event);\n\n // Update status from event\n if (event.data?.status) {\n setStatus(event.data.status);\n }\n\n // Handle completion events\n if (event.type === 'completed' || event.type === 'failed' || event.type === 'cancelled') {\n const finalStatus =\n event.type === 'completed'\n ? 'completed'\n : event.type === 'failed'\n ? 'failed'\n : 'cancelled';\n setStatus(finalStatus);\n\n if (event.data?.run) {\n setRun(event.data.run);\n if (event.type === 'completed') {\n onComplete?.(event.data.run);\n }\n }\n }\n },\n [onEvent, onComplete]\n );\n\n // Setup EventSource\n const setupEventSource = useCallback(() => {\n if (!runId || preferPolling) return;\n\n const url = `${config.apiBaseUrl}/runs/${runId}/events`;\n const eventSource = new EventSource(url);\n\n eventSource.onopen = () => {\n setIsConnected(true);\n handleEvent({\n type: 'connected',\n runId,\n timestamp: Date.now(),\n });\n };\n\n eventSource.onmessage = (e) => {\n try {\n const data = JSON.parse(e.data);\n handleEvent({\n type: data.type ?? 'status',\n runId,\n timestamp: Date.now(),\n data,\n });\n } catch (err) {\n console.error('Failed to parse event:', err);\n }\n };\n\n eventSource.onerror = () => {\n setIsConnected(false);\n // EventSource will auto-reconnect, but we'll start polling as fallback\n startPolling();\n };\n\n eventSourceRef.current = eventSource;\n }, [runId, config.apiBaseUrl, preferPolling, handleEvent]);\n\n // Setup polling\n const startPolling = useCallback(() => {\n if (!runId || pollingIntervalRef.current) return;\n\n const poll = async () => {\n if (!isActiveRef.current || !runId) return;\n\n try {\n const response = await fetch(`${config.apiBaseUrl}/runs/${runId}`, {\n headers: config.headers,\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}`);\n }\n\n const data = await response.json();\n\n handleEvent({\n type: 'status',\n runId,\n timestamp: Date.now(),\n data: {\n status: data.status,\n output: data.output,\n run: data,\n },\n });\n\n // Stop polling if run is complete\n if (data.status === 'completed' || data.status === 'failed' || data.status === 'cancelled') {\n stopPolling();\n handleEvent({\n type: data.status,\n runId,\n timestamp: Date.now(),\n data: { run: data },\n });\n }\n } catch (err) {\n if (err instanceof Error) {\n onError?.(err);\n }\n }\n };\n\n // Initial poll\n poll();\n\n // Setup interval\n pollingIntervalRef.current = setInterval(poll, pollInterval);\n }, [runId, config, pollInterval, handleEvent, onError]);\n\n const stopPolling = useCallback(() => {\n if (pollingIntervalRef.current) {\n clearInterval(pollingIntervalRef.current);\n pollingIntervalRef.current = null;\n }\n }, []);\n\n // Disconnect everything\n const disconnect = useCallback(() => {\n isActiveRef.current = false;\n\n if (eventSourceRef.current) {\n eventSourceRef.current.close();\n eventSourceRef.current = null;\n }\n\n stopPolling();\n setIsConnected(false);\n }, [stopPolling]);\n\n // Reconnect\n const reconnect = useCallback(() => {\n disconnect();\n isActiveRef.current = true;\n\n // Reset state\n setEvents([]);\n setLatestEvent(null);\n setStatus('idle');\n\n // Restart\n if (preferPolling) {\n startPolling();\n } else {\n setupEventSource();\n }\n }, [disconnect, preferPolling, startPolling, setupEventSource]);\n\n // Effect: Setup on mount / runId change\n useEffect(() => {\n if (!runId) {\n disconnect();\n return;\n }\n\n isActiveRef.current = true;\n setEvents([]);\n setLatestEvent(null);\n setStatus('running');\n\n if (preferPolling) {\n startPolling();\n } else {\n setupEventSource();\n // Also start polling as fallback with longer interval\n setTimeout(() => {\n if (isActiveRef.current && !isConnected) {\n startPolling();\n }\n }, 2000);\n }\n\n return () => {\n disconnect();\n };\n }, [runId]); // eslint-disable-line react-hooks/exhaustive-deps\n\n return {\n events,\n latestEvent,\n status,\n isConnected,\n run,\n disconnect,\n reconnect,\n };\n}\n\n// =============================================================================\n// Utility: Subscribe to run events (non-hook version)\n// =============================================================================\n\nexport function subscribeToRunEvents(\n apiBaseUrl: string,\n runId: string,\n callback: (event: RunEvent) => void,\n options: { headers?: Record<string, string> } = {}\n): () => void {\n const url = `${apiBaseUrl}/runs/${runId}/events`;\n const eventSource = new EventSource(url);\n\n eventSource.onopen = () => {\n callback({\n type: 'connected',\n runId,\n timestamp: Date.now(),\n });\n };\n\n eventSource.onmessage = (e) => {\n try {\n const data = JSON.parse(e.data);\n callback({\n type: data.type ?? 'status',\n runId,\n timestamp: Date.now(),\n data,\n });\n } catch (err) {\n console.error('Failed to parse event:', err);\n }\n };\n\n eventSource.onerror = () => {\n // EventSource handles reconnection automatically\n };\n\n return () => eventSource.close();\n}\n","/**\n * useIntensity - Hook for tracking agent activity intensity\n *\n * Provides semantic visual feedback based on agent activity levels.\n */\n\nimport { useState, useEffect, useMemo, useCallback, useRef } from 'react';\nimport type { IntensityValues } from '../protocol/types.js';\nimport { useBBContext } from '../components/BBProvider.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UseIntensityOptions {\n /** Smoothing factor for transitions (0-1, lower = smoother) */\n smoothing?: number;\n\n /** Update interval in ms */\n updateInterval?: number;\n\n /** Sources to track */\n sources?: Array<'activeRuns' | 'pendingSync' | 'custom'>;\n\n /** Custom intensity source (0-1) */\n customIntensity?: number;\n}\n\nexport interface UseIntensityReturn extends IntensityValues {\n /** Set custom intensity value */\n setCustomIntensity: (value: number) => void;\n\n /** CSS custom properties object for inline styles */\n cssVars: Record<string, string>;\n\n /** Get CSS custom properties as a string for style attribute */\n cssVarsString: string;\n}\n\n// =============================================================================\n// Constants\n// =============================================================================\n\nconst DEFAULT_SMOOTHING = 0.3;\nconst DEFAULT_UPDATE_INTERVAL = 50;\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\nexport function useIntensity(options: UseIntensityOptions = {}): UseIntensityReturn {\n const {\n smoothing = DEFAULT_SMOOTHING,\n updateInterval = DEFAULT_UPDATE_INTERVAL,\n sources = ['activeRuns'],\n customIntensity: initialCustom = 0,\n } = options;\n\n const { activeRuns, syncStatus } = useBBContext();\n\n const [customIntensity, setCustomIntensity] = useState(initialCustom);\n const [values, setValues] = useState<IntensityValues>({\n intensity: 0,\n presence: 0,\n activity: 0,\n breathing: 0,\n });\n\n // Refs for smooth animation\n const targetRef = useRef<IntensityValues>({\n intensity: 0,\n presence: 0,\n activity: 0,\n breathing: 0,\n });\n const animationFrameRef = useRef<number | null>(null);\n const lastUpdateRef = useRef(Date.now());\n\n // Calculate target intensity from sources\n const calculateTarget = useCallback(() => {\n let runIntensity = 0;\n let syncIntensity = 0;\n let custom = 0;\n\n if (sources.includes('activeRuns')) {\n runIntensity = Math.min(activeRuns.length / 3, 1); // Max at 3 concurrent runs\n }\n\n if (sources.includes('pendingSync')) {\n syncIntensity = syncStatus === 'pending' ? 0.5 : syncStatus === 'conflict' ? 0.8 : 0;\n }\n\n if (sources.includes('custom')) {\n custom = customIntensity;\n }\n\n // Combine sources\n const combinedIntensity = Math.min(\n Math.max(runIntensity, syncIntensity, custom),\n 1\n );\n\n // Calculate derived values\n const presence = combinedIntensity > 0 ? Math.min(combinedIntensity + 0.3, 1) : 0;\n const activity = combinedIntensity;\n const breathing = combinedIntensity > 0.2 ? Math.min(combinedIntensity * 1.2, 1) : 0;\n\n targetRef.current = {\n intensity: combinedIntensity,\n presence,\n activity,\n breathing,\n };\n }, [activeRuns.length, syncStatus, customIntensity, sources]);\n\n // Smooth animation loop\n useEffect(() => {\n const animate = () => {\n const now = Date.now();\n const delta = (now - lastUpdateRef.current) / 1000;\n lastUpdateRef.current = now;\n\n // Recalculate target\n calculateTarget();\n\n // Lerp toward target\n const lerpFactor = 1 - Math.pow(1 - smoothing, delta * 60);\n\n setValues((prev) => ({\n intensity: prev.intensity + (targetRef.current.intensity - prev.intensity) * lerpFactor,\n presence: prev.presence + (targetRef.current.presence - prev.presence) * lerpFactor,\n activity: prev.activity + (targetRef.current.activity - prev.activity) * lerpFactor,\n breathing: prev.breathing + (targetRef.current.breathing - prev.breathing) * lerpFactor,\n }));\n\n animationFrameRef.current = requestAnimationFrame(animate);\n };\n\n animationFrameRef.current = requestAnimationFrame(animate);\n\n return () => {\n if (animationFrameRef.current) {\n cancelAnimationFrame(animationFrameRef.current);\n }\n };\n }, [calculateTarget, smoothing]);\n\n // CSS custom properties\n const cssVars = useMemo(\n () => ({\n '--glia-intensity': values.intensity.toFixed(3),\n '--glia-intensity-presence': values.presence.toFixed(3),\n '--glia-intensity-activity': values.activity.toFixed(3),\n '--glia-intensity-breathing': values.breathing.toFixed(3),\n }),\n [values]\n );\n\n const cssVarsString = useMemo(\n () =>\n Object.entries(cssVars)\n .map(([key, value]) => `${key}: ${value}`)\n .join('; '),\n [cssVars]\n );\n\n return {\n ...values,\n setCustomIntensity,\n cssVars,\n cssVarsString,\n };\n}\n\n// =============================================================================\n// Provider Component (optional)\n// =============================================================================\n\nimport { createContext, useContext, type ReactNode } from 'react';\n\nconst IntensityContext = createContext<IntensityValues | null>(null);\n\nexport interface IntensityProviderProps {\n children: ReactNode;\n options?: UseIntensityOptions;\n}\n\nexport function IntensityProvider({ children, options }: IntensityProviderProps) {\n const intensity = useIntensity(options);\n\n // Apply CSS vars to document root\n useEffect(() => {\n const root = document.documentElement;\n root.style.setProperty('--glia-intensity', intensity.intensity.toFixed(3));\n root.style.setProperty('--glia-intensity-presence', intensity.presence.toFixed(3));\n root.style.setProperty('--glia-intensity-activity', intensity.activity.toFixed(3));\n root.style.setProperty('--glia-intensity-breathing', intensity.breathing.toFixed(3));\n }, [intensity]);\n\n return (\n <IntensityContext.Provider value={intensity}>\n {children}\n </IntensityContext.Provider>\n );\n}\n\nexport function useIntensityContext(): IntensityValues {\n const context = useContext(IntensityContext);\n if (!context) {\n throw new Error('useIntensityContext must be used within an IntensityProvider');\n }\n return context;\n}\n","/**\n * usePlaySession - Hook for managing play sessions with external environments\n *\n * Handles session lifecycle, LiveKit connections, and JSON-RPC calls to adapters.\n */\n\nimport { useState, useCallback, useRef, useEffect } from 'react';\nimport type { PlaySessionData, PlaySessionStatus, JsonRpcResponse } from '../protocol/types.js';\nimport { useBBContext } from '../components/BBProvider.js';\n\n// =============================================================================\n// Types\n// =============================================================================\n\nexport interface UsePlaySessionOptions {\n /** Adapter ID (e.g., 'openrct2', 'bbdoom') */\n adapter: string;\n\n /** Auto-connect on mount */\n autoConnect?: boolean;\n\n /** Connection timeout in ms */\n timeout?: number;\n\n /** Called when session is established */\n onConnect?: (session: PlaySessionData) => void;\n\n /** Called when session ends */\n onDisconnect?: () => void;\n\n /** Called on RPC result */\n onRpcResult?: (response: JsonRpcResponse) => void;\n\n /** Called on error */\n onError?: (error: Error) => void;\n}\n\nexport interface UsePlaySessionReturn {\n /** Current session or null */\n session: PlaySessionData | null;\n\n /** Session status */\n status: PlaySessionStatus;\n\n /** LiveKit video track (for rendering) */\n videoTrack: MediaStreamTrack | null;\n\n /** LiveKit audio track */\n audioTrack: MediaStreamTrack | null;\n\n /** Make a JSON-RPC call */\n call: <T = unknown>(method: string, params?: Record<string, unknown>) => Promise<JsonRpcResponse<T>>;\n\n /** Shorthand for observe.* methods */\n observe: <T = unknown>(key: string) => Promise<T>;\n\n /** Shorthand for act.* methods */\n act: <T = unknown>(action: string, params?: Record<string, unknown>) => Promise<T>;\n\n /** Connect to the session */\n connect: (options?: { timeout?: number }) => Promise<void>;\n\n /** Disconnect from the session */\n disconnect: () => Promise<void>;\n\n /** Whether currently connected */\n isConnected: boolean;\n\n /** Error message if any */\n error: string | null;\n}\n\n// =============================================================================\n// Hook Implementation\n// =============================================================================\n\nexport function usePlaySession({\n adapter,\n autoConnect = false,\n timeout = 30000,\n onConnect,\n onDisconnect,\n onRpcResult,\n onError,\n}: UsePlaySessionOptions): UsePlaySessionReturn {\n const { config } = useBBContext();\n\n // State\n const [session, setSession] = useState<PlaySessionData | null>(null);\n const [status, setStatus] = useState<PlaySessionStatus>('disconnected');\n const [videoTrack, setVideoTrack] = useState<MediaStreamTrack | null>(null);\n const [audioTrack, setAudioTrack] = useState<MediaStreamTrack | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n // Refs\n const wsRef = useRef<WebSocket | null>(null);\n const rpcIdRef = useRef(0);\n const pendingCallsRef = useRef<Map<number, {\n resolve: (value: JsonRpcResponse) => void;\n reject: (error: Error) => void;\n }>>(new Map());\n\n // Connect to session\n const connect = useCallback(\n async (options?: { timeout?: number }) => {\n if (status === 'connecting' || status === 'connected') return;\n\n setStatus('connecting');\n setError(null);\n\n const connectTimeout = options?.timeout ?? timeout;\n\n try {\n // Create session via API\n const response = await fetch(`${config.apiBaseUrl}/play-sessions`, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n ...config.headers,\n },\n body: JSON.stringify({ adapter }),\n });\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const sessionData = await response.json();\n const newSession: PlaySessionData = {\n id: sessionData.id,\n adapter,\n capabilityToken: sessionData.capabilityToken,\n createdAt: Date.now(),\n expiresAt: sessionData.expiresAt,\n livekitUrl: sessionData.livekitUrl,\n livekitToken: sessionData.livekitToken,\n };\n\n setSession(newSession);\n\n // Connect WebSocket for RPC\n const wsUrl = sessionData.wsUrl ?? `${config.apiBaseUrl.replace('http', 'ws')}/play-sessions/${newSession.id}/ws`;\n const ws = new WebSocket(wsUrl);\n wsRef.current = ws;\n\n // Set up WebSocket handlers\n await new Promise<void>((resolve, reject) => {\n const timeoutId = setTimeout(() => {\n ws.close();\n reject(new Error('Connection timeout'));\n }, connectTimeout);\n\n ws.onopen = () => {\n clearTimeout(timeoutId);\n resolve();\n };\n\n ws.onerror = () => {\n clearTimeout(timeoutId);\n reject(new Error('WebSocket connection failed'));\n };\n });\n\n ws.onmessage = (event) => {\n try {\n const message = JSON.parse(event.data);\n\n // Handle RPC response\n if ('id' in message && pendingCallsRef.current.has(message.id)) {\n const pending = pendingCallsRef.current.get(message.id)!;\n pendingCallsRef.current.delete(message.id);\n pending.resolve(message);\n onRpcResult?.(message);\n }\n } catch {\n // Ignore parse errors\n }\n };\n\n ws.onclose = () => {\n setStatus('disconnected');\n setSession(null);\n wsRef.current = null;\n onDisconnect?.();\n };\n\n ws.onerror = () => {\n setError('WebSocket error');\n onError?.(new Error('WebSocket error'));\n };\n\n // Connect to LiveKit if available\n if (newSession.livekitUrl && newSession.livekitToken) {\n // Note: LiveKit connection would typically use @livekit/client-sdk\n // For now, we just store the connection info for the consumer to use\n }\n\n setStatus('connected');\n onConnect?.(newSession);\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : 'Connection failed';\n setStatus('error');\n setError(errorMessage);\n onError?.(err instanceof Error ? err : new Error(errorMessage));\n }\n },\n [adapter, config, status, timeout, onConnect, onDisconnect, onRpcResult, onError]\n );\n\n // Disconnect\n const disconnect = useCallback(async () => {\n if (wsRef.current) {\n wsRef.current.close();\n wsRef.current = null;\n }\n\n // Optionally notify server\n if (session) {\n try {\n await fetch(`${config.apiBaseUrl}/play-sessions/${session.id}`, {\n method: 'DELETE',\n headers: config.headers,\n });\n } catch {\n // Ignore errors on disconnect\n }\n }\n\n setSession(null);\n setStatus('disconnected');\n setVideoTrack(null);\n setAudioTrack(null);\n onDisconnect?.();\n }, [session, config, onDisconnect]);\n\n // Make RPC call\n const call = useCallback(\n <T = unknown>(method: string, params?: Record<string, unknown>): Promise<JsonRpcResponse<T>> => {\n return new Promise((resolve, reject) => {\n if (!wsRef.current || wsRef.current.readyState !== WebSocket.OPEN) {\n reject(new Error('Not connected'));\n return;\n }\n\n const id = ++rpcIdRef.current;\n const request = {\n jsonrpc: '2.0',\n id,\n method,\n params: params ?? {},\n };\n\n pendingCallsRef.current.set(id, {\n resolve: resolve as (value: JsonRpcResponse) => void,\n reject,\n });\n\n wsRef.current.send(JSON.stringify(request));\n\n // Timeout for RPC call\n setTimeout(() => {\n if (pendingCallsRef.current.has(id)) {\n pendingCallsRef.current.delete(id);\n reject(new Error('RPC call timeout'));\n }\n }, 30000);\n });\n },\n []\n );\n\n // Observe shorthand\n const observe = useCallback(\n async <T = unknown>(key: string): Promise<T> => {\n const response = await call<T>(`observe.${key}`);\n if (response.error) {\n throw new Error(response.error.message);\n }\n return response.result as T;\n },\n [call]\n );\n\n // Act shorthand\n const act = useCallback(\n async <T = unknown>(action: string, params?: Record<string, unknown>): Promise<T> => {\n const response = await call<T>(`act.${action}`, params);\n if (response.error) {\n throw new Error(response.error.message);\n }\n return response.result as T;\n },\n [call]\n );\n\n // Auto-connect on mount\n useEffect(() => {\n if (autoConnect) {\n connect();\n }\n }, [autoConnect]); // eslint-disable-line react-hooks/exhaustive-deps\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n if (wsRef.current) {\n wsRef.current.close();\n }\n };\n }, []);\n\n return {\n session,\n status,\n videoTrack,\n audioTrack,\n call,\n observe,\n act,\n connect,\n disconnect,\n isConnected: status === 'connected',\n error,\n };\n}\n"]}
|