Settings

100% local · no telemetry · no cloud
{#if isQuietware}
(activeTab = id)} />
{/if}

Theme

prefs.theme === "light" ? "Light" : "Dark", (v) => updatePreferences({ theme: v === "Light" ? "light" : "dark" }) } />

Font size

Hotkey

{#if !isQuietware || activeTab === 'start-here'}

Microphone

{#if audioDevicesError}

We couldn't list your audio devices. Plug a microphone in or grant Lumotia microphone permission in your OS settings, then try again.

Technical details
{audioDevicesError}
{:else if visibleAudioDevices.length === 0}

No input devices detected. Check that a microphone is connected and PulseAudio/PipeWire is running.

{:else}

Auto mode tries the system default first, then any other real input. Speaker-monitor sources (loopback) are skipped. If dictation is silent, pick the device explicitly here.

{/if}

Language

{#if currentModelIsEnglishOnly()} {:else} {/if} {#if settings.language === "en"} {/if}

{#if currentModelIsEnglishOnly()} The selected model only supports English in this build. {:else} Auto-detect is only meaningful with multilingual models. {/if}

Engine

{settings.engine === "whisper" ? "Whisper with the currently shipped English-only models in this build" : "Parakeet CTC 0.6B. English-only, fast when the model is installed"}

{/if} {#if !isQuietware || activeTab === 'transcription'}

Format Mode

{settings.formatMode === "Raw" ? "Exact Whisper output, no formatting" : settings.formatMode === "Clean" ? "Grouped into paragraphs, punctuation tidied" : "Structured with lists, headings, and sections"}

Post-processing

Words and phrases the AI cleanup pass should preserve exactly. Useful for medication names, place names, jargon, names of people in your support network, anything Whisper tends to mishear. Vocabulary is scoped to a profile, switch profiles to swap whole vocabularies.

Active Profile

{#if showNewVocabProfile}
{ if (e.key === 'Enter') createVocabProfile(); }} class="bg-bg border border-border rounded-lg px-3 py-2 text-[13px] text-text focus:outline-none focus:border-accent" />
{/if}
{#if profilesStore.active}

Profile Name

{ if (e.key === 'Enter') e.target.blur(); }} class="bg-bg-input border border-border rounded-lg px-3 py-2 text-[13px] text-text min-w-[280px] focus:outline-none focus:border-accent focus:shadow-[0_0_0_3px_rgba(214,132,80,0.1)]" />

Initial Prompt

Passed to Whisper before every transcription in this profile. Used as a biasing prompt, keep it short and topic-specific (names, domain terms, tone cues).

{#if initialPromptDirty} Unsaved changes, saves on blur. {:else} Saved. {/if}

Terms

{ if (e.key === 'Enter') addVocabTerm(); }} class="flex-1 bg-bg-input border border-border rounded-lg px-3 py-2 text-[13px] text-text focus:outline-none focus:border-accent focus:shadow-[0_0_0_3px_rgba(214,132,80,0.1)]" /> { if (e.key === 'Enter') addVocabTerm(); }} class="flex-1 bg-bg-input border border-border rounded-lg px-3 py-2 text-[13px] text-text focus:outline-none focus:border-accent focus:shadow-[0_0_0_3px_rgba(214,132,80,0.1)]" />
{#if !showBulkVocab} {:else}
{/if}
{#if vocabularyError}

{vocabularyError}

{#if vocabularyErrorDetail}
Technical details
{vocabularyErrorDetail}
{/if}
{/if} {#if vocabulary.length === 0}

No terms yet. Add one above.

{:else}
    {#each vocabulary as entry (entry.id)}
  • {entry.term}
    {#if entry.note}
    {entry.note}
    {/if}
  • {/each}
{/if} {:else}

Loading profiles…

{/if}
{#each profiles as profile, i}
{profile.name} {profileWordCount(profile.words)} words {#if deleteProfileArmedIndex === i} {:else} {/if}
{#if editingProfile === i}
{/if}
{/each} {#if showNewProfile}
e.key === "Enter" && createProfile()} data-no-transition />
{:else} {/if}
{#each templates as template, i}
{template.name} {template.sections.length} sections
{#if editingTemplate === i}
{/if}
{/each} {#if showNewTemplate}
e.key === "Enter" && createTemplate()} data-no-transition />
{:else} {/if}
{/if} {#if !isQuietware || activeTab === 'models'}
{#if settings.engine === "whisper"}

Whisper Model

{modelDescriptions[settings.modelSize]}

{#if isModelLoaded(settings.modelSize)} Model loaded {:else if isModelDownloaded(settings.modelSize)} Downloaded {:else if downloadingModel === whisperModelId(settings.modelSize)} {downloadProgress}% {#if downloadTotal > 0} · {formatBytes(downloadBytes)} / {formatBytes(downloadTotal)} {/if} {#if downloadProgress > 0 && downloadStartedAt > 0} {@const remaining = etaSecondsFromPercent(downloadProgress, downloadStartedAt)} {#if remaining > 1} · {formatDuration(remaining)} left {/if} {/if} {:else} {/if}
{:else}

Parakeet Model

Parakeet CTC 0.6B (int8). ~613MB, near-instant transcription

{#if parakeetOk} Model loaded {:else if parakeetDownloaded} Downloaded {:else if parakeetDownloading} {parakeetProgress}% downloading... {:else} {/if}
{/if}

AI Model Tier

{#each LLM_MODELS as model} {/each}

{LLM_MODELS.find((model) => model.id === selectedLlmModelId())?.subtitle || "Local model"}

{llmStatus}

{#if llmTestHint}

{llmTestHint}

{/if}
{#if llmDownloadingModel === selectedLlmModelId()} {llmDownloadProgress}% {#if llmDownloadTotal > 0} · {formatBytes(llmDownloadBytes)} / {formatBytes(llmDownloadTotal)} {/if} {#if llmDownloadProgress > 0 && llmDownloadStartedAt > 0} {@const remaining = etaSecondsFromPercent(llmDownloadProgress, llmDownloadStartedAt)} {#if remaining > 1} · {formatDuration(remaining)} left {/if} {/if} {:else if !llmModelDownloaded(selectedLlmModelId())} {:else if !llmModelLoaded(selectedLlmModelId())} {:else} {/if}

Recommended for this machine: {LLM_MODELS.find((model) => model.id === (settings.llmModelId || "qwen3_5_4b"))?.subtitle || "Qwen3.5 4B"} {#if systemInfo} · {Math.round((systemInfo.ram_mb || 0) / 1024)} GB RAM detected {/if}

{/if} {#if !isQuietware || activeTab === 'tasks'}

How the Tasks page surfaces progress. Always additive.

{#if settings.nudgesEnabled}
{/if}
{/if} {#if !isQuietware || activeTab === 'accessibility'}
{#if isQuietware} {/if}
{/if} {#if !isQuietware || activeTab === 'privacy'}
All data stays on your machine. No telemetry, no cloud, no accounts.

AI use

The local LLM is used for transcript cleanup and task extraction only — both run fully offline after download. No voice, transcript, or task data is sent to any server. See privacy-and-ai-use.md for details.

Activation log

This log lives on your device only. We never send it anywhere. It records anonymous milestones (first capture, first export, first task extracted) so you can see your own usage shape.

{#if loadingEvents}

Loading…

{:else if eventsError}

Couldn't load activation log.

{:else if activationEvents.length === 0}

No activation events recorded yet.

{:else}
{#each activationEvents as ev} {/each}
Kind When
{ev.kind} {formatTimestamp(ev.occurred_at)}
{/if}

Data location

All transcripts, models, and settings are stored in your OS app-data directory. No files are written outside that path.

{/if} {#if !isQuietware || activeTab === 'advanced'}

Feature Tier

{settings.aiTier === "off" ? "No local LLM calls. Lumotia falls back to the existing rule-based path." : settings.aiTier === "cleanup" ? "Use the local model for transcript cleanup and formatting." : "Use the local model for cleanup, task extraction, and task breakdown."}

Cleanup preset

{#if settings.llmPromptPreset === "email"} Formats output as an email paragraph, tight sentences, no markdown, no auto-added greeting or signoff. {:else if settings.llmPromptPreset === "notes"} Formats action items as a bullet list led by imperative verbs; keeps prose informational sentences as prose. {:else if settings.llmPromptPreset === "code"} Preserves technical terms, variable names, file paths, and symbols exactly as spoken. No translation of identifiers. {:else} No preset, the active profile's prompt governs tone alone. {/if}

GPU concurrency

{#if settings.aiGpuConcurrency === "sequential"} On tight-VRAM cards (≤6 GB), loading Whisper + LLM together OOMs. Sequential mode frees the other model before loading; adds a small reload pause between transcribe and cleanup. {:else} Both models stay resident in GPU memory. Faster transitions, but needs enough VRAM to hold both at once. {/if}

Compute Device

{#if hasGpuAcceleration()}

Only accelerators built into this binary are shown here.

{:else}
This build is CPU-only. GPU controls appear in GPU-enabled builds.
{/if}

All off by default. Rituals only appear when you ask for them.

{#if settings.ritualsMorning}

ADHD sleep inertia is intense for the first 30–45 minutes after waking. Pick a time when you're genuinely ready to decide.

{/if} {#if settings.ritualsEvening}
{/if}

Uses your operating system's built-in voices. No audio leaves the machine.

{#if ttsVoicesError}

We couldn't load the text-to-speech voices. The rest of Settings still works.

Technical details
{ttsVoicesError}
{:else if ttsVoicesLoaded && ttsVoices.length === 0}

No additional voices reported by the system synth. Install extra voices through your OS accessibility settings.

{/if}
Slower Normal Faster
{#if settings.meetingAutoCapture}

Apps to watch (comma-separated)

{ const raw = event.currentTarget.value; settings.meetingAutoCaptureApps = raw .split(",") .map((entry) => entry.trim().toLowerCase()) .filter((entry) => entry.length > 0); }} />
{/if} {#if settings.soundCues}
{Math.round(settings.soundCueVolume * 100)}%
{/if} {#if settings.saveAudio}

Output Folder

{outputFolderPreview}

{#if settings.outputFolder} {/if}
{/if}

Toggle recording from anywhere. Click to change.

Theme

prefs.theme === "light" ? "Light" : prefs.theme === "system" ? "System" : "Dark", (v) => updatePreferences({ theme: v === "Light" ? "light" : v === "System" ? "system" : "dark" }) } />

Zone

Font Size {settings.fontSize}px

{$_("settings.language")}

{#each SUPPORTED_LOCALES as option} {/each}

{$_("settings.languageDescription")}

{engineStatus}
{#each [ "100% offline, all processing on your machine", "No Python required, compiled Whisper engine", "No cloud, audio never leaves your computer", "No accounts, no sign-up, no tracking", "No telemetry, zero data collection", ] as item}

{item}

{/each}

Lumotia v1.0 · Powered by whisper.cpp · Built by CORBEL Ltd

Diagnostics

If something goes wrong, generate a diagnostic report to share with the developer. The report contains your settings, recent errors, any crash dumps, and the tail of the log file. Nothing is sent automatically, you preview it first, then choose copy or save.

{#if diagnosticReport} {/if}
{#if diagnosticReportError}

{diagnosticReportError}

{#if diagnosticReportErrorDetail}
Technical details
{diagnosticReportErrorDetail}
{/if}
{/if} {#if diagnosticReportSavedTo}

{diagnosticReportSavedTo}

{/if} {#if diagnosticReport}
Preview report ({diagnosticReport.length} chars)
{diagnosticReport}
{/if}
{/if} {#if !isQuietware || activeTab === 'help'}

Need to walk through onboarding again? Replay the first-run tutorial and the gate will skip past your existing data.

Logs + system info + redacted preferences. Never includes audio or transcript content.

Known limitations for this release are documented in KNOWN-ISSUES.md. Bugs and feature requests can be filed at github.com/jakeadriansames/lumotia/issues.

{/if}