Files
Lumotia/docs/architecture-map/01-frontend/pages/dictation.md
Jake 26c7307607
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
agent: lumotia-rebrand — docs, scripts, root config, residuals
Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.

transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
  -> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
  as immutable audit trail). Includes architecture-map references
  to magnotia_core::*, magnotia_storage::*, etc. now pointing at
  lumotia_*; dev-setup.md tracing output examples (lumotia_startup
  target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
  audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
  hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
  crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
  crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
  doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
  ("lumotia_task_sync"); magnotia_locale i18n localStorage key
  renamed + migration shim added; CSS keyframe names
  magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
  system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
  keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
  wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
  to "lumotia era" earlier — restored).

Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
  legacy detection strings in legacy_and_target_paths() so the
  migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
  — migration call sites reference the legacy magnotia keys
  deliberately.
- docs/handovers/ — historical audit trail.

cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:38:03 +01:00

5.8 KiB

name, type, slice, last_verified
name type slice last_verified
Dictation page architecture-map-page 01-frontend 2026/05/09

Dictation page

Where you are: Architecture mapFrontendPages overview → Dictation

Plain English summary. This is the recording surface. Press the hotkey or the mic button, watch live partial text stream into a textarea, then on stop run the AI cleanup, extract tasks, copy to clipboard or paste into the focused application. The page handles model loading, the live transcription session, the preview overlay, optional template insertion, and task extraction.

At a glance

  • Path: src/lib/pages/DictationPage.svelte
  • LOC: 1 100
  • Imports (selected):
    • Tauri: Channel, invoke from @tauri-apps/api/core. emit from @tauri-apps/api/event. getCurrentWindow from @tauri-apps/api/window.
    • Stores: page, settings, templates, profiles, addToHistory, addTask, tasks from page.svelte.ts. markGenerating, markGenerationDone from llmStatus.svelte.ts. profilesStore from profiles.svelte.ts. toasts. getPreferences from preferences.svelte.ts.
    • Components: Card, ModelDownloader, EmptyState, SpeakerButton.
    • Utils: exportTranscript, extractTasks, pad, FEEDBACK_TIMEOUT_MS, bionicReading action, measurePreWrap, transcriptPretextFont, transcriptPretextLineHeight, playStartCue, playStopCue, playCompleteCue.
    • External: lucide-svelte icons (Mic, Loader2, SquareCheck, AlertTriangle).
  • Used by: src/routes/+page.svelte:20 when page.current === "dictation". Also forced by global hotkey and first run path.

What's in here

Local state (selected)

  • transcript (string), segments (array of {start, end, text}).
  • recording is on the global page store; this page mirrors it.
  • timerInterval, startTime, timerText (mm:ss).
  • Model lifecycle flags: modelReady, modelLoading, needsDownload.
  • AI flags: aiProcessing, aiStatus, extractedCount.
  • Live session: sessionId, drainingSessionId, lastResultAt, lastLiveActivityAt, liveWarning.
  • Tauri channels (typed): resultChannel, statusChannel opened by new Channel(...).
  • UI: showExportMenu, saved, insertPos (cursor-based insertion), activeTemplate.
  • runtimeCapabilities (from get_runtime_capabilities, used to decide engine availability and CUDA presence).

Lifecycle

  • onMount. Loads runtimeCapabilities (DictationPage.svelte:134). Sets up the global hotkey custom event listener (lumotia:toggle-recording, dispatched from the +layout.svelte hotkey path).
  • onDestroy. Tears down listeners and timers.

Recording flow (high level)

  1. Toggle from the mic button or the lumotia:toggle-recording window event.
  2. If model not ready, ensure model: check check_engine, check_parakeet_engine, check_llm_model, then load via load_model / load_parakeet_model / load_llm_model as required (DictationPage.svelte:241-272).
  3. Open two Channel<message> instances (DictationPage.svelte:341-342) and call start_live_transcription_session with the channel handles.
  4. As the backend pushes status and partial result messages, append text to transcript, update segments, and broadcast preview-append to the preview overlay window (DictationPage.svelte:165, 381, 385). If the preview is enabled and not already open, open_preview_window is invoked.
  5. On stop, call stop_live_transcription_session, then run AI cleanup (cleanup_transcript_text_cmd) gated on get_llm_status (DictationPage.svelte:464-472).
  6. Optionally extract tasks via extract_tasks_from_transcript_cmd (DictationPage.svelte:487-491) and add them via the addTask store helper.
  7. Push to history with addToHistory (which calls add_transcript).
  8. Auto copy and/or auto paste based on settings.autoCopy / settings.autoPaste. Paste path uses paste_text (DictationPage.svelte:544-554); fallback to copy_to_clipboard.
  9. Emit preview-cleanup, preview-final, preview-hide to drive the overlay state machine (DictationPage.svelte:531, 539, 606).

Tauri command surface

get_runtime_capabilities, check_llm_model, load_llm_model, load_parakeet_model, load_model, start_live_transcription_session, stop_live_transcription_session, open_preview_window, get_llm_status, cleanup_transcript_text_cmd, extract_tasks_from_transcript_cmd, paste_text, copy_to_clipboard.

Plus emit("preview-append" | "preview-listening" | "preview-cleanup" | "preview-final" | "preview-hide").

Watch outs

  • The page uses // @ts-nocheck. Adding type safety here would catch a class of regressions, especially around the Channel<T> payload shape.
  • The cursor based insertion (insertPos) is fragile. Editing the textarea while a live session is running can corrupt the segment offset map. Tests around extractTasks only cover the post stop path.
  • Multiple paths can flip recording (button, hotkey custom event, error early-out). Treat the page as a state machine with a single source of truth and you will save yourself.
  • extractedCount is purely cosmetic. It is reset on recording start.
  • The "live activity" stalled detector is timer based (lastLiveActivityAt). On a stalled session the user sees liveWarning. The recovery path is "stop and start again".

See also