// screens.jsx — content for each screen of the dashboard // Depends on: window.Icon, window.Sparkline, window.Bars, sample data globals const { useState, useEffect, useRef, useMemo } = React; // ─────────────────────────── shared bits ─────────────────────────── const Pill = ({ tone = "muted", pulse = false, children }) => ( {children} ); const SectionHd = ({ title, sub, actions }) => (

{title}

{sub &&

{sub}

}
{actions &&
{actions}
}
); const Card = ({ title, actions, flush, children }) => (
{title && (
{title} {actions && <>
{actions}
}
)}
{children}
); const TokenField = ({ value, copyValue }) => { const [shown, setShown] = useState(false); const [copied, setCopied] = useState(false); const text = value || ""; const clipboardText = copyValue || text; const masked = "•".repeat(Math.max(8, Math.min(24, text.length || clipboardText.length || 8))); const copy = () => { navigator.clipboard?.writeText(clipboardText).catch(() => {}); setCopied(true); setTimeout(() => setCopied(false), 1100); }; return (
{shown ? clipboardText : masked}
); }; const CopyBtn = ({ text, label = "Copy" }) => { const [copied, setCopied] = useState(false); const copy = () => { navigator.clipboard?.writeText(text).catch(() => {}); setCopied(true); setTimeout(() => setCopied(false), 1100); }; return ( ); }; const stateMeta = { running: { tone: "ok", label: "Running", pulse: true }, warning: { tone: "warn", label: "Running", pulse: true }, stopped: { tone: "err", label: "Stopped", pulse: false }, }; // ─────────────────────────── DASHBOARD ─────────────────────────── const Dashboard = ({ proxyState, onAction, liveStatus }) => { const m = stateMeta[proxyState]; const isUp = proxyState !== "stopped"; const [validation, setValidation] = useState(VALIDATION_STEPS); const [validationMeta, setValidationMeta] = useState(null); const runValidation = () => api.get("/ui/api/validate").then(res => { setValidation((res.steps || []).map(s => ({ name: s.name, expect: `${s.status || 0} ${s.ok ? "OK" : "FAILED"}`, tone: s.ok ? "ok" : "err", ms: s.duration_ms || 0, }))); setValidationMeta({ ok: !!res.ok, ran_at: res.ran_at || "", model: res.upstream_model || res.model || "", }); }).catch(() => {}); useEffect(() => { runValidation(); }, []); const dashboard = liveStatus?.dashboard || {}; const traffic = dashboard.traffic || {}; const sparks = dashboard.sparks || {}; const lastValidation = validationMeta || dashboard.last_validation || {}; const zeroSpark = Array.from({ length: 60 }, () => 0); const reqSpark = sparks.requests || zeroSpark; const latSpark = sparks.latency || zeroSpark; const tokSpark = sparks.tokens || zeroSpark; const errSpark = sparks.errors || zeroSpark; const fmtCount = (n) => { n = Number(n || 0); if (n >= 1000000) return `${(n / 1000000).toFixed(1)}m`; if (n >= 1000) return `${(n / 1000).toFixed(n >= 10000 ? 0 : 1)}k`; return `${n}`; }; const fmtPct = (n) => `${Number(n || 0).toFixed(1)}%`; const fmtDelta = (n) => { n = Number(n || 0); if (!Number.isFinite(n) || Math.abs(n) < 0.1) return "no change"; return `${n > 0 ? "▲" : "▼"} ${Math.abs(n).toFixed(0)}%`; }; const validationOk = validation.length > 0 && validation.every(s => s.tone === "ok"); const rootUrl = liveStatus?.display_url || liveStatus?.public_url || liveStatus?.local_url || "http://127.0.0.1:4000"; const anthropicUrl = liveStatus?.anthropic_url || `${rootUrl}/anthropic`; const openaiUrl = liveStatus?.openai_url || `${rootUrl}/openai/v1`; return (
} /> {/* Hero state row */}
{m.label} {proxyState === "warning" && Codex auth · expires in 7d} {proxyState === "stopped" && Endpoints paused} uptime {isUp ? fmtUptime(liveStatus?.uptime_seconds || 0) : "—"}
Anthropic {anthropicUrl}
OpenAI {openaiUrl}

Split Anthropic/OpenAI API surfaces · forwarding to codex chatgpt backend

