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>
This commit is contained in:
jars
2026-05-09 14:04:13 +01:00
parent 3c47000ea9
commit a1f3f3f134
105 changed files with 11266 additions and 0 deletions

View File

@@ -0,0 +1,77 @@
---
name: Dictation page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---
# Dictation page
> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → 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
- [Stores](../stores.md). `page`, `settings`, `llmStatus` reactivity.
- [Frontend ↔ Tauri bridge](../frontend-tauri-bridge.md). All commands and events.
- [Components](../components.md). `Card`, `ModelDownloader`, `SpeakerButton`, `EmptyState`.
- [../03-audio-transcription/README.md](../../03-audio-transcription/README.md). Live session plumbing on the Rust side.
- [../04-llm-formatting-mcp/README.md](../../04-llm-formatting-mcp/README.md). Cleanup and task extraction commands.

View File

@@ -0,0 +1,63 @@
---
name: Files page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---
# Files page
> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → Files
**Plain English summary.** Drag and drop or browse local audio/video files for transcription. Same engine as live dictation, just file mode. On finish, results land in the page (preview text, segments) and into `addToHistory`.
## At a glance
- **Path:** `src/lib/pages/FilesPage.svelte`
- **LOC:** 263
- **Imports (selected):**
- Tauri: `invoke` (core), `listen` (event).
- Stores: `settings`, `addToHistory` from `page.svelte.ts`. `profilesStore`. `toasts` (transitive via store helpers).
- Components: `Card`, `EmptyState`.
- Utils: `exportTranscript`.
- External: `Upload` icon from `lucide-svelte`. `@tauri-apps/plugin-dialog` (lazy import).
## What's in here
### Drag and drop
- `onMount` registers three Tauri events:
- `tauri://drag-drop` (`FilesPage.svelte:28`). Filters the dropped paths to supported extensions and starts transcription.
- `tauri://drag-enter` (`FilesPage.svelte:34`). Sets `isDragOver = true`.
- `tauri://drag-leave` (`FilesPage.svelte:35`). Sets `isDragOver = false`.
- `onDestroy` calls each unlisten.
### Browse
- `handleBrowse()` lazy imports `@tauri-apps/plugin-dialog` and opens with the audio/video filter (`mp3, wav, m4a, mp4, flac, ogg, webm, mov, mkv`).
### Transcription
- Calls `invoke("transcribe_file", { ... })` (`FilesPage.svelte:76`). Receives transcript text + segments.
- Optional `copy_to_clipboard` on completion.
- Pushes result into history via the store helper.
### State
- `fileTranscript`, `segments`, `isDragOver`, `progress`, `progressText`, `fileName`, `error`, `transcribing`.
## Tauri command surface
`transcribe_file`, `copy_to_clipboard`. Plus dialog plugin.
## Watch outs
- The drag and drop events require the Tauri config to declare drag drop on the relevant window. If the events do not fire, check `tauri.conf.json` and slice 02.
- Long files block the UI of this page until `transcribe_file` resolves. There is no abort.
- The supported extensions list is duplicated between the file dialog filter and (presumably) the Rust side. Drift risk.
- Multi file drag drop iterates serially. No queue UI.
## See also
- [Pages: dictation](dictation.md). The live counterpart.
- [Frontend ↔ Tauri bridge](../frontend-tauri-bridge.md).

View File

