Skip to content

Web GUI

The Web GUI is the browser target of the GUI. It shares one view tree with the Desktop GUI. The agent doesn’t serve it: the shell comes from the release channel (R2), and the origin in front of that channel serves it — by default the agent’s own origin, so the console and /api are same-origin.

gui/index.html and the wasm bundle (with Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp) are published to the release channel. The agent’s own nginx serves that shell at / (infra/nginx/steelframe.conf.tpl, GUI_CHANNEL) and proxies /api, /ws, and /mcp straight to the agent, so the browser is same-origin with the agent and there is no second SSO layer: the app shows its own Sign in to Steelframe gate. A separate GUI origin (infra/caddy/gui.caddy, oauth2-proxy in front of R2) remains the cluster shape for hosts that want a different hostname.

Because the GUI and /api are served from one origin, the browser session is a signed cookie (sf_session), so the Web GUI carries no bearer token.

  • Dashboard — environment health, capacity, active work.
  • Chat — operator Q&A with streamed replies (SSE); thinking collapses into an accordion; chats can be deleted.
  • Board — issue-rooted Kanban plus the local backlog.
  • Config — settings with inline typed editors, branding (project logo and theme colors), credentials, health checks, skills.
  • Audit — state mutations.

The Web GUI uses a GitHub OAuth login against the agent’s GUI origin and a session cookie. If the session is rejected the GUI shows a sign-in gate. Sign-in always targets the page origin — never a remote selected agent, because a cookie set on another origin is one the GUI can never read.

Desktop clients have no cookie session and use a pasted token instead; see Desktop and Auth.

Terminal window
make gui-wasm # pinned cargo +nightly build ... --target wasm32-unknown-unknown, then wasm-bindgen

The release workflow builds and publishes the wasm bundle automatically; a broken or missing bundle fails the release closed.