Commit Graph

66 Commits

Author SHA1 Message Date
1c276e767b fix: block scroll-wheel changes on all ComboBoxText dropdowns (v2.03.28)
Hovering over a combo and scrolling could silently change the selection.
All ComboBoxText widgets now return True from their scroll-event handler,
swallowing the event before GTK's default handler can act on it.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 11:38:48 +02:00
016ffe0390 feat: overlay × cancel button + wakeword shortcut fields inline (v2.03.27)
- Overlay HUD shows a × button in the top-right corner during recording/
  streaming; clicking it cancels dictation. The button area is the only
  clickable region — rest stays fully click-through.
- Wakeword tab "Cancel words" and "Send words" rows now include an inline
  keyboard shortcut entry + Set button, so key_cancel / key_send can be
  configured right next to the spoken-word equivalents.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 04:00:23 +02:00
834cc20553 fix: cancel recording works in wakeword mode + tray Cancel item (v2.03.26)
- Cancel hotkey now fires even when wakeword triggered the recording
  (ModifierScheme state was "idle" so the key was silently ignored)
- Tray menu: "✕ Cancel recording" — always visible, enabled while recording,
  grayed out at idle; works for both wakeword and manual recordings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 03:44:14 +02:00
599eb08c5a feat: smart Save — inline status, no restart for safe changes (v2.03.25)
Save now diffs old vs new config. Safe changes (language, sounds, LLM,
keywords, overlay) show "✓ Applied" in the header for 4s. Restart-required
changes (STT engine, hotkeys, mic, wakeword) show "⚠ restart needed for: …"
and highlight Save & Restart. No modal popup on Save.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 03:29:27 +02:00
9c812a960e fix: Input level meter works without visiting General first (v2.03.24)
_start_meter() was only called from _build_general() and referenced
self.mic_level unconditionally. Now _build_input() also starts the meter
when it's not already running, and both level bars are updated via hasattr.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 02:48:55 +02:00
8301cbb457 fix: wakeword pane actually resizable — wrap controls in ScrolledWindow (v2.03.23)
The controls pane now has shrink=True and a ScrolledWindow wrapper, so
dragging the divider upward collapses the controls and expands the table.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 02:26:32 +02:00
012a069ad0 feat: wakeword benchmark — draggable split pane for results table (v2.03.22)
Controls (TTS config, engine checkboxes, run button) are in the top pane;
the results table is in the bottom pane. Drag the divider to see more rows.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 01:57:31 +02:00
8b26bc3379 feat: wakeword results table — sortable columns + CSV export (v2.03.21)
- All columns sortable by clicking header; numeric cols sort numerically
- "Copy as CSV" → clipboard; "Save CSV…" → file chooser

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 01:47:47 +02:00
6f133771e7 fix: icon vertical centering + wakeword results table (v2.03.20)
- Section header icons were pushed down by bt-section CSS margin-top;
  now only applied to the row container, not the image widget
- Wakeword benchmark shows a full TreeView table: per-voice Detected/Total/
  Recall%/False-fires/Time with colour coding, plus aggregate row per engine

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 01:25:14 +02:00
66e431f50a feat: wakeword engine checkboxes + wakeword model selector in benchmark (v2.03.19)
- Engine checkboxes let you pick which wakeword servers to include in the run
- Wakeword combo selects which model/phrase to test; leave empty for each
  engine's own, pick a specific one (e.g. okay_computer) to override all
- Also fixes: TTS ⟳ no longer fills model combo with Kokoro voice names

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 01:13:54 +02:00
b20aa31261 feat: TTS model fix + per-engine wakeword benchmark results (v2.03.18)
- TTS ⟳ no longer floods model combo with voice names (Kokoro exposes
  voices as /models entries — detected and skipped automatically)
- Wakeword benchmark now shows per-engine Recall/False-fires/time results;
  fixes progress callback signature mismatch that crashed multi-engine runs