@@ -0,0 +1,59 @@
---
name: First run page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---
# First run page
> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → First run
**Plain English summary.** What the user sees the first time they launch Magnotia, before any model is on disk. Probes hardware, recommends a Whisper model size, and downloads the chosen model (Whisper or Parakeet). On success, transitions to the dictation page.
## At a glance
- **Path:** `src/lib/pages/FirstRunPage.svelte`
- **LOC:** 337
- **Imports:**
- Tauri: `invoke`, `listen`.
- Stores: `page`, `settings`, `saveSettings` from `page.svelte.ts`. `toasts`.
- Components: `UnicodeSpinner`.
- External: `lucide-svelte` (`Download`, `CheckCircle`, `Sunrise`, `Moon`, `Play`).
- **Includes:** also `ShutdownRitualPage` is imported here (suggesting the "evening ritual" preview lives in this same flow). Verify on read; treat as a coupled flow.
## What's in here
### Probe
- `onMount` calls `probe_system` and `rank_models` (`FirstRunPage.svelte:31-32`) to compute recommended models given the user's RAM, GPU, OS.
- Sets `probing = false` and renders the recommendation UI.
### Download
- `downloadAndGo(modelId)` (`FirstRunPage.svelte:55-95`):
- Subscribes to `model-download-progress` and `parakeet-download-progress` events.
- Calls `download_model` then `load_model` (Whisper) or `download_parakeet_model` then `load_parakeet_model`.
- On success, sets `ready = true` and routes to dictation (`page.current = "dictation"`).
- Computes `estimatedMinutes` from elapsed and progress percent (`derived.by`).
### Triggering
- The shell auto sets `page.current = "first-run"` if `list_models` and `list_parakeet_models` are both empty (`+layout.svelte:346-353`).
- Skip path: clicking "Get started" without a model lets the user opt out (still routes to dictation).
## Tauri command surface
`probe_system`, `rank_models`, `download_model`, `load_model`, `download_parakeet_model`, `load_parakeet_model`. Events: `model-download-progress`, `parakeet-download-progress`.
## Watch outs
- The download is a single shot. There is no resume on cancel; if the user closes the app mid download, they restart from zero. Slice 02/05 may improve this later.
- `estimatedMinutes` is a linear extrapolation. Network speed is not constant; expect the value to wiggle.
- The page imports `ShutdownRitualPage` but the value of doing so should be confirmed (potential dead import).
## See also
- [Pages overview](../pages-overview.md). When this page is forced.
- [Frontend ↔ Tauri bridge](../frontend-tauri-bridge.md). Probe and download commands.
- [Windows and routes](../windows-and-routes.md). Shell triggers.

View File

@@ -0,0 +1,71 @@
---
name: History page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---
# History page
> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → History
**Plain English summary.** The transcript browser. Lists everything saved to SQLite, full text searchable via FTS5, with inline expansion to read the full body, audio playback, starring, manual + auto tagging, copy, delete, export to Markdown, and "open in viewer" handoff to the dedicated transcript editor window.
## At a glance
- **Path:** `src/lib/pages/HistoryPage.svelte`
- **LOC:** 974
- **Imports (selected):**
- Tauri: `invoke` and `convertFileSrc` from `@tauri-apps/api/core`.
- Stores: `historyStore` helpers from `page.svelte.ts` (`history`, `loadHistory`, `deleteFromHistoryById`, `renameHistoryEntry`), `toasts`, `getPreferences`.
- Utils: `deriveAutoTags`, `buildFrontmatter`, `buildMarkdown`, `normaliseTag` (frontmatter). `saveTranscriptAsMarkdown`, `exportTranscriptsToDir` (saveMarkdown). `clampTextLines`, `measurePreWrap` (textMeasure). `bodyPretextLineHeight`, `pretextFontShorthand` (accessibilityTypography). `buildCumulativeOffsets`, `findVisibleRange` (virtualList). `formatTime`, `formatDuration` (time). `PLAYBACK_SPEEDS` (constants).
- Components: `Card`, `EmptyState`.
- External: `lucide-svelte` (`Search`, `Clock`, `Play`, `Pause`, `FileText`, `Mic`, `ChevronDown`, `ExternalLink`, `Star`, `Tag`).
## What's in here
### List + search
- Loads via `loadHistory` (which calls `list_transcripts` in Rust).
- Search input filters client side (FTS happens server side via `search_transcripts` for some flows; check `page.svelte.ts`).
- Virtualised scrolling using `buildCumulativeOffsets` and `findVisibleRange` from `utils/virtualList.ts`. Row heights use `measurePreWrap` to compute pre wrap heights from the live preferences font.
- Constants: `COLLAPSED_ROW_MIN_HEIGHT`, `COLLAPSED_ROW_VERTICAL_PADDING`, `EXPANDED_BASE_HEIGHT`, `EXPANDED_PADDING`, etc.
### Audio playback
- `convertFileSrc()` maps the saved audio path to a webview URL.
- Inline `<audio>` element. Speed control uses `PLAYBACK_SPEEDS` (`[0.5, 1, 1.5, 2, 3, 5]`).
- A `requestAnimationFrame` loop advances `currentTime`. `cancelAnimationFrame` on stop.
### Per row actions
- Star (toggles `starred` flag, persisted via `update_transcript`).
- Copy (`copy_to_clipboard`).
- Delete (confirms, then calls `delete_transcript`).
- Open in viewer window (`open_viewer_window`, then handoff via `localStorage`).
- Auto tag (calls `extract_content_tags_cmd`, returns suggested tags merged into `tags`).
- Rename via `renameHistoryEntry` store helper.
- Export to markdown via `saveTranscriptAsMarkdown`.
### Bulk
- Bulk auto tag walks the visible list and calls `extract_content_tags_cmd` per row.
- Bulk export to directory via `exportTranscriptsToDir`.
## Tauri command surface
`delete_transcript`, `copy_to_clipboard`, `open_viewer_window`, `extract_content_tags_cmd`. Plus indirect commands from store helpers (`add_transcript`, `update_transcript`, etc) and the dialog plugin used by `saveMarkdown.ts`.
## Watch outs
- Virtual scrolling assumes stable row heights once measured. Toggling preferences (font size, line height) invalidates the measure. The page recomputes on `getPreferences()` change but watch for stutter on rapid changes.
- The viewer handoff writes the transcript ID to `localStorage`. The viewer window then loads from SQLite. Do not put transcript text in `localStorage`.
- Auto tag is rate limited only by user clicks. Bulk over a large library can hammer the LLM. Consider a guard if scaling.
- `convertFileSrc` paths are valid only inside the Tauri webview. If the audio path is missing or moved, `<audio>` will silently fail; show an error state.
## See also
- [Pages: dictation](dictation.md). Where transcripts originate.
- [Stores](../stores.md). `page.svelte.ts` history helpers.
- [Frontend ↔ Tauri bridge](../frontend-tauri-bridge.md). Commands referenced.
- [Windows and routes](../windows-and-routes.md). The viewer window handoff.

