Files
Lumotia/docs/architecture-map/05-core-storage-hotkey-build/frontend-build-config.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.1 KiB

name, type, slice, last_verified
name type slice last_verified
Frontend build config architecture-map-page 05-core-storage-hotkey-build 2026/05/09

Frontend build config

Where you are: Architecture mapCore, Storage, Hotkey, Build → Frontend build config

Plain English summary. Three small config files that pin how Vite, SvelteKit, and TypeScript-flavoured-jsconfig behave. The settings are deliberately minimal — the heavy lifting (routes, components, stores) lives in slice 1.

At a glance

  • Files: vite.config.js (612 bytes), svelte.config.js (214 bytes), jsconfig.json (366 bytes).
  • External: Vite, SvelteKit, Tailwind v4 plugin.
  • Consumers: every dev / build invocation.

vite.config.js

import { defineConfig } from "vite";
import { sveltekit } from "@sveltejs/kit/vite";
import tailwindcss from "@tailwindcss/vite";

const host = process.env.TAURI_DEV_HOST;

export default defineConfig(async () => ({
  plugins: [sveltekit(), tailwindcss()],
  clearScreen: false,
  server: {
    port: 1420,
    strictPort: true,
    host: host || false,
    hmr: host
      ? { protocol: "ws", host, port: 1421 }
      : undefined,
    watch: {
      ignored: ["**/src-tauri/**"],
    },
  },
}));

Notable settings

  • port: 1420 + strictPort: true. Tauri's beforeDevCommand and the run.sh poll both target port 1420. strictPort means Vite errors out instead of falling back to 1421+, so a stuck process is loud.
  • clearScreen: false. Vite's default behaviour clears the terminal. Disabled here so the Tauri logs stay visible alongside Vite's.
  • TAURI_DEV_HOST env var. When set, Vite binds to the network interface and runs HMR on port 1421. Used for testing on a real device while developing on the desktop. Unset on local dev.
  • watch: { ignored: ["**/src-tauri/**"] }. Vite's file watcher ignores the Tauri directory; otherwise every Cargo build artefact change would trigger an HMR pass.

Why Tailwind v4's Vite plugin

Tailwind 4 ships a @tailwindcss/vite plugin that replaces the v3 PostCSS pipeline. The plugin reads CSS-in-JS / @import "tailwindcss" directly from the source files. The repo has no tailwind.config.js or postcss.config.cjs because v4 derives configuration from the CSS itself.

svelte.config.js

import adapter from "@sveltejs/adapter-static";

const config = {
  kit: {
    adapter: adapter({
      fallback: "index.html",
    }),
  },
};
export default config;

Notable settings

  • adapter-static — Magnotia is a Tauri app, not a server-rendered web app. Static adapter outputs a fully pre-rendered HTML/JS bundle that Tauri serves from its embedded webview.
  • fallback: "index.html" — every unknown route serves index.html, which lets the SvelteKit client router take over. Without this, /history typed directly into the URL bar would 404.

jsconfig.json

{
  "extends": "./.svelte-kit/tsconfig.json",
  "compilerOptions": {
    "allowJs": true,
    "checkJs": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "resolveJsonModule": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "strict": true,
    "moduleResolution": "bundler"
  }
}

Notable settings

  • extends ".svelte-kit/tsconfig.json" — SvelteKit generates a tsconfig at npm run dev:frontend's svelte-kit sync step. We extend it to add our own strictness flags.
  • allowJs: true + checkJs: true — the codebase is JavaScript with TypeScript-aware type checking via JSDoc. svelte-check enforces this.
  • strict: true — full strict mode. Null safety, no implicit any, etc. svelte-check is the gate (CI runs npm run check).
  • moduleResolution: "bundler" — TypeScript 5's bundler-aware resolution. Matches Vite's behaviour (no fake CommonJS round-trip).

static/

The static folder maps 1:1 to the served root. Listed here for completeness:

  • favicon.png — app icon (web).
  • pcm-processor.js — the audio worklet (cross-link: static-assets.md).
  • svelte.svg, tauri.svg, vite.svg — placeholder logos.
  • fonts/atkinson-hyperlegible-next.woff2, instrument-serif-italic.woff2, jetbrains-mono.woff2, lexend-variable.woff2, opendyslexic.woff2.
  • textures/grain.png.

Watch-outs

  • vite.config.js is async-returning a config but does no awaiting. Worth the simplification to a synchronous defineConfig({ ... }) if no async setup is added.
  • svelte.config.js does not use vitePreprocess. SvelteKit 2 + Svelte 5 do not require it (Svelte 5's compiler reads JSDoc directly). Keeps the config minimal.
  • jsconfig.json extends a generated file. Running svelte-kit sync is part of npm run check and npm run dev:frontend. CI runs it explicitly.
  • No vitest config. Frontend unit tests are not part of the current workflow. Coverage is via svelte-check (types), e2e dogfooding, and Rust integration tests at the slice-2 boundary.

See also