"use client"; import { useCallback, useEffect, useState } from "react"; import { api } from "@/lib/api/client"; import type { components } from "@/lib/api/schema"; import { Card, CardContent } from "@/components/ui/card"; type Instance = components["schemas"]["InstanceStatus"]; function Stat({ label, value }: { label: string; value: React.ReactNode }) { return (
{label}
{value}
); } export default function AdminPage() { const [instance, setInstance] = useState(null); const [forbidden, setForbidden] = useState(false); const [ready, setReady] = useState(false); const load = useCallback(async () => { const { data, response } = await api.GET("/api/v1/admin/instance"); if (response.status === 403) setForbidden(true); else if (data) setInstance(data); setReady(true); }, []); useEffect(() => { load(); }, [load]); if (!ready) return
Loading…
; // Fail closed on anything that isn't a successful owner load: 403 (not owner), // 401 (not signed in), or any 5xx all land here rather than dereferencing null. if (forbidden || !instance) { return (

Instance admin

{forbidden ? "This area is for the instance owner only. Set OWNER_EMAIL in the server environment to your account email (and verify that email) to claim it." : "Instance status is unavailable right now. Make sure you're signed in as the instance owner."}

); } const i = instance; return (

Instance admin

Operational status for this deployment. You see this because your account is named in OWNER_EMAIL. Instance ownership is an operator role — it does not grant access to other people's private tree data.

AI providers (instance-wide)
{i.ai_providers.length === 0 ? (
None configured. Set provider credentials (Anthropic, OpenAI, x.AI, or Ollama) in the server environment.
) : (
    {i.ai_providers.map((p) => (
  • {p.name} {p.model}
  • ))}
)}
Default provider: {i.default_llm_provider}. Per-tree AI policy is set on each tree's AI page.
); }