Skip to main content

Module ui

Module ui 

Source
Expand description

Web-UI backend support (Phase 7): upstream-parity CORS + the catch-all UI proxy.

Upstream v1 semantics (probed live 2026-08/10):

  • CORS (server/src/cors.ts): allowed = no Origin, http://localhost:*, http://127.0.0.1:*, oc://renderer, tauri://localhost, http(s)://tauri.localhost, https://*.opencode.ai, plus user extras (config server.cors + --cors). Disallowed origins get NO ACAO header (not a rejected request). Preflight → 204, methods GET,HEAD,PUT,PATCH,POST,DELETE, allow-headers echoes requested, max-age 86400.
  • Catch-all (shared/ui.ts serveUIEffect): any unmatched path serves the web app — embedded assets when present, otherwise a reverse proxy to https://app.opencode.ai. The hosted app talks to location.origin when served same-origin, so proxying makes http://127.0.0.1:4096/ a fully working self-hosted UI. HTML proxied through gets the upstream CSP (theme-preload script hash included).

Divergences (documented): OCSERVE_UI=0 disables the proxy (JSON 404 instead) for air-gapped/CI use; OCSERVE_UI_UPSTREAM overrides the URL.

Structs§

AssetEntry
UiProxy
The UI proxy decision + lazy asset cache, frozen at boot (env is read once — SRE fail-fast discipline; changing it = restart).

Constants§

ASSET_CACHE_CAP
Lazy, byte-accounted LRU for proxied static assets (WEBUI-PLAN W3).
ASSET_ENTRY_CAP
Largest single asset we will cache (a pathological upstream artifact larger than this streams through uncached rather than displacing the whole cache).
DEFAULT_UI_UPSTREAM

Functions§

cors_gate
Hand-rolled CORS middleware with exact freeze parity (probed live): preflight → 204 with ACAO + echoed ACAH + ACM 4 methods… actually the freeze method list is GET, HEAD, PUT, PATCH, POST, DELETE, ACAH echoes the requested list, max-age 86400, Vary: Access-Control-Request-Headers, Origin. Simple requests get ACAO only. Disallowed origins pass through WITHOUT headers (upstream never rejects the request itself).
is_allowed_cors_origin
Upstream predicate (cors.ts isAllowedCorsOrigin), verbatim rules.
prewarm_assets
W3 opt-in prewarm: fetch the entry HTML, parse referenced /assets/*, fetch each once so the lazy cache is warm. Bounded (the app references a handful); best-effort — any network error returns without touching state.
ui_fallback
Axum fallback: reverse-proxy unmatched paths to the UI upstream (upstream v1 serveUIEffect). Disabled → JSON 404 {"error":"Not Found"} (upstream’s own notFound() shape when embedded assets are missing).