View File

@@ -0,0 +1,72 @@
---
name: Settings page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---
# Settings page
> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → Settings
**Plain English summary.** The configuration panel. Owns audio device selection, vocabulary, profiles, templates, transcription engine choice and model management (Whisper + Parakeet + LLM), the global hotkey, rituals, nudges, accessibility, text-to-speech, diagnostics, and locale selection. It is by far the largest single file in the frontend at 2 484 lines.
## At a glance
- **Path:** `src/lib/pages/SettingsPage.svelte`
- **LOC:** 2 484
- **Imports (selected):**
- Stores: `settings`, `saveSettings`, `profiles`, `saveProfiles`, `templates`, `saveTemplates`, `page`, `addProfileTaskList`, `removeProfileTaskList` from `page.svelte.ts`. `getPreferences`, `updatePreferences`. `profilesStore`, `DEFAULT_PROFILE_ID`. `toasts`. `refreshLlmStatus`.
- Components: `Card`, `Toggle`, `SegmentedButton`, `HotkeyRecorder`, `ImplementationRulesEditor`, `SettingsGroup`, `ZonePicker`, `AccessibilityControls`.
- Utils: `clampTextLines`, `bodyPretextLineHeight`, `pretextFontShorthand`, `formatDuration`.
- i18n: `_`, `SUPPORTED_LOCALES`, `setLocale`, `currentLocale`.
- External: `lucide-svelte` (`Check`, `Search`, `X`, `Mic`, `BookOpen`, `Type`, `Sparkles`, `SquareCheck`, `Clipboard`, `Sliders`).
## Sections (top level)
Built from `SettingsGroup` accordions. Top level groups (line refs are anchors in the file):
1. **Audio** (`SettingsPage.svelte:1141`). Device list (from `list_audio_devices`), microphone selection.
2. **Vocabulary** (`SettingsPage.svelte:1191`). Two nested groups:
- **Terms and profiles** (`SettingsPage.svelte:1197`). Vocabulary terms attached to the active profile, plus the active profile selector.
- **Profiles and templates** (`SettingsPage.svelte:1415`). Two further nested groups:
- **Profiles** (`SettingsPage.svelte:1423`). Create, rename, delete; default profile cannot be deleted.
- **Templates** (`SettingsPage.svelte:1481`). Per profile templates injected at recording start.
3. **Processing** (also referred to in file as the engine + AI tier section). Phase 9c style group with `onopen` hook that probes `check_engine`, `check_parakeet_engine`, `list_models`, `detect_paste_backends`, etc.
4. **Hotkey**. Wraps `HotkeyRecorder`. Search navigation jumps here when the user clicks the hotkey chip in another section (`SettingsPage.svelte:477`).
5. **Rituals**. Morning triage, evening wind down toggles.
6. **Nudges and implementation intentions**. Wraps `ImplementationRulesEditor`.
7. **Accessibility**. Wraps `AccessibilityControls`. Theme, zone (`ZonePicker`), font family, sizes, line height, letter spacing, bionic reading, reduce motion.
8. **Read aloud (TTS)** (`SettingsPage.svelte:759`). Voice selection from `tts_list_voices`, rate, sample play.
9. **Diagnostics** (`SettingsPage.svelte:377-405`). Generates and saves a redacted diagnostic report.
10. **Tasks** (sparkline toggle, relocated in Phase 9c).
11. **Launch at login**. Wires `@tauri-apps/plugin-autostart`.
12. **Locale**. svelte-i18n locale picker.
## Key state
- `audioDevices`, `downloadedModels`, `parakeetOk`, `parakeetDownloaded`, `pasteBackends`, `systemInfo`, `runtimeCapabilities`, `llmLoaded`, `llmModels`, `llmStatuses`, `ttsVoices`.
- Search query (`X`/`Search` icons) drives a force open mode for `SettingsGroup` (`SettingsPage.svelte:432-477`).
- Three concurrent download progress listeners: Whisper (`model-download-progress`), Parakeet (`parakeet-download-progress`), LLM (`magnotia:llm-download-progress`) (`SettingsPage.svelte:864-880`).
## Tauri command surface
Audio: `list_audio_devices`. Models (Whisper): `list_models`, `download_model`, `load_model`, `check_engine`. Models (Parakeet): `check_parakeet_engine`, `check_parakeet_model`, `download_parakeet_model`, `load_parakeet_model`. Models (LLM): `recommend_llm_tier`, `check_llm_model`, `download_llm_model`, `load_llm_model`, `unload_llm_model`, `delete_llm_model`, `test_llm_model`, `get_llm_status`. Capabilities: `get_runtime_capabilities`, `probe_system`, `detect_paste_backends`. TTS: `tts_list_voices`, `tts_speak`. Diagnostics: `generate_diagnostic_report`, `save_diagnostic_report`. Plus the implicit `save_preferences` invoked by the preferences store on every accessibility toggle.
Events listened to: `model-download-progress`, `parakeet-download-progress`, `magnotia:llm-download-progress`.
## Watch outs
- 2 484 lines, hand rolled accordion, Phase 9c handover already deferred the deeper restructure. New options should be added inside the existing `SettingsGroup` topology rather than threaded into the global header.
- `settings.theme` ("Light"/"Dark"/"System") is the legacy field; `preferences.theme` is the new one. `+layout.svelte:61-68` re maps every effect cycle. Adding new theme options needs both stores.
- `page.current = "shutdown"` button at line 816 is the only entrance from settings into the wind down ritual (other than the tray).
- The `model-download-progress` event payload is shared across Whisper and Parakeet listeners. Take care that progress UI does not cross wires when both downloads run concurrently (rare but possible if `+layout.svelte` triggers a prewarm while Settings is open).
- The diagnostics path strips secrets in Rust; do not re add raw paths or env values to the report payload here.
- Accessibility writes go through `preferences` (Tauri persisted) but `settings.fontSize` writes through `localStorage`. Two persistence channels for similar surfaces.
## See also
- [Components](../components.md). `SettingsGroup`, `HotkeyRecorder`, `ImplementationRulesEditor`, `ZonePicker`, `AccessibilityControls`, `Toggle`, `SegmentedButton`.
- [Stores](../stores.md). `page` settings + profiles + templates. `preferences`. `llmStatus`.
- [Frontend ↔ Tauri bridge](../frontend-tauri-bridge.md). All command names referenced here.
- [Internationalisation](../i18n.md). Locale picker.