- Wakeword fetch feedback: ⟳ shows "Connecting…" then model count/names
- Wakeword Quickstart expanded to ports 10400–10403 + hey_jarvis/alexa
- Wakeword info box added explaining model directory setup

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:59:28 +02:00
7a9dc5a2f7 feat: MP3/OGG/FLAC sound support + browse dialog with auto-preview (v2.03.16)
Sound fields accept WAV/MP3/OGG/FLAC/M4A/AAC/AIFF/Opus. Browse dialog
auto-plays each file on selection so you can preview before confirming.
sound.py falls back to ffplay/gst-play-1.0 for formats not supported
by pw-play/paplay.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:37:07 +02:00
571dae7cc9 feat: full CRUD for wakeword engine presets (v2.03.15)
Add/Quickstart/Reload/Delete buttons + Name field mirror the STT engines UI.
Four quickstart templates for common wyoming-openwakeword setups.
Migration: existing wakeword_uri/model auto-promoted to first preset.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:32:17 +02:00
e831d7f1e6 fix: remove Internal engine section header in Engines tab (v2.03.14)
Device/Compute rows already only show for local engines; the titled section
break was redundant and visually separated fields that belong together.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:24:42 +02:00
34f75844c1 feat: Save buttons in header bar, remove Close button, center section icons (v2.03.13)
HeaderBar replaces bottom button row — Save and Save & Restart appear in the
title bar on the right, X button closes. Section header icons vertically
centered using SMALL_TOOLBAR size and valign=CENTER.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:22:53 +02:00
ccf3801545 feat: icons on all settings tabs and section headers (v2.03.12)
GTK symbolic icons on every tab label and every section/card header.
Also fixes the resize grip landing in the tab bar instead of the bottom-right corner.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-10 00:07:41 +02:00
efa44c8872 feat: resize grip indicator on settings window (v2.03.11)
Draws a classic dotted SE-corner grip overlaid on the bottom-right of the
notebook so users know the settings dialog is resizable.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:50:20 +02:00
c292ff2242 fix: probe Prometheus /metrics at server root, not under /v1 (v2.03.10)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:30:33 +02:00
c3cf123afe feat: server RAM via Prometheus /metrics in benchmark (v2.03.09)
Probe remote engines' /metrics for process_resident_memory_bytes or
container_memory_rss; show actual server-side MB in RAM column.
Falls back to "server" when the endpoint is not exposed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:24:40 +02:00
86632e1918 fix: hide Internal Engine section for remote/streaming engines (v2.03.08)
Removes whitespace gap between STT config card and device/precision card
by hiding the latter when a Server or Realtime engine type is selected.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 23:06:32 +02:00
d5e512a812 feat: per-engine timeout field, WhisperX default 120s (v2.03.07)
- STTEngine gains timeout: int = 30 field; used as HTTP timeout per engine
- Engines tab shows "Timeout (s)" field; blank = 30s default
- WhisperX quickstart template pre-sets 120s (diarization is slow)
- config load/save: only written when != 30 to keep config clean
- RAM column header tooltip explains "server" for Docker/remote engines

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:48:53 +02:00
2326f20a28 fix: numeric sort for Time, Accuracy, RAM columns (v2.03.06)
String sort put "14.85" before "2.47". Now uses a custom comparator
that strips % and non-numeric markers before comparing as float.
Non-numeric values ("—", "server") sort to the bottom.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:37:17 +02:00
05ccfbdeb4 fix: RAM column shows "server" for remote engines (v2.03.05)
Remote engines run models server-side so local RSS never changes.
Show "server" instead of "—" to make the reason clear.
Local engines show measured MB; local already-loaded shows "—".

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:34:41 +02:00
d40721dd3d fix: reduce transcription timeout to 30s (v2.03.04)
300s was too long; nobody waits 5 min for a result.
30s gives slow remote servers a fair window while still failing fast.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:25:17 +02:00
79f3b5cdab fix: API probe URLs, 5min timeout for slow engines like WhisperX (v2.03.03)
- Add _api_base() to strip endpoint-specific path suffixes before probing
  /models, /metadata, /info — fixes /transcribe/models 404 spam when URL
  ends with a custom path like /v1/transcribe
