diff --git a/HANDOVER.md b/HANDOVER.md index ce9718b..63d96f4 100644 --- a/HANDOVER.md +++ b/HANDOVER.md @@ -1,11 +1,11 @@ --- name: handover-2026-04-25 type: reference -tags: [handover, session, magnotia, phase-9, polish-debt] +tags: [handover, session, lumotia, phase-9, polish-debt] description: Session handover — 2026/04/24-25 Phase 9 polish debt mostly shipped --- -# Magnotia Handover — 2026/04/25 +# Lumotia Handover — 2026/04/25 > **Note:** Session-specific handover. Migration v14 (`transcripts.llm_tags`) was the head **at the time of this session**. Subsequent work has advanced the schema; current head is v15 (`idx_transcripts_profile_created`, composite index). For the current codebase shape, see [`docs/architecture-map/`](docs/architecture-map/) and [`KNOWN-ISSUES.md`](KNOWN-ISSUES.md). @@ -13,25 +13,25 @@ Phase 9 session. Spec + plan written from scratch and committed; plan correction ## Rebrand note -Product rename **Magnotia → Magnotia** still in flight. Copy in new docs is "Magnotia"; codebase paths / package names / repos still carry `magnotia`. No rebrand work this session. See `~/.claude/projects/-home-jake-Documents-CORBEL-Main/memory/project_magnotia_rebrand.md`. +Product rename **Lumotia → Lumotia** still in flight. Copy in new docs is "Lumotia"; codebase paths / package names / repos still carry `lumotia`. No rebrand work this session. See `~/.claude/projects/-home-jake-Documents-CORBEL-Main/memory/project_magnotia_rebrand.md`. ## What shipped this session ### 9a — Export plumbing -- `write_text_file_cmd` Rust command in new `src-tauri/src/commands/fs.rs`, with two unit tests (UTF-8 round-trip + bad-parent error path). Registered in `invoke_handler!`. `tempfile = "3"` added as `[dev-dependencies]` on the magnotia crate. +- `write_text_file_cmd` Rust command in new `src-tauri/src/commands/fs.rs`, with two unit tests (UTF-8 round-trip + bad-parent error path). Registered in `invoke_handler!`. `tempfile = "3"` added as `[dev-dependencies]` on the lumotia crate. - `src/lib/utils/saveMarkdown.ts` utility centralises `suggestedFilename`, `saveTranscriptAsMarkdown`, `exportTranscriptsToDir` (directory-mode bulk export with in-batch collision suffixing). - HistoryPage `exportMarkdown` no longer copies to clipboard; it opens the OS save dialog and writes the file. Cancel returns silently. - HistoryPage gained a slim leading checkbox per row, a bulk-action toolbar (select-all / clear / export / delete), `Esc` to clear, `Cmd/Ctrl+A` to select-all-visible when focus is inside the list and not in a text input. ### 9b — LLM content tags -- `magnotia-llm` exports a new `ContentTags { topic, intent }`, an `INTENT_CLOSED_SET`, an `is_valid_intent` helper, a `CONTENT_TAGS_SYSTEM` prompt and a `CONTENT_TAGS_GRAMMAR` GBNF (recursive style matching the existing `TASK_ARRAY_GRAMMAR`). +- `lumotia-llm` exports a new `ContentTags { topic, intent }`, an `INTENT_CLOSED_SET`, an `is_valid_intent` helper, a `CONTENT_TAGS_SYSTEM` prompt and a `CONTENT_TAGS_GRAMMAR` GBNF (recursive style matching the existing `TASK_ARRAY_GRAMMAR`). - `LlmEngine::extract_content_tags` method follows the same render-chat → generate → JSON-parse shape as the existing `cleanup_text` and `extract_tasks`. Truncates to the trailing 2000 chars on a UTF-8 boundary; max_tokens 96 is enough for the JSON envelope. Smoke test in `crates/llm/tests/content_tags_smoke.rs` is gated on `MAGNOTIA_LLM_TEST_MODEL` matching the Phase 8 pattern. - `extract_content_tags_cmd` Tauri wrapper bridges through `state.llm_engine` with the standard `spawn_blocking` + `PowerAssertion` guard. ### 9b structural — migration v14 + persistence wiring A correction layered in after the critical-review pass discovered the original Task 9 was assuming a writable `saveHistory()` path that turned out to be a no-op stub. - Migration v14 adds `transcripts.llm_tags TEXT NOT NULL DEFAULT ''`. -- `magnotia-storage` `database.rs` SELECT statements include the column. `TranscriptRow` + `transcript_row_from` carry it. `update_transcript_meta` accepts an `Option<&str>` for `llm_tags` (sixth optional, `#[allow(too_many_arguments)]` keeps clippy happy without inverting the signature into a struct). +- `lumotia-storage` `database.rs` SELECT statements include the column. `TranscriptRow` + `transcript_row_from` carry it. `update_transcript_meta` accepts an `Option<&str>` for `llm_tags` (sixth optional, `#[allow(too_many_arguments)]` keeps clippy happy without inverting the signature into a struct). - `commands/transcripts.rs` `TranscriptDto` + `UpdateTranscriptMetaRequest` add `llm_tags`; `update_transcript_meta_cmd` forwards. - Frontend types: `TranscriptEntry.llmTags: string[]`, `TranscriptRow.llmTags: string`, `ContentTags`, optional `TranscriptMetaPatch.llmTags`. - `mapTranscriptRow` hydrates `llmTags`. `saveTranscriptMeta` now also forwards `llmTags` payloads. `buildFrontmatter` unions auto + manual + LLM tags into the exported markdown frontmatter. @@ -56,7 +56,7 @@ Fresh run on `main` tip `dd45f10`: - `cargo fmt --check`: clean. - `cargo clippy --all-targets -- -D warnings`: clean. -- `cargo test`: **277 tests pass**, 0 failed. Storage gained 1 new test (`update_transcript_meta_writes_llm_tags`), magnotia-tauri gained 2 (write_text_file). The Phase 8 brittle test fix is in this count. +- `cargo test`: **277 tests pass**, 0 failed. Storage gained 1 new test (`update_transcript_meta_writes_llm_tags`), lumotia-tauri gained 2 (write_text_file). The Phase 8 brittle test fix is in this count. - `npm run check`: 0 errors, 0 warnings across 3957 files. - `npm run build`: clean production build via `@sveltejs/adapter-static`. @@ -64,13 +64,13 @@ Fresh run on `main` tip `dd45f10`: The original Phase 9 spec + plan committed at `49a795f` + `48d3db7` had three mismatches against the actual codebase, surfaced by a critical-review pass before execution. Layered as a corrections appendix in commit `3eb24f2`: -1. `magnotia-llm` is `LlmEngine::generate(prompt, config)` synchronous, not the speculated `LlamaEngine::generate_chat(messages, config).await`. +1. `lumotia-llm` is `LlmEngine::generate(prompt, config)` synchronous, not the speculated `LlamaEngine::generate_chat(messages, config).await`. 2. `AppState.llm_engine: Arc` is direct, not behind a `RwLock`. 3. **Structural** — `transcripts.llm_tags` requires a real SQLite migration plus Tauri command extension because the frontend `saveHistory()` is a no-op stub. Original plan assumed `manualTags`-mirroring would suffice. Migration v14 + `update_transcript_meta` extension landed as a new task to cover this. Picked up the latent `manualTags` persistence bug for free. ## Owed to Jake (next session) -1. **Manual dogfood walkthrough.** Cannot be driven by an automated agent. When opening Magnotia next: +1. **Manual dogfood walkthrough.** Cannot be driven by an automated agent. When opening Lumotia next: - Export one transcript via the History "Export .md" button — save dialog opens, file written to chosen path. Cancel — no toast, no fallback. - Select 3 history rows via checkboxes — toolbar surfaces, "Export selected" writes one .md per row to a chosen folder, collisions suffixed " (2)" etc. - Click "Tag" on one row — within a few seconds, dashed `topic:*` and `intent:*` chips appear. Click a chip — it moves into `manualTags` (solid accent chip). Page refresh — both `manualTags` and `llmTags` survive (this is the persistence-fix outcome). @@ -92,7 +92,7 @@ The original Phase 9 spec + plan committed at `49a795f` + `48d3db7` had three mi | Phases 1-8 | All shipped. | | Phase 9 | **Mostly shipped this session.** Export plumbing, LLM content tags (with persistence), polish on sparkline + badge are live. SettingsPage deeper restructure + walkthrough a11y sweeps deferred. Roadmap entry updated. | | Phase 10a | QC: dogfood walkthrough (above), Rachmann's RB-08 Mac verification (parallel), cross-platform CI, a11y regression, clean-install test. Half day. | -| Phase 10b | Magnotia → Magnotia rename sweep: package name, all 10 crates, bundle ids, install paths, `magnotia.db` → `magnotia.db`, event names, repo rename on both remotes. Half to 1 day. | +| Phase 10b | Lumotia → Lumotia rename sweep: package name, all 10 crates, bundle ids, install paths, `lumotia.db` → `lumotia.db`, event names, repo rename on both remotes. Half to 1 day. | | Phase 10c | Release: 0.1.0 version sync, CHANGELOG seeded from roadmap phases, release notes, tag + push. Half day. | ### Release-blocker state @@ -111,7 +111,7 @@ The original Phase 9 spec + plan committed at `49a795f` + `48d3db7` had three mi - Spec: [docs/superpowers/specs/2026-04-24-phase9-polish-debt-design.md](docs/superpowers/specs/2026-04-24-phase9-polish-debt-design.md) - Plan: [docs/superpowers/plans/2026-04-24-phase9-polish-debt.md](docs/superpowers/plans/2026-04-24-phase9-polish-debt.md) -- Roadmap: [docs/roadmap/2026-04-23-magnotia-feature-complete-roadmap.md](docs/roadmap/2026-04-23-magnotia-feature-complete-roadmap.md) +- Roadmap: [docs/roadmap/2026-04-23-lumotia-feature-complete-roadmap.md](docs/roadmap/2026-04-23-lumotia-feature-complete-roadmap.md) - Previous handover: [HANDOVER-2026-04-24.md](HANDOVER-2026-04-24.md) (Phase 8) - Release-blocker index: [docs/issues/README.md](docs/issues/README.md) - Rebrand memory: `~/.claude/projects/-home-jake-Documents-CORBEL-Main/memory/project_magnotia_rebrand.md` diff --git a/KNOWN-ISSUES.md b/KNOWN-ISSUES.md index 71a76e7..1d97de2 100644 --- a/KNOWN-ISSUES.md +++ b/KNOWN-ISSUES.md @@ -36,7 +36,7 @@ Tracked limitations and partial implementations in the current codebase. Each en ## Cloud providers -### KI-04 — `magnotia-cloud-providers` crate is not user-exposed +### KI-04 — `lumotia-cloud-providers` crate is not user-exposed **Status:** The crate is a declared workspace dependency in [`src-tauri/Cargo.toml:36`](src-tauri/Cargo.toml#L36) and compiles into the binary, but no Tauri command, page, or settings field invokes `store_api_key` / `retrieve_api_key`. There is no UI to enter or store a cloud API key in the current build. diff --git a/README.md b/README.md index 6478fbe..15af4e6 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,8 @@ -# Magnotia +# Lumotia *Think out loud. Keep working.* -Magnotia is a local-first, cognitive-load-aware dictation and task-capture desktop app. Every transcription, LLM cleanup, and task extraction runs on the user's machine. No telemetry, no analytics, no cloud dependency. The app is designed around a single observation: people who think in bursts lose ideas faster than they can type, and the tool's job is to get out of the way. +Lumotia is a local-first, cognitive-load-aware dictation and task-capture desktop app. Every transcription, LLM cleanup, and task extraction runs on the user's machine. No telemetry, no analytics, no cloud dependency. The app is designed around a single observation: people who think in bursts lose ideas faster than they can type, and the tool's job is to get out of the way. --- @@ -21,15 +21,15 @@ Magnotia is a local-first, cognitive-load-aware dictation and task-capture deskt 1. **Local-first is the floor, not a feature.** No voice, transcript, or task ever leaves the user's machine unless they explicitly send it. No telemetry. 2. **Cognitive load is the limiting resource.** Every new setting must earn its mental real estate. Every interaction should reduce, not add, decisions. -3. **Composable, not monolithic.** Magnotia is a dictation primitive: via MCP, CLI, and filesystem export, it slots into whatever workflow the user already has (Obsidian, Claude Desktop, Cline, any text field). +3. **Composable, not monolithic.** Lumotia is a dictation primitive: via MCP, CLI, and filesystem export, it slots into whatever workflow the user already has (Obsidian, Claude Desktop, Cline, any text field). 4. **LLM scope is narrow.** The in-app LLM does transcription cleanup and task extraction. It is not a wake-word agent, not a chat UI, not a multi-provider cloud fan-out. 5. **Raw transcript is always recoverable.** Cleanup is additive, never destructive. The user can always see and revert to what Whisper heard. -These are enforced in the codebase (where practical) and in the docs under [`docs/whisper-ecosystem/magnotia-context.md`](docs/whisper-ecosystem/magnotia-context.md). +These are enforced in the codebase (where practical) and in the docs under [`docs/whisper-ecosystem/lumotia-context.md`](docs/whisper-ecosystem/lumotia-context.md). --- -## What Magnotia does today +## What Lumotia does today ### Speech-to-text - Vulkan-accelerated local **Whisper** inference via [whisper-rs](https://github.com/tazz4843/whisper-rs) 0.16 + whisper.cpp. Works on NVIDIA, AMD, Intel Arc, Apple (via MoltenVK), and integrated graphics. @@ -65,7 +65,7 @@ These are enforced in the codebase (where practical) and in the docs under [`doc - Transcript editor window (`/viewer`) with debounced autosave. ### External integration -- **MCP stdio server** (`magnotia-mcp`) exposing read-only transcripts and tasks to any Model Context Protocol client (Claude Desktop, Cline, Cursor, etc.). No authentication, read-only, local-only. +- **MCP stdio server** (`lumotia-mcp`) exposing read-only transcripts and tasks to any Model Context Protocol client (Claude Desktop, Cline, Cursor, etc.). No authentication, read-only, local-only. ### Accessibility - Dyslexia-friendly fonts bundled: Lexend, Atkinson Hyperlegible Next, OpenDyslexic. @@ -84,7 +84,7 @@ These are enforced in the codebase (where practical) and in the docs under [`doc ## Architecture -Magnotia is a Tauri 2 desktop app with three layers: +Lumotia is a Tauri 2 desktop app with three layers: ``` ┌─────────────────────────────────────────────────────────────────┐ @@ -102,18 +102,18 @@ Magnotia is a Tauri 2 desktop app with three layers: │ window-state │ ├─────────────────────────────────────────────────────────────────┤ │ Rust workspace (crates/) │ -│ magnotia-core, magnotia-audio, magnotia-transcription, magnotia-llm, │ -│ magnotia-ai-formatting, magnotia-storage, magnotia-hotkey, │ -│ magnotia-cloud-providers, magnotia-mcp │ +│ lumotia-core, lumotia-audio, lumotia-transcription, lumotia-llm, │ +│ lumotia-ai-formatting, lumotia-storage, lumotia-hotkey, │ +│ lumotia-cloud-providers, lumotia-mcp │ └─────────────────────────────────────────────────────────────────┘ ``` -The Rust workspace is the brain; Tauri is the OS integration surface; Svelte is the UI. The MCP server (`magnotia-mcp`) is a separate binary that opens Magnotia's SQLite store read-only — it's Magnotia-as-primitive for external agents. +The Rust workspace is the brain; Tauri is the OS integration surface; Svelte is the UI. The MCP server (`lumotia-mcp`) is a separate binary that opens Lumotia's SQLite store read-only — it's Lumotia-as-primitive for external agents. ### Repository layout ``` -magnotia/ +lumotia/ ├── Cargo.toml # workspace root ├── src-tauri/ # Tauri app (main binary + commands) │ ├── src/ @@ -165,15 +165,15 @@ magnotia/ | Crate | Responsibility | |---|---| -| **`magnotia-core`** | Shared types (`Segment`, `Transcript`, `Megabytes`, `ModelId`), constants, the `Engine` / `SpeedTier` / `AccuracyTier` enums, hardware probe (`sysinfo`-based), model registry (Whisper + Parakeet entries), hardware-aware recommendation scoring, `process_watch` for meeting detection. | -| **`magnotia-audio`** | `cpal`-based microphone capture with device hotplug + error forwarding, VAD, `rubato` streaming resampler to 16 kHz mono, `symphonia` file decoding, `hound` WAV I/O. | -| **`magnotia-transcription`** | `whisper-rs` backend (`WhisperRsBackend`) that owns a `WhisperContext` and supports `set_initial_prompt`. `LocalEngine` wraps both Whisper and Parakeet (via `transcribe-rs` ONNX) behind a common `Transcriber` trait. Streaming primitives (`VadChunker`, `LocalAgreement`, buffer trim) live in the `streaming/` module. Model manager handles downloads, paths, and disk checks. | -| **`magnotia-llm`** | `llama-cpp-2` engine with a four-tier Qwen3.5 / Qwen3.6 model manager. Three high-level surfaces: `cleanup_text` (formatting), `decompose_task` (3–7 micro-steps, GBNF-constrained JSON array), `extract_tasks` (optional-array, GBNF-constrained). Resumable HTTP downloads with SHA-256 verify. | -| **`magnotia-ai-formatting`** | Post-processing pipeline: filler removal, British English conversion, anti-hallucination filter, smart paragraph breaks on long pauses, optional LLM cleanup. Also hosts the `llm_client::CLEANUP_PROMPT` constant (prompt-injection-hardened). | -| **`magnotia-storage`** | SQLite via `sqlx` 0.8. Migrations, CRUD for transcripts / tasks / subtasks / profiles / profile terms / settings / error log, FTS5 search, file-storage paths. | -| **`magnotia-hotkey`** | Linux `evdev` hotkey listener with device hotplug. Parses Tauri-style hotkey strings (`Ctrl+Shift+R`), emits Pressed / Released events. Works natively on Wayland (no X11 dependency). Checks `/dev/input/event*` access on startup; surfaces a clear "add yourself to the `input` group" error when missing. | -| **`magnotia-cloud-providers`** | BYOK cloud-STT provider stubs. Currently empty scaffolding. When populated: OpenAI-compatible endpoint + Anthropic (ceiling for scope). | -| **`magnotia-mcp`** | Standalone `magnotia-mcp` binary implementing the MCP stdio protocol (2024-11-05). Read-only tools: `list_transcripts`, `get_transcript`, `search_transcripts`, `list_tasks`. Opens Magnotia's SQLite store. | +| **`lumotia-core`** | Shared types (`Segment`, `Transcript`, `Megabytes`, `ModelId`), constants, the `Engine` / `SpeedTier` / `AccuracyTier` enums, hardware probe (`sysinfo`-based), model registry (Whisper + Parakeet entries), hardware-aware recommendation scoring, `process_watch` for meeting detection. | +| **`lumotia-audio`** | `cpal`-based microphone capture with device hotplug + error forwarding, VAD, `rubato` streaming resampler to 16 kHz mono, `symphonia` file decoding, `hound` WAV I/O. | +| **`lumotia-transcription`** | `whisper-rs` backend (`WhisperRsBackend`) that owns a `WhisperContext` and supports `set_initial_prompt`. `LocalEngine` wraps both Whisper and Parakeet (via `transcribe-rs` ONNX) behind a common `Transcriber` trait. Streaming primitives (`VadChunker`, `LocalAgreement`, buffer trim) live in the `streaming/` module. Model manager handles downloads, paths, and disk checks. | +| **`lumotia-llm`** | `llama-cpp-2` engine with a four-tier Qwen3.5 / Qwen3.6 model manager. Three high-level surfaces: `cleanup_text` (formatting), `decompose_task` (3–7 micro-steps, GBNF-constrained JSON array), `extract_tasks` (optional-array, GBNF-constrained). Resumable HTTP downloads with SHA-256 verify. | +| **`lumotia-ai-formatting`** | Post-processing pipeline: filler removal, British English conversion, anti-hallucination filter, smart paragraph breaks on long pauses, optional LLM cleanup. Also hosts the `llm_client::CLEANUP_PROMPT` constant (prompt-injection-hardened). | +| **`lumotia-storage`** | SQLite via `sqlx` 0.8. Migrations, CRUD for transcripts / tasks / subtasks / profiles / profile terms / settings / error log, FTS5 search, file-storage paths. | +| **`lumotia-hotkey`** | Linux `evdev` hotkey listener with device hotplug. Parses Tauri-style hotkey strings (`Ctrl+Shift+R`), emits Pressed / Released events. Works natively on Wayland (no X11 dependency). Checks `/dev/input/event*` access on startup; surfaces a clear "add yourself to the `input` group" error when missing. | +| **`lumotia-cloud-providers`** | BYOK cloud-STT provider stubs. Currently empty scaffolding. When populated: OpenAI-compatible endpoint + Anthropic (ceiling for scope). | +| **`lumotia-mcp`** | Standalone `lumotia-mcp` binary implementing the MCP stdio protocol (2024-11-05). Read-only tools: `list_transcripts`, `get_transcript`, `search_transcripts`, `list_tasks`. Opens Lumotia's SQLite store. | ### Tauri commands (src-tauri/src/commands/) @@ -313,24 +313,24 @@ Beyond this README, the repo ships extensive internal documentation: ### Product + strategy — `docs/brief/` Research briefs, competitive analysis, and strategic framing. Start with: -- [`what-magnotia-is.md`](docs/brief/what-magnotia-is.md) — product thesis +- [`what-lumotia-is.md`](docs/brief/what-lumotia-is.md) — product thesis - [`why-current-tools-fail.md`](docs/brief/why-current-tools-fail.md) — market gap - [`design-principles.md`](docs/brief/design-principles.md) — full principle list - [`target-audience.md`](docs/brief/target-audience.md), [`market-size-demographics.md`](docs/brief/market-size-demographics.md) - Appendices on cognitive ergonomics, AI body doubling, evolutionary psychology, implementation intentions, HITL scaffolding, voice interfaces ### Brand — `docs/brand/` -- [`magnotia-brand-guidelines.md`](docs/brand/magnotia-brand-guidelines.md) -- [`magnotia-brand-platform.md`](docs/brand/magnotia-brand-platform.md) +- [`lumotia-brand-guidelines.md`](docs/brand/lumotia-brand-guidelines.md) +- [`lumotia-brand-platform.md`](docs/brand/lumotia-brand-platform.md) ### Technical research — `docs/whisper-ecosystem/` -Cross-repo survey of 10 OSS Whisper projects, the Magnotia-specific atomic task backlog, and the two Cursor workstream plans. +Cross-repo survey of 10 OSS Whisper projects, the Lumotia-specific atomic task backlog, and the two Cursor workstream plans. - [`brief.md`](docs/whisper-ecosystem/brief.md) — 31-item task backlog (the canonical research spec) -- [`magnotia-context.md`](docs/whisper-ecosystem/magnotia-context.md) — ideology, shipped state, file-ownership fence for cloud AI agents +- [`lumotia-context.md`](docs/whisper-ecosystem/lumotia-context.md) — ideology, shipped state, file-ownership fence for cloud AI agents - [`workstream-A.md`](docs/whisper-ecosystem/workstream-A.md), [`workstream-B.md`](docs/whisper-ecosystem/workstream-B.md) — executed workstream plans ### GPU tuning — `docs/gpu-tuning/` -- [`plan.md`](docs/gpu-tuning/plan.md) — MVP plan for GGML env-var panel + `magnotia-bench` auto-tuner + `magnotia-configs` community repo +- [`plan.md`](docs/gpu-tuning/plan.md) — MVP plan for GGML env-var panel + `lumotia-bench` auto-tuner + `lumotia-configs` community repo ### Session handovers - [`HANDOVER.md`](HANDOVER.md) — latest session summary @@ -352,7 +352,7 @@ Pinned roadmap items (scoped in docs and session memory): - **Phase 4** — remaining items from [`workstream-A.md`](docs/whisper-ecosystem/workstream-A.md) + [`workstream-B.md`](docs/whisper-ecosystem/workstream-B.md) - **Voice calibration** — three-tier plan replacing the hardcoded speech-gate with per-user baselines - **GPU community tuning** — see [`docs/gpu-tuning/plan.md`](docs/gpu-tuning/plan.md); five-phase roadmap from settings panel to agentic auto-tuner + community config repo -- **Cloud endpoint contract test** — when `magnotia-cloud-providers` grows a real provider +- **Cloud endpoint contract test** — when `lumotia-cloud-providers` grows a real provider - **`ggml` dedup** — replace the interim `-Wl,--allow-multiple-definition` link flag with a proper shared-lib setup; unblocks custom shader / backend work - **Mobile (iOS / Android)** — long-horizon, gated on the single-binary Rust stack scaling @@ -360,7 +360,7 @@ Explicitly shelved (not coming without specific community signal): - Wake-word / always-listening agent - Chat-style LLM UI - Multi-provider cloud fan-out beyond OpenAI-compatible + Anthropic -- Second notes-editing surface (transcripts leave Magnotia via frontmatter to Obsidian) +- Second notes-editing surface (transcripts leave Lumotia via frontmatter to Obsidian) - Speaker diarization - Dragon-style passage-based speaker fine-tuning (Whisper has no speaker adaptation) @@ -387,4 +387,4 @@ To be finalised before public beta. Current intent: MIT or similar permissive li ## Contact **Jake Sames** — [jakeadriansames@gmail.com](mailto:jakeadriansames@gmail.com) -Repo: [github.com/jakejars/magnotia](https://github.com/jakejars/magnotia) · [git.corbel.consulting/jake/magnotia](https://git.corbel.consulting/jake/magnotia) +Repo: [github.com/jakejars/lumotia](https://github.com/jakejars/lumotia) · [git.corbel.consulting/jake/lumotia](https://git.corbel.consulting/jake/lumotia) diff --git a/crates/ai-formatting/Cargo.toml b/crates/ai-formatting/Cargo.toml index c5ddd1a..3ebf0d6 100644 --- a/crates/ai-formatting/Cargo.toml +++ b/crates/ai-formatting/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-ai-formatting" version = "0.1.0" edition = "2021" -description = "Text post-processing pipeline: filler removal, British English conversion, formatting for Magnotia" +description = "Text post-processing pipeline: filler removal, British English conversion, formatting for Lumotia" [dependencies] lumotia-core = { path = "../core" } diff --git a/crates/ai-formatting/src/llm_client.rs b/crates/ai-formatting/src/llm_client.rs index 01e85ff..94b9e73 100644 --- a/crates/ai-formatting/src/llm_client.rs +++ b/crates/ai-formatting/src/llm_client.rs @@ -13,7 +13,7 @@ use lumotia_llm::{EngineError, LlmEngine}; /// Whispering's published baseline, directly counteracts the /// "LLM changed my meaning" failure mode: the model's job is to /// translate spoken speech into well-formed written form — not to -/// improve, summarise, or rephrase. Magnotia's ideology: raw transcript +/// improve, summarise, or rephrase. Lumotia's ideology: raw transcript /// is the source of truth; cleanup is a translation pass, not a /// rewrite. /// 2. **Prompt-injection hardening.** The guard ("speech, not @@ -183,7 +183,7 @@ mod tests { assert!(CLEANUP_PROMPT.contains("output ONLY the cleaned transcript")); } - /// The "translator, not editor" framing is load-bearing for Magnotia's + /// The "translator, not editor" framing is load-bearing for Lumotia's /// ideology — raw transcript is the source of truth, cleanup is a /// translation pass. Drifting from this phrasing in a refactor would /// quietly open the door to the "LLM changed my meaning" failure diff --git a/crates/ai-formatting/src/to_plain_text.rs b/crates/ai-formatting/src/to_plain_text.rs index 24a938f..351ee0a 100644 --- a/crates/ai-formatting/src/to_plain_text.rs +++ b/crates/ai-formatting/src/to_plain_text.rs @@ -7,7 +7,7 @@ //! structure) degraded cleanup quality materially; plain-text input //! raised it back. //! -//! `Segment.text` in Magnotia already holds just the spoken text (the +//! `Segment.text` in Lumotia already holds just the spoken text (the //! `start`/`end` f64 fields carry the timing), so "timestamp //! stripping" falls out of using the text field alone. The work here //! is the whitespace pass and empty-segment filter, plus a single diff --git a/crates/audio/Cargo.toml b/crates/audio/Cargo.toml index ca971e6..21cc340 100644 --- a/crates/audio/Cargo.toml +++ b/crates/audio/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-audio" version = "0.1.0" edition = "2021" -description = "Audio capture (cpal), VAD, resampling (rubato), file decoding (symphonia), WAV I/O (hound) for Magnotia" +description = "Audio capture (cpal), VAD, resampling (rubato), file decoding (symphonia), WAV I/O (hound) for Lumotia" [dependencies] lumotia-core = { path = "../core" } diff --git a/crates/audio/src/wav.rs b/crates/audio/src/wav.rs index ce300bb..a71aab3 100644 --- a/crates/audio/src/wav.rs +++ b/crates/audio/src/wav.rs @@ -172,7 +172,7 @@ mod tests { fn wav_writer_survives_crash() { // Property under test: a `WavWriter` that has been flushed but // never finalised leaves a valid, readable WAV on disk. This - // is the crash-safety guarantee — if the magnotia process aborts + // is the crash-safety guarantee — if the lumotia process aborts // mid-session, the on-disk file up to the last flush is // recoverable. // diff --git a/crates/cloud-providers/Cargo.toml b/crates/cloud-providers/Cargo.toml index 248a7a4..4760584 100644 --- a/crates/cloud-providers/Cargo.toml +++ b/crates/cloud-providers/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-cloud-providers" version = "0.1.0" edition = "2021" -description = "Provider trait and BYOK cloud STT scaffolding for Magnotia (Wyrdnote pending rebrand)" +description = "Provider trait and BYOK cloud STT scaffolding for Lumotia (Wyrdnote pending rebrand)" [dependencies] lumotia-core = { path = "../core" } diff --git a/crates/cloud-providers/src/keystore.rs b/crates/cloud-providers/src/keystore.rs index 0b4757d..cf9bd53 100644 --- a/crates/cloud-providers/src/keystore.rs +++ b/crates/cloud-providers/src/keystore.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use std::sync::{Mutex, OnceLock}; -/// Store an API key in Magnotia's process-local keystore. +/// Store an API key in Lumotia's process-local keystore. /// /// Keys are held in memory for the lifetime of the process and are lost on /// exit. This avoids the undefined behaviour of mutating process environment @@ -19,7 +19,7 @@ pub fn store_api_key(provider: &str, key: &str) { .insert(provider_env_key(provider), key.to_string()); } -/// Retrieve an API key from Magnotia's process-local keystore. +/// Retrieve an API key from Lumotia's process-local keystore. /// /// Returns a previously stored in-memory key when present, otherwise falls /// back to the read-only `LUMOTIA_API_KEY_` environment variable so diff --git a/crates/core/Cargo.toml b/crates/core/Cargo.toml index dc65e6a..10477e9 100644 --- a/crates/core/Cargo.toml +++ b/crates/core/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-core" version = "0.1.0" edition = "2021" -description = "Core types, constants, traits, hardware detection, and model registry for Magnotia" +description = "Core types, constants, traits, hardware detection, and model registry for Lumotia" [dependencies] serde = { version = "1", features = ["derive"] } diff --git a/crates/core/src/error.rs b/crates/core/src/error.rs index e45d09f..dcbb440 100644 --- a/crates/core/src/error.rs +++ b/crates/core/src/error.rs @@ -4,7 +4,7 @@ use serde::Serialize; use crate::types::ModelId; -/// Structured error type for Magnotia. +/// Structured error type for Lumotia. /// /// Implements `Serialize` so errors can be sent to the frontend as /// structured JSON rather than opaque strings. diff --git a/crates/core/src/hardware.rs b/crates/core/src/hardware.rs index 1fa2766..f2f79ef 100644 --- a/crates/core/src/hardware.rs +++ b/crates/core/src/hardware.rs @@ -19,7 +19,7 @@ pub struct CpuInfo { } /// Runtime-detected CPU feature flags relevant to the speech-to-text -/// and LLM backends Magnotia ships. All whisper.cpp / llama.cpp / ggml +/// and LLM backends Lumotia ships. All whisper.cpp / llama.cpp / ggml /// kernels degrade roughly two tiers without AVX2, which is why we /// surface it separately: when AVX2 is absent, the UI should warn the /// user that performance will be a fraction of what they would see diff --git a/crates/core/src/recommendation.rs b/crates/core/src/recommendation.rs index 4790d04..68f3de3 100644 --- a/crates/core/src/recommendation.rs +++ b/crates/core/src/recommendation.rs @@ -184,7 +184,7 @@ mod tests { fn parakeet_is_top_recommendation_when_hardware_supports_it() { // Any machine that fits Parakeet in RAM should see it ranked first — // Parakeet-TDT is English-only but beats Whisper on English at lower - // latency, so it's Magnotia's default recommendation when eligible. + // latency, so it's Lumotia's default recommendation when eligible. // (Users on non-English languages adjust manually — handled at the // settings-UI level, not at the scoring level for now.) let profile = profile_with_ram(Megabytes(16384)); diff --git a/crates/hotkey/Cargo.toml b/crates/hotkey/Cargo.toml index 3487ab5..316ab80 100644 --- a/crates/hotkey/Cargo.toml +++ b/crates/hotkey/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-hotkey" version = "0.1.0" edition = "2021" -description = "Wayland-compatible global hotkey listener for Magnotia — evdev backend with device hotplug" +description = "Wayland-compatible global hotkey listener for Lumotia — evdev backend with device hotplug" [dependencies] lumotia-core = { path = "../core" } diff --git a/crates/hotkey/src/lib.rs b/crates/hotkey/src/lib.rs index 21b6662..9ebdac0 100644 --- a/crates/hotkey/src/lib.rs +++ b/crates/hotkey/src/lib.rs @@ -1,4 +1,4 @@ -//! Wayland-compatible global hotkey listener for Magnotia. +//! Wayland-compatible global hotkey listener for Lumotia. //! //! On Linux, reads `/dev/input/event*` devices via the `evdev` crate to capture //! global hotkeys without any display-server dependency. This works on both X11 @@ -8,7 +8,7 @@ //! On non-Linux platforms, this crate is a no-op — the Tauri global-shortcut //! plugin handles hotkeys there. //! -//! Architecture stolen from oddlama/whisper-overlay and adapted for Magnotia. +//! Architecture stolen from oddlama/whisper-overlay and adapted for Lumotia. #[cfg(target_os = "linux")] mod linux; diff --git a/crates/llm/Cargo.toml b/crates/llm/Cargo.toml index 7b9a869..a5796f6 100644 --- a/crates/llm/Cargo.toml +++ b/crates/llm/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-llm" version = "0.1.0" edition = "2021" -description = "Local LLM engine for Magnotia (Qwen3.5 / Qwen3.6 via llama-cpp-2): transcript cleanup, task extraction, micro-step decomposition" +description = "Local LLM engine for Lumotia (Qwen3.5 / Qwen3.6 via llama-cpp-2): transcript cleanup, task extraction, micro-step decomposition" [features] # Default desktop build keeps the existing openmp + vulkan acceleration. diff --git a/crates/llm/src/model_manager.rs b/crates/llm/src/model_manager.rs index d6ed932..9cabe17 100644 --- a/crates/llm/src/model_manager.rs +++ b/crates/llm/src/model_manager.rs @@ -321,7 +321,7 @@ where .unwrap_or(0); let client = reqwest::Client::builder() - .user_agent("magnotia/0.1.0") + .user_agent("lumotia/0.1.0") .connect_timeout(std::time::Duration::from_secs(30)) .build() .map_err(|e| DownloadError::Http(e.to_string()))?; diff --git a/crates/mcp/Cargo.toml b/crates/mcp/Cargo.toml index 863b624..2439b0a 100644 --- a/crates/mcp/Cargo.toml +++ b/crates/mcp/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-mcp" version = "0.1.0" edition = "2021" -description = "Read-only MCP stdio server exposing Magnotia transcripts and tasks to external agents" +description = "Read-only MCP stdio server exposing Lumotia transcripts and tasks to external agents" [[bin]] name = "lumotia-mcp" diff --git a/crates/mcp/src/lib.rs b/crates/mcp/src/lib.rs index d4c0715..c166e10 100644 --- a/crates/mcp/src/lib.rs +++ b/crates/mcp/src/lib.rs @@ -1,8 +1,8 @@ -//! Minimal Model Context Protocol server exposing Magnotia's local SQLite store. +//! Minimal Model Context Protocol server exposing Lumotia's local SQLite store. //! //! Scope: **read-only** tools. An external agent (Claude desktop, Cline, any //! MCP-capable client) can list / search / fetch transcripts and list tasks. -//! No writes — Magnotia's Tauri app remains the only writer. +//! No writes — Lumotia's Tauri app remains the only writer. //! //! Transport: newline-delimited JSON-RPC 2.0 over stdio, per the stdio //! transport spec. Server spec version: 2024-11-05. @@ -95,7 +95,7 @@ fn initialize_result() -> Value { "version": SERVER_VERSION, }, "instructions": - "Read-only access to Magnotia's local transcript history and task list. \ + "Read-only access to Lumotia's local transcript history and task list. \ All data stays on the user's machine.", }) } @@ -105,7 +105,7 @@ fn tools_list_result() -> Value { "tools": [ { "name": "list_transcripts", - "description": "List recent transcripts from Magnotia's local history, most recent first. \ + "description": "List recent transcripts from Lumotia's local history, most recent first. \ Returns summaries (id, title, created_at, duration, preview).", "inputSchema": { "type": "object", @@ -135,7 +135,7 @@ fn tools_list_result() -> Value { }, { "name": "search_transcripts", - "description": "Full-text search across Magnotia's transcripts. Returns matching summaries.", + "description": "Full-text search across Lumotia's transcripts. Returns matching summaries.", "inputSchema": { "type": "object", "required": ["query"], @@ -155,7 +155,7 @@ fn tools_list_result() -> Value { }, { "name": "list_tasks", - "description": "List tasks from Magnotia's task store. Returns both open and completed.", + "description": "List tasks from Lumotia's task store. Returns both open and completed.", "inputSchema": { "type": "object", "properties": {}, diff --git a/crates/storage/Cargo.toml b/crates/storage/Cargo.toml index 4c03ca9..4442f32 100644 --- a/crates/storage/Cargo.toml +++ b/crates/storage/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-storage" version = "0.1.0" edition = "2021" -description = "SQLite persistence, BM25 search, and file storage for Magnotia" +description = "SQLite persistence, BM25 search, and file storage for Lumotia" [dependencies] lumotia-core = { path = "../core" } diff --git a/crates/storage/src/database.rs b/crates/storage/src/database.rs index d3d9fab..c5cde2e 100644 --- a/crates/storage/src/database.rs +++ b/crates/storage/src/database.rs @@ -905,14 +905,14 @@ pub async fn get_setting(pool: &SqlitePool, key: &str) -> Result> Ok(row.map(|r| r.get("value"))) } -/// One-shot key rename for settings rows carried over from the magnotia era +/// One-shot key rename for settings rows carried over from the lumotia era /// (`magnotia_preferences`, `magnotia_morning_triage_last_shown`, etc.). /// /// Idempotent. Returns `(renamed, orphans_deleted)`: -/// * `renamed` — rows where only the magnotia key existed; the row's key +/// * `renamed` — rows where only the lumotia key existed; the row's key /// is updated to the lumotia equivalent. /// * `orphans_deleted` — rows where BOTH keys existed; the lumotia row is -/// authoritative and the magnotia row is deleted to avoid silent debt. +/// authoritative and the lumotia row is deleted to avoid silent debt. pub async fn migrate_legacy_setting_keys(pool: &SqlitePool) -> Result<(u64, u64)> { let mut tx = pool.begin().await.map_err(|source| Error::Query { operation: "migrate_legacy_setting_keys:begin".into(), @@ -2830,7 +2830,7 @@ mod tests { assert_eq!( get_setting(&pool, "magnotia_preferences").await.unwrap(), None, - "orphan magnotia row deleted" + "orphan lumotia row deleted" ); } diff --git a/crates/storage/src/file_storage.rs b/crates/storage/src/file_storage.rs index 53c1265..89ef059 100644 --- a/crates/storage/src/file_storage.rs +++ b/crates/storage/src/file_storage.rs @@ -21,7 +21,7 @@ pub fn crashes_dir() -> PathBuf { lumotia_core::paths::app_paths().crashes_dir() } -/// Directory for the rolling Rust log file (magnotia.log + rotated magnotia.log.1, etc). +/// Directory for the rolling Rust log file (lumotia.log + rotated lumotia.log.1, etc). /// Subscribers configured in src-tauri/src/lib.rs at startup. pub fn logs_dir() -> PathBuf { lumotia_core::paths::app_paths().logs_dir() diff --git a/crates/storage/src/migrations.rs b/crates/storage/src/migrations.rs index c830bf4..cee57ea 100644 --- a/crates/storage/src/migrations.rs +++ b/crates/storage/src/migrations.rs @@ -963,7 +963,7 @@ mod tests { // dictionary.id is INTEGER PK AUTOINCREMENT (see v2); let SQLite assign rowids. sqlx::query( "INSERT INTO dictionary (term, note, created_at) VALUES \ - ('Magnotia', '', datetime('now')), \ + ('Lumotia', '', datetime('now')), \ ('CORBEL', 'brand', datetime('now')), \ ('Wren', '', datetime('now'))", ) diff --git a/crates/transcription/Cargo.toml b/crates/transcription/Cargo.toml index fd73017..31bdc76 100644 --- a/crates/transcription/Cargo.toml +++ b/crates/transcription/Cargo.toml @@ -2,7 +2,7 @@ name = "lumotia-transcription" version = "0.1.0" edition = "2021" -description = "Speech-to-text engine wrappers, model management, and inference concurrency for Magnotia" +description = "Speech-to-text engine wrappers, model management, and inference concurrency for Lumotia" build = "build.rs" [features] diff --git a/crates/transcription/src/local_engine.rs b/crates/transcription/src/local_engine.rs index 6195bce..ff7c0bd 100644 --- a/crates/transcription/src/local_engine.rs +++ b/crates/transcription/src/local_engine.rs @@ -160,7 +160,7 @@ impl LocalEngine { /// Thin wrapper over `ParakeetModel` that overrides `transcribe_raw` to /// request word-granularity segments. `transcribe-rs` 0.3's trait impl for /// `ParakeetModel::transcribe_raw` ignores `TranscribeOptions` and uses -/// `TimestampGranularity::Token` (per-subword) — which surfaces in Magnotia as +/// `TimestampGranularity::Token` (per-subword) — which surfaces in Lumotia as /// "T Est Ing . One , Two , Three" output. The concrete-type method /// `ParakeetModel::transcribe_with` accepts `ParakeetParams` with an /// explicit granularity; this wrapper exposes that to the trait object. diff --git a/crates/transcription/src/model_manager.rs b/crates/transcription/src/model_manager.rs index c42b5a6..51a2843 100644 --- a/crates/transcription/src/model_manager.rs +++ b/crates/transcription/src/model_manager.rs @@ -37,8 +37,8 @@ impl Drop for DownloadReservation { } /// Resolve the models storage directory. -/// Windows: %LOCALAPPDATA%/magnotia/models -/// Unix: ~/.magnotia/models +/// Windows: %LOCALAPPDATA%/lumotia/models +/// Unix: ~/.lumotia/models pub fn models_dir() -> PathBuf { lumotia_core::paths::app_paths().models_dir() } diff --git a/docs/architecture-map/01-frontend/README.md b/docs/architecture-map/01-frontend/README.md index 8b9dab3..fa22ffb 100644 --- a/docs/architecture-map/01-frontend/README.md +++ b/docs/architecture-map/01-frontend/README.md @@ -18,7 +18,7 @@ last_verified: 2026/05/09 - **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`). +- **Persistence used directly by frontend:** `localStorage` for `lumotia_settings`, `lumotia_profiles`, `lumotia_task_lists`, `lumotia_templates`, `lumotia_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 @@ -44,21 +44,21 @@ last_verified: 2026/05/09 **In (frontend depends on Tauri runtime, slice 02).** - Sixty plus distinct `invoke()` commands. Full list with caller in [frontend-tauri-bridge.md](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`). +- Tauri events listened to: `model-download-progress`, `parakeet-download-progress`, `lumotia:llm-download-progress`, `lumotia:hotkey-pressed`, `lumotia:open-wind-down`, `lumotia: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. +- DOM `CustomEvent` bus on `window` carries internal traffic (`lumotia:start-timer`, `lumotia:toggle-recording`, `lumotia:task-completed`, etc). The Rust side does not listen to these; they are intra frontend. +- Tauri `emit()` is used for `lumotia: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 04 (LLM, formatting, MCP) emits `lumotia: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) @@ -80,7 +80,7 @@ This slice index is the navigation hub. The map files referenced above carry the 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. +6. **Cross window settings sync uses `localStorage` `storage` events.** `float/+layout@.svelte` listens for `storage` to apply settings, while preferences use the dedicated `lumotia: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. diff --git a/docs/architecture-map/01-frontend/actions-utils-types.md b/docs/architecture-map/01-frontend/actions-utils-types.md index 299230e..9e14765 100644 --- a/docs/architecture-map/01-frontend/actions-utils-types.md +++ b/docs/architecture-map/01-frontend/actions-utils-types.md @@ -39,7 +39,7 @@ Caches OS info via `invoke("os_info")` (or similar; check `lib.rs`). Exposes `lo ### `settingsMigrations.ts` (134 LOC) -Versioned migrations for `magnotia_settings`. Holds `CURRENT_SETTINGS_VERSION = 1`. Envelope shape: `{ version: number, data: T }`. Reads bare unversioned blobs as v0. `loadSettingsWithMigration(key, defaults)` walks the chain and toasts on corruption. +Versioned migrations for `lumotia_settings`. Holds `CURRENT_SETTINGS_VERSION = 1`. Envelope shape: `{ version: number, data: T }`. Reads bare unversioned blobs as v0. `loadSettingsWithMigration(key, defaults)` walks the chain and toasts on corruption. ### `frontmatter.ts` (148 LOC) diff --git a/docs/architecture-map/01-frontend/app-shell-and-styling.md b/docs/architecture-map/01-frontend/app-shell-and-styling.md index 6a8777d..941ee76 100644 --- a/docs/architecture-map/01-frontend/app-shell-and-styling.md +++ b/docs/architecture-map/01-frontend/app-shell-and-styling.md @@ -22,7 +22,7 @@ last_verified: 2026/05/09 ### `src/app.html` (13 LOC) -Standard SvelteKit document. Sets `lang="en"`, charset, viewport, favicon, title (`Magnotia`), and applies `data-sveltekit-preload-data="hover"` on ``. The body content is wrapped in `
` so the SvelteKit-injected children render inline. +Standard SvelteKit document. Sets `lang="en"`, charset, viewport, favicon, title (`Lumotia`), and applies `data-sveltekit-preload-data="hover"` on ``. The body content is wrapped in `
` so the SvelteKit-injected children render inline. ### `src/app.d.ts` (8 LOC) diff --git a/docs/architecture-map/01-frontend/components.md b/docs/architecture-map/01-frontend/components.md index 74cbca3..c28d8a7 100644 --- a/docs/architecture-map/01-frontend/components.md +++ b/docs/architecture-map/01-frontend/components.md @@ -25,7 +25,7 @@ last_verified: 2026/05/09 | `Titlebar` | 80 | `src/lib/components/Titlebar.svelte` | Custom window chrome for non Linux (frameless windows). Min/max/close + drag area + sidebar aligned spacer. | | `ToastViewport` | 143 | `src/lib/components/ToastViewport.svelte` | Bottom right toast stack. Reads from the global `toasts` store. Honours `prefers-reduced-motion`. | | `ResizeHandles` | 67 | `src/lib/components/ResizeHandles.svelte` | Invisible 5 px margins for frameless resize. Linux uses native, so `+layout.svelte` suppresses this. | -| `FocusTimer` | 298 | `src/lib/components/FocusTimer.svelte` | Floating top right SVG progress ring. Listens for `magnotia:start-timer` window events and delegates to the focus timer store. Cancel hover, success flourish. Hidden on float and viewer windows by URL probe. | +| `FocusTimer` | 298 | `src/lib/components/FocusTimer.svelte` | Floating top right SVG progress ring. Listens for `lumotia:start-timer` window events and delegates to the focus timer store. Cancel hover, success flourish. Hidden on float and viewer windows by URL probe. | | `MorningTriageModal` | 356 | `src/lib/components/MorningTriageModal.svelte` | Phase 5 modal. Self gated on `settings.ritualsMorning` and time of day. Mounted globally so it appears over any page. | | `TaskSidebar` | 97 | `src/lib/components/TaskSidebar.svelte` | Optional right side dock that appears when `page.taskSidebarOpen`. Quick add input, top tasks, link out to the full Tasks page. | @@ -54,8 +54,8 @@ last_verified: 2026/05/09 | Component | LOC | Purpose | |---|---|---| -| `WipTaskList` | 153 | Renders task rows with energy chips, completion checkbox, expansion to show micro steps, and a "start focus timer" button (dispatches `magnotia:start-timer`). | -| `MicroSteps` | 310 | Per task expansion: nudge bus integration, micro step suggestions from the LLM (`magnotia:microstep-generated`), step completion (`magnotia:step-completed`), per task implementation rules. | +| `WipTaskList` | 153 | Renders task rows with energy chips, completion checkbox, expansion to show micro steps, and a "start focus timer" button (dispatches `lumotia:start-timer`). | +| `MicroSteps` | 310 | Per task expansion: nudge bus integration, micro step suggestions from the LLM (`lumotia:microstep-generated`), step completion (`lumotia:step-completed`), per task implementation rules. | | `EnergyChip` | 106 | Low/medium/high energy selector. Used on task rows and in TasksPage quick add. | | `CompletionSparkline` | 92 | 7 day completion bar chart. Animated entrance with 30 ms stagger, respects `prefers-reduced-motion`. Reads from `recentCompletions` store. | | `VisualTimer` | 33 | Compact visual timer pill used inside MicroSteps and the float window. | diff --git a/docs/architecture-map/01-frontend/design-system.md b/docs/architecture-map/01-frontend/design-system.md index a05173a..5f7605d 100644 --- a/docs/architecture-map/01-frontend/design-system.md +++ b/docs/architecture-map/01-frontend/design-system.md @@ -9,14 +9,14 @@ last_verified: 2026/05/09 > **Where you are:** [Architecture map](../README.md) → [Frontend](README.md) → Design system -**Plain English summary.** Reference material. The runtime styles live in `src/app.css`. Everything under `src/design-system/` is brand documentation, preview pages, JSX UI kits, and ground truth source for the magnotia-design Claude skill. None of it is imported by the runtime SvelteKit app. +**Plain English summary.** Reference material. The runtime styles live in `src/app.css`. Everything under `src/design-system/` is brand documentation, preview pages, JSX UI kits, and ground truth source for the lumotia-design Claude skill. None of it is imported by the runtime SvelteKit app. ## At a glance - **Path:** `src/design-system/` - **Files:** - - `README.md`. Brand and content rules. (Magnotia by CORBEL.) - - `SKILL.md`. magnotia-design skill manifest (`user-invocable: true`). The skill copies assets out and writes throwaway HTML or production code on demand. + - `README.md`. Brand and content rules. (Lumotia by CORBEL.) + - `SKILL.md`. lumotia-design skill manifest (`user-invocable: true`). The skill copies assets out and writes throwaway HTML or production code on demand. - `colors_and_type.css`. Mirror of the runtime `@theme` tokens for buildless preview pages. Intentional duplication, kept in sync by hand. - `preview/`. 20 buildless HTML spec cards. - `ui_kits/`. JSX recreations (`DictationPage.jsx`, `OtherPages.jsx`, `Sidebar.jsx`) plus an `index.html` and a README. @@ -52,7 +52,7 @@ Three `.jsx` files plus `index.html` and a README. Reproduce the desktop pages i ## Why it lives in `src/` -The design system files sit under `src/` so the magnotia-design skill (which runs from this repo) can read ground-truth Svelte source from `magnotia-source/` (a sibling import). The runtime build does not include this folder; it is a reference root. +The design system files sit under `src/` so the lumotia-design skill (which runs from this repo) can read ground-truth Svelte source from `lumotia-source/` (a sibling import). The runtime build does not include this folder; it is a reference root. ## Watch outs diff --git a/docs/architecture-map/01-frontend/frontend-tauri-bridge.md b/docs/architecture-map/01-frontend/frontend-tauri-bridge.md index 57d887a..e9f0760 100644 --- a/docs/architecture-map/01-frontend/frontend-tauri-bridge.md +++ b/docs/architecture-map/01-frontend/frontend-tauri-bridge.md @@ -15,8 +15,8 @@ last_verified: 2026/05/09 - **Direction in (Rust → frontend):** events listed under "Tauri events listened to". - **Direction out (frontend → Rust):** all `invoke()` commands listed under "Tauri commands invoked". -- **DOM-only events:** `magnotia:*` `CustomEvent`s on `window`. These never cross the Rust boundary. -- **Cross-window event:** `magnotia:preferences-changed` is the only one that goes through `emit()`. +- **DOM-only events:** `lumotia:*` `CustomEvent`s on `window`. These never cross the Rust boundary. +- **Cross-window event:** `lumotia:preferences-changed` is the only one that goes through `emit()`. ## Tauri commands invoked (alphabetical) @@ -91,10 +91,10 @@ Plus any commands invoked by `saveMarkdown.ts` via the dialog/file-write plugin | Event | Listener | |---|---| -| `magnotia:hotkey-pressed` | `routes/+layout.svelte:177` (evdev backend) | -| `magnotia:llm-download-progress` | `pages/SettingsPage.svelte:873` | -| `magnotia:open-wind-down` | `routes/+layout.svelte:251` (tray menu hook) | -| `magnotia:preferences-changed` | `routes/+layout.svelte:263`, `routes/float/+layout@.svelte`, `routes/viewer/+layout@.svelte`, `routes/preview/+layout@.svelte:41` | +| `lumotia:hotkey-pressed` | `routes/+layout.svelte:177` (evdev backend) | +| `lumotia:llm-download-progress` | `pages/SettingsPage.svelte:873` | +| `lumotia:open-wind-down` | `routes/+layout.svelte:251` (tray menu hook) | +| `lumotia:preferences-changed` | `routes/+layout.svelte:263`, `routes/float/+layout@.svelte`, `routes/viewer/+layout@.svelte`, `routes/preview/+layout@.svelte:41` | | `model-download-progress` | `pages/SettingsPage.svelte:864`, `pages/FirstRunPage.svelte:46`, `components/ModelDownloader.svelte:31` | | `parakeet-download-progress` | `pages/SettingsPage.svelte:880`, `pages/FirstRunPage.svelte:50` | | `preview-cleanup` | `routes/preview/+page.svelte:141` | @@ -109,28 +109,28 @@ Plus any commands invoked by `saveMarkdown.ts` via the dialog/file-write plugin | Event | Emitter | Purpose | |---|---|---| -| `magnotia:preferences-changed` | `stores/preferences.svelte.ts` (`broadcastPreferences`) | Cross-window preference sync. | +| `lumotia:preferences-changed` | `stores/preferences.svelte.ts` (`broadcastPreferences`) | Cross-window preference sync. | | `preview-append` | `pages/DictationPage.svelte:165` | Stream partial text to overlay window. | | `preview-listening` | `pages/DictationPage.svelte:381` | Tell overlay to enter listening state. | | `preview-cleanup` | `pages/DictationPage.svelte:531` | Tell overlay to enter cleanup state. | | `preview-final` | `pages/DictationPage.svelte:539` | Tell overlay to render final text. | | `preview-hide` | `pages/DictationPage.svelte:606` | Tell overlay to dismiss. | -## DOM-only `magnotia:*` window events (intra-frontend bus) +## DOM-only `lumotia:*` window events (intra-frontend bus) | Event | Dispatcher | Listener(s) | |---|---|---| -| `magnotia:focus-timer-cancelled` | `stores/focusTimer.svelte.ts` | `completionStats` (indirectly), components subscribed to focus timer. | -| `magnotia:focus-timer-complete` | `stores/focusTimer.svelte.ts` | Same as above. | -| `magnotia:implementation-rules-changed` | `stores/implementationIntentions.svelte.ts` | `ImplementationRulesEditor`. | -| `magnotia:microstep-generated` | `stores/nudgeBus.svelte.ts` (around micro step generation) | `MicroSteps.svelte`. | -| `magnotia:morning-triage-finished` | `MorningTriageModal.svelte` | `nudgeBus`. | -| `magnotia:start-timer` | `WipTaskList.svelte`, `MicroSteps.svelte` | `FocusTimer.svelte` + `focusTimer` store. | -| `magnotia:step-completed` | `MicroSteps.svelte` | `completionStats` refresh. | -| `magnotia:task-completed` | `stores/page.svelte.ts` (`completeTask`) | `completionStats`. | -| `magnotia:task-deleted` | `stores/page.svelte.ts` (`deleteTask`) | `completionStats`. | -| `magnotia:task-uncompleted` | `stores/page.svelte.ts` (`uncompleteTask`) | `completionStats`. | -| `magnotia:toggle-recording` | `routes/+layout.svelte` (after hotkey debounce, both backends) | `pages/DictationPage.svelte`. | +| `lumotia:focus-timer-cancelled` | `stores/focusTimer.svelte.ts` | `completionStats` (indirectly), components subscribed to focus timer. | +| `lumotia:focus-timer-complete` | `stores/focusTimer.svelte.ts` | Same as above. | +| `lumotia:implementation-rules-changed` | `stores/implementationIntentions.svelte.ts` | `ImplementationRulesEditor`. | +| `lumotia:microstep-generated` | `stores/nudgeBus.svelte.ts` (around micro step generation) | `MicroSteps.svelte`. | +| `lumotia:morning-triage-finished` | `MorningTriageModal.svelte` | `nudgeBus`. | +| `lumotia:start-timer` | `WipTaskList.svelte`, `MicroSteps.svelte` | `FocusTimer.svelte` + `focusTimer` store. | +| `lumotia:step-completed` | `MicroSteps.svelte` | `completionStats` refresh. | +| `lumotia:task-completed` | `stores/page.svelte.ts` (`completeTask`) | `completionStats`. | +| `lumotia:task-deleted` | `stores/page.svelte.ts` (`deleteTask`) | `completionStats`. | +| `lumotia:task-uncompleted` | `stores/page.svelte.ts` (`uncompleteTask`) | `completionStats`. | +| `lumotia:toggle-recording` | `routes/+layout.svelte` (after hotkey debounce, both backends) | `pages/DictationPage.svelte`. | ## Window APIs @@ -151,8 +151,8 @@ Plus any commands invoked by `saveMarkdown.ts` via the dialog/file-write plugin ## Watch outs - The truncated grep returned `tts_s...` as a unique prefix. Verify every TTS command name (`tts_speak`, possibly `tts_stop`) against `lib.rs` to make sure the table above is exhaustive. -- The "preview-*" events have two flavours: `magnotia:` namespaced (`preferences-changed`) and bare (`preview-listening`, `preview-cleanup`, `preview-hide`, `preview-append`, `preview-final`). The bare names are scoped to the overlay window's two-way handshake. Do not rename. -- `magnotia:open-wind-down` listener is in `+layout.svelte` so the page opens regardless of which window the tray click came from. If you ever isolate windows further, this assumption breaks. +- The "preview-*" events have two flavours: `lumotia:` namespaced (`preferences-changed`) and bare (`preview-listening`, `preview-cleanup`, `preview-hide`, `preview-append`, `preview-final`). The bare names are scoped to the overlay window's two-way handshake. Do not rename. +- `lumotia:open-wind-down` listener is in `+layout.svelte` so the page opens regardless of which window the tray click came from. If you ever isolate windows further, this assumption breaks. - `task-window-focus` is the only event sent specifically to the float window. - DOM `CustomEvent` handlers do not survive across windows (they are window-local). The tasks list refresh trick on focus relies on this. diff --git a/docs/architecture-map/01-frontend/i18n.md b/docs/architecture-map/01-frontend/i18n.md index 16fc971..e176b05 100644 --- a/docs/architecture-map/01-frontend/i18n.md +++ b/docs/architecture-map/01-frontend/i18n.md @@ -38,7 +38,7 @@ export const SUPPORTED_LOCALES: { code: Locale; label: string }[] = [ { code: "de", label: "Deutsch" }, ]; -const STORAGE_KEY = "magnotia_locale"; +const STORAGE_KEY = "lumotia_locale"; register("en", () => import("./locales/en.json")); register("es", () => import("./locales/es.json")); @@ -49,7 +49,7 @@ function detectInitialLocale(): Locale { /* localStorage → navigator.language Public exports: - `initI18n()`. Idempotent. Called from every layout's `onMount`-ish path (`+layout.svelte:38` and the float/viewer/preview break layouts). -- `setLocale(code)`. Writes to `magnotia_locale` and updates the svelte-i18n store. +- `setLocale(code)`. Writes to `lumotia_locale` and updates the svelte-i18n store. - `currentLocale`. A derived store that components subscribe to via `$currentLocale`. - `SUPPORTED_LOCALES` constant for the picker. @@ -65,7 +65,7 @@ Public exports: ## Watch outs - Adding a new locale is one `register("xx", () => import("./locales/xx.json"))` call plus a `SUPPORTED_LOCALES` entry. -- Cross window: each window initialises i18n independently via its layout. Locale change persists to `localStorage["magnotia_locale"]`. Float and viewer pick up the new locale on the next mount, not live. Worth wiring a Tauri event if live cross-window translation is needed. +- Cross window: each window initialises i18n independently via its layout. Locale change persists to `localStorage["lumotia_locale"]`. Float and viewer pick up the new locale on the next mount, not live. Worth wiring a Tauri event if live cross-window translation is needed. - The "British English" toggle in `settings.britishEnglish` is a transcription post-processing flag (slice 04 territory), not a UI locale. Not wired through svelte-i18n. - Default locale is detected from `navigator.language`. In Tauri, this is the OS locale. diff --git a/docs/architecture-map/01-frontend/pages-overview.md b/docs/architecture-map/01-frontend/pages-overview.md index cca56b8..43f97a8 100644 --- a/docs/architecture-map/01-frontend/pages-overview.md +++ b/docs/architecture-map/01-frontend/pages-overview.md @@ -9,7 +9,7 @@ last_verified: 2026/05/09 > **Where you are:** [Architecture map](../README.md) → [Frontend](README.md) → Pages overview -**Plain English summary.** Magnotia has seven main window pages and three secondary window pages. The main window picks which to show by reading `page.current` (a string in the `page` store) and rendering the matching component. The secondary windows are routed by URL (`/float`, `/viewer`, `/preview`). +**Plain English summary.** Lumotia has seven main window pages and three secondary window pages. The main window picks which to show by reading `page.current` (a string in the `page` store) and rendering the matching component. The secondary windows are routed by URL (`/float`, `/viewer`, `/preview`). ## At a glance @@ -31,7 +31,7 @@ last_verified: 2026/05/09 | Tasks | `src/lib/pages/TasksPage.svelte` | 725 | Inbox/today/soon/later board with energy chips, lists, completion sparkline. | | Files | `src/lib/pages/FilesPage.svelte` | 263 | Drop or browse audio/video files. Calls `transcribe_file`. | | First run | `src/lib/pages/FirstRunPage.svelte` | 337 | Hardware probe (`probe_system`), model recommendation, model download. Auto exits to dictation. | -| Shutdown ritual | `src/lib/pages/ShutdownRitualPage.svelte` | 169 | Evening wind down ritual. Triggered from the tray menu via `magnotia:open-wind-down`. | +| Shutdown ritual | `src/lib/pages/ShutdownRitualPage.svelte` | 169 | Evening wind down ritual. Triggered from the tray menu via `lumotia:open-wind-down`. | ### Secondary windows (URL routed) diff --git a/docs/architecture-map/01-frontend/pages/dictation.md b/docs/architecture-map/01-frontend/pages/dictation.md index eb7176e..6f37c85 100644 --- a/docs/architecture-map/01-frontend/pages/dictation.md +++ b/docs/architecture-map/01-frontend/pages/dictation.md @@ -39,12 +39,12 @@ last_verified: 2026/05/09 ### 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). +- `onMount`. Loads `runtimeCapabilities` (`DictationPage.svelte:134`). Sets up the global hotkey custom event listener (`lumotia: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. +1. Toggle from the mic button or the `lumotia: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` 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. diff --git a/docs/architecture-map/01-frontend/pages/first-run.md b/docs/architecture-map/01-frontend/pages/first-run.md index 7c26b26..ba85f63 100644 --- a/docs/architecture-map/01-frontend/pages/first-run.md +++ b/docs/architecture-map/01-frontend/pages/first-run.md @@ -9,7 +9,7 @@ last_verified: 2026/05/09 > **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. +**Plain English summary.** What the user sees the first time they launch Lumotia, 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 diff --git a/docs/architecture-map/01-frontend/pages/settings.md b/docs/architecture-map/01-frontend/pages/settings.md index f23993a..0e2ac12 100644 --- a/docs/architecture-map/01-frontend/pages/settings.md +++ b/docs/architecture-map/01-frontend/pages/settings.md @@ -47,13 +47,13 @@ Built from `SettingsGroup` accordions. Top level groups (line refs are anchors i - `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`). +- Three concurrent download progress listeners: Whisper (`model-download-progress`), Parakeet (`parakeet-download-progress`), LLM (`lumotia: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`. +Events listened to: `model-download-progress`, `parakeet-download-progress`, `lumotia:llm-download-progress`. ## Watch outs diff --git a/docs/architecture-map/01-frontend/pages/tasks.md b/docs/architecture-map/01-frontend/pages/tasks.md index defd297..e0d3c0a 100644 --- a/docs/architecture-map/01-frontend/pages/tasks.md +++ b/docs/architecture-map/01-frontend/pages/tasks.md @@ -43,7 +43,7 @@ last_verified: 2026/05/09 ### 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. +- Listens implicitly to: `lumotia:task-completed`, `lumotia:task-uncompleted`, `lumotia:task-deleted`, `lumotia:step-completed` are emitted from store helpers and consumed by `completionStats.svelte.ts` to refresh the sparkline. ## Tauri command surface (direct) @@ -54,7 +54,7 @@ The store helpers used here call into Rust through `add_task_cmd`, `complete_tas ## 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. +- The sparkline is gated on `settings.showMomentumSparkline` (true by default). It re renders on the four `lumotia: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. diff --git a/docs/architecture-map/01-frontend/stores.md b/docs/architecture-map/01-frontend/stores.md index 6038668..99bbb1f 100644 --- a/docs/architecture-map/01-frontend/stores.md +++ b/docs/architecture-map/01-frontend/stores.md @@ -9,7 +9,7 @@ last_verified: 2026/05/09 > **Where you are:** [Architecture map](../README.md) → [Frontend](README.md) → Stores -**Plain English summary.** Reactive state. Magnotia uses Svelte 5 runes (`$state`, `$derived`, `$effect`) instead of legacy stores. Each file under `src/lib/stores/` exports one (or more) `$state` objects plus the helper functions that read or mutate them. Components import the state directly and Svelte tracks reactivity automatically. Two persistence channels: `localStorage` for settings, profiles, task lists, templates; Tauri (`save_preferences`) for accessibility preferences. +**Plain English summary.** Reactive state. Lumotia uses Svelte 5 runes (`$state`, `$derived`, `$effect`) instead of legacy stores. Each file under `src/lib/stores/` exports one (or more) `$state` objects plus the helper functions that read or mutate them. Components import the state directly and Svelte tracks reactivity automatically. Two persistence channels: `localStorage` for settings, profiles, task lists, templates; Tauri (`save_preferences`) for accessibility preferences. ## At a glance @@ -17,8 +17,8 @@ last_verified: 2026/05/09 - **Files:** 10 (4 085 LOC across stores + utils + types). - **Cross window sync:** - `localStorage` `storage` event in the float window for settings. - - Tauri `emit("magnotia:preferences-changed")` for preferences (handled by every layout). -- **Persistence keys:** `magnotia_settings`, `magnotia_profiles`, `magnotia_task_lists`, `magnotia_templates`, `magnotia_locale`, plus a viewer handoff key. + - Tauri `emit("lumotia:preferences-changed")` for preferences (handled by every layout). +- **Persistence keys:** `lumotia_settings`, `lumotia_profiles`, `lumotia_task_lists`, `lumotia_templates`, `lumotia_locale`, plus a viewer handoff key. ## The stores @@ -26,7 +26,7 @@ last_verified: 2026/05/09 Owns: - `page` (`PageState`): `current`, `status`, `statusColor`, `activeProfile`, `recording`, `timerText`, `handedness`, `taskSidebarOpen`. Initial: `current = "dictation"`. -- `settings` (`SettingsState`). Persisted to `localStorage["magnotia_settings"]` via `utils/settingsMigrations.ts`. Defaults at line 60 onward. Includes engine choice, model size, language, device, format mode, fillers, anti hallucination, British English, auto copy/paste, transcription preview, meeting auto capture (+ apps list), sound cues + volume, timestamps, theme, font size, AI tier, LLM model id and prompt preset, GPU concurrency, prewarm flag, save audio, output folder, global hotkey, sidebar collapsed, microphone device, energy state, match my energy, TTS voice + rate, rituals (morning/evening + time), launch at login, ritualsPromptSeen, nudges (enabled/muted/speakAloud), showMomentumSparkline. +- `settings` (`SettingsState`). Persisted to `localStorage["lumotia_settings"]` via `utils/settingsMigrations.ts`. Defaults at line 60 onward. Includes engine choice, model size, language, device, format mode, fillers, anti hallucination, British English, auto copy/paste, transcription preview, meeting auto capture (+ apps list), sound cues + volume, timestamps, theme, font size, AI tier, LLM model id and prompt preset, GPU concurrency, prewarm flag, save audio, output folder, global hotkey, sidebar collapsed, microphone device, energy state, match my energy, TTS voice + rate, rituals (morning/evening + time), launch at login, ritualsPromptSeen, nudges (enabled/muted/speakAloud), showMomentumSparkline. - `profiles`, `templates`, `taskLists` arrays. - `tasks` and `history` arrays. @@ -34,7 +34,7 @@ Helpers (selected, with line refs): - `addToHistory` → `add_transcript` (`page.svelte.ts:234`). - `mapTranscriptRow`, `saveTranscriptMeta` → `update_transcript` (`page.svelte.ts:272`). - `deleteFromHistoryById` → `delete_transcript` (`page.svelte.ts:320`). -- `addTask`, `completeTask`, `uncompleteTask`, `deleteTask`, `setTaskEnergy`, `updateTask` → matching `*_task_cmd` Rust commands. `completeTask` and friends emit `magnotia:task-completed | -uncompleted | -deleted` window events (line 470 onward). +- `addTask`, `completeTask`, `uncompleteTask`, `deleteTask`, `setTaskEnergy`, `updateTask` → matching `*_task_cmd` Rust commands. `completeTask` and friends emit `lumotia:task-completed | -uncompleted | -deleted` window events (line 470 onward). - Task lists: `addTaskList`, `renameTaskList`, `deleteTaskList`, `moveTaskList`, `sortTaskLists`, `moveTaskToList`, `moveTaskListToProfile`. - Profile mutators: `addProfileTaskList`, `removeProfileTaskList`. - `saveSettings`, `saveProfiles`, `saveTemplates` write to `localStorage`. @@ -45,7 +45,7 @@ Owns the `Preferences` shape: `theme` ("light" | "dark" | "system"), `zone` ("de - DOM is the source of truth at runtime: `readFromDOM()` reads `` data attributes and CSS variables; `applyToDOM(prefs)` writes them. - Persists via `invoke("save_preferences", { preferences: JSON.stringify(prefs) })` with a debounce. Failure shows a single toast per process (`preferences.svelte.ts:101-120`). -- Cross window: `broadcastPreferences` calls `emit("magnotia:preferences-changed", { source, prefs })`. Receivers in `+layout.svelte` and the secondary `+layout@.svelte` files apply external prefs after a label check. +- Cross window: `broadcastPreferences` calls `emit("lumotia:preferences-changed", { source, prefs })`. Receivers in `+layout.svelte` and the secondary `+layout@.svelte` files apply external prefs after a label check. - Exposes `getPreferences`, `updatePreferences`, `updateAccessibility`, `applyExternalPreferences`, `PREFERENCES_CHANGED_EVENT` constant. - Font families resolved from a constant map (Lexend, Atkinson, OpenDyslexic). @@ -74,14 +74,14 @@ Tracks the LLM lifecycle pill. State is one of `idle | loading | generating | do Phase 8 gamification. Owns `recentCompletions` (`DailyCompletionCount[]`) and a `todayCount` derivation. -Refresh triggers (no polling): module load, `magnotia:task-completed`, `magnotia:step-completed`, `magnotia:task-uncompleted`, `magnotia:task-deleted`, window focus (for midnight rollover). +Refresh triggers (no polling): module load, `lumotia:task-completed`, `lumotia:step-completed`, `lumotia:task-uncompleted`, `lumotia:task-deleted`, window focus (for midnight rollover). ### `focusTimer.svelte.ts` (238 LOC). Owns the floating focus timer. State: target ms, started at, label, taskId, paused. - `setInterval` at 250 ms (`TICK_INTERVAL_MS`). -- Triggered by `magnotia:start-timer` window events. Emits `magnotia:focus-timer-cancelled` and `magnotia:focus-timer-complete` on transitions. +- Triggered by `lumotia:start-timer` window events. Emits `lumotia:focus-timer-cancelled` and `lumotia:focus-timer-complete` on transitions. ### `implementationIntentions.svelte.ts` (260 LOC). @@ -90,7 +90,7 @@ Owns the floating focus timer. State: target ms, started at, label, taskId, paus - 30 second `setInterval` (`TIME_RULE_POLL_MS`) checks time based rules. - On match, can route `page.current = "tasks"` (lines 125, 136, 142) and call `tts_speak` if speak aloud is enabled (line 170). - Uses `delete_implementation_rule` to remove a rule (line 82). -- Emits `magnotia:implementation-rules-changed` after writes. +- Emits `lumotia:implementation-rules-changed` after writes. - Lifecycle: `startImplementationIntentions`, `stopImplementationIntentions` from `+layout.svelte`. ### `nudgeBus.svelte.ts` (292 LOC). @@ -101,7 +101,7 @@ Owns the nudge engine. Two `setInterval` handles: - Plus a `microStepTimers` Map for per task delayed notifications. Key commands: `deliver_nudge` (line 112), `tts_speak` (line 119). -Emits `magnotia:morning-triage-finished` after the modal closes. +Emits `lumotia:morning-triage-finished` after the modal closes. Lifecycle: `startNudgeBus`, `stopNudgeBus` from `+layout.svelte`. ### `speaker.svelte.ts` (10 LOC). @@ -111,9 +111,9 @@ Tiny. Holds `speakingId` so `SpeakerButton` instances can debounce / cancel each ## Cross store traffic - `DictationPage.completeRecording()` → `addToHistory` (page) → `add_transcript` Rust → push to history. -- `MicroSteps` "start timer" button → `magnotia:start-timer` → `focusTimer` store transitions → `FocusTimer` component renders ring. -- `TasksPage.addTask` → `tasks` store → emits `magnotia:task-completed/...` → `completionStats` refreshes → `CompletionSparkline` re renders. -- `SettingsPage` accessibility toggle → `updatePreferences` → DOM write + `save_preferences` invoke + `magnotia:preferences-changed` emit → secondary windows mirror. +- `MicroSteps` "start timer" button → `lumotia:start-timer` → `focusTimer` store transitions → `FocusTimer` component renders ring. +- `TasksPage.addTask` → `tasks` store → emits `lumotia:task-completed/...` → `completionStats` refreshes → `CompletionSparkline` re renders. +- `SettingsPage` accessibility toggle → `updatePreferences` → DOM write + `save_preferences` invoke + `lumotia:preferences-changed` emit → secondary windows mirror. - Float window settings sync uses `localStorage` `storage` event, not the Tauri preference event. Drift candidate. ## Watch outs @@ -121,7 +121,7 @@ Tiny. Holds `speakingId` so `SpeakerButton` instances can debounce / cancel each - `page.svelte.ts` is doing a lot. Splitting transcripts, tasks, task lists, settings, profiles into separate stores would help but is outside this map's job. - `settings` and `preferences` overlap (theme, font size, `transcriptSize`). Settings are localStorage only; preferences are Tauri persisted. Race possible during the migration `$effect`. - `nudgeBus` and `implementationIntentions` both run timers. They are torn down in `+layout.svelte` `onDestroy`. Only the main window starts them. -- `completionStats` listens on the DOM `window` for events; it does not subscribe to `tasks` directly. Adding a new task mutation that does not emit one of the `magnotia:task-*` events will silently break the sparkline. +- `completionStats` listens on the DOM `window` for events; it does not subscribe to `tasks` directly. Adding a new task mutation that does not emit one of the `lumotia:task-*` events will silently break the sparkline. ## See also diff --git a/docs/architecture-map/01-frontend/windows-and-routes.md b/docs/architecture-map/01-frontend/windows-and-routes.md index 93c494e..3835a17 100644 --- a/docs/architecture-map/01-frontend/windows-and-routes.md +++ b/docs/architecture-map/01-frontend/windows-and-routes.md @@ -9,7 +9,7 @@ last_verified: 2026/05/09 > **Where you are:** [Architecture map](../README.md) → [Frontend](README.md) → Windows and routes -**Plain English summary.** Magnotia is a single SvelteKit build that runs as multiple desktop windows. The Rust side opens four webviews (main, tasks float, transcript viewer, transcription preview) and points each one at a different SvelteKit route. The frontend uses SvelteKit's `+layout@.svelte` "break" trick so secondary windows skip the main shell (sidebar, titlebar, toast viewport) and render a focused, single purpose UI. +**Plain English summary.** Lumotia is a single SvelteKit build that runs as multiple desktop windows. The Rust side opens four webviews (main, tasks float, transcript viewer, transcription preview) and points each one at a different SvelteKit route. The frontend uses SvelteKit's `+layout@.svelte` "break" trick so secondary windows skip the main shell (sidebar, titlebar, toast viewport) and render a focused, single purpose UI. ## At a glance @@ -45,7 +45,7 @@ Responsibilities: - Detect Tauri runtime (`hasTauriRuntime`) and OS (`loadOsInfo`). Linux uses native KWin/Mutter decorations; macOS and Windows render the custom `Titlebar` plus invisible `ResizeHandles`. Default `useCustomChrome = false` to avoid a flash on Linux (`+layout.svelte:49`). - Hotkey backend selection. On Wayland, attempt the evdev backend (`check_hotkey_access`). Otherwise fall back to `tauri-plugin-global-shortcut`. Falls back to "unavailable" if neither path works (`+layout.svelte:76-102`). - Hotkey registration. Only the `main` window owns the global shortcut. The function debounces evdev autorepeat at 120 ms (Handy issue #1143 referenced in comments, `+layout.svelte:171-186`). -- Cross window listeners: `magnotia:hotkey-pressed` (evdev path), `magnotia:open-wind-down` (tray menu), `magnotia:preferences-changed` (sync prefs across windows). Apply external preferences if the source label differs from our own. +- Cross window listeners: `lumotia:hotkey-pressed` (evdev path), `lumotia:open-wind-down` (tray menu), `lumotia:preferences-changed` (sync prefs across windows). Apply external preferences if the source label differs from our own. - Theme migration `$effect`. Reads `settings.theme` (legacy "Light" / "Dark" / "System") and writes `preferences.theme` ("light" / "dark" / "system"). See README debt note 2. - Font size CSS variable `--font-size-transcript` set on `` from `settings.fontSize`. - Global error capture. `window.onerror` and `unhandledrejection` forward to `log_frontend_error` Rust command. Best effort, swallow throws. @@ -80,11 +80,11 @@ Tasks float window. Self contained quick add, list filter, sort menu, completed ### `src/routes/viewer/+layout@.svelte` (77 LOC) -Same break layout pattern. Mounts `Titlebar`, `ToastViewport`, applies preferences sync via `magnotia:preferences-changed`, applies theme. +Same break layout pattern. Mounts `Titlebar`, `ToastViewport`, applies preferences sync via `lumotia:preferences-changed`, applies theme. ### `src/routes/viewer/+page.svelte` (606 LOC) -Transcript editor. Hydrates from a transcript ID handed off via `localStorage` (`magnotia:viewer-handoff` style key, see file). Fetches the full row from SQLite via `get_transcript`. Renders an `