Desktop Client
The Diminuendo desktop client (@igentai/dim-desktop) is a native desktop application built with Tauri v2 and React. It provides the same user interface as the web client but runs as a native window with the WebSocket connection managed by a Rust backend process. This architecture delivers lower latency, native window management, system tray integration, and direct local filesystem access for Chronicle workspace synchronization.
Tech Stack
| Technology | Version | Purpose |
|---|---|---|
| Tauri | v2 (@tauri-apps/cli ^2.2) | Native desktop shell |
| @tauri-apps/api | ^2.2 | Frontend IPC bindings |
| React | 19 | UI framework |
| TypeScript | 5.x | Type safety |
| Tailwind CSS | v4 | Styling |
| Effect | ^3.12 | Gateway adapter typed effects |
| Zustand | 5 | State management |
| Diminuendo Rust SDK | local | WebSocket client in the Rust backend |
Architecture
Unlike the web client, the desktop client does not hold a WebSocket connection from the renderer process. Instead, the Tauri Rust backend owns the connection:tokio task that reads from the Rust SDK’s mpsc::UnboundedReceiver<ServerEvent> and emits each event to the frontend via Tauri’s event system. The frontend’s TauriGatewayAdapter listens for these events and forwards them into the shared Zustand stores.
Data Flow
Command Path (Frontend to Gateway)
1
User Action
The user submits a message through the chat input.
2
Adapter Dispatch
useChat() calls adapter.runTurn() on the TauriGatewayAdapter, which calls invoke("run_turn", { sessionId, text }).3
Tauri IPC
Tauri’s IPC bridge serializes the arguments and delivers them to the Rust process.
4
Rust Command
The
#[tauri::command] run_turn handler retrieves the DiminuendoClient from Tauri’s managed state and calls client.run_turn().5
WebSocket
The Rust SDK serializes the message as JSON and sends it over the WebSocket to the gateway.
Event Path (Gateway to Frontend)
1
Gateway Event
The gateway publishes an event to the session topic.
2
WebSocket
The Rust SDK’s background
tokio task receives the event from the WebSocket and sends it through the mpsc channel.3
Event Emission
The event receiver task calls
app_handle.emit("gateway-event", &event), which serializes the event and sends it to the frontend webview.4
Adapter Stream
The
TauriGatewayAdapter’s listen("gateway-event") callback receives the event and pushes it into the Effect Stream.Stream.5
Store Update
The
useGatewayConnection hook routes the event to the appropriate Zustand store. React components re-render with the updated state.Advantages over the Web Client
Lower Latency
The Rust backend holds the WebSocket connection natively via
tokio-tungstenite. There is no browser WebSocket implementation overhead, no JavaScript event loop contention for I/O processing, and no garbage collection pauses during high-throughput event streams.Native Window Management
Full control over window chrome, title bar, resizing behavior, and multi-window support via Tauri’s window management API. The application can implement custom title bars, frameless windows, and platform-specific window behaviors.
System Tray
Background presence via system tray icon with notification badges. The application can run minimized to the tray and surface notifications when agent turns complete or questions are requested.
Local File Access
Direct filesystem access for Chronicle local-sync integration. The desktop client can synchronize agent workspace files to local directories, enabling users to open and edit files in their preferred IDE.
Chronicle Local-Sync Integration
The desktop client integrates with Chronicle’s local-sync mode, which replaces FUSE/NFS with real APFS files synchronized via FSEvents. Tauri IPC commands provide the interface:| Command | Description |
|---|---|
start_sync | Begin synchronizing a session’s workspace to a local directory |
stop_sync | Stop synchronization for a session |
sync_status | Query the current sync state (active, paused, error) |
resolve_conflict | Resolve a file conflict when both local and remote changes exist |
Chronicle local-sync uses the
notify crate (v7) with RecommendedWatcher for FSEvents on macOS. File changes are debounced and echo-suppressed to prevent infinite sync loops when the materializer writes files that the watcher would otherwise detect as local changes.Development
Start the desktop client in development mode:local-sync feature enabled by default.
Build
- macOS:
.dmgand.appbundle - Windows:
.msiinstaller and.exe - Linux:
.deb,.rpm, and.AppImage
Prerequisites
- Rust toolchain (stable)
- Tauri CLI:
cargo install tauri-cli - Platform-specific dependencies (see Tauri prerequisites)
- A running Diminuendo gateway instance for development