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 (configserver.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.tsserveUIEffect): any unmatched path serves the web app — embedded assets when present, otherwise a reverse proxy tohttps://app.opencode.ai. The hosted app talks tolocation.originwhen served same-origin, so proxying makeshttp://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§
- Asset
Entry - 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).