import CustomerGrid from "./customer-grid/CustomerGrid"; import { OverlayProvider } from "./customer-grid/OverlaySurface"; import { isStreamlitComponent } from "./customer-grid/hostBridge"; import Shell from "./shell/Shell"; // HOSTED = either Streamlit path (the component iframe, or the legacy injected // payload). There the surrounding app owns all chrome and this tree renders the // BARE grid, byte-for-byte the behavior the embed always had. Only the // standalone build gets the shell (wave 4, the strangler frame). Computed once // at module level, like useCustomerData's own mode constants — the host mode // cannot change within a page lifetime. // EXPORTED (EXIT wave 1): main.tsx needs the same answer to decide whether to // install the standalone event sink, and two copies of a mode predicate is how // the two halves of "standalone-only" end up disagreeing. export const HOSTED = isStreamlitComponent() || typeof (window as unknown as { __AIOS_GRID__?: unknown }).__AIOS_GRID__ !== "undefined"; export default function App() { if (HOSTED) { return (