View File

@@ -0,0 +1,65 @@
---
name: Tasks page
type: architecture-map-page
slice: 01-frontend
last_verified: 2026/05/09
---
# Tasks page
> **Where you are:** [Architecture map](../../README.md) → [Frontend](../README.md) → [Pages overview](../pages-overview.md) → Tasks
**Plain English summary.** The full screen tasks board. Inbox, today, soon, later buckets. Per task energy chips (low/medium/high), per task lists, micro steps, completion sparkline, search, sort, drag to reorder, and a "pop out" button that opens the same tasks in a small persistent floating window via `open_task_window`.
## At a glance
- **Path:** `src/lib/pages/TasksPage.svelte`
- **LOC:** 725
- **Imports (selected):**
- Stores: from `page.svelte.ts`: `tasks`, `addTask`, `completeTask`, `uncompleteTask`, `deleteTask`, `updateTask`, `setTaskEnergy`, `taskLists`, `addTaskList`, `renameTaskList`, `deleteTaskList`, `settings`, `saveSettings`. From `completionStats.svelte.ts`: `recentCompletions`, `todayCount`.
- Components: `WipTaskList`, `EmptyState`, `CompletionSparkline`, `EnergyChip`, `Card`.
- Utils: `formatTimestamp` (time). `BUCKET_COLORS`, `EFFORT_LABELS`, `EFFORT_ORDER` (constants).
- External: `lucide-svelte` (`SquareCheck`, `Search`, `ExternalLink`, `ChevronLeft`, `ArrowUpDown`, `Plus`, `X`, `ChevronRight`, `Zap`).
## What's in here
### Local state
- `activeBucket` (`"all" | "inbox" | "today" | "soon" | "later"`).
- `activeListId` (`"all" | "inbox" | <listId>`).
- `showCompleted`, `quickInput`, `searchQuery`, `sidebarCollapsed`.
### Render
- Quick add input (top). Sets bucket via segmented choice, energy via `EnergyChip`.
- Filter / sort header. Sort modes use `EFFORT_ORDER` for effort comparisons.
- Task list body uses `WipTaskList` (which renders rows with `MicroSteps` expansion).
- "Pop out" icon → `invoke("open_task_window")` (`TasksPage.svelte:231`).
- Sparkline panel renders `CompletionSparkline` if `settings.showMomentumSparkline` is true.
### Stores it depends on
- `tasks` (live array). `taskLists`. `recentCompletions` for the sparkline.
### Events
- Listens implicitly to: `magnotia:task-completed`, `magnotia:task-uncompleted`, `magnotia:task-deleted`, `magnotia:step-completed` are emitted from store helpers and consumed by `completionStats.svelte.ts` to refresh the sparkline.
## Tauri command surface (direct)
- `open_task_window` (page action).
The store helpers used here call into Rust through `add_task_cmd`, `complete_task_cmd`, `uncomplete_task_cmd`, `delete_task_cmd`, plus list management commands (`*_task_list_cmd`).
## Watch outs
- Drag and drop is heavy on this page. Reorder mutations should always go via the store helpers; do not manipulate `tasks` directly or you will desync the SQLite source of truth.
- The sparkline is gated on `settings.showMomentumSparkline` (true by default). It re renders on the four `magnotia:task-*` events, plus window focus for date rollover.
- "Pop out" deliberately does not pass any state. The float window reads the same store, which is shared via store hydration on mount and `localStorage` for `settings`.
- Sort, filter, search are not persisted. Reload returns to defaults.
## See also
- [Components](../components.md). `WipTaskList`, `MicroSteps`, `EnergyChip`, `CompletionSparkline`.
- [Stores](../stores.md). `page` task helpers, `completionStats`.
- [Windows and routes](../windows-and-routes.md). The float window equivalent.