Commit Graph

12 Commits

Author SHA1 Message Date
d6bf9ed245 refactor(frontend): migrate JS modules to TypeScript
Wholesale JS -> TS migration of the frontend — stores, utils, actions,
and all Svelte component scripts adopt type annotations. Compile-time
surfaces (app.d.ts, lib/types/) added for shared DTO types.

Build plumbing:
  - package.json: dev:frontend script that runs svelte-kit sync first
  - tauri.conf.json: beforeDevCommand points at dev:frontend
  - run.sh: dropped the sed-hack that temporarily blanked beforeDevCommand;
    now relies on npm run dev:frontend to avoid double-Vite
  - jsconfig.json: allowImportingTsExtensions

Preserves all Group 1 behaviour:
  - page.svelte.ts keeps loadHistory / loadTasks Tauri-first, no
    localStorage; saveTranscriptMeta + mapTranscriptRow + mapTaskRow
    intact; update_task_cmd and update_transcript_meta_cmd invocations
    carry the correct payload shape.
  - Toasts, preferences stores typed without behaviour change.
  - Viewer still routes segment edits through saveTranscriptMeta; the
    Task 1.5 TODO markers are gone.

taskExtractor.ts is functionally improved during the migration:
  - multi-task matches in the same sentence
  - list-style shopping-verb expansion (get bread, milk, and cheese)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 20:05:54 +01:00
ea48d03cee agent: dogfood polish 2026/04/19 — Linux native chrome + History redesign + mic picker cleanup
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
Second dogfood sprint. Headline fix: Linux now uses native KWin/Mutter
decorations instead of fragile frameless `startResizeDragging`, which
collapsed diagonal corner resize to a single axis and made drag feel
laggy. macOS / Windows keep custom chrome via `useCustomChrome` gate.

Other changes:

- Cross-window preferences sync via `kon:preferences-changed` Tauri
  event — theme and font changes propagate live to float/viewer.
- Hotkey recorder rewritten to use capture-phase document listener
  gated by $effect; button focus was unreliable in webkit2gtk.
- History page redesigned for cognitive-load hygiene: title-first
  compact row, inline title input, Edit popout opening /viewer in
  edit mode, clipboard export as .md with YAML frontmatter, manual
  tag chips + + Add tag input, header tag filter (cap 7), global
  Starred filter, `tag:xyz` search syntax.
- `deriveAutoTags` kept as empty hook for post-Task-7 LLM topic tags;
  research found all previous auto-tag chips redundant with row UI.
- Viewer window adds edit mode with debounced-save textarea; native
  title renamed to "Kon - Transcription Editor".
- Window minimums updated per GNOME HIG + WCAG reflow research:
  main 960x600, float 360x480, editor 560x520.
- Microphone picker filters raw ALSA strings (hw:, plughw:, front:,
  sysdefault:, null) and dedupes by CARD=X. New `description` field
  on DeviceInfo reads /proc/asound/cards so Blue Yeti shows as "Blue
  Microphones" instead of the short "Microphones" card name.
- GPU reporting fixed: get_runtime_capabilities now returns
  accelerators=[cpu,vulkan] and whisper.supports_gpu=true, matching
  the transcribe-rs whisper-vulkan feature linked unconditionally.
- ResizeHandles kept for macOS/Windows frameless: 12px edges, 20px
  corners via CSS vars, pointerdown + setPointerCapture, corners
  above edges in z-order, rendered as sibling (not child) of the
  animated layout root so `position: fixed` is viewport-relative.
- Dueling drag-region handlers removed — `data-tauri-drag-region` and
  manual `startDragging()` were stacked on the same elements; kept
  the manual handler which has the button/input early-return logic.

See HANDOVER.md for the full session log and deferred items.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-19 14:30:42 +01:00
e436a69839 fix(preferences): use Object.assign mutation to prevent infinite effect loops
Replacing the preferences object (spread reassignment) caused all consumers'
prefs references to go stale — the loop guard read the old value forever.
Svelte 5 shared state pattern requires a stable const object with property
mutations, not reassignment. Also removes duplicate theme sync $effect from
SettingsPage (already handled in +layout.svelte).
2026-04-18 10:18:29 +01:00
62ea58d95a diagnostics: panic hook + frontend error capture + Settings → About diagnostic report
THE BRIEF:
For the friends beta we need verbal feedback AND technical feedback —
some bugs the user cannot describe but a stack trace can. Built it in
two layers, with Layer 3 deferred until there is real volume.

