import type { ReactNode } from "react"; import { Loader2, ShieldCheck, Terminal, TriangleAlert } from "lucide-react"; import { Link } from "@/lib/router"; import { Button } from "@/components/ui/button"; import { BOOTSTRAP_FALLBACK_COMMAND } from "@/bootstrapSetup"; import type { AuthSession } from "@paperclipai/shared"; type BootstrapPendingPageProps = { claimAvailable: boolean; hasActiveInvite?: boolean; session: AuthSession | null | undefined; claimState: "idle" | "claiming" | "success"; claimError?: { status?: number; message?: string } | null; onClaim: () => void; }; function CliFallback({ hasActiveInvite = false }: { hasActiveInvite?: boolean }) { return (
Prefer to finish setup from the host?

{hasActiveInvite ? "A bootstrap invite is already active. Check your Paperclip startup logs for the first-admin URL, or run this command on the host to rotate it:" : "Run this command on the host that runs Paperclip to print a one-time first-admin invite URL:"}

{BOOTSTRAP_FALLBACK_COMMAND}
      
); } function StateChrome({ children }: { children: ReactNode }) { return (
{children}
); } function displayIdentity(session: AuthSession) { return session.user.email || session.user.name || session.user.id; } function claimErrorCopy(error: BootstrapPendingPageProps["claimError"]) { if (error?.status === 409) { return { title: "Someone else has already claimed this instance.", body: "Refresh to sign in, or ask the existing admin to invite you from Instance settings -> Access.", }; } if (error?.status === 401) { return { title: "Your session expired. Sign in again to claim this instance.", body: "", }; } return { title: "We couldn't reach the server. Try again in a moment.", body: "", }; } export function BootstrapPendingPage({ claimAvailable, hasActiveInvite = false, session, claimState, claimError, onClaim, }: BootstrapPendingPageProps) { if (!claimAvailable) { return (

This Paperclip is waiting on its first admin

This instance runs in invite-only mode. The operator must generate a one-time first-admin invite URL from the host. Once you have the link, open it from this browser to finish setup.

Browser-based claim is intentionally disabled in public mode so anyone on the network can't promote themselves.

); } if (claimState === "success") { return (

You're the instance admin

Setup is complete. Taking you to onboarding to create your first company...

Redirecting...
); } if (!session) { return (

Finish setting up this Paperclip

No admin has claimed this instance yet. Sign in or create your Paperclip account to become the first admin from this browser.

); } const errorCopy = claimErrorCopy(claimError); const isClaiming = claimState === "claiming"; return (

Finish setting up this Paperclip

No admin has claimed this instance yet. Claim it now to become the first admin and start onboarding.

Signed in as {displayIdentity(session)}

Wrong account?{" "} Switch account .

{claimError && (

{errorCopy.title}

{errorCopy.body &&

{errorCopy.body}

}
)}
); }