import { createRootRoute, Outlet, useRouterState } from "@tanstack/react-router"; import { useEffect, useState, type ReactNode } from "react"; import { ExecutorProvider } from "@executor-js/react/api/provider"; import { ExecutorPluginsProvider } from "@executor-js/sdk/client"; import { OrganizationProvider } from "@executor-js/react/api/organization-context"; import { OrgSlugGate } from "@executor-js/react/multiplayer/org-slug-gate"; import { Toaster } from "@executor-js/react/components/sonner"; import { AuthProvider, useAuth } from "@executor-js/react/multiplayer/auth-context"; import { Shell, defaultShellNavItems } from "@executor-js/react/multiplayer/shell"; import { plugins as clientPlugins } from "virtual:executor/plugins-client"; import { authClient } from "../auth-client"; import { McpConsentPage } from "../mcp-consent"; import { LoginPage } from "../login"; import { SetupPage } from "../setup"; import { fetchNeedsSetup } from "../setup-status"; // --------------------------------------------------------------------------- // Self-host root: the SHARED multiplayer composition with Better Auth as the // provider. Same shell, pages, and account surface as cloud — the only // self-host specifics are the login form (email/password) and sign-out (Better // Auth), injected here. No billing, Sentry, or PostHog. // --------------------------------------------------------------------------- export const Route = createRootRoute({ component: RootComponent, }); // Self-host adds the account's API keys and the instance Admin page (members + // invite links) to the shared nav. The Admin page and its API gate to // owner/admin, so a non-admin who opens it just sees the access notice. const selfHostNavItems = [ ...defaultShellNavItems, { to: "/api-keys", label: "API keys" }, { to: "/admin", label: "Admin" }, ]; const signOut = async () => { await authClient.signOut(); window.location.href = "/"; }; const Loading = () => (