PRIVACY POSTURE (matches Kon's local-first positioning):
- All capture is to disk only. Nothing is transmitted.
- The manual report bundler shows the user exactly what would be
  shared and lets them choose to copy / save it.
- No remote endpoint, no Sentry, no opt-out telemetry.

LAYER 1 — Always-on local capture:
- Rust panic hook (commands/diagnostics.rs::install_panic_hook) writes
  each panic to ~/.kon/crashes/<unix-ts>-<short-id>.crash. Captures
  thread name, OS/arch, RUST_BACKTRACE state, and the panic info.
  Installed before tauri::Builder so it catches setup-time panics too.
- Frontend window.onerror + window.unhandledrejection in
  src/routes/+layout.svelte forward to the new log_frontend_error
  Tauri command, which inserts into the existing error_log SQLite
  table. Best-effort: errors in the error handler itself are swallowed
  so logging can never crash the app.
- Existing error_log table (migration v1) is now actually used —
  closes the TODO from crates/storage/src/database.rs:409.

LAYER 2 — Manual diagnostic report:
- Settings → About → Diagnostics section: Generate report → Preview →
  Copy / Save.
- Report is plain markdown so it pastes cleanly into email, Discord,
  GitHub issues. Sections: app version + OS, sanitised settings JSON,
  recent error_log rows, last 5 crash dumps with previews, log file
  tail (8KB).
- Preview is shown in a <details> with the full text the user can
  inspect before deciding to share.
- Save writes to ~/.kon/diagnostic-reports/kon-diagnostic-<ts>.md.

NEW FILES:
- src-tauri/src/commands/diagnostics.rs (panic hook + 5 Tauri commands)

CHANGES:
- crates/storage/src/file_storage.rs: crashes_dir() + logs_dir() helpers
- crates/storage/src/database.rs: ErrorLogRow + list_recent_errors()
- crates/storage/src/lib.rs: re-exports
- src-tauri/src/commands/mod.rs: + diagnostics module
- src-tauri/src/lib.rs: install_panic_hook() before Builder; 5 new
  Tauri commands registered (log_frontend_error,
  list_recent_errors_command, list_crash_files,
  generate_diagnostic_report, save_diagnostic_report)
- src/routes/+layout.svelte: installGlobalErrorCapture() at mount
- src/lib/pages/SettingsPage.svelte: diagnostic state + buttons +
  preview block at the end of the About section

cargo check -p kon-storage clean. Settings.svelte if/each balanced.

LAYER 3 (deferred):
- Optional opt-in remote reporting (self-hosted Sentry on Tartarus or
  similar). Not for friends beta. Open up after volume justifies it.
2026-04-17 13:47:20 +01:00
9f3be5c007 ui+app: Day 5+6 — Settings → Vocabulary panel + Wayland self-relaunch
VOCABULARY PANEL (Day 5):
src/lib/pages/SettingsPage.svelte gains a new collapsible "Vocabulary"
section between Audio and Transcription. Wires the dictionary commands
shipped in 1cce567:
- list_dictionary_command on mount + onfocus refresh
- add_dictionary_entry_command (term + optional note)
- delete_dictionary_entry_command
- Inline error feedback via vocabularyError
- Empty-state copy + per-entry remove button with aria-label

The dictionary terms are intended to be injected into the LLM cleanup
prompt so the model preserves user-specific vocabulary (medication
names, place names, jargon, names of people in the user's support
network — particularly important for the ND audience). The LLM client
itself is currently a stub (crates/ai-formatting/src/llm_client.rs);
when it lands, it can import list_dictionary from kon_storage and
inject terms into the prompt suffix.

WAYLAND SELF-RELAUNCH (Day 6):
src-tauri/src/lib.rs gains ensure_x11_on_wayland() which runs before
tauri::Builder. On Linux Wayland sessions (XDG_SESSION_TYPE=wayland) it
sets GDK_BACKEND=x11, WINIT_UNIX_BACKEND=x11, and
WEBKIT_DISABLE_DMABUF_RENDERER=1 — the env vars HANDOVER.md documents
the user manually prefixing.

Drops the "users have to remember the env-var prefix" friction.
Idempotent: existing values are respected. Inspired by Open-Whispr's
Chromium --ozone-platform=x11 self-relaunch.

Compile-checked: cargo check -p kon-storage clean. Settings.svelte
$state / #if balanced (28 state, 34/34 if/endif).

NEXT: Phase 6 — dogfooding readiness doc with Jake test instructions.
2026-04-17 13:16:07 +01:00
96980c7d5c audio: fix mic capture — skip monitor sources, validate by RMS, add device picker
Day 1 of the upgrade plan (output/reports/kon-upgrade-plan-2026-04-17.md
in the CORBEL workspace). Fixes the HANDOVER.md blocker: native live
transcription was capturing silence because PulseAudio/PipeWire monitor
sources (speaker loopback) were winning the device-selection race —
they deliver zero-valued bytes that satisfied the original
"any device that produces data within 350ms" check.

WHAT CHANGED:

crates/audio/src/capture.rs (rewrite):
- New `DeviceInfo` struct (serde-derived) for the Settings device picker
- New `MicrophoneCapture::list_devices()` enumerates inputs with metadata
- New `MicrophoneCapture::start_with_device(name)` for explicit selection
- Refactored `start()` with monitor-source filtering by name pattern
  (.monitor suffix, "Monitor of " prefix, "loopback" substring) and
  RMS-energy validation in a 350ms window
- Two-pass selection: real inputs first, monitor sources only as
  last-resort fallback with explicit warning log
- Drop counter (Arc<AtomicU64>) tracks chunks dropped by `try_send`
  failure under load — Codex review caught this as a silent-failure risk
- `dropped_chunks()` accessor for the live session
- Verbose tracing at every step for diagnosis
- Unit test for monitor-name detection
- `cargo check -p kon-audio` passes clean

crates/audio/src/lib.rs:
- Re-export `DeviceInfo`

crates/audio/Cargo.toml:
- Add serde dependency (for DeviceInfo derives)

src-tauri/src/commands/audio.rs:
- New `list_audio_devices` Tauri command (returns Vec<DeviceInfo>)

src-tauri/src/lib.rs:
- Register `list_audio_devices` in invoke_handler

src/lib/pages/SettingsPage.svelte:
- New "Audio" section with microphone picker dropdown
- Auto-populates on mount via `list_audio_devices`
- Refresh button + clear messaging about monitor sources
- Likely-monitor entries marked disabled in the dropdown
- Auto mode is the default (empty string in settings.microphoneDevice)

src/lib/stores/page.svelte.js:
- New `microphoneDevice` field in defaults (empty = auto-select)

NEXT STEPS (per the upgrade plan):
- Wire `microphoneDevice` from settings into `MicrophoneCapture::start_with_device`
  in the live and standalone capture paths (currently both still call
  the auto-selecting `start()`)
- Test on real hardware (Wayland + multiple input devices)
- Codex sanity-check of this diff is running in parallel; addendum to
  follow if anything substantive comes back

Refs: /home/jake/Documents/CORBEL-Projects/kon/HANDOVER.md
      output/reports/kon-upgrade-plan-2026-04-17.md (CORBEL workspace)
2026-04-17 12:43:13 +01:00
jake
01f6e42346 agent: settings — restyle with zone picker and accessibility controls
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 11:04:06 +00:00
jake
4c0fd0aeda agent: foundation — sync incremental changes from legacy codebase
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-21 10:50:32 +00:00
jake
2ab34eb15a refactor(kon): settings page — collapsible sections, first section open by default
- Consolidated 7 separate Card components into a single Card with 8 accordion sections
- Added openSection $state variable; 'transcription' open by default, others collapsed
- Each section header is a clickable button with +/− indicator; clicking open section closes it
- Section headings use font-display italic 18px (vs 26px page title) as accordion headers
- All existing functionality preserved: toggles, dropdowns, model download/load, profiles, templates, hotkey recorder, output folder picker
- Profiles & Templates remain as nested accordion-within-accordion (existing pattern kept)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:29:49 +00:00
jake
ad31249e88 fix(kon): remove all Ramble references — titles, exports, copy, version bump to v1.0
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 02:09:51 +00:00
jake
fe3739fdbb fix(kon): task sidebar overlay, Parakeet model management, conditional engine settings
TaskSidebar:
- Changed from flex layout member to fixed overlay with backdrop
- Click backdrop or press Escape to close
- Content no longer shrinks when sidebar opens — buttons stay accessible
- Positioned at z-50 over main content, top offset for titlebar

Settings — Parakeet model management:
- Added Parakeet model state: download, check, load status
- New downloadParakeet() and loadParakeet() functions
- Listens for parakeet-download-progress events
- Parakeet section shows download/load/status controls

Settings — conditional engine sections:
- Whisper model selector only shows when engine === "whisper"
- Parakeet model controls only show when engine === "parakeet"
- Cleaner UI — only active engine's options visible

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 23:26:27 +00:00
jake
9926a42b7a feat(kon): scaffold hybrid modular workspace
- Cargo workspace with 6 domain crates: core, audio, transcription, ai-formatting, storage, cloud-providers
- Minimal Tauri shell (lib.rs + main.rs) with plugin registration
- Svelte 5 frontend copied from Ramble v0.2
- All crates compile as empty stubs
- App identifier: uk.co.corbel.kon

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-16 20:21:38 +00:00