Files
Lumotia/docs/architecture-map/01-frontend/README.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

8.9 KiB

name, type, slice, last_verified
name type slice last_verified
Frontend slice (Svelte 5 + SvelteKit + Tauri webview) architecture-map-slice-index 01-frontend 2026/05/09

Frontend (Slice 01)

Where you are: Architecture map → Frontend

Plain English summary. This slice is everything the user sees. It is a Svelte 5 single page app, served by SvelteKit in SPA mode, hosted inside Tauri's webview. It owns four windows (main, tasks float, transcript viewer, transcription preview overlay), seven page modules switched by an in memory router store, around thirty reusable components, ten reactive stores, and the design system tokens. The frontend never touches the filesystem, audio, models or the LLM directly. Everything that crosses the WebView boundary goes through invoke() (calling Rust commands) or Tauri events. If you delete this slice, you delete the entire user surface but keep the engine.

At a glance

  • Path: src/
  • Total LOC counted: about 17 200 (583 app.css + 2 740 routes + 6 230 pages + 3 174 components + 4 085 stores/utils/types + ~ 2 360 design system + 130 misc).
  • File counts: 7 pages, 25 components, 10 stores, 1 action, 16 utils, 1 type module, 3 locales, 4 routes (root + float/viewer/preview), 20 design system preview HTMLs, 3 design system JSX kits.
  • Frameworks: Svelte 5 (runes mode), SvelteKit 2.58, @sveltejs/adapter-static with index.html fallback (SPA), Vite 6, Tailwind v4 via @tailwindcss/vite, svelte-i18n 4, lucide-svelte for icons.
  • Tauri SDK touchpoints: @tauri-apps/api (core invoke, event, window) plus plugin-autostart, plugin-dialog, plugin-global-shortcut, plugin-notification, plugin-opener. SSR is disabled (src/routes/+layout.js) so the whole tree is client side only.
  • Persistence used directly by frontend: localStorage for magnotia_settings, magnotia_profiles, magnotia_task_lists, magnotia_templates, magnotia_locale, plus a small handoff key for the viewer window. Preferences additionally persist via Tauri (save_preferences).
  • Build commands: npm run dev (svelte-kit sync && vite dev), npm run build, npm run check (svelte-check using jsconfig.json).

Map of this slice

  • Windows and routes. The four Tauri windows, the SvelteKit routes that back them, the +layout@.svelte break, and how the shell decides between custom chrome and native decorations.
  • Pages overview. Index of the seven pages routed by page.current, and the /float, /viewer, /preview route pages.
  • Pages: dictation. The hero recording surface.
  • Pages: settings. The 2 484 line settings panel.
  • Pages: history. FTS5 backed transcript browser.
  • Pages: tasks. Inbox, today, soon, later board.
  • Pages: files. Drag and drop file transcription.
  • Pages: first run. Hardware probe and model bootstrap.
  • Components. All 25 reusable components grouped by role.
  • Stores. Ten Svelte 5 $state stores, plus what each owns and what events they react to.
  • Actions, utils, types. The single Svelte action, the 16 utility modules, and the app.ts type bible.
  • Internationalisation. svelte-i18n setup, locale persistence, current coverage.
  • Design system. Reference material under src/design-system/ (preview HTML, JSX UI kits). Note: this is reference, not live code.
  • Frontend ↔ Tauri bridge. Every invoke() command name and every event listened for or emitted, with their callers.
  • App shell and styling. app.css, app.html, fonts, Tailwind v4 configuration, accessibility CSS variables.

How this slice connects to others

