Web UI
The Web UI is a SvelteKit single-page app served by Fastify. xterm.js powers the terminal, and a WebSocket carries terminal I/O plus session and sign-request events.
Layout
Section titled “Layout”- Sidebar (desktop) — endpoints, your passkeys, and active sessions. Slides in from the left on mobile (
<768px). - Active session — terminal fills the main panel, auto-resizes with the window.
- Settings tab bar — General, Endpoints, Passkeys, Sessions, Notifications, Setup (plus an admin-only “Other SSH Keys” tab when file-based keys exist).
Routes
Section titled “Routes”| Route | View |
|---|---|
/ | Default terminal — last-used or first available session |
/session/:id | Specific terminal session |
/observer | Multi-session grid view |
/sign/:id | Sign-request approval page |
/register | Passkey registration (gated by selfRegistrationEnabled) |
/auth/callback | OAuth redirect URI — handled client-side, you never land here manually |
/passkey-invite/:token | Token-gated cross-device passkey enrollment |
/settings/general | Account settings + build info (SHA / ref via /api/version) |
/settings/endpoints | SSH endpoint CRUD |
/settings/keys | Passkey management (add / revoke / invite). Revoke offers an optional “invalidate all sessions” |
/settings/sessions | Authorized OAuth clients — list and revoke (this app, MCP clients, agents) |
/settings/ssh-keys | Admin only — file-based “Other SSH Keys” (when present) |
/settings/notifications | Web Push subscription |
/settings/setup | Onboarding / setup checklist |
/audit/sessions | Session-lifecycle audit log |
/audit/signings | Signing-request audit log |
/admin/accounts | Admin: account management (admins only) |
/admin/general | Admin: instance-wide settings (admins only) |
There’s no /login route — login is server-rendered by the OAuth flow at /api/hydra/login (the SPA redirects into it automatically when it has no token).
Sessions
Section titled “Sessions”Click Connect on an endpoint in the sidebar to open a terminal. Each session is labelled with its source (ui, mcp, ssh) so you can tell who created it. Sessions persist across reloads — the connection lives in the broker, not the browser.
- Switch sessions — click a session in the sidebar. Any unread output is still buffered.
- Take/release control — when multiple tabs are attached to the same session, only one at a time has input. Other tabs see output but can’t type.
- Real-time sync — sessions created via MCP for the same account, or in another tab logged in as you, appear in the sidebar instantly. No refresh needed. Other accounts’ sessions are never visible.
Observer mode
Section titled “Observer mode”/observer shows multiple of your sessions side-by-side in a responsive grid — useful for watching what your AI agent (or a SSH-agent-proxy run) is doing across several boxes at once. Like every other view, the grid is scoped to the logged-in account; you can’t observe another user’s sessions. Cells are read-only — click in to switch to the regular terminal view to type.
First-run onboarding
Section titled “First-run onboarding”Brand-new accounts are walked through a short in-app wizard before they land on the main terminal: registering the first passkey, adding an SSH endpoint with a hint about sshd setup, an MCP-client introduction, and the option to subscribe to Web Push and explore advanced topics. The wizard is dismissible; you can revisit any of those settings later under Settings → ….
Audit log
Section titled “Audit log”/audit/sessions and /audit/signings show every session your account has opened and every signing decision (approved, denied, expired, cancelled) with the full request context preserved at decision time. Reads are keyset-paginated and account-scoped — admin role doesn’t widen the view across other accounts. See Concepts → Audit log.
Sign-request approval
Section titled “Sign-request approval”When ShellWatch needs a human to authorise an action (passkey signature for endpoint auth, agent-proxy operation, agent forwarding from a running session), a toast appears with a link to /sign/:id. If you’ve subscribed to Web Push (Settings → Notifications) and your tab is closed, you’ll get an OS-level notification instead.
The approval page shows context — endpoint label, source IP, MCP client name/version, agent client hostname/OS — so you can sanity-check before tapping your authenticator. See Concepts → Sign requests for what each field means and what’s trustworthy.
Mobile / PWA
Section titled “Mobile / PWA”The UI is a Progressive Web App. On iOS Safari and Android Chrome you can “Add to Home Screen” to get an app-style launcher. Combined with Web Push, this turns your phone into the approval device for sign requests fired by AI agents or local ssh clients on any of your machines.
Keyboard
Section titled “Keyboard”The terminal is xterm.js — standard terminal shortcuts work (Ctrl-C, Ctrl-D, etc.). Browser shortcuts compete with shell shortcuts in the usual way (Ctrl-W will close the tab if you don’t catch it). Use a separate browser window for ShellWatch if this is a problem.