This document describes the architecture of the OpenVCS client application in Client/.
See umbrella context in ../ARCHITECTURE.md.
Client/ is the running desktop application:
Frontend/is the TypeScript/Vite UI.Backend/is the Tauri/Rust host runtime.- The backend exposes command handlers to frontend and delegates VCS work to plugin-provided backends.
Primary flow:
- UI calls Tauri commands.
- Backend command handlers resolve current repo/backend.
- Backend uses plugin runtime proxies for VCS operations.
- Backend emits UI events/log updates.
Frontend:
Frontend/src/scripts/main.ts: UI bootstrap and feature wiring.Frontend/src/scripts/lib/tauri.ts: minimal bridge wrapper forinvoke/listen.Frontend/src/scripts/features/: feature modules grouped by domain.Frontend/src/styles/: tokens, layout, modal, and component styles.
Backend:
Backend/src/lib.rs: app startup, plugin sync, command registration.Backend/src/tauri_commands/: backend command surface grouped by feature area.Backend/src/state.rs: app config, repo state, recents, output log.Backend/src/repo.rs: repository handle wrapper aroundArc<dyn Vcs>.Backend/src/plugin_vcs_backends.rs: backend discovery and open logic.Backend/src/plugin_bundles.rs: installed-plugin indexing, source metadata, and runtime resolution.Backend/src/plugin_runtime/node_instance.rs: plugin process lifecycle and JSON-RPC calls.Backend/src/plugin_runtime/vcs_proxy.rs:Vcstrait proxy over plugin RPC.Backend/src/plugins.rs: plugin discovery/manifest summarization for UI.
- Frontend/backend boundary: Frontend never directly runs VCS operations; it calls backend commands.
- Command boundary:
Feature-facing backend API lives under
Backend/src/tauri_commands/. - Backend/plugin boundary: Backend communicates with plugin processes over JSON-RPC over stdio.
- Repo-open UI labels can be resolved from the active backend via backend-provided action-label maps; generic VCS text remains the fallback.
- Settings boundary: Backend persists/loads app configuration and mediates environment application.
- Active repo backend is treated as dynamic availability; stale handles are rejected when backend disappears.
- Plugin modules require approval before execution.
- Output/log/progress signaling is centralized through backend event emission.
- State lifecycle: Startup config load, optional reopen-last-repo, runtime config updates.
- Monitoring:
Optional Sentry reporting is initialized separately in
Backend/src/monitoring.rsandFrontend/src/scripts/lib/monitoring.ts, with backend/frontend events gated bygeneral.crash_reports. The frontend captures errors and relays them to a backend-owned Sentry client over Tauri IPC, while backend Sentry uses runtime process env values with a build-time embedded fallback for packaged builds. Recent frontend console output is retained as breadcrumbs and attached to frontend monitoring events. Backend Rustlogrecords are bridged into Sentry without replacing the existing console/file logger:error!records produce Sentry events,warn!records become breadcrumbs/logs, andinfo!records become breadcrumbs when crash reporting is enabled. - Plugin lifecycle: Built-in/user plugin discovery, config-driven sync, install/uninstall, and approval gating.
- Reliability: RPC timeout handling, respawn backoff, and auto-disable after repeated crashes.
- UX: Theme management, modal/system prompts, command palette, keyboard flows.
- Add a new backend command:
Add handler in
Backend/src/tauri_commands/and wire inBackend/src/lib.rs. - Add UI feature:
Add module under
Frontend/src/scripts/features/and wire frommain.ts. - Add plugin RPC method usage:
Update backend plugin command path in
Backend/src/tauri_commands/plugins.rs.