Files
Lumotia/docs/handovers/HANDOVER-2026-04-19.md
Jake 26c7307607
Some checks failed
check / cargo check (macos-latest) (push) Has been cancelled
check / cargo check (ubuntu-22.04) (push) Has been cancelled
check / cargo check (windows-latest) (push) Has been cancelled
check / svelte build + lint (push) Has been cancelled
agent: lumotia-rebrand — docs, scripts, root config, residuals
Phase 9 of the rebrand cascade. Sweep covers everything the Phase 8
frontend pass deliberately skipped: docs/, root markdown, scripts,
Cargo.toml descriptions, code comments that survived earlier
word-boundary sed, plus a handful of identifiers caught on the final
verify pass.

transcription-app changes:
- README.md, HANDOVER.md, KNOWN-ISSUES.md, run.sh — magnotia/Magnotia
  -> lumotia/Lumotia.
- docs/ — sweep across all subdirs except docs/handovers/ (preserved
  as immutable audit trail). Includes architecture-map references
  to magnotia_core::*, magnotia_storage::*, etc. now pointing at
  lumotia_*; dev-setup.md tracing output examples (lumotia_startup
  target); brief/ + superpowers/ + issues/ + whisper-ecosystem/ +
  audit/.
- Cargo.toml descriptions on 9 crates (core, audio, cloud-providers,
  hotkey, llm, mcp, plus referenced others).
- crates/core/src/{error,hardware,recommendation,paths}.rs +
  crates/audio/src/wav.rs + crates/llm/src/model_manager.rs +
  crates/cloud-providers/src/keystore.rs + crates/mcp/src/lib.rs —
  doc comments and a model-manager user-agent string.
- Caught on final pass: BroadcastChannel("magnotia_task_sync") -> ...
  ("lumotia_task_sync"); magnotia_locale i18n localStorage key
  renamed + migration shim added; CSS keyframe names
  magnotiaPulse / magnotiaBar / magnotiaFade renamed in the design-
  system kit; magnotia_viewer_item / magnotia_viewer_mode handoff
  keys renamed in HistoryPage + viewer/+page.svelte; src/assets/
  wordmark.svg text.
- src-tauri/src/lib.rs comment cleanup ("magnotia era" was sed'd
  to "lumotia era" earlier — restored).

Preserved (intentional):
- crates/core/src/paths.rs — keeps "magnotia" / "Magnotia" / ".magnotia"
  legacy detection strings in legacy_and_target_paths() so the
  migration shim can still find user data from the magnotia era.
- src/lib/stores/{page,focusTimer}.svelte.ts + src/lib/i18n/index.ts
  — migration call sites reference the legacy magnotia keys
  deliberately.
- docs/handovers/ — historical audit trail.

cargo build --workspace passes. npm run check: 0 errors / 0 warnings
(3958 files). cargo test --workspace: 339 pass / 0 fail.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 12:38:03 +01:00

8.8 KiB
Raw Permalink Blame History

name, type, tags, description
name type tags description
handover-2026-04-19 reference
handover
session
lumotia
Session handover — 2026/04/19 dogfood polish + cross-platform window chrome

Lumotia Handover — 2026/04/19

Originally written when the product was named Kon (and briefly Corbie); references rewritten in the 2026-04-30 rebrand sweep.

Second dogfood sprint. Four phases: (1) fix bugs surfaced on first real use, (2) redesign History for cognitive-load hygiene, (3) resolve broken window resize/drag on Linux Wayland, (4) clean up microphone picker.

What shipped this session

Cross-window preferences sync

  • preferences.svelte.js emits lumotia:preferences-changed Tauri event on update.
  • Main / viewer / float layouts listen and call applyExternalPreferences without re-emit, so theme and font changes propagate live across sibling windows.
  • Echo suppressed via source window label check.

Hotkey recorder

  • Root cause of "can't change hotkey": button-level onkeydown relied on post-click keyboard focus, which webkit2gtk on Linux does not guarantee.
  • Fix: document.addEventListener("keydown", ..., { capture: true }) inside a $effect gated by recording. Beats any descendant handler. Escape now cancels.

History page redesign (research-backed)

  • Compact row now shows the title (or "Untitled"), not body-preview text — metadata already lives in the row columns (date, duration, source icon).
  • Expanded row gets an inline title input (replaces the old Rename prompt modal).
  • Edit button opens the viewer window in edit mode (editable textarea, debounced save to localStorage + storage-event sync back to main history).
  • Export .md copies a full YAML-frontmatter markdown document to the clipboard — paste into Obsidian.
  • Tags: $lib/utils/frontmatter.js exposes deriveAutoTags (currently returns []), buildFrontmatter, serialiseFrontmatter, buildMarkdown. Manual tags stored as item.manualTags, rendered as removable chips in the expanded row with + add tag input.
  • Header tag chip bar (cap 7, click to filter, × to clear), plus tag:xyz search syntax.
  • Global Starred filter toggle in the History header.
  • Research memo found all five previous auto-tag families redundant with existing row UI — kept the derivation hook for the post-Task-7 topic:* content tag from lumotia-llm.
  • Duplicate-transcript render fix: expanded <p> only if compact preview actually truncated.

Viewer / editor popout

  • /viewer route now reads lumotia_viewer_mode from localStorage ("view" | "edit").
  • Edit mode renders a plain textarea bound to item.text; 400ms debounced save flushes on input, final flush on onDestroy. Segment-specific controls (Compact, Starred) hidden in edit mode.
  • Native title: "Lumotia - Transcription Editor".

Platform-aware window chrome (Linux fix)

