--- name: Frontend ↔ Tauri bridge type: architecture-map-page slice: 01-frontend last_verified: 2026/05/09 --- # Frontend ↔ Tauri bridge > **Where you are:** [Architecture map](../README.md) → [Frontend](README.md) → Frontend ↔ Tauri bridge **Plain English summary.** The complete surface where the Svelte frontend talks to the Rust runtime. Two channels: synchronous request/response via `invoke()`, and asynchronous events via `listen()` / `emit()`. Every command name and every event name the frontend touches is listed here so slice 02 can verify reciprocal mentions. ## At a glance - **Direction in (Rust → frontend):** events listed under "Tauri events listened to". - **Direction out (frontend → Rust):** all `invoke()` commands listed under "Tauri commands invoked". - **DOM-only events:** `lumotia:*` `CustomEvent`s on `window`. These never cross the Rust boundary. - **Cross-window event:** `lumotia:preferences-changed` is the only one that goes through `emit()`. ## Tauri commands invoked (alphabetical) Discovered via `grep -rho 'invoke([\"\\']\\([a-zA-Z_][a-zA-Z0-9_]*\\)' src/`. Each name appears at least once in the frontend. | Command | Caller(s) | |---|---| | `add_transcript` | `stores/page.svelte.ts:234` (`addToHistory`) | | `check_engine` | `pages/SettingsPage.svelte:826` | | `check_for_update` | `routes/+layout.svelte:356` | | `check_hotkey_access` | `routes/+layout.svelte:86` | | `check_llm_model` | `pages/DictationPage.svelte:241`, `pages/SettingsPage.svelte:597` | | `check_parakeet_engine` | `pages/SettingsPage.svelte:857` | | `check_parakeet_model` | `pages/SettingsPage.svelte:858` | | `cleanup_transcript_text_cmd` | `pages/DictationPage.svelte:472` | | `complete_task_cmd` | `stores/page.svelte.ts:474` | | `copy_to_clipboard` | DictationPage, FilesPage, HistoryPage, viewer/+page, preview/+page | | `delete_implementation_rule` | `stores/implementationIntentions.svelte.ts:82` | | `delete_llm_model` | `pages/SettingsPage.svelte:660` | | `delete_profile_cmd` | `stores/profiles.svelte.ts:93` | | `delete_profile_term_cmd` | `stores/profiles.svelte.ts:121` | | `delete_task_cmd` | `stores/page.svelte.ts:456` | | `delete_transcript` | `stores/page.svelte.ts:320`, `pages/HistoryPage.svelte:285` | | `deliver_nudge` | `stores/nudgeBus.svelte.ts:112` | | `detect_meeting_processes` | `routes/+layout.svelte:399` | | `detect_paste_backends` | `pages/SettingsPage.svelte:850` | | `download_llm_model` | `pages/SettingsPage.svelte:619` | | `download_model` | `pages/SettingsPage.svelte:929`, `pages/FirstRunPage.svelte:59` | | `download_parakeet_model` | `pages/SettingsPage.svelte:988`, `pages/FirstRunPage.svelte:73` | | `extract_content_tags_cmd` | `pages/HistoryPage.svelte:433, 470` | | `extract_tasks_from_transcript_cmd` | `pages/DictationPage.svelte:491` | | `generate_diagnostic_report` | `pages/SettingsPage.svelte:377` | | `get_llm_status` | DictationPage, SettingsPage, layout (refresh path) | | `get_runtime_capabilities` | `pages/DictationPage.svelte:134`, `pages/SettingsPage.svelte:543` | | `is_wayland_session` | `routes/+layout.svelte:82` | | `list_audio_devices` | `pages/SettingsPage.svelte:187` | | `list_models` | `routes/+layout.svelte:346`, `pages/SettingsPage.svelte:846, 930` | | `list_parakeet_models` | `routes/+layout.svelte:347` | | `load_llm_model` | `pages/DictationPage.svelte:243`, `pages/SettingsPage.svelte:634` | | `load_model` | `pages/DictationPage.svelte:272`, `pages/SettingsPage.svelte:944`, `pages/FirstRunPage.svelte:60` | | `load_parakeet_model` | `pages/DictationPage.svelte:270`, `pages/SettingsPage.svelte:1003`, `pages/FirstRunPage.svelte:74` | | `log_frontend_error` | `routes/+layout.svelte:282` | | `open_preview_window` | `pages/DictationPage.svelte:385` | | `open_task_window` | `pages/TasksPage.svelte:231` | | `open_viewer_window` | `pages/HistoryPage.svelte:392, 556` | | `paste_text` | `pages/DictationPage.svelte:544` | | `paste_text_replacing` | `routes/preview/+page.svelte:92` | | `prewarm_default_model_cmd` | `routes/+layout.svelte:371` | | `probe_system` | `pages/SettingsPage.svelte:822`, `pages/FirstRunPage.svelte:31` | | `rank_models` | `pages/FirstRunPage.svelte:32` | | `recommend_llm_tier` | `pages/SettingsPage.svelte:587` | | `save_diagnostic_report` | `pages/SettingsPage.svelte:405` | | `save_preferences` | `stores/preferences.svelte.ts:109` | | `start_evdev_hotkey` | `routes/+layout.svelte:129` | | `start_live_transcription_session` | `pages/DictationPage.svelte:344` | | `stop_evdev_hotkey` | `routes/+layout.svelte:424` | | `stop_live_transcription_session` | `pages/DictationPage.svelte:415` | | `test_llm_model` | `pages/SettingsPage.svelte:684` | | `transcribe_file` | `pages/FilesPage.svelte:76` | | `tts_list_voices` | `pages/SettingsPage.svelte:750` | | `tts_speak` | `pages/SettingsPage.svelte:769`, `stores/implementationIntentions.svelte.ts:170`, `stores/nudgeBus.svelte.ts:119` | | `tts_stop` | `components/SpeakerButton.svelte` (cancel current TTS) | | `uncomplete_task_cmd` | `stores/page.svelte.ts:491` | | `unload_llm_model` | `pages/SettingsPage.svelte:648` | | `update_evdev_hotkey` | `routes/+layout.svelte:127` | | `update_profile_cmd` | `stores/profiles.svelte.ts:77` | | `update_transcript` | `stores/page.svelte.ts:272`, `routes/viewer/+page.svelte:326` | Plus any commands invoked by `saveMarkdown.ts` via the dialog/file-write plugin imports rather than direct `invoke`. (Verified the truncated `tts_s...` resolves to `tts_speak` and `tts_stop`; both are listed.) ## Tauri events listened to (Rust → frontend) | Event | Listener | |---|---| | `lumotia:hotkey-pressed` | `routes/+layout.svelte:177` (evdev backend) | | `lumotia:llm-download-progress` | `pages/SettingsPage.svelte:873` | | `lumotia:open-wind-down` | `routes/+layout.svelte:251` (tray menu hook) | | `lumotia:preferences-changed` | `routes/+layout.svelte:263`, `routes/float/+layout@.svelte`, `routes/viewer/+layout@.svelte`, `routes/preview/+layout@.svelte:41` | | `model-download-progress` | `pages/SettingsPage.svelte:864`, `pages/FirstRunPage.svelte:46`, `components/ModelDownloader.svelte:31` | | `parakeet-download-progress` | `pages/SettingsPage.svelte:880`, `pages/FirstRunPage.svelte:50` | | `preview-cleanup` | `routes/preview/+page.svelte:141` | | `preview-hide` | `routes/preview/+page.svelte:161` | | `preview-listening` | `routes/preview/+page.svelte:113` | | `task-window-focus` | `routes/float/+layout@.svelte` | | `tauri://drag-drop` | `pages/FilesPage.svelte:28` | | `tauri://drag-enter` | `pages/FilesPage.svelte:34` | | `tauri://drag-leave` | `pages/FilesPage.svelte:35` | ## Tauri events emitted (frontend → Rust or other windows) | Event | Emitter | Purpose | |---|---|---| | `lumotia:preferences-changed` | `stores/preferences.svelte.ts` (`broadcastPreferences`) | Cross-window preference sync. | | `preview-append` | `pages/DictationPage.svelte:165` | Stream partial text to overlay window. | | `preview-listening` | `pages/DictationPage.svelte:381` | Tell overlay to enter listening state. | | `preview-cleanup` | `pages/DictationPage.svelte:531` | Tell overlay to enter cleanup state. | | `preview-final` | `pages/DictationPage.svelte:539` | Tell overlay to render final text. | | `preview-hide` | `pages/DictationPage.svelte:606` | Tell overlay to dismiss. | ## DOM-only `lumotia:*` window events (intra-frontend bus) | Event | Dispatcher | Listener(s) | |---|---|---| | `lumotia:focus-timer-cancelled` | `stores/focusTimer.svelte.ts` | `completionStats` (indirectly), components subscribed to focus timer. | | `lumotia:focus-timer-complete` | `stores/focusTimer.svelte.ts` | Same as above. | | `lumotia:implementation-rules-changed` | `stores/implementationIntentions.svelte.ts` | `ImplementationRulesEditor`. | | `lumotia:microstep-generated` | `stores/nudgeBus.svelte.ts` (around micro step generation) | `MicroSteps.svelte`. | | `lumotia:morning-triage-finished` | `MorningTriageModal.svelte` | `nudgeBus`. | | `lumotia:start-timer` | `WipTaskList.svelte`, `MicroSteps.svelte` | `FocusTimer.svelte` + `focusTimer` store. | | `lumotia:step-completed` | `MicroSteps.svelte` | `completionStats` refresh. | | `lumotia:task-completed` | `stores/page.svelte.ts` (`completeTask`) | `completionStats`. | | `lumotia:task-deleted` | `stores/page.svelte.ts` (`deleteTask`) | `completionStats`. | | `lumotia:task-uncompleted` | `stores/page.svelte.ts` (`uncompleteTask`) | `completionStats`. | | `lumotia:toggle-recording` | `routes/+layout.svelte` (after hotkey debounce, both backends) | `pages/DictationPage.svelte`. | ## Window APIs - `getCurrentWindow().minimize()` and `.toggleMaximize()`. `Titlebar.svelte`. - `getCurrentWindow().label`. Used to guard hotkey registration to the main window only and to filter own-source preference echoes. - `convertFileSrc(absolutePath)`. HistoryPage and viewer use this for `