The plugin system is Hyprnote's modular architecture for extending Tauri's core functionality. Each plugin encapsulates a distinct domain (window management, audio processing, speech-to-text, etc.) and follows a consistent architectural pattern to expose functionality to the frontend via type-safe commands and events.
This document covers the plugin architecture pattern, plugin lifecycle, type-safety mechanisms, and the actor-based concurrency model used by some plugins. For the overall desktop application architecture, see Desktop Application Architecture. For specific audio processing implementation details, see Audio Capture Layer and Listener Plugin.
All plugins in Hyprnote follow a standardized structure that ensures consistency and type safety across the codebase.
Sources: plugins/windows/src/lib.rs42-83 plugins/local-stt/src/lib.rs32-97 plugins/listener/src/lib.rs33-67
Each plugin consists of:
| Component | Purpose | Example Files |
|---|---|---|
| Extension Trait | Extends tauri::Manager with plugin-specific methods | WindowsPluginExt, LocalSttPluginExt, ListenerPluginExt |
| Commands Module | Tauri commands exposed to frontend | plugins/*/src/commands.rs |
| Events Module | Event definitions for frontend emission | plugins/*/src/events.rs |
| Managed State | Plugin-specific state stored in Tauri's state container | ManagedState, SharedState |
| Error Types | Plugin-specific error enum implementing Serialize | plugins/*/src/error.rs |
| Init Function | Plugin initialization and registration | init() function returning TauriPlugin<R> |
Sources: plugins/windows/src/ext.rs113-236 plugins/local-stt/src/ext.rs17-48 plugins/listener/src/ext.rs35-52
Each plugin defines an extension trait that adds methods to any type implementing tauri::Manager<R>:
This pattern allows plugin functionality to be called directly on AppHandle or Window instances anywhere in the codebase, providing ergonomic access without tight coupling.
Sources: plugins/local-stt/src/ext.rs17-48 plugins/windows/src/ext.rs113-236 plugins/listener/src/ext.rs35-52
Sources: plugins/windows/src/commands.rs plugins/local-stt/src/commands.rs plugins/listener/src/commands.rs
The Windows plugin manages application windows and navigation.
Key Commands:
window_show: Creates or shows a windowwindow_destroy: Destroys a window instancewindow_navigate: Navigates window to a pathwindow_emit_navigate: Emits navigation eventwindow_is_exists: Checks if window existsManaged State: The plugin tracks window state including visibility and session IDs for analytics.
Sources: plugins/windows/src/lib.rs23-40 plugins/windows/src/commands.rs1-108 plugins/windows/src/ext.rs1-236
Events Emitted:
Navigate: Window navigation eventsWindowDestroyed: Cleanup notification when windows closeMainWindowState: Sidebar/panel expansion stateSources: plugins/windows/src/events.rs65-109
The Local STT plugin manages speech-to-text model lifecycle and server processes.
Architecture:
Sources: plugins/local-stt/src/ext.rs100-153 plugins/local-stt/src/server/supervisor.rs
Key Commands:
start_server(model): Starts STT server (internal or external)stop_server(server_type): Stops running STT serverdownload_model(model, channel): Downloads model with progress trackingget_servers(): Returns status of all STT serversis_model_downloaded(model): Checks model availabilitySources: plugins/local-stt/src/commands.rs1-94
Server Types:
| Server Type | Models | Implementation |
|---|---|---|
| Internal | Whisper variants (QuantizedTiny, QuantizedBase, etc.) | InternalSTTActor - Axum HTTP server in-process plugins/local-stt/src/server/internal.rs32-136 |
| External | AM models (Parakeet v2/v3, Whisper Large v3) | ExternalSTTActor - Sidecar process via tauri_plugin_shell plugins/local-stt/src/server/external.rs69-260 |
State Management:
The download_task map tracks active model downloads with cancellation support, while stt_supervisor provides access to the actor supervision tree.
Sources: plugins/local-stt/src/lib.rs23-28
The Listener plugin orchestrates audio capture, real-time transcription, and recording sessions.
Architecture:
Sources: plugins/listener/src/ext.rs119-155 plugins/listener/src/actors/controller.rs
Key Commands:
start_session(params): Spawns ControllerActor with session parametersstop_session(): Gracefully stops active sessionrun_batch(params): Processes audio file for batch transcriptionget_mic_muted() / set_mic_muted(muted): Microphone mute controlset_microphone_device(device_name): Changes audio input deviceSources: plugins/listener/src/commands.rs1-83
Session Events:
The plugin emits SessionEvent variants to communicate session state and transcription results:
Sources: plugins/listener/src/events.rs12-51
Sources: plugins/windows/src/lib.rs62-83 plugins/local-stt/src/lib.rs51-97
Each plugin implements a setup closure that executes during application initialization:
Example: Local STT Plugin Initialization
The Local STT plugin spawns a supervisor actor during setup:
plugins/local-stt/src/lib.rs80-92
Sources: plugins/local-stt/src/lib.rs51-97
All plugins use tauri-specta to generate type-safe TypeScript bindings from Rust types. This ensures compile-time type safety across the IPC boundary.
Sources: plugins/windows/src/lib.rs42-60 plugins/local-stt/src/lib.rs32-49
Each plugin's js/bindings.gen.ts exports:
Commands object:
Events object:
Type definitions:
All Rust types marked with #[derive(specta::Type)] are exported as TypeScript types.
Sources: plugins/local-stt/js/bindings.gen.ts9-80 plugins/listener/js/bindings.gen.ts87-116
Commands are defined with both Tauri and specta attributes:
Key aspects:
#[tauri::command]: Registers with Tauri's IPC system#[specta::specta]: Generates TypeScript type informationString for serialization across IPCSources: plugins/local-stt/src/commands.rs62-68 plugins/listener/src/commands.rs50-58
Events use the tauri_specta::Event derive macro:
Events are emitted using the generated trait methods:
Sources: plugins/listener/src/events.rs12-51 plugins/windows/src/events.rs65-101
Plugins that manage complex concurrent operations use the ractor actor framework for fault-tolerant supervision trees.
Sources: plugins/local-stt/src/server/supervisor.rs19-32 plugins/local-stt/src/server/internal.rs32-136 plugins/local-stt/src/server/external.rs69-260
The STT supervisor uses DynamicSupervisor with strict resource limits:
Sources: plugins/local-stt/src/server/supervisor.rs19-32
Starting a Server:
plugins/local-stt/src/ext.rs100-153
ChildSpec with spawn function and restart policyDynamicSupervisor::spawn_child()Stopping a Server:
plugins/local-stt/src/server/supervisor.rs94-120
DynamicSupervisor::terminate_child()| Aspect | InternalSTTActor | ExternalSTTActor |
|---|---|---|
| Process | In-process Axum server | Spawned sidecar via shell |
| Models | Whisper variants | AM models |
| Port | Random ephemeral port | Provided by args or random |
| Lifecycle | Graceful shutdown via watch channel | Process kill on cleanup |
| Health | Immediate (in-memory) | Retry with backoff (HTTP) |
Sources: plugins/local-stt/src/server/internal.rs40-100 plugins/local-stt/src/server/external.rs106-219
Each actor defines a message enum for inter-actor communication:
Messages are sent using ractor primitives:
call_t!(): Synchronous RPC with timeoutsend_message(): Async message sendcast(): Fire-and-forget messageSources: plugins/local-stt/src/server/internal.rs14-17 plugins/local-stt/src/server/external.rs10-13
Each plugin defines granular permissions that control frontend access to commands.
Permissions are defined in TOML and auto-generated into JSON schemas:
plugins/windows/permissions/default.toml1-12
Permissions are registered during the plugin build process:
This generates permission schemas in permissions/schemas/schema.json and documentation in permissions/autogenerated/reference.md.
Sources: plugins/windows/build.rs plugins/local-stt/build.rs plugins/listener/build.rs
All permissions follow the pattern: <plugin-name>:<allow|deny>-<command-name>
Examples:
windows:allow-window-showlocal-stt:allow-start-serverlistener:allow-start-sessionSources: plugins/windows/permissions/autogenerated/reference.md plugins/local-stt/permissions/autogenerated/reference.md plugins/listener/permissions/autogenerated/reference.md
| Plugin | Primary Responsibility | Key Technologies | Actor-Based |
|---|---|---|---|
| Windows | Window lifecycle and navigation | Tauri window APIs, analytics integration | No |
| Local STT | STT model and server management | ractor, Axum, whisper.cpp, sidecar processes | Yes |
| Listener | Audio session orchestration | ractor, hypr-audio, owhisper-client | Yes |
| Database | Data persistence and sync | libsql, Turso | No |
| Local LLM | LLM server management | llama.cpp, OpenAI-compatible API | Yes |
| Auth | Authentication and user management | Nango integration | No |
| Analytics | Event tracking | External analytics service | No |
Sources: Referenced throughout document; diagram structure based on Diagram 4 from overview
Refresh this wiki
This wiki was recently refreshed. Please wait 7 days to refresh again.