Root cause: Tauri v2 frameless decorations: false on KDE Wayland + webkit2gtk does not honour diagonal corner resize (collapses NorthEast etc. to a single axis via GTK's gtk_window_begin_resize_drag), and data-tauri-drag-region adds noticeable drag latency. Setting setPointerCapture ahead of startResizeDragging does not help once the compositor has taken over the pointer grab. Verified via Context7 docs + Codex diagnosis — Linux frameless is a known-fragile path.

Fix:

  • Linux uses native KWin/Mutter decorations. src-tauri/tauri.linux.conf.json overlays decorations: true + full main window config (title, sizes) — overlays replace the windows array, so every field must be present, not just the delta. src-tauri/src/commands/windows.rs uses cfg!(target_os = "linux") to set decorations per window.
  • macOS / Windows keep custom chrome. src/lib/utils/osInfo.js isLinux() gates <Titlebar> and <ResizeHandles> via useCustomChrome = $state(false); flips to !isLinux() after loadOsInfo() resolves.
  • Dueling drag-region handlers removed across Titlebar, float page, viewer page — everywhere a manual startDragging() lives, the data-tauri-drag-region attribute was deleted (they're alternatives per Tauri docs, not combinable).
  • ResizeHandles kept for macOS/Windows frameless: 12 px edges / 20 px corners via CSS vars (--lumotia-resize-edge, --lumotia-resize-corner), pointerdown + setPointerCapture, corners with explicit higher z-index. Handles rendered as siblings of the animated layout div so position: fixed is viewport-relative rather than captured by the transform containing block.

Window minimum sizes (evidence-backed)

Research pass cited GNOME HIG (1024×600 desktop / 360×294 mobile floors), WCAG 2.2 SC 1.4.10 Reflow (320 CSS px), Raycast 750×474 as a reference for single-pane working width, and consistent A11y principle that nothing should clip in the default configuration.

Window Was Now Rationale
Main 1020×540 960×600 Fits 210 px sidebar + ~750 px content; GNOME vertical floor.
Float 400×400 360×480 360 = GNOME mobile floor; 480 fits pills + quick-add + sort + ~6 task rows without scroll.
Transcript editor 450×500 560×520 Exceeds WCAG reflow floor; ~60-70 char measure for editing.

Microphone picker cleanup

  • ALSA enumeration was leaking hw:, plughw:, front:, sysdefault:, null et al into the dropdown.
  • SettingsPage.svelte now renders only sentinel devices (default, pipewire, pulse) + one entry per unique sound card, keyed off the sysdefault:CARD=X alias.
  • crates/audio/src/capture.rs reads /proc/asound/cards and populates a new description field on DeviceInfo with the card's full product string (e.g. "Blue Microphones" for Jake's Yeti). Frontend prefers description → CARD=X short name → raw name.

GPU reporting

  • commands/models.rs::get_runtime_capabilities was hardcoded to accelerators: vec!["cpu"] and supports_gpu: false for whisper. Updated to ["cpu", "vulkan"] and whisper supports_gpu: true, reflecting that crates/transcription/Cargo.toml links transcribe-rs with the whisper-vulkan feature unconditionally.
  • Settings now shows the Vulkan option instead of the "This build is CPU-only" notice.

Desktop shortcut

  • ~/Desktop/Lumotia.desktop launcher with the 128×128 icon, Terminal=true so logs are visible and Ctrl+C cleanly stops the run.sh wrapper.

What's deferred

  • Transparent windows (transparent: true) — Tauri issue #13270 reports this smooths drag/resize further on Linux, but it's moot now that Linux uses native decorations.
  • File-system export (.md save dialog) — currently clipboard-only. Needs a Rust write_text_file command for plugin-less file writes.
  • Bulk select + bulk export in History.
  • LLM-powered content tags (topic:*, intent:*) — slots into Task 7 lumotia-llm stub once Phase 3 wires real llama-cpp-2.
  • Settings UX overhaul — Jake flagged that current settings feel overwhelming. Proposed: bunch high-traffic settings, hide advanced behind a toggle. Brainstorm + plan deferred to a dedicated session.
  • Task 7 (MicroSteps end-to-end) — storage + Tauri CRUD + lumotia-llm stub + frontend dual-write all landed in an earlier commit chain. The MicroSteps UI was written as the final task 7 step but not yet dogfooded against the stub LLM. Needs manual walkthrough.

Gotchas discovered today

Issue Fix
tauri.linux.conf.json stripped title and min sizes from main window Overlay replaces the windows array — include every field, not just the delta
data-tauri-drag-region + manual startDragging() on the same node caused drag latency Pick one — we use manual startDragging for the button/input early-return logic
Corner resize collapsed to single axis on KWin Wayland Native decorations on Linux side-step the whole frameless path
animate-float-enter on the viewer/float layout root created a containing block that broke position: fixed on ResizeHandles children Render ResizeHandles as a sibling of the animated div, not a descendant
Lumotia binary auto-respawned on file-save while a second run.sh was also launching → two visible instances sharing one Vite server Do not script ./run.sh while the user has already launched via the desktop icon; rely on HMR
run.sh leaves "beforeDevCommand": "" in tauri.conf.json if its cleanup trap is bypassed (e.g. SIGKILL) Cleanup trap restores "npm run dev" on graceful exit; SIGTERM (not SIGKILL) is the right kill signal
/proc/asound/cards header lines have leading whitespace for 2-digit card ID alignment Parser trims leading whitespace before checking for leading digit

How to resume

Picking up Lumotia dogfooding from 2026/04/19.
HANDOVER is at HANDOVER.md in the project root.
Active priorities: (1) confirm resize/drag/mic cleanup, (2) Task 7 MicroSteps
dogfood with lumotia-llm stub, (3) Settings UX brainstorm.