- Increase default transcribe() timeout 60s → 300s — WhisperX with speaker
  diarization (pyannote) takes 2-5 min and was always timing out

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:23:13 +02:00
766002a478 fix: WhisperX URL — add template, tooltip clarifying /transcribe path (v2.03.02)
- Add "WhisperX server" quickstart template pre-filled with /transcribe endpoint
- Add tooltip to STT URL field explaining that non-standard servers (WhisperX)
  should use the full endpoint as the URL, not /v1
- _url_field_lb accepts optional tooltip= kwarg

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:16:21 +02:00
d9603c98bf feat: RAM usage column in benchmark, docs update (v2.03.01)
- benchmark.py: measure RSS delta via /proc/self/status before/after each
  transcription; add ram_mb field to BenchRow
- gtksettings.py: add RAM (MB) column to results table (index 8); tooltip
  column shifted to index 10
- CHANGELOG.md: full history from v2.02.00 through v2.03.01
- README.md: benchmark description updated to mention RAM column
- MANUAL.md: benchmark result columns as table; Log tab documents
  level filter dropdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:11:38 +02:00
f5f65ffba9 fix: stability, WhisperX 404, log levels (v2.03.00)
- Stability: remove blocking TCP socket call from _collect() — was
  freezing the GTK main thread on Save when wakeword server unreachable;
  now checks async in background and logs result
- Thread safety: fix _ww_load() reading GTK widget from background thread;
  capture URI on main thread before spawning
- WhisperX 404: _transcribe_remote now detects non-standard paths
  (anything other than /v1) and uses the URL as the full endpoint,
  so http://host/transcribe works without /audio/transcriptions appended
- Log levels: logbuffer stores (ts, level, msg) tuples; log() accepts
  level= (DEBUG/INFO/WARNING/ERROR); Log tab gets a Level dropdown
  (Verbose/Info/Warning/Error) that filters displayed entries live

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 22:01:14 +02:00
6fb41d5a9b feat: wakeword server preset dropdown in Input tab (v2.02.03)
Adds a "Server preset" combo in the Hands-free wakeword card that lists
all configured wakeword engines by name. Selecting one auto-fills the
URI and model fields and re-probes the connection. Selection persists
via wakeword_active in config.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 21:01:57 +02:00
48014ae662 fix: license in md style, benchmark pane minimum height (v2.02.02)
- About tab: render License with _md_panel instead of _text_panel
- Benchmark pane: set_size_request 320px min, shrink=False on both sides
  so the engine list and results table are always visible

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 20:55:57 +02:00
9b95c632fa feat: show last benchmark time+accuracy on selected STT engine (v2.02.01)
After running a benchmark, each engine's best result (time, accuracy)
is persisted to config and shown as a small info line in the Engines tab
when that engine is selected. Updates live as the benchmark runs.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 20:42:22 +02:00
2df5be3212 feat: language metadata in benchmark — Lang column, filter support (v2.02.00)
- stt.py: add ModelMeta dataclass, fmt_languages(), list_models_meta(),
  detect_remote_device(); refactor list_models() to delegate
- benchmark.py: add languages field to BenchRow; fetch via _get_langs()
  with URL-level caching using list_models_meta()
- gtksettings.py: show language labels per engine in checkbox list;
  add language codes to search filter; add Lang column to results table

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 20:02:12 +02:00
51ab6d5aff ui: larger, more visible tab labels (v2.01.03)
- Tab font-size 12px → 14px (matches body text)
- Inactive tabs: muted foreground color so they're clearly readable
  but visually distinct from the active tab