{isUp ? ( <> ) : ( )}
{liveStatus?.public_url ? "Public HTTPS · local app remains private" : "Local-only · bound to 127.0.0.1"}
PID
{isUp ? (liveStatus?.pid || "—") : "—"}
Upstream
{liveStatus?.upstream || "codex"} · chatgpt subscription
Codex auth
{liveStatus?.codex_auth?.exists ? Found · {liveStatus?.codex_auth?.mode || "unknown"} : Missing} {liveStatus?.codex_auth?.path || "~/.codex/auth.json"}
Local API key
Claude settings
{liveStatus?.claude_settings?.mode || "none"} · api key {liveStatus?.claude_settings?.api_key_present ? "present" : "absent"} · cache {liveStatus?.claude_settings?.gateway_cache_present ? "present" : "absent"}
Codex sessions
{liveStatus?.codex_sessions?.count || 0} · prompt key {liveStatus?.codex_sessions?.prompt_cache_key_enabled ? "on" : "off"} · one-shot {liveStatus?.codex_sessions?.side_thread_count || 0}
Browser bridge
{liveStatus?.antigravity?.ready ? Ready : Needs check} Code {liveStatus?.antigravity?.mcp?.present ? "MCP ready" : "MCP missing"} · Desktop {liveStatus?.antigravity?.mcp?.desktop?.present ? "MCP ready" : "MCP missing"} {liveStatus?.antigravity?.extension?.manifest?.version ? ` · ext ${liveStatus.antigravity.extension.manifest.version}` : ""}
Active aliases
{liveStatus?.models?.length || 0} · opus[1m], sonnet[1m], gpt-5.3-codex
Last request
{liveStatus?.last_request ? `${liveStatus.last_request.meth} ${liveStatus.last_request.path} · ${liveStatus.last_request.status}` : "—"}
{/* Stats */}
Requests / min
{isUp ? fmtCount(dashboard.requests_per_min) : "0"} = 0 ? "delta-up" : "delta-down"}`}>{fmtDelta(dashboard.requests_delta_pct)}
Avg latency
{isUp ? (Number(dashboard.avg_latency_ms || 0) / 1000).toFixed(2) : "—"}s {fmtCount(dashboard.requests_per_min)} req · last 60s
Tokens / min
{isUp ? fmtCount(dashboard.tokens_per_min) : "0"} in {fmtCount(dashboard.input_tokens)} · out {fmtCount(dashboard.output_tokens)}
Error rate
{Number(dashboard.error_rate || 0).toFixed(1)}% {dashboard.error_count ? `${dashboard.error_count} errors` : "no errors"}
{/* Two-col validation + recent traffic */}
Run again} flush> {validation.map(s => ( ))}
CheckResultDuration
{s.name} {s.expect} {s.ms < 1000 ? `${s.ms} ms` : `${(s.ms/1000).toFixed(2)} s`}
{validationOk ? "All checks passed" : "Some checks failed"} · last run {lastValidation.ran_at || "not yet"} · model {lastValidation.upstream_model || lastValidation.model || "—"}
window 1s}>
Math.max(0, v))}/>
−60s−30snow
2xx
{traffic.status_2xx || 0} {fmtPct(traffic.status_2xx_pct)}
4xx
{traffic.status_4xx || 0} {fmtPct(traffic.status_4xx_pct)}
5xx
{traffic.status_5xx || 0} {fmtPct(traffic.status_5xx_pct)}
streamed
{traffic.streamed || 0} {fmtPct(traffic.streamed_pct)}
); }; // ─────────────────────────── CONFIGURATION ─────────────────────────── const Configuration = ({ pushToast }) => { const [cfg, setCfg] = useState(DEFAULT_CONFIG); const [secrets, setSecrets] = useState({}); const [aliases, setAliases] = useState(ALIAS_DEFAULTS); const [dirty, setDirty] = useState(false); const [authMeta, setAuthMeta] = useState(null); useEffect(() => { api.get("/ui/api/config").then(res => { setCfg(c => ({ ...c, ...res.config })); setSecrets(res.secrets || {}); setAliases((res.aliases || []).map(a => ({ from: a.from, to: a.to, context: a.context || "200k" }))); setDirty(false); }).catch(() => {}); api.get("/ui/api/status").then(res => setAuthMeta(res.codex_auth)).catch(() => {}); }, []); const update = (k, v) => { setCfg(c => ({ ...c, [k]: v })); setDirty(true); }; const updateAlias = (i, k, v) => { setAliases(a => a.map((row, idx) => idx === i ? { ...row, [k]: v } : row)); setDirty(true); }; const removeAlias = (i) => { setAliases(a => a.filter((_, idx) => idx !== i)); setDirty(true); }; const addAlias = () => { setAliases(a => [...a, { from: "", to: "", context: "200k" }]); setDirty(true); }; const portValid = /^\d{2,5}$/.test(cfg.PROXY_PORT) && +cfg.PROXY_PORT >= 1024; const urlValid = /^https?:\/\//.test(cfg.CODEX_BASE_URL); const canSave = dirty && portValid && urlValid; const save = () => { if (!canSave) return; api.post("/ui/api/config", { config: cfg, aliases }).then(res => { setDirty(false); pushToast(res.message || "Configuration saved · restart proxy to apply"); }).catch(e => pushToast(`Save failed · ${e.message || e}`)); }; const reset = () => { setCfg(DEFAULT_CONFIG); setAliases(ALIAS_DEFAULTS); setDirty(true); }; return (
{dirty && Unsaved changes} } />
UPSTREAM Where this proxy forwards requests.
{["codex", "openai"].map(opt => ( ))}
{cfg.UPSTREAM === "codex" ? "Uses your Codex ChatGPT subscription via ~/.codex/auth.json." : "Uses a raw OpenAI API key. Codex-only models will be unavailable."}
CODEX_BASE_URL Endpoint of the Codex backend.
update("CODEX_BASE_URL", e.target.value)}/> {!urlValid &&
Must start with http:// or https://
}
CODEX_AUTH_FILE Path to the local Codex auth cache.
update("CODEX_AUTH_FILE", e.target.value)}/>
{authMeta?.exists ? `File exists · mode ${authMeta.mode || "unknown"}` : "File missing or unavailable"}
PROXY_PUBLIC_URL Public HTTPS/domain URL shown to clients. Standard ports stay hidden.
update("PROXY_PUBLIC_URL", e.target.value)} placeholder="https://ai-api1.cus.cx"/>
Leave empty for local-only installs.
PROXY_PORT Port to bind on 127.0.0.1.
update("PROXY_PORT", e.target.value)} style={{maxWidth: 120}}/> {portValid ?
Port available · proxy will bind to 127.0.0.1:{cfg.PROXY_PORT}
:
Use a numeric port ≥ 1024.
}
PROXY_API_KEY Token Claude Code presents to this proxy. Never sent upstream.
This is the local-proxy authentication, not your Codex ChatGPT auth.
REQUEST_TIMEOUT_MS Per-request timeout against the upstream.
update("REQUEST_TIMEOUT_MS", e.target.value)} style={{maxWidth: 160}}/>
LOG_LEVEL Verbosity of the proxy log stream.
{["debug", "info", "warn", "error"].map(opt => ( ))}
Add alias} flush >
Claude Code asks for Anthropic model names; the proxy rewrites the model field before forwarding.
Public alias (Claude Code) Codex model Context
{aliases.map((a, i) => (
updateAlias(i, "from", e.target.value)}/> updateAlias(i, "to", e.target.value)}/>
))}
); }; // ─────────────────────────── API KEYS ─────────────────────────── const ApiKeys = ({ pushToast = () => {}, liveStatus }) => { const [data, setData] = useState({ providers: [], clients: [], defaults: {} }); const [providerForm, setProviderForm] = useState({ id: "", provider: "gemini", label: "Google AI Studio", base_url: "", api_key: "" }); const [clientForm, setClientForm] = useState({ label: "Claude Code", schema: "both", provider: "default", provider_key_id: "" }); const [createdKey, setCreatedKey] = useState(""); const load = () => api.get("/ui/api/keys").then(setData).catch(e => pushToast(`Load failed · ${e.message || e}`)); useEffect(() => { load(); }, []); const defaults = data.defaults || {}; const providerOptions = data.providers || []; const selectedProviderKeys = providerOptions.filter(p => p.provider === clientForm.provider && p.enabled); const rootUrl = liveStatus?.display_url || liveStatus?.public_url || liveStatus?.local_url || "http://127.0.0.1:4000"; const anthropicUrl = liveStatus?.anthropic_url || defaults.anthropic_base || `${rootUrl}/anthropic`; const openaiUrl = liveStatus?.openai_url || defaults.openai_local_url || `${rootUrl}/openai/v1`; const providerBaseDefault = providerForm.provider === "gemini" ? defaults.gemini_base_url : defaults.openai_base_url; const saveProvider = () => { api.post("/ui/api/keys/provider", { ...providerForm, base_url: providerForm.base_url || providerBaseDefault }) .then(res => { setData(d => ({ ...d, providers: res.providers || d.providers, clients: res.clients || d.clients })); setProviderForm(f => ({ ...f, id: "", api_key: "" })); pushToast(res.message || "Provider key saved"); }) .catch(e => pushToast(`Save failed · ${e.message || e}`)); }; const renewProvider = (p) => { setProviderForm({ id: p.id, provider: p.provider, label: p.label, base_url: p.base_url, api_key: "", }); pushToast(`Renewing ${p.label} · paste the new provider key`); }; const createClient = () => { api.post("/ui/api/keys/client", clientForm) .then(res => { setCreatedKey(res.api_key || ""); setData(d => ({ ...d, providers: res.providers || d.providers, clients: res.clients || d.clients })); pushToast(res.message || "Client key created"); }) .catch(e => pushToast(`Create failed · ${e.message || e}`)); }; const toggle = (kind, row) => { api.post("/ui/api/keys/toggle", { kind, id: row.id, enabled: !row.enabled }) .then(res => setData(d => ({ ...d, providers: res.providers || d.providers, clients: res.clients || d.clients }))) .catch(e => pushToast(`Update failed · ${e.message || e}`)); }; return (
Refresh} />
Anthropic base URL
{anthropicUrl}
Use this with Claude Code.
OpenAI-compatible base URL
{openaiUrl}
Use this for OpenAI SDK-compatible clients.
Provider keys
{providerOptions.length}
OpenAI · Google AI Studio
Client keys
{(data.clients || []).length}
Local proxy authentication
{[ { value: "gemini", label: "Google AI Studio" }, { value: "openai", label: "OpenAI" }, ].map(opt => ( ))}
setProviderForm(f => ({ ...f, label: e.target.value }))}/> setProviderForm(f => ({ ...f, base_url: e.target.value }))}/> setProviderForm(f => ({ ...f, api_key: e.target.value }))} type="password"/> {providerForm.id && }
Schema: OpenAI-compatible. Gemini uses the Google AI Studio OpenAI-compatible base URL; keys are encrypted in SQLite.
setClientForm(f => ({ ...f, label: e.target.value }))}/> {clientForm.provider !== "default" && ( )} {createdKey && (
Copy this key now. It will not be shown again.
)}
{(data.providers || []).map(p => ( ))}
ProviderSchemaLabelBase URLKeyStatus
{p.provider} {p.schema || "openai-compatible"} {p.label} {p.base_url} {p.key_preview} {p.enabled ? Enabled : Disabled}
{!(data.providers || []).length &&
No provider keys yet.
}
{(data.clients || []).map(k => ( ))}
LabelKeySchemaRouteStatus
{k.label} {k.key_preview} {k.schema || "both"} {k.provider ? `${k.provider}${k.provider_label ? " · " + k.provider_label : ""}` : "default"} {k.enabled ? Enabled : Disabled}
{!(data.clients || []).length &&
No client keys yet.
}
); }; // ─────────────────────────── MODELS ─────────────────────────── const CODEX_MODEL_OPTIONS = ["gpt-5.5", "gpt-5.4", "gpt-5.4-mini", "gpt-5.3-codex"]; function modelStatusFor(real) { if (!real) return "unsupported"; return CODEX_MODEL_OPTIONS.includes(real) ? "ok" : "untested"; } function normalizeModelDraft(m, idx = 0) { const alias = m.alias || ""; const real = m.real || ""; const status = m.status || modelStatusFor(real); return { id: m.id || alias || `model-${idx}`, alias, real, status, context: (m.context || "200k").toLowerCase() === "1m" ? "1m" : "200k", desc: m.desc || `${alias || "New alias"} maps to ${real || "no upstream model"}`, default: !!m.default, recommended: !!m.recommended, }; } const Models = ({ pushToast = () => {} }) => { const [filter, setFilter] = useState("all"); const [query, setQuery] = useState(""); const [models, setModels] = useState(SAMPLE_MODELS.map(normalizeModelDraft)); const [editing, setEditing] = useState(null); const [dirty, setDirty] = useState(false); const [saving, setSaving] = useState(false); const refresh = () => api.get("/ui/api/models").then(res => { setModels((res.models || []).map((m, i) => normalizeModelDraft({ alias: m.alias, real: m.real, status: m.status, context: m.context || "200k", desc: `${m.alias} maps to ${m.real}`, default: m.default, recommended: m.recommended, }, i))); setDirty(false); setEditing(null); }).catch(() => {}); useEffect(() => { refresh(); }, []); const aliasCounts = useMemo(() => models.reduce((acc, m) => { const key = m.alias.trim().toLowerCase(); if (key) acc[key] = (acc[key] || 0) + 1; return acc; }, {}), [models]); const invalidIds = useMemo(() => new Set(models.filter(m => { const alias = m.alias.trim(); const real = m.real.trim(); return !alias || !real || aliasCounts[alias.toLowerCase()] > 1 || /\s/.test(alias); }).map(m => m.id)), [models, aliasCounts]); const filtered = models.filter(m => { const statusMatch = filter === "all" || m.status === filter || (filter === "warn" && (m.status === "warn" || m.status === "untested")); const q = query.trim().toLowerCase(); const queryMatch = !q || m.alias.toLowerCase().includes(q) || m.real.toLowerCase().includes(q); return statusMatch && queryMatch; }); const counts = models.reduce((acc, m) => { acc[m.status] = (acc[m.status] || 0) + 1; return acc; }, {}); const canSave = dirty && !saving && invalidIds.size === 0; const updateModel = (id, key, value) => { setModels(rows => rows.map(row => { if (row.id !== id) return row; const next = normalizeModelDraft({ ...row, [key]: value, status: key === "real" ? modelStatusFor(value) : row.status }); if (key === "real") next.status = modelStatusFor(value.trim()); next.desc = `${next.alias || "New alias"} maps to ${next.real || "no upstream model"}`; return next; })); setDirty(true); }; const addAlias = () => { const id = `new-${Date.now()}`; setModels(rows => [...rows, normalizeModelDraft({ id, alias: "", real: "gpt-5.5", context: "200k", status: "ok", desc: "New alias maps to gpt-5.5" })]); setEditing(id); setFilter("all"); setDirty(true); }; const removeModel = (id) => { setModels(rows => rows.filter(row => row.id !== id)); if (editing === id) setEditing(null); setDirty(true); }; const save = () => { if (!canSave) { if (invalidIds.size > 0) pushToast("Fix blank or duplicate model aliases first"); return; } setSaving(true); api.post("/ui/api/models", { models: models.map(m => ({ alias: m.alias.trim(), real: m.real.trim(), context: m.context })), }).then(res => { setModels((res.models || []).map((m, i) => normalizeModelDraft({ alias: m.alias, real: m.real, status: m.status, context: m.context || "200k", desc: `${m.alias} maps to ${m.real}`, default: m.default, recommended: m.recommended, }, i))); setDirty(false); setEditing(null); pushToast(res.message || "Model aliases saved"); }).catch(e => pushToast(`Save failed · ${e.message || e}`)) .finally(() => setSaving(false)); }; return (
{dirty && {invalidIds.size ? "Fix rows" : "Unsaved changes"}} } />
setQuery(e.target.value)} style={{ width: 220, height: 26 }}/>
{CODEX_MODEL_OPTIONS.map(model => {filtered.map(m => ( ))}
Public alias Codex model Context Status Notes
{editing === m.id ? ( updateModel(m.id, "alias", e.target.value)} placeholder="claude-sonnet-4-6"/> ) : (
{m.alias} {m.default && default} {m.recommended && recommended}
)}
{editing === m.id ? ( updateModel(m.id, "real", e.target.value)} placeholder="gpt-5.5"/> ) : (m.real || "—")} {editing === m.id ? ( ) : (m.context === "1m" ? 1M tokens : 200k)} {m.status === "ok" && Available} {m.status === "warn" && Untested} {m.status === "untested" && Untested} {m.status === "unsupported" && Unsupported} {invalidIds.has(m.id) ? "Alias and Codex model are required; aliases must be unique." : `${m.alias || "New alias"} maps to ${m.real || "no upstream model"}`}
{filtered.length === 0 && (
No model aliases match this filter.
)}
How aliasing works. Claude Code requests Anthropic-style model names like opus[1m] or claude-opus-4-7[1m]. This proxy rewrites the model field at request time and forwards the call to the configured Codex model. Capabilities (tool use, streaming, vision) are mapped per-alias — see the configuration screen to override.
); }; window.Pill = Pill; window.SectionHd = SectionHd; window.Card = Card; window.TokenField = TokenField; window.CopyBtn = CopyBtn; window.Dashboard = Dashboard; window.Configuration = Configuration; window.ApiKeys = ApiKeys; window.Models = Models;