# Changelog All notable changes to D3RO Voice will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## [Unreleased] ### Planned - macOS / Linux support - Additional Whisper model management UI - Cloud-optional backup (encrypted, opt-in) - Plugin system for custom pipelines ## [1.5.0] - 2026-09-23 > Published from an annotated tag. Installer and update metadata are served by the > canonical Forgejo feed; no binaries are committed to this repository. ### Added - **Next-sentence suggestions while you type.** With the feature turned on, a small ghost-text panel sits next to the caret in whatever app has focus and offers up to three ways to continue the sentence. `Ctrl+Alt+Right` accepts, `Down`/`Up` move between candidates, `Left` or the panel's X dismisses, and all four are ordinary rebindable shortcuts. The panel never takes focus and is click-through until you turn interaction on. - **Typed-text learning from the field you are in,** read through UI Automation and diffed as a snapshot, so committed Korean and Japanese IME text is counted correctly (key codes cannot reconstruct it). Password fields are refused before any read, and IME composition suppresses learning and suggestions until the character is committed. - **Weekly input insights** (`Settings > Input` and a dashboard card): keystroke, click and scroll totals, mouse travel converted to meters, top hours and apps, flow windows, edit friction (edits per 100 characters) and per-app suggestion quality. - **A personal phrase memory** built from your own typed sentences and voice history, ranked by frequency, recency (30-day half-life) and same-app usage, and offered as prompt hints. Phrases can be deleted individually or all at once. - **A privacy receipt** that reports the real number of retained rows and the 30-day retention rule, plus **smart exclusion**: only the app you are in can be suggested for the exclusion list, and only after repeated unreadable fields, never automatically. - **A shortcut safety audit** in Settings that flags invalid or conflicting bindings across every action. - **A local personal graph** that links your sentences by "follows" and shared-terms relationships, so related context can surface even when the current prefix differs. It is local SQLite only, with no embeddings or network. ### Changed - **Local model requests are now bounded and individually cancellable.** `LocalLLMService` gives every request its own abort controller, relays external cancellation, requires a `done` frame before a stream counts as successful, and clears incomplete streams. Generation and streaming are capped at 2048 tokens / 120 seconds and chat at 512 / 60 seconds. Text suggestions use `keep_alive: 2m` and no longer warm the model at startup. - **Voice conversations are single-flight** and pass their cancellation through to the active local chat request, so ending a conversation aborts its own inference instead of only changing what the UI shows. - Console windows are suppressed for the app's Windows helper processes (text to speech, voice actions, audio-device and active-window enumeration, and every ffmpeg path). ### Fixed - **Custom instructions ran the instruction instead of your text.** Every built-in instruction (translate, summarize, rephrase, explain code, free prompt) inserted the instruction's own wording rather than the processed result, and only `{{text}}` was ever substituted, which none of the presets use. The instruction is now the system prompt, the transcript is the text, and `{{text}}`, `{{userPrompt}}` and `{{targetLanguage}}` are resolved in one shared place. This path had never worked in any shipped release. - **The suggestion panel could refuse to close, revive itself, or appear on a bare click.** Holding the modifier that Windows turns into `Ctrl+Alt` no longer fires the voice shortcut underneath, closing the panel during generation discards that request instead of re-showing it, a click without typing no longer triggers a suggestion, and pressing Enter stops the same text from being suggested again. - **The global input hook is reference-counted**, so the shortcut service and input telemetry can attach at the same time without one disabling the other. ## [1.4.0] - 2026-09-21 ### Added - **Several shortcuts per action.** Every action now holds a list of bindings instead of a single one, so a second (or third) shortcut can be added with the `+` button and removed individually. - **Mouse buttons as shortcuts.** Side buttons (back / forward) can be bound on their own; right and middle click require a modifier. Left click cannot be bound because it drives every on-screen interaction. Mouse events cannot be swallowed, so a bound button still performs its original action — the settings screen says so before the binding is saved. - **Pick a key from a searchable list.** Besides pressing the key, a shortcut can now be chosen from a grouped dropdown with a search box inside it, which also makes keys reachable that are awkward to press while recording. - **The history and command popups are rebindable.** `Ctrl+Shift+V` and `Ctrl+Shift+C` were fixed in code and had no settings entry; they are now ordinary actions. The voice command shortcut, which had never been exposed in settings, is visible as well. ### Fixed - **Double-press hands-free never triggered.** Dictation and hands-free ship with the same default key and are told apart by the double press, but shortcut lookup stopped at the first match, so hands-free was unreachable in installed builds. Both actions now receive the event and are split by press type. - **Reserved system shortcuts could be assigned anyway.** The check compared joined key names, so pressing the modifiers in a different order let `Ctrl+C` and friends through. Combinations are now compared structurally. - **Turning shortcuts off also killed the popup shortcuts permanently.** Disabling global shortcuts released every registration in the process, including ones it did not own, and re-enabling never restored them. - **Enabling shortcuts after starting with them off left nothing bound.** - **Shortcut labels were frozen in the language they were recorded in** and did not follow the app language or platform conventions. They are now derived on display. - **The dashboard caption indicator never reflected the real state** because the event payload was stored instead of the state inside it. ### Changed - Shortcuts are stored as one list per action. Existing shortcuts are migrated automatically on first launch; no reconfiguration is needed. ## [1.3.7] - 2026-09-19 ### Fixed - **Recording and live caption overlays never worked in installed builds.** Popup pages loaded their scripts as classic `