Web Client

The Diminuendo web client (@igentai/dim-web) is a single-page application built with Vite and React that connects directly to the gateway over WebSocket. It provides a real-time interface for interacting with AI coding agents, viewing streaming responses, inspecting tool calls, and managing sessions.

Tech Stack

TechnologyVersionPurpose
Vite6Build tool and dev server
React19UI framework
TypeScript5.xType safety
Tailwind CSSv4Utility-first styling
Effect^3.12Gateway adapter typed effects
Zustand5State management
react-markdown10Markdown rendering for assistant messages
remark-gfm4GitHub-flavored markdown (tables, task lists, strikethrough)
shiki3Syntax highlighting for code blocks
lucide-react0.470Icon set

Architecture

The web client uses the WebGatewayAdapter, which wraps the TypeScript SDK’s DiminuendoClient to connect directly to the gateway over WebSocket. There is no intermediate backend — the browser establishes a WebSocket connection to the gateway and communicates using the wire protocol directly.
Browser
  ├── React Components (from @igentai/dim-shared)
  ├── Zustand Stores (from @igentai/dim-shared)
  ├── WebGatewayAdapter
  │     └── DiminuendoClient (TypeScript SDK)
  │           └── WebSocket → Gateway
  └── Vite dev server (development only)

Data Flow

The complete path of a user interaction through the web client:
1

User Action

The user types a message in the chat input and presses Enter.
2

Hook Dispatch

The useChat() hook calls chatStore.runTurn(sessionId, text), which invokes adapter.runTurn() on the WebGatewayAdapter.
3

SDK Transmission

The adapter delegates to DiminuendoClient.runTurn(), which serializes the message as JSON and sends it over the WebSocket.
4

Gateway Processing

The gateway receives the message, validates it, routes it through the MessageRouter, and forwards it to Podium (the agent orchestration platform).
5

Agent Execution

Podium dispatches the message to the coding agent, which begins processing. The agent streams events back through Podium to the gateway.
6

Event Streaming

The gateway maps Podium events to the wire protocol and publishes them to the session topic. The client’s WebSocket receives each event as it arrives.
7

Store Update

The DiminuendoClient’s event handlers fire. The WebGatewayAdapter forwards each event through the events stream. The useGatewayConnection hook routes each event to the appropriate Zustand store — text_delta events go to the chat store, session_state events go to the session store, and so on.
8

React Re-render

Zustand’s selector-based subscriptions trigger re-renders only in the affected components. The assistant message component re-renders to show the new text delta, the tool call component appears when a tool_call event arrives, and the status indicator updates on session_state changes.

Key Components

All UI components are defined in the @igentai/dim-shared package and consumed by the web client without modification:

Chat Container

The top-level chat layout that composes the message list, input area, and session controls. Manages scroll behavior via useAutoScroll() to ensure new content is visible during streaming responses while preserving the user’s scroll position when they scroll up to review history.

Message List

Renders the conversation as a sequence of user and assistant messages. Each assistant message can contain:
  • Text blocks — rendered as Markdown using react-markdown with remark-gfm for tables, task lists, and strikethrough
  • Code blocks — syntax-highlighted using shiki with language detection
  • Tool call blocks — show the tool name, arguments (collapsible JSON), and result
  • Thinking blocks — collapsible sections showing the agent’s reasoning process
  • Terminal output — monospaced blocks for command execution output

Session Sidebar

Lists all sessions for the authenticated tenant. Supports creating new sessions, renaming, archiving/unarchiving, and deleting. Sessions are grouped by status (active, archived) and sorted by last activity.

Development

Start the web client development server:
cd clients
npm install
npm run dev:web
This starts Vite’s dev server on http://localhost:5173 with hot module replacement. The dev server proxies WebSocket connections to the gateway (default: ws://localhost:8080/ws).
The web client expects a running Diminuendo gateway instance. Start the gateway with DEV_MODE=true to bypass authentication and enable auto-authentication with a dev identity.

Build

cd clients
npm run build:web
Produces a static site in clients/web/dist/ suitable for deployment to any static hosting service (Vercel, Netlify, S3 + CloudFront, etc.).
In production, the web client must connect to a gateway that enforces authentication. The ALLOWED_ORIGINS environment variable on the gateway must include the web client’s origin to pass CSRF checks.