Files
Lumotia/docs/architecture-map/01-frontend/pages/dictation.md
jars a1f3f3f134 docs: architecture map (initial 5-slice generation, 105 pages)
Five-slice navigable map of the entire codebase under
docs/architecture-map/. Each slice is a self-contained
breadcrumbed sub-tree:

  01-frontend (16)              Svelte/SvelteKit UI
  02-tauri-runtime (26)         src-tauri commands + lifecycle
  03-audio-transcription (16)   audio + transcription crates
  04-llm-formatting-mcp (19)    llm, ai-formatting, mcp, cloud
  05-core-storage-hotkey-build  core, storage, hotkey, workspace,
                          (26) CI, dev glue

Plus master README.md and data-flow-end-to-end.md tracing
audio bytes from microphone to FTS5 search to MCP read.

Generated by 5 parallel subagents on 2026/05/09 against
HEAD 3c47000. Each page has YAML frontmatter, file:line code
refs, sibling cross-links, plain-English summaries.

Aggregated debt surfaced (full lists in master README):
RB-08 macOS power assertion, schema head drift v14 vs v15,
VAD blocked on ort version conflict, streaming primitives
not wired into live.rs, no prompt versioning, MCP has no
auth, cloud-providers in-memory keystore, SettingsPage
2 484 LOC, commands/live.rs 1 737 LOC, dual theme system,
brand rename to Lumenote pending across the codebase.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 14:04:13 +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 (magnotia: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 magnotia: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