Embedded Web Server & WebSockets
Relevant source files
The following files were used as context for generating this wiki page:
The Termul embedded web server provides a headless runtime and remote access capabilities using the Rust Axum framework. This system enables the standalone termul-server binary and supports shared-live remote sessions by exposing RESTful API endpoints and WebSocket upgrades for real-time terminal I/O and event dispatching.
The server manages static asset delivery, health monitoring, and project-aware operations including filesystem access, Git integration, and Agentic Computing Protocol (ACP) interactions. It maintains parity with the desktop Tauri runtime by mirroring internal commands as HTTP routes, allowing the same React/TypeScript renderer to function in both desktop and browser environments.
Sources: src-tauri/src/web/router.rs:1-15, src-tauri/src/server_main.rs:1-15, AGENTS.md:7-12
Server Architecture and Routing
The core of the web system is an Axum router that defines the API surface and static file handling. The router prioritizes specialized routes like /ws and /health to ensure they are not shadowed by the static asset fallback.
The diagram illustrates how incoming requests pass through security gates before reaching specific API handlers or service managers.
Sources: src-tauri/src/web/router.rs:77-160, src-tauri/src/web/router.rs:370-385
Key Route Categories
| Prefix / Route | Methods | Description |
|---|---|---|
/health | GET | Returns liveness status and remote write capabilities. |
/ws | GET | Upgrades to the main app WebSocket for ACP events and state. |
/terminal/ws | GET | Upgrades to a dedicated terminal WebSocket for PTY I/O. |
/fs/* | GET, POST | Handles directory listing, reading, writing, and deletion. |
/git/* | POST | Exposes Git operations like status, diff, commit, and push. |
/projects/* | GET, POST, PUT | Manages project registration and default project settings. |
/workspace/* | GET, POST | Synchronizes workspace manifests for cross-client continuity. |
Sources: src-tauri/src/web/router.rs:141-260, src/renderer/lib/web-server-api.test.ts:40-200
Standalone Server (termul-server)
The termul-server is a standalone console application that operates without a GUI. It initializes the Rust tokio runtime to host the Axum server and manages durable session persistence.
Configuration and CLI Flags
The server accepts various flags to control its behavior, security posture, and data locations.
- Network Control:
--hostdefaults to127.0.0.1and--portdefaults to8080. - Write Admission:
--allow-remote-writespermits non-loopback peers to perform mutations, provided they pass the auth gate. - State Management: Flags like
--state-dir,--sessions-dir, and--projects-filedefine where the server stores its data. - Auth Gate:
--web-auth-tokenenables a mandatory Bearer token check for gated routes.
Sources: src-tauri/src/server_main.rs:434-520, src-tauri/src/server_main.rs:165-180
Security and Authentication
Termul implements a web_auth_gate middleware that enforces token-based security.
The sequence diagram shows the authorization flow for protected API endpoints.
Sources: src-tauri/src/web/router.rs:445-485
WebSocket Infrastructure
WebSockets provide the low-latency communication required for terminal emulation and real-time agent feedback.
Terminal WebSockets
The /terminal/ws route handles PTY (Pseudo-Terminal) data streams. When a client connects, the server upgrades the connection and links it to a specific terminal session managed by the PtyManager. This allows the browser to send keystrokes and receive ANSI escape sequences for rendering in the Xterm.js frontend.
Sources: src-tauri/src/web/router.rs:143, README.md:155-165
App State Dispatches
The primary /ws endpoint facilitates the Agentic Computing Protocol (ACP). It handles:
- Event Broadcasting: Notifying clients of filesystem changes via the
fs_changedevent. - State Replay: Sending historical transcript data to newly connected clients.
- Permission Requests: Managing interactive prompts that require user approval for agent actions.
Sources: src-tauri/src/web/router.rs:142, src/renderer/lib/tests/parity-checklist.test.ts:1080-1110
Client-Side Integration
The React renderer uses a facade pattern to switch between Tauri IPC (invoke) and the Web Server REST API (fetch) based on the environment detected by isTauriContext().
// Example from parity-checklist tests showing the web transport
it('readDirectory hits HTTP GET when !isTauriContext()', async () => {
const result = await webServerFilesystem.readDirectory('C:/proj');
expect(mockFetch).toHaveBeenCalledWith(
`${window.location.origin}/fs/ls?path=C%3A%2Fproj`,
expect.objectContaining({ method: 'GET' })
);
});
Sources: src/renderer/lib/web-server-api.test.ts:135-155, src/renderer/lib/tests/parity-checklist.test.ts:250-280
Periodic Self-Updates
The standalone server includes a periodic update loop. It checks for new binaries on designated update channels (stable, insider, nightly), verifies digital signatures using a baked-in public key, and atomically swaps the binary. If a new binary fails to restart, the server automatically restores the previous version to ensure continuous availability.
Sources: src-tauri/src/server_main.rs:355-430
The embedded web server and WebSocket system transform Termul from a local desktop application into a flexible, project-aware server capable of remote collaboration and headless operation. Through the use of Axum and shared Rust services, it maintains strict functional parity across all deployment surfaces.