In (frontend depends on Tauri runtime, slice 02).

  • Sixty plus distinct invoke() commands. Full list with caller in frontend-tauri-bridge.md.
  • Tauri events listened to: model-download-progress, parakeet-download-progress, magnotia:llm-download-progress, magnotia:hotkey-pressed, magnotia:open-wind-down, magnotia:preferences-changed, task-window-focus, preview-listening, preview-cleanup, preview-hide, plus drag drop (tauri://drag-drop, tauri://drag-enter, tauri://drag-leave).
  • Window APIs: getCurrentWindow().minimize() / toggleMaximize() / setPosition() / label.
  • Plugin imports loaded lazily: @tauri-apps/plugin-global-shortcut, @tauri-apps/plugin-dialog.

Out (frontend triggers behaviour back into the runtime).

  • DOM CustomEvent bus on window carries internal traffic (magnotia:start-timer, magnotia:toggle-recording, magnotia:task-completed, etc). The Rust side does not listen to these; they are intra frontend.
  • Tauri emit() is used for magnotia:preferences-changed only, to fan preference updates across windows.
  • Multi window orchestration: pages call open_task_window, open_viewer_window, open_preview_window to ask Rust to spawn secondary webviews.

Other slices that read frontend conventions.

  • Slice 02 (Tauri runtime) emits the events listed above and registers commands the frontend invokes.
  • Slice 03 (audio + transcription) ships partial results via a Channel (Tauri 2 typed channel) opened in DictationPage.
  • Slice 04 (LLM, formatting, MCP) emits magnotia:llm-download-progress and cleanup_transcript_text_cmd results consumed by Dictation.
  • Slice 05 (storage, hotkey, build) supplies add_transcript, delete_transcript, profiles, tasks and the evdev hotkey backend.

Existing in repo docs (do not duplicate)

  • docs/brief/ and docs/whisper-ecosystem/brief.md. Product brief and feature set.
  • docs/icon-mapping.md. Lucide icon migration audit.
  • docs/code-review-2026-04-22.md. Last code review snapshot.
  • docs/handovers/. Ship logs (e.g. Phase 9c is the most recent settings related one).
  • docs/audit/. UX and accessibility audits.
  • docs/superpowers/. Process artefacts.
  • src/design-system/README.md, src/design-system/SKILL.md. Brand and design ground truth.

This slice index is the navigation hub. The map files referenced above carry the detail.

Open questions, debt, drift, dead code

  1. src/lib/Sidebar.svelte lives outside components/. Every other reusable Svelte module is under src/lib/components/. The sidebar is the only sibling of those folders. Cosmetic but it surprises contributors.
  2. Two parallel theme systems. settings.theme (string "Light"/"Dark"/"System") coexists with preferences.theme ("light"/"dark"/"system"). +layout.svelte:61-68 and float/+layout@.svelte both run a "legacy → new" migration $effect every time. The legacy pathway should be retired.
  3. @ts-nocheck is widespread. +layout.svelte, DictationPage.svelte, FilesPage.svelte, FirstRunPage.svelte and the float/viewer/preview layouts all opt out of TypeScript. Type safety stops at the page boundary.
  4. SettingsPage.svelte is 2 484 lines. Phase 9c handover already flagged this. SettingsGroup.svelte exists but the deeper restructure into seven progressive disclosure groups plus search has been deferred.
  5. profiles redirect is a dead route. +page.svelte:13 still rewrites page.current === "profiles" to "settings", suggesting the old profiles page was removed but call sites may persist. Worth grepping and deleting the redirect after a release.
  6. Cross window settings sync uses localStorage storage events. float/+layout@.svelte listens for storage to apply settings, while preferences use the dedicated magnotia:preferences-changed Tauri event. Inconsistent. Settings sync via storage is fragile because it only fires on cross document writes.
  7. shims.d.ts next to the lib root. Single shim file at src/lib/shims.d.ts. Worth verifying it is still needed (Svelte 5 + SvelteKit ship most ambient types now).
  8. design-system/ui_kits/ contains JSX components and an HTML index. They are reference, not live, and should not import from the runtime tree. Confirm the build excludes them.
  9. speaker.svelte.ts is ten lines. A near empty store. Used by SpeakerButton.svelte. Consider folding into a util if it never grows.
  10. CSS variable --font-size-transcript is set on body from +layout.svelte but preferences already sets --font-size-body and --transcript-font-size. Three knobs for transcript text size in different stores. Drift between settings.fontSize and preferences.accessibility.transcriptSize is likely.
  11. i18n coverage is thin. Each locale has 19 lines. svelte-i18n is wired but most strings remain hardcoded. Treat as a stub.
  12. Tailwind v4 has no standalone config file. All theming lives in app.css @theme. There is no tailwind.config.{js,ts}. Mention this so contributors do not waste time looking.
  13. docs/architecture-map/01-frontend/ was empty before this pass. Reciprocal slice indexes (02 to 05) need updating to point here.