- Active tab: bold + blue (#1a73e8), slightly more padding (8px 18px)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:34:48 +02:00
8d79c84a8f chore: adopt x.xx.xx versioning schema (v2.01.02)
Schema: MAJOR.FEATURE.FIX
  MAJOR  — breaking changes / major redesign
  FEATURE — two-digit, new user-visible features (00-99)
  FIX     — two-digit, bug fixes within a feature release (00-99)

Renamed 2.1.2 → 2.01.02 to start the new format.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:27:13 +02:00
81b79299ea fix: _run_bench crashes when Engines tab was never opened (v2.1.2)
_stt_commit() accesses self.stt_name which only exists after the Engines
tab is lazily built. Guard with hasattr so running a benchmark directly
from the Benchmark tab no longer throws AttributeError.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:21:56 +02:00
0eafb59d82 benchmark: resizable engine/results pane; auto-save WAV+ref paths (v2.1.1)
- Engine checklist and results table now split by a Gtk.Paned (vertical)
  so the user can drag the divider to give more room to either panel
- WAV and reference .txt paths are written to disk (save()) the moment a
  file is picked via the file chooser, without needing to click Save;
  also saved on Run if they changed since the last disk write

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:18:34 +02:00
e39b253906 benchmark: engine checkbox selector + status dots; manual/about/templates (v2.0.9)
- Benchmark tab: scrollable engine checklist above Run with live
  reachability dots (green/red), name+model+URL filter, All/None buttons;
  _run_bench respects selection and shows clear message when nothing ticked
- About tab: changelog now rendered via _md_panel (markdown headers, bold,
  lists) instead of plain monospace _text_panel
- Manual tab: graceful fallback with clickable GitHub link when MANUAL.md
  is not installed; build-deb.sh now copies MANUAL.md from repo root so
  /opt/blitztext/MANUAL.md exists in future installs
- STT quickstart templates expanded: Speaches docker, whisper.cpp server,
  NVIDIA NIM/Parakeet, five built-in local model sizes (tiny→large-v3)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 19:06:08 +02:00
a6d960bfbf benchmark: sortable columns (v2.0.8)
Wrap ListStore in TreeModelSort and set sort_column_id on every column
so clicking any header sorts ascending/descending.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:36:27 +02:00
5458fdc1eb engines: Test button inline with result + selectable; benchmark: persist WAV/ref paths (v2.0.7)
- Engines tab: move Test button out of the toolbar, place it in a row
  directly beside the result label so button and output are co-located;
  result label is now selectable so error text can be copied
- Benchmark tab: add bench_wav/bench_ref/bench_expand_models to Config;
  file pickers restore last-used paths on open; any change (file-set,
  toggle, or Run) writes directly to cfg so paths survive without Save;
  [benchmark] section written to config.toml on Save

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:29:01 +02:00
1c16cfeb0f benchmark: remote GPU detection, URL column, test-all-models (v2.0.6)
- stt.detect_remote_device(): probes /info (faster-whisper-server) then
  /metadata (NVIDIA NIM) to detect CUDA vs CPU; cached per unique URL
- BenchRow gains url field; Device column now shows "CUDA" for GPU remotes
  instead of the generic "remote"
- Benchmark table gains URL column (scheme stripped, max 180px wide)
- "Test all models per engine" checkbox: fetches list_models() for each
  remote engine and expands to one row per model when checked
- benchmark.run() gains expand_models parameter

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:19:42 +02:00
bc6e2a6e54 benchmark: deduplicate engines, friendly error messages, tooltip for full error (v2.0.5)
- _run_bench: deduplicate STT engines by name before running; show a
  warning in the summary line listing which names were skipped
- _bench_add_row: replace raw HTTP error strings with human-readable
  reasons ("Wrong model name", "Server offline", "Timed out", etc.);
  full raw error stored in hidden column 7 shown as row tooltip on hover
- bench_store: added 8th column (tooltip text); tree.set_tooltip_column(7)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 18:12:09 +02:00
4d59853da6 benchmark: add 'Best for' column, rename GPU→CUDA (v2.0.4)
- BenchRow gains `best_for` field: "Short clips" / "Short / medium" /
  "Long / batch" / "Streaming" — derived from engine type and model name
- Device now shows "CUDA" instead of "GPU" for clarity
- Benchmark table gains a "Best for" column between Device and Time(s)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 17:28:55 +02:00
0ff0f604c2 stt: omit model field when empty (fixes Riva 400); settings: always-visible scrollbar (v2.0.3)
- stt._transcribe_remote: no longer falls back to "whisper-1" when
  engine.model is empty — omits the field entirely so Riva/NIM uses its
  default model instead of rejecting the request with HTTP 400
- gtksettings._page: switch vertical scroll policy to ALWAYS and disable
  overlay scrolling so the scrollbar is permanently visible, making
  it obvious when a tab has more content below the visible area

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 17:00:58 +02:00
6534284c56 bump version to 2.0.2
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 16:04:38 +02:00
aea24400af fix: auto-paste long/multiline output, O(n²) overlay accumulation (v2.0.1)
Root cause of session freeze confirmed: a 15 000-char code block was typed
character-by-character via xdotool at 12ms/char = ~3 min, flooding the X11
per-client event buffer until the entire session froze.

- paste.py: any text >300 chars or containing newlines auto-upgrades to
  clipboard paste (instant Ctrl+V) regardless of configured output mode.
  xdotool type is kept only for short single-line text where it matters.
- daemon.py: replace on_token "".join(acc) accumulation (O(n²) for long
  code blocks) with a sliding deque that shows only the last 400 chars in
  the overlay — Pango no longer re-lays out a growing 15 KB string on each
  incoming token.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:56:44 +02:00
99340b0ff3 bump version to 2.0.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:35:28 +02:00
59118364fb bump version to 1.9.9
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 15:10:22 +02:00
48be824a50 settings: emoji search, Manual tab fix, readable infobox (v1.9.5)
- Emoji picker: SearchEntry at top filters all categories via unicodedata.name()
  in real time; category view hides while searching, restores on clear
- Manual tab: add pkg_dir/MANUAL.md to _app_paths() search list so it works in
  both venv and deb installs (MANUAL.md deployed alongside the package)
- bt-infobox CSS: replace @theme_selected_bg_color (saturated blue) with a
  neutral 5% mix of fg/bg so banner text is always readable

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 13:09:42 +02:00
2fe6632269 settings: complete UI redesign — card layout, section titles, scrollable tabs (v1.9.4)
All settings tabs now use a card-based GTK3 layout:
- Related fields grouped into Gtk.ListBox cards with rounded borders (bt-card /
  boxed-list CSS) and bold all-caps section headers via _card_section helper
- CSS provider injected at init: .bt-section, .bt-card, .bt-infobox styles
- Each notebook page wraps content in a ScrolledWindow (740×700 px dialog)
- _labeled and _switch_row accept both Gtk.Box and Gtk.ListBox parents
- New helpers: _section_title, _card_section, _lb_add, _url_field_lb,
  _icon_field_lb, _key_field_lb
- Engines toolbars: creation buttons (+ Add/Stream/Quickstart) left-aligned,
  action buttons (Delete/Test/⟳) right-aligned via pack_end
- Presets: Identity / Trigger / Behaviour / Prompt cards
- Input: Input mode & keys / Quality gate / Wakeword / Sound cues cards
- General: Microphone / Output & language / Notifications / Startup cards
- Section names cleaned up (no more "WW -" prefix, cleaner device label)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 12:18:50 +02:00
dd617f625e settings: info buttons, Manual tab, engine quickstart templates, human-readable type names (v1.9.3)
- Every _labeled and _switch_row field now gets a clickable ⓘ info button
  that opens a plain-language help popover — targeted at non-technical users
- New Manual tab in Settings renders MANUAL.md directly inside the dialog
- STT and LLM toolbars each get a "Quickstart ▾" button: a menu of common
  providers (OpenAI, Groq, OpenRouter, Ollama, LM Studio, vLLM, llama-swap,
  faster-whisper-server, NVIDIA Riva) that pre-fills the engine form in one click
- Engine type combos now show human-readable labels ("Internal — faster-whisper",
  "LAN server — runs on your machine", "GPU (CUDA)", "int8 — fast, less memory")
  while storing the same internal key values (no config migration needed)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-09 11:48:02 +02:00